As I demonstrated above the recycle bin can contain more than one item with the same display name.
A better method is to use IShellFolder::CompareIds. I saved the absolute pidls of the recycle bin items enumerated in my previous posts to files. Then I enumerated the items in the recycle bin and did the comparison using the IShellFolder interface retrieved for the Recycle bin as well as for the Desktop.
Example code -
CComHeapPtr<ITEMIDLIST_ABSOLUTE> pidlBin;
CComPtr<IShellFolder> pDesktop, psf;
CHeapPtr<BYTE> pBuffer;
// Read the binary file that contains the pidl for item in recycle bin.
HANDLE hFile = CreateFileW(L"PIDL-$RERVIFA.bin", GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
if (hFile != INVALID_HANDLE_VALUE)
{
DWORD dwRead{};
auto cBytes = GetFileSize(hFile, nullptr);
pBuffer.Allocate(cBytes);
ReadFile(hFile, pBuffer, cBytes, &dwRead, NULL);
ATLASSERT(cBytes == dwRead);
CloseHandle(hFile);
}
auto hr = SHGetDesktopFolder(&pDesktop);
hr = SHGetKnownFolderIDList(FOLDERID_RecycleBinFolder, KF_FLAG_DEFAULT, NULL, &pidlBin);
if (SUCCEEDED(hr))
{
hr = pDesktop->BindToObject(pidlBin, nullptr, IID_PPV_ARGS(&psf));
if (SUCCEEDED(hr))
{
CComPtr<IEnumIDList> pEnumIdlist;
hr = psf->EnumObjects(NULL, SHCONTF_FOLDERS | SHCONTF_NONFOLDERS, &pEnumIdlist);
if (SUCCEEDED(hr))
{
ULONG cFetched{};
for (CComHeapPtr<ITEMID_CHILD> pidlChild; pEnumIdlist->Next(1, &pidlChild, &cFetched) == S_OK; pidlChild.Free())
{
STRRET strnormal{}, strparsing{};
hr = psf->GetDisplayNameOf(pidlChild, SHGDN_NORMAL, &strnormal);
hr = psf->GetDisplayNameOf(pidlChild, SHGDN_FORPARSING, &strparsing);
if (SUCCEEDED(hr))
{
CComHeapPtr<WCHAR> pwszName, pwszParsing;
hr = StrRetToStrW(&strnormal, nullptr, &pwszName);
hr = StrRetToStrW(&strparsing, nullptr, &pwszParsing);
if (SUCCEEDED(hr))
{
wprintf_s(L"IShellFolder Enumeration name was %s\n", (LPWSTR)pwszName);
wprintf_s(L"Parsing name: %s\n", (LPWSTR)pwszParsing);
// Find last pidl the represents child item in the recycle bin
auto pidlSaved = ILFindLastID(reinterpret_cast<PCUIDLIST_RELATIVE>(static_cast<BYTE*>(pBuffer)));
// Compare using IShellFolder for recycle bin
hr = psf->CompareIDs(SHCIDS_CANONICALONLY, static_cast<PCUITEMID_CHILD>((ITEMID_CHILD*)pidlChild), pidlSaved);
bool IsMatch = static_cast<short>(HRESULT_CODE(hr)) == 0;
if(IsMatch)
wprintf(L"******************** Recycle bin IShellFolder Matched Item!!! *******************\n");
// Construct absolute pidl for enumerated item from recycle bin
auto pidlAbsolute = ILCombine(pidlBin, pidlChild);
// Compare using IShellFolder for desktop
hr = pDesktop->CompareIDs(SHCIDS_CANONICALONLY, pidlAbsolute, reinterpret_cast<PCUIDLIST_RELATIVE>(static_cast<BYTE*>(pBuffer)));
IsMatch = static_cast<short>(HRESULT_CODE(hr)) == 0;
if (IsMatch)
wprintf(L"******************** Desktop IShellFolder Matched Item!!! *******************\n");
CoTaskMemFree(pidlAbsolute);
}
}
}
}
}
}
Results of pidl matching -