From dda07ee7d3e8ebfecd20c390302e944483db2c9a Mon Sep 17 00:00:00 2001 From: Encryptor Date: Wed, 16 Nov 2016 23:50:15 +0300 Subject: [PATCH] + Better Exception handling + Obfuscate file name and dates --- RudeFox.FrontEnd/Models/FileSystemType.cs | 28 ++++++++ RudeFox.FrontEnd/RudeFox.FrontEnd.csproj | 1 + RudeFox.FrontEnd/Services/ShredderService.cs | 74 ++++++++++++++++---- RudeFox.FrontEnd/ViewModels/MainWindowVM.cs | 43 +++++++++--- RudeFox.FrontEnd/ViewModels/WorkItemVM.cs | 17 +++-- 5 files changed, 136 insertions(+), 27 deletions(-) create mode 100644 RudeFox.FrontEnd/Models/FileSystemType.cs diff --git a/RudeFox.FrontEnd/Models/FileSystemType.cs b/RudeFox.FrontEnd/Models/FileSystemType.cs new file mode 100644 index 0000000..4741426 --- /dev/null +++ b/RudeFox.FrontEnd/Models/FileSystemType.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace RudeFox.Models +{ + public enum FileSystemType + { + /// + /// New Technology File System. + /// + NTFS, + /// + /// File Allocation Table. + /// + FAT32, + /// + /// Unknown File System. + /// + Unknown, + /// + /// Used with ExpanDrive. + /// + EXFS + } +} diff --git a/RudeFox.FrontEnd/RudeFox.FrontEnd.csproj b/RudeFox.FrontEnd/RudeFox.FrontEnd.csproj index 31fc425..c4e0c1a 100644 --- a/RudeFox.FrontEnd/RudeFox.FrontEnd.csproj +++ b/RudeFox.FrontEnd/RudeFox.FrontEnd.csproj @@ -68,6 +68,7 @@ Code + diff --git a/RudeFox.FrontEnd/Services/ShredderService.cs b/RudeFox.FrontEnd/Services/ShredderService.cs index e244c86..600efd5 100644 --- a/RudeFox.FrontEnd/Services/ShredderService.cs +++ b/RudeFox.FrontEnd/Services/ShredderService.cs @@ -1,4 +1,5 @@ using RudeFox.Helpers; +using RudeFox.Models; using System; using System.Collections.Generic; using System.IO; @@ -19,7 +20,8 @@ private ShredderService() #endregion #region Fields - private const int MAX_BUFFER_SIZE = 1 * Constants.MEGABYTE; + private const int MAX_BUFFER_SIZE = Constants.MEGABYTE; + private const int OBFUSCATE_ROUNDS = 5; Random _random = new Random(); #endregion @@ -95,8 +97,7 @@ public async Task ShredFileAsync(FileInfo file, CancellationToken cancella }; if (!file.Exists) return false; - - if (cancellationToken != null) cancellationToken.ThrowIfCancellationRequested(); + file.IsReadOnly = false; var result = await OverWriteFileAsync(file, cancellationToken, writeProgress).ConfigureAwait(false); if (!result) return result; @@ -110,6 +111,8 @@ await Task.Run(() => file.Delete(); }).ConfigureAwait(false); + await DestroyEntityMetaData(file); + if (progress != null) progress.Report(1.0); return true; @@ -160,15 +163,41 @@ public async Task ShredFolderAsync(DirectoryInfo folder, CancellationToken if (percent == 1.0) bytesComplete += length; }; + var result = await ShredFolderAsync(dir, cancellationToken, itemProgress).ConfigureAwait(false); if (!result) return result; } } + // BUG: Don't know why this causes issues. + // await DestroyEntityMetaData(folder); folder.Delete(); + return true; } + public bool IsFileLocked(FileInfo file) + { + FileStream stream = null; + + try + { + stream = file.Open(FileMode.Open, FileAccess.Read, FileShare.None); + } + catch (IOException) + { + return true; + } + finally + { + if (stream != null) stream.Close(); + } + + return false; + } + #endregion + + #region Private Methods private async Task OverWriteFileAsync(FileInfo file, CancellationToken cancellationToken, IProgress progress) { if (!file.Exists) return false; @@ -208,25 +237,44 @@ await Task.Run(() => return true; } - - public bool IsFileLocked(FileInfo file) + private async Task DestroyEntityMetaData(FileSystemInfo entity, FileSystemType fileSystemType = FileSystemType.Unknown) { - FileStream stream = null; + if (!entity.Exists) + return false; try { - stream = file.Open(FileMode.Open, FileAccess.Read, FileShare.None); + // prevent the indexing service from locking the file + entity.Attributes = FileAttributes.NotContentIndexed; } - catch (IOException) + catch (ArgumentException e) { - return true; + throw new UnauthorizedAccessException(e.Message, e); } - finally + + await Task.Run(() => { - if (stream != null) stream.Close(); - } + // rename the file a few times to remove it from the file system table. + for (var round = 0; round < OBFUSCATE_ROUNDS; round++) + { + var newPath = Path.Combine(Path.GetDirectoryName(entity.FullName), Path.GetRandomFileName()); - return false; + var file = entity as FileInfo; + var folder = entity as DirectoryInfo; + + if (file != null) + file.MoveTo(newPath); + else + folder.MoveTo(newPath); + } + + var newTime = new DateTime(1981, 1, 1, 0, 0, 1); + entity.LastAccessTime = newTime; + entity.LastWriteTime = newTime; + entity.CreationTime = newTime; + }); + + return true; } #endregion } diff --git a/RudeFox.FrontEnd/ViewModels/MainWindowVM.cs b/RudeFox.FrontEnd/ViewModels/MainWindowVM.cs index 7dde8ef..da57bc6 100644 --- a/RudeFox.FrontEnd/ViewModels/MainWindowVM.cs +++ b/RudeFox.FrontEnd/ViewModels/MainWindowVM.cs @@ -47,7 +47,6 @@ public ObservableCollection WorkItems #endregion #region Drag and drop - void IDropTarget.DragOver(IDropInfo dropInfo) { var data = dropInfo.Data as IDataObject; @@ -90,6 +89,7 @@ private async void DeleteItems(List paths) join p in paths on i.Path equals p select p; + paths.RemoveAll(p => duplicates.Contains(p)); foreach (var path in paths) @@ -126,8 +126,9 @@ on i.Path equals p var tasks = newItems.Select(item => { - return ShredderService.Instance.ShredItemAsync(item.Path, item.CancellationTokenSource.Token, item.TaskProgress); - }); + item.Task = ShredderService.Instance.ShredItemAsync(item.Path, item.CancellationTokenSource.Token, item.TaskProgress); + return item.Task; + }).ToList(); try { @@ -139,18 +140,40 @@ on i.Path equals p } catch (AggregateException exc) { - var msg = $"{exc.InnerExceptions.Count()} error(s) occured: "; - foreach(var ex in exc.InnerExceptions) + var failedTasks = tasks.Where(t => t.IsFaulted); + tasks.RemoveAll(t => failedTasks.Contains(t)); + + var failedItems = WorkItems.Where(item => item.Task.IsFaulted || item.Task.IsCanceled); + + for (int i = 0; i < WorkItems.Count; i++) { - msg += "\n---------------------------"; - msg += Environment.NewLine; - msg += ex.ToString(); + if (failedItems.Contains(WorkItems[i])) + { + WorkItems.RemoveAt(i); + i--; + } } - MessageBox.Show(msg); + + var exception = exc.Flatten(); + MessageBox.Show(exception.ToString()); + } catch( Exception exc) { - var failed = tasks.Where(t => t.IsFaulted); + var failedTasks = tasks.Where(t => t.IsFaulted); + tasks.RemoveAll(t => failedTasks.Contains(t)); + + var failedItems = WorkItems.Where(item => item.Task.IsFaulted || item.Task.IsCanceled); + + for (int i = 0; i < WorkItems.Count; i++) + { + if (failedItems.Contains(WorkItems[i])) + { + WorkItems.RemoveAt(i); + i--; + } + } + MessageBox.Show(exc.ToString()); } } diff --git a/RudeFox.FrontEnd/ViewModels/WorkItemVM.cs b/RudeFox.FrontEnd/ViewModels/WorkItemVM.cs index ebf6508..1822bac 100644 --- a/RudeFox.FrontEnd/ViewModels/WorkItemVM.cs +++ b/RudeFox.FrontEnd/ViewModels/WorkItemVM.cs @@ -63,13 +63,13 @@ public double Progress } } - private long _length = -1; + private long _bytes = -1; public long Bytes { - get { return _length; } + get { return _bytes; } set { - if (SetProperty(ref _length, value)) + if (SetProperty(ref _bytes, value)) RaisePropertyChanged(nameof(Size)); } } @@ -116,6 +116,13 @@ public string Size } } + private Task _task; + public Task Task + { + get { return _task; } + set { SetProperty(ref _task, value); } + } + public CancellationTokenSource CancellationTokenSource { get; set; } public Progress TaskProgress { get; set; } @@ -134,8 +141,10 @@ private async void CalculateBytes() { if (File.Exists(Path)) Bytes = new FileInfo(Path).Length; - else + else if (Directory.Exists(Path)) Bytes = await ShredderService.Instance.GetFolderSize(new DirectoryInfo(Path)); + else + Bytes = -1; } private void OnDeleteRequested(bool canceled = false) {