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)); }
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)); }