September 18th, 2008

How can I tell that a directory is really a recycle bin?

Here’s a question inspired by an actual customer question:

I need a function that, given a path, tells me whether it is a Recycle Bin folder. I tried using functions like SHGetSpecialFolderPath with CSIDL_BITBUCKET, but that doesn’t work because the Recycle Bin is a virtual folder that is the union of the Recycle Bins of all drives.

The customer noted that they don’t want to hard-code the words RECYCLED and RECYCLER, which is a good decision because the name of the directory depends on many things. I mentioned earlier that it depends on the file system. It also depends on whether the drive is accessed locally or remotely; network-based Recycle Bin folders follow yet another naming scheme. It may even depend on what operating system the user is running. No, hard-coding the name of the Recycle Bin folders is not a good idea.

The SHDESCRIPTIONID structure tells you a little more about a shell folder. In addition to the “description ID”, it also gives you a CLSID, and it is the CLSID that is relevant here.

#include <windows.h>
#include <shlobj.h>
#include <tchar.h>
#include <stdio.h>

HRESULT GetFolderDescriptionId(LPCWSTR pszPath, SHDESCRIPTIONID *pdid) { HRESULT hr; LPITEMIDLIST pidl; if (SUCCEEDED(hr = SHParseDisplayName(pszPath, NULL, &pidl, 0, NULL))) { IShellFolder *psf; LPCITEMIDLIST pidlChild; if (SUCCEEDED(hr = SHBindToParent(pidl, IID_IShellFolder, (void**)&psf, &pidlChild))) { hr = SHGetDataFromIDList(psf, pidlChild, SHGDFIL_DESCRIPTIONID, pdid, sizeof(*pdid)); psf->Release(); } CoTaskMemFree(pidl); } return hr; }

int __cdecl wmain(int argc, WCHAR **argv) { SHDESCRIPTIONID did; if (SUCCEEDED(GetFolderDescriptionId(argv[1], &did)) && did.clsid == CLSID_RecycleBin) { printf(“is a recycle bin\n”); } else { printf(“is not a recycle bin\n”); } return 0; }

The GetFolderDescriptionId function takes the path to a folder and converts it to an ITEMIDLIST just so it can call SHGetDataFromIDList to obtain the SHDESCRIPTIONID. All we care about in this case is whether the CLSID is the Recycle Bin or not.

C:\> checkrecycle C:\Windows
is not a recycle bin
C:\> checkrecycle C:\RECYCLER\S-1-5-21-2127521184-1604012920-1887927527-72713
is a recycle bin

Of course, now that I told you how to do it, I have to tell you that this is not how to do it. This is another example of a customer having a problem, solving half of it, and asking for help with the other half, unaware that they are approaching the problem from the wrong direction. Next time, we’ll look at the customer’s real problem.

Topics
Code

Author

Raymond has been involved in the evolution of Windows for more than 30 years. In 2003, he began a Web site known as The Old New Thing which has grown in popularity far beyond his wildest imagination, a development which still gives him the heebie-jeebies. The Web site spawned a book, coincidentally also titled The Old New Thing (Addison Wesley 2007). He occasionally appears on the Windows Dev Docs Twitter account to tell stories which convey no useful information.

0 comments

Discussion are closed.