public override void Write(Stream output, IDirectory inputDirectory) { const uint xorMask1 = 0x41441043; const uint xorMask2 = 0x11C22050; const uint xorMask3 = 0xD05608C3; const uint xorMask4 = 0x532C7319; const int headerSize = 32; int shift = (Flags & 0x800) > 0 ? 12 : 10; int alignment = 1 << shift; BinaryWriter writer = new BinaryWriter(output, Encoding.Default, true); long headerPosition = output.Position; output.Skip(headerSize); long tableOffset = output.Position; output.Skip(8 * Entries.Count); //long unknownTableOffset = output.Position; //output.Skip(16 * UnknownEntries.Count); output.AlignWrite(alignment, 0x00); long dataOffset = output.Position; ulong[] sections = new ulong[Entries.Count]; for (int i = 0; i < Entries.Count; i++) { QarEntry entry = Entries[i]; entry.CalculateHash(); ulong section = (ulong)(output.Position >> shift) << 40 | (entry.Hash & 0xFF) << 32 | entry.Hash >> 32 & 0xFFFFFFFFFF; sections[i] = section; entry.Write(output, inputDirectory); output.AlignWrite(alignment, 0x00); } long endPosition = output.Position; uint endPositionHead = (uint)(endPosition >> shift); output.Position = headerPosition; writer.Write(QarMagicNumber); // SQAR writer.Write(Flags ^ xorMask1); writer.Write((uint)Entries.Count ^ xorMask2); writer.Write(xorMask3); // unknown count (not saved in the xml and output directory) writer.Write(endPositionHead ^ xorMask4); writer.Write((uint)dataOffset ^ xorMask1); writer.Write(1 ^ xorMask1); writer.Write(0 ^ xorMask2); output.Position = tableOffset; byte[] encryptedSectionsData = EncryptSections(sections); writer.Write(encryptedSectionsData); output.Position = endPosition; }
public override void Read(Stream input) { const uint xorMask1 = 0x41441043; const uint xorMask2 = 0x11C22050; const uint xorMask3 = 0xD05608C3; const uint xorMask4 = 0x532C7319; BinaryReader reader = new BinaryReader(input, Encoding.Default, true); uint magicNumber = reader.ReadUInt32(); // SQAR Flags = reader.ReadUInt32() ^ xorMask1; uint fileCount = reader.ReadUInt32() ^ xorMask2; uint unknownCount = reader.ReadUInt32() ^ xorMask3; uint blockFileEnd = reader.ReadUInt32() ^ xorMask4; uint offsetFirstFile = reader.ReadUInt32() ^ xorMask1; Version = reader.ReadUInt32() ^ xorMask1; // 1 2 uint unknown2 = reader.ReadUInt32() ^ xorMask2; // 0 // Determines the alignment block size. int blockShiftBits = (Flags & 0x800) > 0 ? 12 : 10; byte[] sectionsData = reader.ReadBytes((int)(8 * fileCount)); ulong[] sections = DecryptSectionList(fileCount, sectionsData, Version); byte[] unknownSectionData = reader.ReadBytes((int)(16 * unknownCount)); List <QarEntry> entries = new List <QarEntry>(); foreach (var section in sections) { ulong sectionBlock = section >> 40; ulong hash = section & 0xFFFFFFFFFF; ulong sectionOffset = sectionBlock << blockShiftBits; reader.BaseStream.Position = (long)sectionOffset; var entry = new QarEntry(); entry.Read(reader, Version); entries.Add(entry); } Entries = entries; }
public override void Read(Stream input) { const uint xorMask1 = 0x41441043; const uint xorMask2 = 0x11C22050; const uint xorMask3 = 0xD05608C3; const uint xorMask4 = 0x532C7319; BinaryReader reader = new BinaryReader(input, Encoding.Default, true); uint magicNumber = reader.ReadUInt32(); // SQAR Flags = reader.ReadUInt32() ^ xorMask1; uint fileCount = reader.ReadUInt32() ^ xorMask2; uint unknownCount = reader.ReadUInt32() ^ xorMask3; uint blockFileEnd = reader.ReadUInt32() ^ xorMask4; uint offsetFirstFile = reader.ReadUInt32() ^ xorMask1; uint unknown1 = reader.ReadUInt32() ^ xorMask1; // 1 uint unknown2 = reader.ReadUInt32() ^ xorMask2; // 0 // Determines the alignment block size. int blockShiftBits = (Flags & 0x800) > 0 ? 12 : 10; byte[] sectionsData = reader.ReadBytes((int)(8 * fileCount)); ulong[] sections = DecryptSectionList(fileCount, sectionsData); byte[] unknownSectionData = reader.ReadBytes((int)(16 * unknownCount)); List<QarEntry> entries = new List<QarEntry>(); foreach (var section in sections) { ulong sectionBlock = section >> 40; ulong hash = section & 0xFFFFFFFFFF; ulong sectionOffset = sectionBlock << blockShiftBits; reader.BaseStream.Position = (long)sectionOffset; var entry = new QarEntry(); entry.Read(reader); entries.Add(entry); } Entries = entries; }