Changeset 485
- Timestamp:
- 11/10/2008 12:27:47 AM (5 years ago)
- Location:
- branches/eraser6/Manager
- Files:
-
- 2 edited
-
DirectExecutor.cs (modified) (12 diffs)
-
Task.cs (modified) (6 diffs)
Legend:
- Unmodified
- Added
- Removed
-
branches/eraser6/Manager/DirectExecutor.cs
r482 r485 3 3 * Copyright 2008 The Eraser Project 4 4 * Original Author: Joel Low <lowjoel@users.sourceforge.net> 5 * Modified By: 5 * Modified By: Kasra Nassiri <cjax@users.sourceforge.net> @17/10/2008 6 * Modified By: 6 7 * 7 8 * This file is part of Eraser. … … 251 252 //Check if the task is recurring. If it is, check if we missed it. 252 253 if (currentTask.Schedule is RecurringSchedule) 253 ScheduleTask(currentTask); 254 ScheduleTask(currentTask); 254 255 } 255 256 … … 313 314 else if (target is Task.FilesystemObject) 314 315 EraseFilesystemObject(task, (Task.FilesystemObject)target, progress); 315 else if (target is Task.RecycleBin)316 EraseRecycleBin(task, (Task.RecycleBin)target);317 316 else 318 317 throw new ArgumentException("Unknown erasure target."); … … 413 412 } 414 413 415 public static List<string> GetFiles(DirectoryInfo root)416 {417 List<string> files = new List<string>();418 419 foreach (FileSystemInfo fsInfo in root.GetFileSystemInfos())420 try421 {422 if (fsInfo is FileInfo)423 {424 FileInfo file = (FileInfo)fsInfo;425 if (Eraser.Util.File.IsProtectedSystemFile(file.FullName))426 ;427 else428 {429 foreach (string i in Util.File.GetADSes(file))430 files.Add(file.FullName + ':' + i);431 432 files.Add(file.FullName);433 }434 }435 else if (fsInfo is DirectoryInfo)436 {437 DirectoryInfo dir = (DirectoryInfo)fsInfo;438 foreach (DirectoryInfo subDir in dir.GetDirectories())439 files.AddRange(GetFiles(subDir));440 }441 }442 catch (UnauthorizedAccessException)443 {444 }445 catch (IOException)446 {447 }448 return files;449 }450 451 414 /// <summary> 452 415 /// Executes a unused space erase. … … 533 496 GenerateRandomFileName(18); 534 497 while (System.IO.File.Exists(currFile)); 535 498 536 499 //Create the stream 537 500 using (FileStream stream = new FileStream(currFile, … … 540 503 //Set the length of the file to be the amount of free space left 541 504 //or the maximum size of one of these dumps. 542 stream.SetLength(Math.Min(ErasureMethod.FreeSpaceFileUnit, 543 volInfo.AvailableFreeSpace)); 505 long streamLength = Math.Min(ErasureMethod.FreeSpaceFileUnit, 506 volInfo.AvailableFreeSpace); 507 508 //Handle IO exceptions gracefully, because the filesystem 509 //may require more space than demanded by us for file allocation. 510 while (true) 511 try 512 { 513 stream.SetLength(streamLength); 514 break; 515 } 516 catch (IOException) 517 { 518 long amountToReduce = 32 * volInfo.ClusterSize; 519 if (streamLength > amountToReduce) 520 streamLength -= amountToReduce; 521 else 522 throw; 523 } 544 524 545 525 //Then run the erase task … … 586 566 RemoveFolder(info); 587 567 } 588 568 589 569 //new NotImplementedException(): clear directory entries: Eraser.cpp@2348 590 570 } … … 593 573 private delegate void ClusterTipsEraseProgress(int currentFile, 594 574 string currentFilePath, int totalFiles); 595 private delegate void threadPoolHandler(ThreadPoolArgs args); 596 597 struct ThreadPoolArgs 598 { 599 public ThreadPoolArgs(Task _task, String _file, 600 ErasureMethod _method, 601 ClusterTipsEraseProgress _callBack) 602 { 603 task = _task; 604 file = _file; 605 method = _method; 606 callBack = _callBack; 607 } 608 609 public Task task; 610 public String file; 611 public ErasureMethod method; 612 public ClusterTipsEraseProgress callBack; 613 614 public static void resetPool() 615 { 616 ObjectCount = TObjectCount = Mapped = 0; 617 } 618 619 public static long Mapped = 0; 620 public static long TObjectCount = 0; 621 public static long ObjectCount = 0; 622 public static object ThreadLock = new object(); 623 public static EventWaitHandle Handle = new AutoResetEvent(true); 624 } 625 575 626 576 private static void EraseClusterTips(Task task, Task.UnusedSpace target, 627 577 ErasureMethod method, ClusterTipsEraseProgress callback) … … 633 583 subFolders = delegate(DirectoryInfo info) 634 584 { 635 foreach (FileSystemInfo fsInfo in info.GetFileSystemInfos())636 585 try 637 586 { 638 if (fsInfo is FileInfo) 639 { 640 FileInfo file = (FileInfo)fsInfo; 587 foreach (FileInfo file in info.GetFiles()) 641 588 if (Eraser.Util.File.IsProtectedSystemFile(file.FullName)) 642 task.Log.Add(new LogEntry(string.Format(" \"{0}\"did not have its cluster tips " +643 "erased, because it is a protectedsystem file", file.FullName), LogLevel.INFORMATION));589 task.Log.Add(new LogEntry(string.Format("{0} did not have its cluster tips " + 590 "erased, because it is a system file", file.FullName), LogLevel.INFORMATION)); 644 591 else 645 592 { … … 649 596 files.Add(file.FullName); 650 597 } 651 } 652 else if (fsInfo is DirectoryInfo) 653 { 654 DirectoryInfo dir = (DirectoryInfo)fsInfo; 655 foreach (DirectoryInfo subDir in dir.GetDirectories()) 656 subFolders(subDir); 657 } 658 else 659 throw new NotImplementedException("Unknown FileSystemInfo type"); 598 599 foreach (DirectoryInfo subDirInfo in info.GetDirectories()) 600 subFolders(subDirInfo); 660 601 } 661 602 catch (UnauthorizedAccessException e) 662 603 { 663 task.Log.Add(new LogEntry(string.Format(" \"{0}\"did not have its cluster tips erased because of " +664 " : {1}", info.FullName, e.Message), LogLevel.ERROR));604 task.Log.Add(new LogEntry(string.Format("{0} did not have its cluster tips erased because of " + 605 "the following error: {1}", info.FullName, e.Message), LogLevel.ERROR)); 665 606 } 666 607 catch (IOException e) 667 608 { 668 task.Log.Add(new LogEntry(string.Format(" \"{0}\"did not have its cluster tips erased because of " +669 " : {1}", info.FullName, e.Message), LogLevel.ERROR));609 task.Log.Add(new LogEntry(string.Format("{0} did not have its cluster tips erased because of " + 610 "the following error: {1}", info.FullName, e.Message), LogLevel.ERROR)); 670 611 } 671 612 }; 672 613 673 614 subFolders(new DirectoryInfo(target.Drive)); 674 ThreadPoolArgs.Handle.WaitOne(); 675 676 677 foreach (string file in files) 678 EraseClusterTips(task, target, method, callback); 679 615 616 //For every file, erase the cluster tips. 617 for (int i = 0, j = files.Count; i != j; ++i) 618 { 619 try 620 { 621 EraseFileClusterTips(files[i], method); 622 } 623 catch (Exception e) 624 { 625 task.Log.Add(new LogEntry(string.Format("{0} did not have its cluster tips " + 626 "erased. The error returned was: {1}", files[i], e.Message), LogLevel.ERROR)); 627 } 628 callback(i, files[i], files.Count); 629 } 680 630 } 681 631 682 632 /// <summary> 683 633 /// Erases the cluster tips of the given file. 684 /// This method is used for thread-pool tests685 634 /// </summary> 686 635 /// <param name="file">The file to erase.</param> 687 636 /// <param name="method">The erasure method to use.</param> 688 private static void EraseFileClusterTips(object args) 689 { 690 lock (ThreadPoolArgs.ThreadLock) 691 { 692 ThreadPoolArgs arguments = (ThreadPoolArgs)args; 637 private static void EraseFileClusterTips(string file, ErasureMethod method) 638 { 639 //Get the file access times 640 StreamInfo streamInfo = new StreamInfo(file); 641 DateTime lastAccess = DateTime.MinValue, lastWrite = DateTime.MinValue, 642 created = DateTime.MinValue; 643 { 644 FileInfo info = streamInfo.File; 645 if (info != null) 646 { 647 lastAccess = info.LastAccessTime; 648 lastWrite = info.LastWriteTime; 649 created = info.CreationTime; 650 } 651 } 652 653 //Create the stream, lengthen the file, then tell the erasure method 654 //to erase the tips. 655 using (FileStream stream = streamInfo.Open(FileMode.Open, FileAccess.Write)) 656 { 657 long fileLength = stream.Length; 658 long fileArea = GetFileArea(file); 693 659 694 660 try 695 661 { 696 //Get the file access times 697 StreamInfo streamInfo = new StreamInfo(arguments.file); 698 DateTime lastAccess = DateTime.MinValue, lastWrite = DateTime.MinValue, 699 created = DateTime.MinValue; 700 { 701 FileInfo info = streamInfo.File; 702 if (info != null) 703 { 704 lastAccess = info.LastAccessTime; 705 lastWrite = info.LastWriteTime; 706 created = info.CreationTime; 707 } 708 } 709 710 //Create the stream, lengthen the file, then tell the erasure method 711 //to erase the tips. 712 using (FileStream stream = streamInfo.Open(FileMode.Open, FileAccess.Write)) 713 { 714 long fileLength = stream.Length; 715 long fileArea = GetFileArea(arguments.file); 716 717 try 718 { 719 stream.SetLength(fileArea); 720 stream.Seek(fileLength, SeekOrigin.Begin); 721 722 //Erase the file 723 arguments.method.Erase(stream, long.MaxValue, PRNGManager.GetInstance( 724 ManagerLibrary.Instance.Settings.ActivePRNG), null); 725 } 726 finally 727 { 728 //Make sure the file is restored! 729 stream.SetLength(fileLength); 730 } 731 } 732 733 //Set the file times 734 FileInfo fileInfo = streamInfo.File; 735 if (fileInfo != null) 736 { 737 fileInfo.LastAccessTime = lastAccess; 738 fileInfo.LastWriteTime = lastWrite; 739 fileInfo.CreationTime = created; 740 } 741 742 arguments.callBack((int)Interlocked.Read(ref ThreadPoolArgs.ObjectCount), 743 arguments.file, 744 (int)(Interlocked.Read(ref ThreadPoolArgs.TObjectCount) 745 + Interlocked.Read(ref ThreadPoolArgs.ObjectCount))); 746 747 Interlocked.Decrement(ref ThreadPoolArgs.ObjectCount); 748 } 749 catch (Exception e) 750 { 751 arguments.task.Log.Add(new LogEntry(string.Format("\"{0}\" did not have its cluster tips " + 752 "erased because: {1}", arguments.file, e.Message), LogLevel.ERROR)); 753 } 754 } 755 if (Interlocked.Read(ref ThreadPoolArgs.ObjectCount) == -1 && 756 Interlocked.Read(ref ThreadPoolArgs.Mapped) == 1) 757 ThreadPoolArgs.Handle.Set(); 758 } 759 662 stream.SetLength(fileArea); 663 stream.Seek(fileLength, SeekOrigin.Begin); 664 665 //Erase the file 666 method.Erase(stream, long.MaxValue, PRNGManager.GetInstance( 667 ManagerLibrary.Instance.Settings.ActivePRNG), null); 668 } 669 finally 670 { 671 //Make sure the file is restored! 672 stream.SetLength(fileLength); 673 } 674 } 675 676 //Set the file times 677 FileInfo fileInfo = streamInfo.File; 678 if (fileInfo != null) 679 { 680 fileInfo.LastAccessTime = lastAccess; 681 fileInfo.LastWriteTime = lastWrite; 682 fileInfo.CreationTime = created; 683 } 684 } 685 760 686 /// <summary> 761 687 /// Erases the old MFT or FAT records. This creates small one-byte files … … 809 735 throw new NotImplementedException("Could not erase old file system " + 810 736 "records: Unsupported File system"); 811 }812 813 814 /// <summary>815 /// Erases the files in the RecycleBin of ALL dirves.816 /// TODO: Add individual drive selection. (or should we?)817 /// </summary>818 /// <param name="task"></param>819 /// <param name="target"></param>820 private void EraseRecycleBin(Task task, Task.RecycleBin target)821 {822 //progress report823 bool isReadOnly;824 long dataTotal = 0;825 826 //Retrieve the list of files to erase.827 List<Task.RecycleBin.DirectoryDictionary> directories = target.GetPaths(task);828 829 TaskProgressEventArgs eventArgs = new TaskProgressEventArgs(task);830 831 //Record the start of the erasure pass so we can calculate speed of erasures832 EraseProgressManager statistics = new EraseProgressManager(task);833 834 //Get the erasure method if the user specified he wants the default.835 ErasureMethod method = target.Method;836 if (method == null)837 method = ErasureMethodManager.GetInstance(ManagerLibrary.Instance.Settings.DefaultFileErasureMethod);838 839 //Calculate the total amount of data required to finish the wipe.840 foreach (Task.RecycleBin.DirectoryDictionary d in directories)841 dataTotal += d.size;842 dataTotal = method.CalculateEraseDataSize(null, dataTotal);843 844 foreach (Task.RecycleBin.DirectoryDictionary dir in directories)845 {846 foreach (string file in dir.files)847 {848 try849 {850 StreamInfo info = new StreamInfo(file);851 852 //Remove the read-only flag, if it is set.853 if (isReadOnly = info.IsReadOnly) info.IsReadOnly = false;854 855 try856 {857 // create the file stream, and call the erasure method to write to858 // the stream.859 using (FileStream strm = info.Open(FileMode.Open, FileAccess.Write,860 FileShare.None, FileOptions.WriteThrough))861 {862 // set the end of the stream after the wrap-round the cluster size863 strm.SetLength(GetFileArea(file));864 865 // nothing to do continue866 if (strm.Length == 0) continue;867 868 // erase the file.869 long itemWritten = 0, itemTotal = method.CalculateEraseDataSize(null, strm.Length);870 method.Erase(strm, long.MaxValue,871 PRNGManager.GetInstance(ManagerLibrary.Instance.Settings.ActivePRNG),872 delegate(long lastWritten, int currentPass)873 {874 statistics.DataWritten += lastWritten;875 eventArgs.currentItemPass = currentPass;876 877 eventArgs.currentItemProgress = (int)878 (((double)(itemWritten += lastWritten) * 100) / (double)itemTotal + 0.5);879 880 eventArgs.overallProgress = (int)881 ((double)(statistics.DataWritten * 100) / (double)dataTotal + 0.5);882 883 if (statistics.Speed != 0)884 {885 eventArgs.timeLeft = (int)886 ((double)((double)dataTotal - (double)statistics.DataWritten)887 / (double)statistics.Speed + 0.5);888 }889 else890 {891 eventArgs.timeLeft = -1;892 }893 894 task.OnProgressChanged(eventArgs);895 896 lock (currentTask)897 if (currentTask.cancelled)898 throw new FatalException("The task was cancelled.");899 }900 );901 902 // set the length of the file to 0.903 strm.Seek(0, SeekOrigin.Begin);904 strm.SetLength(0);905 }906 907 // remove the file.908 FileInfo fileInfo = info.File;909 if (fileInfo != null)910 RemoveFile(fileInfo);911 }912 finally913 {914 // re-set the read-only flag915 info.IsReadOnly = isReadOnly;916 }917 }918 catch (Exception e)919 {920 // show as much exception info as possible921 task.Log.Add(new LogEntry(string.Format("\"{0}\": Error {Message:{1},InnerException:{2},Source:{3},StackTrace:{4},TargetSite:{5}}", file,922 e.Message, e.InnerException, e.Source, e.StackTrace, e.TargetSite), LogLevel.ERROR));923 }924 }925 RemoveFolder(new DirectoryInfo(dir.directory));926 }927 737 } 928 738 … … 1238 1048 if (entries[index] is DirectoryInfo) 1239 1049 result = GetRandomFileName((DirectoryInfo)entries[index]); 1240 else 1050 else 1241 1051 result = ((FileInfo)entries[index]).FullName; 1242 1052 } -
branches/eraser6/Manager/Task.cs
r482 r485 84 84 { 85 85 get; 86 }87 88 private ErasureMethod method = null;89 }90 91 [Serializable]92 public class RecycleBin : ErasureTarget93 {94 #region Serialization code95 public RecycleBin(SerializationInfo info, StreamingContext context)96 {97 Guid methodGuid = (Guid)info.GetValue("Method", typeof(Guid));98 if (methodGuid == Guid.Empty)99 method = ErasureMethodManager.Default;100 else101 method = ErasureMethodManager.GetInstance(methodGuid);102 }103 104 public virtual void GetObjectData(SerializationInfo info,105 StreamingContext context)106 {107 info.AddValue("Method", method.GUID);108 }109 #endregion110 111 /// <summary>112 /// Constructor.113 /// </summary>114 public RecycleBin()115 {116 if (method == null)117 lock(ManagerLibrary.Instance.Settings)118 method = ErasureMethodManager.GetInstance(119 ManagerLibrary.Instance.Settings.DefaultFileErasureMethod);120 }121 122 public struct DirectoryDictionary123 {124 public long size;125 public string directory;126 public List<string> files;127 };128 129 /// <summary>130 /// Retrieves the list of files/folders to erase as a list.131 /// </summary>132 /// <param name="totalSize">Returns the total size in bytes of the133 /// items.</param>134 /// <returns>A list containing the paths to all the files to be erased.</returns>135 internal List<DirectoryDictionary> GetPaths(Task task)136 {137 List<DirectoryDictionary> dir_files_pair = new List<DirectoryDictionary>();138 long totalSize;139 foreach (DriveInfo drive in DriveInfo.GetDrives())140 {141 try142 {143 if (drive.DriveType == DriveType.CDRom ||144 drive.DriveType == DriveType.Network ||145 drive.DriveType == DriveType.Unknown)146 continue;147 148 string root = Path.Combine(drive.Name, @"RECYCLER\");149 DirectoryInfo dir = new DirectoryInfo(root);150 if (dir.Exists == false) continue;151 152 foreach (DirectoryInfo director in dir.GetDirectories())153 {154 totalSize = 0;155 List<string> files = new List<string>();156 foreach (FileInfo info in director.GetFiles())157 {158 if ((info.Attributes & FileAttributes.Encrypted) != 0 )159 {160 task.log.Add(new LogEntry(161 string.Format("\"{0}\"", info.FullName) +162 "was not erased, because encrypted " +163 "files cannot be wipped with Eraser.", LogLevel.NOTICE));164 }165 166 totalSize += info.Length;167 files.Add(info.FullName);168 }169 DirectoryDictionary d = new DirectoryDictionary();170 d.directory = director.FullName;171 d.files = files;172 d.size = totalSize;173 dir_files_pair.Add(d);174 }175 }176 catch (IOException) { /* oopts! */ }177 }178 return dir_files_pair;179 }180 181 182 /// <summary>183 /// The method used for erasing the file. If the variable is equal to184 /// ErasureMethodManager.Default then the default is queried for the185 /// task type.186 /// </summary>187 public ErasureMethod Method188 {189 get { return method; }190 set { method = value; }191 }192 193 /// <summary>194 /// Retrieves the text to display representing this task.195 /// </summary>196 public override string UIText197 {198 get199 {200 return "RecycleBin";201 }202 86 } 203 87 … … 424 308 result.Add(file.FullName); 425 309 } 426 310 427 311 //Return the filtered list. 428 312 return result; … … 465 349 } 466 350 351 [Serializable] 352 public class RecycleBin : FilesystemObject 353 { 354 #region Serialization code 355 public RecycleBin(SerializationInfo info, StreamingContext context) 356 : base(info, context) 357 { 358 } 359 #endregion 360 361 internal override List<string> GetPaths(out long totalSize) 362 { 363 totalSize = 0; 364 List<string> result = new List<string>(); 365 string[] rootDirectory = new string[] { 366 "$RECYCLE.BIN", 367 "RECYCLER" 368 }; 369 370 foreach (DriveInfo drive in DriveInfo.GetDrives()) 371 { 372 if (drive.DriveType == DriveType.CDRom || 373 drive.DriveType == DriveType.Network || 374 drive.DriveType == DriveType.Unknown) 375 continue; 376 377 foreach (string rootDir in rootDirectory) 378 { 379 DirectoryInfo dir = new DirectoryInfo( 380 System.IO.Path.Combine(drive.Name, rootDir)); 381 if (!dir.Exists) 382 continue; 383 384 GetRecyclerFiles(dir, ref result, ref totalSize); 385 } 386 } 387 388 return result; 389 } 390 391 /// <summary> 392 /// Retrieves all files within this folder, without exclusions. 393 /// </summary> 394 /// <param name="info">The DirectoryInfo object representing the folder to traverse.</param> 395 /// <param name="paths">The list of files to store path information in.</param> 396 /// <param name="totalSize">Receives the total size of the files.</param> 397 private void GetRecyclerFiles(DirectoryInfo info, ref List<string> paths, 398 ref long totalSize) 399 { 400 foreach (FileSystemInfo fsInfo in info.GetFileSystemInfos()) 401 { 402 if (fsInfo is FileInfo) 403 { 404 paths.Add(fsInfo.FullName); 405 totalSize += ((FileInfo)fsInfo).Length; 406 GetPathADSes(ref paths, ref totalSize, fsInfo.FullName); 407 } 408 else 409 GetRecyclerFiles((DirectoryInfo)fsInfo, ref paths, ref totalSize); 410 } 411 } 412 413 /// <summary> 414 /// Retrieves the text to display representing this task. 415 /// </summary> 416 public override string UIText 417 { 418 get 419 { 420 return "Recycle Bin"; 421 } 422 } 423 } 424 467 425 #region Serialization code 468 426 public Task(SerializationInfo info, StreamingContext context) … … 471 429 name = (string)info.GetValue("Name", typeof(string)); 472 430 targets = (List<ErasureTarget>)info.GetValue("Targets", typeof(List<ErasureTarget>)); 473 log = (Log Manager)info.GetValue("Log", typeof(LogManager));431 log = (Logger)info.GetValue("Log", typeof(Logger)); 474 432 475 433 Schedule schedule = (Schedule)info.GetValue("Schedule", typeof(Schedule)); … … 594 552 /// The log entries which this task has accumulated. 595 553 /// </summary> 596 public Log Manager Log554 public Logger Log 597 555 { 598 556 get { return log; } … … 670 628 private Schedule schedule = Schedule.RunNow; 671 629 private List<ErasureTarget> targets = new List<ErasureTarget>(); 672 private Log Manager log = new LogManager();630 private Logger log = new Logger(); 673 631 } 674 632
Note: See TracChangeset
for help on using the changeset viewer.
