Changeset 485 for branches/eraser6/Manager/DirectExecutor.cs
- Timestamp:
- 11/10/2008 12:27:47 AM (5 years ago)
- File:
-
- 1 edited
-
branches/eraser6/Manager/DirectExecutor.cs (modified) (12 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 }
Note: See TracChangeset
for help on using the changeset viewer.
