public override IPatchResult Parse(string inputDir, string outputDir) { if (!IsFile) { var path = Path.Combine(outputDir, Filename).TrimEnd('\\'); if (!Directory.Exists(path)) { Directory.CreateDirectory(path); } return(new PatchResultSuccessful(path)); } using (var reader = new BinaryReader(PreparedStream)) { var Length = reader.ReadInt32(); var Checksum = reader.ReadUInt32(); var calculatedChecksum = CRC32.CalculateChecksumStream(PreparedStream); PreparedStream.Position = 8; var outputFile = Path.Combine(outputDir, Filename); Directory.CreateDirectory(Path.GetDirectoryName(outputFile)); using (var os = File.OpenWrite(outputFile)) { PreparedStream.CopyTo(os); } if (calculatedChecksum != Checksum) { return(new PatchResultPatchedFileCorrupt(outputFile)); } return(new PatchResultSuccessful(outputFile)); } }
public void Parse(string inputDirectory, string outputDirectory, out List <IPatchResult> patchResults) { var startTime = DateTime.Now; if (Encoding.ASCII.GetString(_reader.ReadBytes(8)) != "WzPatch\x1A") { throw new Exception("Not a WzPatch file"); } _reader.ReadInt32(); // Skipped; version number? uint checksum = _reader.ReadUInt32(); Console.WriteLine("Checking patchfile checksum...."); if (CRC32.CalculateChecksumStream(_stream) != checksum) { throw new Exception("Patch file is corrupt"); } _reader.BaseStream.Seek(16, SeekOrigin.Begin); Console.WriteLine("Inflating patchfile...."); _stream.Seek(2, SeekOrigin.Current); // Skip zlib header var inflatedPatchfile = zlibInflate(_stream); // Cleanup the previous stream _stream.Close(); _stream.Dispose(); // Continue with new stream _stream = inflatedPatchfile; _stream.Position = 0; Directory.CreateDirectory(outputDirectory); rawPatchfilename = Path.Combine(outputDirectory, "rawpatch.bin"); Console.WriteLine($"Saving raw patchdata to disk @ {rawPatchfilename}"); using (var fs = File.OpenWrite(rawPatchfilename)) { _stream.CopyTo(fs); } _stream.Position = 0; var patchSize = _stream.Length; Console.WriteLine("Saved patchfile"); _reader = new BinaryReader(_stream); parseSteps(inputDirectory, outputDirectory, out patchResults); File.Delete(rawPatchfilename); File.WriteAllText(Path.Combine(outputDirectory, $"MS-AutoPatcher log {DateTime.Now.ToString("yyyyMMdd HHmmss")}.log"), $@" Patchfile: {Filename} Raw patch size {patchSize} bytes Total time: {DateTime.Now.Subtract(startTime)} Results: {string.Join(Environment.NewLine, patchResults.Select(x => x.Filename + "\t\t" + x.Info))} "); }