internal static bool Detect(Stream stream) { if (stream.Length < 2048) { return(false); } stream.Position = 1024; byte[] superblockData = Utilities.ReadFully(stream, 1024); SuperBlock superblock = new SuperBlock(); superblock.ReadFrom(superblockData, 0); return(superblock.Magic == SuperBlock.Ext2Magic); }
public VfsExtFileSystem(Stream stream) : base(new DiscFileSystemOptions()) { stream.Position = 1024; byte[] superblockData = Utilities.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 }; uint numGroups = Utilities.Ceil(superblock.BlocksCount, superblock.BlocksPerGroup); long blockDescStart = (superblock.FirstDataBlock + 1) * (long)superblock.BlockSize; stream.Position = blockDescStart; byte[] blockDescData = Utilities.ReadFully(stream, (int)numGroups * BlockGroup.DescriptorSize); _blockGroups = new BlockGroup[numGroups]; for (int i = 0; i < numGroups; ++i) { BlockGroup bg = new BlockGroup(); bg.ReadFrom(blockDescData, i * BlockGroup.DescriptorSize); _blockGroups[i] = bg; } RootDirectory = new Directory(Context, 2, GetInode(2)); }
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 = Utilities.ReadFully(Context.RawStream, superBlock.InodeSize); return(Utilities.ToStruct <Inode>(inodeData, 0)); }