public void Patch() { var length = DetectLength(); var disk = StreamFormatter.CreateDisk(outputHDI, sysDisk, length, patchData.SysFiles); var dstStream = disk.Partitions[0].Open(); var dstFat = new PC98FatFileSystem(dstStream); foreach (var img in _sourceImages) { if (IsFloppy(img)) { using (var source = VirtualDisk.OpenDisk(img, FileAccess.Read)) { using (var fs = new PC98FatFileSystem(source.Content)) { CopyFiles(fs, dstFat); } } } else if (img.ToLower().EndsWith(".hdi")) { using (var srcDisk = Disk.OpenDisk(img, FileAccess.Read)) { using (var srcStream = srcDisk.Partitions[0].Open()) { using (var srcFat = new PC98FatFileSystem(srcStream)) { CopyFiles(srcFat, dstFat); } } } } } }
private void CopyFile(string srcName, string dstName, PC98FatFileSystem srcFat, FatFileSystem dstFat) { using (var src = srcFat.OpenFile(srcName, FileMode.Open)) { MakeDirectory(dstName, dstFat); if (dstFat.FileExists(dstName)) { Debug.WriteLine("exists"); //dstFat.DeleteFile(dstName); } var tmpfile = "~copy.tmp"; if (dstFat.FileExists(tmpfile)) { dstFat.DeleteFile(tmpfile); } using (var dst = dstFat.OpenFile(tmpfile, FileMode.Create)) { src.CopyTo(dst); } dstFat.MoveFile(tmpfile, dstName, true); var fi = dstFat.GetFileInfo(dstName); fi.LastWriteTime = DateTime.Now; fi.LastAccessTime = DateTime.Now; /*try { * dstFat.MoveFile(tmpfile, dstName, true); * var fi = dstFat.GetFileInfo(dstName); * fi.LastWriteTime = DateTime.Now; * } catch (Exception e) { * Debug.WriteLine(dstName); * }*/ } }
private static void CopySysFiles(PC98FatFileSystem fs, PC98FatFileSystem newfs, string[] sysFiles) { foreach (var file in sysFiles) { var compressedFile = file.Substring(0, file.Length - 1) + "_"; if (fs.FileExists(file)) { using (var dst = newfs.OpenFile(file, FileMode.CreateNew)) { using (var src = fs.OpenFile(file, FileMode.Open)) { src.CopyTo(dst); } } } else if (fs.FileExists(compressedFile)) { using (var dst = newfs.OpenFile(file, FileMode.CreateNew)) { using (var src = fs.OpenFile(compressedFile, FileMode.Open)) { UnpackMSLZ(src, dst); } } } else { throw new FileNotFoundException($"Can't find file {file} in the system disk"); } } }
private void ApplyPatch(string srcName, PatchedFile file, PC98FatFileSystem srcFat, FatFileSystem dstFat) { if (srcName.EndsWith("CRUISER.COM")) { var dir = System.IO.Path.GetDirectoryName(Application.ExecutablePath); var name = Path.Combine(dir, srcName.TrimStart('\\')); using (var src = srcFat.OpenFile(srcName, FileMode.Open)) { using (var dst = File.Create(name)) { src.CopyTo(dst); } } using (var dst = File.Create(name + ".patch")) { dst.Write(file.Patch, 0, file.Patch.Length); } } MakeDirectory(file.Name, dstFat); using (var ms = new MemoryStream(file.Patch)) { ms.Position = 0; using (var src = srcFat.OpenFile(srcName, FileMode.Open)) { using (var dst = dstFat.OpenFile(file.Name, FileMode.Create)) { BsPatch.Apply(src, file.Patch, dst); } } } }
public static void FormatStream(int size, Stream s, PC98FatFileSystem fs) { FormatData format; if (size == 5) { format = img5; } else if (size == 10) { format = img10; } else if (size == 15) { format = img15; } else if (size == 20) { format = img20; } else if (size == 30) { format = img30; } else if (size == 40) { format = img40; } else { throw new ArgumentOutOfRangeException(); } s.Position = format.IplStart; s.Write(format.IplContent, 0, format.IplContent.Length); FillZero(s, format.E5Start); s.Position = format.PartInfoStart; s.Write(format.PartInfo, 0, format.PartInfo.Length); s.Position = format.E5Start; FillE5(s); s.Position = format.BootloaderStart; FillZero(s, format.BootloaderEnd); s.Position = format.BpbStart; s.Write(format.BpbContent, 0, format.BpbContent.Length); s.Position = format.FatStart; // первая копия FAT s.Write(format.FatContent, 0, format.FatContent.Length); // заполняем нулями до конца FAT FillZero(s, format.RootSectorStart); // вторая копия FAT s.Position = format.FatEnd; s.Write(format.FatContent, 0, format.FatContent.Length); s.Position = format.RootSectorStart; for (var i = 0; i < (format.RootSectorEnd - format.RootSectorEnd); i += 32) { s.WriteByte(0); s.Position += 31; } WriteBootloader(s, fs, format); }
public static bool CheckSysDisk(string file) { using (var disk = Disk.OpenDisk(file, FileAccess.Read)) { using (var fs = new PC98FatFileSystem(disk.Content)) { if (fs.FileExists(@"\HDFORMAT.EXE") && fs.FileExists(@"\MSDOS.SYS")) { return(true); } } } return(false); }
public static Disk CreateDisk(string filename, string dosDisk, int length, string[] sysFiles) { if (File.Exists(filename)) { File.Delete(filename); } HddType size; if (length == 5) { size = HddType.Size5Mb; } else if (length == 10) { size = HddType.Size10Mb; } else if (length == 15) { size = HddType.Size15Mb; } else if (length == 20) { size = HddType.Size20Mb; } else if (length == 30) { size = HddType.Size30Mb; } else if (length == 40) { size = HddType.Size40Mb; } else { throw new ArgumentOutOfRangeException("Unsupported image size"); } using (var source = DiscUtils.Fdi.Disk.OpenDisk(dosDisk, FileAccess.Read)) { var fh = File.Create(filename); var disk = Disk.InitializeFixed(fh, Ownership.None, size); using (var fs = new PC98FatFileSystem(source.Content)) { FormatStream(length, disk.Content, fs); using (var partStream = disk.Partitions[0].Open()) { using (var newfs = new PC98FatFileSystem(partStream)) { CopySysFiles(fs, newfs, sysFiles); } } } return(disk); } }
private void CopyFiles(PC98FatFileSystem srcFat, FatFileSystem dstFat) { var fileList = new Dictionary <string, string>(); BuildChecksums(fileList, srcFat, @"\"); foreach (var file in patchData.PatchData) { if (file.Processed) { continue; } if (file.Action == PatchAction.Original) { var srcName = FindFile(file, fileList); if (!string.IsNullOrEmpty(srcName)) { //throw new FileNotFoundException($"Can't find file {file.Name} in original game image or checksums differ"); CopyFile(srcName, file.Name, srcFat, dstFat); file.Processed = true; progressCb?.Invoke(); } } else if (file.Action == PatchAction.Copy) { CreateFile(file, dstFat); file.Processed = true; } else if (file.Action == PatchAction.Patch) { var srcName = FindFile(file, fileList); if (!string.IsNullOrEmpty(srcName)) { ApplyPatch(srcName, file, srcFat, dstFat); file.Processed = true; progressCb?.Invoke(); } } else if (file.Action == PatchAction.Ask) { var fileName = form.AskForFile(file.Name); if (string.IsNullOrEmpty(fileName)) { throw new ArgumentException($"Can't continue patch without {file.Name}"); } CopyFileFromFs(file.Name, fileName, dstFat); file.Processed = true; } } }
private static void BuildChecksums(Dictionary <string, string> fileList, PC98FatFileSystem srcFat, string dir) { var files = srcFat.GetFiles(dir); foreach (var file in files) { using (var s = srcFat.OpenFile(file, FileMode.Open)) { fileList.Add(file, Md5sum(s)); } } var dirs = srcFat.GetDirectories(dir); foreach (var dirname in dirs) { BuildChecksums(fileList, srcFat, dirname); } }
private static void CopySysFiles(PC98FatFileSystem fs, PC98FatFileSystem newfs) { var files = new string[] { @"\IO.SYS", @"\MSDOS.SYS", @"\COMMAND.COM", @"\CONFIG.SYS" }; foreach (var file in files) { using (var dst = newfs.OpenFile(file, FileMode.CreateNew)) { using (var src = fs.OpenFile(file, FileMode.Open)) { src.CopyTo(dst); } } } using (var dst = newfs.OpenFile(@"\HIMEM.SYS", FileMode.CreateNew)) { using (var src = fs.OpenFile(@"\HIMEM.SY_", FileMode.Open)) { UnpackMSLZ(src, dst); } } }
public static void CreateDisk() { var filename = @"D:\Translations\Tools\Patcher\images\newdisk_empty40.hdi"; using (var fh = File.Create(filename)) { using (var disk = Disk.InitializeFixed(fh, Ownership.None, HddType.Size40Mb)) { using (var source = DiscUtils.Fdi.Disk.OpenDisk(@"S:\Translations\Patcher\dos1.fdi", FileAccess.Read)) { using (var fs = new PC98FatFileSystem(source.Content)) { var s = disk.Content; FormatStream(40, s, fs); using (var partStream = disk.Partitions[0].Open()) { using (var newfs = new PC98FatFileSystem(partStream)) { CopySysFiles(fs, newfs); } } } } } } }
private static void WriteBootloader(Stream s, PC98FatFileSystem fs, FormatData format) { using (var fh = fs.OpenFile(@"\HDFORMAT.EXE", FileMode.Open)) { var sub = new byte[] { 0xE9, 0xD1, 0x02, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, }; var buf = new byte[0x1000]; var readPos = fh.Position; var len = format.BootloaderEnd - format.BootloaderStart; var currPos = fh.Position; var found = false; while (fh.Position < fh.Length) { currPos = fh.Position; fh.Read(buf, 0, buf.Length); var pos = FindSub(buf, sub); if (pos > (buf.Length - sub.Length)) { fh.Position = pos; continue; } if (pos >= 0) { currPos = currPos + pos; found = true; break; } } if (!found) { throw new EntryPointNotFoundException("Can't find bootloader fingerprint in the HDFORMAT.EXE"); } fh.Position = currPos; s.Position = format.BootloaderStart; fh.Read(buf, 0, buf.Length); s.Write(buf, 0, buf.Length); fh.Read(buf, 0, buf.Length); s.Write(buf, 0, buf.Length); } }
public static bool CheckGameSource(PatchContainer patch, string file, Action cb) { var found = false; using (var disk = Disk.OpenDisk(file, FileAccess.Read)) { SparseStream s; if (IsFloppy(file)) { s = disk.Content; } else if (file.ToLower().EndsWith(".hdi")) { s = disk.Partitions[0].Open(); } else { return(false); } using (var fs = new PC98FatFileSystem(s)) { var filelist = new Dictionary <string, string>(); BuildChecksums(filelist, fs, @"\"); foreach (var fdata in patch.PatchData) { if (fdata.Found) { continue; } if (!string.IsNullOrEmpty(FindFile(fdata, filelist))) { fdata.Found = true; cb(); found = true; patch.FoundFiles++; } } } } return(found); }