Changeset 795


Ignore:
Timestamp:
12/12/2008 3:04:28 AM (6 years ago)
Author:
lowjoel
Message:

-Replace FAT/MFT with a more file system neutral term "file system entries". That will be used in place of the specific terms in the UI, but in the code MFT and FAT will be used when referring to the specific file systems.
-Remove *both* resident file system table files and the old file system entries. Previous versions were implemented wrongly in that they implemented the former but not the latter. This rixes #89.
-Added a basic NTFS API for use in file system table clean ups.

Location:
branches/eraser6
Files:
1 added
6 edited

Legend:

Unmodified
Added
Removed
  • branches/eraser6/Manager/DirectExecutor.cs

    r778 r795  
    595595                } 
    596596 
    597                 //Erase old file system records 
    598                 progress.Event.currentItemName = S._("Old file system records"); 
     597                //Erase old resident file system table files 
     598                progress.Event.currentItemName = S._("Old resident file system table files"); 
    599599                task.OnProgressChanged(progress.Event); 
    600                 EraseFilesystemRecords(info, method); 
     600                EraseOldFilesystemResidentFiles(info, method, null); 
    601601            } 
    602602            finally 
    603603            { 
     604                //Remove the folder holding all our temporary files. 
    604605                progress.Event.currentItemName = S._("Removing temporary files"); 
    605606                task.OnProgressChanged(progress.Event); 
    606  
    607                 //Remove the folder holding all our temporary files. 
    608607                RemoveFolder(info); 
    609608            } 
     609 
     610            //Then clean the old file system entries 
     611            progress.Event.currentItemName = S._("Old file system entries"); 
     612            EraseOldFilesystemEntries(info.Parent, 
     613                delegate(int currentFile, int totalFiles) 
     614                { 
     615                    progress.Event.currentItemProgress = (float)currentFile / totalFiles; 
     616                    progress.Event.CurrentTargetProgress = (float)( 
     617                        0.9 + progress.Event.CurrentItemProgress / 10); 
     618                    task.OnProgressChanged(progress.Event); 
     619                } 
     620            ); 
    610621        } 
    611622 
     
    739750            } 
    740751        } 
     752 
     753        /// <summary> 
     754        /// The prototype of callbacks handling the file system table erase progress 
     755        /// </summary> 
     756        /// <param name="currentFile">The current file being erased.</param> 
     757        /// <param name="totalFiles">The estimated number of files that must be erased.</param> 
     758        private delegate void FilesystemEntriesEraseProgress(int currentFile, int totalFiles); 
    741759         
    742760        /// <summary> 
    743         /// Erases the old MFT or FAT records. This creates small one-byte files 
    744         /// until the MFT or FAT grows, if the disk is not full. If the disk is 
    745         /// full, just keep forcing the MFT to store files until nothing else 
    746         /// fits. 
     761        /// Erases old file system table-resident files. This creates small one-byte 
     762        /// files until disk is full. This will erase unused space which was used for 
     763        /// files resident in the file system table. 
    747764        /// </summary> 
    748765        /// <param name="info">The directory information structure containing 
    749         /// the path to store the temporary one-byte files. The MFT of that 
    750         /// drive will be erased.</param> 
    751         /// <param name="method">The method used to erase the records.</param> 
    752         private void EraseFilesystemRecords(DirectoryInfo info, ErasureMethod method) 
     766        /// the path to store the temporary one-byte files. The file system table 
     767        /// of that drive will be erased.</param> 
     768        /// <param name="method">The method used to erase the files.</param> 
     769        private void EraseOldFilesystemResidentFiles(DirectoryInfo info, ErasureMethod method, 
     770            FilesystemEntriesEraseProgress callback) 
    753771        { 
    754772            VolumeInfo volInfo = VolumeInfo.FromMountpoint(info.FullName); 
    755             string volFormat = volInfo.VolumeFormat; 
    756             if (volFormat == "NTFS") 
    757             { 
    758                 //If the volume is full, squeeze one-byte files. 
     773            if (volInfo.VolumeFormat == "NTFS") 
     774            { 
    759775                try 
    760776                { 
    761                     StreamInfo mftInfo = new StreamInfo(Path.Combine(volInfo.VolumeID, "$MFT")); 
    762                     long oldMFTSize = mftInfo.Length; 
     777                    //Squeeze one-byte files until the volume or the MFT is full. 
     778                    long oldMFTSize = NtfsAPI.GetMftValidSize(volInfo); 
    763779                    for ( ; ; ) 
    764780                    { 
     
    768784                            FileMode.CreateNew, FileAccess.Write)) 
    769785                        { 
    770                             //Stretch the file size to the size of one MFT record 
    771                             strm.SetLength(1); 
     786                            //Stretch the file size to use up some of the resident space. 
     787                            strm.SetLength(volInfo.ClusterSize); 
    772788 
    773789                            //Then run the erase task 
     
    777793                        } 
    778794 
    779                         //Determine if we can stop. We will stop if the disk is not 
    780                         //full and the MFT has grown in size. 
    781                         if (volInfo.AvailableFreeSpace != 0 && mftInfo.Length != oldMFTSize) 
     795                        //We can stop when the MFT has grown. 
     796                        if (NtfsAPI.GetMftValidSize(volInfo) > oldMFTSize) 
    782797                            break; 
    783798                    } 
     
    786801                { 
    787802                    //OK, enough squeezing. 
     803                } 
     804            } 
     805        } 
     806 
     807        /// <summary> 
     808        /// Erases the unused space in the file system table by creating files, until 
     809        /// the table grows. 
     810        ///  
     811        /// This will overwrite unused portions of the table which were previously 
     812        /// used to store file entries. 
     813        /// </summary> 
     814        /// <param name="info">The directory information structure containing the path 
     815        /// to store the temporary files.</param> 
     816        /// <param name="callback">The callback function to handle the progress of the 
     817        /// file system entry erasure.</param> 
     818        private void EraseOldFilesystemEntries(DirectoryInfo info, FilesystemEntriesEraseProgress callback) 
     819        { 
     820            VolumeInfo volInfo = VolumeInfo.FromMountpoint(info.FullName); 
     821            if (volInfo.VolumeFormat == "NTFS") 
     822            { 
     823                //Create a directory to hold all the temporary files 
     824                DirectoryInfo tempDir = info.CreateSubdirectory(GenerateRandomFileName(32)); 
     825 
     826                try 
     827                { 
     828                    //Get the size of the MFT 
     829                    long mftSize = NtfsAPI.GetMftValidSize(volInfo); 
     830                    long mftRecordSegmentSize = NtfsAPI.GetMftRecordSegmentSize(volInfo); 
     831                    int pollingInterval = (int)(mftSize / volInfo.ClusterSize / 20); 
     832                    int totalFiles = Math.Max(1, (int)(mftSize / mftRecordSegmentSize)); 
     833 
     834                    for (int files = 0; ; ++files) 
     835                    { 
     836                        using (FileStream strm = new FileStream(Path.Combine( 
     837                            info.FullName, GenerateRandomFileName(18)), FileMode.CreateNew, 
     838                            FileAccess.Write)) 
     839                        { 
     840                        } 
     841 
     842                        if (files % pollingInterval == 0) 
     843                        { 
     844                            if (callback != null) 
     845                                callback(files, totalFiles); 
     846 
     847                            lock (currentTask) 
     848                                if (currentTask.Cancelled) 
     849                                    throw new FatalException(S._("The task was cancelled.")); 
     850 
     851                            //Check if the MFT has grown. 
     852                            if (mftSize < NtfsAPI.GetMftValidSize(volInfo)) 
     853                                break; 
     854                        } 
     855                    } 
     856                } 
     857                catch (IOException) 
     858                { 
     859                } 
     860                finally 
     861                { 
     862                    //Clear up all the temporary files 
     863                    RemoveFolder(tempDir); 
    788864                } 
    789865            } 
    790866            else 
    791867                throw new NotImplementedException(S._("Could not erase old file system " + 
    792                     "records: Unsupported File system")); //Eraser.cpp@2348 
     868                    "entries: Unsupported File system")); //Eraser.cpp@2348 
    793869        } 
    794870 
     
    9381014            info.Attributes = FileAttributes.NotContentIndexed; 
    9391015 
    940             //Rename the file a few times to erase the record from the MFT. 
     1016            //Rename the file a few times to erase the entry from the file system 
     1017            //table. 
    9411018            for (int i = 0, tries = 0; i < FilenameErasePasses; ++tries) 
    9421019            { 
  • branches/eraser6/Manager/Executor.cs

    r741 r795  
    201201        /// <summary> 
    202202        /// The number of times file names are renamed to erase the file name from 
    203         /// the MFT. 
     203        /// the file system table. 
    204204        /// </summary> 
    205205        protected const int FilenameErasePasses = 7; 
  • branches/eraser6/Manager/Strings.en.resx

    r607 r795  
    145145    <value>The task was cancelled.</value> 
    146146  </data> 
     147  <data name="Old resident file system entries" xml:space="preserve"> 
     148    <value>Old resident file system entries</value> 
     149  </data> 
     150  <data name="Removing temporary files" xml:space="preserve"> 
     151    <value>Removing temporary files</value> 
     152  </data> 
    147153  <data name="Old file system records" xml:space="preserve"> 
    148154    <value>Old file system records</value> 
    149155  </data> 
    150   <data name="Removing temporary files" xml:space="preserve"> 
    151     <value>Removing temporary files</value> 
    152   </data> 
    153156  <data name="Files in {0} did not have their cluster tips erased because it is a hard link or a symbolic link." xml:space="preserve"> 
    154157    <value>Files in {0} did not have their cluster tips erased because it is a hard link or a symbolic link.</value> 
  • branches/eraser6/Manager/Strings.nl.resx

    r605 r795  
    145145    <value>(Untranslated)</value> 
    146146  </data> 
     147  <data name="Old resident file system entries" xml:space="preserve"> 
     148    <value>(Untranslated)</value> 
     149  </data> 
     150  <data name="Removing temporary files" xml:space="preserve"> 
     151    <value>(Untranslated)</value> 
     152  </data> 
    147153  <data name="Old file system records" xml:space="preserve"> 
    148154    <value>(Untranslated)</value> 
    149155  </data> 
    150   <data name="Removing temporary files" xml:space="preserve"> 
    151     <value>(Untranslated)</value> 
    152   </data> 
    153156  <data name="Files in {0} did not have their cluster tips erased because it is a hard link or a symbolic link." xml:space="preserve"> 
    154157    <value>(Untranslated)</value> 
  • branches/eraser6/Manager/Strings.resx

    r605 r795  
    145145    <value>The task was cancelled.</value> 
    146146  </data> 
     147  <data name="Old resident file system entries" xml:space="preserve"> 
     148    <value>Old resident file system entries</value> 
     149  </data> 
     150  <data name="Removing temporary files" xml:space="preserve"> 
     151    <value>Removing temporary files</value> 
     152  </data> 
    147153  <data name="Old file system records" xml:space="preserve"> 
    148154    <value>Old file system records</value> 
    149155  </data> 
    150   <data name="Removing temporary files" xml:space="preserve"> 
    151     <value>Removing temporary files</value> 
    152   </data> 
    153156  <data name="Files in {0} did not have their cluster tips erased because it is a hard link or a symbolic link." xml:space="preserve"> 
    154157    <value>Files in {0} did not have their cluster tips erased because it is a hard link or a symbolic link.</value> 
  • branches/eraser6/Util/Util.csproj

    r780 r795  
    5050    <Compile Include="Localisation.cs" /> 
    5151    <Compile Include="MsCorEEAPI.cs" /> 
     52    <Compile Include="NtfsAPI.cs" /> 
    5253    <Compile Include="StreamInfo.cs" /> 
    5354    <Compile Include="KernelAPI.cs" /> 
Note: See TracChangeset for help on using the changeset viewer.