public override void EraseFileSystemObject(StreamInfo info, ErasureMethod method, ErasureMethodProgressFunction callback) { VolumeInfo volume = VolumeInfo.FromMountpoint(info.DirectoryName); if (info.Length < Math.Max(volume.ClusterSize, 1024)) { using (FileStream strm = info.Open(FileMode.Open, FileAccess.Write, FileShare.None)) { method.Erase(strm, long.MaxValue, PrngManager.GetInstance(ManagerLibrary.Settings.ActivePrng), null); } } long fileArea = GetFileArea(info.FullName); if (fileArea == 0) return; using (FileStream strm = info.Open(FileMode.Open, FileAccess.Write, FileShare.None, FileOptions.WriteThrough)) { strm.SetLength(fileArea); method.Erase(strm, long.MaxValue, PrngManager.GetInstance(ManagerLibrary.Settings.ActivePrng), callback ); strm.Seek(0, SeekOrigin.Begin); strm.SetLength(0); } }
public override long GetFileArea(string filePath) { StreamInfo info = new StreamInfo(filePath); VolumeInfo volume = VolumeInfo.FromMountPoint(info.Directory.FullName); long clusterSize = volume.ClusterSize; return (info.Length + (clusterSize - 1)) & ~(clusterSize - 1); }
public override void EraseClusterTips(VolumeInfo info, ErasureMethod method, ClusterTipsSearchProgress searchCallback, ClusterTipsEraseProgress eraseCallback) { List<string> files = new List<string>(); if (!info.IsMounted) throw new InvalidOperationException(S._("Could not erase cluster tips in {0} " + "as the volume is not mounted.", info.VolumeId)); ListFiles(new DirectoryInfo(info.MountPoints[0]), files, searchCallback); for (int i = 0, j = files.Count; i != j; ++i) { StreamInfo streamInfo = new StreamInfo(files[i]); FileAttributes fileAttr = streamInfo.Attributes; try { streamInfo.Attributes = FileAttributes.Normal; EraseFileClusterTips(files[i], method); } catch (UnauthorizedAccessException) { Logger.Log(S._("{0} did not have its cluster tips erased because you do not " + "have the required permissions to erase the file cluster tips.", files[i]), LogLevel.Information); } catch (IOException e) { Logger.Log(S._("{0} did not have its cluster tips erased. The error returned " + "was: {1}", files[i], e.Message), LogLevel.Error); } finally { streamInfo.Attributes = fileAttr; } eraseCallback(i, files.Count, files[i]); } }
public static IList<string> GetADSes(FileInfo info) { List<string> result = new List<string>(); using (FileStream stream = new StreamInfo(info.FullName).Open(FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) using (SafeFileHandle streamHandle = stream.SafeFileHandle) { NativeMethods.FILE_STREAM_INFORMATION[] streams = GetADSes(streamHandle); foreach (NativeMethods.FILE_STREAM_INFORMATION streamInfo in streams) { string streamName = streamInfo.StreamName.Substring(1, streamInfo.StreamName.LastIndexOf(':') - 1); if (streamName.Length != 0) result.Add(streamName); } } return result.AsReadOnly(); }
private void EraseFileClusterTips(string file, ErasureMethod method) { StreamInfo streamInfo = new StreamInfo(file); DateTime lastAccess = streamInfo.LastAccessTime; DateTime lastWrite = streamInfo.LastWriteTime; DateTime created = streamInfo.CreationTime; long fileArea = GetFileArea(file); long fileLength = streamInfo.Length; if (fileArea == fileLength) return; using (FileStream stream = streamInfo.Open(FileMode.Open, FileAccess.Write, FileShare.None, FileOptions.WriteThrough)) { try { stream.SetLength(fileArea); stream.Seek(fileLength, SeekOrigin.Begin); method.Erase(stream, long.MaxValue, PrngManager.GetInstance( ManagerLibrary.Settings.ActivePrng), null); } finally { stream.SetLength(fileLength); streamInfo.LastAccessTime = lastAccess; streamInfo.LastWriteTime = lastWrite; streamInfo.CreationTime = created; } } }
private void EraseFilesystemObject(Task task, FileSystemObjectTarget target) { long dataTotal = 0; List<string> paths = target.GetPaths(out dataTotal); ErasureMethod method = target.Method; TaskEventArgs eventArgs = new TaskEventArgs(task); SteppedProgressManager progress = new SteppedProgressManager(); target.Progress = progress; task.Progress.Steps.Add(new SteppedProgressManager.Step(progress, 1.0f / task.Targets.Count)); for (int i = 0; i < paths.Count; ++i) { ProgressManager step = new ProgressManager(); progress.Steps.Add(new SteppedProgressManager.Step(step, 1.0f / paths.Count, S._("Erasing files..."))); task.OnProgressChanged(target, new ProgressChangedEventArgs(step, new TaskProgressChangedEventArgs(paths[i], 0, method.Passes))); StreamInfo info = new StreamInfo(paths[i]); FileSystem fsManager = FileSystemManager.Get( VolumeInfo.FromMountpoint(info.DirectoryName)); if (!info.Exists) { task.Log.LastSessionEntries.Add(new LogEntry(S._("The file {0} was not erased " + "as the file does not exist.", paths[i]), LogLevel.Notice)); continue; } bool isReadOnly = false; try { if (isReadOnly = info.IsReadOnly) info.IsReadOnly = false; if ((info.Attributes & FileAttributes.Compressed) != 0 || (info.Attributes & FileAttributes.Encrypted) != 0 || (info.Attributes & FileAttributes.SparseFile) != 0) { task.Log.LastSessionEntries.Add(new LogEntry(S._("The file {0} could " + "not be erased because the file was either compressed, encrypted or " + "a sparse file.", info.FullName), LogLevel.Error)); } fsManager.EraseFileSystemObject(info, method, delegate(long lastWritten, long totalData, int currentPass) { if (currentTask.Canceled) throw new OperationCanceledException(S._("The task was cancelled.")); step.Completed += lastWritten; step.Total = totalData; task.OnProgressChanged(target, new ProgressChangedEventArgs(step, new TaskProgressChangedEventArgs(info.FullName, currentPass, method.Passes))); }); FileInfo fileInfo = info.File; if (fileInfo != null) fsManager.DeleteFile(fileInfo); step.Completed = step.Total = 1; } catch (UnauthorizedAccessException) { task.Log.LastSessionEntries.Add(new LogEntry(S._("The file {0} could not " + "be erased because the file's permissions prevent access to the file.", info.FullName), LogLevel.Error)); } catch (FileLoadException) { if (!ManagerLibrary.Settings.ForceUnlockLockedFiles) throw; List<System.Diagnostics.Process> processes = new List<System.Diagnostics.Process>(); foreach (OpenHandle handle in OpenHandle.Items) if (handle.Path == paths[i]) processes.Add(System.Diagnostics.Process.GetProcessById(handle.ProcessId)); StringBuilder processStr = new StringBuilder(); foreach (System.Diagnostics.Process process in processes) processStr.AppendFormat(System.Globalization.CultureInfo.InvariantCulture, "{0}, ", process.MainModule.FileName); task.Log.LastSessionEntries.Add(new LogEntry(S._( "Could not force closure of file \"{0}\" (locked by {1})", paths[i], processStr.ToString().Remove(processStr.Length - 2)), LogLevel.Error)); } finally { if (isReadOnly && info.Exists && !info.IsReadOnly) info.IsReadOnly = isReadOnly; } } if (target is FolderTarget) { ProgressManager step = new ProgressManager(); progress.Steps.Add(new SteppedProgressManager.Step(step, 0.0f, S._("Removing folders..."))); FolderTarget fldr = (FolderTarget)target; FileSystem fsManager = FileSystemManager.Get(VolumeInfo.FromMountpoint(fldr.Path)); Action<DirectoryInfo> eraseEmptySubFolders = null; eraseEmptySubFolders = delegate(DirectoryInfo info) { foreach (DirectoryInfo subDir in info.GetDirectories()) eraseEmptySubFolders(subDir); task.OnProgressChanged(target, new ProgressChangedEventArgs(step, new TaskProgressChangedEventArgs(info.FullName, 0, 0))); FileSystemInfo[] files = info.GetFileSystemInfos(); if (files.Length == 0) fsManager.DeleteFolder(info); }; eraseEmptySubFolders(new DirectoryInfo(fldr.Path)); if (fldr.DeleteIfEmpty) { DirectoryInfo info = new DirectoryInfo(fldr.Path); task.OnProgressChanged(target, new ProgressChangedEventArgs(step, new TaskProgressChangedEventArgs(info.FullName, 0, 0))); bool isVolumeRoot = info.Parent == null; foreach (VolumeInfo volume in VolumeInfo.Volumes) foreach (string mountPoint in volume.MountPoints) if (info.FullName == mountPoint) isVolumeRoot = true; if (!isVolumeRoot && info.Exists && info.GetFiles("*", SearchOption.AllDirectories).Length == 0) fsManager.DeleteFolder(info); } } if (target is RecycleBinTarget) { ProgressManager step = new ProgressManager(); progress.Steps.Add(new SteppedProgressManager.Step(step, 0.0f, S._("Emptying recycle bin..."))); task.OnProgressChanged(target, new ProgressChangedEventArgs(step, new TaskProgressChangedEventArgs(string.Empty, 0, 0))); ShellApi.EmptyRecycleBin(EmptyRecycleBinOptions.NoConfirmation | EmptyRecycleBinOptions.NoProgressUI | EmptyRecycleBinOptions.NoSound); } target.Progress = null; }
public abstract void EraseFileSystemObject(StreamInfo info, ErasureMethod method, ErasureMethodProgressFunction callback);
public override void EraseFileSystemObject(StreamInfo info, ErasureMethod method, ErasureMethodProgressFunction callback) { long fileArea = GetFileArea(info.FullName); using (FileStream strm = info.Open(FileMode.Open, FileAccess.Write, FileShare.None, FileOptions.WriteThrough)) { strm.SetLength(fileArea); if (strm.Length != 0) { method.Erase(strm, long.MaxValue, PrngManager.GetInstance(ManagerLibrary.Settings.ActivePrng), callback ); } strm.Seek(0, SeekOrigin.Begin); strm.SetLength(0); } }