ReactOS 0.4.16-dev-963-g182f353
CCleanupHandler.cpp
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS Disk Cleanup
3 * LICENSE: MIT (https://spdx.org/licenses/MIT)
4 * PURPOSE: CCleanupHandler implementation
5 * COPYRIGHT: Copyright 2023-2025 Mark Jansen <mark.jansen@reactos.org>
6 */
7
8#include "cleanmgr.h"
9
10
12 : hSubKey(subKey)
13 , KeyName(keyName)
14 , Guid(guid)
15 , dwFlags(0)
16 , Priority(0)
17 , StateFlags(0)
18 , SpaceUsed(0)
19 , ShowHandler(true)
20 , hIcon(NULL)
21{
22}
23
25{
26 Deactivate();
28}
29
30void
32{
33 if (Handler)
34 {
35 DWORD dwFlags = 0;
36 Handler->Deactivate(&dwFlags);
37 if (dwFlags & EVCF_REMOVEFROMLIST)
39 }
40}
41
42bool
44{
47 {
48 return false;
49 }
50
51 DWORD dwSize = sizeof(Priority);
53 {
55 Priority = 200;
56 }
57
58 dwSize = sizeof(StateFlags);
60 StateFlags = 0;
61
62 WCHAR PathBuffer[MAX_PATH] = {};
63 ULONG nChars = _countof(PathBuffer);
64 if (hSubKey.QueryStringValue(L"IconPath", PathBuffer, &nChars) != ERROR_SUCCESS)
65 {
66 CStringW Tmp;
67 WCHAR GuidStr[50] = {};
68 if (StringFromGUID2(Guid, GuidStr, _countof(GuidStr)))
69 {
70 Tmp.Format(L"CLSID\\%s\\DefaultIcon", GuidStr);
72 nChars = _countof(PathBuffer);
73 if (clsid.Open(HKEY_CLASSES_ROOT, Tmp, KEY_READ) != ERROR_SUCCESS ||
74 clsid.QueryStringValue(NULL, PathBuffer, &nChars) != ERROR_SUCCESS)
75 {
76 PathBuffer[0] = UNICODE_NULL;
77 }
78 }
79 }
80 if (!PathBuffer[0])
81 StringCchCopyW(PathBuffer, _countof(PathBuffer), L"%systemroot%\\system32\\shell32.dll");
82
83 int Index = 0;
84 WCHAR *ptr = wcschr(PathBuffer, L',');
85 if (ptr)
86 {
87 *ptr++ = UNICODE_NULL;
88 Index = wcstol(ptr, NULL, 10);
89 }
90 HICON Large, Small;
91 UINT Result = ExtractIconExW(PathBuffer, Index, &Large, &Small, 1);
92 if (Result < 1)
93 Result = ExtractIconExW(L"%systemroot%\\system32\\shell32.dll", 0, &Large, &Small, 1);
94 if (Result >= 1)
95 {
96 hIcon = Small;
97 if (!hIcon)
98 {
99 hIcon = Large;
100 }
101 else
102 {
103 ::DestroyIcon(Large);
104 }
105 }
106
107 // These options should come from the command line
108 // dwFlags |= EVCF_SETTINGSMODE;
109 // dwFlags |= EVCF_OUTOFDISKSPACE;
110
112 HRESULT hr = Handler->QueryInterface(IID_PPV_ARG(IEmptyVolumeCache2, &spHandler2));
113 if (SUCCEEDED(hr))
114 {
115 hr = spHandler2->InitializeEx(
118 return false;
119
120 // No files to clean will return S_FALSE;
121 if (hr != S_OK)
122 return false;
123 }
124 else
125 {
126 // Observed behavior:
127 // When Initialize is called, wszDescription is actually pointing to data
128 // wszDescription.AllocateBytes(0x400u);
129 hr = Handler->Initialize(hSubKey, pcwszVolume, &wszDisplayName, &wszDescription, &dwFlags);
131 return false;
132
133 // No files to clean will return S_FALSE;
134 if (hr != S_OK)
135 return false;
136
138 WCHAR GuidStr[50] = {};
139 nChars = _countof(GuidStr);
140 if (hSubKey.QueryStringValue(L"PropertyBag", GuidStr, &nChars) == ERROR_SUCCESS)
141 {
142 GUID guid = {};
144 {
146 CoCreateInstance(guid, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARG(IPropertyBag, &spBag)));
147 }
148 }
149 ReadProperty(L"Display", spBag, wszDisplayName);
150 ReadProperty(L"Description", spBag, wszDescription);
151
152 if (dwFlags & EVCF_HASSETTINGS)
153 {
154 ReadProperty(L"AdvancedButtonText", spBag, wszBtnText);
155 }
156 }
157
158 if ((dwFlags & EVCF_ENABLEBYDEFAULT) && !(StateFlags & HANDLER_STATE_SELECTED))
159 {
161 }
162
163 // For convenience
164 if (!wszDisplayName)
166
167 return true;
168}
169
170void
172{
173 if (storage)
174 return;
175
176 if (pBag)
177 {
178 CComVariant tmp;
179 tmp.vt = VT_BSTR;
180 HRESULT hr = pBag->Read(Name, &tmp, NULL);
181 if (!FAILED_UNEXPECTEDLY(hr) && tmp.vt == VT_BSTR)
182 {
184 }
185 }
186
187 if (!storage)
188 {
189 WCHAR TmpStr[0x200] = {};
190 DWORD dwSize = _countof(TmpStr);
191
193 {
194 WCHAR ResolvedStr[0x200] = {};
195 SHLoadIndirectString(TmpStr, ResolvedStr, _countof(ResolvedStr), NULL);
196 SHStrDupW(ResolvedStr, &storage);
197 }
198 }
199}
200
201BOOL
203{
204 return !!(dwFlags & EVCF_HASSETTINGS);
205}
206
207BOOL
209{
210 return !!(dwFlags & EVCF_DONTSHOWIFZERO);
211}
212
#define HANDLER_STATE_SELECTED
LONG QueryStringValue(LPCTSTR pszValueName, LPTSTR pszValue, ULONG *pnChars) noexcept
Definition: atlbase.h:1240
LONG QueryDWORDValue(LPCTSTR pszValueName, DWORD &dwValue) noexcept
Definition: atlbase.h:1217
LONG QueryBinaryValue(LPCTSTR pszValueName, void *pValue, ULONG *pnBytes) noexcept
Definition: atlbase.h:1229
void __cdecl Format(UINT nFormatID,...)
Definition: cstringt.h:818
#define ERROR_SUCCESS
Definition: deptool.c:10
LPWSTR Name
Definition: desk.c:124
#define NULL
Definition: types.h:112
#define wcschr
Definition: compat.h:17
#define MAX_PATH
Definition: compat.h:34
@ VT_BSTR
Definition: compat.h:2303
#define FAILED_UNEXPECTEDLY(hr)
Definition: precomp.h:121
HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID iid, LPVOID *ppv)
Definition: compobj.c:3325
HRESULT WINAPI CLSIDFromString(LPCOLESTR idstr, LPCLSID id)
Definition: compobj.c:2338
INT WINAPI StringFromGUID2(REFGUID id, LPOLESTR str, INT cmax)
Definition: compobj.c:2434
HRESULT WINAPI SHStrDupW(LPCWSTR src, LPWSTR *dest)
Definition: string.c:2018
HRESULT WINAPI SHLoadIndirectString(LPCWSTR src, LPWSTR dst, UINT dst_len, void **reserved)
Definition: string.c:2890
#define UNIMPLEMENTED_DBGBREAK(...)
Definition: debug.h:57
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
UINT WINAPI ExtractIconExW(LPCWSTR lpszFile, INT nIconIndex, HICON *phiconLarge, HICON *phiconSmall, UINT nIcons)
Definition: iconcache.cpp:855
_Check_return_ long __cdecl wcstol(_In_z_ const wchar_t *_Str, _Out_opt_ _Deref_post_z_ wchar_t **_EndPtr, _In_ int _Radix)
HRESULT Read([in] LPCOLESTR pszPropName, [in, out] VARIANT *pVar, [in] IErrorLog *pErrorLog)
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
const GUID * guid
PSDBQUERYRESULT_VISTA PVOID DWORD * dwSize
Definition: env.c:56
static PVOID ptr
Definition: dispmode.c:27
static HICON
Definition: imagelist.c:80
HICON hIcon
Definition: msconfig.c:44
REFCLSID clsid
Definition: msctf.c:82
unsigned int UINT
Definition: ndis.h:50
#define KEY_READ
Definition: nt_native.h:1023
#define UNICODE_NULL
#define L(x)
Definition: ntvdm.h:50
HRESULT hr
Definition: shlfolder.c:183
#define _countof(array)
Definition: sndvol32.h:70
#define true
Definition: stdbool.h:36
STRSAFEAPI StringCchCopyW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszSrc)
Definition: strsafe.h:149
void ReadProperty(LPCWSTR Name, IPropertyBag *pBag, CComHeapPtr< WCHAR > &storage)
BOOL DontShowIfZero() const
CComHeapPtr< WCHAR > wszBtnText
CCleanupHandler(CRegKey &subKey, const CStringW &keyName, const GUID &guid)
CComPtr< IEmptyVolumeCache > Handler
bool Initialize(LPCWSTR pcwszVolume)
BOOL HasSettings() const
CComHeapPtr< WCHAR > wszDescription
CComHeapPtr< WCHAR > wszDisplayName
BSTR bstrVal
Definition: compat.h:2399
VARTYPE vt
Definition: compat.h:2381
uint32_t ULONG
Definition: typedefs.h:59
_In_ WDFCOLLECTION _In_ ULONG Index
_Must_inspect_result_ _In_ WDFDEVICE _In_ PCUNICODE_STRING KeyName
Definition: wdfdevice.h:2699
_In_ WDFINTERRUPT _In_ WDF_INTERRUPT_POLICY _In_ WDF_INTERRUPT_PRIORITY Priority
Definition: wdfinterrupt.h:655
_Must_inspect_result_ _In_ WDFOBJECT _In_ CONST GUID * Guid
Definition: wdfobject.h:762
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1176
#define HKEY_CLASSES_ROOT
Definition: winreg.h:10
BOOL WINAPI DestroyIcon(_In_ HICON)
Definition: cursoricon.c:2391
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:409
#define IID_PPV_ARG(Itype, ppType)
__wchar_t WCHAR
Definition: xmlstorage.h:180
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185