private byte[] BuildMetaData(PartitionFileSystemType type) { if (type == PartitionFileSystemType.Hashed) { CalculateHashes(); } int entryTableSize = Entries.Count * PartitionFileEntry.GetEntrySize(type); int stringTableSize = CalcStringTableSize(HeaderSize + entryTableSize, type); int metaDataSize = HeaderSize + entryTableSize + stringTableSize; var metaData = new byte[metaDataSize]; var writer = new BinaryWriter(new MemoryStream(metaData)); writer.WriteUTF8(GetMagicValue(type)); writer.Write(Entries.Count); writer.Write(stringTableSize); writer.Write(0); int stringOffset = 0; foreach (Entry entry in Entries) { writer.Write(entry.Offset); writer.Write(entry.Length); writer.Write(stringOffset); if (type == PartitionFileSystemType.Standard) { writer.Write(0); } else { writer.Write(entry.HashLength); writer.Write(entry.HashOffset); writer.Write(entry.Hash); } stringOffset += entry.NameLength + 1; } foreach (Entry entry in Entries) { writer.WriteUTF8Z(entry.Name); } return(metaData); }
public PartitionFileSystemHeader(BinaryReader reader) { Magic = reader.ReadAscii(4); NumFiles = reader.ReadInt32(); StringTableSize = reader.ReadInt32(); Reserved = reader.ReadInt32(); switch (Magic) { case "PFS0": Type = PartitionFileSystemType.Standard; break; case "HFS0": Type = PartitionFileSystemType.Hashed; break; default: throw new InvalidDataException($"Invalid Partition FS type \"{Magic}\""); } int entrySize = PartitionFileEntry.GetEntrySize(Type); int stringTableOffset = 16 + entrySize * NumFiles; HeaderSize = stringTableOffset + StringTableSize; Files = new PartitionFileEntry[NumFiles]; for (int i = 0; i < NumFiles; i++) { Files[i] = new PartitionFileEntry(reader, Type) { Index = i }; } for (int i = 0; i < NumFiles; i++) { reader.BaseStream.Position = stringTableOffset + Files[i].StringTableOffset; Files[i].Name = reader.ReadAsciiZ(); } }