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); }
public static bool TryRead(BinaryReader reader, int version, ulong hash, ulong seed, out QarArchiveEntryContentHeader header) { header = new QarArchiveEntryContentHeader(); // attemtp to read the file signature // read a chunk for processing // a chunk is 8 bytes byte[] buffer = new byte[8]; // not enough data if (reader.Read(buffer, 0, buffer.Length) != buffer.Length) { return(false); } var decryptAlgorithm = new Decrypt1Transform(version, hash, seed); // decrypt the buffer decryptAlgorithm.TransformBlock(buffer, 0, buffer.Length, buffer, 0); // get the encryption type and the key header.Signature = BitConverter.ToUInt32(buffer, 0); header.Key = BitConverter.ToUInt32(buffer, 4); // file not encrypted // unset the encryption and the key if (header.Signature != Signature1 && header.Signature != Signature2) { header.Signature = 0; header.Key = 0; } else if (header.Signature == Signature2) { // not enough data if (reader.Read(buffer, 0, buffer.Length) != buffer.Length) { return(false); } decryptAlgorithm.TransformBlock(buffer, 0, buffer.Length, buffer, 0); // additional 8 bytes // the size of the file, excluding the header header.Size1 = BitConverter.ToUInt32(buffer, 0); header.Size2 = BitConverter.ToUInt32(buffer, 4); if (header.Size1 != header.Size2) { return(false); } } return(true); }