Results 1 to 9 of 9

Thread: [VB6, Vista] List the Recycle Bin location(s) on a drive

Threaded View

  1. #1

    Thread Starter
    PowerPoster
    Join Date
    Jul 2010
    Location
    NYC
    Posts
    7,654

    Arrow [VB6, Vista] List the Recycle Bin location(s) on a drive


    Hard coded paths aren't the best system, since they change from Windows version to version. So AAraya was asking about how to do this, and after seeing a StackOverflow and OldNewThing post about using IPersist to get the class ID of a folder, I wrote this in response. The code guarantees that the locations returned are the current, official system bin locations. Note that, especially on non-system drives, a Recycle Bin location may only exist when there are files in it, so if you don't get any results it doesn't mean that there won't be the next time you delete a file on that drive.

    Main Code

    This project wraps a single main function, FindRecycleBinsOnDrive:

    Code:
    Private Declare Function ILCreateFromPathW Lib "shell32" (ByVal pwszPath As Long) As Long
    Private Declare Sub CoTaskMemFree Lib "ole32.dll" (ByVal PV As Long) ' Frees memory allocated by the shell
    Private Declare Function SysReAllocString Lib "oleaut32.dll" (ByVal pBSTR As Long, Optional ByVal pszStrPtr As Long) As Long
    Private Declare Function SHCreateItemFromParsingName Lib "shell32" (ByVal pszPath As Long, pbc As Any, riid As UUID, ppv As Any) As Long
    
    Private Function FindRecycleBinsOnDrive(sDrive As String) As String()
    Dim pItem As IShellItem
    Dim penum1 As IEnumShellItems, penum2 As IEnumShellItems
    Dim pChild As IShellItem, pChild2 As IShellItem
    Dim lpPath As Long, sPath As String
    Dim sParent As String
    Dim n As Long
    Dim pcl As Long, pcl2 As Long
    Dim gid As oleexp.UUID
    Dim pPersist As oleexp.IPersist
    Dim lAtr As SFGAO_Flags
    Dim sOut() As String
    ReDim sOut(0)
    
    Call SHCreateItemFromParsingName(StrPtr(sDrive), ByVal 0&, IID_IShellItem, pItem)
    
    If (pItem Is Nothing) = False Then
       pItem.BindToHandler ByVal 0&, BHID_EnumItems, IID_IEnumShellItems, penum1
       Do While penum1.Next(1&, pChild, pcl) = S_OK
            pChild.GetAttributes SFGAO_FOLDER Or SFGAO_HIDDEN Or SFGAO_SYSTEM, lAtr
            If ((lAtr And SFGAO_FOLDER) = SFGAO_FOLDER) And ((lAtr And SFGAO_HIDDEN) = SFGAO_HIDDEN) And ((lAtr And SFGAO_SYSTEM) = SFGAO_SYSTEM) Then
                pChild.BindToHandler ByVal 0&, BHID_EnumItems, IID_IEnumShellItems, penum2
                Do While penum2.Next(1&, pChild2, pcl2) = S_OK
                    pChild2.BindToHandler ByVal 0&, BHID_SFObject, IID_IPersist, pPersist
                    If (pPersist Is Nothing) = False Then
                       pPersist.GetClassID gid
                       pChild2.GetDisplayName SIGDN_DESKTOPABSOLUTEPARSING, lpPath
                       If IsEqualGUID(gid, CLSID_RecycleBin) Then
                           pChild2.GetDisplayName SIGDN_FILESYSPATH, lpPath
                           ReDim Preserve sOut(n)
                           sOut(n) = LPWSTRtoStr(lpPath)
                           n = n + 1
                       End If
                    End If
                Loop
            End If
        Loop
    Else
        Debug.Print "Failed to get drive object"
    End If
    
    FindRecycleBinsOnDrive = sOut
    End Function
    
    Private Function CLSID_RecycleBin() As UUID
    '{645ff040-5081-101b-9f08-00aa002f954e}
    Static iid As UUID
     If (iid.Data1 = 0) Then Call DEFINE_UUID(iid, &H645FF040, CInt(&H5081), CInt(&H101B), &H9F, &H8, &H0, &HAA, &H0, &H2F, &H95, &H4E)
     CLSID_RecycleBin = iid
    End Function
    
    Private Function LPWSTRtoStr(lPtr As Long, Optional ByVal fFree As Boolean = True) As String
    SysReAllocString VarPtr(LPWSTRtoStr), lPtr
    If fFree Then
        Call CoTaskMemFree(lPtr)
    End If
    End Function
    The code increases efficiency by only examining folders that have the properties of the Recycle Bin, a folder with the Hidden and System attributes.

    Alternative Method

    I had also written a different method to get the top level bin names. This method uses the KnownFolderManager class to enumerate (just the first level of) files in the Recycle Bin virtual object (which includes all the physical locations on different drives), and then get the top level bin folders of all drives at once:

    Code:
    Private Sub EnumRecycleBinPaths(sBinPaths() As String)
    Dim kfm As New KnownFolderManager
    Dim pk As IKnownFolder
    Dim pItem As IShellItem
    Dim penum1 As IEnumShellItems
    Dim pChild As IShellItem
    Dim lpPath As Long, sPath As String
    Dim sParent As String
    Dim n As Long
    Dim pcl As Long
    
    ReDim sBinPaths(0)
    kfm.GetFolder FOLDERID_RecycleBinFolder, pk
    If (pk Is Nothing) = False Then
       pk.GetShellItem KF_FLAG_DEFAULT, IID_IShellItem, pItem
       pItem.BindToHandler ByVal 0&, BHID_EnumItems, IID_IEnumShellItems, penum1
       Do While penum1.Next(1&, pChild, pcl) = S_OK
            pChild.GetDisplayName SIGDN_FILESYSPATH, lpPath
            sPath = LPWSTRtoStr(lpPath)
            sParent = Left$(sPath, 3)
            sPath = Mid$(sPath, 4)
            sParent = sParent & Left$(sPath, InStr(sPath, "\"))
            arr_add_dedupe sBinPaths, sParent
        Loop
    End If
    
    End Sub
    Private Sub arr_add_dedupe(sAr() As String, sNew As String)
    Dim i As Long
    For i = 0 To UBound(sAr)
        If sAr(i) = sNew Then Exit Sub
    Next
    Debug.Print "New entry=" & sNew
    If (UBound(sAr) = 0) And (sAr(0) = "") Then
        sAr(0) = sNew
    Else
        ReDim Preserve sAr(UBound(sAr) + 1)
        sAr(UBound(sAr)) = sNew
    End If
    End Sub
    This method is simpler, but might be slower if you have tens of thousands of items in the root of your recycle bin (like Plex does).

    Requirements
    -Windows Vista or newer (you can get to IPersist while enumerating with IShellFolder, if you really needed to do this on XP)
    -oleexp.tlb v4.0 or higher
    -oleexp AddOn mIID.bas (included in oleexp download)
    Attached Files Attached Files
    Last edited by fafalone; Sep 4th, 2017 at 11:17 AM.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width