Esempio n. 1
0
 protected override bool ResolveParameter(string param)
 {
     int equalPos = param.IndexOf('=');
     if (IsParam(param, "method", "m"))
     {
      if (equalPos == -1)
       throw new ArgumentException("--method must be specified with an Erasure " +
        "method GUID.");
      List<KeyValuePair<string, string> > subParams =
       GetSubParameters(param.Substring(equalPos + 1));
      ErasureMethod = new Guid(subParams[0].Key);
     }
     else if (IsParam(param, "schedule", "s"))
     {
      if (equalPos == -1)
       throw new ArgumentException("--schedule must be specified with a Schedule " +
        "type.");
      List<KeyValuePair<string, string> > subParams =
       GetSubParameters(param.Substring(equalPos + 1));
      switch (subParams[0].Key)
      {
       case "now":
        Schedule = Schedule.RunNow;
        break;
       case "manually":
        Schedule = Schedule.RunManually;
        break;
       case "restart":
        Schedule = Schedule.RunOnRestart;
        break;
       default:
        throw new ArgumentException("Unknown schedule type: " + subParams[0].Key);
      }
     }
     else if (IsParam(param, "recycled", "r"))
     {
      Targets.Add(new RecycleBinTarget());
     }
     else if (IsParam(param, "unused", "u"))
     {
      if (equalPos == -1)
       throw new ArgumentException("--unused must be specified with the Volume " +
        "to erase.");
      UnusedSpaceTarget target = new UnusedSpaceTarget();
      target.EraseClusterTips = false;
      List<KeyValuePair<string, string> > subParams =
       GetSubParameters(param.Substring(equalPos + 1));
      foreach (KeyValuePair<string, string> kvp in subParams)
       if (kvp.Value == null && target.Drive == null)
        target.Drive = Path.GetFullPath(kvp.Key);
       else if (kvp.Key == "clusterTips")
        target.EraseClusterTips = true;
       else
        throw new ArgumentException("Unknown subparameter: " + kvp.Key);
      Targets.Add(target);
     }
     else if (IsParam(param, "dir", "d") || IsParam(param, "directory", null))
     {
      if (equalPos == -1)
       throw new ArgumentException("--directory must be specified with the " +
        "directory to erase.");
      FolderTarget target = new FolderTarget();
      List<KeyValuePair<string, string> > subParams =
       GetSubParameters(param.Substring(equalPos + 1));
      foreach (KeyValuePair<string, string> kvp in subParams)
       if (kvp.Value == null && target.Path == null)
        target.Path = Path.GetFullPath(kvp.Key);
       else if (kvp.Key == "excludeMask")
       {
        if (kvp.Value == null)
     throw new ArgumentException("The exclude mask must be specified " +
      "if the excludeMask subparameter is specified");
        target.ExcludeMask = kvp.Value;
       }
       else if (kvp.Key == "includeMask")
       {
        if (kvp.Value == null)
     throw new ArgumentException("The include mask must be specified " +
      "if the includeMask subparameter is specified");
        target.IncludeMask = kvp.Value;
       }
       else if (kvp.Key == "delete")
        target.DeleteIfEmpty = true;
       else
        throw new ArgumentException("Unknown subparameter: " + kvp.Key);
      Targets.Add(target);
     }
     else if (IsParam(param, "file", "f"))
     {
      if (equalPos == -1)
       throw new ArgumentException("--file must be specified with the " +
        "file to erase.");
      FileTarget target = new FileTarget();
      List<KeyValuePair<string, string> > subParams =
       GetSubParameters(param.Substring(equalPos + 1));
      foreach (KeyValuePair<string, string> kvp in subParams)
       if (kvp.Value == null && target.Path == null)
        target.Path = Path.GetFullPath(kvp.Key);
       else
        throw new ArgumentException("Unknown subparameter: " + kvp.Key);
      Targets.Add(target);
     }
     else
      return false;
     return true;
 }
