在本地NTFS驱动器上查找回收站 [英] Finding the Recycle Bin on a local NTFS drive

查看:203
本文介绍了在本地NTFS驱动器上查找回收站的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图写一些简单的代码,将返回本地驱动器上回收站的目录。看起来好像很简单 - 在Google上应该有一千个答案。还没有找到:($ /

我发现FAT和NTFS驱动器有不同的基本名称(RECYCLED和RECYCLER),我发现回收 bin是一个虚拟文件夹,它结合了机器上所有驱动器的回收站。

我没有找到的是找到C盘的回收站目录 - - 甚至在一个越南语(或任何其他非英语)的机器上。(没有职位,我可以找到指示是否RECYCLER得到国际化或没有)

任何人都可以指向我到一个明确的答案?

谢谢

更新:意识到 CSIDL_BITBUCKET 以及使用它的函数,但是从我读过的所有内容来看,它指向的是一个虚拟目录,该目录是该用户在所有驱动器上删除的所有文件的联合。物理回收站目录(在我的Vista上,它似乎是C:\ $ Recycle.Bin据我所知)据我所知

解决方案

<使用R.陈先生的建议,以及别人的技术(不记得我在哪里找到它)我提出了一个功能,可以找到驱动器上的回收站目录。该函数循环遍历根目录中的目录,查看隐藏和/或系统目录。当它找到一个,它检查子目录寻找一个有CLSID_Recycle Bin。

请注意,我已经在下面包含两个GetFolderCLSID函数。 Raymond Chen是比较简单的,但在Windows 2000上不起作用。其他的实现比较长,但似乎无处不在。



调用如下:CString recycleDir = FindRecycleBinOnDrive(LC:\);

  CString FindRecycleBinOnDrive(LPCWSTR路径)
{
CString搜索;
search.Format(L%c:\\ *,path [0]);
WIN32_FIND_DATA fd = {0};
HANDLE fHandle = FindFirstFile(search,& fd);
while(INVALID_HANDLE_VALUE!= fHandle)
{
if(FILE_ATTRIBUTE_DIRECTORY ==(fd.dFFileAttributes& FILE_ATTRIBUTE_DIRECTORY))//只检查目录
{
if 0!=(fd.dwFileAttributes&(FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN)))//只检查隐藏和/或系统目录
{
//回收站目录本身不会被标记, SID特定的子目录会,所以现在看看它们
CString childSearch;
childSearch.Format(L%c:\\%s \\ *,path [0],fd.cFileName);
WIN32_FIND_DATA childFD = {0};
HANDLE childHandle = FindFirstFile(childSearch,& childFD); ((FILE_ATTRIBUTE_DIRECTORY ==(childFD.dwFileAttributes& FILE_ATTRIBUTE_DIRECTORY))&&& //只检查目录
(childFD)
while(INVALID_HANDLE_VALUE!= childHandle)
{
if .cFileName [0]!= L'。'))//不检查。和.. dirs
{
CString fullPath;
fullPath.Format(L%c:\\%s\\\%s,path [0],fd.cFileName,childFD.cFileName);
CLSID id = {0};
HRESULT hr = GetFolderCLSID(fullPath,id);
if(SUCCEEDED(hr))
{
if(IsEqualGUID(CLSID_RecycleBin,id))
{
FindClose(childHandle);
FindClose(fHandle);
//返回父(回收站)目录
fullPath.Format(L%c:\\%s,path [0],fd.cFileName);
返回fullPath;




Log(logERROR,LGetFolderCLSID%s返回%08X,hr,fullPath);


$ b if(FALSE == FindNextFile(childHandle,& childFD))
{
FindClose(childHandle);
childHandle = INVALID_HANDLE_VALUE;



if(FALSE == FindNextFile(fHandle,& fd))
{
FindClose(fHandle );
fHandle = INVALID_HANDLE_VALUE;
}
}
_ASSERT(0);
返回L;


$ b $ //作用于Windows 2000,甚至作为本地系统帐户
HRESULT GetFolderCLSID(LPCWSTR路径,CLSID& pathCLSID)
{
LPMALLOC pMalloc = NULL;
HRESULT hr = 0;
if(SUCCEEDED(hr = SHGetMalloc(& pMalloc)))
{
LPSHELLFOLDER pshfDesktop = NULL;
if(SUCCEEDED(hr = SHGetDesktopFolder(& pshfDesktop)))
{
LPITEMIDLIST pidl = NULL;
DWORD dwAttributes = SFGAO_FOLDER;
if(SUCCEEDED(hr = pshfDesktop-> ParseDisplayName(NULL,NULL,(LPWSTR)path,NULL,& pidl,& dwAttributes)))
{
LPPERSIST pPersist = NULL ;
if(SUCCEEDED(hr = pshfDesktop-> BindToObject(pidl,NULL,IID_IPersist,(LPVOID *)& pPersist)))
{
hr = pPersist-> GetClassID ; pathCLSID);
pPersist-> Release();
}
pMalloc->免费(pidl);

pshfDesktop-> Release();
}
pMalloc-> Release();
}
return hr;


$ b $ //在Windows 2000上不支持,因为SHParseDisplayName没有实现,所以
// HRESULT GetFolderCLSID(LPCWSTR pszPath,CLSID& pathCLSID)
// {
// SHDESCRIPTIONID did = {0};
// HRESULT hr = 0;
// LPITEMIDLIST pidl = NULL;
// if(SUCCEEDED(hr = SHParseDisplayName(pszPath,NULL,& pidl,0,NULL)))//不支持Windows 2000
// {
// IShellFolder * psf = NULL;
// LPCITEMIDLIST pidlChild = NULL;
// if(SUCCEEDED(hr = SHBindToParent(pidl,IID_IShellFolder,(void **)& psf,& pidlChild)))
// {
// hr = SHGetDataFromIDList psf,pidlChild,SHGDFIL_DESCRIPTIONID,& did,sizeof(did));
// psf-> Release();
// pathCLSID = did.clsid;
//}
// CoTaskMemFree(pidl);
//}
// return hr;
//}


I'm trying to write some simple code that will return the directory for the recycle bin on a local drive. Seems like it would be simple -- should be a thousand answers on Google. Haven't found one yet :(

I HAVE found that FAT and NTFS drives have different base names (RECYCLED and RECYCLER). I've found that 'the' recycle bin is a virtual folder that combines the recycle bins of all drives on the machine.

What I haven't found is a way to find C: drive's recycle bin directory -- even on a Vietnamese (or any other non-English) machine. (No posts I can find indicate whether "RECYCLER" gets internationalized or not)

Can anyone point me to a definitive answer?

Thanks

UPDATE: Aware of CSIDL_BITBUCKET and the functions that use it. From everything I've read though, it points to a virtual directory which is the union of all deleted files by that user on all drives. Looking for the physical recycle bin directory (on my Vista it appears to be C:\$Recycle.Bin as far as I can tell)

解决方案

Using Raymond Chen's advice, and someone else's technique (can't remember where I found it) I present a function that will find the Recycle Bin directory on a drive. The function cycles through the directories in the root directory looking at hidden and/or system directories. When it finds one, it checks the child subdirectories looking for one that has CLSID_Recycle Bin.

Note that I've included two GetFolderCLSID functions below. Raymond Chen's is the simpler one, but it doesn't work on Windows 2000. The other implementation is longer, but appears to work everywhere.

Call like: CString recycleDir = FindRecycleBinOnDrive(L"C:\");

CString FindRecycleBinOnDrive(LPCWSTR path)
{
    CString search;
    search.Format(L"%c:\\*", path[0]);
    WIN32_FIND_DATA fd = {0};
    HANDLE fHandle = FindFirstFile(search, &fd);
    while(INVALID_HANDLE_VALUE != fHandle)
    {
        if(FILE_ATTRIBUTE_DIRECTORY == (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) //only check directories
        {
            if(0 != (fd.dwFileAttributes & (FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN))) //only check hidden and/or system directories
            {
                //the recycle bin directory itself won't be marked, but a SID-specific child directory will, so now look at them
                CString childSearch;
                childSearch.Format(L"%c:\\%s\\*", path[0], fd.cFileName);
                WIN32_FIND_DATA childFD = {0};
                HANDLE childHandle = FindFirstFile(childSearch, &childFD);
                while(INVALID_HANDLE_VALUE != childHandle)
                {
                    if((FILE_ATTRIBUTE_DIRECTORY == (childFD.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) && //only check directories
                        (childFD.cFileName[0] != L'.')) //don't check . and .. dirs
                    {
                        CString fullPath;
                        fullPath.Format(L"%c:\\%s\\%s", path[0], fd.cFileName, childFD.cFileName);
                        CLSID id = {0};
                        HRESULT hr = GetFolderCLSID(fullPath, id);
                        if(SUCCEEDED(hr))
                        {
                            if(IsEqualGUID(CLSID_RecycleBin, id))
                            {
                                FindClose(childHandle);
                                FindClose(fHandle);
                                //return the parent (recycle bin) directory
                                fullPath.Format(L"%c:\\%s", path[0], fd.cFileName);
                                return fullPath;
                            }
                        }
                        else
                        {
                            Log(logERROR, L"GetFolderCLSID returned %08X for %s", hr, fullPath);
                        }
                    }

                    if(FALSE == FindNextFile(childHandle, &childFD))
                    {
                        FindClose(childHandle);
                        childHandle = INVALID_HANDLE_VALUE;
                    }
                }
            }
        }
        if(FALSE == FindNextFile(fHandle, &fd))
        {
            FindClose(fHandle);
            fHandle = INVALID_HANDLE_VALUE;
        }
    }
    _ASSERT(0);
    return L"";
}


//Works on Windows 2000, and even as Local System account
HRESULT GetFolderCLSID(LPCWSTR path, CLSID& pathCLSID)
{
    LPMALLOC pMalloc = NULL;
    HRESULT hr = 0;
    if (SUCCEEDED(hr = SHGetMalloc(&pMalloc))) 
    {
        LPSHELLFOLDER pshfDesktop = NULL;
        if (SUCCEEDED(hr = SHGetDesktopFolder(&pshfDesktop))) 
        {
            LPITEMIDLIST pidl = NULL;
            DWORD dwAttributes = SFGAO_FOLDER;
            if (SUCCEEDED(hr = pshfDesktop->ParseDisplayName(NULL, NULL, (LPWSTR)path, NULL, &pidl, &dwAttributes))) 
            {
                LPPERSIST pPersist = NULL;
                if (SUCCEEDED(hr = pshfDesktop->BindToObject(pidl, NULL, IID_IPersist, (LPVOID *) &pPersist))) 
                {
                    hr = pPersist->GetClassID(&pathCLSID); 
                    pPersist->Release();
                } 
                pMalloc->Free(pidl);
            } 
            pshfDesktop->Release();
        } 
        pMalloc->Release();
    }
    return hr;
}


//Not supported on Windows 2000 since SHParseDisplayName wasn't implemented then
//HRESULT GetFolderCLSID(LPCWSTR pszPath, CLSID& pathCLSID)
//{
//  SHDESCRIPTIONID did = {0};
//  HRESULT hr = 0;
//  LPITEMIDLIST pidl = NULL;
//  if (SUCCEEDED(hr = SHParseDisplayName(pszPath, NULL, &pidl, 0, NULL))) //not supported by Windows 2000
//  {
//      IShellFolder *psf = NULL;
//      LPCITEMIDLIST pidlChild = NULL;
//      if (SUCCEEDED(hr = SHBindToParent(pidl, IID_IShellFolder, (void**)&psf, &pidlChild))) 
//      {
//          hr = SHGetDataFromIDList(psf, pidlChild, SHGDFIL_DESCRIPTIONID, &did, sizeof(did));
//          psf->Release();
//          pathCLSID = did.clsid;
//      }
//      CoTaskMemFree(pidl);
//  }
//  return hr;
//}

这篇关于在本地NTFS驱动器上查找回收站的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