예제 #1
0
        private Inode GetInode(uint inodeNum)
        {
            uint index = inodeNum - 1;

            SuperBlock superBlock = Context.SuperBlock;

            uint       group           = index / superBlock.InodesPerGroup;
            uint       groupOffset     = index - group * superBlock.InodesPerGroup;
            BlockGroup inodeBlockGroup = GetBlockGroup(group);

            uint inodesPerBlock = superBlock.BlockSize / superBlock.InodeSize;
            uint block          = groupOffset / inodesPerBlock;
            uint blockOffset    = groupOffset - block * inodesPerBlock;

            Context.RawStream.Position = (inodeBlockGroup.InodeTableBlock + block) * (long)superBlock.BlockSize +
                                         blockOffset * superBlock.InodeSize;
            byte[] inodeData = StreamUtilities.ReadFully(Context.RawStream, superBlock.InodeSize);

            return(EndianUtilities.ToStruct <Inode>(inodeData, 0));
        }
예제 #2
0
        public VfsExtFileSystem(Stream stream, FileSystemParameters parameters)
            : base(new ExtFileSystemOptions(parameters))
        {
            stream.Position = 1024;
            byte[] superblockData = StreamUtilities.ReadFully(stream, 1024);

            SuperBlock superblock = new SuperBlock();

            superblock.ReadFrom(superblockData, 0);

            if (superblock.Magic != SuperBlock.Ext2Magic)
            {
                throw new IOException("Invalid superblock magic - probably not an Ext file system");
            }

            if (superblock.RevisionLevel == SuperBlock.OldRevision)
            {
                throw new IOException("Old ext revision - not supported");
            }

            if ((superblock.IncompatibleFeatures & ~SupportedIncompatibleFeatures) != 0)
            {
                throw new IOException("Incompatible ext features present: " +
                                      (superblock.IncompatibleFeatures & ~SupportedIncompatibleFeatures));
            }

            Context = new Context
            {
                RawStream  = stream,
                SuperBlock = superblock,
                Options    = (ExtFileSystemOptions)Options
            };

            uint numGroups      = MathUtilities.Ceil(superblock.BlocksCount, superblock.BlocksPerGroup);
            long blockDescStart = (superblock.FirstDataBlock + 1) * (long)superblock.BlockSize;

            stream.Position = blockDescStart;
            var bgDescSize = superblock.Has64Bit ? BlockGroup64.DescriptorSize64 : BlockGroup.DescriptorSize;

            byte[] blockDescData = StreamUtilities.ReadFully(stream, (int)numGroups * bgDescSize);

            _blockGroups = new BlockGroup[numGroups];
            for (int i = 0; i < numGroups; ++i)
            {
                BlockGroup bg = superblock.Has64Bit ? new BlockGroup64() : new BlockGroup();
                bg.ReadFrom(blockDescData, i * bgDescSize);
                _blockGroups[i] = bg;
            }

            var journalSuperBlock = new JournalSuperBlock();

            if (superblock.JournalInode != 0)
            {
                var journalInode      = GetInode(superblock.JournalInode);
                var journalDataStream = journalInode.GetContentBuffer(Context);
                var journalData       = StreamUtilities.ReadFully(journalDataStream, 0, 1024 + 12);
                journalSuperBlock.ReadFrom(journalData, 0);
                Context.JournalSuperblock = journalSuperBlock;
            }

            RootDirectory = new Directory(Context, 2, GetInode(2));
        }