[PATCH v2 0/2] MR11150: wshom.ocx: Fix Popup not waiting correctly
`MsgWaitForMultipleObjects` can return immediately if the current thread already has a message waiting (posted by something unrelated to this function). We need to process messages until the handle we actually care about becomes signaled or times out. -- v2: (Style) Fix old missing space https://gitlab.winehq.org/wine/wine/-/merge_requests/11150
From: Anders Kjersem <andersdev@proton.me> --- dlls/wshom.ocx/shell.c | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/dlls/wshom.ocx/shell.c b/dlls/wshom.ocx/shell.c index 4056201a6b7..a613dc20b7f 100644 --- a/dlls/wshom.ocx/shell.c +++ b/dlls/wshom.ocx/shell.c @@ -29,6 +29,24 @@ extern HRESULT WINAPI DoOpenPipeStream(HANDLE pipe, IOMode mode, ITextStream **s WINE_DEFAULT_DEBUG_CHANNEL(wshom); +DWORD WaitForHandles(DWORD nCount, const HANDLE *pHandles, DWORD dwTimeout) +{ + for (;;) + { + DWORD status = MsgWaitForMultipleObjects(nCount, pHandles, FALSE, dwTimeout, QS_ALLINPUT); + if (status == WAIT_OBJECT_0 + nCount) + { + for (MSG msg; PeekMessageW(&msg, NULL, 0, 0, TRUE);) + { + TranslateMessage(&msg); + DispatchMessageW(&msg); + } + continue; + } + return status; + } +} + typedef struct { struct provideclassinfo classinfo; @@ -1410,7 +1428,7 @@ static HRESULT WINAPI WshShell3_Run(IWshShell3 *iface, BSTR cmd, VARIANT *style, if (waitforprocess) { DWORD code; - WaitForSingleObject(info.hProcess, INFINITE); + WaitForHandles(1, &info.hProcess, INFINITE); GetExitCodeProcess(info.hProcess, &code); CloseHandle(info.hProcess); *exit_code = code; @@ -1483,11 +1501,11 @@ static HRESULT WINAPI WshShell3_Popup(IWshShell3 *iface, BSTR text, VARIANT *sec param.text = text; param.button = -1; hthread = CreateThread(NULL, 0, popup_thread_proc, ¶m, 0, &tid); - status = MsgWaitForMultipleObjects(1, &hthread, FALSE, V_I4(&timeout) ? V_I4(&timeout) * 1000: INFINITE, 0); + status = WaitForHandles(1, &hthread, V_I4(&timeout) ? V_I4(&timeout) * 1000: INFINITE); if (status == WAIT_TIMEOUT) { PostThreadMessageW(tid, WM_QUIT, 0, 0); - MsgWaitForMultipleObjects(1, &hthread, FALSE, INFINITE, 0); + WaitForHandles(1, &hthread, INFINITE); /* Wait for thread because it will write to param.button */ param.button = -1; } *button = param.button; -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11150
From: Anders Kjersem <andersdev@proton.me> --- dlls/wshom.ocx/shell.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dlls/wshom.ocx/shell.c b/dlls/wshom.ocx/shell.c index a613dc20b7f..1675b263895 100644 --- a/dlls/wshom.ocx/shell.c +++ b/dlls/wshom.ocx/shell.c @@ -1501,7 +1501,7 @@ static HRESULT WINAPI WshShell3_Popup(IWshShell3 *iface, BSTR text, VARIANT *sec param.text = text; param.button = -1; hthread = CreateThread(NULL, 0, popup_thread_proc, ¶m, 0, &tid); - status = WaitForHandles(1, &hthread, V_I4(&timeout) ? V_I4(&timeout) * 1000: INFINITE); + status = WaitForHandles(1, &hthread, V_I4(&timeout) ? V_I4(&timeout) * 1000 : INFINITE); if (status == WAIT_TIMEOUT) { PostThreadMessageW(tid, WM_QUIT, 0, 0); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11150
participants (2)
-
Anders Kjersem -
Anders Kjersem (@anders)