Example #1
0
 private void EraseUnusedSpace(Task task, UnusedSpaceTarget target)
 {
     if (!Security.IsAdministrator())
        {
     if (Environment.OSVersion.Platform == PlatformID.Win32NT &&
      Environment.OSVersion.Version >= new Version(6, 0))
     {
      throw new UnauthorizedAccessException(S._("The program does not have the " +
       "required permissions to erase the unused space on disk. Run the program " +
       "as an administrator and retry the operation."));
     }
     else
      throw new UnauthorizedAccessException(S._("The program does not have the " +
       "required permissions to erase the unused space on disk."));
        }
        if (SystemRestore.GetInstances().Count != 0)
        {
     task.Log.LastSessionEntries.Add(new LogEntry(S._("The drive {0} has System " +
      "Restore or Volume Shadow Copies enabled. This may allow copies of files " +
      "stored on the disk to be recovered and pose a security concern.",
      target.Drive), LogLevel.Warning));
        }
        if (VolumeInfo.FromMountPoint(target.Drive).HasQuota)
     task.Log.LastSessionEntries.Add(new LogEntry(S._("The drive {0} has disk quotas " +
      "active. This will prevent the complete erasure of unused space and may pose " +
      "a security concern.", target.Drive), LogLevel.Warning));
        ErasureMethod method = target.Method;
        DirectoryInfo info = new DirectoryInfo(target.Drive);
        VolumeInfo volInfo = VolumeInfo.FromMountPoint(target.Drive);
        FileSystem fsManager = FileSystemManager.Get(volInfo);
        SteppedProgressManager progress = new SteppedProgressManager();
        target.Progress = progress;
        task.Progress.Steps.Add(new SteppedProgressManagerStep(
     progress, 1.0f / task.Targets.Count));
        if (target.EraseClusterTips)
        {
     ProgressManager tipSearch = new ProgressManager();
     progress.Steps.Add(new SteppedProgressManagerStep(tipSearch,
      0.0f, S._("Searching for files' cluster tips...")));
     tipSearch.Total = 1;
     ClusterTipsSearchProgress searchProgress = delegate(string path)
      {
       if (currentTask.Canceled)
        throw new OperationCanceledException(S._("The task was cancelled."));
       task.OnProgressChanged(target,
        new ProgressChangedEventArgs(tipSearch,
     new TaskProgressChangedEventArgs(path, 0, 0)));
      };
     ProgressManager tipProgress = new ProgressManager();
     progress.Steps.Add(new SteppedProgressManagerStep(tipProgress, 0.1f,
      S._("Erasing cluster tips...")));
     ClusterTipsEraseProgress eraseProgress =
      delegate(int currentFile, int totalFiles, string currentFilePath)
      {
       tipSearch.MarkComplete();
       tipProgress.Total = totalFiles;
       tipProgress.Completed = currentFile;
       task.OnProgressChanged(target,
        new ProgressChangedEventArgs(tipProgress,
     new TaskProgressChangedEventArgs(currentFilePath, 0, 0)));
       if (currentTask.Canceled)
        throw new OperationCanceledException(S._("The task was cancelled."));
      };
     fsManager.EraseClusterTips(VolumeInfo.FromMountPoint(target.Drive),
      method, task.Log, searchProgress, eraseProgress);
        }
        info = info.CreateSubdirectory(Path.GetFileName(
     FileSystem.GenerateRandomFileName(info, 18)));
        try
        {
     if (info.IsCompressed())
      info.Uncompress();
     ProgressManager mainProgress = new ProgressManager();
     progress.Steps.Add(new SteppedProgressManagerStep(mainProgress,
      target.EraseClusterTips ? 0.8f : 0.9f, S._("Erasing unused space...")));
     while (volInfo.AvailableFreeSpace > 0)
     {
      string currFile = FileSystem.GenerateRandomFileName(info, 18);
      using (FileStream stream = new FileStream(currFile, FileMode.CreateNew,
       FileAccess.Write, FileShare.None, 8, FileOptions.WriteThrough))
      {
       mainProgress.Total = mainProgress.Completed +
        method.CalculateEraseDataSize(null, volInfo.AvailableFreeSpace);
       long streamLength = Math.Min(ErasureMethod.FreeSpaceFileUnit,
        mainProgress.Total);
       while (true)
        try
        {
     stream.SetLength(streamLength);
     break;
        }
        catch (IOException)
        {
     if (streamLength > volInfo.ClusterSize)
      streamLength -= volInfo.ClusterSize;
     else
      throw;
        }
       method.Erase(stream, long.MaxValue,
        PrngManager.GetInstance(ManagerLibrary.Settings.ActivePrng),
        delegate(long lastWritten, long totalData, int currentPass)
        {
     mainProgress.Completed += lastWritten;
     task.OnProgressChanged(target,
      new ProgressChangedEventArgs(mainProgress,
       new TaskProgressChangedEventArgs(target.Drive, currentPass, method.Passes)));
     if (currentTask.Canceled)
      throw new OperationCanceledException(S._("The task was cancelled."));
        }
       );
      }
     }
     mainProgress.MarkComplete();
     ProgressManager residentProgress = new ProgressManager();
     progress.Steps.Add(new SteppedProgressManagerStep(residentProgress,
      0.05f, S._("Old resident file system table files")));
     fsManager.EraseOldFileSystemResidentFiles(volInfo, info, method,
      delegate(int currentFile, int totalFiles)
      {
       residentProgress.Completed = currentFile;
       residentProgress.Total = totalFiles;
       task.OnProgressChanged(target,
        new ProgressChangedEventArgs(residentProgress,
     new TaskProgressChangedEventArgs(string.Empty, 0, 0)));
       if (currentTask.Canceled)
        throw new OperationCanceledException(S._("The task was cancelled."));
      }
     );
     residentProgress.MarkComplete();
        }
        finally
        {
     ProgressManager tempFiles = new ProgressManager();
     progress.Steps.Add(new SteppedProgressManagerStep(tempFiles,
      0.0f, S._("Removing temporary files...")));
     task.OnProgressChanged(target, new ProgressChangedEventArgs(tempFiles,
      new TaskProgressChangedEventArgs(string.Empty, 0, 0)));
     fsManager.DeleteFolder(info);
     tempFiles.Completed = tempFiles.Total;
        }
        ProgressManager structureProgress = new ProgressManager();
        progress.Steps.Add(new SteppedProgressManagerStep(structureProgress,
     0.05f, S._("Erasing unused directory structures...")));
        fsManager.EraseDirectoryStructures(volInfo,
     delegate(int currentFile, int totalFiles)
     {
      if (currentTask.Canceled)
       throw new OperationCanceledException(S._("The task was cancelled."));
      structureProgress.Total = totalFiles;
      structureProgress.Completed = currentFile;
      task.OnProgressChanged(target,
       new ProgressChangedEventArgs(structureProgress,
        new TaskProgressChangedEventArgs(string.Empty, 0, 0)));
     }
        );
        structureProgress.MarkComplete();
        target.Progress = null;
 }