コード例 #1
0
        public Result Read(out long entriesRead, Span <DirectoryEntry> entryBuffer)
        {
            if (!Mode.HasFlag(OpenDirectoryMode.File))
            {
                entriesRead = 0;
                return(Result.Success);
            }

            int entriesRemaining = ParentFileSystem.Files.Length - CurrentIndex;
            int toRead           = Math.Min(entriesRemaining, entryBuffer.Length);

            for (int i = 0; i < toRead; i++)
            {
                PartitionFileEntry fileEntry = ParentFileSystem.Files[CurrentIndex];
                ref DirectoryEntry entry     = ref entryBuffer[i];

                Span <byte> nameUtf8 = Encoding.UTF8.GetBytes(fileEntry.Name);

                entry.Type = DirectoryEntryType.File;
                entry.Size = fileEntry.Size;

                StringUtils.Copy(entry.Name, nameUtf8);
                entry.Name[PathTools.MaxPathLength] = 0;

                CurrentIndex++;
            }
コード例 #2
0
        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);
        }
コード例 #3
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:
                ThrowHelper.ThrowResult(ResultFs.InvalidPartitionFileSystemMagic, $"Invalid Partition FS type \"{Magic}\"");
                break;
            }

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