public override void List(out List <File> files, out List <File> dirs) { files = new List <File>(); dirs = new List <File>(); this.files = files; this.dirs = dirs; Ext fs = (Ext)filesystem; if (Type == FileType.Directory) { Ext.INode inode = fs.GetINode(inode_number); Byte[] block = new Byte[fs.BlockSize]; if ((inode.flags & 0x80000) == 0) // old, indirect blocks { IndirectBlockIterator it = new IndirectBlockIterator(fs, inode.block); while (it.ReadNextBlock(block)) { AddFilesFromLinearBlock(block, files, dirs); // dir hash present: ( inode.flags & 0x1000 ) != 0 } } else // extents { ExtentBlockIterator it = new ExtentBlockIterator(fs, inode.block); while (it.ReadNextBlock(block)) { AddFilesFromLinearBlock(block, files, dirs); // dir hash present: ( inode.flags & 0x1000 ) != 0 } } } }
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 override void List( out List< File > files, out List< File > dirs ) { files = new List< File >(); dirs = new List< File >(); this.files = files; this.dirs = dirs; Ext fs = (Ext)filesystem; if ( Type == FileType.Directory ) { Ext.INode inode = fs.GetINode( inode_number ); Byte[] block = new Byte[ fs.BlockSize ]; if ( ( inode.flags & 0x80000 ) == 0 ) // old, indirect blocks { IndirectBlockIterator it = new IndirectBlockIterator( fs, inode.block ); while ( it.ReadNextBlock( block ) ) { AddFilesFromLinearBlock( block, files, dirs ); // dir hash present: ( inode.flags & 0x1000 ) != 0 } } else // extents { ExtentBlockIterator it = new ExtentBlockIterator( fs, inode.block ); while ( it.ReadNextBlock( block ) ) { AddFilesFromLinearBlock( block, files, dirs ); // dir hash present: ( inode.flags & 0x1000 ) != 0 } } } }
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(); } }