Reactos

[CLEANMGR] Only allow one instance per drive (#7832)

CORE-18941

authored by

Whindmar Saksit and committed by
GitHub
467dec4d 21b3382f

+47 -2
+13
base/applications/cleanmgr/cleanmgr/CSelectDriveDlg.cpp
··· 25 25 26 26 LRESULT OnInitDialog(UINT, WPARAM, LPARAM, BOOL&) 27 27 { 28 + // Try to find an existing instance of this dialog 29 + WCHAR buf[300]; 30 + GetWindowTextW(buf, _countof(buf)); 31 + for (HWND hNext = NULL, hFind; (hFind = ::FindWindowExW(NULL, hNext, NULL, buf)) != NULL; hNext = hFind) 32 + { 33 + if (hFind != *this && ::IsWindowVisible(hFind)) 34 + { 35 + ::SetForegroundWindow(hFind); 36 + EndDialog(IDCANCEL); 37 + return FALSE; 38 + } 39 + } 40 + 28 41 CWindow cbo = GetDlgItem(IDC_DRIVES); 29 42 WCHAR VolumeNameBuffer[MAX_PATH + 1]; 30 43 CStringW Tmp;
+34 -2
base/applications/cleanmgr/cleanmgr/cleanmgr.cpp
··· 247 247 return true; 248 248 } 249 249 250 + static inline UINT GetWindowProcessId(_In_ HWND hWnd) 251 + { 252 + DWORD pid; 253 + return GetWindowThreadProcessId(hWnd, &pid) ? pid : 0; 254 + } 255 + 256 + static BOOL CALLBACK EnumSingleInstanceCallback(_In_ HWND hWnd, _In_ LPARAM lParam) 257 + { 258 + if (::IsWindowVisible(hWnd) && (LPARAM)GetWindowProcessId(hWnd) == lParam) 259 + { 260 + ::SetForegroundWindow(hWnd); 261 + return FALSE; 262 + } 263 + return TRUE; 264 + } 265 + 250 266 HRESULT Run(_In_ int nShowCmd) throw() 251 267 { 252 268 if (m_Drive == UNICODE_NULL) ··· 257 273 if (m_Drive == UNICODE_NULL) 258 274 return E_FAIL; 259 275 276 + CStringW Title; 277 + Title.Format(IDS_PROPERTIES_MAIN_TITLE, m_Drive); 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 + { 284 + ::EnumWindows(EnumSingleInstanceCallback, GetWindowProcessId(hFind)); 285 + return S_FALSE; 286 + } 287 + } 288 + 260 289 CCleanupHandlerList Handlers; 261 290 CEmptyVolumeCacheCallBack CacheCallBack; 262 291 ··· 271 300 psh.dwFlags = PSH_NOAPPLYNOW | PSH_USEICONID | PSH_NOCONTEXTHELP; 272 301 psh.hInstance = _AtlBaseModule.GetResourceInstance(); 273 302 psh.pszIcon = MAKEINTRESOURCEW(IDI_CLEANMGR); 274 - CStringW Title; 275 - Title.Format(IDS_PROPERTIES_MAIN_TITLE, m_Drive); 276 303 psh.pszCaption = Title; 277 304 psh.nPages = _countof(hpsp); 278 305 psh.phpage = hpsp; 279 306 280 307 if (PropertySheetW(&psh) >= 1) 281 308 { 309 + ::DestroyWindow(hWndInstance); // Allow new "cleanmgr /D" without waiting for these handlers 282 310 Handlers.ExecuteCleanup(&CacheCallBack); 311 + } 312 + else 313 + { 314 + ::DestroyWindow(hWndInstance); 283 315 } 284 316 return S_OK; 285 317 }