public PfsHeader(BinaryReader reader) { Magic = reader.ReadAscii(4); NumFiles = reader.ReadInt32(); StringTableSize = reader.ReadInt32(); Reserved = reader.ReadInt32(); switch (Magic) { case "PFS0": Type = PfsType.Pfs0; break; case "HFS0": Type = PfsType.Hfs0; break; default: throw new InvalidDataException($"Invalid Partition FS type \"{Magic}\""); } int entrysize = GetFileEntrySize(Type); int stringTableOffset = 16 + entrysize * NumFiles; HeaderSize = stringTableOffset + StringTableSize; Files = new PfsFileEntry[NumFiles]; for (int i = 0; i < NumFiles; i++) { Files[i] = new PfsFileEntry(reader, Type) { Index = i }; } for (int i = 0; i < NumFiles; i++) { reader.BaseStream.Position = stringTableOffset + Files[i].StringTableOffset; Files[i].Name = reader.ReadAsciiZ(); } if (Type == PfsType.Hfs0) { for (int i = 0; i < NumFiles; i++) { reader.BaseStream.Position = HeaderSize + Files[i].Offset; Files[i].HashValidity = Crypto.CheckMemoryHashTable(reader.ReadBytes(Files[i].HashedRegionSize), Files[i].Hash, 0, Files[i].HashedRegionSize); } } }
private static int GetFileEntrySize(PfsType type) { switch (type) { case PfsType.Pfs0: return(24); case PfsType.Hfs0: return(0x40); default: throw new ArgumentOutOfRangeException(nameof(type), type, null); } }
public PfsFileEntry(BinaryReader reader, PfsType type) { Offset = reader.ReadInt64(); Size = reader.ReadInt64(); StringTableOffset = reader.ReadUInt32(); if (type == PfsType.Hfs0) { HashedRegionSize = reader.ReadInt32(); Reserved = reader.ReadInt64(); Hash = reader.ReadBytes(Crypto.Sha256DigestSize); } else { Reserved = reader.ReadUInt32(); } }