Changeset 1193
- Timestamp:
- 9/28/2009 5:56:32 AM (4 years ago)
- Location:
- trunk/eraser6/Eraser.Manager
- Files:
-
- 6 edited
-
DirectExecutor.cs (modified) (10 diffs)
-
FileSystem.cs (modified) (7 diffs)
-
Method.cs (modified) (4 diffs)
-
Strings.en.resx (modified) (2 diffs)
-
Strings.nl.resx (modified) (2 diffs)
-
Strings.resx (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/eraser6/Eraser.Manager/DirectExecutor.cs
r1179 r1193 478 478 } 479 479 480 #region Unused Space erasure functions481 480 /// <summary> 482 481 /// Executes a unused space erase. … … 510 509 //Get the erasure method if the user specified he wants the default. 511 510 ErasureMethod method = target.Method; 512 511 512 //Make a folder to dump our temporary files in 513 DirectoryInfo info = new DirectoryInfo(target.Drive); 514 VolumeInfo volInfo = VolumeInfo.FromMountpoint(target.Drive); 515 FileSystem fsManager = FileSystem.Get(volInfo); 516 info = info.CreateSubdirectory(Path.GetFileName( 517 FileSystem.GenerateRandomFileName(info, 18))); 518 513 519 //Erase the cluster tips of every file on the drive. 514 520 if (target.EraseClusterTips) … … 524 530 525 531 //Define the callback handlers 526 ClusterTipsSearchProgress searchProgress = delegate(string path)532 FileSystem.ClusterTipsSearchProgress searchProgress = delegate(string path) 527 533 { 528 534 progress.Event.CurrentItemName = path; … … 533 539 }; 534 540 535 ClusterTipsEraseProgress eraseProgress =541 FileSystem.ClusterTipsEraseProgress eraseProgress = 536 542 delegate(int currentFile, int totalFiles, string currentFilePath) 537 543 { … … 550 556 }; 551 557 552 EraseClusterTips(task, target, method, searchProgress, eraseProgress); 553 } 554 555 //Make a folder to dump our temporary files in 556 DirectoryInfo info = new DirectoryInfo(target.Drive); 557 VolumeInfo volInfo = VolumeInfo.FromMountpoint(target.Drive); 558 FileSystem fsManager = FileSystem.Get(volInfo); 559 info = info.CreateSubdirectory(Path.GetFileName( 560 FileSystem.GenerateRandomFileName(info, 18))); 558 fsManager.EraseClusterTips(VolumeInfo.FromMountpoint(target.Drive), 559 method, task.Log, searchProgress, eraseProgress); 560 } 561 561 562 562 try … … 604 604 method.Erase(stream, long.MaxValue, 605 605 PrngManager.GetInstance(ManagerLibrary.Settings.ActivePrng), 606 delegate(long lastWritten, int currentPass)606 delegate(long lastWritten, long totalData, int currentPass) 607 607 { 608 608 progress.Completed = Math.Min(progress.Total, … … 663 663 } 664 664 665 private delegate void SubFoldersHandler(DirectoryInfo info); 666 private delegate void ClusterTipsSearchProgress(string currentPath); 667 private delegate void ClusterTipsEraseProgress(int currentFile, int totalFiles, 668 string currentFilePath); 669 670 private static void EraseClusterTips(Task task, UnusedSpaceTarget target, 671 ErasureMethod method, ClusterTipsSearchProgress searchCallback, 672 ClusterTipsEraseProgress eraseCallback) 673 { 674 //List all the files which can be erased. 675 List<string> files = new List<string>(); 676 SubFoldersHandler subFolders = null; 677 678 subFolders = delegate(DirectoryInfo info) 679 { 680 //Check if we've been cancelled 681 if (task.Canceled) 682 throw new OperationCanceledException(S._("The task was cancelled.")); 683 684 try 685 { 686 //Skip this directory if it is a reparse point 687 if ((info.Attributes & FileAttributes.ReparsePoint) != 0) 688 { 689 task.Log.LastSessionEntries.Add(new LogEntry(S._("Files in {0} did " + 690 "not have their cluster tips erased because it is a hard link or " + 691 "a symbolic link.", info.FullName), LogLevel.Information)); 692 return; 693 } 694 695 foreach (FileInfo file in info.GetFiles()) 696 if (Util.File.IsProtectedSystemFile(file.FullName)) 697 task.Log.LastSessionEntries.Add(new LogEntry(S._("{0} did not have " + 698 "its cluster tips erased, because it is a system file", 699 file.FullName), LogLevel.Information)); 700 else if ((file.Attributes & FileAttributes.ReparsePoint) != 0) 701 task.Log.LastSessionEntries.Add(new LogEntry(S._("{0} did not have " + 702 "its cluster tips erased because it is a hard link or a " + 703 "symbolic link.", file.FullName), LogLevel.Information)); 704 else if ((file.Attributes & FileAttributes.Compressed) != 0 || 705 (file.Attributes & FileAttributes.Encrypted) != 0 || 706 (file.Attributes & FileAttributes.SparseFile) != 0) 707 { 708 task.Log.LastSessionEntries.Add(new LogEntry(S._("{0} did not have " + 709 "its cluster tips erased because it is compressed, encrypted " + 710 "or a sparse file.", file.FullName), LogLevel.Information)); 711 } 712 else 713 { 714 try 715 { 716 foreach (string i in Util.File.GetADSes(file)) 717 files.Add(file.FullName + ':' + i); 718 719 files.Add(file.FullName); 720 } 721 catch (UnauthorizedAccessException e) 722 { 723 task.Log.LastSessionEntries.Add(new LogEntry(S._("{0} did not " + 724 "have its cluster tips erased because of the following " + 725 "error: {1}", info.FullName, e.Message), LogLevel.Error)); 726 } 727 catch (IOException e) 728 { 729 task.Log.LastSessionEntries.Add(new LogEntry(S._("{0} did not " + 730 "have its cluster tips erased because of the following " + 731 "error: {1}", info.FullName, e.Message), LogLevel.Error)); 732 } 733 } 734 735 foreach (DirectoryInfo subDirInfo in info.GetDirectories()) 736 { 737 searchCallback(subDirInfo.FullName); 738 subFolders(subDirInfo); 739 } 740 } 741 catch (UnauthorizedAccessException e) 742 { 743 task.Log.LastSessionEntries.Add(new LogEntry(S._("{0} did not have its " + 744 "cluster tips erased because of the following error: {1}", 745 info.FullName, e.Message), LogLevel.Error)); 746 } 747 catch (IOException e) 748 { 749 task.Log.LastSessionEntries.Add(new LogEntry(S._("{0} did not have its " + 750 "cluster tips erased because of the following error: {1}", 751 info.FullName, e.Message), LogLevel.Error)); 752 } 753 }; 754 755 subFolders(new DirectoryInfo(target.Drive)); 756 757 //For every file, erase the cluster tips. 758 for (int i = 0, j = files.Count; i != j; ++i) 759 { 760 //Get the file attributes for restoring later 761 StreamInfo info = new StreamInfo(files[i]); 762 FileAttributes fileAttr = info.Attributes; 763 764 try 765 { 766 //Reset the file attributes. 767 info.Attributes = FileAttributes.Normal; 768 EraseFileClusterTips(files[i], method); 769 } 770 catch (UnauthorizedAccessException) 771 { 772 task.Log.LastSessionEntries.Add(new LogEntry(S._("{0} did not have its " + 773 "cluster tips erased because you do not have the required permissions to " + 774 "erase the file cluster tips.", files[i]), LogLevel.Error)); 775 } 776 catch (IOException e) 777 { 778 task.Log.LastSessionEntries.Add(new LogEntry(S._("{0} did not have its " + 779 "cluster tips erased. The error returned was: {1}", files[i], 780 e.Message), LogLevel.Error)); 781 } 782 finally 783 { 784 info.Attributes = fileAttr; 785 } 786 eraseCallback(i, files.Count, files[i]); 787 } 788 } 789 790 /// <summary> 791 /// Erases the cluster tips of the given file. 792 /// </summary> 793 /// <param name="file">The file to erase.</param> 794 /// <param name="method">The erasure method to use.</param> 795 private static void EraseFileClusterTips(string file, ErasureMethod method) 796 { 797 //Get the file access times 798 StreamInfo streamInfo = new StreamInfo(file); 799 DateTime lastAccess = streamInfo.LastAccessTime; 800 DateTime lastWrite = streamInfo.LastWriteTime; 801 DateTime created = streamInfo.CreationTime; 802 803 //And get the file lengths to know how much to overwrite 804 long fileArea = GetFileArea(file); 805 long fileLength = streamInfo.Length; 806 807 //If the file length equals the file area there is no cluster tip to overwrite 808 if (fileArea == fileLength) 809 return; 810 811 //Otherwise, create the stream, lengthen the file, then tell the erasure 812 //method to erase the cluster tips. 813 using (FileStream stream = streamInfo.Open(FileMode.Open, FileAccess.Write, 814 FileShare.None, FileOptions.WriteThrough)) 815 { 816 try 817 { 818 stream.SetLength(fileArea); 819 stream.Seek(fileLength, SeekOrigin.Begin); 820 821 //Erase the file 822 method.Erase(stream, long.MaxValue, PrngManager.GetInstance( 823 ManagerLibrary.Settings.ActivePrng), null); 824 } 825 finally 826 { 827 //Make sure the file length is restored! 828 stream.SetLength(fileLength); 829 830 //Reset the file times 831 streamInfo.LastAccessTime = lastAccess; 832 streamInfo.LastWriteTime = lastWrite; 833 streamInfo.CreationTime = created; 834 } 835 } 836 } 837 #endregion 838 839 #region Filesystem Object erasure functions 665 /// <summary> 666 /// Traverses the given folder and deletes it securely only if it is 667 /// empty. 668 /// </summary> 669 /// <param name="info">The folder to check.</param> 670 private delegate void FolderEraseDelegate(DirectoryInfo info); 671 840 672 /// <summary> 841 673 /// Erases a file or folder on the volume. … … 894 726 } 895 727 896 //Create the file stream, and call the erasure method to write to 897 //the stream. 898 long fileArea = GetFileArea(paths[i]); 899 using (FileStream strm = info.Open(FileMode.Open, FileAccess.Write, 900 FileShare.None, FileOptions.WriteThrough)) 901 { 902 //Set the end of the stream after the wrap-round the cluster size 903 strm.SetLength(fileArea); 904 905 //If the stream is empty, there's nothing to overwrite. Continue 906 //to the next entry 907 if (strm.Length != 0) 728 long itemWritten = 0; 729 fsManager.EraseFileSystemObject(info, method, 730 delegate(long lastWritten, long totalData, int currentPass) 908 731 { 909 //Then erase the file. 910 long itemWritten = 0, 911 itemTotal = method.CalculateEraseDataSize(null, strm.Length); 912 method.Erase(strm, long.MaxValue, 913 PrngManager.GetInstance(ManagerLibrary.Settings.ActivePrng), 914 delegate(long lastWritten, int currentPass) 915 { 916 dataTotal -= lastWritten; 917 progress.Completed += lastWritten; 918 progress.Event.CurrentItemPass = currentPass; 919 progress.Event.CurrentItemProgress = (float) 920 ((itemWritten += lastWritten) / (float)itemTotal); 921 progress.Event.CurrentTargetProgress = 922 (i + progress.Event.CurrentItemProgress) / 923 (float)paths.Count; 924 progress.Event.TimeLeft = progress.TimeLeft; 925 task.OnProgressChanged(progress.Event); 926 927 if (currentTask.Canceled) 928 throw new OperationCanceledException(S._("The task was cancelled.")); 929 } 930 ); 931 } 932 933 //Set the length of the file to 0. 934 strm.Seek(0, SeekOrigin.Begin); 935 strm.SetLength(0); 936 } 732 dataTotal -= lastWritten; 733 progress.Completed += lastWritten; 734 progress.Event.CurrentItemPass = currentPass; 735 progress.Event.CurrentItemProgress = (float) 736 ((itemWritten += lastWritten) / (float)totalData); 737 progress.Event.CurrentTargetProgress = 738 (i + progress.Event.CurrentItemProgress) / 739 (float)paths.Count; 740 progress.Event.TimeLeft = progress.TimeLeft; 741 task.OnProgressChanged(progress.Event); 742 743 if (currentTask.Canceled) 744 throw new OperationCanceledException(S._("The task was cancelled.")); 745 }); 937 746 938 747 //Remove the file. 939 748 FileInfo fileInfo = info.File; 940 if (fileInfo != null)941 fsManager.DeleteFile(fileInfo); 749 /*if (fileInfo != null) 750 fsManager.DeleteFile(fileInfo);*/ 942 751 } 943 752 catch (UnauthorizedAccessException) … … 982 791 FolderTarget fldr = (FolderTarget)target; 983 792 FileSystem fsManager = FileSystem.Get(VolumeInfo.FromMountpoint(fldr.Path)); 984 SubFoldersHandlereraseEmptySubFolders = null;793 FolderEraseDelegate eraseEmptySubFolders = null; 985 794 eraseEmptySubFolders = delegate(DirectoryInfo info) 986 795 { … … 1029 838 1030 839 /// <summary> 1031 /// Retrieves the size of the file on disk, calculated by the amount of1032 /// clusters allocated by it.1033 /// </summary>1034 /// <param name="filePath">The path to the file.</param>1035 /// <returns>The area of the file.</returns>1036 private static long GetFileArea(string filePath)1037 {1038 StreamInfo info = new StreamInfo(filePath);1039 VolumeInfo volume = VolumeInfo.FromMountpoint(info.Directory.FullName);1040 long clusterSize = volume.ClusterSize;1041 return (info.Length + (clusterSize - 1)) & ~(clusterSize - 1);1042 }1043 #endregion1044 1045 /// <summary>1046 840 /// The thread object. 1047 841 /// </summary> -
trunk/eraser6/Eraser.Manager/FileSystem.cs
r1145 r1193 201 201 /// </summary> 202 202 /// <param name="info">The folder to delete</param> 203 public abstract void DeleteFolder(DirectoryInfo info); 203 /// <param name="recursive">True if the folder and all its subfolders and 204 /// files to be securely deleted.</param> 205 public abstract void DeleteFolder(DirectoryInfo info, bool recursive); 206 207 /// <seealso cref="DeleteFolder"/> 208 /// <param name="info">The folder to delete.</param> 209 public void DeleteFolder(DirectoryInfo info) 210 { 211 DeleteFolder(info, true); 212 } 213 214 /// <summary> 215 /// The function prototype for cluster tip search progress callbacks. This is 216 /// called when the cluster tips are being searched. 217 /// </summary> 218 /// <param name="currentPath">The directory being searched</param> 219 public delegate void ClusterTipsSearchProgress(string currentPath); 220 221 /// <summary> 222 /// The function prototype for cluster tip erasure callbacks. This is called when 223 /// the cluster tips are being erased. 224 /// </summary> 225 /// <param name="currentFile">The current file index being erased.</param> 226 /// <param name="totalFiles">The total number of files to be erased.</param> 227 /// <param name="currentFilePath">The path to the current file being erased.</param> 228 public delegate void ClusterTipsEraseProgress(int currentFile, int totalFiles, 229 string currentFilePath); 230 231 /// <summary> 232 /// Erases all file cluster tips in the given volume. 233 /// </summary> 234 /// <param name="info">The volume to search for file cluster tips and erase them.</param> 235 /// <param name="method">The erasure method being employed.</param> 236 /// <param name="logger">The log manager instance that tracks log messages.</param> 237 /// <param name="searchCallback">The callback function for search progress.</param> 238 /// <param name="eraseCallback">The callback function for erasure progress.</param> 239 public abstract void EraseClusterTips(VolumeInfo info, ErasureMethod method, 240 Logger logger, ClusterTipsSearchProgress searchCallback, 241 ClusterTipsEraseProgress eraseCallback); 204 242 205 243 /// <summary> … … 233 271 234 272 /// <summary> 273 /// Erases the file system object from the drive. 274 /// </summary> 275 /// <param name="info"></param> 276 public abstract void EraseFileSystemObject(StreamInfo info, ErasureMethod method, 277 EraserMethodProgressFunction callback); 278 279 /// <summary> 280 /// Retrieves the size of the file on disk, calculated by the amount of 281 /// clusters allocated by it. 282 /// </summary> 283 /// <param name="filePath">The path to the file.</param> 284 /// <returns>The area of the file.</returns> 285 public abstract long GetFileArea(string filePath); 286 287 /// <summary> 235 288 /// The number of times file names are renamed to erase the file name from 236 289 /// the file system table. … … 313 366 } 314 367 315 public override void DeleteFolder(DirectoryInfo info) 316 { 368 public override void DeleteFolder(DirectoryInfo info, bool recursive) 369 { 370 if (!recursive && info.GetFileSystemInfos().Length != 0) 371 throw new InvalidOperationException(S._("The folder {0} cannot be deleted as it is " + 372 "not empty.")); 373 317 374 //TODO: check for reparse points 318 375 foreach (DirectoryInfo dir in info.GetDirectories()) … … 342 399 //Remove the folder 343 400 info.Delete(true); 401 } 402 403 public override void EraseClusterTips(VolumeInfo info, ErasureMethod method, 404 Logger log, ClusterTipsSearchProgress searchCallback, 405 ClusterTipsEraseProgress eraseCallback) 406 { 407 //List all the files which can be erased. 408 List<string> files = new List<string>(); 409 if (!info.IsMounted) 410 throw new InvalidOperationException(S._("Could not erase cluster tips in {0} " + 411 "as the volume is not mounted.", info.VolumeId)); 412 ListFiles(new DirectoryInfo(info.MountPoints[0]), files, log, searchCallback); 413 414 //For every file, erase the cluster tips. 415 for (int i = 0, j = files.Count; i != j; ++i) 416 { 417 //Get the file attributes for restoring later 418 StreamInfo streamInfo = new StreamInfo(files[i]); 419 FileAttributes fileAttr = streamInfo.Attributes; 420 421 try 422 { 423 //Reset the file attributes. 424 streamInfo.Attributes = FileAttributes.Normal; 425 EraseFileClusterTips(files[i], method); 426 } 427 catch (UnauthorizedAccessException) 428 { 429 log.LastSessionEntries.Add(new LogEntry(S._("{0} did not have its " + 430 "cluster tips erased because you do not have the required permissions to " + 431 "erase the file cluster tips.", files[i]), LogLevel.Error)); 432 } 433 catch (IOException e) 434 { 435 log.LastSessionEntries.Add(new LogEntry(S._("{0} did not have its " + 436 "cluster tips erased. The error returned was: {1}", files[i], 437 e.Message), LogLevel.Error)); 438 } 439 finally 440 { 441 streamInfo.Attributes = fileAttr; 442 } 443 eraseCallback(i, files.Count, files[i]); 444 } 445 } 446 447 private void ListFiles(DirectoryInfo info, List<string> files, Logger log, 448 ClusterTipsSearchProgress searchCallback) 449 { 450 try 451 { 452 //Skip this directory if it is a reparse point 453 if ((info.Attributes & FileAttributes.ReparsePoint) != 0) 454 { 455 log.LastSessionEntries.Add(new LogEntry(S._("Files in {0} did " + 456 "not have their cluster tips erased because it is a hard link or " + 457 "a symbolic link.", info.FullName), LogLevel.Information)); 458 return; 459 } 460 461 foreach (FileInfo file in info.GetFiles()) 462 if (Util.File.IsProtectedSystemFile(file.FullName)) 463 log.LastSessionEntries.Add(new LogEntry(S._("{0} did not have " + 464 "its cluster tips erased, because it is a system file", 465 file.FullName), LogLevel.Information)); 466 else if ((file.Attributes & FileAttributes.ReparsePoint) != 0) 467 log.LastSessionEntries.Add(new LogEntry(S._("{0} did not have " + 468 "its cluster tips erased because it is a hard link or a " + 469 "symbolic link.", file.FullName), LogLevel.Information)); 470 else if ((file.Attributes & FileAttributes.Compressed) != 0 || 471 (file.Attributes & FileAttributes.Encrypted) != 0 || 472 (file.Attributes & FileAttributes.SparseFile) != 0) 473 { 474 log.LastSessionEntries.Add(new LogEntry(S._("{0} did not have " + 475 "its cluster tips erased because it is compressed, encrypted " + 476 "or a sparse file.", file.FullName), LogLevel.Information)); 477 } 478 else 479 { 480 try 481 { 482 foreach (string i in Util.File.GetADSes(file)) 483 files.Add(file.FullName + ':' + i); 484 485 files.Add(file.FullName); 486 } 487 catch (UnauthorizedAccessException e) 488 { 489 log.LastSessionEntries.Add(new LogEntry(S._("{0} did not " + 490 "have its cluster tips erased because of the following " + 491 "error: {1}", info.FullName, e.Message), LogLevel.Error)); 492 } 493 catch (IOException e) 494 { 495 log.LastSessionEntries.Add(new LogEntry(S._("{0} did not " + 496 "have its cluster tips erased because of the following " + 497 "error: {1}", info.FullName, e.Message), LogLevel.Error)); 498 } 499 } 500 501 foreach (DirectoryInfo subDirInfo in info.GetDirectories()) 502 { 503 searchCallback(subDirInfo.FullName); 504 ListFiles(subDirInfo, files, log, searchCallback); 505 } 506 } 507 catch (UnauthorizedAccessException e) 508 { 509 log.LastSessionEntries.Add(new LogEntry(S._("{0} did not have its " + 510 "cluster tips erased because of the following error: {1}", 511 info.FullName, e.Message), LogLevel.Error)); 512 } 513 catch (IOException e) 514 { 515 log.LastSessionEntries.Add(new LogEntry(S._("{0} did not have its " + 516 "cluster tips erased because of the following error: {1}", 517 info.FullName, e.Message), LogLevel.Error)); 518 } 519 } 520 521 /// <summary> 522 /// Erases the cluster tips of the given file. 523 /// </summary> 524 /// <param name="file">The file to erase.</param> 525 /// <param name="method">The erasure method to use.</param> 526 private void EraseFileClusterTips(string file, ErasureMethod method) 527 { 528 //Get the file access times 529 StreamInfo streamInfo = new StreamInfo(file); 530 DateTime lastAccess = streamInfo.LastAccessTime; 531 DateTime lastWrite = streamInfo.LastWriteTime; 532 DateTime created = streamInfo.CreationTime; 533 534 //And get the file lengths to know how much to overwrite 535 long fileArea = GetFileArea(file); 536 long fileLength = streamInfo.Length; 537 538 //If the file length equals the file area there is no cluster tip to overwrite 539 if (fileArea == fileLength) 540 return; 541 542 //Otherwise, create the stream, lengthen the file, then tell the erasure 543 //method to erase the cluster tips. 544 using (FileStream stream = streamInfo.Open(FileMode.Open, FileAccess.Write, 545 FileShare.None, FileOptions.WriteThrough)) 546 { 547 try 548 { 549 stream.SetLength(fileArea); 550 stream.Seek(fileLength, SeekOrigin.Begin); 551 552 //Erase the file 553 method.Erase(stream, long.MaxValue, PrngManager.GetInstance( 554 ManagerLibrary.Settings.ActivePrng), null); 555 } 556 finally 557 { 558 //Make sure the file length is restored! 559 stream.SetLength(fileLength); 560 561 //Reset the file times 562 streamInfo.LastAccessTime = lastAccess; 563 streamInfo.LastWriteTime = lastWrite; 564 streamInfo.CreationTime = created; 565 } 566 } 567 } 568 569 public override long GetFileArea(string filePath) 570 { 571 StreamInfo info = new StreamInfo(filePath); 572 VolumeInfo volume = VolumeInfo.FromMountpoint(info.Directory.FullName); 573 long clusterSize = volume.ClusterSize; 574 return (info.Length + (clusterSize - 1)) & ~(clusterSize - 1); 344 575 } 345 576 … … 372 603 FileAccess.Write, FileShare.None, 8, FileOptions.WriteThrough)) 373 604 { 374 //Stretch the file size to use up some of the resident space. 375 strm.SetLength(1); 376 377 //Then run the erase task 378 method.Erase(strm, long.MaxValue, 379 PrngManager.GetInstance(ManagerLibrary.Settings.ActivePrng), 380 null); 605 long streamSize = 0; 606 try 607 { 608 while (true) 609 { 610 //Stretch the file size to use up some of the resident space. 611 strm.SetLength(++streamSize); 612 613 //Then run the erase task 614 method.Erase(strm, long.MaxValue, 615 PrngManager.GetInstance(ManagerLibrary.Settings.ActivePrng), 616 null); 617 } 618 } 619 catch (IOException) 620 { 621 if (streamSize == 1) 622 return; 623 } 381 624 } 382 625 … … 445 688 446 689 DeleteFolder(tempDir); 690 } 691 } 692 693 public override void EraseFileSystemObject(StreamInfo info, ErasureMethod method, 694 EraserMethodProgressFunction callback) 695 { 696 //Check if the file fits in one MFT record 697 long mftRecordSize = NtfsApi.GetMftRecordSegmentSize(VolumeInfo.FromMountpoint(info.DirectoryName)); 698 while (info.Length < mftRecordSize) 699 { 700 //Yes it does, erase exactly to the file length 701 using (FileStream strm = info.Open(FileMode.Open, FileAccess.Write, 702 FileShare.None)) 703 { 704 strm.SetLength(strm.Length + 1); 705 method.Erase(strm, long.MaxValue, 706 PrngManager.GetInstance(ManagerLibrary.Settings.ActivePrng), null); 707 } 708 } 709 710 //Create the file stream, and call the erasure method to write to 711 //the stream. 712 long fileArea = GetFileArea(info.FullName); 713 714 //If the stream is empty, there's nothing to overwrite. Continue 715 //to the next entry 716 if (fileArea == 0) 717 return; 718 719 using (FileStream strm = info.Open(FileMode.Open, FileAccess.Write, 720 FileShare.None, FileOptions.WriteThrough)) 721 { 722 //Set the end of the stream after the wrap-round the cluster size 723 strm.SetLength(fileArea); 724 725 //Then erase the file. 726 method.Erase(strm, long.MaxValue, 727 PrngManager.GetInstance(ManagerLibrary.Settings.ActivePrng), 728 callback 729 ); 730 731 //Set the length of the file to 0. 732 strm.Seek(0, SeekOrigin.Begin); 733 strm.SetLength(0); 447 734 } 448 735 } … … 475 762 } 476 763 764 public override void EraseFileSystemObject(StreamInfo info, ErasureMethod method, 765 EraserMethodProgressFunction callback) 766 { 767 //Create the file stream, and call the erasure method to write to 768 //the stream. 769 long fileArea = GetFileArea(info.FullName); 770 using (FileStream strm = info.Open(FileMode.Open, FileAccess.Write, 771 FileShare.None, FileOptions.WriteThrough)) 772 { 773 //Set the end of the stream after the wrap-round the cluster size 774 strm.SetLength(fileArea); 775 776 //If the stream is empty, there's nothing to overwrite. Continue 777 //to the next entry 778 if (strm.Length != 0) 779 { 780 //Then erase the file. 781 method.Erase(strm, long.MaxValue, 782 PrngManager.GetInstance(ManagerLibrary.Settings.ActivePrng), 783 callback 784 ); 785 } 786 787 //Set the length of the file to 0. 788 strm.Seek(0, SeekOrigin.Begin); 789 strm.SetLength(0); 790 } 791 } 792 793 477 794 protected override DateTime MinTimestamp 478 795 { -
trunk/eraser6/Eraser.Manager/Method.cs
r1176 r1193 170 170 /// <param name="lastWritten">The amount of data written to the stream since 171 171 /// the last call to the delegate.</param> 172 /// <param name="totalData">The total amount of data that must be written to 173 /// complete the erasure.</param> 172 174 /// <param name="currentPass">The current pass number. The total number 173 175 /// of passes can be found from the Passes property.</param> 174 public delegate void EraserMethodProgressFunction(long lastWritten, int currentPass); 176 public delegate void EraserMethodProgressFunction(long lastWritten, long totalData, 177 int currentPass); 175 178 176 179 /// <summary> … … 299 302 long strmStart = stream.Position; 300 303 long strmLength = Math.Min(stream.Length - strmStart, erasureLength); 304 long totalData = CalculateEraseDataSize(null, strmLength); 301 305 302 306 //Allocate memory for a buffer holding data for the pass. … … 308 312 //Do a progress callback first. 309 313 if (callback != null) 310 callback(0, pass + 1);314 callback(0, totalData, pass + 1); 311 315 312 316 //Start from the beginning again … … 336 340 //Do a progress callback. 337 341 if (callback != null) 338 callback(amount, pass + 1);342 callback(amount, totalData, pass + 1); 339 343 } 340 344 } -
trunk/eraser6/Eraser.Manager/Strings.en.resx
r1178 r1193 151 151 <value>Erasing unused directory structures...</value> 152 152 </data> 153 <data name="Erasing files..." xml:space="preserve"> 154 <value>Erasing files...</value> 155 </data> 156 <data name="The file {0} could not be erased because the file was either compressed, encrypted or a sparse file." xml:space="preserve"> 157 <value>The file {0} could not be erased because the file was either compressed, encrypted or a sparse file.</value> 158 </data> 159 <data name="The file {0} could not be erased because the file's permissions prevent access to the file." xml:space="preserve"> 160 <value>The file {0} could not be erased because the file's permissions prevent access to the file.</value> 161 </data> 162 <data name="Could not force closure of file \"{0}\" (locked by {1})" xml:space="preserve"> 163 <value>Could not force closure of file \"{0}\" (locked by {1})</value> 164 </data> 165 <data name="Removing folders..." xml:space="preserve"> 166 <value>Removing folders...</value> 167 </data> 168 <data name="Emptying recycle bin..." xml:space="preserve"> 169 <value>Emptying recycle bin...</value> 170 </data> 171 <data name="EntropySource GUID not found: {0}" xml:space="preserve"> 172 <value>EntropySource GUID not found: {0}</value> 173 </data> 174 <data name="Erasure method not found: {0}" xml:space="preserve"> 175 <value>Erasure method not found: {0}</value> 176 </data> 177 <data name="PRNG not found: {0}" xml:space="preserve"> 178 <value>PRNG not found: {0}</value> 179 </data> 180 <data name="The file system on the drive {0} is not supported." xml:space="preserve"> 181 <value>The file system on the drive {0} is not supported.</value> 182 </data> 183 <data name="Plausible deniability was selected, but no decoy files were found. The current file has been only replaced with random data." xml:space="preserve"> 184 <value>Plausible deniability was selected, but no decoy files were found. The current file has been only replaced with random data.</value> 185 </data> 186 <data name="The file {0} is currently in use and cannot be removed." xml:space="preserve"> 187 <value>The file {0} is currently in use and cannot be removed.</value> 188 </data> 189 <data name="The folder {0} cannot be deleted as it is not empty." xml:space="preserve"> 190 <value>(Untranslated)</value> 191 </data> 192 <data name="Could not erase cluster tips in {0} as the volume is not mounted." xml:space="preserve"> 193 <value>(Untranslated)</value> 194 </data> 195 <data name="{0} did not have its cluster tips erased because you do not have the required permissions to erase the file cluster tips." xml:space="preserve"> 196 <value>{0} did not have its cluster tips erased because you do not have the required permissions to erase the file cluster tips.</value> 197 </data> 198 <data name="{0} did not have its cluster tips erased. The error returned was: {1}" xml:space="preserve"> 199 <value>{0} did not have its cluster tips erased. The error returned was: {1}</value> 200 </data> 153 201 <data name="Files in {0} did not have their cluster tips erased because it is a hard link or a symbolic link." xml:space="preserve"> 154 202 <value>Files in {0} did not have their cluster tips erased because it is a hard link or a symbolic link.</value> … … 166 214 <value>{0} did not have its cluster tips erased because of the following error: {1}</value> 167 215 </data> 168 <data name="{0} did not have its cluster tips erased because you do not have the required permissions to erase the file cluster tips." xml:space="preserve">169 <value>{0} did not have its cluster tips erased because you do not have the required permissions to erase the file cluster tips.</value>170 </data>171 <data name="{0} did not have its cluster tips erased. The error returned was: {1}" xml:space="preserve">172 <value>{0} did not have its cluster tips erased. The error returned was: {1}</value>173 </data>174 <data name="Erasing files..." xml:space="preserve">175 <value>Erasing files...</value>176 </data>177 <data name="The file {0} could not be erased because the file was either compressed, encrypted or a sparse file." xml:space="preserve">178 <value>The file {0} could not be erased because the file was either compressed, encrypted or a sparse file.</value>179 </data>180 <data name="The file {0} could not be erased because the file's permissions prevent access to the file." xml:space="preserve">181 <value>The file {0} could not be erased because the file's permissions prevent access to the file.</value>182 </data>183 <data name="Could not force closure of file \"{0}\" (locked by {1})" xml:space="preserve">184 <value>Could not force closure of file \"{0}\" (locked by {1})</value>185 </data>186 <data name="Removing folders..." xml:space="preserve">187 <value>Removing folders...</value>188 </data>189 <data name="Emptying recycle bin..." xml:space="preserve">190 <value>Emptying recycle bin...</value>191 </data>192 <data name="EntropySource GUID not found: {0}" xml:space="preserve">193 <value>EntropySource GUID not found: {0}</value>194 </data>195 <data name="Erasure method not found: {0}" xml:space="preserve">196 <value>Erasure method not found: {0}</value>197 </data>198 <data name="PRNG not found: {0}" xml:space="preserve">199 <value>PRNG not found: {0}</value>200 </data>201 <data name="The file system on the drive {0} is not supported." xml:space="preserve">202 <value>The file system on the drive {0} is not supported.</value>203 </data>204 <data name="Plausible deniability was selected, but no decoy files were found. The current file has been only replaced with random data." xml:space="preserve">205 <value>Plausible deniability was selected, but no decoy files were found. The current file has been only replaced with random data.</value>206 </data>207 <data name="The file {0} is currently in use and cannot be removed." xml:space="preserve">208 <value>The file {0} is currently in use and cannot be removed.</value>209 </data>210 216 <data name="{0} (1 pass)" xml:space="preserve"> 211 217 <value>{0} (1 pass)</value> -
trunk/eraser6/Eraser.Manager/Strings.nl.resx
r1178 r1193 151 151 <value>(Untranslated)</value> 152 152 </data> 153 <data name="Erasing files..." xml:space="preserve"> 154 <value>(Untranslated)</value> 155 </data> 156 <data name="The file {0} could not be erased because the file was either compressed, encrypted or a sparse file." xml:space="preserve"> 157 <value>(Untranslated)</value> 158 </data> 159 <data name="The file {0} could not be erased because the file's permissions prevent access to the file." xml:space="preserve"> 160 <value>(Untranslated)</value> 161 </data> 162 <data name="Could not force closure of file \"{0}\" (locked by {1})" xml:space="preserve"> 163 <value>(Untranslated)</value> 164 </data> 165 <data name="Removing folders..." xml:space="preserve"> 166 <value>(Untranslated)</value> 167 </data> 168 <data name="Emptying recycle bin..." xml:space="preserve"> 169 <value>(Untranslated)</value> 170 </data> 171 <data name="EntropySource GUID not found: {0}" xml:space="preserve"> 172 <value>(Untranslated)</value> 173 </data> 174 <data name="Erasure method not found: {0}" xml:space="preserve"> 175 <value>(Untranslated)</value> 176 </data> 177 <data name="PRNG not found: {0}" xml:space="preserve"> 178 <value>(Untranslated)</value> 179 </data> 180 <data name="The file system on the drive {0} is not supported." xml:space="preserve"> 181 <value>(Untranslated)</value> 182 </data> 183 <data name="Plausible deniability was selected, but no decoy files were found. The current file has been only replaced with random data." xml:space="preserve"> 184 <value>(Untranslated)</value> 185 </data> 186 <data name="The file {0} is currently in use and cannot be removed." xml:space="preserve"> 187 <value>(Untranslated)</value> 188 </data> 189 <data name="The folder {0} cannot be deleted as it is not empty." xml:space="preserve"> 190 <value>(Untranslated)</value> 191 </data> 192 <data name="Could not erase cluster tips in {0} as the volume is not mounted." xml:space="preserve"> 193 <value>(Untranslated)</value> 194 </data> 195 <data name="{0} did not have its cluster tips erased because you do not have the required permissions to erase the file cluster tips." xml:space="preserve"> 196 <value>(Untranslated)</value> 197 </data> 198 <data name="{0} did not have its cluster tips erased. The error returned was: {1}" xml:space="preserve"> 199 <value>(Untranslated)</value> 200 </data> 153 201 <data name="Files in {0} did not have their cluster tips erased because it is a hard link or a symbolic link." xml:space="preserve"> 154 202 <value>(Untranslated)</value> … … 166 214 <value>(Untranslated)</value> 167 215 </data> 168 <data name="{0} did not have its cluster tips erased because you do not have the required permissions to erase the file cluster tips." xml:space="preserve">169 <value>(Untranslated)</value>170 </data>171 <data name="{0} did not have its cluster tips erased. The error returned was: {1}" xml:space="preserve">172 <value>(Untranslated)</value>173 </data>174 <data name="Erasing files..." xml:space="preserve">175 <value>(Untranslated)</value>176 </data>177 <data name="The file {0} could not be erased because the file was either compressed, encrypted or a sparse file." xml:space="preserve">178 <value>(Untranslated)</value>179 </data>180 <data name="The file {0} could not be erased because the file's permissions prevent access to the file." xml:space="preserve">181 <value>(Untranslated)</value>182 </data>183 <data name="Could not force closure of file \"{0}\" (locked by {1})" xml:space="preserve">184 <value>(Untranslated)</value>185 </data>186 <data name="Removing folders..." xml:space="preserve">187 <value>(Untranslated)</value>188 </data>189 <data name="Emptying recycle bin..." xml:space="preserve">190 <value>(Untranslated)</value>191 </data>192 <data name="EntropySource GUID not found: {0}" xml:space="preserve">193 <value>(Untranslated)</value>194 </data>195 <data name="Erasure method not found: {0}" xml:space="preserve">196 <value>(Untranslated)</value>197 </data>198 <data name="PRNG not found: {0}" xml:space="preserve">199 <value>(Untranslated)</value>200 </data>201 <data name="The file system on the drive {0} is not supported." xml:space="preserve">202 <value>(Untranslated)</value>203 </data>204 <data name="Plausible deniability was selected, but no decoy files were found. The current file has been only replaced with random data." xml:space="preserve">205 <value>(Untranslated)</value>206 </data>207 <data name="The file {0} is currently in use and cannot be removed." xml:space="preserve">208 <value>(Untranslated)</value>209 </data>210 216 <data name="{0} (1 pass)" xml:space="preserve"> 211 217 <value>(Untranslated)</value> -
trunk/eraser6/Eraser.Manager/Strings.resx
r1178 r1193 151 151 <value>Erasing unused directory structures...</value> 152 152 </data> 153 <data name="Erasing files..." xml:space="preserve"> 154 <value>Erasing files...</value> 155 </data> 156 <data name="The file {0} could not be erased because the file was either compressed, encrypted or a sparse file." xml:space="preserve"> 157 <value>The file {0} could not be erased because the file was either compressed, encrypted or a sparse file.</value> 158 </data> 159 <data name="The file {0} could not be erased because the file's permissions prevent access to the file." xml:space="preserve"> 160 <value>The file {0} could not be erased because the file's permissions prevent access to the file.</value> 161 </data> 162 <data name="Could not force closure of file \"{0}\" (locked by {1})" xml:space="preserve"> 163 <value>Could not force closure of file \"{0}\" (locked by {1})</value> 164 </data> 165 <data name="Removing folders..." xml:space="preserve"> 166 <value>Removing folders...</value> 167 </data> 168 <data name="Emptying recycle bin..." xml:space="preserve"> 169 <value>Emptying recycle bin...</value> 170 </data> 171 <data name="EntropySource GUID not found: {0}" xml:space="preserve"> 172 <value>EntropySource GUID not found: {0}</value> 173 </data> 174 <data name="Erasure method not found: {0}" xml:space="preserve"> 175 <value>Erasure method not found: {0}</value> 176 </data> 177 <data name="PRNG not found: {0}" xml:space="preserve"> 178 <value>PRNG not found: {0}</value> 179 </data> 180 <data name="The file system on the drive {0} is not supported." xml:space="preserve"> 181 <value>The file system on the drive {0} is not supported.</value> 182 </data> 183 <data name="Plausible deniability was selected, but no decoy files were found. The current file has been only replaced with random data." xml:space="preserve"> 184 <value>Plausible deniability was selected, but no decoy files were found. The current file has been only replaced with random data.</value> 185 </data> 186 <data name="The file {0} is currently in use and cannot be removed." xml:space="preserve"> 187 <value>The file {0} is currently in use and cannot be removed.</value> 188 </data> 189 <data name="The folder {0} cannot be deleted as it is not empty." xml:space="preserve"> 190 <value>The folder {0} cannot be deleted as it is not empty.</value> 191 </data> 192 <data name="Could not erase cluster tips in {0} as the volume is not mounted." xml:space="preserve"> 193 <value>Could not erase cluster tips in {0} as the volume is not mounted.</value> 194 </data> 195 <data name="{0} did not have its cluster tips erased because you do not have the required permissions to erase the file cluster tips." xml:space="preserve"> 196 <value>{0} did not have its cluster tips erased because you do not have the required permissions to erase the file cluster tips.</value> 197 </data> 198 <data name="{0} did not have its cluster tips erased. The error returned was: {1}" xml:space="preserve"> 199 <value>{0} did not have its cluster tips erased. The error returned was: {1}</value> 200 </data> 153 201 <data name="Files in {0} did not have their cluster tips erased because it is a hard link or a symbolic link." xml:space="preserve"> 154 202 <value>Files in {0} did not have their cluster tips erased because it is a hard link or a symbolic link.</value> … … 166 214 <value>{0} did not have its cluster tips erased because of the following error: {1}</value> 167 215 </data> 168 <data name="{0} did not have its cluster tips erased because you do not have the required permissions to erase the file cluster tips." xml:space="preserve">169 <value>{0} did not have its cluster tips erased because you do not have the required permissions to erase the file cluster tips.</value>170 </data>171 <data name="{0} did not have its cluster tips erased. The error returned was: {1}" xml:space="preserve">172 <value>{0} did not have its cluster tips erased. The error returned was: {1}</value>173 </data>174 <data name="Erasing files..." xml:space="preserve">175 <value>Erasing files...</value>176 </data>177 <data name="The file {0} could not be erased because the file was either compressed, encrypted or a sparse file." xml:space="preserve">178 <value>The file {0} could not be erased because the file was either compressed, encrypted or a sparse file.</value>179 </data>180 <data name="The file {0} could not be erased because the file's permissions prevent access to the file." xml:space="preserve">181 <value>The file {0} could not be erased because the file's permissions prevent access to the file.</value>182 </data>183 <data name="Could not force closure of file \"{0}\" (locked by {1})" xml:space="preserve">184 <value>Could not force closure of file \"{0}\" (locked by {1})</value>185 </data>186 <data name="Removing folders..." xml:space="preserve">187 <value>Removing folders...</value>188 </data>189 <data name="Emptying recycle bin..." xml:space="preserve">190 <value>Emptying recycle bin...</value>191 </data>192 <data name="EntropySource GUID not found: {0}" xml:space="preserve">193 <value>EntropySource GUID not found: {0}</value>194 </data>195 <data name="Erasure method not found: {0}" xml:space="preserve">196 <value>Erasure method not found: {0}</value>197 </data>198 <data name="PRNG not found: {0}" xml:space="preserve">199 <value>PRNG not found: {0}</value>200 </data>201 <data name="The file system on the drive {0} is not supported." xml:space="preserve">202 <value>The file system on the drive {0} is not supported.</value>203 </data>204 <data name="Plausible deniability was selected, but no decoy files were found. The current file has been only replaced with random data." xml:space="preserve">205 <value>Plausible deniability was selected, but no decoy files were found. The current file has been only replaced with random data.</value>206 </data>207 <data name="The file {0} is currently in use and cannot be removed." xml:space="preserve">208 <value>The file {0} is currently in use and cannot be removed.</value>209 </data>210 216 <data name="{0} (1 pass)" xml:space="preserve"> 211 217 <value>{0} (1 pass)</value>
Note: See TracChangeset
for help on using the changeset viewer.
