ReactOS 0.4.16-dev-963-g182f353
cleanmgr.cpp
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS Disk Cleanup
3 * LICENSE: MIT (https://spdx.org/licenses/MIT)
4 * PURPOSE: Disk cleanup entrypoint
5 * COPYRIGHT: Copyright 2023-2025 Mark Jansen <mark.jansen@reactos.org>
6 */
7
8#include "cleanmgr.h"
9
10// for listview with extend style LVS_EX_CHECKBOXES, State image 1 is the unchecked box, and state image 2 is the
11// checked box. see this: https://docs.microsoft.com/en-us/windows/win32/controls/extended-list-view-styles
12#define STATEIMAGETOINDEX(x) (((x)&LVIS_STATEIMAGEMASK) >> 12)
13#define STATEIMAGE_UNCHECKED 1
14#define STATEIMAGE_CHECKED 2
15
16
18 public CPropertyPageImpl<CCleanMgrProperties>
19{
25 bool m_IgnoreChanges = true;
26
27
29 : m_Drive(Drive)
30 , m_TotalSpaceUsed(TotalSpaceUsed)
31 , m_HandlerList(handlerList)
32 {
33 }
34
35 int OnApply()
36 {
39
41 return PSNRET_INVALID;
42
43 return PSNRET_NOERROR;
44 }
45
47 {
49 _AtlBaseModule.GetResourceInstance(), MAKEINTRESOURCEW(IDI_CLEANMGR), IMAGE_ICON, 0, 0,
52
54 RECT rc;
57
58 LV_COLUMN column = {};
59 column.mask = LVCF_FMT | LVCF_WIDTH;
60 column.fmt = LVCFMT_LEFT;
61 column.cx = rc.right * 80 / 100;
63 column.fmt = LVCFMT_RIGHT;
64 column.cx = rc.right * 20 / 100;
65
67 HIMAGELIST hImagelist = ImageList_Create(16, 16, ILC_MASK | ILC_COLOR32, 1, 1);
69
71
74 {
75 if (!current->ShowHandler)
76 return;
77
78 LV_ITEM item = {};
80 item.lParam = (LPARAM)current;
81 item.pszText = (LPWSTR)current->wszDisplayName;
83 item.iImage = ImageList_AddIcon(hImagelist, current->hIcon);
87
88 item.mask = LVIF_TEXT;
89 WCHAR ByteSize[100] = {};
92 });
93
94 // Now we should start responding to changes
95 m_IgnoreChanges = false;
96
97 // Select the first item
99
101 return TRUE;
102 }
103
105 {
106 LVITEMW item = {};
107 item.iItem = Index;
108 if (item.iItem >= 0)
109 {
110 item.mask = LVIF_PARAM;
112 return (CCleanupHandler*)item.lParam;
113 }
114 return nullptr;
115 }
116
117
118 LRESULT OnDetails(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
119 {
121 if (handler)
122 {
123 handler->Handler->ShowProperties(m_hWnd);
124 }
125 return 0L;
126 }
127
128 LRESULT OnHandlerItemchanged(int idCtrl, LPNMHDR pnmh, BOOL& bHandled)
129 {
130 if (idCtrl == IDC_HANDLERLIST)
131 {
132 // We are still initializing, don't respond to changes just yet!
133 if (m_IgnoreChanges)
134 return 0L;
135
136 LPNMLISTVIEW pnic = (LPNMLISTVIEW)pnmh;
137
138 // We only care about state changes
139 if (!(pnic->uChanged & LVIF_STATE))
140 return 0L;
141
142
143 INT ItemIndex = pnic->iItem;
144 if (ItemIndex == -1 || ItemIndex >= ListView_GetItemCount(pnic->hdr.hwndFrom))
145 {
146 return 0L;
147 }
148
149 bool GotSelected = (pnic->uNewState & LVIS_SELECTED) && !(pnic->uOldState & LVIS_SELECTED);
150 if (GotSelected)
151 {
152 CWindow DetailsButton = GetDlgItem(IDC_DETAILS);
154
155 SetDlgItemText(IDC_DESCRIPTION, handler->wszDescription ? handler->wszDescription : L"");
156 if (handler->HasSettings())
157 {
158 DetailsButton.ShowWindow(SW_SHOW);
159 DetailsButton.SetWindowText(handler->wszBtnText);
160 }
161 else
162 {
163 DetailsButton.ShowWindow(SW_HIDE);
164 }
165 }
166
167 int iOldState = STATEIMAGETOINDEX(pnic->uOldState);
168 int iNewState = STATEIMAGETOINDEX(pnic->uNewState);
169
170 if ((iOldState ^ iNewState) == (STATEIMAGE_UNCHECKED ^ STATEIMAGE_CHECKED))
171 {
173 if (iNewState == STATEIMAGE_CHECKED)
174 handler->StateFlags |= HANDLER_STATE_SELECTED;
175 else
176 handler->StateFlags &= ~HANDLER_STATE_SELECTED;
178 }
179 }
180 return 0L;
181 }
182
184 {
185 CStringW tmp;
186 WCHAR ByteSize[100];
188
191
192 DWORDLONG SelectedGained = 0;
193
196 {
197 if (current->StateFlags & HANDLER_STATE_SELECTED)
198 {
199 SelectedGained += current->SpaceUsed;
200 }
201 });
202
203 StrFormatByteSizeW(SelectedGained, ByteSize, _countof(ByteSize));
205 }
206
211 CHAIN_MSG_MAP(CPropertyPageImpl<CCleanMgrProperties>) // Allow the default handler to call 'OnApply' etc
213};
214
215
216
217class CCleanMgrModule : public ATL::CAtlExeModuleT< CCleanMgrModule >
218{
219public:
221
223 _In_z_ LPCTSTR lpCmdLine,
224 _Out_ HRESULT* pnRetCode) throw()
225 {
226 int argc = 0;
228
229 for (int n = 1; n < argc; ++n)
230 {
231 if ((argv[n][0] == '/' || argv[n][0] == '-') && towlower(argv[n][1]) == 'd')
232 {
233 if (iswalpha(argv[n][2]))
234 {
235 m_Drive = towupper(argv[n][2]);
236 continue;
237 }
238 if ((n + 1) < argc)
239 {
240 m_Drive = towupper(argv[n + 1][0]);
241 ++n;
242 continue;
243 }
244 }
245 }
246 *pnRetCode = S_OK;
247 return true;
248 }
249
251 {
252 DWORD pid;
253 return GetWindowThreadProcessId(hWnd, &pid) ? pid : 0;
254 }
255
257 {
259 {
261 return FALSE;
262 }
263 return TRUE;
264 }
265
266 HRESULT Run(_In_ int nShowCmd) throw()
267 {
268 if (m_Drive == UNICODE_NULL)
269 {
271 }
272
273 if (m_Drive == UNICODE_NULL)
274 return E_FAIL;
275
278
279 HWND hWndInstance = ::CreateWindowExW(WS_EX_TOOLWINDOW, WC_STATIC, Title, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL);
280 for (HWND hNext = NULL, hFind; (hFind = ::FindWindowExW(NULL, hNext, WC_STATIC, Title)) != NULL; hNext = hFind)
281 {
282 if (hFind != hWndInstance)
283 {
285 return S_FALSE;
286 }
287 }
288
290 CEmptyVolumeCacheCallBack CacheCallBack;
291
292 Handlers.LoadHandlers(m_Drive);
293 DWORDLONG TotalSpaceUsed = Handlers.ScanDrive(&CacheCallBack);
294
295 CCleanMgrProperties cleanMgr(m_Drive, TotalSpaceUsed, &Handlers);
296 HPROPSHEETPAGE hpsp[1] = { cleanMgr.Create() };
297
298 PROPSHEETHEADERW psh = { };
299 psh.dwSize = sizeof(psh);
300 psh.dwFlags = PSH_NOAPPLYNOW | PSH_USEICONID | PSH_NOCONTEXTHELP;
301 psh.hInstance = _AtlBaseModule.GetResourceInstance();
303 psh.pszCaption = Title;
304 psh.nPages = _countof(hpsp);
305 psh.phpage = hpsp;
306
307 if (PropertySheetW(&psh) >= 1)
308 {
309 ::DestroyWindow(hWndInstance); // Allow new "cleanmgr /D" without waiting for these handlers
310 Handlers.ExecuteCleanup(&CacheCallBack);
311 }
312 else
313 {
314 ::DestroyWindow(hWndInstance);
315 }
316 return S_OK;
317 }
318};
319
321
322
323
324extern "C" int WINAPI wWinMain(HINSTANCE /*hInstance*/, HINSTANCE /*hPrevInstance*/,
325 LPWSTR /*lpCmdLine*/, int nShowCmd)
326{
327 return _AtlModule.WinMain(nShowCmd);
328}
#define HANDLER_STATE_SELECTED
static int argc
Definition: ServiceArgs.c:12
HWND hWnd
Definition: settings.c:17
#define IDC_DESCRIPTION
Definition: resource.h:17
#define IDS_CONFIRM_DELETE
Definition: resource.h:26
#define IDS_PROPERTIES_MAIN_TITLE
Definition: resource.h:23
#define IDI_CLEANMGR
Definition: resource.h:10
#define IDS_DISK_CLEANUP
Definition: resource.h:25
#define IDC_DISKICON
Definition: resource.h:13
#define IDS_TOTAL_CLEANABLE_CAPTION
Definition: resource.h:24
#define IDD_PROPERTIES_MAIN
Definition: resource.h:12
#define IDC_SELECTED_GAINED
Definition: resource.h:16
#define IDC_HANDLERLIST
Definition: resource.h:15
#define IDC_DETAILS
Definition: resource.h:18
#define IDC_TOTAL_CLEANABLE
Definition: resource.h:14
PWCHAR Drive
Definition: chkdsk.c:73
int WinMain(int nShowCmd)
Definition: atlbase.h:762
HPROPSHEETPAGE Create()
Definition: rosdlgs.h:57
void __cdecl Format(UINT nFormatID,...)
Definition: cstringt.h:818
BOOL SetWindowText(LPCTSTR lpszString)
Definition: atlwin.h:1300
BOOL GetClientRect(LPRECT lpRect) const
Definition: atlwin.h:541
HWND m_hWnd
Definition: atlwin.h:273
BOOL ShowWindow(int nCmdShow)
Definition: atlwin.h:1333
HRESULT Run(_In_ int nShowCmd)
Definition: cleanmgr.cpp:266
static BOOL CALLBACK EnumSingleInstanceCallback(_In_ HWND hWnd, _In_ LPARAM lParam)
Definition: cleanmgr.cpp:256
static UINT GetWindowProcessId(_In_ HWND hWnd)
Definition: cleanmgr.cpp:250
bool ParseCommandLine(_In_z_ LPCTSTR lpCmdLine, _Out_ HRESULT *pnRetCode)
Definition: cleanmgr.cpp:222
void ForEach(Fn callback)
#define STATEIMAGETOINDEX(x)
Definition: cleanmgr.cpp:12
#define STATEIMAGE_UNCHECKED
Definition: cleanmgr.cpp:13
int WINAPI wWinMain(HINSTANCE, HINSTANCE, LPWSTR, int nShowCmd)
Definition: cleanmgr.cpp:324
CCleanMgrModule _AtlModule
Definition: cleanmgr.cpp:320
#define STATEIMAGE_CHECKED
Definition: cleanmgr.cpp:14
void SelectDrive(WCHAR &Drive)
WPARAM wParam
Definition: combotst.c:138
char * Text
Definition: combotst.c:136
LPARAM lParam
Definition: combotst.c:139
#define E_FAIL
Definition: ddrawi.h:102
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
HIMAGELIST WINAPI ImageList_Create(INT cx, INT cy, UINT flags, INT cInitial, INT cGrow)
Definition: imagelist.c:814
INT_PTR WINAPI PropertySheetW(LPCPROPSHEETHEADERW lppsh)
Definition: propsheet.c:2916
static const WCHAR Title[]
Definition: oid.c:1259
#define CALLBACK
Definition: compat.h:35
UINT(* handler)(MSIPACKAGE *)
Definition: action.c:7512
LPWSTR WINAPI StrFormatByteSizeW(LONGLONG llBytes, LPWSTR lpszDest, UINT cchMax)
Definition: string.c:2394
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
unsigned short WORD
Definition: ntddk_ex.h:93
IShellIconOverlayIdentifier ** Handlers
Definition: folders.cpp:25
GLdouble n
Definition: glext.h:7729
#define iswalpha(_c)
Definition: ctype.h:664
#define S_OK
Definition: intsafe.h:52
unsigned long long DWORDLONG
Definition: intsafe.h:93
#define MESSAGE_HANDLER(msg, func)
Definition: atlwin.h:1926
#define CHAIN_MSG_MAP(theChainClass)
Definition: atlwin.h:1998
#define BEGIN_MSG_MAP(theClass)
Definition: atlwin.h:1898
#define COMMAND_ID_HANDLER(id, func)
Definition: atlwin.h:1953
#define END_MSG_MAP()
Definition: atlwin.h:1917
#define NOTIFY_HANDLER(id, cd, func)
Definition: atlwin.h:1989
if(dx< 0)
Definition: linetemp.h:194
struct task_struct * current
Definition: linux.c:32
static HICON
Definition: imagelist.c:80
static ATOM item
Definition: dde.c:856
#define argv
Definition: mplay32.c:18
HICON hIcon
Definition: msconfig.c:44
struct _PSP * HPROPSHEETPAGE
Definition: mstask.idl:90
unsigned int UINT
Definition: ndis.h:50
#define _In_z_
Definition: no_sal2.h:164
#define _Out_
Definition: no_sal2.h:160
#define _In_
Definition: no_sal2.h:158
#define UNICODE_NULL
#define L(x)
Definition: ntvdm.h:50
#define PSNRET_INVALID
Definition: prsht.h:130
#define PSNRET_NOERROR
Definition: prsht.h:129
#define PSH_USEICONID
Definition: prsht.h:42
#define PSH_NOAPPLYNOW
Definition: prsht.h:47
#define LVSIL_SMALL
Definition: commctrl.h:2304
#define ListView_InsertItem(hwnd, pitem)
Definition: commctrl.h:2413
#define ListView_SetItemState(hwndLV, i, data, mask)
Definition: commctrl.h:2678
#define ListView_SetExtendedListViewStyleEx(hwndLV, dwMask, dw)
Definition: commctrl.h:2731
#define ListView_InsertColumn(hwnd, iCol, pcol)
Definition: commctrl.h:2641
#define ListView_SetCheckState(hwndLV, i, fCheck)
Definition: commctrl.h:2679
#define LVIF_STATE
Definition: commctrl.h:2317
#define ListView_SetImageList(hwnd, himl, iImageList)
Definition: commctrl.h:2309
#define LVCF_WIDTH
Definition: commctrl.h:2592
#define ILC_COLOR32
Definition: commctrl.h:358
#define ListView_GetNextItem(hwnd, i, flags)
Definition: commctrl.h:2439
#define LVS_EX_CHECKBOXES
Definition: commctrl.h:2736
#define LVS_EX_FULLROWSELECT
Definition: commctrl.h:2739
#define ListView_GetItemCount(hwnd)
Definition: commctrl.h:2312
#define LVIS_SELECTED
Definition: commctrl.h:2324
#define LVIF_PARAM
Definition: commctrl.h:2316
#define LV_ITEM
Definition: commctrl.h:2342
struct tagNMLISTVIEW * LPNMLISTVIEW
#define ListView_SetItemText(hwndLV, i, iSubItem_, pszText_)
Definition: commctrl.h:2696
#define LVIF_TEXT
Definition: commctrl.h:2314
#define LVCF_FMT
Definition: commctrl.h:2591
#define ImageList_AddIcon(himl, hicon)
Definition: commctrl.h:415
#define WC_STATIC
Definition: commctrl.h:4687
#define LVCFMT_LEFT
Definition: commctrl.h:2603
#define ILC_MASK
Definition: commctrl.h:351
#define LVCFMT_RIGHT
Definition: commctrl.h:2604
#define LVIF_IMAGE
Definition: commctrl.h:2315
#define LVN_ITEMCHANGED
Definition: commctrl.h:3136
#define LVIS_FOCUSED
Definition: commctrl.h:2323
#define ListView_GetItem(hwnd, pitem)
Definition: commctrl.h:2399
#define LV_COLUMN
Definition: commctrl.h:2552
LPWSTR *WINAPI CommandLineToArgvW(LPCWSTR lpCmdline, int *numargs)
Definition: shell32_main.c:79
#define _countof(array)
Definition: sndvol32.h:70
CCleanupHandler * GetHandler(int Index)
Definition: cleanmgr.cpp:104
LRESULT OnHandlerItemchanged(int idCtrl, LPNMHDR pnmh, BOOL &bHandled)
Definition: cleanmgr.cpp:128
LRESULT OnDetails(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled)
Definition: cleanmgr.cpp:118
LRESULT OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
Definition: cleanmgr.cpp:46
DWORDLONG m_TotalSpaceUsed
Definition: cleanmgr.cpp:23
CWindow m_HandlerListControl
Definition: cleanmgr.cpp:21
CCleanMgrProperties(WCHAR Drive, DWORDLONG TotalSpaceUsed, CCleanupHandlerList *handlerList)
Definition: cleanmgr.cpp:28
CCleanupHandlerList * m_HandlerList
Definition: cleanmgr.cpp:24
HINSTANCE hInstance
Definition: prsht.h:296
DWORD dwSize
Definition: prsht.h:293
DWORD dwFlags
Definition: prsht.h:294
LPCWSTR pszIcon
Definition: prsht.h:299
HPROPSHEETPAGE * phpage
Definition: prsht.h:309
LPCWSTR pszCaption
Definition: prsht.h:301
HWND hwndFrom
Definition: winuser.h:3160
UINT uNewState
Definition: commctrl.h:3041
LPARAM lParam
Definition: commctrl.h:3045
UINT uOldState
Definition: commctrl.h:3042
LONG right
Definition: windef.h:308
#define towlower(c)
Definition: wctype.h:97
#define towupper(c)
Definition: wctype.h:99
int32_t INT
Definition: typedefs.h:58
_In_ WDFCOLLECTION _In_ ULONG Index
DWORD WINAPI GetWindowThreadProcessId(HWND hWnd, PDWORD lpdwProcessId)
_In_ ULONG_PTR _In_ ULONG _Out_ ULONG_PTR * pid
Definition: winddi.h:3837
LONG_PTR LPARAM
Definition: windef.h:208
LONG_PTR LRESULT
Definition: windef.h:209
UINT_PTR WPARAM
Definition: windef.h:207
#define WINAPI
Definition: msvc.h:6
#define S_FALSE
Definition: winerror.h:2357
#define SW_HIDE
Definition: winuser.h:771
#define STM_SETICON
Definition: winuser.h:2095
#define IMAGE_ICON
Definition: winuser.h:212
#define SM_CXVSCROLL
Definition: winuser.h:964
BOOL WINAPI SetForegroundWindow(_In_ HWND)
HANDLE WINAPI LoadImageW(_In_opt_ HINSTANCE hInst, _In_ LPCWSTR name, _In_ UINT type, _In_ int cx, _In_ int cy, _In_ UINT fuLoad)
Definition: cursoricon.c:2541
#define WS_EX_TOOLWINDOW
Definition: winuser.h:404
#define WM_INITDIALOG
Definition: winuser.h:1742
#define MB_YESNO
Definition: winuser.h:820
int WINAPI MessageBoxW(_In_opt_ HWND hWnd, _In_opt_ LPCWSTR lpText, _In_opt_ LPCWSTR lpCaption, _In_ UINT uType)
HWND WINAPI GetDlgItem(_In_opt_ HWND, _In_ int)
HWND WINAPI FindWindowExW(_In_opt_ HWND, _In_opt_ HWND, _In_opt_ LPCWSTR, _In_opt_ LPCWSTR)
BOOL WINAPI EnumWindows(_In_ WNDENUMPROC lpEnumFunc, _In_ LPARAM lParam)
HWND WINAPI CreateWindowExW(_In_ DWORD dwExStyle, _In_opt_ LPCWSTR lpClassName, _In_opt_ LPCWSTR lpWindowName, _In_ DWORD dwStyle, _In_ int X, _In_ int Y, _In_ int nWidth, _In_ int nHeight, _In_opt_ HWND hWndParent, _In_opt_ HMENU hMenu, _In_opt_ HINSTANCE hInstance, _In_opt_ LPVOID lpParam)
#define LR_SHARED
Definition: winuser.h:1103
#define MB_ICONQUESTION
Definition: winuser.h:792
#define SW_SHOW
Definition: winuser.h:778
#define LR_DEFAULTSIZE
Definition: winuser.h:1097
#define MAKEINTRESOURCEW(i)
Definition: winuser.h:582
#define IDYES
Definition: winuser.h:838
#define SendDlgItemMessage
Definition: winuser.h:5854
BOOL WINAPI IsWindowVisible(_In_ HWND)
BOOL WINAPI DestroyWindow(_In_ HWND)
#define MAKEINTRESOURCE
Definition: winuser.h:591
int WINAPI GetSystemMetrics(_In_ int)
#define SetDlgItemText
Definition: winuser.h:5861
_IRQL_requires_same_ _In_ CLONG ByteSize
Definition: rtltypes.h:412
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
const CHAR * LPCTSTR
Definition: xmlstorage.h:193