mirror of
https://github.com/microsoft/PowerToys.git
synced 2025-12-15 03:07:56 +01:00
Ensure the lifetime of CPowerRenameProcessUI on the worker thread (#11106)
* Ensure the lifetime of CPowerRenameProcessUI on the worker thread to prevent AV during shutdown * Ensure worker thread progress dialog pointer is valid. Also add a call to StopProgressDialog from the worker thread as the progress dialog can be particular about thread affinity for that method call. Co-authored-by: Chris Davis (EDGE) <chrdavis@microsoft.com>
This commit is contained in:
@@ -1523,7 +1523,12 @@ HRESULT CPowerRenameProgressUI::Start()
|
||||
{
|
||||
_Cleanup();
|
||||
m_canceled = false;
|
||||
AddRef();
|
||||
m_workerThreadHandle = CreateThread(nullptr, 0, s_workerThread, this, 0, nullptr);
|
||||
if (!m_workerThreadHandle)
|
||||
{
|
||||
Release();
|
||||
}
|
||||
return (m_workerThreadHandle) ? S_OK : E_FAIL;
|
||||
}
|
||||
|
||||
@@ -1538,20 +1543,22 @@ DWORD WINAPI CPowerRenameProgressUI::s_workerThread(_In_ void* pv)
|
||||
|
||||
SetTimer(hwndMessage, TIMERID_CHECKCANCELED, CANCEL_CHECK_INTERVAL, nullptr);
|
||||
|
||||
if (SUCCEEDED(CoCreateInstance(CLSID_ProgressDialog, NULL, CLSCTX_INPROC, IID_PPV_ARGS(&pThis->m_sppd))))
|
||||
CComPtr<IProgressDialog> sppd;
|
||||
if (SUCCEEDED(CoCreateInstance(CLSID_ProgressDialog, NULL, CLSCTX_INPROC, IID_PPV_ARGS(&sppd))))
|
||||
{
|
||||
pThis->m_sppd = sppd;
|
||||
wchar_t buff[100] = { 0 };
|
||||
LoadString(g_hInst, IDS_LOADING, buff, ARRAYSIZE(buff));
|
||||
pThis->m_sppd->SetLine(1, buff, FALSE, NULL);
|
||||
sppd->SetLine(1, buff, FALSE, NULL);
|
||||
LoadString(g_hInst, IDS_LOADING_MSG, buff, ARRAYSIZE(buff));
|
||||
pThis->m_sppd->SetLine(2, buff, FALSE, NULL);
|
||||
sppd->SetLine(2, buff, FALSE, NULL);
|
||||
LoadString(g_hInst, IDS_APP_TITLE, buff, ARRAYSIZE(buff));
|
||||
pThis->m_sppd->SetTitle(buff);
|
||||
sppd->SetTitle(buff);
|
||||
SetTimer(hwndMessage, TIMERID_CHECKCANCELED, CANCEL_CHECK_INTERVAL, nullptr);
|
||||
pThis->m_sppd->StartProgressDialog(NULL, NULL, PROGDLG_MARQUEEPROGRESS, NULL);
|
||||
sppd->StartProgressDialog(NULL, NULL, PROGDLG_MARQUEEPROGRESS, NULL);
|
||||
}
|
||||
|
||||
while (pThis->m_sppd && !pThis->m_canceled)
|
||||
while (pThis->m_sppd && !sppd->HasUserCancelled())
|
||||
{
|
||||
MSG msg;
|
||||
while (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE))
|
||||
@@ -1561,8 +1568,13 @@ DWORD WINAPI CPowerRenameProgressUI::s_workerThread(_In_ void* pv)
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure dialog is stopped
|
||||
sppd->StopProgressDialog();
|
||||
|
||||
KillTimer(hwndMessage, TIMERID_CHECKCANCELED);
|
||||
DestroyWindow(hwndMessage);
|
||||
|
||||
pThis->Release();
|
||||
}
|
||||
|
||||
CoUninitialize();
|
||||
@@ -1587,9 +1599,12 @@ void CPowerRenameProgressUI::_Cleanup()
|
||||
|
||||
if (m_workerThreadHandle)
|
||||
{
|
||||
// Wait for up to 5 seconds for worker thread to finish
|
||||
WaitForSingleObject(m_workerThreadHandle, 5000);
|
||||
CloseHandle(m_workerThreadHandle);
|
||||
m_workerThreadHandle = nullptr;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void CPowerRenameProgressUI::_UpdateCancelState()
|
||||
@@ -1634,6 +1649,7 @@ LRESULT CPowerRenameProgressUI::_WndProc(_In_ HWND hwnd, _In_ UINT msg, _In_ WPA
|
||||
break;
|
||||
|
||||
case WM_DESTROY:
|
||||
_UpdateCancelState();
|
||||
KillTimer(hwnd, TIMERID_CHECKCANCELED);
|
||||
break;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user