Пример #1
0
        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);
                            }
                        }
                    }
                }
            }
        }
Пример #2
0
        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);
                 * }*/
            }
        }
Пример #3
0
 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");
         }
     }
 }
Пример #4
0
 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);
             }
         }
     }
 }
Пример #5
0
        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);
        }
Пример #6
0
 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);
 }
Пример #7
0
        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);
            }
        }
Пример #8
0
        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;
                }
            }
        }
Пример #9
0
        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);
            }
        }
Пример #10
0
        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);
                }
            }
        }
Пример #11
0
        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);
                                }
                            }
                        }
                    }
                }
            }
        }
Пример #12
0
 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);
     }
 }
Пример #13
0
        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);
        }