Changeset 2073


Ignore:
Timestamp:
5/8/2010 4:53:12 AM (5 years ago)
Author:
lowjoel
Message:

Define and document the CopyFileEx? function needed to implement secure move. Addresses #60

Location:
trunk/eraser/Eraser.Util
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/eraser/Eraser.Util/ExtensionMethods/IO.cs

    r1999 r2073  
    3939    { 
    4040        /// <summary> 
     41        /// Copies an existing file to a new file, allowing the monitoring of the progress 
     42        /// of the copy operation. 
     43        /// </summary> 
     44        /// <param name="info">The <see cref="System.IO.FileSystemInfo"/> object 
     45        /// to copy.</param> 
     46        /// <param name="destFileName">The name of the new file to copy to.</param> 
     47        /// <param name="progress">The progress callback function to execute</param> 
     48        /// <returns>A new file, or an overwrite of an existing file if the file exists.</returns> 
     49        public static FileInfo CopyTo(this FileInfo info, string destFileName, 
     50            CopyProgressFunction progress) 
     51        { 
     52            bool cancel = false; 
     53            NativeMethods.CopyProgressFunction callback = delegate( 
     54                    long TotalFileSize, long TotalBytesTransferred, long StreamSize, 
     55                    long StreamBytesTransferred, uint dwStreamNumber, 
     56                    NativeMethods.CopyProgressFunctionCallbackReasons dwCallbackReason, 
     57                    SafeFileHandle hSourceFile, SafeFileHandle hDestinationFile, IntPtr lpData) 
     58                { 
     59                    return progress(TotalFileSize, TotalBytesTransferred); 
     60                }; 
     61 
     62            if (!NativeMethods.CopyFileEx(info.FullName, destFileName, callback, IntPtr.Zero, 
     63                ref cancel, 0)) 
     64            { 
     65                throw Win32ErrorCode.GetExceptionForWin32Error(Marshal.GetLastWin32Error()); 
     66            } 
     67 
     68            return new FileInfo(destFileName); 
     69        } 
     70 
     71        /// <summary> 
     72        /// An application-defined callback function used with the <see cref="CopyTo" /> 
     73        /// function. It is called when a portion of a copy or move operation is 
     74        /// completed. 
     75        /// </summary> 
     76        /// <param name="TotalFileSize">The total size of the file, in bytes.</param> 
     77        /// <param name="TotalBytesTransferred">The total number of bytes 
     78        /// transferred from the source file to the destination file since the 
     79        /// copy operation began.</param> 
     80        /// <returns>The <see cref="CopyProgressFunction"/> function should return 
     81        /// one of the <see cref="CopyProgressFunctionResult"/> values.</returns> 
     82        public delegate CopyProgressFunctionResult CopyProgressFunction( 
     83            long TotalFileSize, long TotalBytesTransferred); 
     84 
     85        /// <summary> 
     86        /// Result codes which can be returned from the 
     87        /// <see cref="CopyProgressFunction"/> callbacks. 
     88        /// </summary> 
     89        public enum CopyProgressFunctionResult 
     90        { 
     91            /// <summary> 
     92            /// Cancel the copy operation and delete the destination file. 
     93            /// </summary> 
     94            Cancel = 1, 
     95 
     96            /// <summary> 
     97            /// Continue the copy operation. 
     98            /// </summary> 
     99            Continue = 0, 
     100 
     101            /// <summary> 
     102            /// Continue the copy operation, but stop invoking 
     103            /// <see cref="CopyProgressRoutine"/> to report progress. 
     104            /// </summary> 
     105            Quiet = 3, 
     106 
     107            /// <summary> 
     108            /// Stop the copy operation. It can be restarted at a later time. 
     109            /// </summary> 
     110            Stop = 2 
     111        } 
     112 
     113        /// <summary> 
    41114        /// Gets the parent directory of the current <see cref="System.IO.FileSystemInfo"/> 
    42115        /// object. 
    43116        /// </summary> 
    44         /// <param name="info">The <see cref="System.IO.FileSystemInfo"/>object 
     117        /// <param name="info">The <see cref="System.IO.FileSystemInfo"/> object 
    45118        /// to query its parent.</param> 
    46119        /// <returns>The parent directory of the current 
  • trunk/eraser/Eraser.Util/NativeMethods/Kernel.cs

    r2002 r2073  
    3333    internal static partial class NativeMethods 
    3434    { 
     35        /// <summary> 
     36        /// Copies an existing file to a new file, notifying the application of 
     37        /// its progress through a callback function. 
     38        /// </summary> 
     39        /// <param name="lpExistingFileName">The name of an existing file. 
     40        ///  
     41        /// In the ANSI version of this function, the name is limited to MAX_PATH 
     42        /// characters. To extend this limit to 32,767 wide characters, call the 
     43        /// ]Unicode version of the function and prepend "\\?\" to the path. 
     44        /// For more information, see Naming a File. 
     45        ///  
     46        /// If lpExistingFileName does not exist, the CopyFileEx function fails, 
     47        /// and the GetLastError function returns ERROR_FILE_NOT_FOUND.</param> 
     48        /// <param name="lpNewFileName">The name of the new file. 
     49        ///  
     50        /// In the ANSI version of this function, the name is limited to MAX_PATH 
     51        /// characters. To extend this limit to 32,767 wide characters, call the 
     52        /// Unicode version of the function and prepend "\\?\" to the path. For 
     53        /// more information, see Naming a File.</param> 
     54        /// <param name="lpProgressRoutine">The address of a callback function of 
     55        /// type <see cref="ExtensionMethods.IO.CopyProgressFunction"/> that is 
     56        /// called each time another portion of the file has been copied. This 
     57        /// parameter can be NULL. For more information on the progress callback 
     58        /// function, see the <see cref="ExtensionMethods.IO.CopyProgressFunction"/> 
     59        /// function.</param> 
     60        /// <param name="lpData">The argument to be passed to the callback function. 
     61        /// This parameter can be NULL.</param> 
     62        /// <param name="pbCancel">If this flag is set to TRUE during the copy 
     63        /// operation, the operation is canceled. Otherwise, the copy operation 
     64        /// will continue to completion.</param> 
     65        /// <param name="dwCopyFlags">Flags that specify how the file is to be 
     66        /// copied. This parameter can be a combination of the 
     67        /// <see cref="CopyFileFlags"/> enumeration. 
     68        /// </param> 
     69        /// <returns>If the function succeeds, the return value is nonzero. 
     70        ///  
     71        /// If the function fails, the return value is zero. To get extended error information 
     72        /// call <see cref="Marshal.GetLastWin32Error"/>. 
     73        ///  
     74        /// If lpProgressRoutine returns PROGRESS_CANCEL due to the user canceling the 
     75        /// operation, CopyFileEx will return zero and GetLastError will return 
     76        /// ERROR_REQUEST_ABORTED. In this case, the partially copied destination file is 
     77        /// deleted. 
     78        ///  
     79        /// If lpProgressRoutine returns PROGRESS_STOP due to the user stopping the 
     80        /// operation, CopyFileEx will return zero and GetLastError will return 
     81        /// ERROR_REQUEST_ABORTED. In this case, the partially copied destination file 
     82        /// is left intact.</returns> 
     83        [DllImport("Kernel32.dll", SetLastError = true)] 
     84        public static extern bool CopyFileEx(string lpExistingFileName, 
     85            string lpNewFileName, CopyProgressFunction lpProgressRoutine, 
     86            IntPtr lpData, ref bool pbCancel, CopyFileFlags dwCopyFlags); 
     87 
     88        /// <summary> 
     89        /// Flags used with <see cref="CopyFileEx"/> 
     90        /// </summary> 
     91        [Flags] 
     92        public enum CopyFileFlags 
     93        { 
     94            /// <summary> 
     95            /// An attempt to copy an encrypted file will succeed even if the 
     96            /// destination copy cannot be encrypted. 
     97            ///  
     98            /// Windows 2000: This value is not supported. 
     99            /// </summary> 
     100            AllowDecryptedDestination = 0x00000008, 
     101 
     102            /// <summary> 
     103            /// If the source file is a symbolic link, the destination file is 
     104            /// also a symbolic link pointing to the same file that the source 
     105            /// symbolic link is pointing to. 
     106            ///  
     107            /// Windows Server 2003 and Windows XP/2000: This value is not 
     108            /// supported. 
     109            /// </summary> 
     110            CopySymlink = 0x00000800, 
     111 
     112            /// <summary> 
     113            /// The copy operation fails immediately if the target file already 
     114            /// exists. 
     115            /// </summary> 
     116            FailIfExists = 0x00000001, 
     117 
     118            /// <summary> 
     119            /// The copy operation is performed using unbuffered I/O, bypassing 
     120            /// system I/O cache resources. Recommended for very large file 
     121            /// transfers. 
     122            /// 
     123            /// Windows Server 2003 and Windows XP/2000: This value is not 
     124            /// supported. 
     125            /// </summary> 
     126            NoBuffering = 0x00001000, 
     127 
     128            /// <summary> 
     129            /// The file is copied and the original file is opened for write 
     130            /// access. 
     131            /// </summary> 
     132            OpenSourceForWrite = 0x00000004, 
     133 
     134            /// <summary> 
     135            /// Progress of the copy is tracked in the target file in case the 
     136            /// copy fails. The failed copy can be restarted at a later time by 
     137            /// specifying the same values for lpExistingFileName and lpNewFileName 
     138            /// as those used in the call that failed. 
     139            /// </summary> 
     140            Restartable = 0x00000002 
     141        } 
     142 
     143        /// <summary> 
     144        /// An application-defined callback function used with the CopyFileEx, 
     145        /// MoveFileTransacted, and MoveFileWithProgress functions. It is called when 
     146        /// a portion of a copy or move operation is completed. The LPPROGRESS_ROUTINE 
     147        /// type defines a pointer to this callback function. CopyProgressRoutine is 
     148        /// a placeholder for the application-defined function name. 
     149        /// </summary> 
     150        /// <param name="TotalFileSize">The total size of the file, in bytes.</param> 
     151        /// <param name="TotalBytesTransferred">The total number of bytes 
     152        /// transferred from the source file to the destination file since the 
     153        /// copy operation began.</param> 
     154        /// <param name="StreamSize">The total size of the current file stream, 
     155        /// in bytes.</param> 
     156        /// <param name="StreamBytesTransferred">The total number of bytes in the 
     157        /// current stream that have been transferred from the source file to the 
     158        /// destination file since the copy operation began.</param> 
     159        /// <param name="dwStreamNumber">A handle to the current stream. The 
     160        /// first time CopyProgressRoutine is called, the stream number is 1.</param> 
     161        /// <param name="dwCallbackReason">The reason that CopyProgressRoutine was 
     162        /// called. This parameter can be one of the following values.</param> 
     163        /// <param name="hSourceFile">A handle to the source file.</param> 
     164        /// <param name="hDestinationFile">A handle to the destination file.</param> 
     165        /// <param name="lpData">Argument passed to CopyProgressRoutine by CopyFileEx, 
     166        /// MoveFileTransacted, or MoveFileWithProgress.</param> 
     167        /// <returns>The CopyProgressRoutine function should return one of the 
     168        /// <see cref="CopyProgressFunctionResult"/> values.</returns> 
     169        public delegate ExtensionMethods.IO.CopyProgressFunctionResult CopyProgressFunction( 
     170            long TotalFileSize, long TotalBytesTransferred, long StreamSize, 
     171            long StreamBytesTransferred, uint dwStreamNumber, 
     172            CopyProgressFunctionCallbackReasons dwCallbackReason, 
     173            SafeFileHandle hSourceFile, SafeFileHandle hDestinationFile, IntPtr lpData); 
     174 
     175        /// <summary> 
     176        /// Callback reasons for the <see cref="CopyProgressFunction"/> callbacks. 
     177        /// </summary> 
     178        public enum CopyProgressFunctionCallbackReasons 
     179        { 
     180            /// <summary> 
     181            /// Another part of the data file was copied. 
     182            /// </summary> 
     183            ChunkFinished = 0x00000000, 
     184 
     185            /// <summary> 
     186            /// Another stream was created and is about to be copied. This is 
     187            /// the callback reason given when the callback routine is first invoked. 
     188            /// </summary> 
     189            StreamSwitch = 0x00000001 
     190        } 
     191 
    35192        /// <summary> 
    36193        /// Deletes an existing file. 
Note: See TracChangeset for help on using the changeset viewer.