private void ParseHET() { Reader.Seek((long)HetTablePos64, SeekOrigin.Begin); if (Reader.Read <Media.FourCC>() != new Media.FourCC("HET\x1A")) { throw new Exception("WTF"); } if (Reader.ReadUInt32() != 1) { throw new Exception("WTF"); } HetDataSize = Reader.ReadUInt32(); HetTableSize = Reader.ReadUInt32(); HetMaxFileCount = Reader.ReadUInt16(); HetHashTableSize = Reader.ReadUInt16(); HetHashEntrySize = Reader.ReadUInt32(); HetTotalIndexSize = Reader.ReadUInt32(); HetIndexSizeExtra = Reader.ReadUInt32(); HetIndexSize = Reader.ReadUInt32(); HetBlockTableSize = Reader.ReadUInt32(); HetHashTableOffset = Reader.Position; }
private void ReadData(Ibasa.IO.BinaryReader reader) { LowResImage = new SharpIL.Resource( new Size3i(LowResImageWidth, LowResImageHeight, 1), 1, 1, EncodingFromFormat(LowResImageFormat)); HighResImage = new SharpIL.Resource( new Size3i(Width, Height, Depth), MipmapCount, Frames * Faces, EncodingFromFormat(ImageFormat)); if (VersionMinor < 3) { reader.Read(LowResImage[0, 0], 0, LowResImage[0, 0].Length); for (int mip = MipmapCount - 1; mip >= 0; --mip) { Size3f size = HighResImage.ComputeMipSliceSize(mip); for (int frame = 0; frame < Frames; ++frame) { for (int face = 0; face < Faces; ++face) { int array = face + (Faces * frame); reader.Read( HighResImage[mip, array], 0, HighResImage[mip, array].Length); } } } } else { //low res int lowResOffset = Resources.Find((resource) => resource.Type == ResourceType.LowResImage).Data; reader.Seek((uint)lowResOffset, SeekOrigin.Begin); reader.Read(LowResImage[0, 0], 0, LowResImage[0, 0].Length); //high res int highResOffset = Resources.Find((resource) => resource.Type == ResourceType.Image).Data; reader.Seek((uint)highResOffset, SeekOrigin.Begin); for (int mip = MipmapCount - 1; mip >= 0; --mip) { Size3f size = HighResImage.ComputeMipSliceSize(mip); for (int frame = 0; frame < Frames; ++frame) { for (int face = 0; face < Faces; ++face) { byte[] data = HighResImage[mip, face + (Faces * frame)]; reader.Read(data, 0, data.Length); } } } } }
private void ReadData(Ibasa.IO.BinaryReader reader) { int depth = (HeaderFlags.HasFlag(HeaderFlagsEnum.Depth) ? Depth : 1); int mipmapCount = (HeaderFlags.HasFlag(HeaderFlagsEnum.MipmapCount) ? MipmapCount : 1); if (IsDX10Mode) { int arraySize = (CubemapFlags.HasFlag(CubemapFlagsEnum.Cubemap) ? 6 : 1) * ArraySize; Image = new Resource(new Size3i(Width, Height, depth), mipmapCount, arraySize, SelectLoadFormat()); for (int arraySlice = 0; arraySlice < Image.ArraySize; ++arraySlice) { for (int mipSlice = 0; mipSlice < Image.MipLevels; ++mipSlice) { byte[] subresource = Image[mipSlice, arraySlice]; reader.Read(subresource, 0, subresource.Length); } } } else if (PixelFlags.HasFlag(PixelFlagsEnum.FourCC)) { int arraySize = (CubemapFlags.HasFlag(CubemapFlagsEnum.Cubemap) ? 6 : 1); Image = new Resource(new Size3i(Width, Height, depth), mipmapCount, arraySize, SelectLoadFormat()); for (int arraySlice = 0; arraySlice < Image.ArraySize; ++arraySlice) { for (int mipSlice = 0; mipSlice < Image.MipLevels; ++mipSlice) { byte[] subresource = Image[mipSlice, arraySlice]; reader.Read(subresource, 0, subresource.Length); } } } }
private void ReadHeader(Ibasa.IO.BinaryReader reader) { Header.ImageId = new byte[reader.ReadByte()]; Header.ColorMapType = reader.ReadByte(); Header.ImageType = reader.ReadByte(); Header.ColourMapOrigin = reader.ReadUInt16(); Header.ColorMapLength = reader.ReadUInt16(); Header.ColorMapDepth = reader.ReadByte(); Header.XOrigin = reader.ReadUInt16(); Header.YOrigin = reader.ReadUInt16(); Header.Width = reader.ReadUInt16(); Header.Height = reader.ReadUInt16(); Header.PixelDepth = reader.ReadByte(); Header.ImageDescriptor = reader.ReadByte(); reader.Read(Header.ImageId, 0, Header.ImageId.Length); }
public Mpq(Stream stream) { Reader = new Ibasa.IO.BinaryReader(stream, Encoding.ASCII); long offset = 0; bool founda, foundb; { Ibasa.Media.FourCC mpqa = new Media.FourCC("MPQ\x1A"); Ibasa.Media.FourCC mpqb = new Media.FourCC("MPQ\x1B"); //find offset var fourcc = Reader.Read<Ibasa.Media.FourCC>(); founda = fourcc == mpqa; foundb = fourcc == mpqb; while (!founda && !foundb) { offset += 512; fourcc = Reader.Read<Ibasa.Media.FourCC>(); founda = fourcc == mpqa; foundb = fourcc == mpqb; } } if (foundb) { var userdatasize = Reader.ReadUInt32(); offset += Reader.ReadUInt32(); var userdataheader = Reader.ReadUInt32(); } Reader.Seek(offset, SeekOrigin.Begin); if (Reader.Read<Media.FourCC>() != new Media.FourCC("MPQ\x1A")) throw new Exception("WTF"); HeaderSize = Reader.ReadUInt32(); ArchiveSize = Reader.ReadUInt32(); FormatVersion = Reader.ReadUInt16(); BlockSize = Reader.ReadUInt16(); HashTablePos = Reader.ReadUInt32(); BlockTablePos = Reader.ReadUInt32(); HashTableSize = Reader.ReadUInt32(); BlockTableSize = Reader.ReadUInt32(); if (FormatVersion >= 2) { HiBlockTablePos64 = Reader.ReadUInt64(); HashTablePosHi = Reader.ReadUInt16(); BlockTablePosHi = Reader.ReadUInt16(); } if (FormatVersion >= 3) { ArchiveSize64 = Reader.ReadUInt64(); BetTablePos64 = Reader.ReadUInt64(); HetTablePos64 = Reader.ReadUInt64(); } if (FormatVersion >= 4) { hashtablesize64 = Reader.ReadUInt64(); blocktablesize64 = Reader.ReadUInt64(); hiblocktablesize64 = Reader.ReadUInt64(); hettablesize64 = Reader.ReadUInt64(); bettablesize64 = Reader.ReadUInt64(); dawchunksize = Reader.ReadUInt32(); md5_blocktable = Reader.ReadBytes(16); md5_hashtable = Reader.ReadBytes(16); md5_hiblocktable = Reader.ReadBytes(16); md5_bettable = Reader.ReadBytes(16); md5_hettable = Reader.ReadBytes(16); md5_mpqheader = Reader.ReadBytes(16); } if (HetTablePos64 != 0) { ParseHET(); } if (BetTablePos64 != 0) { ParseBET(); } }
public Mpq(Stream stream) { Reader = new Ibasa.IO.BinaryReader(stream, Encoding.ASCII); long offset = 0; bool founda, foundb; { Ibasa.Media.FourCC mpqa = new Media.FourCC("MPQ\x1A"); Ibasa.Media.FourCC mpqb = new Media.FourCC("MPQ\x1B"); //find offset var fourcc = Reader.Read <Ibasa.Media.FourCC>(); founda = fourcc == mpqa; foundb = fourcc == mpqb; while (!founda && !foundb) { offset += 512; fourcc = Reader.Read <Ibasa.Media.FourCC>(); founda = fourcc == mpqa; foundb = fourcc == mpqb; } } if (foundb) { var userdatasize = Reader.ReadUInt32(); offset += Reader.ReadUInt32(); var userdataheader = Reader.ReadUInt32(); } Reader.Seek(offset, SeekOrigin.Begin); if (Reader.Read <Media.FourCC>() != new Media.FourCC("MPQ\x1A")) { throw new Exception("WTF"); } HeaderSize = Reader.ReadUInt32(); ArchiveSize = Reader.ReadUInt32(); FormatVersion = Reader.ReadUInt16(); BlockSize = Reader.ReadUInt16(); HashTablePos = Reader.ReadUInt32(); BlockTablePos = Reader.ReadUInt32(); HashTableSize = Reader.ReadUInt32(); BlockTableSize = Reader.ReadUInt32(); if (FormatVersion >= 2) { HiBlockTablePos64 = Reader.ReadUInt64(); HashTablePosHi = Reader.ReadUInt16(); BlockTablePosHi = Reader.ReadUInt16(); } if (FormatVersion >= 3) { ArchiveSize64 = Reader.ReadUInt64(); BetTablePos64 = Reader.ReadUInt64(); HetTablePos64 = Reader.ReadUInt64(); } if (FormatVersion >= 4) { hashtablesize64 = Reader.ReadUInt64(); blocktablesize64 = Reader.ReadUInt64(); hiblocktablesize64 = Reader.ReadUInt64(); hettablesize64 = Reader.ReadUInt64(); bettablesize64 = Reader.ReadUInt64(); dawchunksize = Reader.ReadUInt32(); md5_blocktable = Reader.ReadBytes(16); md5_hashtable = Reader.ReadBytes(16); md5_hiblocktable = Reader.ReadBytes(16); md5_bettable = Reader.ReadBytes(16); md5_hettable = Reader.ReadBytes(16); md5_mpqheader = Reader.ReadBytes(16); } if (HetTablePos64 != 0) { ParseHET(); } if (BetTablePos64 != 0) { ParseBET(); } }
public Gcf(Stream stream) { Reader = new Ibasa.IO.BinaryReader(stream, Encoding.ASCII); { long seek = Reader.Position; uint checksum = Reader.ReadBytes(10 * 4).Aggregate(0U, (sum, value) => sum + value); Reader.Position = seek; if (Reader.ReadUInt32() != 0x00000001) // HeaderVersion Always 0x00000001 { throw new InvalidDataException("Header version mismatch."); } if (Reader.ReadUInt32() != 0x00000001) // MajorVersion Always 0x00000001 { throw new InvalidDataException("Major version mismatch."); } var minor = Reader.ReadInt32(); if (minor != 3 && minor != 5 && minor != 6) { throw new InvalidDataException(string.Format("Minor version mismatch, read {0} expected 3, 5 or 6.", minor)); } GCFVersion = new Version(1, minor); CacheID = Reader.ReadInt32(); LastVersionPlayed = Reader.ReadInt32(); var dummy0 = Reader.ReadUInt32(); var dummy1 = Reader.ReadUInt32(); FileSize = Reader.ReadUInt32(); // Total size of GCF file in bytes. SectorSize = Reader.ReadUInt32(); // Size of each data block in bytes. SectorCount = Reader.ReadUInt32(); // Number of data blocks. if (checksum != Reader.ReadUInt32())// Header checksum. throw new InvalidDataException("Checksum mismatch."); } { long seek = Reader.Position; uint checksum = Reader.Read<uint>(7).Aggregate(0U, (sum, value) => sum + value); Reader.Position = seek; BlockCount = Reader.ReadUInt32(); // Number of data blocks. if (BlockCount != SectorCount) { throw new InvalidDataException("BlockCount does not match SectorCount."); } BlocksUsed = Reader.ReadUInt32(); // Number of data blocks that point to data. var dummy0 = Reader.ReadUInt32(); var dummy1 = Reader.ReadUInt32(); var dummy2 = Reader.ReadUInt32(); var dummy3 = Reader.ReadUInt32(); var dummy4 = Reader.ReadUInt32(); if (checksum != Reader.ReadUInt32()) // Header checksum. throw new InvalidDataException("Checksum mismatch."); } BlockEntryOffset = Reader.Position; //Seek past block entries Reader.Seek(BlockCount * BlockEntry.Size, SeekOrigin.Current); { //FragmentationMapHeader long seek = Reader.Position; uint checksum = Reader.Read<uint>(3).Aggregate(0U, (sum, value) => sum + value); Reader.Position = seek; uint sectorCount = Reader.ReadUInt32(); if (SectorCount != sectorCount) throw new InvalidDataException(); FirstUnusedEntry = Reader.ReadUInt32(); Terminator = Reader.ReadUInt32() == 0 ? 0x0000ffff : 0xffffffff; if (checksum != Reader.ReadUInt32()) // Header checksum. throw new InvalidDataException("Checksum mismatch."); } FragmentationMapEntryOffset = Reader.BaseStream.Position; //Seek past block entries Reader.Seek(BlockCount * 4, SeekOrigin.Current); { //BlockMapHeader if (GCFVersion.Minor <= 5) { uint blockCount = Reader.ReadUInt32(); uint firstBlockEntryIndex = Reader.ReadUInt32(); uint lastBlockEntryIndex = Reader.ReadUInt32(); uint dummy0 = Reader.ReadUInt32(); uint checksum = Reader.ReadUInt32(); //struct BlockMapEntry //{ // public uint PreviousBlockEntryIndex; // The previous block entry. (N/A if == BlockCount.) // public uint NextBlockEntryIndex; // The next block entry. (N/A if == BlockCount.) //} Reader.Seek(blockCount * 8, SeekOrigin.Current); } } { //DirectoryHeader if (Reader.ReadUInt32() != 0x00000004) // HeaderVersion Always 0x00000004 throw new InvalidDataException("Header version mismatch."); if (Reader.ReadUInt32() != CacheID) // CacheID throw new InvalidDataException("CacheID mismatch."); if (Reader.ReadUInt32() != LastVersionPlayed) // LastVersionPlayed throw new InvalidDataException("LastVersionPlayed mismatch."); ItemCount = Reader.ReadUInt32(); //public uint ItemCount; // Number of items in the directory. FileCount = Reader.ReadUInt32(); //public uint FileCount; // Number of files in the directory. var dummy0 = Reader.ReadUInt32(); DirectorySize = Reader.ReadUInt32(); //public uint DirectorySize; // Size of lpGCFDirectoryEntries & lpGCFDirectoryNames & lpGCFDirectoryInfo1Entries & lpGCFDirectoryInfo2Entries & lpGCFDirectoryCopyEntries & lpGCFDirectoryLocalEntries in bytes. NameSize = Reader.ReadUInt32(); //public uint NameSize; // Size of the directory names in bytes. HashTableKeyCount = Reader.ReadUInt32(); //public uint HashTableKeyCount; // Number of Info1 entires. CopyCount = Reader.ReadUInt32(); //public uint CopyCount; // Number of files to copy. LocalCount = Reader.ReadUInt32(); //public uint LocalCount; // Number of files to keep local. var dummy1 = Reader.ReadUInt32(); var dummy2 = Reader.ReadUInt32(); var checksum = Reader.ReadUInt32(); // Header checksum never computes } DirectoryEntryOffset = Reader.BaseStream.Position; Reader.Seek(ItemCount * DirectoryEntry.Size, SeekOrigin.Current); DirectoryNameOffset = Reader.BaseStream.Position; Reader.Seek(NameSize, SeekOrigin.Current); DirectoryInfo1EntryOffset = Reader.BaseStream.Position; Reader.Seek(HashTableKeyCount * DirectoryInfo1Entry.Size, SeekOrigin.Current); DirectoryInfo2EntryOffset = Reader.BaseStream.Position; Reader.Seek(ItemCount * DirectoryInfo2Entry.Size, SeekOrigin.Current); DirectoryCopyEntryOffset = Reader.BaseStream.Position; Reader.Seek(CopyCount * DirectoryCopyEntry.Size, SeekOrigin.Current); DirectoryLocalEntryOffset = Reader.BaseStream.Position; Reader.Seek(LocalCount * DirectoryLocalEntry.Size, SeekOrigin.Current); { //DirectoryMapHeader //public uint Dummy0; //public uint Dummy1; Reader.Seek(8, SeekOrigin.Current); } DirectoryMapEntryOffset = Reader.BaseStream.Position; Reader.Seek(ItemCount * 4, SeekOrigin.Current); { //ChecksumHeader ChecksumMapHeader if (Reader.ReadUInt32() != 0x00000001) // HeaderVersion Always 0x00000001 throw new InvalidDataException(); ChecksumSize = Reader.ReadUInt32(); // Size of LPGCFCHECKSUMHEADER & LPGCFCHECKSUMMAPHEADER & in bytes. if (Reader.ReadUInt32() != 0x14893721) // FormatCode Always 0x14893721 throw new InvalidDataException(); if (Reader.ReadUInt32() != 0x00000001) // Dummy0 Always 0x00000001 throw new InvalidDataException(); ChecksumItemCount = Reader.ReadUInt32(); // Number of file ID entries. ChecksumCount = Reader.ReadUInt32(); // Number of checksums. } ChecksumMapEntryOffset = Reader.BaseStream.Position; Reader.Seek(ChecksumItemCount * ChecksumMapEntry.Size, SeekOrigin.Current); ChecksumEntryOffset = Reader.BaseStream.Position; Reader.Seek(ChecksumCount * 4, SeekOrigin.Current); //Skip past signature Reader.Seek(0x80, SeekOrigin.Current); if (Reader.ReadUInt32() != LastVersionPlayed) // LastVersionPlayed throw new InvalidDataException("LastVersionPlayed mismatch."); { //DataHeader uint checksum = 0; uint sectorCount, sectorSize; checksum += (sectorCount = Reader.ReadUInt32()); // Number of data blocks. if (SectorCount != sectorCount) throw new InvalidDataException(); checksum += (sectorSize = Reader.ReadUInt32()); // Size of each data block in bytes. if (SectorSize != sectorSize) throw new InvalidDataException(); checksum += (FirstSectorOffset = Reader.ReadUInt32()); // Offset to first data block. checksum += (SectorsUsed = Reader.ReadUInt32()); // Number of data blocks that contain data. if (checksum != Reader.ReadUInt32()) //public uint Checksum; // Header checksum. throw new InvalidDataException(); } for (uint index = 0; index < ItemCount; ++index) { DirectoryEntry entry = GetDirectoryEntry(index); if (entry.ParentIndex == 0xFFFFFFFF) { RootDirectory = new GcfDirectoryInfo(this, index); break; } } }
int GetDataBlock(uint blockIndex, uint blockOffset, byte[] buffer, int index, int count) { Reader.Seek(FirstSectorOffset + blockIndex * SectorSize + blockOffset, SeekOrigin.Begin); return(Reader.Read(buffer, index, Math.Min(count, (int)(SectorSize - blockOffset)))); }
public Gcf(Stream stream) { Reader = new Ibasa.IO.BinaryReader(stream, Encoding.ASCII); { long seek = Reader.Position; uint checksum = Reader.ReadBytes(10 * 4).Aggregate(0U, (sum, value) => sum + value); Reader.Position = seek; if (Reader.ReadUInt32() != 0x00000001) // HeaderVersion Always 0x00000001 { throw new InvalidDataException("Header version mismatch."); } if (Reader.ReadUInt32() != 0x00000001) // MajorVersion Always 0x00000001 { throw new InvalidDataException("Major version mismatch."); } var minor = Reader.ReadInt32(); if (minor != 3 && minor != 5 && minor != 6) { throw new InvalidDataException(string.Format("Minor version mismatch, read {0} expected 3, 5 or 6.", minor)); } GCFVersion = new Version(1, minor); CacheID = Reader.ReadInt32(); LastVersionPlayed = Reader.ReadInt32(); var dummy0 = Reader.ReadUInt32(); var dummy1 = Reader.ReadUInt32(); FileSize = Reader.ReadUInt32(); // Total size of GCF file in bytes. SectorSize = Reader.ReadUInt32(); // Size of each data block in bytes. SectorCount = Reader.ReadUInt32(); // Number of data blocks. if (checksum != Reader.ReadUInt32()) // Header checksum. { throw new InvalidDataException("Checksum mismatch."); } } { long seek = Reader.Position; uint checksum = Reader.Read <uint>(7).Aggregate(0U, (sum, value) => sum + value); Reader.Position = seek; BlockCount = Reader.ReadUInt32(); // Number of data blocks. if (BlockCount != SectorCount) { throw new InvalidDataException("BlockCount does not match SectorCount."); } BlocksUsed = Reader.ReadUInt32(); // Number of data blocks that point to data. var dummy0 = Reader.ReadUInt32(); var dummy1 = Reader.ReadUInt32(); var dummy2 = Reader.ReadUInt32(); var dummy3 = Reader.ReadUInt32(); var dummy4 = Reader.ReadUInt32(); if (checksum != Reader.ReadUInt32()) // Header checksum. { throw new InvalidDataException("Checksum mismatch."); } } BlockEntryOffset = Reader.Position; //Seek past block entries Reader.Seek(BlockCount * BlockEntry.Size, SeekOrigin.Current); { //FragmentationMapHeader long seek = Reader.Position; uint checksum = Reader.Read <uint>(3).Aggregate(0U, (sum, value) => sum + value); Reader.Position = seek; uint sectorCount = Reader.ReadUInt32(); if (SectorCount != sectorCount) { throw new InvalidDataException(); } FirstUnusedEntry = Reader.ReadUInt32(); Terminator = Reader.ReadUInt32() == 0 ? 0x0000ffff : 0xffffffff; if (checksum != Reader.ReadUInt32()) // Header checksum. { throw new InvalidDataException("Checksum mismatch."); } } FragmentationMapEntryOffset = Reader.BaseStream.Position; //Seek past block entries Reader.Seek(BlockCount * 4, SeekOrigin.Current); { //BlockMapHeader if (GCFVersion.Minor <= 5) { uint blockCount = Reader.ReadUInt32(); uint firstBlockEntryIndex = Reader.ReadUInt32(); uint lastBlockEntryIndex = Reader.ReadUInt32(); uint dummy0 = Reader.ReadUInt32(); uint checksum = Reader.ReadUInt32(); //struct BlockMapEntry //{ // public uint PreviousBlockEntryIndex; // The previous block entry. (N/A if == BlockCount.) // public uint NextBlockEntryIndex; // The next block entry. (N/A if == BlockCount.) //} Reader.Seek(blockCount * 8, SeekOrigin.Current); } } { //DirectoryHeader if (Reader.ReadUInt32() != 0x00000004) // HeaderVersion Always 0x00000004 { throw new InvalidDataException("Header version mismatch."); } if (Reader.ReadUInt32() != CacheID) // CacheID { throw new InvalidDataException("CacheID mismatch."); } if (Reader.ReadUInt32() != LastVersionPlayed) // LastVersionPlayed { throw new InvalidDataException("LastVersionPlayed mismatch."); } ItemCount = Reader.ReadUInt32(); //public uint ItemCount; // Number of items in the directory. FileCount = Reader.ReadUInt32(); //public uint FileCount; // Number of files in the directory. var dummy0 = Reader.ReadUInt32(); DirectorySize = Reader.ReadUInt32(); //public uint DirectorySize; // Size of lpGCFDirectoryEntries & lpGCFDirectoryNames & lpGCFDirectoryInfo1Entries & lpGCFDirectoryInfo2Entries & lpGCFDirectoryCopyEntries & lpGCFDirectoryLocalEntries in bytes. NameSize = Reader.ReadUInt32(); //public uint NameSize; // Size of the directory names in bytes. HashTableKeyCount = Reader.ReadUInt32(); //public uint HashTableKeyCount; // Number of Info1 entires. CopyCount = Reader.ReadUInt32(); //public uint CopyCount; // Number of files to copy. LocalCount = Reader.ReadUInt32(); //public uint LocalCount; // Number of files to keep local. var dummy1 = Reader.ReadUInt32(); var dummy2 = Reader.ReadUInt32(); var checksum = Reader.ReadUInt32(); // Header checksum never computes } DirectoryEntryOffset = Reader.BaseStream.Position; Reader.Seek(ItemCount * DirectoryEntry.Size, SeekOrigin.Current); DirectoryNameOffset = Reader.BaseStream.Position; Reader.Seek(NameSize, SeekOrigin.Current); DirectoryInfo1EntryOffset = Reader.BaseStream.Position; Reader.Seek(HashTableKeyCount * DirectoryInfo1Entry.Size, SeekOrigin.Current); DirectoryInfo2EntryOffset = Reader.BaseStream.Position; Reader.Seek(ItemCount * DirectoryInfo2Entry.Size, SeekOrigin.Current); DirectoryCopyEntryOffset = Reader.BaseStream.Position; Reader.Seek(CopyCount * DirectoryCopyEntry.Size, SeekOrigin.Current); DirectoryLocalEntryOffset = Reader.BaseStream.Position; Reader.Seek(LocalCount * DirectoryLocalEntry.Size, SeekOrigin.Current); { //DirectoryMapHeader //public uint Dummy0; //public uint Dummy1; Reader.Seek(8, SeekOrigin.Current); } DirectoryMapEntryOffset = Reader.BaseStream.Position; Reader.Seek(ItemCount * 4, SeekOrigin.Current); { //ChecksumHeader ChecksumMapHeader if (Reader.ReadUInt32() != 0x00000001) // HeaderVersion Always 0x00000001 { throw new InvalidDataException(); } ChecksumSize = Reader.ReadUInt32(); // Size of LPGCFCHECKSUMHEADER & LPGCFCHECKSUMMAPHEADER & in bytes. if (Reader.ReadUInt32() != 0x14893721) // FormatCode Always 0x14893721 { throw new InvalidDataException(); } if (Reader.ReadUInt32() != 0x00000001) // Dummy0 Always 0x00000001 { throw new InvalidDataException(); } ChecksumItemCount = Reader.ReadUInt32(); // Number of file ID entries. ChecksumCount = Reader.ReadUInt32(); // Number of checksums. } ChecksumMapEntryOffset = Reader.BaseStream.Position; Reader.Seek(ChecksumItemCount * ChecksumMapEntry.Size, SeekOrigin.Current); ChecksumEntryOffset = Reader.BaseStream.Position; Reader.Seek(ChecksumCount * 4, SeekOrigin.Current); //Skip past signature Reader.Seek(0x80, SeekOrigin.Current); if (Reader.ReadUInt32() != LastVersionPlayed) // LastVersionPlayed { throw new InvalidDataException("LastVersionPlayed mismatch."); } { //DataHeader uint checksum = 0; uint sectorCount, sectorSize; checksum += (sectorCount = Reader.ReadUInt32()); // Number of data blocks. if (SectorCount != sectorCount) { throw new InvalidDataException(); } checksum += (sectorSize = Reader.ReadUInt32()); // Size of each data block in bytes. if (SectorSize != sectorSize) { throw new InvalidDataException(); } checksum += (FirstSectorOffset = Reader.ReadUInt32()); // Offset to first data block. checksum += (SectorsUsed = Reader.ReadUInt32()); // Number of data blocks that contain data. if (checksum != Reader.ReadUInt32()) //public uint Checksum; // Header checksum. { throw new InvalidDataException(); } } for (uint index = 0; index < ItemCount; ++index) { DirectoryEntry entry = GetDirectoryEntry(index); if (entry.ParentIndex == 0xFFFFFFFF) { RootDirectory = new GcfDirectoryInfo(this, index); break; } } }