public IndirectBlockIterator( Ext filesystem, UInt32[] direct_block ) { this.filesystem = filesystem; this.direct_block = direct_block; }
public ExtentBlockIterator( Ext filesystem, UInt32[] block ) { this.filesystem = filesystem; Byte[] raw_inode_blocks = new Byte[60]; Utils.LoadByteArrayFromUInt32Array( raw_inode_blocks, block, 15 ); ProcessBlock( raw_inode_blocks ); }
public IndirectBlockIterator(Ext filesystem, UInt32[] direct_block) { this.filesystem = filesystem; this.direct_block = direct_block; }
public override void Save(string path, BackgroundWorker worker) { List <File> files; List <File> dirs; if (worker != null) { worker.ReportProgress(0, path + "\\" + name); } List(out files, out dirs); if (type == FileType.Directory) { Directory.CreateDirectory(path + "\\" + name); foreach (File file in dirs) { file.Save(path + "\\" + name, worker); if (worker != null && worker.CancellationPending) { return; } } foreach (File file in files) { file.Save(path + "\\" + name, worker); if (worker != null && worker.CancellationPending) { return; } } if (worker != null) { worker.ReportProgress(100); } } else if (type == FileType.File || type == FileType.Link) { Ext fs = (Ext)filesystem; Ext.INode inode = fs.GetINode(inode_number); Byte[] block = new Byte[fs.BlockSize]; FileStream stream = new FileStream(path + "\\" + name, FileMode.Create); if (type == FileType.Link && inode.size < 60) // fast symlink { Byte[] raw_inode_blocks = new Byte[60]; Utils.LoadByteArrayFromUInt32Array(raw_inode_blocks, inode.block, 15); stream.Write(raw_inode_blocks, 0, (int)inode.size); } else // files, slow symlinks { Int64 size_remaining = inode.size; if ((inode.flags & 0x80000) == 0) // old, indirect blocks { IndirectBlockIterator it = new IndirectBlockIterator(fs, inode.block); while (it.ReadNextBlock(block)) { if (size_remaining < fs.BlockSize) { stream.Write(block, 0, (int)size_remaining); size_remaining = 0; } else { stream.Write(block, 0, (int)fs.BlockSize); size_remaining -= fs.BlockSize; } if (worker != null) { worker.ReportProgress(100 - (int)(100 * size_remaining / inode.size)); if (worker.CancellationPending) { stream.Close(); return; } } } } else // extents { ExtentBlockIterator it = new ExtentBlockIterator(fs, inode.block); while (it.ReadNextBlock(block)) { if (size_remaining < fs.BlockSize) { stream.Write(block, 0, (int)size_remaining); size_remaining = 0; } else { stream.Write(block, 0, (int)fs.BlockSize); size_remaining -= fs.BlockSize; } if (worker != null) { worker.ReportProgress(100 - (int)(100 * size_remaining / inode.size)); if (worker.CancellationPending) { stream.Close(); return; } } } } } stream.Close(); } }
public List<FileSystem> GetFileSystems() { List< FileSystem > filesystems = new List< FileSystem >(); if ( stream == null || !stream.CanRead ) return filesystems; Byte[] sector = new Byte[ sector_size ]; stream.Read( sector, 0, (int)sector_size ); if ( sector[ 510 ] != 0x55 || sector[ 511 ] != 0xaa ) return filesystems; // mbr magic number missing List< MBRPartitionEntry > mbr_partitions = new List< MBRPartitionEntry >(); MBRPartitionEntry current_partition; int partition_id = 0; for ( UInt32 i=0; i<4; i++ ) { current_partition = new MBRPartitionEntry(); current_partition.Parse( sector, 446 + i*16 ); if ( known_partition_types.Contains( current_partition.type ) ) // known { current_partition.id = partition_id; mbr_partitions.Add( current_partition ); ++partition_id; } else if ( current_partition.type == PartitionType.Extended ) // extended partition: contains others { Byte[] extended_sector = new Byte[ sector_size ]; MBRPartitionEntry extended_entry = new MBRPartitionEntry(); MBRPartitionEntry extended_next = new MBRPartitionEntry(); do { stream.Seek( ( ( Int64 ) current_partition.start_lba + ( Int64 ) extended_next.start_lba ) * ( Int64 ) sector_size, SeekOrigin.Begin ); stream.Read( extended_sector, 0, (int)sector_size ); extended_entry.Parse( extended_sector, 446 ); extended_entry.start_lba += current_partition.start_lba + extended_next.start_lba; extended_next.Parse( extended_sector, 446 + 16 ); if ( known_partition_types.Contains( extended_entry.type ) ) { extended_entry.id = partition_id; mbr_partitions.Add( extended_entry ); extended_entry = new MBRPartitionEntry(); } ++partition_id; } while ( extended_next.size_lba != 0 ); } else // unknown { ++partition_id; } } foreach ( MBRPartitionEntry mbr_entry in mbr_partitions ) { FileSystem fs = null; switch ( mbr_entry.type ) { case PartitionType.Ext: { FileSystem temp = null; try { temp = new Ext( this, mbr_entry ); fs = temp; } catch ( Exception ) {} break; } } if ( fs != null ) filesystems.Add( fs ); } return filesystems; }