Пример #1
0
 private void Main()
 {
     while (thread.ThreadState != ThreadState.AbortRequested)
        {
     Task task = null;
     lock (tasksLock)
     {
      while (scheduledTasks.Count != 0)
       if (scheduledTasks.Values[0].Count == 0)
       {
        scheduledTasks.RemoveAt(0);
       }
       else
       {
        if (scheduledTasks.Keys[0] <= DateTime.Now)
        {
     List<Task> tasks = scheduledTasks.Values[0];
     task = tasks[0];
     tasks.RemoveAt(0);
        }
        if (task == null)
        {
     for (int i = 0; i < scheduledTasks.Count; )
      if (scheduledTasks.Values[i].Count == 0)
       scheduledTasks.RemoveAt(i);
      else
       ++i;
        }
        break;
       }
     }
     if (task != null)
     {
      currentTask = task;
      try
      {
       KernelApi.SetThreadExecutionState(ThreadExecutionState.Continuous |
        ThreadExecutionState.SystemRequired);
       task.Canceled = false;
       task.OnTaskStarted(new TaskEventArgs(task));
       OnTaskProcessing(new TaskEventArgs(task));
       task.Log.Entries.NewSession();
       TaskProgressManager progress = new TaskProgressManager(task);
       foreach (ErasureTarget target in task.Targets)
        try
        {
     progress.Event.CurrentTarget = target;
     ++progress.Event.CurrentTargetIndex;
     UnusedSpaceTarget unusedSpaceTarget =
      target as UnusedSpaceTarget;
     FileSystemObjectTarget fileSystemObjectTarget =
      target as FileSystemObjectTarget;
     if (unusedSpaceTarget != null)
      EraseUnusedSpace(task, unusedSpaceTarget, progress);
     else if (fileSystemObjectTarget != null)
      EraseFilesystemObject(task, fileSystemObjectTarget, progress);
     else
      throw new ArgumentException(S._("Unknown erasure target."));
        }
        catch (FatalException)
        {
     throw;
        }
        catch (OperationCanceledException)
        {
     throw;
        }
        catch (Exception e)
        {
     task.Log.LastSessionEntries.Add(new LogEntry(e.Message, LogLevel.Error));
        }
      }
      catch (FatalException e)
      {
       task.Log.LastSessionEntries.Add(new LogEntry(e.Message, LogLevel.Fatal));
      }
      catch (OperationCanceledException e)
      {
       task.Log.LastSessionEntries.Add(new LogEntry(e.Message, LogLevel.Fatal));
      }
      catch (Exception e)
      {
       task.Log.LastSessionEntries.Add(new LogEntry(e.Message, LogLevel.Error));
      }
      finally
      {
       KernelApi.SetThreadExecutionState(ThreadExecutionState.Continuous);
       if (task.Schedule is RecurringSchedule)
        ((RecurringSchedule)task.Schedule).Reschedule(DateTime.Now);
       if (task.Schedule == Schedule.RunOnRestart)
        task.Schedule = Schedule.RunNow;
       task.OnTaskFinished(new TaskEventArgs(task));
       OnTaskProcessed(new TaskEventArgs(task));
       currentTask = null;
      }
     }
     schedulerInterrupt.WaitOne(30000, false);
        }
 }
Пример #2
0
      private void EraseFilesystemObject(Task task, FileSystemObjectTarget target,
 TaskProgressManager progress)
      {
          long dataTotal = 0;
             List<string> paths = target.GetPaths(out dataTotal);
             ErasureMethod method = target.Method;
             dataTotal = method.CalculateEraseDataSize(paths, dataTotal);
             progress.Event.CurrentTargetStatus = S._("Erasing files...");
             for (int i = 0; i < paths.Count; ++i)
             {
          progress.Event.CurrentTargetProgress = i / (float)paths.Count;
          progress.Event.CurrentTarget = target;
          progress.Event.CurrentItemName = paths[i];
          progress.Event.CurrentItemProgress = 0;
          progress.Event.CurrentTargetTotalPasses = method.Passes;
          task.OnProgressChanged(progress.Event);
          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));
           }
           long itemWritten = 0;
           fsManager.EraseFileSystemObject(info, method,
            delegate(long lastWritten, long totalData, int currentPass)
            {
             dataTotal -= lastWritten;
             progress.Completed += lastWritten;
             progress.Event.CurrentItemPass = currentPass;
             progress.Event.CurrentItemProgress = (float)
          ((itemWritten += lastWritten) / (float)totalData);
             progress.Event.CurrentTargetProgress =
          (i + progress.Event.CurrentItemProgress) /
          (float)paths.Count;
             progress.Event.TimeLeft = progress.TimeLeft;
             task.OnProgressChanged(progress.Event);
             if (currentTask.Canceled)
          throw new OperationCanceledException(S._("The task was cancelled."));
            });
           FileInfo fileInfo = info.File;
           if (fileInfo != null)
            fsManager.DeleteFile(fileInfo);
          }
          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)
             {
          progress.Event.CurrentTargetStatus = S._("Removing folders...");
          FolderTarget fldr = (FolderTarget)target;
          FileSystem fsManager = FileSystemManager.Get(VolumeInfo.FromMountpoint(fldr.Path));
          FolderEraseDelegate eraseEmptySubFolders = null;
          eraseEmptySubFolders = delegate(DirectoryInfo info)
          {
           foreach (DirectoryInfo subDir in info.GetDirectories())
            eraseEmptySubFolders(subDir);
           progress.Event.CurrentItemName = info.FullName;
           task.OnProgressChanged(progress.Event);
           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);
           progress.Event.CurrentItemName = info.FullName;
           task.OnProgressChanged(progress.Event);
           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)
             {
          progress.Event.CurrentTargetStatus = S._("Emptying recycle bin...");
          task.OnProgressChanged(progress.Event);
          ShellApi.EmptyRecycleBin(EmptyRecycleBinOptions.NoConfirmation |
           EmptyRecycleBinOptions.NoProgressUI | EmptyRecycleBinOptions.NoSound);
             }
      }
Пример #3
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);
     }
        );
 }
Пример #4
0
 public void Load()
 {
     LoadData();
     taskProgressManager = gameObject.AddComponent <TaskProgressManager>();
     taskProgressManager.Init();
 }