views:

522

answers:

2

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.


This question is to document a response posted in http://blogs.msdn.com/oldnewthing/archive/2008/09/18/8956382.aspx

A: 

From http://blogs.msdn.com/oldnewthing/archive/2008/09/18/8956382.aspx:

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. 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
smink
-1. You should just link to the blog post, don't copy and paste. Raymond Chen, the original author of this, hates people who (in his words) The original author (Raymond Chen) hates what he calls "people who reprint [Raymond's] blog articles (usually erroneously attributed) in order to improve the search engine ranking of [their] site." From here http://blogs.msdn.com/oldnewthing/archive/2008/02/18/7761978.aspx
MarkJ
+4  A: 

What about copyright issues? The original post has a copyright notice, and you copy pasted it as is. Wouldn't that create problems for StackOverflow ?

What if Google starts ranking SO higher than the original link I can't imaging the original author being too happy about this.

I suppose paraphrasing the answer and providing a link to the original source or maybe using an example from the official documentation instead of the post would have been better.

Pat
Hum. I did hyperlinked to the original source from the very beginning.
smink
Sure. But that does not solve any of the issues (in case they are issues), if there is a copyright problem a link would not solve it, and if this gets higher Google rank, people will read the full solution here without following the link. I don't know, it just feels wrong without consent from the OP
Pat
+1 The original author (Raymond Chen) hates what he calls "people who reprint blog articles (usually erroneously attributed) in order to improve the search engine ranking of [their] site." From here http://blogs.msdn.com/oldnewthing/archive/2008/02/18/7761978.aspx
MarkJ