diff --git a/README.md b/README.md index 91a8c992..a6fbe525 100644 --- a/README.md +++ b/README.md @@ -39,10 +39,11 @@ Wine. All those differences are also documented on the Included bug fixes and improvements =================================== -**Bugfixes and features included in the next upcoming release [2]:** +**Bugfixes and features included in the next upcoming release [3]:** * Add stub for NtSetLdtEntries/ZwSetLdtEntries ([Wine Bug #26268](https://bugs.winehq.org/show_bug.cgi?id=26268)) * Allow selection of audio device for PulseAudio backend +* CoWaitForMultipleHandles shouldn't process window events when APC calls are queued ([Wine Bug #32568](https://bugs.winehq.org/show_bug.cgi?id=32568)) **Bugs fixed in Wine Staging 1.7.30 [90]:** diff --git a/debian/changelog b/debian/changelog index 7f88c021..6aa31889 100644 --- a/debian/changelog +++ b/debian/changelog @@ -2,6 +2,7 @@ wine-compholio (1.7.31) UNRELEASED; urgency=low * Added possibility to temporarily disable patches to patch system. * Added patch to allow selecting specific audio device for PulseAudio backend. * Added patch with stub for NtSetLdtEntries/ZwSetLdtEntries. + * Added patch to prevent processing message events for CoWaitForMultipleHandles when APC calls are queued. * Removed patch for iphlpapi stub functions (accepted upstream). * Removed patches for FindFirstFileExW (accepted upstream). * Removed patches for TLB dependencies lookup in resources (accepted upstream). diff --git a/patches/Makefile b/patches/Makefile index 227dad10..388baf4b 100644 --- a/patches/Makefile +++ b/patches/Makefile @@ -63,6 +63,7 @@ PATCHLIST := \ ntdll-WRITECOPY.ok \ ntoskrnl-Irp_Status.ok \ ntoskrnl-Write_CR4.ok \ + ole32-CoWaitForMultipleHandles.ok \ quartz-MediaSeeking_Positions.ok \ riched20-IText_Interface.ok \ server-ACL_Compat.ok \ @@ -1019,6 +1020,26 @@ ntoskrnl-Write_CR4.ok: echo '+ { "ntoskrnl-Write_CR4", "Stefan Leichter", "Emulate write to CR4 register." },'; \ ) > ntoskrnl-Write_CR4.ok +# Patchset ole32-CoWaitForMultipleHandles +# | +# | Included patches: +# | * CoWaitForMultipleHandles shouldn't process window events when APC calls are queued. [by Sebastian Lackner] +# | +# | This patchset fixes the following Wine bugs: +# | * [#32568] CoWaitForMultipleHandles shouldn't process window events when APC calls are queued +# | +# | Modified files: +# | * dlls/ole32/compobj.c, dlls/ole32/tests/compobj.c, include/objbase.h +# | +.INTERMEDIATE: ole32-CoWaitForMultipleHandles.ok +ole32-CoWaitForMultipleHandles.ok: + $(call APPLY_FILE,ole32-CoWaitForMultipleHandles/0001-ole32-tests-Add-tests-for-CoWaitForMultipleHandles.patch) + $(call APPLY_FILE,ole32-CoWaitForMultipleHandles/0002-ole32-Verify-arguments-for-CoWaitForMultipleHandles-.patch) + $(call APPLY_FILE,ole32-CoWaitForMultipleHandles/0003-ole32-Don-t-process-window-events-when-APC-calls-are.patch) + @( \ + echo '+ { "ole32-CoWaitForMultipleHandles", "Sebastian Lackner", "CoWaitForMultipleHandles shouldn'\''t process window events when APC calls are queued." },'; \ + ) > ole32-CoWaitForMultipleHandles.ok + # Patchset quartz-MediaSeeking_Positions # | # | Included patches: diff --git a/patches/ole32-CoWaitForMultipleHandles/0001-ole32-tests-Add-tests-for-CoWaitForMultipleHandles.patch b/patches/ole32-CoWaitForMultipleHandles/0001-ole32-tests-Add-tests-for-CoWaitForMultipleHandles.patch new file mode 100644 index 00000000..fdb61a48 --- /dev/null +++ b/patches/ole32-CoWaitForMultipleHandles/0001-ole32-tests-Add-tests-for-CoWaitForMultipleHandles.patch @@ -0,0 +1,255 @@ +From 31d234ff3ce4c423b939a7d1dd91f40bc4654a10 Mon Sep 17 00:00:00 2001 +From: Sebastian Lackner +Date: Wed, 5 Nov 2014 00:35:06 +0100 +Subject: ole32/tests: Add tests for CoWaitForMultipleHandles. + +Unfortunately times out on Windows 8? +--- + dlls/ole32/tests/compobj.c | 197 +++++++++++++++++++++++++++++++++++++++++++++ + include/objbase.h | 3 +- + 2 files changed, 199 insertions(+), 1 deletion(-) + +diff --git a/dlls/ole32/tests/compobj.c b/dlls/ole32/tests/compobj.c +index 1dfa9fb..de4c64f 100644 +--- a/dlls/ole32/tests/compobj.c ++++ b/dlls/ole32/tests/compobj.c +@@ -31,6 +31,7 @@ + #include "objbase.h" + #include "shlguid.h" + #include "urlmon.h" /* for CLSID_FileProtocol */ ++#include "dde.h" + + #include "ctxtcall.h" + +@@ -2034,6 +2035,7 @@ static void test_CoInitializeEx(void) + /* Cleanup */ + CoUninitialize(); + OleUninitialize(); ++ OleUninitialize(); + } + + static void test_OleRegGetMiscStatus(void) +@@ -2088,6 +2090,200 @@ static void test_CoCreateGuid(void) + ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + } + ++static void CALLBACK apc_test_proc(ULONG_PTR param) ++{ ++ /* nothing */ ++} ++ ++static void test_CoWaitForMultipleHandles(void) ++{ ++ static const char cls_name[] = "cowait_test_class"; ++ HANDLE handles[2]; ++ WNDCLASSEXA wc; ++ BOOL success; ++ DWORD index; ++ HRESULT hr; ++ HWND hWnd; ++ MSG msg; ++ ++ hr = pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED); ++ ok(hr == S_OK, "CoInitializeEx failed with error 0x%08x\n", hr); ++ ++ memset(&wc, 0, sizeof(wc)); ++ wc.cbSize = sizeof(wc); ++ wc.style = CS_VREDRAW | CS_HREDRAW; ++ wc.hInstance = GetModuleHandleA(0); ++ wc.hCursor = LoadCursorA(NULL, (LPCSTR)IDC_ARROW); ++ wc.hbrBackground = NULL; ++ wc.lpszClassName = cls_name; ++ wc.lpfnWndProc = DefWindowProcA; ++ success = RegisterClassExA(&wc) != 0; ++ ok(success, "RegisterClassExA failed %u\n", GetLastError()); ++ ++ hWnd = CreateWindowExA(0, cls_name, "Test", WS_TILEDWINDOW, 0, 0, 640, 480, 0, 0, 0, 0); ++ ok(hWnd != 0, "CreateWindowExA failed %u\n", GetLastError()); ++ handles[0] = CreateSemaphoreA(NULL, 1, 1, NULL); ++ ok(handles[0] != 0, "CreateSemaphoreA failed %u\n", GetLastError()); ++ handles[1] = CreateSemaphoreA(NULL, 1, 1, NULL); ++ ok(handles[1] != 0, "CreateSemaphoreA failed %u\n", GetLastError()); ++ ++ /* test without flags */ ++ ++ index = 0xdeadbeef; ++ PostMessageA(hWnd, WM_DDE_FIRST, 0, 0); ++ hr = CoWaitForMultipleHandles(0, 50, 0, NULL, &index); ++ todo_wine ++ ok(hr == E_INVALIDARG, "expected hr E_INVALIDARG, got 0x%08x\n", hr); ++ todo_wine ++ ok(index == 0, "expected index 0, got %u\n", index); ++ success = PeekMessageA(&msg, hWnd, WM_DDE_FIRST, WM_DDE_FIRST, PM_REMOVE); ++ todo_wine ++ ok(success, "CoWaitForMultipleHandles unexpectedly pumped messages\n"); ++ ++ PostMessageA(hWnd, WM_DDE_FIRST, 0, 0); ++ hr = CoWaitForMultipleHandles(0, 50, 0, handles, NULL); ++ todo_wine ++ ok(hr == E_INVALIDARG, "expected hr E_INVALIDARG, got 0x%08x\n", hr); ++ success = PeekMessageA(&msg, hWnd, WM_DDE_FIRST, WM_DDE_FIRST, PM_REMOVE); ++ todo_wine ++ ok(success, "CoWaitForMultipleHandles unexpectedly pumped messages\n"); ++ ++ index = 0xdeadbeef; ++ PostMessageA(hWnd, WM_DDE_FIRST, 0, 0); ++ hr = CoWaitForMultipleHandles(0, 50, 0, handles, &index); ++ todo_wine ++ ok(hr == RPC_E_NO_SYNC, "expected hr RPC_E_NO_SYNC, got 0x%08x\n", hr); ++ todo_wine ++ ok(index == 0, "expected index 0, got %u\n", index); ++ success = PeekMessageA(&msg, hWnd, WM_DDE_FIRST, WM_DDE_FIRST, PM_REMOVE); ++ todo_wine ++ ok(success, "CoWaitForMultipleHandles unexpectedly pumped messages\n"); ++ ++ index = 0xdeadbeef; ++ PostMessageA(hWnd, WM_DDE_FIRST, 0, 0); ++ hr = CoWaitForMultipleHandles(0, 50, 1, handles, &index); ++ ok(hr == S_OK, "expected hr S_OK, got 0x%08x\n", hr); ++ ok(index == 0, "expected index 0, got %u\n", index); ++ success = PeekMessageA(&msg, hWnd, WM_DDE_FIRST, WM_DDE_FIRST, PM_REMOVE); ++ ok(success, "CoWaitForMultipleHandles unexpectedly pumped messages\n"); ++ ++ index = 0xdeadbeef; ++ PostMessageA(hWnd, WM_DDE_FIRST, 0, 0); ++ hr = CoWaitForMultipleHandles(0, 50, 2, handles, &index); ++ ok(hr == S_OK, "expected hr S_OK, got 0x%08x\n", hr); ++ ok(index == 1, "expected index 1, got %u\n", index); ++ success = PeekMessageA(&msg, hWnd, WM_DDE_FIRST, WM_DDE_FIRST, PM_REMOVE); ++ ok(success, "CoWaitForMultipleHandles unexpectedly pumped messages\n"); ++ ++ index = 0xdeadbeef; ++ PostMessageA(hWnd, WM_DDE_FIRST, 0, 0); ++ hr = CoWaitForMultipleHandles(0, 50, 2, handles, &index); ++ ok(hr == RPC_S_CALLPENDING, "expected hr RPC_S_CALLPENDING, got 0x%08x\n", hr); ++ todo_wine ++ ok(index == 0, "expected index 0, got %u\n", index); ++ success = PeekMessageA(&msg, hWnd, WM_DDE_FIRST, WM_DDE_FIRST, PM_REMOVE); ++ ok(!success, "CoWaitForMultipleHandles didn't pump any messages\n"); ++ ++ ReleaseSemaphore(handles[0], 1, NULL); ++ ReleaseSemaphore(handles[1], 1, NULL); ++ ++ /* test with COWAIT_WAITALL */ ++ ++ index = 0xdeadbeef; ++ PostMessageA(hWnd, WM_DDE_FIRST, 0, 0); ++ hr = CoWaitForMultipleHandles(COWAIT_WAITALL, 50, 2, handles, &index); ++ ok(hr == S_OK, "expected hr S_OK, got 0x%08x\n", hr); ++ ok(index == 0, "expected index 0, got %u\n", index); ++ success = PeekMessageA(&msg, hWnd, WM_DDE_FIRST, WM_DDE_FIRST, PM_REMOVE); ++ ok(success, "CoWaitForMultipleHandles unexpectedly pumped messages\n"); ++ ++ index = 0xdeadbeef; ++ PostMessageA(hWnd, WM_DDE_FIRST, 0, 0); ++ hr = CoWaitForMultipleHandles(0, 50, 2, handles, &index); ++ ok(hr == RPC_S_CALLPENDING, "expected hr RPC_S_CALLPENDING, got 0x%08x\n", hr); ++ todo_wine ++ ok(index == 0, "expected index 0, got %u\n", index); ++ success = PeekMessageA(&msg, hWnd, WM_DDE_FIRST, WM_DDE_FIRST, PM_REMOVE); ++ ok(!success, "CoWaitForMultipleHandles didn't pump any messages\n"); ++ ++ ReleaseSemaphore(handles[0], 1, NULL); ++ ReleaseSemaphore(handles[1], 1, NULL); ++ ++ /* test with COWAIT_ALERTABLE */ ++ ++ index = 0xdeadbeef; ++ PostMessageA(hWnd, WM_DDE_FIRST, 0, 0); ++ hr = CoWaitForMultipleHandles(COWAIT_ALERTABLE, 50, 1, handles, &index); ++ ok(hr == S_OK, "expected hr S_OK, got 0x%08x\n", hr); ++ ok(index == 0, "expected index 0, got %u\n", index); ++ success = PeekMessageA(&msg, hWnd, WM_DDE_FIRST, WM_DDE_FIRST, PM_REMOVE); ++ ok(success, "CoWaitForMultipleHandles unexpectedly pumped messages\n"); ++ ++ index = 0xdeadbeef; ++ PostMessageA(hWnd, WM_DDE_FIRST, 0, 0); ++ hr = CoWaitForMultipleHandles(COWAIT_ALERTABLE, 50, 2, handles, &index); ++ ok(hr == S_OK, "expected hr S_OK, got 0x%08x\n", hr); ++ ok(index == 1, "expected index 1, got %u\n", index); ++ success = PeekMessageA(&msg, hWnd, WM_DDE_FIRST, WM_DDE_FIRST, PM_REMOVE); ++ ok(success, "CoWaitForMultipleHandles unexpectedly pumped messages\n"); ++ ++ index = 0xdeadbeef; ++ PostMessageA(hWnd, WM_DDE_FIRST, 0, 0); ++ hr = CoWaitForMultipleHandles(COWAIT_ALERTABLE, 50, 2, handles, &index); ++ ok(hr == RPC_S_CALLPENDING, "expected hr RPC_S_CALLPENDING, got 0x%08x\n", hr); ++ todo_wine ++ ok(index == 0, "expected index 0, got %u\n", index); ++ success = PeekMessageA(&msg, hWnd, WM_DDE_FIRST, WM_DDE_FIRST, PM_REMOVE); ++ ok(!success, "CoWaitForMultipleHandles didn't pump any messages\n"); ++ ++ index = 0xdeadbeef; ++ PostMessageA(hWnd, WM_DDE_FIRST, 0, 0); ++ success = QueueUserAPC(apc_test_proc, GetCurrentThread(), 0); ++ ok(success, "QueueUserAPC failed %u\n", GetLastError()); ++ hr = CoWaitForMultipleHandles(COWAIT_ALERTABLE, 50, 2, handles, &index); ++ ok(hr == S_OK, "expected hr S_OK, got 0x%08x\n", hr); ++ ok(index == WAIT_IO_COMPLETION, "expected index WAIT_IO_COMPLETION, got %u\n", index); ++ success = PeekMessageA(&msg, hWnd, WM_DDE_FIRST, WM_DDE_FIRST, PM_REMOVE); ++ todo_wine ++ ok(success, "CoWaitForMultipleHandles unexpectedly pumped messages\n"); ++ ++ /* test with COWAIT_INPUTAVAILABLE ++ * (Semaphores are still locked by previous test) */ ++ ++ index = 0xdeadbeef; ++ PostMessageA(hWnd, WM_DDE_FIRST, 0, 0); ++ success = PeekMessageA(&msg, hWnd, WM_DDE_FIRST, WM_DDE_FIRST, PM_NOREMOVE); ++ ok(success, "PeekMessageA returned FALSE\n"); ++ hr = CoWaitForMultipleHandles(0, 50, 2, handles, &index); ++ ok(hr == RPC_S_CALLPENDING, "expected hr RPC_S_CALLPENDING, got 0x%08x\n", hr); ++ todo_wine ++ ok(index == 0, "expected index 0, got %u\n", index); ++ success = PeekMessageA(&msg, hWnd, WM_DDE_FIRST, WM_DDE_FIRST, PM_REMOVE); ++ ok(!success, "CoWaitForMultipleHandles didn't pump any messages\n"); ++ ++ index = 0xdeadbeef; ++ PostMessageA(hWnd, WM_DDE_FIRST, 0, 0); ++ success = PeekMessageA(&msg, hWnd, WM_DDE_FIRST, WM_DDE_FIRST, PM_NOREMOVE); ++ ok(success, "PeekMessageA returned FALSE\n"); ++ hr = CoWaitForMultipleHandles(COWAIT_INPUTAVAILABLE, 50, 2, handles, &index); ++ ok(hr == RPC_S_CALLPENDING || broken(hr == E_INVALIDARG), ++ "expected hr RPC_S_CALLPENDING, got 0x%08x\n", hr); ++ todo_wine ++ ok(index == 0, "expected index 0, got %u\n", index); ++ success = PeekMessageA(&msg, hWnd, WM_DDE_FIRST, WM_DDE_FIRST, PM_REMOVE); ++ ok(!success || broken(hr == E_INVALIDARG && success), ++ "CoWaitForMultipleHandles didn't pump any messages\n"); ++ ++ CloseHandle(handles[0]); ++ CloseHandle(handles[1]); ++ DestroyWindow(hWnd); ++ ++ success = UnregisterClassA(cls_name, GetModuleHandleA(0)); ++ ok(success, "UnregisterClass failed %u\n", GetLastError()); ++ ++ CoUninitialize(); ++} ++ + static void init_funcs(void) + { + HMODULE hOle32 = GetModuleHandleA("ole32"); +@@ -2148,4 +2344,5 @@ START_TEST(compobj) + test_CoInitializeEx(); + test_OleRegGetMiscStatus(); + test_CoCreateGuid(); ++ test_CoWaitForMultipleHandles(); + } +diff --git a/include/objbase.h b/include/objbase.h +index e1e45c9..c1a6f3c 100644 +--- a/include/objbase.h ++++ b/include/objbase.h +@@ -381,7 +381,8 @@ HRESULT WINAPI CoRegisterChannelHook(REFGUID ExtensionGuid, IChannelHook *pChann + typedef enum tagCOWAIT_FLAGS + { + COWAIT_WAITALL = 0x00000001, +- COWAIT_ALERTABLE = 0x00000002 ++ COWAIT_ALERTABLE = 0x00000002, ++ COWAIT_INPUTAVAILABLE = 0x00000004 + } COWAIT_FLAGS; + + HRESULT WINAPI CoWaitForMultipleHandles(DWORD dwFlags,DWORD dwTimeout,ULONG cHandles,LPHANDLE pHandles,LPDWORD lpdwindex); +-- +2.1.3 + diff --git a/patches/ole32-CoWaitForMultipleHandles/0002-ole32-Verify-arguments-for-CoWaitForMultipleHandles-.patch b/patches/ole32-CoWaitForMultipleHandles/0002-ole32-Verify-arguments-for-CoWaitForMultipleHandles-.patch new file mode 100644 index 00000000..739b33cd --- /dev/null +++ b/patches/ole32-CoWaitForMultipleHandles/0002-ole32-Verify-arguments-for-CoWaitForMultipleHandles-.patch @@ -0,0 +1,112 @@ +From ed866ac6a70e8309ea539b0f4bb03a0a7d73029f Mon Sep 17 00:00:00 2001 +From: Sebastian Lackner +Date: Wed, 5 Nov 2014 00:39:51 +0100 +Subject: ole32: Verify arguments for CoWaitForMultipleHandles, always + initialize index to zero. + +--- + dlls/ole32/compobj.c | 11 +++++++++++ + dlls/ole32/tests/compobj.c | 13 ------------- + 2 files changed, 11 insertions(+), 13 deletions(-) + +diff --git a/dlls/ole32/compobj.c b/dlls/ole32/compobj.c +index 1fab04f..1d9b943 100644 +--- a/dlls/ole32/compobj.c ++++ b/dlls/ole32/compobj.c +@@ -4431,6 +4431,17 @@ HRESULT WINAPI CoWaitForMultipleHandles(DWORD dwFlags, DWORD dwTimeout, + TRACE("(0x%08x, 0x%08x, %d, %p, %p)\n", dwFlags, dwTimeout, cHandles, + pHandles, lpdwindex); + ++ if (!lpdwindex) ++ return E_INVALIDARG; ++ ++ *lpdwindex = 0; ++ ++ if (!pHandles) ++ return E_INVALIDARG; ++ ++ if (!cHandles) ++ return RPC_E_NO_SYNC; ++ + while (TRUE) + { + DWORD now = GetTickCount(); +diff --git a/dlls/ole32/tests/compobj.c b/dlls/ole32/tests/compobj.c +index de4c64f..8b864bf 100644 +--- a/dlls/ole32/tests/compobj.c ++++ b/dlls/ole32/tests/compobj.c +@@ -2132,31 +2132,23 @@ static void test_CoWaitForMultipleHandles(void) + index = 0xdeadbeef; + PostMessageA(hWnd, WM_DDE_FIRST, 0, 0); + hr = CoWaitForMultipleHandles(0, 50, 0, NULL, &index); +- todo_wine + ok(hr == E_INVALIDARG, "expected hr E_INVALIDARG, got 0x%08x\n", hr); +- todo_wine + ok(index == 0, "expected index 0, got %u\n", index); + success = PeekMessageA(&msg, hWnd, WM_DDE_FIRST, WM_DDE_FIRST, PM_REMOVE); +- todo_wine + ok(success, "CoWaitForMultipleHandles unexpectedly pumped messages\n"); + + PostMessageA(hWnd, WM_DDE_FIRST, 0, 0); + hr = CoWaitForMultipleHandles(0, 50, 0, handles, NULL); +- todo_wine + ok(hr == E_INVALIDARG, "expected hr E_INVALIDARG, got 0x%08x\n", hr); + success = PeekMessageA(&msg, hWnd, WM_DDE_FIRST, WM_DDE_FIRST, PM_REMOVE); +- todo_wine + ok(success, "CoWaitForMultipleHandles unexpectedly pumped messages\n"); + + index = 0xdeadbeef; + PostMessageA(hWnd, WM_DDE_FIRST, 0, 0); + hr = CoWaitForMultipleHandles(0, 50, 0, handles, &index); +- todo_wine + ok(hr == RPC_E_NO_SYNC, "expected hr RPC_E_NO_SYNC, got 0x%08x\n", hr); +- todo_wine + ok(index == 0, "expected index 0, got %u\n", index); + success = PeekMessageA(&msg, hWnd, WM_DDE_FIRST, WM_DDE_FIRST, PM_REMOVE); +- todo_wine + ok(success, "CoWaitForMultipleHandles unexpectedly pumped messages\n"); + + index = 0xdeadbeef; +@@ -2179,7 +2171,6 @@ static void test_CoWaitForMultipleHandles(void) + PostMessageA(hWnd, WM_DDE_FIRST, 0, 0); + hr = CoWaitForMultipleHandles(0, 50, 2, handles, &index); + ok(hr == RPC_S_CALLPENDING, "expected hr RPC_S_CALLPENDING, got 0x%08x\n", hr); +- todo_wine + ok(index == 0, "expected index 0, got %u\n", index); + success = PeekMessageA(&msg, hWnd, WM_DDE_FIRST, WM_DDE_FIRST, PM_REMOVE); + ok(!success, "CoWaitForMultipleHandles didn't pump any messages\n"); +@@ -2201,7 +2192,6 @@ static void test_CoWaitForMultipleHandles(void) + PostMessageA(hWnd, WM_DDE_FIRST, 0, 0); + hr = CoWaitForMultipleHandles(0, 50, 2, handles, &index); + ok(hr == RPC_S_CALLPENDING, "expected hr RPC_S_CALLPENDING, got 0x%08x\n", hr); +- todo_wine + ok(index == 0, "expected index 0, got %u\n", index); + success = PeekMessageA(&msg, hWnd, WM_DDE_FIRST, WM_DDE_FIRST, PM_REMOVE); + ok(!success, "CoWaitForMultipleHandles didn't pump any messages\n"); +@@ -2231,7 +2221,6 @@ static void test_CoWaitForMultipleHandles(void) + PostMessageA(hWnd, WM_DDE_FIRST, 0, 0); + hr = CoWaitForMultipleHandles(COWAIT_ALERTABLE, 50, 2, handles, &index); + ok(hr == RPC_S_CALLPENDING, "expected hr RPC_S_CALLPENDING, got 0x%08x\n", hr); +- todo_wine + ok(index == 0, "expected index 0, got %u\n", index); + success = PeekMessageA(&msg, hWnd, WM_DDE_FIRST, WM_DDE_FIRST, PM_REMOVE); + ok(!success, "CoWaitForMultipleHandles didn't pump any messages\n"); +@@ -2256,7 +2245,6 @@ static void test_CoWaitForMultipleHandles(void) + ok(success, "PeekMessageA returned FALSE\n"); + hr = CoWaitForMultipleHandles(0, 50, 2, handles, &index); + ok(hr == RPC_S_CALLPENDING, "expected hr RPC_S_CALLPENDING, got 0x%08x\n", hr); +- todo_wine + ok(index == 0, "expected index 0, got %u\n", index); + success = PeekMessageA(&msg, hWnd, WM_DDE_FIRST, WM_DDE_FIRST, PM_REMOVE); + ok(!success, "CoWaitForMultipleHandles didn't pump any messages\n"); +@@ -2268,7 +2256,6 @@ static void test_CoWaitForMultipleHandles(void) + hr = CoWaitForMultipleHandles(COWAIT_INPUTAVAILABLE, 50, 2, handles, &index); + ok(hr == RPC_S_CALLPENDING || broken(hr == E_INVALIDARG), + "expected hr RPC_S_CALLPENDING, got 0x%08x\n", hr); +- todo_wine + ok(index == 0, "expected index 0, got %u\n", index); + success = PeekMessageA(&msg, hWnd, WM_DDE_FIRST, WM_DDE_FIRST, PM_REMOVE); + ok(!success || broken(hr == E_INVALIDARG && success), +-- +2.1.3 + diff --git a/patches/ole32-CoWaitForMultipleHandles/0003-ole32-Don-t-process-window-events-when-APC-calls-are.patch b/patches/ole32-CoWaitForMultipleHandles/0003-ole32-Don-t-process-window-events-when-APC-calls-are.patch new file mode 100644 index 00000000..4dfbbd4c --- /dev/null +++ b/patches/ole32-CoWaitForMultipleHandles/0003-ole32-Don-t-process-window-events-when-APC-calls-are.patch @@ -0,0 +1,52 @@ +From 2c0d07adf0da9d822938c5759c052ed0dc7e2b53 Mon Sep 17 00:00:00 2001 +From: Sebastian Lackner +Date: Wed, 5 Nov 2014 00:49:59 +0100 +Subject: ole32: Don't process window events when APC calls are queued. + +--- + dlls/ole32/compobj.c | 16 +++++++++++++--- + dlls/ole32/tests/compobj.c | 1 - + 2 files changed, 13 insertions(+), 4 deletions(-) + +diff --git a/dlls/ole32/compobj.c b/dlls/ole32/compobj.c +index 1d9b943..f4c3c26 100644 +--- a/dlls/ole32/compobj.c ++++ b/dlls/ole32/compobj.c +@@ -4460,9 +4460,19 @@ HRESULT WINAPI CoWaitForMultipleHandles(DWORD dwFlags, DWORD dwTimeout, + + TRACE("waiting for rpc completion or window message\n"); + +- res = MsgWaitForMultipleObjectsEx(cHandles, pHandles, +- (dwTimeout == INFINITE) ? INFINITE : start_time + dwTimeout - now, +- QS_SENDMESSAGE | QS_ALLPOSTMESSAGE | QS_PAINT, wait_flags); ++ /* MsgWaitForMultipleObjectsEx will always process Window messages, even when an ++ * APC call is queued. We work around that by checking for APC calls manually first */ ++ ++ res = WAIT_TIMEOUT; ++ ++ if (dwFlags & COWAIT_ALERTABLE) ++ res = WaitForMultipleObjectsEx(cHandles, pHandles, ++ (dwFlags & COWAIT_WAITALL) != 0, 0, TRUE); ++ ++ if (res == WAIT_TIMEOUT) ++ res = MsgWaitForMultipleObjectsEx(cHandles, pHandles, ++ (dwTimeout == INFINITE) ? INFINITE : start_time + dwTimeout - now, ++ QS_SENDMESSAGE | QS_ALLPOSTMESSAGE | QS_PAINT, wait_flags); + + if (res == WAIT_OBJECT_0 + cHandles) /* messages available */ + { +diff --git a/dlls/ole32/tests/compobj.c b/dlls/ole32/tests/compobj.c +index 8b864bf..21490ef 100644 +--- a/dlls/ole32/tests/compobj.c ++++ b/dlls/ole32/tests/compobj.c +@@ -2233,7 +2233,6 @@ static void test_CoWaitForMultipleHandles(void) + ok(hr == S_OK, "expected hr S_OK, got 0x%08x\n", hr); + ok(index == WAIT_IO_COMPLETION, "expected index WAIT_IO_COMPLETION, got %u\n", index); + success = PeekMessageA(&msg, hWnd, WM_DDE_FIRST, WM_DDE_FIRST, PM_REMOVE); +- todo_wine + ok(success, "CoWaitForMultipleHandles unexpectedly pumped messages\n"); + + /* test with COWAIT_INPUTAVAILABLE +-- +2.1.3 + diff --git a/patches/ole32-CoWaitForMultipleHandles/definition b/patches/ole32-CoWaitForMultipleHandles/definition new file mode 100644 index 00000000..0466e4f9 --- /dev/null +++ b/patches/ole32-CoWaitForMultipleHandles/definition @@ -0,0 +1,4 @@ +Author: Sebastian Lackner +Subject: CoWaitForMultipleHandles shouldn't process window events when APC calls are queued. +Revision: 1 +Fixes: [32568] CoWaitForMultipleHandles shouldn't process window events when APC calls are queued