Changeset 1142


Ignore:
Timestamp:
6/19/2009 6:34:00 AM (6 years ago)
Author:
lowjoel
Message:

-More error-proof cluster tip erasure. This is because of how we now cache a reference to the opened handle so when the StreamInfo? class needs to set file times it can use the cached exclusive handle.
-Do not let the OnProgressChanged? event be called with an empty item name

Location:
trunk/eraser6
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/eraser6/Eraser.Manager/DirectExecutor.cs

    r1134 r1142  
    804804                return; 
    805805 
    806             try 
    807             { 
    808                 //Otherwise, create the stream, lengthen the file, then tell the erasure 
    809                 //method to erase the cluster tips. 
    810                 using (FileStream stream = streamInfo.Open(FileMode.Open, FileAccess.Write, 
    811                     FileShare.None, FileOptions.WriteThrough)) 
    812                 { 
    813                     try 
    814                     { 
    815                         stream.SetLength(fileArea); 
    816                         stream.Seek(fileLength, SeekOrigin.Begin); 
    817  
    818                         //Erase the file 
    819                         method.Erase(stream, long.MaxValue, PrngManager.GetInstance( 
    820                             ManagerLibrary.Settings.ActivePrng), null); 
    821                     } 
    822                     finally 
    823                     { 
    824                         //Make sure the file length is restored! 
    825                         stream.SetLength(fileLength); 
    826                     } 
    827                 } 
    828             } 
    829             finally 
    830             { 
    831                 //Reset the file times 
    832                 streamInfo.LastAccessTime = lastAccess; 
    833                 streamInfo.LastWriteTime = lastWrite; 
    834                 streamInfo.CreationTime = created; 
     806            //Otherwise, create the stream, lengthen the file, then tell the erasure 
     807            //method to erase the cluster tips. 
     808            using (FileStream stream = streamInfo.Open(FileMode.Open, FileAccess.Write, 
     809                FileShare.None, FileOptions.WriteThrough)) 
     810            { 
     811                try 
     812                { 
     813                    stream.SetLength(fileArea); 
     814                    stream.Seek(fileLength, SeekOrigin.Begin); 
     815 
     816                    //Erase the file 
     817                    method.Erase(stream, long.MaxValue, PrngManager.GetInstance( 
     818                        ManagerLibrary.Settings.ActivePrng), null); 
     819                } 
     820                finally 
     821                { 
     822                    //Make sure the file length is restored! 
     823                    stream.SetLength(fileLength); 
     824 
     825                    //Reset the file times 
     826                    streamInfo.LastAccessTime = lastAccess; 
     827                    streamInfo.LastWriteTime = lastWrite; 
     828                    streamInfo.CreationTime = created; 
     829                } 
    835830            } 
    836831        } 
     
    977972            { 
    978973                progress.Event.CurrentTargetStatus = S._("Removing folders..."); 
    979                 task.OnProgressChanged(progress.Event); 
    980  
     974                 
    981975                //Remove all subfolders which are empty. 
    982976                FolderTarget fldr = (FolderTarget)target; 
     
    987981                    foreach (DirectoryInfo subDir in info.GetDirectories()) 
    988982                        eraseEmptySubFolders(subDir); 
     983 
     984                    progress.Event.CurrentItemName = info.FullName; 
     985                    task.OnProgressChanged(progress.Event); 
     986 
    989987                    FileSystemInfo[] files = info.GetFileSystemInfos(); 
    990988                    if (files.Length == 0) 
     
    996994                { 
    997995                    DirectoryInfo info = new DirectoryInfo(fldr.Path); 
     996                    progress.Event.CurrentItemName = info.FullName; 
     997                    task.OnProgressChanged(progress.Event); 
    998998 
    999999                    //See if this is the root of a volume. 
  • trunk/eraser6/Eraser.Util/StreamInfo.cs

    r1062 r1142  
    182182            { 
    183183                DateTime creationTime, lastAccess, lastWrite; 
    184                 using (SafeFileHandle handle = fileHandle) 
    185                     KernelApi.GetFileTime(handle, out creationTime, out lastAccess, 
    186                         out lastWrite); 
     184                GetFileTime(out creationTime, out lastAccess, out lastWrite); 
    187185                return lastAccess; 
    188186            } 
    189187            set 
    190188            { 
    191                 using (SafeFileHandle handle = OpenHandle(FileMode.Open, FileAccess.Write, 
    192                     FileShare.Read, FileOptions.None)) 
     189                SetFileTime(DateTime.MinValue, value, DateTime.MinValue); 
     190            } 
     191        } 
     192 
     193        public DateTime LastWriteTime 
     194        { 
     195            get 
     196            { 
     197                DateTime creationTime, lastAccess, lastWrite; 
     198                GetFileTime(out creationTime, out lastAccess, out lastWrite); 
     199                return lastWrite; 
     200            } 
     201            set 
     202            { 
     203                SetFileTime(DateTime.MinValue, DateTime.MinValue, value); 
     204            } 
     205        } 
     206 
     207        public DateTime CreationTime 
     208        { 
     209            get 
     210            { 
     211                DateTime creationTime, lastAccess, lastWrite; 
     212                GetFileTime(out creationTime, out lastAccess, out lastWrite); 
     213                return creationTime; 
     214            } 
     215            set 
     216            { 
     217                SetFileTime(value, DateTime.MinValue, DateTime.MinValue); 
     218            } 
     219        } 
     220 
     221        private void GetFileTime(out DateTime creationTime, out DateTime lastAccess, 
     222            out DateTime lastWrite) 
     223        { 
     224            SafeFileHandle handle = exclusiveHandle; 
     225            bool ownsHandle = false; 
     226            try 
     227            { 
     228                if (handle == null || handle.IsClosed || handle.IsInvalid) 
    193229                { 
    194                     KernelApi.SetFileTime(handle, DateTime.MinValue, value, DateTime.MinValue); 
     230                    handle = fileHandle; 
     231                    ownsHandle = true; 
    195232                } 
    196233            } 
    197         } 
    198  
    199         public DateTime LastWriteTime 
    200         { 
    201             get 
    202             { 
    203                 DateTime creationTime, lastAccess, lastWrite; 
    204                 using (SafeFileHandle handle = fileHandle) 
    205                     KernelApi.GetFileTime(handle, out creationTime, out lastAccess, 
    206                         out lastWrite); 
    207                 return lastWrite; 
    208             } 
    209             set 
    210             { 
    211                 using (SafeFileHandle handle = OpenHandle(FileMode.Open, FileAccess.Write, 
    212                     FileShare.Read, FileOptions.None)) 
     234            catch (ObjectDisposedException) 
     235            { 
     236                handle = fileHandle; 
     237                ownsHandle = true; 
     238            } 
     239 
     240            try 
     241            { 
     242                KernelApi.GetFileTime(handle, out creationTime, out lastAccess, out lastWrite); 
     243            } 
     244            finally 
     245            { 
     246                if (ownsHandle) 
     247                    handle.Close(); 
     248            } 
     249        } 
     250 
     251        private void SetFileTime(DateTime creationTime, DateTime lastAccess, DateTime lastWrite) 
     252        { 
     253            SafeFileHandle handle = exclusiveHandle; 
     254            bool ownsHandle = false; 
     255            try 
     256            { 
     257                if (handle == null || handle.IsClosed || handle.IsInvalid) 
    213258                { 
    214                     KernelApi.SetFileTime(handle, DateTime.MinValue, DateTime.MinValue, value); 
     259                    handle = fileHandle; 
     260                    ownsHandle = true; 
    215261                } 
    216262            } 
    217         } 
    218  
    219         public DateTime CreationTime 
    220         { 
    221             get 
    222             { 
    223                 DateTime creationTime, lastAccess, lastWrite; 
    224                 using (SafeFileHandle handle = fileHandle) 
    225                     KernelApi.GetFileTime(handle, out creationTime, out lastAccess, 
    226                         out lastWrite); 
    227                 return creationTime; 
    228             } 
    229             set 
    230             { 
    231                 using (SafeFileHandle handle = OpenHandle(FileMode.Open, FileAccess.Write, 
    232                     FileShare.Read, FileOptions.None)) 
    233                 { 
    234                     KernelApi.SetFileTime(handle, value, DateTime.MinValue, DateTime.MinValue); 
    235                 } 
     263            catch (ObjectDisposedException) 
     264            { 
     265                handle = fileHandle; 
     266                ownsHandle = true; 
     267            } 
     268 
     269            try 
     270            { 
     271                KernelApi.SetFileTime(handle, creationTime, lastAccess, lastWrite); 
     272            } 
     273            finally 
     274            { 
     275                if (ownsHandle) 
     276                    handle.Close(); 
    236277            } 
    237278        } 
     
    351392            if (result.IsInvalid) 
    352393                throw KernelApi.GetExceptionForWin32Error(Marshal.GetLastWin32Error()); 
     394 
     395            //Cache the handle if we have an exclusive handle - this is used for things like 
     396            //file times. 
     397            if (share == FileShare.None) 
     398                exclusiveHandle = result; 
    353399            return result; 
    354400        } 
     
    374420            } 
    375421        } 
    376  
     422         
     423        /// <summary> 
     424        /// Cached exclusive file handle. This is used for setting file access times 
     425        /// </summary> 
     426        private SafeFileHandle exclusiveHandle; 
    377427        private string fileName; 
    378428        private string streamName; 
Note: See TracChangeset for help on using the changeset viewer.