2 * Trash virtual folder support. The trashing engine is implemented in trash.c
4 * Copyright (C) 2006 Mikolaj Zalewski
5 * Copyright (C) 2009 Andrew Hill
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #define MAX_PROPERTY_SHEET_PAGE 32
26 WINE_DEFAULT_DEBUG_CHANNEL(CRecycleBin
);
38 static const columninfo RecycleBinColumns
[] =
40 {IDS_SHV_COLUMN1
, &FMTID_Storage
, PID_STG_NAME
, SHCOLSTATE_TYPE_STR
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_LEFT
, 30},
41 {IDS_SHV_COLUMN_DELFROM
, &FMTID_Displaced
, PID_DISPLACED_FROM
, SHCOLSTATE_TYPE_STR
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_LEFT
, 30},
42 {IDS_SHV_COLUMN_DELDATE
, &FMTID_Displaced
, PID_DISPLACED_DATE
, SHCOLSTATE_TYPE_DATE
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_LEFT
, 20},
43 {IDS_SHV_COLUMN2
, &FMTID_Storage
, PID_STG_SIZE
, SHCOLSTATE_TYPE_INT
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_RIGHT
, 20},
44 {IDS_SHV_COLUMN3
, &FMTID_Storage
, PID_STG_STORAGETYPE
, SHCOLSTATE_TYPE_INT
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_LEFT
, 20},
45 {IDS_SHV_COLUMN4
, &FMTID_Storage
, PID_STG_WRITETIME
, SHCOLSTATE_TYPE_DATE
| SHCOLSTATE_ONBYDEFAULT
, LVCFMT_LEFT
, 20},
46 /* {"creation time", &FMTID_Storage, PID_STG_CREATETIME, SHCOLSTATE_TYPE_DATE, LVCFMT_LEFT, 20}, */
47 /* {"attribs", &FMTID_Storage, PID_STG_ATTRIBUTES, SHCOLSTATE_TYPE_STR, LVCFMT_LEFT, 20}, */
51 #define COLUMN_DELFROM 1
52 #define COLUMN_DATEDEL 2
55 #define COLUMN_MTIME 5
57 #define COLUMNS_COUNT 6
63 class CRecycleBinEnum
:
64 public IEnumIDListImpl
70 HRESULT WINAPI
Initialize(DWORD dwFlags
);
71 static BOOL WINAPI
CBEnumRecycleBin(IN PVOID Context
, IN HANDLE hDeletedFile
);
72 BOOL WINAPI
CBEnumRecycleBin(IN HANDLE hDeletedFile
);
74 BEGIN_COM_MAP(CRecycleBinEnum
)
75 COM_INTERFACE_ENTRY_IID(IID_IEnumIDList
, IEnumIDList
)
79 class CRecycleBinItemContextMenu
:
80 public CComObjectRootEx
<CComMultiThreadModelNoCS
>,
86 CRecycleBinItemContextMenu();
87 ~CRecycleBinItemContextMenu();
88 HRESULT WINAPI
Initialize(LPCITEMIDLIST pidl
);
91 virtual HRESULT WINAPI
QueryContextMenu(HMENU hMenu
, UINT indexMenu
, UINT idCmdFirst
, UINT idCmdLast
, UINT uFlags
);
92 virtual HRESULT WINAPI
InvokeCommand(LPCMINVOKECOMMANDINFO lpcmi
);
93 virtual HRESULT WINAPI
GetCommandString(UINT_PTR idCommand
, UINT uFlags
, UINT
*lpReserved
, LPSTR lpszName
, UINT uMaxNameLen
);
96 virtual HRESULT WINAPI
HandleMenuMsg(UINT uMsg
, WPARAM wParam
, LPARAM lParam
);
98 BEGIN_COM_MAP(CRecycleBinItemContextMenu
)
99 COM_INTERFACE_ENTRY_IID(IID_IContextMenu
, IContextMenu
)
100 COM_INTERFACE_ENTRY_IID(IID_IContextMenu2
, IContextMenu2
)
106 PIDLRecycleStruct
*pFileDetails
;
109 } SEARCH_CONTEXT
, *PSEARCH_CONTEXT
;
113 DWORD dwNukeOnDelete
;
116 } DRIVE_ITEM_CONTEXT
, *PDRIVE_ITEM_CONTEXT
;
118 BOOL WINAPI
CBSearchRecycleBin(IN PVOID Context
, IN HANDLE hDeletedFile
)
120 PSEARCH_CONTEXT pContext
= (PSEARCH_CONTEXT
)Context
;
122 PDELETED_FILE_DETAILS_W pFileDetails
;
126 if (!GetDeletedFileDetailsW(hDeletedFile
,
130 GetLastError() != ERROR_INSUFFICIENT_BUFFER
)
132 ERR("GetDeletedFileDetailsW failed\n");
136 pFileDetails
= (DELETED_FILE_DETAILS_W
*)SHAlloc(dwSize
);
143 if (!GetDeletedFileDetailsW(hDeletedFile
,
148 ERR("GetDeletedFileDetailsW failed\n");
149 SHFree(pFileDetails
);
153 ret
= memcmp(pFileDetails
, pContext
->pFileDetails
, dwSize
);
156 pContext
->hDeletedFile
= hDeletedFile
;
157 pContext
->bFound
= TRUE
;
160 CloseRecycleBinHandle(hDeletedFile
);
162 SHFree(pFileDetails
);
166 static PIDLRecycleStruct
* _ILGetRecycleStruct(LPCITEMIDLIST pidl
)
168 LPPIDLDATA pdata
= _ILGetDataPointer(pidl
);
170 if (pdata
&& pdata
->type
== 0x00)
171 return (PIDLRecycleStruct
*) & (pdata
->u
.crecycle
);
176 CRecycleBinEnum::CRecycleBinEnum()
180 CRecycleBinEnum::~CRecycleBinEnum()
184 HRESULT WINAPI
CRecycleBinEnum::Initialize(DWORD dwFlags
)
186 static LPCWSTR szDrive
= L
"C:\\";
188 if (dwFlags
& SHCONTF_NONFOLDERS
)
190 TRACE("Starting Enumeration\n");
192 if (!EnumerateRecycleBinW(szDrive
/* FIXME */ , CBEnumRecycleBin
, (PVOID
)this))
194 WARN("Error: EnumerateCRecycleBinW failed\n");
205 static LPITEMIDLIST
_ILCreateRecycleItem(PDELETED_FILE_DETAILS_W pFileDetails
)
209 PIDLRecycleStruct
* p
;
210 int size0
= (char*)&tmp
.u
.crecycle
.szName
- (char*)&tmp
.u
.crecycle
;
214 size
+= (wcslen(pFileDetails
->FileName
) + 1) * sizeof(WCHAR
);
216 pidl
= (LPITEMIDLIST
)SHAlloc(size
+ 4);
220 pidl
->mkid
.cb
= size
+ 2;
221 memcpy(pidl
->mkid
.abID
, &tmp
, 2 + size0
);
223 p
= &((PIDLDATA
*)pidl
->mkid
.abID
)->u
.crecycle
;
224 RtlCopyMemory(p
, pFileDetails
, sizeof(DELETED_FILE_DETAILS_W
));
225 wcscpy(p
->szName
, pFileDetails
->FileName
);
226 *(WORD
*)((char*)pidl
+ (size
+ 2)) = 0;
230 BOOL WINAPI
CRecycleBinEnum::CBEnumRecycleBin(IN PVOID Context
, IN HANDLE hDeletedFile
)
232 return ((CRecycleBinEnum
*)Context
)->CBEnumRecycleBin(hDeletedFile
);
235 BOOL WINAPI
CRecycleBinEnum::CBEnumRecycleBin(IN HANDLE hDeletedFile
)
237 PDELETED_FILE_DETAILS_W pFileDetails
;
239 LPITEMIDLIST pidl
= NULL
;
242 if (!GetDeletedFileDetailsW(hDeletedFile
,
246 GetLastError() != ERROR_INSUFFICIENT_BUFFER
)
248 ERR("GetDeletedFileDetailsW failed\n");
252 pFileDetails
= (DELETED_FILE_DETAILS_W
*)SHAlloc(dwSize
);
259 if (!GetDeletedFileDetailsW(hDeletedFile
,
264 ERR("GetDeletedFileDetailsW failed\n");
265 SHFree(pFileDetails
);
269 pidl
= _ILCreateRecycleItem(pFileDetails
);
272 SHFree(pFileDetails
);
276 ret
= AddToEnumList(pidl
);
280 SHFree(pFileDetails
);
281 TRACE("Returning %d\n", ret
);
282 CloseRecycleBinHandle(hDeletedFile
);
286 /**************************************************************************
287 * IContextMenu2 Bitbucket Item Implementation
290 CRecycleBinItemContextMenu::CRecycleBinItemContextMenu()
295 CRecycleBinItemContextMenu::~CRecycleBinItemContextMenu()
300 HRESULT WINAPI
CRecycleBinItemContextMenu::Initialize(LPCITEMIDLIST pidl
)
302 apidl
= ILClone(pidl
);
304 return E_OUTOFMEMORY
;
308 HRESULT WINAPI
CRecycleBinItemContextMenu::QueryContextMenu(HMENU hMenu
, UINT indexMenu
, UINT idCmdFirst
, UINT idCmdLast
, UINT uFlags
)
310 WCHAR szBuffer
[30] = {0};
313 TRACE("(%p)->(hmenu=%p indexmenu=%x cmdfirst=%x cmdlast=%x flags=%x )\n", this, hMenu
, indexMenu
, idCmdFirst
, idCmdLast
, uFlags
);
315 if (LoadStringW(shell32_hInstance
, IDS_RESTORE
, szBuffer
, sizeof(szBuffer
) / sizeof(WCHAR
)))
317 szBuffer
[(sizeof(szBuffer
)/sizeof(WCHAR
))-1] = L
'\0';
318 _InsertMenuItemW(hMenu
, indexMenu
++, TRUE
, idCmdFirst
+ Count
, MFT_STRING
, szBuffer
, MFS_ENABLED
);
322 if (LoadStringW(shell32_hInstance
, IDS_CUT
, szBuffer
, sizeof(szBuffer
) / sizeof(WCHAR
)))
324 _InsertMenuItemW(hMenu
, indexMenu
++, TRUE
, idCmdFirst
+ Count
++, MFT_SEPARATOR
, NULL
, MFS_ENABLED
);
325 szBuffer
[(sizeof(szBuffer
)/sizeof(WCHAR
))-1] = L
'\0';
326 _InsertMenuItemW(hMenu
, indexMenu
++, TRUE
, idCmdFirst
+ Count
++, MFT_STRING
, szBuffer
, MFS_ENABLED
);
329 if (LoadStringW(shell32_hInstance
, IDS_DELETE
, szBuffer
, sizeof(szBuffer
) / sizeof(WCHAR
)))
331 szBuffer
[(sizeof(szBuffer
)/sizeof(WCHAR
))-1] = L
'\0';
332 _InsertMenuItemW(hMenu
, indexMenu
++, TRUE
, idCmdFirst
+ Count
++, MFT_SEPARATOR
, NULL
, MFS_ENABLED
);
333 _InsertMenuItemW(hMenu
, indexMenu
++, TRUE
, idCmdFirst
+ Count
++, MFT_STRING
, szBuffer
, MFS_ENABLED
);
336 if (LoadStringW(shell32_hInstance
, IDS_PROPERTIES
, szBuffer
, sizeof(szBuffer
) / sizeof(WCHAR
)))
338 szBuffer
[(sizeof(szBuffer
)/sizeof(WCHAR
))-1] = L
'\0';
339 _InsertMenuItemW(hMenu
, indexMenu
++, TRUE
, idCmdFirst
+ Count
++, MFT_SEPARATOR
, NULL
, MFS_ENABLED
);
340 _InsertMenuItemW(hMenu
, indexMenu
++, TRUE
, idCmdFirst
+ Count
, MFT_STRING
, szBuffer
, MFS_DEFAULT
);
343 return MAKE_HRESULT(SEVERITY_SUCCESS
, 0, Count
);
346 HRESULT WINAPI
CRecycleBinItemContextMenu::InvokeCommand(LPCMINVOKECOMMANDINFO lpcmi
)
348 SEARCH_CONTEXT Context
;
349 static LPCWSTR szDrive
= L
"C:\\";
351 TRACE("(%p)->(invcom=%p verb=%p wnd=%p)\n", this, lpcmi
, lpcmi
->lpVerb
, lpcmi
->hwnd
);
353 if (lpcmi
->lpVerb
== MAKEINTRESOURCEA(1) || lpcmi
->lpVerb
== MAKEINTRESOURCEA(5))
355 Context
.pFileDetails
= _ILGetRecycleStruct(apidl
);
356 Context
.bFound
= FALSE
;
358 EnumerateRecycleBinW(szDrive
, CBSearchRecycleBin
, (PVOID
)&Context
);
362 if (lpcmi
->lpVerb
== MAKEINTRESOURCEA(1))
365 if (RestoreFile(Context
.hDeletedFile
))
372 DeleteFileHandleToRecycleBin(Context
.hDeletedFile
);
376 else if (lpcmi
->lpVerb
== MAKEINTRESOURCEA(3))
378 FIXME("implement cut\n");
381 else if (lpcmi
->lpVerb
== MAKEINTRESOURCEA(7))
383 FIXME("implement properties\n");
390 HRESULT WINAPI
CRecycleBinItemContextMenu::GetCommandString(UINT_PTR idCommand
, UINT uFlags
, UINT
*lpReserved
, LPSTR lpszName
, UINT uMaxNameLen
)
392 TRACE("(%p)->(idcom=%lx flags=%x %p name=%p len=%x)\n", this, idCommand
, uFlags
, lpReserved
, lpszName
, uMaxNameLen
);
397 HRESULT WINAPI
CRecycleBinItemContextMenu::HandleMenuMsg(UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
399 TRACE("CRecycleBin_IContextMenu2Item_HandleMenuMsg (%p)->(msg=%x wp=%lx lp=%lx)\n", this, uMsg
, wParam
, lParam
);
404 static HRESULT WINAPI
CRecycleBinItemContextMenuConstructor(REFIID riid
, LPCITEMIDLIST pidl
, LPVOID
*ppv
)
406 CComObject
<CRecycleBinItemContextMenu
> *theMenu
;
407 CComPtr
<IUnknown
> result
;
410 TRACE("%s\n", shdebugstr_guid(&riid
));
415 ATLTRY(theMenu
= new CComObject
<CRecycleBinItemContextMenu
>);
417 return E_OUTOFMEMORY
;
418 hResult
= theMenu
->QueryInterface(riid
, (void **)&result
);
424 hResult
= theMenu
->Initialize(pidl
);
427 *ppv
= result
.Detach();
428 TRACE ("--(%p)\n", *ppv
);
432 CRecycleBin::CRecycleBin()
438 CRecycleBin::~CRecycleBin()
440 /* InterlockedDecrement(&objCount);*/
444 /*************************************************************************
445 * RecycleBin IPersistFolder2 interface
448 HRESULT WINAPI
CRecycleBin::GetClassID(CLSID
*pClassID
)
450 TRACE("(%p, %p)\n", this, pClassID
);
451 if (pClassID
== NULL
)
453 memcpy(pClassID
, &CLSID_RecycleBin
, sizeof(CLSID
));
457 HRESULT WINAPI
CRecycleBin::Initialize(LPCITEMIDLIST pidl
)
459 TRACE("(%p, %p)\n", this, pidl
);
461 SHFree((LPVOID
)this->pidl
);
462 this->pidl
= ILClone(pidl
);
463 if (this->pidl
== NULL
)
464 return E_OUTOFMEMORY
;
468 HRESULT WINAPI
CRecycleBin::GetCurFolder(LPITEMIDLIST
*ppidl
)
471 *ppidl
= ILClone(pidl
);
475 /*************************************************************************
476 * RecycleBin IShellFolder2 interface
479 HRESULT WINAPI
CRecycleBin::ParseDisplayName(HWND hwnd
, LPBC pbc
,
480 LPOLESTR pszDisplayName
, ULONG
*pchEaten
, LPITEMIDLIST
*ppidl
,
481 ULONG
*pdwAttributes
)
488 PDELETED_FILE_DETAILS_W
489 UnpackDetailsFromPidl(LPCITEMIDLIST pidl
)
491 return (PDELETED_FILE_DETAILS_W
)&pidl
->mkid
.abID
;
494 HRESULT WINAPI
CRecycleBin::EnumObjects(HWND hwndOwner
, DWORD dwFlags
, LPENUMIDLIST
*ppEnumIDList
)
496 CComObject
<CRecycleBinEnum
> *theEnumerator
;
497 CComPtr
<IEnumIDList
> result
;
500 TRACE ("(%p)->(HWND=%p flags=0x%08x pplist=%p)\n", this, hwndOwner
, dwFlags
, ppEnumIDList
);
502 if (ppEnumIDList
== NULL
)
504 *ppEnumIDList
= NULL
;
505 ATLTRY (theEnumerator
= new CComObject
<CRecycleBinEnum
>);
506 if (theEnumerator
== NULL
)
507 return E_OUTOFMEMORY
;
508 hResult
= theEnumerator
->QueryInterface(IID_PPV_ARG(IEnumIDList
, &result
));
509 if (FAILED (hResult
))
511 delete theEnumerator
;
514 hResult
= theEnumerator
->Initialize(dwFlags
);
515 if (FAILED (hResult
))
517 *ppEnumIDList
= result
.Detach();
519 TRACE ("-- (%p)->(new ID List: %p)\n", this, *ppEnumIDList
);
524 HRESULT WINAPI
CRecycleBin::BindToObject(LPCITEMIDLIST pidl
, LPBC pbc
, REFIID riid
, void **ppv
)
526 FIXME("(%p, %p, %p, %s, %p) - stub\n", this, pidl
, pbc
, debugstr_guid(&riid
), ppv
);
530 HRESULT WINAPI
CRecycleBin::BindToStorage(LPCITEMIDLIST pidl
, LPBC pbc
, REFIID riid
, void **ppv
)
532 FIXME("(%p, %p, %p, %s, %p) - stub\n", this, pidl
, pbc
, debugstr_guid(&riid
), ppv
);
536 HRESULT WINAPI
CRecycleBin::CompareIDs(LPARAM lParam
, LPCITEMIDLIST pidl1
, LPCITEMIDLIST pidl2
)
539 TRACE("(%p, %p, %p, %p)\n", this, (void *)lParam
, pidl1
, pidl2
);
540 if (pidl1
->mkid
.cb
!= pidl2
->mkid
.cb
)
541 return MAKE_HRESULT(SEVERITY_SUCCESS
, 0, pidl1
->mkid
.cb
- pidl2
->mkid
.cb
);
542 return MAKE_HRESULT(SEVERITY_SUCCESS
, 0, (unsigned short)memcmp(pidl1
->mkid
.abID
, pidl2
->mkid
.abID
, pidl1
->mkid
.cb
));
545 HRESULT WINAPI
CRecycleBin::CreateViewObject(HWND hwndOwner
, REFIID riid
, void **ppv
)
547 LPSHELLVIEW pShellView
;
548 HRESULT hr
= E_NOINTERFACE
;
550 TRACE("(%p, %p, %s, %p)\n", this, hwndOwner
, debugstr_guid(&riid
), ppv
);
557 if (IsEqualIID (riid
, IID_IDropTarget
))
559 WARN ("IDropTarget not implemented\n");
562 else if (IsEqualIID (riid
, IID_IContextMenu
) || IsEqualIID (riid
, IID_IContextMenu2
))
564 hr
= this->QueryInterface(riid
, ppv
);
566 else if (IsEqualIID (riid
, IID_IShellView
))
568 hr
= IShellView_Constructor ((IShellFolder
*)this, &pShellView
);
571 hr
= pShellView
->QueryInterface(riid
, ppv
);
572 pShellView
->Release();
577 TRACE ("-- (%p)->(interface=%p)\n", this, ppv
);
582 HRESULT WINAPI
CRecycleBin::GetAttributesOf(UINT cidl
, LPCITEMIDLIST
*apidl
,
585 TRACE("(%p, %d, {%p, ...}, {%x})\n", this, cidl
, apidl
? apidl
[0] : NULL
, (unsigned int)*rgfInOut
);
586 *rgfInOut
&= SFGAO_FOLDER
|SFGAO_DROPTARGET
|SFGAO_HASPROPSHEET
|SFGAO_CANLINK
;
590 HRESULT WINAPI
CRecycleBin::GetUIObjectOf(HWND hwndOwner
, UINT cidl
, LPCITEMIDLIST
*apidl
,
591 REFIID riid
, UINT
*prgfInOut
, void **ppv
)
593 IUnknown
*pObj
= NULL
;
594 HRESULT hr
= E_INVALIDARG
;
596 TRACE ("(%p)->(%p,%u,apidl=%p, %p %p)\n", this,
597 hwndOwner
, cidl
, apidl
, prgfInOut
, ppv
);
604 if ((IsEqualIID (riid
, IID_IContextMenu
) || IsEqualIID(riid
, IID_IContextMenu2
)) && (cidl
>= 1))
606 hr
= CRecycleBinItemContextMenuConstructor(riid
, apidl
[0], (void **)&pObj
);
608 else if (IsEqualIID (riid
, IID_IDropTarget
) && (cidl
>= 1))
610 hr
= this->QueryInterface(IID_IDropTarget
, (LPVOID
*) & pObj
);
615 if (SUCCEEDED(hr
) && !pObj
)
619 TRACE ("(%p)->hr=0x%08x\n", this, hr
);
623 HRESULT WINAPI
CRecycleBin::GetDisplayNameOf(LPCITEMIDLIST pidl
, SHGDNF uFlags
, STRRET
*pName
)
625 PIDLRecycleStruct
*pFileDetails
;
628 TRACE("(%p, %p, %x, %p)\n", this, pidl
, (unsigned int)uFlags
, pName
);
631 if (_ILIsBitBucket (pidl
))
635 if (HCR_GetClassNameW(CLSID_RecycleBin
, pszPath
, MAX_PATH
))
637 pName
->uType
= STRRET_WSTR
;
638 pName
->pOleStr
= StrDupW(pszPath
);
643 pFileDetails
= _ILGetRecycleStruct(pidl
);
647 pName
->uType
= STRRET_CSTR
;
651 pFileName
= wcsrchr(pFileDetails
->szName
, L
'\\');
655 pName
->uType
= STRRET_CSTR
;
659 pName
->pOleStr
= StrDupW(pFileName
+ 1);
660 if (pName
->pOleStr
== NULL
)
661 return E_OUTOFMEMORY
;
663 pName
->uType
= STRRET_WSTR
;
667 HRESULT WINAPI
CRecycleBin::SetNameOf(HWND hwnd
, LPCITEMIDLIST pidl
, LPCOLESTR pszName
,
668 SHGDNF uFlags
, LPITEMIDLIST
*ppidlOut
)
671 return E_FAIL
; /* not supported */
674 HRESULT WINAPI
CRecycleBin::GetDefaultSearchGUID(GUID
*pguid
)
680 HRESULT WINAPI
CRecycleBin::EnumSearches(IEnumExtraSearch
**ppEnum
)
687 HRESULT WINAPI
CRecycleBin::GetDefaultColumn(DWORD dwReserved
, ULONG
*pSort
, ULONG
*pDisplay
)
689 TRACE("(%p, %x, %p, %p)\n", this, (unsigned int)dwReserved
, pSort
, pDisplay
);
695 HRESULT WINAPI
CRecycleBin::GetDefaultColumnState(UINT iColumn
, SHCOLSTATEF
*pcsFlags
)
697 TRACE("(%p, %d, %p)\n", this, iColumn
, pcsFlags
);
698 if (iColumn
>= COLUMNS_COUNT
)
700 *pcsFlags
= RecycleBinColumns
[iColumn
].pcsFlags
;
704 HRESULT WINAPI
CRecycleBin::GetDetailsEx(LPCITEMIDLIST pidl
, const SHCOLUMNID
*pscid
, VARIANT
*pv
)
710 static HRESULT
FormatDateTime(LPWSTR buffer
, int size
, FILETIME
* ft
)
716 FileTimeToLocalFileTime(ft
, &lft
);
717 FileTimeToSystemTime(&lft
, &time
);
719 ret
= GetDateFormatW(LOCALE_USER_DEFAULT
, DATE_SHORTDATE
, &time
, NULL
, buffer
, size
);
720 if (ret
> 0 && ret
< size
)
722 /* Append space + time without seconds */
724 GetTimeFormatW(LOCALE_USER_DEFAULT
, TIME_NOSECONDS
, &time
, NULL
, &buffer
[ret
], size
- ret
);
727 return (ret
!= 0 ? E_FAIL
: S_OK
);
730 HRESULT WINAPI
CRecycleBin::GetDetailsOf(LPCITEMIDLIST pidl
, UINT iColumn
, LPSHELLDETAILS pDetails
)
732 PIDLRecycleStruct
* pFileDetails
;
733 WCHAR buffer
[MAX_PATH
];
734 WCHAR szTypeName
[100];
738 TRACE("(%p, %p, %d, %p)\n", this, pidl
, iColumn
, pDetails
);
739 if (iColumn
>= COLUMNS_COUNT
)
741 pDetails
->fmt
= RecycleBinColumns
[iColumn
].fmt
;
742 pDetails
->cxChar
= RecycleBinColumns
[iColumn
].cxChars
;
745 pDetails
->str
.uType
= STRRET_WSTR
;
746 LoadStringW(shell32_hInstance
, RecycleBinColumns
[iColumn
].column_name_id
, buffer
, MAX_PATH
);
747 return SHStrDupW(buffer
, &pDetails
->str
.pOleStr
);
750 if (iColumn
== COLUMN_NAME
)
751 return GetDisplayNameOf(pidl
, SHGDN_NORMAL
, &pDetails
->str
);
753 pFileDetails
= _ILGetRecycleStruct(pidl
);
757 FormatDateTime(buffer
, MAX_PATH
, &pFileDetails
->DeletionTime
);
760 pszBackslash
= wcsrchr(pFileDetails
->szName
, L
'\\');
761 Length
= (pszBackslash
- pFileDetails
->szName
);
762 memcpy((LPVOID
)buffer
, pFileDetails
->szName
, Length
* sizeof(WCHAR
));
763 buffer
[Length
] = L
'\0';
766 StrFormatKBSizeW(pFileDetails
->FileSize
.QuadPart
, buffer
, MAX_PATH
);
769 FormatDateTime(buffer
, MAX_PATH
, &pFileDetails
->LastModification
);
772 szTypeName
[0] = L
'\0';
773 wcscpy(buffer
, PathFindExtensionW(pFileDetails
->szName
));
774 if (!( HCR_MapTypeToValueW(buffer
, buffer
, sizeof(buffer
) / sizeof(WCHAR
), TRUE
) &&
775 HCR_MapTypeToValueW(buffer
, szTypeName
, sizeof(szTypeName
) / sizeof(WCHAR
), FALSE
)))
777 wcscpy (szTypeName
, PathFindExtensionW(pFileDetails
->szName
));
778 wcscat(szTypeName
, L
"-");
779 Length
= wcslen(szTypeName
);
780 if (LoadStringW(shell32_hInstance
, IDS_SHV_COLUMN1
, &szTypeName
[Length
], (sizeof(szTypeName
) / sizeof(WCHAR
)) - Length
))
781 szTypeName
[(sizeof(szTypeName
)/sizeof(WCHAR
))-1] = L
'\0';
783 pDetails
->str
.uType
= STRRET_WSTR
;
784 return SHStrDupW(szTypeName
, &pDetails
->str
.pOleStr
);
790 pDetails
->str
.uType
= STRRET_WSTR
;
791 return SHStrDupW(buffer
, &pDetails
->str
.pOleStr
);
794 HRESULT WINAPI
CRecycleBin::MapColumnToSCID(UINT iColumn
, SHCOLUMNID
*pscid
)
796 TRACE("(%p, %d, %p)\n", this, iColumn
, pscid
);
797 if (iColumn
>= COLUMNS_COUNT
)
799 pscid
->fmtid
= *RecycleBinColumns
[iColumn
].fmtId
;
800 pscid
->pid
= RecycleBinColumns
[iColumn
].pid
;
804 /*************************************************************************
805 * RecycleBin IContextMenu interface
808 HRESULT WINAPI
CRecycleBin::QueryContextMenu(HMENU hMenu
, UINT indexMenu
, UINT idCmdFirst
, UINT idCmdLast
, UINT uFlags
)
814 TRACE("QueryContextMenu %p %p %u %u %u %u\n", this, hMenu
, indexMenu
, idCmdFirst
, idCmdLast
, uFlags
);
819 memset(&mii
, 0, sizeof(mii
));
820 mii
.cbSize
= sizeof(mii
);
821 mii
.fMask
= MIIM_TYPE
| MIIM_ID
| MIIM_STATE
;
822 mii
.fState
= MFS_ENABLED
;
824 LoadStringW(shell32_hInstance
, IDS_EMPTY_BITBUCKET
, szBuffer
, sizeof(szBuffer
) / sizeof(WCHAR
));
825 mii
.dwTypeData
= szBuffer
;
826 mii
.cch
= wcslen(mii
.dwTypeData
);
827 mii
.wID
= idCmdFirst
+ id
++;
828 mii
.fType
= MFT_STRING
;
831 if (!InsertMenuItemW(hMenu
, indexMenu
, TRUE
, &mii
))
834 return MAKE_HRESULT(SEVERITY_SUCCESS
, 0, id
);
837 HRESULT WINAPI
CRecycleBin::InvokeCommand(LPCMINVOKECOMMANDINFO lpcmi
)
841 LPSHELLVIEW lpSV
= NULL
;
843 TRACE("%p %p verb %p\n", this, lpcmi
, lpcmi
->lpVerb
);
845 if (LOWORD(lpcmi
->lpVerb
) == iIdEmpty
)
849 hr
= SHEmptyRecycleBinW(lpcmi
->hwnd
, L
"C:\\", 0);
850 TRACE("result %x\n", hr
);
854 lpSB
= (LPSHELLBROWSER
)SendMessageA(lpcmi
->hwnd
, CWM_GETISHELLBROWSER
, 0, 0);
855 if (lpSB
&& SUCCEEDED(lpSB
->QueryActiveShellView(&lpSV
)))
861 HRESULT WINAPI
CRecycleBin::GetCommandString(UINT_PTR idCommand
, UINT uFlags
, UINT
*lpReserved
, LPSTR lpszName
, UINT uMaxNameLen
)
863 FIXME("%p %lu %u %p %p %u\n", this, idCommand
, uFlags
, lpReserved
, lpszName
, uMaxNameLen
);
868 /*************************************************************************
869 * RecycleBin IShellPropSheetExt interface
872 HRESULT WINAPI
CRecycleBin::AddPages(LPFNSVADDPROPSHEETPAGE pfnAddPage
, LPARAM lParam
)
874 FIXME("%p %p %lu\n", this, pfnAddPage
, lParam
);
879 HRESULT WINAPI
CRecycleBin::ReplacePage(EXPPS uPageID
, LPFNSVADDPROPSHEETPAGE pfnReplaceWith
, LPARAM lParam
)
881 FIXME("%p %lu %p %lu\n", this, uPageID
, pfnReplaceWith
, lParam
);
886 /*************************************************************************
887 * RecycleBin IShellExtInit interface
890 HRESULT WINAPI
CRecycleBin::Initialize(LPCITEMIDLIST pidlFolder
, IDataObject
*pdtobj
, HKEY hkeyProgID
)
892 TRACE("%p %p %p %p\n", this, pidlFolder
, pdtobj
, hkeyProgID
);
896 void toggleNukeOnDeleteOption(HWND hwndDlg
, BOOL bEnable
)
900 SendDlgItemMessage(hwndDlg
, 14001, BM_SETCHECK
, BST_UNCHECKED
, 0);
901 EnableWindow(GetDlgItem(hwndDlg
, 14002), FALSE
);
902 SendDlgItemMessage(hwndDlg
, 14003, BM_SETCHECK
, BST_CHECKED
, 0);
906 SendDlgItemMessage(hwndDlg
, 14001, BM_SETCHECK
, BST_CHECKED
, 0);
907 EnableWindow(GetDlgItem(hwndDlg
, 14002), TRUE
);
908 SendDlgItemMessage(hwndDlg
, 14003, BM_SETCHECK
, BST_UNCHECKED
, 0);
914 InitializeRecycleBinDlg(HWND hwndDlg
, WCHAR DefaultDrive
)
916 WCHAR CurDrive
= L
'A';
917 WCHAR szDrive
[] = L
"A:\\";
921 DWORD MaxComponent
, Flags
;
927 ULARGE_INTEGER TotalNumberOfFreeBytes
, TotalNumberOfBytes
, FreeBytesAvailable
;
932 PDRIVE_ITEM_CONTEXT pItem
= NULL
, pDefault
= NULL
, pFirst
= NULL
;
934 hDlgCtrl
= GetDlgItem(hwndDlg
, 14000);
936 if (!LoadStringW(shell32_hInstance
, IDS_RECYCLEBIN_LOCATION
, szVolume
, sizeof(szVolume
) / sizeof(WCHAR
)))
939 GetClientRect(hDlgCtrl
, &rect
);
941 memset(&lc
, 0, sizeof(LV_COLUMN
) );
942 lc
.mask
= LVCF_WIDTH
| LVCF_TEXT
| LVCF_SUBITEM
| LVCF_FMT
;
944 columnSize
= 140; //FIXME
946 lc
.fmt
= LVCFMT_FIXED_WIDTH
;
948 lc
.cchTextMax
= wcslen(szVolume
);
949 lc
.pszText
= szVolume
;
950 (void)SendMessageW(hDlgCtrl
, LVM_INSERTCOLUMNW
, 0, (LPARAM
)&lc
);
952 if (!LoadStringW(shell32_hInstance
, IDS_RECYCLEBIN_DISKSPACE
, szVolume
, sizeof(szVolume
) / sizeof(WCHAR
)))
956 lc
.cx
= rect
.right
- rect
.left
- columnSize
;
957 lc
.cchTextMax
= wcslen(szVolume
);
958 lc
.pszText
= szVolume
;
959 (void)SendMessageW(hDlgCtrl
, LVM_INSERTCOLUMNW
, 1, (LPARAM
)&lc
);
961 dwDrives
= GetLogicalDrives();
965 if ((dwDrives
& 0x1))
967 UINT Type
= GetDriveTypeW(szDrive
);
968 if (Type
== DRIVE_FIXED
) //FIXME
970 if (!GetVolumeInformationW(szDrive
, szName
, sizeof(szName
) / sizeof(WCHAR
), &dwSerial
, &MaxComponent
, &Flags
, NULL
, 0))
976 swprintf(szVolume
, L
"%s (%c)", szName
, szDrive
[0]);
977 memset(&li
, 0x0, sizeof(LVITEMW
));
978 li
.mask
= LVIF_TEXT
| LVIF_PARAM
;
980 li
.pszText
= szVolume
;
981 li
.iItem
= itemCount
;
982 SendMessageW(hDlgCtrl
, LVM_INSERTITEMW
, 0, (LPARAM
)&li
);
983 if (GetDiskFreeSpaceExW(szDrive
, &FreeBytesAvailable
, &TotalNumberOfBytes
, &TotalNumberOfFreeBytes
))
985 if (StrFormatByteSizeW(TotalNumberOfFreeBytes
.QuadPart
, szVolume
, sizeof(szVolume
) / sizeof(WCHAR
)))
988 pItem
= (DRIVE_ITEM_CONTEXT
*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(DRIVE_ITEM_CONTEXT
));
991 swprintf(szName
, L
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Bitbucket\\Volume\\%04X-%04X", LOWORD(dwSerial
), HIWORD(dwSerial
));
992 dwSize
= sizeof(DWORD
);
993 RegGetValueW(HKEY_CURRENT_USER
, szName
, L
"MaxCapacity", RRF_RT_DWORD
, NULL
, &pItem
->dwMaxCapacity
, &dwSize
);
994 dwSize
= sizeof(DWORD
);
995 RegGetValueW(HKEY_CURRENT_USER
, szName
, L
"NukeOnDelete", RRF_RT_DWORD
, NULL
, &pItem
->dwNukeOnDelete
, &dwSize
);
996 pItem
->dwSerial
= dwSerial
;
997 li
.mask
= LVIF_PARAM
;
998 li
.lParam
= (LPARAM
)pItem
;
999 (void)SendMessageW(hDlgCtrl
, LVM_SETITEMW
, 0, (LPARAM
)&li
);
1000 if (CurDrive
== DefaultDrive
)
1002 defIndex
= itemCount
;
1009 li
.mask
= LVIF_TEXT
;
1011 li
.pszText
= szVolume
;
1012 li
.iItem
= itemCount
;
1013 (void)SendMessageW(hDlgCtrl
, LVM_SETITEMW
, 0, (LPARAM
)&li
);
1020 szDrive
[0] = CurDrive
;
1021 dwDrives
= (dwDrives
>> 1);
1028 toggleNukeOnDeleteOption(hwndDlg
, pDefault
->dwNukeOnDelete
);
1029 SetDlgItemInt(hwndDlg
, 14002, pDefault
->dwMaxCapacity
, FALSE
);
1031 ZeroMemory(&li
, sizeof(li
));
1032 li
.mask
= LVIF_STATE
;
1033 li
.stateMask
= (UINT
) - 1;
1034 li
.state
= LVIS_FOCUSED
| LVIS_SELECTED
;
1035 li
.iItem
= defIndex
;
1036 (void)SendMessageW(hDlgCtrl
, LVM_SETITEMW
, 0, (LPARAM
)&li
);
1040 static BOOL
StoreDriveSettings(HWND hwndDlg
)
1043 HWND hDlgCtrl
= GetDlgItem(hwndDlg
, 14000);
1045 PDRIVE_ITEM_CONTEXT pItem
;
1051 if (RegCreateKeyExW(HKEY_CURRENT_USER
, L
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Bitbucket\\Volume", 0, NULL
, 0, KEY_WRITE
, NULL
, &hKey
, NULL
) != ERROR_SUCCESS
)
1054 iCount
= ListView_GetItemCount(hDlgCtrl
);
1056 ZeroMemory(&li
, sizeof(li
));
1057 li
.mask
= LVIF_PARAM
;
1059 for(iIndex
= 0; iIndex
< iCount
; iIndex
++)
1062 if (SendMessageW(hDlgCtrl
, LVM_GETITEMW
, 0, (LPARAM
)&li
))
1064 pItem
= (PDRIVE_ITEM_CONTEXT
)li
.lParam
;
1065 swprintf(szSerial
, L
"%04X-%04X", LOWORD(pItem
->dwSerial
), HIWORD(pItem
->dwSerial
));
1066 if (RegCreateKeyExW(hKey
, szSerial
, 0, NULL
, 0, KEY_WRITE
, NULL
, &hSubKey
, NULL
) == ERROR_SUCCESS
)
1068 dwSize
= sizeof(DWORD
);
1069 RegSetValueExW(hSubKey
, L
"NukeOnDelete", 0, REG_DWORD
, (LPBYTE
)&pItem
->dwNukeOnDelete
, dwSize
);
1070 dwSize
= sizeof(DWORD
);
1071 RegSetValueExW(hSubKey
, L
"MaxCapacity", 0, REG_DWORD
, (LPBYTE
)&pItem
->dwMaxCapacity
, dwSize
);
1072 RegCloseKey(hSubKey
);
1081 static VOID
FreeDriveItemContext(HWND hwndDlg
)
1084 HWND hDlgCtrl
= GetDlgItem(hwndDlg
, 14000);
1087 iCount
= ListView_GetItemCount(hDlgCtrl
);
1089 ZeroMemory(&li
, sizeof(li
));
1090 li
.mask
= LVIF_PARAM
;
1092 for(iIndex
= 0; iIndex
< iCount
; iIndex
++)
1095 if (SendMessageW(hDlgCtrl
, LVM_GETITEMW
, 0, (LPARAM
)&li
))
1097 HeapFree(GetProcessHeap(), 0, (LPVOID
)li
.lParam
);
1103 GetDefaultItem(HWND hwndDlg
, LVITEMW
* li
)
1106 UINT iItemCount
, iIndex
;
1108 hDlgCtrl
= GetDlgItem(hwndDlg
, 14000);
1112 iItemCount
= ListView_GetItemCount(hDlgCtrl
);
1116 ZeroMemory(li
, sizeof(LVITEMW
));
1117 li
->mask
= LVIF_PARAM
| LVIF_STATE
;
1118 li
->stateMask
= (UINT
) - 1;
1119 for (iIndex
= 0; iIndex
< iItemCount
; iIndex
++)
1122 if (SendMessageW(hDlgCtrl
, LVM_GETITEMW
, 0, (LPARAM
)li
))
1124 if (li
->state
& LVIS_SELECTED
)
1132 static INT_PTR CALLBACK
1143 PDRIVE_ITEM_CONTEXT pItem
;
1146 PROPSHEETPAGE
* page
;
1152 page
= (PROPSHEETPAGE
*)lParam
;
1153 InitializeRecycleBinDlg(hwndDlg
, (WCHAR
)page
->lParam
);
1154 dwStyle
= (DWORD
) SendDlgItemMessage(hwndDlg
, 14000, LVM_GETEXTENDEDLISTVIEWSTYLE
, 0, 0);
1155 dwStyle
= dwStyle
| LVS_EX_FULLROWSELECT
;
1156 SendDlgItemMessage(hwndDlg
, 14000, LVM_SETEXTENDEDLISTVIEWSTYLE
, 0, dwStyle
);
1157 if (GetDlgCtrlID((HWND
)wParam
) != 14000)
1159 SetFocus(GetDlgItem(hwndDlg
, 14000));
1164 switch(LOWORD(wParam
))
1167 toggleNukeOnDeleteOption(hwndDlg
, FALSE
);
1168 PropSheet_Changed(GetParent(hwndDlg
), hwndDlg
);
1171 toggleNukeOnDeleteOption(hwndDlg
, TRUE
);
1172 PropSheet_Changed(GetParent(hwndDlg
), hwndDlg
);
1175 PropSheet_Changed(GetParent(hwndDlg
), hwndDlg
);
1180 lppsn
= (LPPSHNOTIFY
) lParam
;
1181 lppl
= (LPNMLISTVIEW
) lParam
;
1182 if (lppsn
->hdr
.code
== PSN_APPLY
)
1184 if (GetDefaultItem(hwndDlg
, &li
) > -1)
1186 pItem
= (PDRIVE_ITEM_CONTEXT
)li
.lParam
;
1189 uResult
= GetDlgItemInt(hwndDlg
, 14002, &bSuccess
, FALSE
);
1191 pItem
->dwMaxCapacity
= uResult
;
1192 if (SendDlgItemMessageW(hwndDlg
, 14003, BM_GETCHECK
, 0, 0) == BST_CHECKED
)
1193 pItem
->dwNukeOnDelete
= TRUE
;
1195 pItem
->dwNukeOnDelete
= FALSE
;
1198 if (StoreDriveSettings(hwndDlg
))
1200 SetWindowLongPtr( hwndDlg
, DWL_MSGRESULT
, PSNRET_NOERROR
);
1204 else if (lppl
->hdr
.code
== LVN_ITEMCHANGING
)
1206 ZeroMemory(&li
, sizeof(li
));
1207 li
.mask
= LVIF_PARAM
;
1208 li
.iItem
= lppl
->iItem
;
1209 if (!SendMessageW(lppl
->hdr
.hwndFrom
, LVM_GETITEMW
, 0, (LPARAM
)&li
))
1212 pItem
= (PDRIVE_ITEM_CONTEXT
)li
.lParam
;
1216 if (!(lppl
->uOldState
& LVIS_FOCUSED
) && (lppl
->uNewState
& LVIS_FOCUSED
))
1218 /* new focused item */
1219 toggleNukeOnDeleteOption(lppl
->hdr
.hwndFrom
, pItem
->dwNukeOnDelete
);
1220 SetDlgItemInt(hwndDlg
, 14002, pItem
->dwMaxCapacity
, FALSE
);
1222 else if ((lppl
->uOldState
& LVIS_FOCUSED
) && !(lppl
->uNewState
& LVIS_FOCUSED
))
1225 uResult
= GetDlgItemInt(hwndDlg
, 14002, &bSuccess
, FALSE
);
1227 pItem
->dwMaxCapacity
= uResult
;
1228 if (SendDlgItemMessageW(hwndDlg
, 14003, BM_GETCHECK
, 0, 0) == BST_CHECKED
)
1229 pItem
->dwNukeOnDelete
= TRUE
;
1231 pItem
->dwNukeOnDelete
= FALSE
;
1238 FreeDriveItemContext(hwndDlg
);
1244 BOOL
SH_ShowRecycleBinProperties(WCHAR sDrive
)
1246 HPROPSHEETPAGE hpsp
[1];
1247 PROPSHEETHEADERW psh
;
1248 HPROPSHEETPAGE hprop
;
1253 ZeroMemory(&psh
, sizeof(PROPSHEETHEADERW
));
1254 psh
.dwSize
= sizeof(PROPSHEETHEADERW
);
1255 psh
.dwFlags
= PSP_DEFAULT
| PSH_PROPTITLE
;
1256 psh
.pszCaption
= MAKEINTRESOURCEW(IDS_RECYCLEBIN_FOLDER_NAME
);
1257 psh
.hwndParent
= NULL
;
1259 psh
.hInstance
= shell32_hInstance
;
1261 hprop
= SH_CreatePropertySheetPage(IDD_RECYCLE_BIN_PROPERTIES
, RecycleBinDlg
, (LPARAM
)sDrive
, NULL
);
1264 ERR("Failed to create property sheet\n");
1267 hpsp
[psh
.nPages
] = hprop
;
1271 ret
= PropertySheetW(&psh
);
1279 TRASH_CanTrashFile(LPCWSTR wszPath
)
1282 DWORD dwNukeOnDelete
, dwType
, VolSerialNumber
, MaxComponentLength
;
1283 DWORD FileSystemFlags
, dwSize
, dwDisposition
;
1286 WCHAR szKey
[150] = L
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Bitbucket\\Volume\\";
1288 if (wszPath
[1] != L
':')
1294 if (GetDriveTypeW(wszPath
) != DRIVE_FIXED
)
1296 /* no bitbucket on removable media */
1300 if (!GetVolumeInformationW(wszPath
, NULL
, 0, &VolSerialNumber
, &MaxComponentLength
, &FileSystemFlags
, NULL
, 0))
1302 ERR("GetVolumeInformationW failed with %u\n", GetLastError());
1306 swprintf(szBuffer
, L
"%04X-%04X", LOWORD(VolSerialNumber
), HIWORD(VolSerialNumber
));
1307 wcscat(szKey
, szBuffer
);
1309 if (RegCreateKeyExW(HKEY_CURRENT_USER
, szKey
, 0, NULL
, 0, KEY_WRITE
, NULL
, &hKey
, &dwDisposition
) != ERROR_SUCCESS
)
1311 ERR("RegCreateKeyExW failed\n");
1315 if (dwDisposition
& REG_CREATED_NEW_KEY
)
1317 /* per default move to bitbucket */
1319 RegSetValueExW(hKey
, L
"NukeOnDelete", 0, REG_DWORD
, (LPBYTE
)&dwNukeOnDelete
, sizeof(DWORD
));
1320 /* per default unlimited size */
1322 RegSetValueExW(hKey
, L
"MaxCapacity", 0, REG_DWORD
, (LPBYTE
)&dwSize
, sizeof(DWORD
));
1328 dwSize
= sizeof(dwNukeOnDelete
);
1329 ret
= RegQueryValueExW(hKey
, L
"NukeOnDelete", NULL
, &dwType
, (LPBYTE
)&dwNukeOnDelete
, &dwSize
);
1330 if (ret
!= ERROR_SUCCESS
)
1332 if (ret
== ERROR_FILE_NOT_FOUND
)
1334 /* restore key and enable bitbucket */
1336 RegSetValueExW(hKey
, L
"NukeOnDelete", 0, REG_DWORD
, (LPBYTE
)&dwNukeOnDelete
, sizeof(DWORD
));
1341 else if (dwNukeOnDelete
)
1343 /* do not delete to bitbucket */
1348 * check if bitbucket is full
1356 TRASH_TrashFile(LPCWSTR wszPath
)
1358 TRACE("(%s)\n", debugstr_w(wszPath
));
1359 return DeleteFileToRecycleBin(wszPath
);
1362 /*************************************************************************
1363 * SHUpdateCRecycleBinIcon [SHELL32.@]
1367 EXTERN_C HRESULT WINAPI
SHUpdateRecycleBinIcon(void)