Reactos
at master 149 lines 4.1 kB view raw
1/* 2 * PROJECT: shell32 3 * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later) 4 * PURPOSE: CRecycleBinCleaner implementation 5 * COPYRIGHT: Copyright 2023-2025 Mark Jansen <mark.jansen@reactos.org> 6 */ 7 8#include "precomp.h" 9 10WINE_DEFAULT_DEBUG_CHANNEL(shell); 11 12 13CLSID CLSID_RecycleBinCleaner = { 0x5ef4af3a, 0xf726, 0x11d0, { 0xb8, 0xa2, 0x00, 0xc0, 0x4f, 0xc3, 0x09, 0xa4 } }; 14 15struct CRecycleBinCleaner : 16 public CComObjectRootEx<CComSingleThreadModel>, 17 public CComCoClass<CRecycleBinCleaner, &CLSID_RecycleBinCleaner>, 18 public IEmptyVolumeCache2 19{ 20 WCHAR m_wszVolume[4]; 21 22 void 23 OutputResourceString(DWORD dwResId, _Out_ LPWSTR *ppwszOutput) 24 { 25 CStringW Tmp(MAKEINTRESOURCEW(dwResId)); 26 SHStrDupW(Tmp, ppwszOutput); 27 } 28 29public: 30 31 // +IEmptyVolumeCache 32 STDMETHODIMP Initialize( 33 _In_ HKEY hkRegKey, 34 _In_ LPCWSTR pcwszVolume, 35 _Out_ LPWSTR* ppwszDisplayName, 36 _Out_ LPWSTR* ppwszDescription, 37 _Out_ DWORD* pdwFlags) 38 { 39 if (!pdwFlags) 40 return E_POINTER; 41 42 *pdwFlags = EVCF_HASSETTINGS; 43 44 OutputResourceString(IDS_RECYCLE_CLEANER_DISPLAYNAME, ppwszDisplayName); 45 OutputResourceString(IDS_RECYCLE_CLEANER_DESCRIPTION, ppwszDescription); 46 47 return StringCchCopyW(m_wszVolume, _countof(m_wszVolume), pcwszVolume); 48 } 49 50 STDMETHODIMP GetSpaceUsed( 51 _Out_ DWORDLONG* pdwlSpaceUsed, 52 _In_opt_ IEmptyVolumeCacheCallBack* picb) 53 { 54 if (!pdwlSpaceUsed) 55 return E_POINTER; 56 57 SHQUERYRBINFO bin = { sizeof(bin) }; 58 HRESULT hr = SHQueryRecycleBinW(m_wszVolume, &bin); 59 if (FAILED_UNEXPECTEDLY(hr)) 60 { 61 bin.i64Size = 0; 62 } 63 *pdwlSpaceUsed = bin.i64Size; 64 if (picb) 65 { 66 picb->ScanProgress(bin.i64Size, EVCCBF_LASTNOTIFICATION, NULL); 67 } 68 69 return S_OK; 70 } 71 72 STDMETHODIMP Purge( 73 _In_ DWORDLONG dwlSpaceToFree, 74 _In_opt_ IEmptyVolumeCacheCallBack *picb) 75 { 76 DWORDLONG dwlPrevious = 0; 77 GetSpaceUsed(&dwlPrevious, NULL); 78 79 SHEmptyRecycleBinW(NULL, m_wszVolume, SHERB_NOCONFIRMATION | SHERB_NOPROGRESSUI | SHERB_NOSOUND); 80 if (picb) 81 { 82 picb->PurgeProgress(dwlPrevious, 0, EVCCBF_LASTNOTIFICATION, NULL); 83 } 84 85 return S_OK; 86 } 87 88 STDMETHODIMP ShowProperties( 89 _In_ HWND hwnd) 90 { 91 CComHeapPtr<ITEMIDLIST> pidl; 92 HRESULT hr; 93 if (FAILED_UNEXPECTEDLY(hr = SHGetSpecialFolderLocation(hwnd, CSIDL_BITBUCKET, &pidl))) 94 return hr; 95 96 SHELLEXECUTEINFOW seei = {sizeof(seei)}; 97 seei.hwnd = hwnd; 98 seei.lpVerb = L"open"; 99 seei.nShow = SW_SHOWNORMAL; 100 seei.fMask = SEE_MASK_IDLIST; 101 seei.lpIDList = pidl; 102 ShellExecuteExW(&seei); 103 104 return S_OK; 105 } 106 107 STDMETHODIMP Deactivate( 108 _Out_ DWORD* pdwFlags) 109 { 110 if (!pdwFlags) 111 return E_POINTER; 112 113 *pdwFlags = 0; 114 115 return S_OK; 116 } 117 // -IEmptyVolumeCache 118 119 120 // +IEmptyVolumeCache2 121 STDMETHODIMP InitializeEx( 122 _In_ HKEY hkRegKey, 123 _In_ LPCWSTR pcwszVolume, 124 _In_ LPCWSTR pcwszKeyName, 125 _Out_ LPWSTR* ppwszDisplayName, 126 _Out_ LPWSTR* ppwszDescription, 127 _Out_ LPWSTR* ppwszBtnText, 128 _Out_ DWORD* pdwFlags) 129 { 130 OutputResourceString(IDS_RECYCLE_CLEANER_BUTTON_TEXT, ppwszBtnText); 131 132 return Initialize(hkRegKey, pcwszVolume, ppwszDisplayName, ppwszDescription, pdwFlags); 133 } 134 // -IEmptyVolumeCache2 135 136 137 DECLARE_PROTECT_FINAL_CONSTRUCT(); 138 DECLARE_REGISTRY_RESOURCEID(IDR_RECYCLEBINCLEANER) 139 DECLARE_NOT_AGGREGATABLE(CRecycleBinCleaner) 140 141 BEGIN_COM_MAP(CRecycleBinCleaner) 142 COM_INTERFACE_ENTRY_IID(IID_IEmptyVolumeCache2, IEmptyVolumeCache2) 143 COM_INTERFACE_ENTRY_IID(IID_IEmptyVolumeCache, IEmptyVolumeCache) 144 COM_INTERFACE_ENTRY_IID(IID_IUnknown, IUnknown) 145 END_COM_MAP() 146}; 147 148 149OBJECT_ENTRY_AUTO(CLSID_RecycleBinCleaner, CRecycleBinCleaner)