public static bool TryRead(BinaryReader reader, int version, out QarArchiveEntryHeader header) { header = new QarArchiveEntryHeader(); // hash 8 bytes uint hashLow = reader.ReadUInt32() ^ xorMask1; uint hashHigh = reader.ReadUInt32() ^ xorMask1; header.Hash = (ulong)hashHigh << 32 | hashLow; // size 8 bytes (4+4), compressed and not, the order depends on the version header.Size1 = reader.ReadUInt32() ^ xorMask2; header.Size2 = reader.ReadUInt32() ^ xorMask3; // data hash 16 bytes uint md51 = reader.ReadUInt32() ^ xorMask4; uint md52 = reader.ReadUInt32() ^ xorMask1; uint md53 = reader.ReadUInt32() ^ xorMask1; uint md54 = reader.ReadUInt32() ^ xorMask2; byte[] md5Hash = new byte[16]; Buffer.BlockCopy(BitConverter.GetBytes(md51), 0, md5Hash, 0, sizeof(uint)); Buffer.BlockCopy(BitConverter.GetBytes(md52), 0, md5Hash, 4, sizeof(uint)); Buffer.BlockCopy(BitConverter.GetBytes(md53), 0, md5Hash, 8, sizeof(uint)); Buffer.BlockCopy(BitConverter.GetBytes(md54), 0, md5Hash, 12, sizeof(uint)); header.DataHash = md5Hash; // some file have a special signature if they are crypted // here we attempt to read the file signature QarArchiveEntryContentHeader.TryRead(reader, version, header.Hash, header.Seed, out header.Content); return(true); }
// header is 32 bytes void ReadHeader() { // we cant read if the archive has been closed. _archive.ThrowIfDisposed(); using (var stream = _archive.Open(Offset)) using (var reader = new BinaryReader(stream)) { if (!QarArchiveEntryHeader.TryRead(reader, _archive.Version, out header)) { throw new InvalidDataException("The contents of the stream are not in the qar archive format."); } } }