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);
        }
Beispiel #2
0
        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();
            }
        }
Beispiel #3
0
 public IFile OpenFile(PartitionFileEntry entry, OpenMode mode)
 {
     return(new PartitionFile(BaseStorage, HeaderSize + entry.Offset, entry.Size, mode));
 }