Esempio n. 2
0
 private void EraseUnusedSpace(Task task, UnusedSpaceTarget target, TaskProgressManager progress)
 {
     if (!AdvApi.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 (VolumeInfo.FromMountpoint(target.Drive).HasQuota)
     task.Log.LastSessionEntries.Add(new LogEntry(S._("The drive which is having its " +
      "unused space erased has disk quotas active. This will prevent the complete " +
      "erasure of unused space and will pose a security concern"), LogLevel.Warning));
        ErasureMethod method = target.Method;
        DirectoryInfo info = new DirectoryInfo(target.Drive);
        VolumeInfo volInfo = VolumeInfo.FromMountpoint(target.Drive);
        FileSystem fsManager = FileSystemManager.Get(volInfo);
        if (target.EraseClusterTips)
        {
     progress.Event.CurrentTargetStatus = S._("Searching for files' cluster tips...");
     progress.Event.CurrentTargetTotalPasses = method.Passes;
     progress.Event.CurrentItemProgress = -1.0f;
     progress.Event.TimeLeft = new TimeSpan(0, 0, -1);
     ProgressManager tipProgress = new ProgressManager();
     tipProgress.Start();
     ClusterTipsSearchProgress searchProgress = delegate(string path)
      {
       progress.Event.CurrentItemName = path;
       task.OnProgressChanged(progress.Event);
       if (currentTask.Canceled)
        throw new OperationCanceledException(S._("The task was cancelled."));
      };
     ClusterTipsEraseProgress eraseProgress =
      delegate(int currentFile, int totalFiles, string currentFilePath)
      {
       tipProgress.Total = totalFiles;
       tipProgress.Completed = currentFile;
       progress.Event.CurrentTargetStatus = S._("Erasing cluster tips...");
       progress.Event.CurrentItemName = currentFilePath;
       progress.Event.CurrentItemProgress = tipProgress.Progress;
       progress.Event.CurrentTargetProgress = progress.Event.CurrentItemProgress / 10;
       progress.Event.TimeLeft = tipProgress.TimeLeft;
       task.OnProgressChanged(progress.Event);
       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 (Eraser.Util.File.IsCompressed(info.FullName))
      Eraser.Util.File.SetCompression(info.FullName, false);
     progress.Event.CurrentTargetStatus = S._("Erasing unused space...");
     progress.Event.CurrentItemName = target.Drive;
     task.OnProgressChanged(progress.Event);
     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))
      {
       long streamLength = Math.Min(ErasureMethod.FreeSpaceFileUnit,
        volInfo.AvailableFreeSpace);
       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)
        {
     progress.Completed = Math.Min(progress.Total,
      progress.Completed + lastWritten);
     progress.Event.CurrentItemPass = currentPass;
     progress.Event.CurrentItemProgress = progress.Progress;
     if (target.EraseClusterTips)
      progress.Event.CurrentTargetProgress = (float)
       (0.1f + progress.Event.CurrentItemProgress * 0.8f);
     else
      progress.Event.CurrentTargetProgress = (float)
       (progress.Event.CurrentItemProgress * 0.9f);
     progress.Event.TimeLeft = progress.TimeLeft;
     task.OnProgressChanged(progress.Event);
     if (currentTask.Canceled)
      throw new OperationCanceledException(S._("The task was cancelled."));
        }
       );
      }
     }
     progress.Event.CurrentItemName = S._("Old resident file system table files");
     task.OnProgressChanged(progress.Event);
     fsManager.EraseOldFileSystemResidentFiles(volInfo, info, method, null);
        }
        finally
        {
     progress.Event.CurrentTargetStatus = S._("Removing temporary files...");
     task.OnProgressChanged(progress.Event);
     fsManager.DeleteFolder(info);
        }
        progress.Event.CurrentTargetStatus = S._("Erasing unused directory structures...");
        ProgressManager fsEntriesProgress = new ProgressManager();
        fsEntriesProgress.Start();
        fsManager.EraseDirectoryStructures(volInfo,
     delegate(int currentFile, int totalFiles)
     {
      if (currentTask.Canceled)
       throw new OperationCanceledException(S._("The task was cancelled."));
      fsEntriesProgress.Total = totalFiles;
      fsEntriesProgress.Completed = currentFile;
      progress.Event.TimeLeft = fsEntriesProgress.TimeLeft;
      progress.Event.CurrentItemProgress = fsEntriesProgress.Progress;
      progress.Event.CurrentTargetProgress = (float)(
       0.9 + progress.Event.CurrentItemProgress / 10);
      task.OnProgressChanged(progress.Event);
     }
        );
 }
