Ignore:
Timestamp:
6/13/2010 12:29:44 AM (2 years ago)
Author:
lowjoel
Message:

Implements #273: Use NtSetInformationFile? to deeply set file times.

File:
1 edited

Legend:

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

    r2151 r2155  
    5050 
    5151        /// <summary> 
     52        /// Deeply sets the file times associated with the current 
     53        /// <see cref="FileInfo"/> object. 
     54        /// </summary> 
     55        /// <param name="updateTime">The time the basic information was last set.</param> 
     56        /// <param name="createdTime">The time the file was created.</param> 
     57        /// <param name="lastModifiedTime">The time the file was last modified.</param> 
     58        /// <param name="lastAccessedTime">The time the file was last accessed.</param> 
     59        public static void SetTimes(this FileSystemInfo info, DateTime updateTime, 
     60            DateTime createdTime, DateTime lastModifiedTime, DateTime lastAccessedTime) 
     61        { 
     62            FileInfo file = info as FileInfo; 
     63            DirectoryInfo directory = info as DirectoryInfo; 
     64 
     65            if (file != null) 
     66                file.SetTimes(updateTime, createdTime, lastModifiedTime, lastAccessedTime); 
     67            else if (directory != null) 
     68                directory.SetTimes(updateTime, createdTime, lastModifiedTime, lastAccessedTime); 
     69            else 
     70                throw new NotImplementedException(); 
     71        } 
     72 
     73        /// <summary> 
     74        /// Deeply sets the file times associated with the current 
     75        /// <see cref="FileInfo"/> object. 
     76        /// </summary> 
     77        /// <param name="updateTime">The time the basic information was last set.</param> 
     78        /// <param name="createdTime">The time the file was created.</param> 
     79        /// <param name="lastModifiedTime">The time the file was last modified.</param> 
     80        /// <param name="lastAccessedTime">The time the file was last accessed.</param> 
     81        public static void SetTimes(this FileInfo info, DateTime updateTime, 
     82            DateTime createdTime, DateTime lastModifiedTime, DateTime lastAccessedTime) 
     83        { 
     84            using (SafeFileHandle streamHandle = new StreamInfo(info.FullName). 
     85                OpenHandle(FileMode.Open, NativeMethods.FILE_WRITE_ATTRIBUTES, 
     86                    FileShare.ReadWrite, FileOptions.None)) 
     87            { 
     88                SetTimes(streamHandle, updateTime, createdTime, lastModifiedTime, lastAccessedTime); 
     89            } 
     90        } 
     91 
     92        /// <summary> 
     93        /// Deeply sets the file times associated with the current 
     94        /// <see cref="DirectoryInfo"/> object. 
     95        /// </summary> 
     96        /// <param name="updateTime">The time the basic information was last set.</param> 
     97        /// <param name="createdTime">The time the file was created.</param> 
     98        /// <param name="lastModifiedTime">The time the file was last modified.</param> 
     99        /// <param name="lastAccessedTime">The time the file was last accessed.</param> 
     100        public static void SetTimes(this DirectoryInfo info, DateTime updateTime, 
     101            DateTime createdTime, DateTime lastModifiedTime, DateTime lastAccessedTime) 
     102        { 
     103            using (SafeFileHandle streamHandle = new StreamInfo(info.FullName). 
     104                OpenHandle(FileMode.Open, NativeMethods.FILE_WRITE_ATTRIBUTES, 
     105                    FileShare.ReadWrite, (FileOptions)NativeMethods.FILE_FLAG_BACKUP_SEMANTICS)) 
     106            { 
     107                SetTimes(streamHandle, updateTime, createdTime, lastModifiedTime, lastAccessedTime); 
     108            } 
     109        } 
     110 
     111        internal static void SetTimes(SafeFileHandle handle, DateTime updateTime, 
     112            DateTime createdTime, DateTime lastModifiedTime, DateTime lastAccessedTime) 
     113        { 
     114            NativeMethods.FILE_BASIC_INFORMATION fileInfo = 
     115                new NativeMethods.FILE_BASIC_INFORMATION(); 
     116            fileInfo.ChangeTime = updateTime.ToFileTime(); 
     117            fileInfo.CreationTime = createdTime.ToFileTime(); 
     118            fileInfo.LastAccessTime = lastAccessedTime.ToFileTime(); 
     119            fileInfo.LastWriteTime = lastModifiedTime.ToFileTime(); 
     120 
     121            if (fileInfo.ChangeTime == 0) 
     122                throw new ArgumentOutOfRangeException("updateTime"); 
     123            if (fileInfo.CreationTime == 0) 
     124                throw new ArgumentOutOfRangeException("createdTime"); 
     125            if (fileInfo.LastAccessTime == 0) 
     126                throw new ArgumentOutOfRangeException("lastAccessedTime"); 
     127            if (fileInfo.LastWriteTime == 0) 
     128                throw new ArgumentOutOfRangeException("lastModifiedTime"); 
     129 
     130            IntPtr fileInfoPtr = Marshal.AllocHGlobal(Marshal.SizeOf(fileInfo)); 
     131            try 
     132            { 
     133                Marshal.StructureToPtr(fileInfo, fileInfoPtr, true); 
     134                NativeMethods.IO_STATUS_BLOCK status; 
     135                uint result = NativeMethods.NtSetInformationFile(handle, 
     136                    out status, fileInfoPtr, (uint)Marshal.SizeOf(fileInfo), 
     137                    NativeMethods.FILE_INFORMATION_CLASS.FileBasicInformation); 
     138 
     139                if (result != 0) 
     140                    throw new IOException(); 
     141            } 
     142            finally 
     143            { 
     144                Marshal.FreeHGlobal(fileInfoPtr); 
     145            } 
     146        } 
     147 
     148        /// <summary> 
    52149        /// Gets the parent directory of the current <see cref="System.IO.FileSystemInfo"/> 
    53150        /// object. 
Note: See TracChangeset for help on using the changeset viewer.