public bool Read(BinaryReader br, PatchHeader header) { if (br.BaseStream.Position == br.BaseStream.Length) { return(false); } byte entryCount = br.ReadByte(); if (entryCount == 0) { return(false); } CKey = new MD5Hash(br.ReadBytes(header.FileKeySize)); DecompressedSize = br.ReadUInt40BE(); Records = new List <PatchRecord>(entryCount); for (int i = 0; i < entryCount; i++) { var entry = new PatchRecord(); entry.Read(br, header); Records.Add(entry); } return(true); }
public void Read(BinaryReader br, PatchHeader header) { EKey = new MD5Hash(br.ReadBytes(header.FileKeySize)); DecompressedSize = br.ReadUInt40BE(); PatchEKey = new MD5Hash(br.ReadBytes(header.PatchEKeySize)); PatchSize = br.ReadUInt32BE(); Ordinal = br.ReadByte(); }
private void Read(Stream stream) { if (stream == null) { throw new ArgumentNullException(nameof(stream)); } if (!stream.CanRead || stream.Length <= 1) { throw new NotSupportedException($"Unable to read PatchFile stream"); } using (var reader = new BinaryReader(stream)) { PatchHeader.Read(reader); // read the patch entries int pageSize = 1 << PatchHeader.PageSize; long length = reader.BaseStream.Length; foreach (var offset in GetOffsets(reader)) { reader.BaseStream.Position = offset; // buffer the page then read the entries to minimise file reads using (var ms = new MemoryStream(reader.ReadBytes(pageSize))) using (var br = new BinaryReader(ms)) { var block = new PatchEntry(); while (block.Read(br, PatchHeader)) { _PatchEntries[block.CKey] = block; block = new PatchEntry(); } } } #region Unknown Data // Unknown = br.ReadBytes((int)(br.BaseStream.Length - br.BaseStream.Position)); /* * // the following is unknown entries that comprise of: * // a keysize byte followed by either a CKey or Ekey * // the key type relevant size (decompressed/compressed) * // and optionally an ESpec string * // blocks are always a pair of 112 bytes then 160, Encoding Entry then Content Entry * // * // struct encodin_entry { * // char _unk0[4]; // always 0 * // char KeySize; * // char Hash[KeySize]; * // char _unk15[7]; * // uint32_t some_offset; * // * // // 0x44 CompressedSize; * // } * // * // struct content_entry { * // char _unk0[4]; // always 0 * // char KeySize; * // char Hash[KeySize]; * // char _unk15[7]; * // uint32_t some_offset; * // * // // 0x34 DeompressedSize; * // // 0x6C partial ESpec always ends in 0xA0 * // } */ #endregion Checksum = stream.MD5Hash(); } }
/// <summary> /// Creates a new PatchFile /// </summary> public PatchFile() { PatchHeader = new PatchHeader(); _PatchEntries = new SortedList <MD5Hash, PatchEntry>(new MD5HashComparer()); }