Esempio n. 3
0
 private void EraseUnusedSpace(Task task, UnusedSpaceTarget target)
 {
     if (!AdvApi.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 SteppedProgressManager.Step(
     progress, 1.0f / task.Targets.Count));
        if (target.EraseClusterTips)
        {
     ProgressManager tipSearch = new ProgressManager();
     progress.Steps.Add(new SteppedProgressManager.Step(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 SteppedProgressManager.Step(tipProgress, 0.1f,
      S._("Erasing cluster tips...")));
     ClusterTipsEraseProgress eraseProgress =
      delegate(int currentFile, int totalFiles, string currentFilePath)
      {
       tipSearch.Completed = tipSearch.Total;
       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 (Eraser.Util.File.IsCompressed(info.FullName))
      Eraser.Util.File.SetCompression(info.FullName, false);
     ProgressManager mainProgress = new ProgressManager();
     progress.Steps.Add(new SteppedProgressManager.Step(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 + 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.Completed = mainProgress.Total;
     ProgressManager residentProgress = new ProgressManager();
     progress.Steps.Add(new SteppedProgressManager.Step(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.Completed = residentProgress.Total = 1;
        }
        finally
        {
     ProgressManager tempFiles = new ProgressManager();
     progress.Steps.Add(new SteppedProgressManager.Step(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 = 1;
        }
        ProgressManager structureProgress = new ProgressManager();
        progress.Steps.Add(new SteppedProgressManager.Step(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.Completed = structureProgress.Total;
        target.Progress = null;
 }
Esempio n. 4
0
        private static void CommandAddTask(ConsoleArguments arg)
        {
            AddTaskArguments arguments = (AddTaskArguments)arg;

               Task task = new Task();
               ErasureMethod method = arguments.ErasureMethod == Guid.Empty ?
            ErasureMethodManager.Default :
            ErasureMethodManager.GetInstance(arguments.ErasureMethod);
               switch (arguments.Schedule.ToUpperInvariant())
               {
            case "NOW":
             task.Schedule = Schedule.RunNow;
             break;
            case "MANUALLY":
             task.Schedule = Schedule.RunManually;
             break;
            case "RESTART":
             task.Schedule = Schedule.RunOnRestart;
             break;
            default:
             throw new ArgumentException(string.Format(CultureInfo.CurrentCulture,
              "Unknown schedule type: {0}", arguments.Schedule), "--schedule");
               }

               List<string> trueValues = new List<string>(new string[] { "yes", "true" });
               string[] strings = new string[] {

            "(?<recycleBin>recyclebin)",

            "unused=(?<unusedVolume>.*)(?<unusedTips>,clusterTips(=(?<unusedTipsValue>true|false))?)?",

            "dir=(?<directoryName>.*)(?<directoryParams>(?<directoryExcludeMask>,-[^,]+)|(?<directoryIncludeMask>,\\+[^,]+)|(?<directoryDeleteIfEmpty>,deleteIfEmpty(=(?<directoryDeleteIfEmptyValue>true|false))?))*",

            "file=(?<fileName>.*)"
               };

               Regex regex = new Regex(string.Join("|", strings),
            RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.RightToLeft);
               foreach (string argument in arguments.PositionalArguments)
               {
            Match match = regex.Match(argument);
            if (match.Captures.Count == 0)
            {
             Console.WriteLine("Unknown argument: {0}, skipped.", argument);
             continue;
            }

            ErasureTarget target = null;
            if (match.Groups["recycleBin"].Success)
            {
             target = new RecycleBinTarget();
            }
            else if (match.Groups["unusedVolume"].Success)
            {
             UnusedSpaceTarget unusedSpaceTarget = new UnusedSpaceTarget();
             target = unusedSpaceTarget;
             unusedSpaceTarget.Drive = match.Groups["unusedVolume"].Value;

             if (!match.Groups["unusedTips"].Success)
              unusedSpaceTarget.EraseClusterTips = false;
             else if (!match.Groups["unusedTipsValue"].Success)
              unusedSpaceTarget.EraseClusterTips = true;
             else
              unusedSpaceTarget.EraseClusterTips =
               trueValues.IndexOf(match.Groups["unusedTipsValue"].Value) != -1;
            }
            else if (match.Groups["directoryName"].Success)
            {
             FolderTarget folderTarget = new FolderTarget();
             target = folderTarget;

             folderTarget.Path = match.Groups["directoryName"].Value;
             if (!match.Groups["directoryDeleteIfEmpty"].Success)
              folderTarget.DeleteIfEmpty = false;
             else if (!match.Groups["directoryDeleteIfEmptyValue"].Success)
              folderTarget.DeleteIfEmpty = true;
             else
              folderTarget.DeleteIfEmpty =
               trueValues.IndexOf(match.Groups["directoryDeleteIfEmptyValue"].Value) != -1;
             if (match.Groups["directoryExcludeMask"].Success)
              folderTarget.ExcludeMask += match.Groups["directoryExcludeMask"].Value.Remove(0, 2) + ' ';
             if (match.Groups["directoryIncludeMask"].Success)
              folderTarget.IncludeMask += match.Groups["directoryIncludeMask"].Value.Remove(0, 2) + ' ';
            }
            else if (match.Groups["fileName"].Success)
            {
             FileTarget fileTarget = new FileTarget();
             target = fileTarget;
             fileTarget.Path = match.Groups["fileName"].Value;
            }

            if (target == null)
             continue;

            target.Method = method;
            task.Targets.Add(target);
               }

               if (task.Targets.Count == 0)
            throw new ArgumentException("Tasks must contain at least one erasure target.");

               try
               {
            using (RemoteExecutorClient client = new RemoteExecutorClient())
            {
             client.Run();
             if (!client.IsConnected)
             {

              Process eraserInstance = Process.Start(
               Assembly.GetExecutingAssembly().Location, "--quiet");
              eraserInstance.WaitForInputIdle();

              client.Run();
              if (!client.IsConnected)
               throw new IOException("Eraser cannot connect to the running " +
            "instance for erasures.");
             }

             client.Tasks.Add(task);
            }
               }
               catch (UnauthorizedAccessException e)
               {

            throw new UnauthorizedAccessException("Another instance of Eraser " +
             "is already running but it is running with higher privileges than " +
             "this instance of Eraser. Tasks cannot be added in this manner.\n\n" +
             "Close the running instance of Eraser and start it again without " +
             "administrator privileges, or run the command again as an " +
             "administrator.", e);
               }
        }