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