*
* Copyright (C) 2006 Mikolaj Zalewski
* Copyright (C) 2009 Andrew Hill
+ * Copyright (C) 2018 Russell Johnson
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
#include <precomp.h>
+#include <mmsystem.h>
#include <ntquery.h>
-#define MAX_PROPERTY_SHEET_PAGE 32
-
WINE_DEFAULT_DEBUG_CHANNEL(CRecycleBin);
typedef struct
static const columninfo RecycleBinColumns[] =
{
- {IDS_SHV_COLUMN1, &FMTID_Storage, PID_STG_NAME, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_LEFT, 30},
+ {IDS_SHV_COLUMN_NAME, &FMTID_Storage, PID_STG_NAME, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_LEFT, 30},
{IDS_SHV_COLUMN_DELFROM, &FMTID_Displaced, PID_DISPLACED_FROM, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_LEFT, 30},
{IDS_SHV_COLUMN_DELDATE, &FMTID_Displaced, PID_DISPLACED_DATE, SHCOLSTATE_TYPE_DATE | SHCOLSTATE_ONBYDEFAULT, LVCFMT_LEFT, 20},
- {IDS_SHV_COLUMN2, &FMTID_Storage, PID_STG_SIZE, SHCOLSTATE_TYPE_INT | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 20},
- {IDS_SHV_COLUMN3, &FMTID_Storage, PID_STG_STORAGETYPE, SHCOLSTATE_TYPE_INT | SHCOLSTATE_ONBYDEFAULT, LVCFMT_LEFT, 20},
- {IDS_SHV_COLUMN4, &FMTID_Storage, PID_STG_WRITETIME, SHCOLSTATE_TYPE_DATE | SHCOLSTATE_ONBYDEFAULT, LVCFMT_LEFT, 20},
+ {IDS_SHV_COLUMN_SIZE, &FMTID_Storage, PID_STG_SIZE, SHCOLSTATE_TYPE_INT | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 20},
+ {IDS_SHV_COLUMN_TYPE, &FMTID_Storage, PID_STG_STORAGETYPE, SHCOLSTATE_TYPE_INT | SHCOLSTATE_ONBYDEFAULT, LVCFMT_LEFT, 20},
+ {IDS_SHV_COLUMN_MODIFIED, &FMTID_Storage, PID_STG_WRITETIME, SHCOLSTATE_TYPE_DATE | SHCOLSTATE_ONBYDEFAULT, LVCFMT_LEFT, 20},
/* {"creation time", &FMTID_Storage, PID_STG_CREATETIME, SHCOLSTATE_TYPE_DATE, LVCFMT_LEFT, 20}, */
/* {"attribs", &FMTID_Storage, PID_STG_ATTRIBUTES, SHCOLSTATE_TYPE_STR, LVCFMT_LEFT, 20}, */
};
* Recycle Bin folder
*/
+HRESULT CRecyclerExtractIcon_CreateInstance(LPCITEMIDLIST pidl, REFIID riid, LPVOID * ppvOut)
+{
+ CComPtr<IDefaultExtractIconInit> initIcon;
+ HRESULT hr = SHCreateDefaultExtractIcon(IID_PPV_ARG(IDefaultExtractIconInit, &initIcon));
+ if (FAILED_UNEXPECTEDLY(hr))
+ return hr;
+
+ /* FIXME: This is completely unimplemented */
+ initIcon->SetNormalIcon(swShell32Name, 0);
+
+ return initIcon->QueryInterface(riid, ppvOut);
+}
+
class CRecycleBinEnum :
public CEnumIDListBase
{
BOOL bFound;
} SEARCH_CONTEXT, *PSEARCH_CONTEXT;
-typedef struct
-{
- DWORD dwNukeOnDelete;
- DWORD dwSerial;
- DWORD dwMaxCapacity;
-} DRIVE_ITEM_CONTEXT, *PDRIVE_ITEM_CONTEXT;
-
BOOL WINAPI CBSearchRecycleBin(IN PVOID Context, IN HANDLE hDeletedFile)
{
PSEARCH_CONTEXT pContext = (PSEARCH_CONTEXT)Context;
TRACE("(%p)->(hmenu=%p indexmenu=%x cmdfirst=%x cmdlast=%x flags=%x )\n", this, hMenu, indexMenu, idCmdFirst, idCmdLast, uFlags);
- if (LoadStringW(shell32_hInstance, IDS_RESTORE, szBuffer, sizeof(szBuffer) / sizeof(WCHAR)))
+ if (LoadStringW(shell32_hInstance, IDS_RESTORE, szBuffer, _countof(szBuffer)))
{
- szBuffer[(sizeof(szBuffer)/sizeof(WCHAR))-1] = L'\0';
+ szBuffer[_countof(szBuffer)-1] = L'\0';
_InsertMenuItemW(hMenu, indexMenu++, TRUE, idCmdFirst + Count, MFT_STRING, szBuffer, MFS_ENABLED);
Count++;
}
- if (LoadStringW(shell32_hInstance, IDS_CUT, szBuffer, sizeof(szBuffer) / sizeof(WCHAR)))
+ if (LoadStringW(shell32_hInstance, IDS_CUT, szBuffer, _countof(szBuffer)))
{
_InsertMenuItemW(hMenu, indexMenu++, TRUE, idCmdFirst + Count++, MFT_SEPARATOR, NULL, MFS_ENABLED);
- szBuffer[(sizeof(szBuffer)/sizeof(WCHAR))-1] = L'\0';
+ szBuffer[_countof(szBuffer)-1] = L'\0';
_InsertMenuItemW(hMenu, indexMenu++, TRUE, idCmdFirst + Count++, MFT_STRING, szBuffer, MFS_ENABLED);
}
- if (LoadStringW(shell32_hInstance, IDS_DELETE, szBuffer, sizeof(szBuffer) / sizeof(WCHAR)))
+ if (LoadStringW(shell32_hInstance, IDS_DELETE, szBuffer, _countof(szBuffer)))
{
- szBuffer[(sizeof(szBuffer)/sizeof(WCHAR))-1] = L'\0';
+ szBuffer[_countof(szBuffer)-1] = L'\0';
_InsertMenuItemW(hMenu, indexMenu++, TRUE, idCmdFirst + Count++, MFT_SEPARATOR, NULL, MFS_ENABLED);
_InsertMenuItemW(hMenu, indexMenu++, TRUE, idCmdFirst + Count++, MFT_STRING, szBuffer, MFS_ENABLED);
}
- if (LoadStringW(shell32_hInstance, IDS_PROPERTIES, szBuffer, sizeof(szBuffer) / sizeof(WCHAR)))
+ if (LoadStringW(shell32_hInstance, IDS_PROPERTIES, szBuffer, _countof(szBuffer)))
{
- szBuffer[(sizeof(szBuffer)/sizeof(WCHAR))-1] = L'\0';
+ szBuffer[_countof(szBuffer)-1] = L'\0';
_InsertMenuItemW(hMenu, indexMenu++, TRUE, idCmdFirst + Count++, MFT_SEPARATOR, NULL, MFS_ENABLED);
_InsertMenuItemW(hMenu, indexMenu++, TRUE, idCmdFirst + Count, MFT_STRING, szBuffer, MFS_DEFAULT);
}
return E_NOTIMPL;
}
-/**************************************************************************
-* registers clipboardformat once
-*/
-void CRecycleBin::SF_RegisterClipFmt()
-{
- TRACE ("(%p)\n", this);
-
- if (!cfShellIDList)
- cfShellIDList = RegisterClipboardFormatW(CFSTR_SHELLIDLIST);
-}
-
CRecycleBin::CRecycleBin()
{
pidl = NULL;
- iIdEmpty = 0;
- cfShellIDList = 0;
- SF_RegisterClipFmt();
- fAcceptFmt = FALSE;
}
CRecycleBin::~CRecycleBin()
{
- /* InterlockedDecrement(&objCount);*/
SHFree(pidl);
}
return S_OK;
}
-HRESULT WINAPI CRecycleBin::GetCurFolder(LPITEMIDLIST *ppidl)
+HRESULT WINAPI CRecycleBin::GetCurFolder(PIDLIST_ABSOLUTE *ppidl)
{
TRACE("\n");
*ppidl = ILClone(pidl);
HRESULT WINAPI CRecycleBin::EnumObjects(HWND hwndOwner, DWORD dwFlags, LPENUMIDLIST *ppEnumIDList)
{
- return ShellObjectCreatorInit<CRecycleBinEnum>(dwFlags, IID_IEnumIDList, ppEnumIDList);
+ return ShellObjectCreatorInit<CRecycleBinEnum>(dwFlags, IID_PPV_ARG(IEnumIDList, ppEnumIDList));
}
HRESULT WINAPI CRecycleBin::BindToObject(PCUIDLIST_RELATIVE pidl, LPBC pbc, REFIID riid, void **ppv)
HRESULT WINAPI CRecycleBin::CompareIDs(LPARAM lParam, PCUIDLIST_RELATIVE pidl1, PCUIDLIST_RELATIVE pidl2)
{
- /* TODO */
- TRACE("(%p, %p, %p, %p)\n", this, (void *)lParam, pidl1, pidl2);
- if (pidl1->mkid.cb != pidl2->mkid.cb)
- return MAKE_HRESULT(SEVERITY_SUCCESS, 0, pidl1->mkid.cb - pidl2->mkid.cb);
- return MAKE_HRESULT(SEVERITY_SUCCESS, 0, (unsigned short)memcmp(pidl1->mkid.abID, pidl2->mkid.abID, pidl1->mkid.cb));
+ PIDLRecycleStruct* pData1 = _ILGetRecycleStruct(pidl1);
+ PIDLRecycleStruct* pData2 = _ILGetRecycleStruct(pidl2);
+ LPWSTR pName1, pName2;
+
+ if(!pData1 || !pData2 || LOWORD(lParam) >= COLUMNS_COUNT)
+ return E_INVALIDARG;
+
+ SHORT result;
+ LONGLONG diff;
+ switch (LOWORD(lParam))
+ {
+ case 0: /* Name */
+ pName1 = PathFindFileNameW(pData1->szName);
+ pName2 = PathFindFileNameW(pData2->szName);
+ result = wcsicmp(pName1, pName2);
+ break;
+ case 1: /* Orig. Location */
+ result = wcsicmp(pData1->szName, pData2->szName);
+ break;
+ case 2: /* Date Deleted */
+ result = CompareFileTime(&pData1->DeletionTime, &pData2->DeletionTime);
+ break;
+ case 3: /* Size */
+ diff = pData1->FileSize.QuadPart - pData2->FileSize.QuadPart;
+ return MAKE_COMPARE_HRESULT(diff);
+ case 4: /* Type */
+ pName1 = PathFindExtensionW(pData1->szName);
+ pName2 = PathFindExtensionW(pData2->szName);
+ result = wcsicmp(pName1, pName2);
+ break;
+ case 5: /* Modified */
+ result = CompareFileTime(&pData1->LastModification, &pData2->LastModification);
+ break;
+ }
+ return MAKE_COMPARE_HRESULT(result);
}
HRESULT WINAPI CRecycleBin::CreateViewObject(HWND hwndOwner, REFIID riid, void **ppv)
if (IsEqualIID (riid, IID_IDropTarget))
{
- hr = this->QueryInterface (IID_IDropTarget, ppv);
+ hr = CRecyclerDropTarget_CreateInstance(riid, ppv);
}
else if (IsEqualIID (riid, IID_IContextMenu) || IsEqualIID (riid, IID_IContextMenu2))
{
}
else if (IsEqualIID (riid, IID_IShellView))
{
- hr = IShellView_Constructor ((IShellFolder *)this, &pShellView);
- if (pShellView)
- {
- hr = pShellView->QueryInterface(riid, ppv);
- }
+ SFV_CREATE sfvparams = {sizeof(SFV_CREATE), this};
+ hr = SHCreateShellFolderView(&sfvparams, (IShellView**)ppv);
}
else
return hr;
+
TRACE ("-- (%p)->(interface=%p)\n", this, ppv);
return hr;
HRESULT WINAPI CRecycleBin::GetUIObjectOf(HWND hwndOwner, UINT cidl, PCUITEMID_CHILD_ARRAY apidl,
REFIID riid, UINT *prgfInOut, void **ppv)
{
- IUnknown *pObj = NULL;
+ LPVOID pObj = NULL;
HRESULT hr = E_INVALIDARG;
TRACE ("(%p)->(%p,%u,apidl=%p, %p %p)\n", this,
{
hr = ShellObjectCreatorInit<CRecycleBinItemContextMenu>(apidl[0], riid, &pObj);
}
- else if (IsEqualIID (riid, IID_IDropTarget) && (cidl == 1))
+ else if((IsEqualIID(riid, IID_IExtractIconA) || IsEqualIID(riid, IID_IExtractIconW)) && (cidl == 1))
{
- IDropTarget * pDt = NULL;
- hr = QueryInterface(IID_PPV_ARG(IDropTarget, &pDt));
- pObj = pDt;
+ hr = CRecyclerExtractIcon_CreateInstance(apidl[0], riid, &pObj);
}
else
hr = E_NOINTERFACE;
TRACE("(%p, %p, %x, %p)\n", this, pidl, (unsigned int)uFlags, pName);
-
- if (_ILIsBitBucket (pidl))
- {
- WCHAR pszPath[100];
-
- if (HCR_GetClassNameW(CLSID_RecycleBin, pszPath, MAX_PATH))
- {
- pName->uType = STRRET_WSTR;
- pName->pOleStr = StrDupW(pszPath);
- return S_OK;
- }
- }
-
pFileDetails = _ILGetRecycleStruct(pidl);
if (!pFileDetails)
{
HRESULT WINAPI CRecycleBin::GetDefaultColumn(DWORD dwReserved, ULONG *pSort, ULONG *pDisplay)
{
TRACE("(%p, %x, %p, %p)\n", this, (unsigned int)dwReserved, pSort, pDisplay);
- *pSort = 0;
- *pDisplay = 0;
+ if (pSort)
+ *pSort = 0;
+ if (pDisplay)
+ *pDisplay = 0;
return S_OK;
}
pDetails->fmt = RecycleBinColumns[iColumn].fmt;
pDetails->cxChar = RecycleBinColumns[iColumn].cxChars;
if (pidl == NULL)
- {
- pDetails->str.uType = STRRET_WSTR;
- LoadStringW(shell32_hInstance, RecycleBinColumns[iColumn].column_name_id, buffer, MAX_PATH);
- return SHStrDupW(buffer, &pDetails->str.pOleStr);
- }
+ return SHSetStrRet(&pDetails->str, RecycleBinColumns[iColumn].column_name_id);
if (iColumn == COLUMN_NAME)
return GetDisplayNameOf(pidl, SHGDN_NORMAL, &pDetails->str);
FormatDateTime(buffer, MAX_PATH, &pFileDetails->LastModification);
break;
case COLUMN_TYPE:
+ // FIXME: We should in fact use a UNICODE version of _ILGetFileType
szTypeName[0] = L'\0';
wcscpy(buffer, PathFindExtensionW(pFileDetails->szName));
- if (!( HCR_MapTypeToValueW(buffer, buffer, sizeof(buffer) / sizeof(WCHAR), TRUE) &&
- HCR_MapTypeToValueW(buffer, szTypeName, sizeof(szTypeName) / sizeof(WCHAR), FALSE )))
+ if (!( HCR_MapTypeToValueW(buffer, buffer, _countof(buffer), TRUE) &&
+ HCR_MapTypeToValueW(buffer, szTypeName, _countof(szTypeName), FALSE )))
{
- wcscpy (szTypeName, PathFindExtensionW(pFileDetails->szName));
- wcscat(szTypeName, L"-");
- Length = wcslen(szTypeName);
- if (LoadStringW(shell32_hInstance, IDS_SHV_COLUMN1, &szTypeName[Length], (sizeof(szTypeName) / sizeof(WCHAR)) - Length))
- szTypeName[(sizeof(szTypeName)/sizeof(WCHAR))-1] = L'\0';
+ /* load localized file string */
+ szTypeName[0] = '\0';
+ if(LoadStringW(shell32_hInstance, IDS_ANY_FILE, szTypeName, _countof(szTypeName)))
+ {
+ szTypeName[63] = '\0';
+ StringCchPrintfW(buffer, _countof(buffer), szTypeName, PathFindExtensionW(pFileDetails->szName));
+ }
}
- pDetails->str.uType = STRRET_WSTR;
- return SHStrDupW(szTypeName, &pDetails->str.pOleStr);
- break;
+ return SHSetStrRet(&pDetails->str, szTypeName);
default:
return E_FAIL;
}
- pDetails->str.uType = STRRET_WSTR;
- return SHStrDupW(buffer, &pDetails->str.pOleStr);
+ return SHSetStrRet(&pDetails->str, buffer);
}
HRESULT WINAPI CRecycleBin::MapColumnToSCID(UINT iColumn, SHCOLUMNID *pscid)
return S_OK;
}
+BOOL CRecycleBin::RecycleBinIsEmpty()
+{
+ CComPtr<IEnumIDList> spEnumFiles;
+ HRESULT hr = EnumObjects(NULL, SHCONTF_FOLDERS | SHCONTF_NONFOLDERS, &spEnumFiles);
+ if (FAILED(hr))
+ return TRUE;
+ CComHeapPtr<ITEMIDLIST> spPidl;
+ ULONG itemcount;
+ return spEnumFiles->Next(1, &spPidl, &itemcount) != S_OK;
+ }
+
/*************************************************************************
* RecycleBin IContextMenu interface
*/
if (!hMenu)
return E_INVALIDARG;
- memset(&mii, 0, sizeof(mii));
+ ZeroMemory(&mii, sizeof(mii));
mii.cbSize = sizeof(mii);
mii.fMask = MIIM_TYPE | MIIM_ID | MIIM_STATE;
- mii.fState = MFS_ENABLED;
+ mii.fState = RecycleBinIsEmpty() ? MFS_DISABLED : MFS_ENABLED;
szBuffer[0] = L'\0';
- LoadStringW(shell32_hInstance, IDS_EMPTY_BITBUCKET, szBuffer, sizeof(szBuffer) / sizeof(WCHAR));
+ LoadStringW(shell32_hInstance, IDS_EMPTY_BITBUCKET, szBuffer, _countof(szBuffer));
mii.dwTypeData = szBuffer;
mii.cch = wcslen(mii.dwTypeData);
mii.wID = idCmdFirst + id++;
return S_OK;
}
-void toggleNukeOnDeleteOption(HWND hwndDlg, BOOL bEnable)
-{
- if (bEnable)
- {
- SendDlgItemMessage(hwndDlg, 14001, BM_SETCHECK, BST_UNCHECKED, 0);
- EnableWindow(GetDlgItem(hwndDlg, 14002), FALSE);
- SendDlgItemMessage(hwndDlg, 14003, BM_SETCHECK, BST_CHECKED, 0);
- }
- else
- {
- SendDlgItemMessage(hwndDlg, 14001, BM_SETCHECK, BST_CHECKED, 0);
- EnableWindow(GetDlgItem(hwndDlg, 14002), TRUE);
- SendDlgItemMessage(hwndDlg, 14003, BM_SETCHECK, BST_UNCHECKED, 0);
- }
-}
-
-
-static VOID
-InitializeRecycleBinDlg(HWND hwndDlg, WCHAR DefaultDrive)
-{
- WCHAR CurDrive = L'A';
- WCHAR szDrive[] = L"A:\\";
- DWORD dwDrives;
- WCHAR szName[100];
- WCHAR szVolume[100];
- DWORD MaxComponent, Flags;
- DWORD dwSerial;
- LVCOLUMNW lc;
- HWND hDlgCtrl;
- LVITEMW li;
- INT itemCount;
- ULARGE_INTEGER TotalNumberOfFreeBytes, TotalNumberOfBytes, FreeBytesAvailable;
- RECT rect;
- int columnSize;
- int defIndex = 0;
- DWORD dwSize;
- PDRIVE_ITEM_CONTEXT pItem = NULL, pDefault = NULL, pFirst = NULL;
-
- hDlgCtrl = GetDlgItem(hwndDlg, 14000);
-
- if (!LoadStringW(shell32_hInstance, IDS_RECYCLEBIN_LOCATION, szVolume, sizeof(szVolume) / sizeof(WCHAR)))
- szVolume[0] = 0;
-
- GetClientRect(hDlgCtrl, &rect);
-
- memset(&lc, 0, sizeof(LV_COLUMN) );
- lc.mask = LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM | LVCF_FMT;
-
- columnSize = 140; //FIXME
- lc.iSubItem = 0;
- lc.fmt = LVCFMT_FIXED_WIDTH;
- lc.cx = columnSize;
- lc.cchTextMax = wcslen(szVolume);
- lc.pszText = szVolume;
- (void)SendMessageW(hDlgCtrl, LVM_INSERTCOLUMNW, 0, (LPARAM)&lc);
-
- if (!LoadStringW(shell32_hInstance, IDS_RECYCLEBIN_DISKSPACE, szVolume, sizeof(szVolume) / sizeof(WCHAR)))
- szVolume[0] = 0;
-
- lc.iSubItem = 1;
- lc.cx = rect.right - rect.left - columnSize;
- lc.cchTextMax = wcslen(szVolume);
- lc.pszText = szVolume;
- (void)SendMessageW(hDlgCtrl, LVM_INSERTCOLUMNW, 1, (LPARAM)&lc);
-
- dwDrives = GetLogicalDrives();
- itemCount = 0;
- do
- {
- if ((dwDrives & 0x1))
- {
- UINT Type = GetDriveTypeW(szDrive);
- if (Type == DRIVE_FIXED) //FIXME
- {
- if (!GetVolumeInformationW(szDrive, szName, sizeof(szName) / sizeof(WCHAR), &dwSerial, &MaxComponent, &Flags, NULL, 0))
- {
- szName[0] = 0;
- dwSerial = -1;
- }
-
- swprintf(szVolume, L"%s (%c)", szName, szDrive[0]);
- memset(&li, 0x0, sizeof(LVITEMW));
- li.mask = LVIF_TEXT | LVIF_PARAM;
- li.iSubItem = 0;
- li.pszText = szVolume;
- li.iItem = itemCount;
- SendMessageW(hDlgCtrl, LVM_INSERTITEMW, 0, (LPARAM)&li);
- if (GetDiskFreeSpaceExW(szDrive, &FreeBytesAvailable , &TotalNumberOfBytes, &TotalNumberOfFreeBytes))
- {
- if (StrFormatByteSizeW(TotalNumberOfFreeBytes.QuadPart, szVolume, sizeof(szVolume) / sizeof(WCHAR)))
- {
-
- pItem = (DRIVE_ITEM_CONTEXT *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(DRIVE_ITEM_CONTEXT));
- if (pItem)
- {
- swprintf(szName, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Bitbucket\\Volume\\%04X-%04X", LOWORD(dwSerial), HIWORD(dwSerial));
- dwSize = sizeof(DWORD);
- RegGetValueW(HKEY_CURRENT_USER, szName, L"MaxCapacity", RRF_RT_DWORD, NULL, &pItem->dwMaxCapacity, &dwSize);
- dwSize = sizeof(DWORD);
- RegGetValueW(HKEY_CURRENT_USER, szName, L"NukeOnDelete", RRF_RT_DWORD, NULL, &pItem->dwNukeOnDelete, &dwSize);
- pItem->dwSerial = dwSerial;
- li.mask = LVIF_PARAM;
- li.lParam = (LPARAM)pItem;
- (void)SendMessageW(hDlgCtrl, LVM_SETITEMW, 0, (LPARAM)&li);
- if (CurDrive == DefaultDrive)
- {
- defIndex = itemCount;
- pDefault = pItem;
- }
- }
- if (!pFirst)
- pFirst = pItem;
-
- li.mask = LVIF_TEXT;
- li.iSubItem = 1;
- li.pszText = szVolume;
- li.iItem = itemCount;
- (void)SendMessageW(hDlgCtrl, LVM_SETITEMW, 0, (LPARAM)&li);
- }
- }
- itemCount++;
- }
- }
- CurDrive++;
- szDrive[0] = CurDrive;
- dwDrives = (dwDrives >> 1);
- } while(dwDrives);
-
- if (!pDefault)
- pDefault = pFirst;
- if (pDefault)
- {
- toggleNukeOnDeleteOption(hwndDlg, pDefault->dwNukeOnDelete);
- SetDlgItemInt(hwndDlg, 14002, pDefault->dwMaxCapacity, FALSE);
- }
- ZeroMemory(&li, sizeof(li));
- li.mask = LVIF_STATE;
- li.stateMask = (UINT) - 1;
- li.state = LVIS_FOCUSED | LVIS_SELECTED;
- li.iItem = defIndex;
- (void)SendMessageW(hDlgCtrl, LVM_SETITEMW, 0, (LPARAM)&li);
-
-}
-
-static BOOL StoreDriveSettings(HWND hwndDlg)
-{
- int iCount, iIndex;
- HWND hDlgCtrl = GetDlgItem(hwndDlg, 14000);
- LVITEMW li;
- PDRIVE_ITEM_CONTEXT pItem;
- HKEY hKey, hSubKey;
- WCHAR szSerial[20];
- DWORD dwSize;
-
-
- if (RegCreateKeyExW(HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Bitbucket\\Volume", 0, NULL, 0, KEY_WRITE, NULL, &hKey, NULL) != ERROR_SUCCESS)
- return FALSE;
-
- iCount = ListView_GetItemCount(hDlgCtrl);
-
- ZeroMemory(&li, sizeof(li));
- li.mask = LVIF_PARAM;
-
- for(iIndex = 0; iIndex < iCount; iIndex++)
- {
- li.iItem = iIndex;
- if (SendMessageW(hDlgCtrl, LVM_GETITEMW, 0, (LPARAM)&li))
- {
- pItem = (PDRIVE_ITEM_CONTEXT)li.lParam;
- swprintf(szSerial, L"%04X-%04X", LOWORD(pItem->dwSerial), HIWORD(pItem->dwSerial));
- if (RegCreateKeyExW(hKey, szSerial, 0, NULL, 0, KEY_WRITE, NULL, &hSubKey, NULL) == ERROR_SUCCESS)
- {
- dwSize = sizeof(DWORD);
- RegSetValueExW(hSubKey, L"NukeOnDelete", 0, REG_DWORD, (LPBYTE)&pItem->dwNukeOnDelete, dwSize);
- dwSize = sizeof(DWORD);
- RegSetValueExW(hSubKey, L"MaxCapacity", 0, REG_DWORD, (LPBYTE)&pItem->dwMaxCapacity, dwSize);
- RegCloseKey(hSubKey);
- }
- }
- }
- RegCloseKey(hKey);
- return TRUE;
-
-}
-
-static VOID FreeDriveItemContext(HWND hwndDlg)
-{
- int iCount, iIndex;
- HWND hDlgCtrl = GetDlgItem(hwndDlg, 14000);
- LVITEMW li;
-
- iCount = ListView_GetItemCount(hDlgCtrl);
-
- ZeroMemory(&li, sizeof(li));
- li.mask = LVIF_PARAM;
-
- for(iIndex = 0; iIndex < iCount; iIndex++)
- {
- li.iItem = iIndex;
- if (SendMessageW(hDlgCtrl, LVM_GETITEMW, 0, (LPARAM)&li))
- {
- HeapFree(GetProcessHeap(), 0, (LPVOID)li.lParam);
- }
- }
-}
-
-static INT
-GetDefaultItem(HWND hwndDlg, LVITEMW * li)
-{
- HWND hDlgCtrl;
- UINT iItemCount, iIndex;
-
- hDlgCtrl = GetDlgItem(hwndDlg, 14000);
- if (!hDlgCtrl)
- return -1;
-
- iItemCount = ListView_GetItemCount(hDlgCtrl);
- if (!iItemCount)
- return -1;
-
- ZeroMemory(li, sizeof(LVITEMW));
- li->mask = LVIF_PARAM | LVIF_STATE;
- li->stateMask = (UINT) - 1;
- for (iIndex = 0; iIndex < iItemCount; iIndex++)
- {
- li->iItem = iIndex;
- if (SendMessageW(hDlgCtrl, LVM_GETITEMW, 0, (LPARAM)li))
- {
- if (li->state & LVIS_SELECTED)
- return iIndex;
- }
- }
- return -1;
-
-}
-
-static INT_PTR CALLBACK
-RecycleBinDlg(
- HWND hwndDlg,
- UINT uMsg,
- WPARAM wParam,
- LPARAM lParam
-)
-{
- LPPSHNOTIFY lppsn;
- LPNMLISTVIEW lppl;
- LVITEMW li;
- PDRIVE_ITEM_CONTEXT pItem;
- BOOL bSuccess;
- UINT uResult;
- PROPSHEETPAGE * page;
- DWORD dwStyle;
-
- switch(uMsg)
- {
- case WM_INITDIALOG:
- page = (PROPSHEETPAGE*)lParam;
- InitializeRecycleBinDlg(hwndDlg, (WCHAR)page->lParam);
- dwStyle = (DWORD) SendDlgItemMessage(hwndDlg, 14000, LVM_GETEXTENDEDLISTVIEWSTYLE, 0, 0);
- dwStyle = dwStyle | LVS_EX_FULLROWSELECT;
- SendDlgItemMessage(hwndDlg, 14000, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, dwStyle);
- if (GetDlgCtrlID((HWND)wParam) != 14000)
- {
- SetFocus(GetDlgItem(hwndDlg, 14000));
- return FALSE;
- }
- return TRUE;
- case WM_COMMAND:
- switch(LOWORD(wParam))
- {
- case 14001:
- toggleNukeOnDeleteOption(hwndDlg, FALSE);
- PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
- break;
- case 14003:
- toggleNukeOnDeleteOption(hwndDlg, TRUE);
- PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
- break;
- case 14004:
- PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
- break;
- }
- break;
- case WM_NOTIFY:
- lppsn = (LPPSHNOTIFY) lParam;
- lppl = (LPNMLISTVIEW) lParam;
- if (lppsn->hdr.code == PSN_APPLY)
- {
- if (GetDefaultItem(hwndDlg, &li) > -1)
- {
- pItem = (PDRIVE_ITEM_CONTEXT)li.lParam;
- if (pItem)
- {
- uResult = GetDlgItemInt(hwndDlg, 14002, &bSuccess, FALSE);
- if (bSuccess)
- pItem->dwMaxCapacity = uResult;
- if (SendDlgItemMessageW(hwndDlg, 14003, BM_GETCHECK, 0, 0) == BST_CHECKED)
- pItem->dwNukeOnDelete = TRUE;
- else
- pItem->dwNukeOnDelete = FALSE;
- }
- }
- if (StoreDriveSettings(hwndDlg))
- {
- SetWindowLongPtr( hwndDlg, DWL_MSGRESULT, PSNRET_NOERROR );
- return TRUE;
- }
- }
- else if (lppl->hdr.code == LVN_ITEMCHANGING)
- {
- ZeroMemory(&li, sizeof(li));
- li.mask = LVIF_PARAM;
- li.iItem = lppl->iItem;
- if (!SendMessageW(lppl->hdr.hwndFrom, LVM_GETITEMW, 0, (LPARAM)&li))
- return TRUE;
-
- pItem = (PDRIVE_ITEM_CONTEXT)li.lParam;
- if (!pItem)
- return TRUE;
-
- if (!(lppl->uOldState & LVIS_FOCUSED) && (lppl->uNewState & LVIS_FOCUSED))
- {
- /* new focused item */
- toggleNukeOnDeleteOption(lppl->hdr.hwndFrom, pItem->dwNukeOnDelete);
- SetDlgItemInt(hwndDlg, 14002, pItem->dwMaxCapacity, FALSE);
- }
- else if ((lppl->uOldState & LVIS_FOCUSED) && !(lppl->uNewState & LVIS_FOCUSED))
- {
- /* kill focus */
- uResult = GetDlgItemInt(hwndDlg, 14002, &bSuccess, FALSE);
- if (bSuccess)
- pItem->dwMaxCapacity = uResult;
- if (SendDlgItemMessageW(hwndDlg, 14003, BM_GETCHECK, 0, 0) == BST_CHECKED)
- pItem->dwNukeOnDelete = TRUE;
- else
- pItem->dwNukeOnDelete = FALSE;
- }
- return TRUE;
-
- }
- break;
- case WM_DESTROY:
- FreeDriveItemContext(hwndDlg);
- break;
- }
- return FALSE;
-}
-
-BOOL SH_ShowRecycleBinProperties(WCHAR sDrive)
-{
- HPROPSHEETPAGE hpsp[1];
- PROPSHEETHEADERW psh;
- HPROPSHEETPAGE hprop;
-
- BOOL ret;
-
-
- ZeroMemory(&psh, sizeof(PROPSHEETHEADERW));
- psh.dwSize = sizeof(PROPSHEETHEADERW);
- psh.dwFlags = PSP_DEFAULT | PSH_PROPTITLE;
- psh.pszCaption = MAKEINTRESOURCEW(IDS_RECYCLEBIN_FOLDER_NAME);
- psh.hwndParent = NULL;
- psh.phpage = hpsp;
- psh.hInstance = shell32_hInstance;
-
- hprop = SH_CreatePropertySheetPage(IDD_RECYCLE_BIN_PROPERTIES, RecycleBinDlg, (LPARAM)sDrive, NULL);
- if (!hprop)
- {
- ERR("Failed to create property sheet\n");
- return FALSE;
- }
- hpsp[psh.nPages] = hprop;
- psh.nPages++;
-
-
- ret = PropertySheetW(&psh);
- if (ret < 0)
- return FALSE;
- else
- return TRUE;
-}
-
+/**
+ * Tests whether a file can be trashed
+ * @param wszPath Path to the file to be trash
+ * @returns TRUE if the file can be trashed, FALSE otherwise
+ */
BOOL
TRASH_CanTrashFile(LPCWSTR wszPath)
{
DWORD FileSystemFlags, dwSize, dwDisposition;
HKEY hKey;
WCHAR szBuffer[10];
- WCHAR szKey[150] = L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Bitbucket\\Volume\\";
+ WCHAR szKey[150] = L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\BitBucket\\Volume\\";
if (wszPath[1] != L':')
{
return FALSE;
}
- if (GetDriveTypeW(wszPath) != DRIVE_FIXED)
+ // Copy and retrieve the root path from get given string
+ WCHAR wszRootPathName[MAX_PATH];
+ StringCbCopy(wszRootPathName, sizeof(wszRootPathName), wszPath);
+ PathStripToRootW(wszRootPathName);
+
+ // Test to see if the drive is fixed (non removable)
+ if (GetDriveTypeW(wszRootPathName) != DRIVE_FIXED)
{
/* no bitbucket on removable media */
return FALSE;
}
- if (!GetVolumeInformationW(wszPath, NULL, 0, &VolSerialNumber, &MaxComponentLength, &FileSystemFlags, NULL, 0))
+ if (!GetVolumeInformationW(wszRootPathName, NULL, 0, &VolSerialNumber, &MaxComponentLength, &FileSystemFlags, NULL, 0))
{
- ERR("GetVolumeInformationW failed with %u\n", GetLastError());
+ ERR("GetVolumeInformationW failed with %u wszRootPathName=%s\n", GetLastError(), debugstr_w(wszRootPathName));
return FALSE;
}
{
FIXME("stub\n");
-
-
return S_OK;
}
-/****************************************************************************
- * IDropTarget implementation
+/*************************************************************************
+ * SHEmptyRecycleBinA (SHELL32.@)
*/
-BOOL CRecycleBin::QueryDrop(DWORD dwKeyState, LPDWORD pdwEffect)
+HRESULT WINAPI SHEmptyRecycleBinA(HWND hwnd, LPCSTR pszRootPath, DWORD dwFlags)
{
- /* TODO on shift we should delete, we should update the cursor manager to show this. */
-
- DWORD dwEffect = DROPEFFECT_COPY;
-
- *pdwEffect = DROPEFFECT_NONE;
-
- if (fAcceptFmt) { /* Does our interpretation of the keystate ... */
- *pdwEffect = KeyStateToDropEffect (dwKeyState);
+ LPWSTR szRootPathW = NULL;
+ int len;
+ HRESULT hr;
- if (*pdwEffect == DROPEFFECT_NONE)
- *pdwEffect = dwEffect;
+ TRACE("%p, %s, 0x%08x\n", hwnd, debugstr_a(pszRootPath), dwFlags);
- /* ... matches the desired effect ? */
- if (dwEffect & *pdwEffect) {
- return TRUE;
+ if (pszRootPath)
+ {
+ len = MultiByteToWideChar(CP_ACP, 0, pszRootPath, -1, NULL, 0);
+ if (len == 0)
+ return HRESULT_FROM_WIN32(GetLastError());
+ szRootPathW = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
+ if (!szRootPathW)
+ return E_OUTOFMEMORY;
+ if (MultiByteToWideChar(CP_ACP, 0, pszRootPath, -1, szRootPathW, len) == 0)
+ {
+ HeapFree(GetProcessHeap(), 0, szRootPathW);
+ return HRESULT_FROM_WIN32(GetLastError());
}
}
- return FALSE;
-}
-HRESULT WINAPI CRecycleBin::DragEnter(IDataObject *pDataObject,
- DWORD dwKeyState, POINTL pt, DWORD *pdwEffect)
-{
- TRACE("Recycle bin drag over (%p)\n", this);
- /* The recycle bin accepts pretty much everything, and sets a CSIDL flag. */
- fAcceptFmt = TRUE;
+ hr = SHEmptyRecycleBinW(hwnd, szRootPathW, dwFlags);
+ HeapFree(GetProcessHeap(), 0, szRootPathW);
- QueryDrop(dwKeyState, pdwEffect);
- return S_OK;
+ return hr;
}
-HRESULT WINAPI CRecycleBin::DragOver(DWORD dwKeyState, POINTL pt,
- DWORD *pdwEffect)
+HRESULT WINAPI SHEmptyRecycleBinW(HWND hwnd, LPCWSTR pszRootPath, DWORD dwFlags)
{
- TRACE("(%p)\n", this);
-
- if (!pdwEffect)
- return E_INVALIDARG;
+ WCHAR szPath[MAX_PATH] = {0}, szBuffer[MAX_PATH];
+ DWORD dwSize, dwType, count;
+ LONG ret;
+ IShellFolder *pDesktop, *pRecycleBin;
+ PIDLIST_ABSOLUTE pidlRecycleBin;
+ PITEMID_CHILD pidl;
+ HRESULT hr = S_OK;
+ LPENUMIDLIST penumFiles;
+ STRRET StrRet;
- QueryDrop(dwKeyState, pdwEffect);
+ TRACE("%p, %s, 0x%08x\n", hwnd, debugstr_w(pszRootPath), dwFlags);
- return S_OK;
-}
+ if (!(dwFlags & SHERB_NOCONFIRMATION))
+ {
+ hr = SHGetDesktopFolder(&pDesktop);
+ if (FAILED(hr))
+ return hr;
+ hr = SHGetFolderLocation(NULL, CSIDL_BITBUCKET, NULL, 0, &pidlRecycleBin);
+ if (FAILED(hr))
+ {
+ pDesktop->Release();
+ return hr;
+ }
+ hr = pDesktop->BindToObject(pidlRecycleBin, NULL, IID_PPV_ARG(IShellFolder, &pRecycleBin));
+ CoTaskMemFree(pidlRecycleBin);
+ pDesktop->Release();
+ if (FAILED(hr))
+ return hr;
+ hr = pRecycleBin->EnumObjects(hwnd, SHCONTF_FOLDERS | SHCONTF_NONFOLDERS | SHCONTF_INCLUDEHIDDEN, &penumFiles);
+ if (FAILED(hr))
+ {
+ pRecycleBin->Release();
+ return hr;
+ }
-HRESULT WINAPI CRecycleBin::DragLeave()
-{
- TRACE("(%p)\n", this);
+ count = 0;
+ if (hr != S_FALSE)
+ {
+ while (penumFiles->Next(1, &pidl, NULL) == S_OK)
+ {
+ count++;
+ pRecycleBin->GetDisplayNameOf(pidl, SHGDN_NORMAL, &StrRet);
+ StrRetToBuf(&StrRet, pidl, szBuffer, _countof(szBuffer));
+ CoTaskMemFree(pidl);
+ }
+ penumFiles->Release();
+ }
+ pRecycleBin->Release();
- fAcceptFmt = FALSE;
+ switch (count)
+ {
+ case 0:
+ /* no files, don't need confirmation */
+ break;
+
+ case 1:
+ /* we have only one item inside the bin, so show a message box with its name */
+ if (ShellMessageBoxW(shell32_hInstance, hwnd, MAKEINTRESOURCEW(IDS_DELETEITEM_TEXT), MAKEINTRESOURCEW(IDS_EMPTY_BITBUCKET),
+ MB_ICONEXCLAMATION | MB_YESNO | MB_DEFBUTTON2, szBuffer) == IDNO)
+ {
+ return S_OK;
+ }
+ break;
- return S_OK;
-}
+ default:
+ /* we have more than one item, so show a message box with the count of the items */
+ StringCbPrintfW(szBuffer, sizeof(szBuffer), L"%u", count);
+ if (ShellMessageBoxW(shell32_hInstance, hwnd, MAKEINTRESOURCEW(IDS_DELETEMULTIPLE_TEXT), MAKEINTRESOURCEW(IDS_EMPTY_BITBUCKET),
+ MB_ICONEXCLAMATION | MB_YESNO | MB_DEFBUTTON2, szBuffer) == IDNO)
+ {
+ return S_OK;
+ }
+ break;
+ }
+ }
-HRESULT WINAPI CRecycleBin::Drop(IDataObject *pDataObject,
- DWORD dwKeyState, POINTL pt, DWORD *pdwEffect)
-{
- TRACE("(%p) object dropped on recycle bin, effect %u\n", this, *pdwEffect);
-
- /* TODO: pdwEffect should be read and make the drop object be permanently deleted in the move case (shift held) */
-
- FORMATETC fmt;
- TRACE("(%p)->(DataObject=%p)\n", this, pDataObject);
- InitFormatEtc (fmt, cfShellIDList, TYMED_HGLOBAL);
-
- /* Handle cfShellIDList Drop objects here, otherwise send the approriate message to other software */
- if (SUCCEEDED(pDataObject->QueryGetData(&fmt))) {
- IStream *s;
- CoMarshalInterThreadInterfaceInStream(IID_IDataObject, pDataObject, &s);
- SHCreateThread(DoDeleteThreadProc, s, NULL, NULL);
+ if (dwFlags & SHERB_NOPROGRESSUI)
+ {
+ ret = EmptyRecycleBinW(pszRootPath);
}
else
{
- /*
- * TODO call SetData on the data object with format CFSTR_TARGETCLSID
- * set to the Recycle Bin's class identifier CLSID_RecycleBin.
- */
+ /* FIXME
+ * show a progress dialog
+ */
+ ret = EmptyRecycleBinW(pszRootPath);
}
- return S_OK;
-}
-DWORD WINAPI DoDeleteThreadProc(LPVOID lpParameter)
-{
- CoInitialize(NULL);
- CComPtr<IDataObject> pDataObject;
- HRESULT hr = CoGetInterfaceAndReleaseStream (static_cast<IStream*>(lpParameter), IID_PPV_ARG(IDataObject, &pDataObject));
- if (SUCCEEDED(hr))
+ if (!ret)
+ return HRESULT_FROM_WIN32(GetLastError());
+
+ if (!(dwFlags & SHERB_NOSOUND))
{
- DoDeleteDataObject(pDataObject);
+ dwSize = sizeof(szPath);
+ ret = RegGetValueW(HKEY_CURRENT_USER,
+ L"AppEvents\\Schemes\\Apps\\Explorer\\EmptyRecycleBin\\.Current",
+ NULL,
+ RRF_RT_REG_SZ,
+ &dwType,
+ (PVOID)szPath,
+ &dwSize);
+ if (ret != ERROR_SUCCESS)
+ return S_OK;
+
+ if (dwType != REG_EXPAND_SZ) /* type dismatch */
+ return S_OK;
+
+ szPath[_countof(szPath)-1] = L'\0';
+ PlaySoundW(szPath, NULL, SND_FILENAME);
}
- CoUninitialize();
- return 0;
+ return S_OK;
}
-HRESULT WINAPI DoDeleteDataObject(IDataObject *pda)
+HRESULT WINAPI SHQueryRecycleBinA(LPCSTR pszRootPath, LPSHQUERYRBINFO pSHQueryRBInfo)
{
- TRACE("performing delete");
+ LPWSTR szRootPathW = NULL;
+ int len;
HRESULT hr;
- STGMEDIUM medium;
- FORMATETC formatetc;
- InitFormatEtc(formatetc, RegisterClipboardFormatW(CFSTR_SHELLIDLIST), TYMED_HGLOBAL);
- hr = pda->GetData(&formatetc, &medium);
- if (FAILED(hr))
- return hr;
+ TRACE("%s, %p\n", debugstr_a(pszRootPath), pSHQueryRBInfo);
- /* lock the handle */
- LPIDA lpcida = (LPIDA)GlobalLock(medium.hGlobal);
- if (!lpcida)
- {
- ReleaseStgMedium(&medium);
- return E_FAIL;
- }
-
- /* convert the data into pidl */
- LPITEMIDLIST pidl;
- LPITEMIDLIST *apidl = _ILCopyCidaToaPidl(&pidl, lpcida);
- if (!apidl)
- {
- ReleaseStgMedium(&medium);
- return E_FAIL;
- }
-
- CComPtr<IShellFolder> psfDesktop;
- CComPtr<IShellFolder> psfFrom = NULL;
-
- /* Grab the desktop shell folder */
- hr = SHGetDesktopFolder(&psfDesktop);
- if (FAILED(hr))
+ if (pszRootPath)
{
- ERR("SHGetDesktopFolder failed\n");
- SHFree(pidl);
- _ILFreeaPidl(apidl, lpcida->cidl);
- ReleaseStgMedium(&medium);
- return E_FAIL;
- }
-
- /* Find source folder, this is where the clipboard data was copied from */
- if (_ILIsDesktop(pidl))
- {
- psfFrom = psfDesktop;
- }
- else
- {
- hr = psfDesktop->BindToObject(pidl, NULL, IID_PPV_ARG(IShellFolder, &psfFrom));
- if (FAILED(hr))
+ len = MultiByteToWideChar(CP_ACP, 0, pszRootPath, -1, NULL, 0);
+ if (len == 0)
+ return HRESULT_FROM_WIN32(GetLastError());
+ szRootPathW = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
+ if (!szRootPathW)
+ return E_OUTOFMEMORY;
+ if (MultiByteToWideChar(CP_ACP, 0, pszRootPath, -1, szRootPathW, len) == 0)
{
- ERR("no IShellFolder\n");
- SHFree(pidl);
- _ILFreeaPidl(apidl, lpcida->cidl);
- ReleaseStgMedium(&medium);
- return E_FAIL;
+ HeapFree(GetProcessHeap(), 0, szRootPathW);
+ return HRESULT_FROM_WIN32(GetLastError());
}
}
- STRRET strTemp;
- hr = psfFrom->GetDisplayNameOf(apidl[0], SHGDN_FORPARSING, &strTemp);
- if (FAILED(hr))
- {
- ERR("IShellFolder_GetDisplayNameOf failed with %x\n", hr);
- SHFree(pidl);
- _ILFreeaPidl(apidl, lpcida->cidl);
- ReleaseStgMedium(&medium);
- return hr;
- }
+ hr = SHQueryRecycleBinW(szRootPathW, pSHQueryRBInfo);
+ HeapFree(GetProcessHeap(), 0, szRootPathW);
- WCHAR wszPath[MAX_PATH];
- hr = StrRetToBufW(&strTemp, apidl[0], wszPath, _countof(wszPath));
- if (FAILED(hr))
- {
- ERR("StrRetToBufW failed with %x\n", hr);
- SHFree(pidl);
- _ILFreeaPidl(apidl, lpcida->cidl);
- ReleaseStgMedium(&medium);
- return hr;
- }
-
- /* Only keep the base path */
- LPWSTR pwszFilename = PathFindFileNameW(wszPath);
- *pwszFilename = L'\0';
-
- /* Build paths list */
- LPWSTR pwszPaths = BuildPathsList(wszPath, lpcida->cidl, (LPCITEMIDLIST*) apidl);
- if (!pwszPaths)
- {
- SHFree(pidl);
- _ILFreeaPidl(apidl, lpcida->cidl);
- ReleaseStgMedium(&medium);
- return E_FAIL;
- }
+ return hr;
+}
- /* Delete them */
- SHFILEOPSTRUCTW FileOp;
- ZeroMemory(&FileOp, sizeof(FileOp));
- FileOp.wFunc = FO_DELETE;
- FileOp.pFrom = pwszPaths;
- FileOp.fFlags = FOF_ALLOWUNDO;
+HRESULT WINAPI SHQueryRecycleBinW(LPCWSTR pszRootPath, LPSHQUERYRBINFO pSHQueryRBInfo)
+{
+ FIXME("%s, %p - stub\n", debugstr_w(pszRootPath), pSHQueryRBInfo);
- if (SHFileOperationW(&FileOp) != 0)
+ if (!(pszRootPath) || (pszRootPath[0] == 0) ||
+ !(pSHQueryRBInfo) || (pSHQueryRBInfo->cbSize < sizeof(SHQUERYRBINFO)))
{
- ERR("SHFileOperation failed with 0x%x for %s\n", GetLastError(), debugstr_w(pwszPaths));
- hr = E_FAIL;
+ return E_INVALIDARG;
}
- HeapFree(GetProcessHeap(), 0, pwszPaths);
- SHFree(pidl);
- _ILFreeaPidl(apidl, lpcida->cidl);
- ReleaseStgMedium(&medium);
+ pSHQueryRBInfo->i64Size = 0;
+ pSHQueryRBInfo->i64NumItems = 0;
- return hr;
-}
\ No newline at end of file
+ return S_OK;
+}