Changeset 2523 for trunk/eraser


Ignore:
Timestamp:
3/14/2012 9:58:21 AM (3 years ago)
Author:
lowjoel
Message:

Implement recycle bin erasures according to what Vista and 7 would detect as part of the Recycle Bin. This would erase recycle bins which are on UNC paths and mounted drives without a drive letter. Tested and works with Windows 7 and Windows XP SP3.

Location:
trunk/eraser
Files:
3 edited

Legend:

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

    r2522 r2523  
    3232using Eraser.Plugins; 
    3333using Eraser.Plugins.ExtensionPoints; 
     34using Microsoft.Win32; 
    3435 
    3536namespace Eraser.DefaultPlugins 
     
    7576        protected override List<StreamInfo> GetPaths() 
    7677        { 
    77             List<StreamInfo> result = new List<StreamInfo>(); 
     78            List<DirectoryInfo> directories = new List<DirectoryInfo>(); 
    7879            string[] rootDirectory = new string[] { 
    7980                    "$RECYCLE.BIN", 
     
    8485                User.ToString(); 
    8586 
    86             foreach (DriveInfo drive in DriveInfo.GetDrives()) 
     87            //First try to get the recycle bin on each of of the physical volumes we have 
     88            foreach (VolumeInfo volume in VolumeInfo.Volumes) 
    8789            { 
     90                if (!volume.IsMounted) 
     91                    continue; 
     92 
    8893                foreach (string rootDir in rootDirectory) 
    8994                { 
    9095                    //First get the global recycle bin for the current drive 
    91                     string recycleBinPath = System.IO.Path.Combine(drive.Name, rootDir); 
     96                    string recycleBinPath = System.IO.Path.Combine( 
     97                        volume.MountPoints[0].FullName, rootDir); 
    9298                    if (!Directory.Exists(recycleBinPath)) 
    9399                        continue; 
     
    97103                        recycleBinPath = System.IO.Path.Combine(recycleBinPath, userSid); 
    98104 
    99                     foreach (FileInfo file in GetFiles(new DirectoryInfo(recycleBinPath))) 
     105                    directories.Add(new DirectoryInfo(recycleBinPath)); 
     106                } 
     107            } 
     108 
     109            //Then try the Shell's known folders for Vista and later 
     110            using (RegistryKey key = Registry.CurrentUser.OpenSubKey( 
     111                "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\BitBucket\\KnownFolder")) 
     112            { 
     113                if (key != null) 
     114                { 
     115                    string[] knownFolders = key.GetSubKeyNames(); 
     116                    foreach (string stringGuid in knownFolders) 
    100117                    { 
    101                         //Add the ADSes 
    102                         result.AddRange(GetPathADSes(file)); 
     118                        Guid guid = new Guid(stringGuid); 
     119                        DirectoryInfo info = Shell.KnownFolderIDs.GetPath(guid); 
    103120 
    104                         //Then the file itself 
    105                         result.Add(new StreamInfo(file.FullName)); 
     121                        if (info == null) 
     122                            continue; 
     123 
     124                        directories.Add(info); 
    106125                    } 
    107126                } 
    108127            } 
     128 
     129            //Then get all the files in each of the directories 
     130            List<StreamInfo> result = new List<StreamInfo>(); 
     131            foreach (DirectoryInfo directory in directories) 
     132                foreach (FileInfo file in GetFiles(directory)) 
     133                { 
     134                    //Add the ADSes 
     135                    result.AddRange(GetPathADSes(file)); 
     136 
     137                    //Then the file itself 
     138                    result.Add(new StreamInfo(file.FullName)); 
     139                } 
    109140 
    110141            return result; 
  • trunk/eraser/Eraser.Util/NativeMethods/Shell.cs

    r2516 r2523  
    414414        public static extern bool SHGetPathFromIDList(IntPtr pidl, 
    415415            StringBuilder pszPath); 
     416 
     417        /// <summary> 
     418        /// Retrieves the full path of a known folder identified by the folder's KNOWNFOLDERID. 
     419        /// </summary> 
     420        /// <param name="rfid">A reference to the KNOWNFOLDERID that identifies the 
     421        /// folder.</param> 
     422        /// <param name="dwFlags">Flags that specify special retrieval options. This value 
     423        /// can be 0; otherwise, one or more of the KNOWN_FOLDER_FLAG values.</param> 
     424        /// <param name="hToken">An access token that represents a particular user. If 
     425        /// this parameter is NULL, which is the most common usage, the function requests 
     426        /// the known folder for the current user. 
     427        ///  
     428        /// Request a specific user's folder by passing the hToken of that user. This is 
     429        /// typically done in the context of a service that has sufficient privileges to 
     430        /// retrieve the token of a given user. That token must be opened with TOKEN_QUERY 
     431        /// and TOKEN_IMPERSONATE rights. In addition to passing the user's hToken, the 
     432        /// registry hive of that specific user must be mounted. See Access Control for 
     433        /// further discussion of access control issues. 
     434        ///  
     435        /// Assigning the hToken parameter a value of -1 indicates the Default User. This 
     436        /// allows clients of SHGetKnownFolderPath to find folder locations (such as the 
     437        /// Desktop folder) for the Default User. The Default User user profile is duplicated 
     438        /// when any new user account is created, and includes special folders such as 
     439        /// Documents and Desktop. Any items added to the Default User folder also appear in 
     440        /// any new user account. Note that access to the Default User folders requires 
     441        /// administrator privileges.</param> 
     442        /// <param name="ppszPath">When this method returns, contains the address of a 
     443        /// pointer to a null-terminated Unicode string that specifies the path of the 
     444        /// known folder. The calling process is responsible for freeing this resource 
     445        /// once it is no longer needed by calling CoTaskMemFree. The returned path does 
     446        /// not include a trailing backslash. For example, "C:\Users" is returned rather 
     447        /// than "C:\Users\".</param> 
     448        /// <returns>Returns S_OK if successful, or an error value otherwise</returns> 
     449        [DllImport("Shell32.dll", CharSet = CharSet.Unicode)] 
     450        [return: MarshalAs(UnmanagedType.Error)] 
     451        internal static extern uint SHGetKnownFolderPath( 
     452            ref Guid rfid, uint dwFlags, IntPtr hToken, out IntPtr ppszPath); 
    416453    } 
    417454} 
  • trunk/eraser/Eraser.Util/Shell.cs

    r2516 r2523  
    121121                } 
    122122            } 
     123 
     124            /// <summary> 
     125            /// Retrieves the full path of a known folder identified by the folder's 
     126            /// KNOWNFOLDERID. 
     127            /// </summary> 
     128            /// <param name="guid">The KNOWNFOLDERID that identifies the folder.</param> 
     129            /// <returns>The DirectoryInfo for the given known folder path, or null if 
     130            /// an error occurred.</returns> 
     131            public static DirectoryInfo GetPath(Guid guid) 
     132            { 
     133                try 
     134                { 
     135                    IntPtr path = IntPtr.Zero; 
     136                    uint result = NativeMethods.SHGetKnownFolderPath(ref guid, 0, IntPtr.Zero, 
     137                        out path); 
     138 
     139                    if (result == 0) 
     140                    { 
     141                        string pathStr = Marshal.PtrToStringUni(path); 
     142                        Marshal.FreeCoTaskMem(path); 
     143 
     144                        return new DirectoryInfo(pathStr); 
     145                    } 
     146                    else 
     147                    { 
     148                        throw Marshal.GetExceptionForHR((int)result); 
     149                    } 
     150                } 
     151                catch (EntryPointNotFoundException) 
     152                { 
     153                    return null; 
     154                } 
     155            } 
    123156        } 
    124157    } 
Note: See TracChangeset for help on using the changeset viewer.