|
| 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 <[email protected]> |
| 6 | + */ |
| 7 | + |
| 8 | +#include "precomp.h" |
| 9 | + |
| 10 | +WINE_DEFAULT_DEBUG_CHANNEL(shell); |
| 11 | + |
| 12 | + |
| 13 | +CLSID CLSID_RecycleBinCleaner = { 0x5ef4af3a, 0xf726, 0x11d0, 0xb8, 0xa2, 0x00, 0xc0, 0x4f, 0xc3, 0x09, 0xa4 }; |
| 14 | + |
| 15 | +struct 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 | + |
| 29 | +public: |
| 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 | + |
| 149 | +OBJECT_ENTRY_AUTO(CLSID_RecycleBinCleaner, CRecycleBinCleaner) |
0 commit comments