Changeset 2112


Ignore:
Timestamp:
5/15/2010 7:21:19 AM (4 years ago)
Author:
lowjoel
Message:

Implemented secure move of files and folders.

Location:
trunk/eraser
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/eraser/Eraser.DefaultPlugins/ErasureTargets/SecureMoveErasureTarget.cs

    r2110 r2112  
    9494        { 
    9595            List<StreamInfo> result = new List<StreamInfo>(); 
    96             if (!File.Exists(Path)) 
     96            if (!(File.Exists(Path) || Directory.Exists(Path))) 
    9797                return result; 
    9898 
     
    118118        { 
    119119            //If the path doesn't exist, exit. 
    120             if (!File.Exists(Path)) 
     120            if (!File.Exists(Path) && !Directory.Exists(Path)) 
    121121                return; 
    122122 
    123123            //Create the progress manager. 
    124124            Progress = new SteppedProgressManager(); 
     125            Task.Progress.Steps.Add(new SteppedProgressManagerStep(Progress, 
     126                1.0f / Task.Targets.Count)); 
    125127 
    126128            try 
    127129            { 
    128130                //Depending on whether the path is a file or directory, execute the 
    129                 //correct fucntion. 
     131                //correct function. 
    130132                if ((File.GetAttributes(Path) & FileAttributes.Directory) != 0) 
    131133                { 
     
    158160                //Compute the total size of the file on the disk (including ADSes) 
    159161                List<StreamInfo> fileStreams = new List<StreamInfo>( 
    160                     file.GetADSes().Select(x => new StreamInfo(info.FullName, x))); 
    161                 fileStreams.Add(new StreamInfo(info.FullName)); 
     162                    file.GetADSes().Select(x => new StreamInfo(file.FullName, x))); 
     163                fileStreams.Add(new StreamInfo(file.FullName)); 
    162164                long fileSize = fileStreams.Sum(x => x.Length); 
    163165 
     
    174176                try 
    175177                { 
    176                     //Compute the path to the new file. 
    177                     Uri sourceDir = new Uri(Path); 
    178                     Uri currentDir = new Uri(file.FullName).MakeRelativeUri(sourceDir); 
    179  
    180                     file.CopyTo(Destination, delegate(long TotalFileSize, long TotalBytesTransferred) 
     178                    //Compute the path to the new directory. 
     179                    DirectoryInfo sourceDirectory = file.Directory; 
     180                    DirectoryInfo destDirectory = new DirectoryInfo( 
     181                        SourceToDestinationPath(file.DirectoryName)); 
     182 
     183                    //Make sure all necessary folders exist before the copy. 
     184                    if (!destDirectory.Exists) 
     185                        destDirectory.Create(); 
     186                     
     187                    //Then copy the file. 
     188                    file.CopyTo(System.IO.Path.Combine(destDirectory.FullName, file.Name), 
     189                        delegate(long TotalFileSize, long TotalBytesTransferred) 
    181190                        { 
    182191                            return CopyProgress(copyProgress, file, TotalFileSize, 
     
    205214                EraseFile(file, eraseProgress); 
    206215            } 
     216 
     217            //Then copy the timestamps from the source folders and delete the source. 
     218            ProgressManager folderDeleteProgress = new ProgressManager(); 
     219            Progress.Steps.Add(new SteppedProgressManagerStep(folderDeleteProgress, 0.0f, 
     220                S._("Removing folders..."))); 
     221 
     222            Action<DirectoryInfo> CopyTimesAndDelete = null; 
     223            CopyTimesAndDelete = delegate(DirectoryInfo subDirectory) 
     224            { 
     225                foreach (DirectoryInfo child in subDirectory.GetDirectories()) 
     226                    CopyTimesAndDelete(child); 
     227 
     228                //Update progress. 
     229                OnProgressChanged(this, new ProgressChangedEventArgs(folderDeleteProgress, 
     230                    new TaskProgressChangedEventArgs(subDirectory.FullName, 1, 1))); 
     231 
     232                //Get the directory which we copied to and copy the file times to the 
     233                //destination directory 
     234                DirectoryInfo destDirectory = new DirectoryInfo( 
     235                    SourceToDestinationPath(subDirectory.FullName)); 
     236                if (!destDirectory.Exists) 
     237                    destDirectory.Create(); 
     238                destDirectory.CopyTimes(subDirectory); 
     239 
     240                //Then delete the source directory. 
     241                FileSystem fsManager = ManagerLibrary.Instance.FileSystemRegistrar[ 
     242                    VolumeInfo.FromMountPoint(Path)]; 
     243                fsManager.DeleteFolder(subDirectory); 
     244            }; 
     245            CopyTimesAndDelete(info); 
     246        } 
     247 
     248        /// <summary> 
     249        /// Converts the source path to the destination path. 
     250        /// </summary> 
     251        /// <param name="sourcePath">The source path to convert.</param> 
     252        /// <returns>The destination path that the file would have been moved to.</returns> 
     253        private string SourceToDestinationPath(string sourcePath) 
     254        { 
     255            DirectoryInfo source = new DirectoryInfo(Path); 
     256            string baseDir = System.IO.Path.Combine(Destination, source.Name); 
     257            return System.IO.Path.Combine(baseDir, 
     258                Shell.MakeRelativeTo(source, sourcePath)); 
    207259        } 
    208260 
     
    211263            ProgressManager copyProgress = new ProgressManager(); 
    212264            Progress.Steps.Add(new SteppedProgressManagerStep(copyProgress, 0.5f, 
    213                 S._("Copying source files to destination"))); 
     265                S._("Copying source files to destination..."))); 
    214266 
    215267            try 
    216268            { 
    217                 info.CopyTo(Destination, delegate(long TotalFileSize, long TotalBytesTransferred) 
     269                //Make sure all necessary folders exist before the copy. 
     270                Directory.CreateDirectory(Destination); 
     271 
     272                //Then copy the file. 
     273                string path = System.IO.Path.Combine(Destination, info.Name); 
     274                info.CopyTo(path, delegate(long TotalFileSize, long TotalBytesTransferred) 
    218275                    { 
    219276                        return CopyProgress(copyProgress, info, TotalFileSize, 
  • trunk/eraser/Eraser.DefaultPlugins/Strings.en.resx

    r2106 r2112  
    244244    <value>Erasing incomplete destination file</value> 
    245245  </data> 
     246  <data name="Securely moving files and folders..." xml:space="preserve"> 
     247    <value>Securely moving files and folders...</value> 
     248  </data> 
     249  <data name="Copying source files to destination..." xml:space="preserve"> 
     250    <value>Copying source files to destination...</value> 
     251  </data> 
    246252  <data name="Select the Source folder" xml:space="preserve"> 
    247253    <value>Select the Source folder</value> 
  • trunk/eraser/Eraser.DefaultPlugins/Strings.it.resx

    r2106 r2112  
    244244    <value>(Untranslated)</value> 
    245245  </data> 
     246  <data name="Securely moving files and folders..." xml:space="preserve"> 
     247    <value>(Untranslated)</value> 
     248  </data> 
     249  <data name="Copying source files to destination..." xml:space="preserve"> 
     250    <value>(Untranslated)</value> 
     251  </data> 
    246252  <data name="Select the Source folder" xml:space="preserve"> 
    247253    <value>Seleziona la cartella sorgente</value> 
     
    254260  </data> 
    255261  <data name="Save Source file to" xml:space="preserve"> 
    256     <value>Muover la cartella sorgente in:</value> 
    257   </data> 
    258   <data name="Save Source file to" xml:space="preserve"> 
    259262    <value>(Untranslated)</value> 
    260263  </data> 
  • trunk/eraser/Eraser.DefaultPlugins/Strings.nl.resx

    r2106 r2112  
    244244    <value>(Untranslated)</value> 
    245245  </data> 
     246  <data name="Securely moving files and folders..." xml:space="preserve"> 
     247    <value>(Untranslated)</value> 
     248  </data> 
     249  <data name="Copying source files to destination..." xml:space="preserve"> 
     250    <value>(Untranslated)</value> 
     251  </data> 
    246252  <data name="Select the Source folder" xml:space="preserve"> 
    247253    <value>(Untranslated)</value> 
  • trunk/eraser/Eraser.DefaultPlugins/Strings.pl.resx

    r2106 r2112  
    244244    <value>(Untranslated)</value> 
    245245  </data> 
     246  <data name="Securely moving files and folders..." xml:space="preserve"> 
     247    <value>(Untranslated)</value> 
     248  </data> 
     249  <data name="Copying source files to destination..." xml:space="preserve"> 
     250    <value>(Untranslated)</value> 
     251  </data> 
    246252  <data name="Select the Source folder" xml:space="preserve"> 
    247253    <value>(Untranslated)</value> 
  • trunk/eraser/Eraser.DefaultPlugins/Strings.resx

    r2106 r2112  
    244244    <value>Erasing incomplete destination file</value> 
    245245  </data> 
     246  <data name="Securely moving files and folders..." xml:space="preserve"> 
     247    <value>Securely moving files and folders...</value> 
     248  </data> 
     249  <data name="Copying source files to destination..." xml:space="preserve"> 
     250    <value>Copying source files to destination...</value> 
     251  </data> 
    246252  <data name="Select the Source folder" xml:space="preserve"> 
    247253    <value>Select the Source folder</value> 
  • trunk/eraser/Eraser.Util/ExtensionMethods/IO.cs

    r2076 r2112  
    3939    { 
    4040        /// <summary> 
     41        /// Copies the file times from the provided file. 
     42        /// </summary> 
     43        /// <param name="rhs">The file times to copy from.</param> 
     44        public static void CopyTimes(this FileSystemInfo lhs, FileSystemInfo rhs) 
     45        { 
     46            lhs.CreationTimeUtc = rhs.CreationTimeUtc; 
     47            lhs.LastAccessTimeUtc = rhs.LastAccessTimeUtc; 
     48            lhs.LastWriteTimeUtc = rhs.LastWriteTimeUtc; 
     49        } 
     50 
     51        /// <summary> 
    4152        /// Copies an existing file to a new file, allowing the monitoring of the progress 
    4253        /// of the copy operation. 
  • trunk/eraser/Eraser.Util/Shell.cs

    r2057 r2112  
    2727using System.Runtime.InteropServices; 
    2828using Microsoft.Win32; 
     29using System.IO; 
    2930 
    3031namespace Eraser.Util 
     
    9091 
    9192        /// <summary> 
     93        /// Makes the first path relative to the second. 
     94        /// </summary> 
     95        /// <remarks>Modified from: 
     96        /// http://mrpmorris.blogspot.com/2007/05/convert-absolute-path-to-relative-path.html</remarks> 
     97        /// <param name="absolutePath">The path to use as the root of the relative path.</param> 
     98        /// <param name="relativeTo">The path to make relative.</param> 
     99        /// <returns>The relative path to the provided path.</returns> 
     100        public static string MakeRelativeTo(FileSystemInfo absolutePath, string relativeTo) 
     101        { 
     102            string[] absoluteDirectories = absolutePath.FullName.Split( 
     103                Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar); 
     104            string[] relativeDirectories = relativeTo.Split( 
     105                Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar); 
     106 
     107            //Get the shortest of the two paths 
     108            int length = absoluteDirectories.Length < relativeDirectories.Length ? 
     109                absoluteDirectories.Length : relativeDirectories.Length; 
     110 
     111            //Use to determine where in the loop we exited 
     112            int lastCommonRoot = -1; 
     113            int index; 
     114 
     115            //Find common root 
     116            for (index = 0; index < length; index++) 
     117                if (absoluteDirectories[index] == relativeDirectories[index]) 
     118                    lastCommonRoot = index; 
     119                else 
     120                    break; 
     121 
     122            //If we didn't find a common prefix then throw 
     123            if (lastCommonRoot == -1) 
     124                throw new ArgumentException("Paths do not have a common base"); 
     125 
     126            //Build up the relative path 
     127            StringBuilder relativePath = new StringBuilder(); 
     128 
     129            //Add on the .. 
     130            for (index = lastCommonRoot + 1; index < absoluteDirectories.Length; index++) 
     131                if (absoluteDirectories[index].Length > 0) 
     132                    relativePath.Append("..\\"); 
     133 
     134            //Add on the folders 
     135            for (index = lastCommonRoot + 1; index < relativeDirectories.Length - 1; index++) 
     136                relativePath.Append(relativeDirectories[index] + "\\"); 
     137            if (lastCommonRoot < relativeDirectories.Length - 1) 
     138                relativePath.Append(relativeDirectories[relativeDirectories.Length - 1]); 
     139 
     140            return relativePath.ToString(); 
     141        } 
     142 
     143        /// <summary> 
    92144        /// A List of known folder IDs in the shell namespace. 
    93145        /// </summary> 
Note: See TracChangeset for help on using the changeset viewer.