protected BlockGroupDescriptor GetGroupDescriptor(UInt32 block_group_id) { Byte[] block = new Byte[BlockSize]; const uint gd_entry_size = 32; Int64 containing_block_id = block_group_id / (BlockSize / gd_entry_size); block_group_id = block_group_id % (BlockSize / gd_entry_size); if (BlockSize == 1024) { ReadBlock(block, 2 + containing_block_id); } else { ReadBlock(block, 1 + containing_block_id); } BlockGroupDescriptor descriptor = new BlockGroupDescriptor(); Utils.LoadLE32(out descriptor.block_bitmap_id, block, block_group_id * gd_entry_size + 0); Utils.LoadLE32(out descriptor.inode_bitmap_id, block, block_group_id * gd_entry_size + 4); Utils.LoadLE32(out descriptor.inode_table_id, block, block_group_id * gd_entry_size + 8); Utils.LoadLE16(out descriptor.free_blocks_count, block, block_group_id * gd_entry_size + 12); Utils.LoadLE16(out descriptor.free_inodes_count, block, block_group_id * gd_entry_size + 14); Utils.LoadLE16(out descriptor.dir_count, block, block_group_id * gd_entry_size + 16); return(descriptor); }
/// <summary> /// The ProcessRecord method instantiates a Superblock object based /// on the disk given as an argument. /// </summary> protected override void ProcessRecord() { #region MBR MasterBootRecord mbr = MasterBootRecord.Get(devicePath); uint superblockOffset = 0; foreach (PartitionEntry partition in mbr.PartitionTable) { if (partition.Bootable && partition.SystemID == "LINUX") { superblockOffset = partition.StartSector; } } #endregion MBR // Obtain a handle to the device named "devicePath" IntPtr hDevice = NativeMethods.getHandle(devicePath); using (FileStream streamToRead = NativeMethods.getFileStream(hDevice)) { // Get Superblock to understand File System Layout Superblock superBlock = new Superblock(Superblock.GetBytes(streamToRead, superblockOffset)); if (this.MyInvocation.BoundParameters.ContainsKey("GroupNumber")) { if (asbytes) { WriteObject(BlockGroupDescriptor.GetBytes(streamToRead, superblockOffset, superBlock, number)); } else { WriteObject(new BlockGroupDescriptor(BlockGroupDescriptor.GetBytes(streamToRead, superblockOffset, superBlock, number))); } } else { if (asbytes) { BlockGroupDescriptorTable.GetBytes(streamToRead, superblockOffset, superBlock); } else { byte[] bgdtBytes = BlockGroupDescriptorTable.GetBytes(streamToRead, superblockOffset, superBlock); for (uint o = 0; o < bgdtBytes.Length; o += BlockGroupDescriptor.BLOCK_GROUP_DESCRIPTOR_LENGTH) { WriteObject(new BlockGroupDescriptor(NativeMethods.GetSubArray(bgdtBytes, o, BlockGroupDescriptor.BLOCK_GROUP_DESCRIPTOR_LENGTH))); } } } } }
public INode GetINode(UInt32 inode_number) { INode inode = new INode(); inode.inode = inode_number; inode_number--; BlockGroupDescriptor block_group_descriptor = bg_descriptors[(int)(inode_number / inodes_per_group)]; Byte[] block = new Byte[BlockSize]; uint inodes_per_block = BlockSize / inode_size; uint inode_number_in_bg = inode_number % inodes_per_group; uint inode_block_index = inode_number_in_bg / inodes_per_block; uint inode_offset = (inode_number_in_bg % inodes_per_block) * inode_size; ReadBlock(block, block_group_descriptor.inode_table_id + inode_block_index); Utils.LoadLE16(out inode.mode, block, inode_offset + 0); Utils.LoadLE16(out inode.uid, block, inode_offset + 2); Utils.LoadLE32To64(out inode.size, block, inode_offset + 108); // top 32 bits inode.size *= 0x100000000; // << 32 UInt32 temp; Utils.LoadLE32(out temp, block, inode_offset + 4); // bottom 32 bits inode.size += temp; Utils.LoadLE32(out inode.atime, block, inode_offset + 8); Utils.LoadLE32(out inode.ctime, block, inode_offset + 12); Utils.LoadLE32(out inode.mtime, block, inode_offset + 16); Utils.LoadLE32(out inode.dtime, block, inode_offset + 20); Utils.LoadLE16(out inode.gid, block, inode_offset + 24); Utils.LoadLE16(out inode.link_count, block, inode_offset + 26); Utils.LoadLE32To64(out inode.sector_count, block, inode_offset + 28); Utils.LoadLE32(out inode.flags, block, inode_offset + 32); for (UInt32 i = 0; i < inode.block.Length; i++) { Utils.LoadLE32(out inode.block[i], block, inode_offset + 40 + i * 4); } Utils.LoadLE32(out inode.file_acl, block, inode_offset + 104); return(inode); }
/// <summary> /// /// </summary> protected override void ProcessRecord() { #region MBR MasterBootRecord mbr = MasterBootRecord.Get(devicePath); uint superblockOffset = 0; foreach (PartitionEntry partition in mbr.PartitionTable) { if (partition.Bootable && partition.SystemID == "LINUX") { superblockOffset = partition.StartSector; } } #endregion MBR // Obtain a handle to the device named "devicePath" IntPtr hDevice = NativeMethods.getHandle(devicePath); using (FileStream streamToRead = NativeMethods.getFileStream(hDevice)) { // Get Superblock to understand File System Layout Superblock superBlock = new Superblock(Superblock.GetBytes(streamToRead, superblockOffset)); if (this.MyInvocation.BoundParameters.ContainsKey("Inode")) { if (inode == 0) { throw new Exception("0 is not a valid Inode value."); } else { uint block_group = (inode - 1) / superBlock.InodesPerGroup; BlockGroupDescriptor bgd = new BlockGroupDescriptor(BlockGroupDescriptorTable.GetBytes(streamToRead, superblockOffset, superBlock)); uint inodeTableOffset = (superblockOffset * NativeMethods.BYTES_PER_SECTOR) + (bgd.InodeTableOffset * superBlock.BlockSize); uint inodeSectorOffset = (inode - 1) / (NativeMethods.BYTES_PER_SECTOR / (uint)superBlock.InodeSize); byte[] SectorBytes = NativeMethods.readDrive(streamToRead, inodeTableOffset + (inodeSectorOffset * NativeMethods.BYTES_PER_SECTOR), NativeMethods.BYTES_PER_SECTOR); uint sectorOffset = ((inode - 1) % (NativeMethods.BYTES_PER_SECTOR / (uint)superBlock.InodeSize)) * (uint)superBlock.InodeSize; byte[] inodeBytes = NativeMethods.GetSubArray(SectorBytes, sectorOffset, (uint)superBlock.InodeSize); if (asbytes) { WriteObject(inodeBytes); } else { WriteObject(new Inode(inodeBytes, inode)); } } } else { // Create a byte array representing the BGDT byte[] bgdtBytes = BlockGroupDescriptorTable.GetBytes(streamToRead, superblockOffset, superBlock); // Iterate through BGDTs and output associate Inodes for (uint o = 0; o < bgdtBytes.Length; o += BlockGroupDescriptor.BLOCK_GROUP_DESCRIPTOR_LENGTH) { BlockGroupDescriptor bgd = new BlockGroupDescriptor(NativeMethods.GetSubArray(bgdtBytes, o, BlockGroupDescriptor.BLOCK_GROUP_DESCRIPTOR_LENGTH)); uint inodeTableOffset = (superblockOffset * NativeMethods.BYTES_PER_SECTOR) + (bgd.InodeTableOffset * superBlock.BlockSize); byte[] inodeTableBytes = InodeTable.GetBytes(streamToRead, superBlock, inodeTableOffset); for (uint i = 0; i < inodeTableBytes.Length; i += (uint)superBlock.InodeSize) { uint inode = ((o / BlockGroupDescriptor.BLOCK_GROUP_DESCRIPTOR_LENGTH) + 1) * ((i / (uint)superBlock.InodeSize) + 1); WriteObject(new Inode(NativeMethods.GetSubArray(inodeTableBytes, i, superBlock.InodeSize), inode)); } } } } }
protected BlockGroupDescriptor GetGroupDescriptor( UInt32 block_group_id ) { Byte[] block = new Byte[ BlockSize ]; const uint gd_entry_size = 32; Int64 containing_block_id = block_group_id / ( BlockSize / gd_entry_size ); block_group_id = block_group_id % ( BlockSize / gd_entry_size ); if ( BlockSize == 1024 ) { ReadBlock( block, 2 + containing_block_id ); } else { ReadBlock( block, 1 + containing_block_id ); } BlockGroupDescriptor descriptor = new BlockGroupDescriptor(); Utils.LoadLE32( out descriptor.block_bitmap_id, block, block_group_id * gd_entry_size + 0 ); Utils.LoadLE32( out descriptor.inode_bitmap_id, block, block_group_id * gd_entry_size + 4 ); Utils.LoadLE32( out descriptor.inode_table_id, block, block_group_id * gd_entry_size + 8 ); Utils.LoadLE16( out descriptor.free_blocks_count, block, block_group_id * gd_entry_size + 12 ); Utils.LoadLE16( out descriptor.free_inodes_count, block, block_group_id * gd_entry_size + 14 ); Utils.LoadLE16( out descriptor.dir_count, block, block_group_id * gd_entry_size + 16 ); return descriptor; }