diff --git a/dlls/ole32/tests/ole_server.c b/dlls/ole32/tests/ole_server.c index b0bf01d96e8..6fec244e25c 100644 --- a/dlls/ole32/tests/ole_server.c +++ b/dlls/ole32/tests/ole_server.c @@ -32,6 +32,9 @@ DEFINE_GUID(CLSID_WineTestObject, 0xdeadbeef,0xdead,0xbeef,0xde,0xad,0xbe,0xef,0xde,0xad,0xbe,0xef); DEFINE_GUID(CLSID_UnknownUnmarshal,0x4c1e39e1,0xe3e3,0x4296,0xaa,0x86,0xec,0x93,0x8d,0x89,0x6e,0x92); +static HRESULT (WINAPI *pCoIncrementMTAUsage)(CO_MTA_USAGE_COOKIE *cookie); +static HRESULT (WINAPI *pCoDecrementMTAUsage)(CO_MTA_USAGE_COOKIE cookie); + struct winetest_info { LONG child_failures; @@ -237,10 +240,22 @@ static void ole_server(void) { HRESULT hr; DWORD key; + CO_MTA_USAGE_COOKIE cookie; - trace("server: starting %u\n", GetCurrentProcessId()); + trace("server: starting (pid %#x/tid %#x)\n", GetCurrentProcessId(), GetCurrentThreadId()); + + pCoIncrementMTAUsage = (void *)GetProcAddress(GetModuleHandleA("ole32.dll"), "CoIncrementMTAUsage"); + pCoDecrementMTAUsage = (void *)GetProcAddress(GetModuleHandleA("ole32.dll"), "CoDecrementMTAUsage"); + + hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); + ok(hr == S_OK, "CoInitializeEx error %#x\n", hr); + + if (pCoIncrementMTAUsage) + { + hr = pCoIncrementMTAUsage(&cookie); + ok(hr == S_OK, "got %#x\n", hr); + } - hr = CoInitializeEx(NULL, COINIT_MULTITHREADED); if (hr == S_OK) { trace("server: registering class object\n"); @@ -258,7 +273,13 @@ static void ole_server(void) SetEvent(init_done_event); trace("server: waiting for requests\n"); - WaitForSingleObject(done_event, INFINITE); + + for (;;) + { + MSG msg; + while (PeekMessageW(&msg, NULL, 0, 0, 0)) DispatchMessageW(&msg); + if (WaitForSingleObject(done_event, 50) == WAIT_OBJECT_0) break; + } /* 1 remainining class ref is supposed to be cleared by CoRevokeClassObject */ ok(class_ref == 1, "expected 1 class refs, got %d\n", class_ref); @@ -280,6 +301,12 @@ static void ole_server(void) trace("server: ret CoUninitialize\n"); } + if (pCoDecrementMTAUsage) + { + hr = pCoDecrementMTAUsage(cookie); + ok(hr == S_OK, "got %#x\n", hr); + } + trace("server: exiting %u\n", GetCurrentProcessId()); } @@ -331,10 +358,8 @@ static void unregister_server(void) DELETE, NULL, &root, NULL); if (ret == ERROR_SUCCESS) { - ret = RegDeleteKeyA(root, "InprocHandler32"); - ok(ret == ERROR_SUCCESS, "RegDeleteKey error %u\n", ret); - ret = RegDeleteKeyA(root, "LocalServer32"); - ok(ret == ERROR_SUCCESS, "RegDeleteKey error %u\n", ret); + RegDeleteKeyA(root, "InprocHandler32"); + RegDeleteKeyA(root, "LocalServer32"); ret = RegDeleteKeyA(root, ""); ok(ret == ERROR_SUCCESS, "RegDeleteKey error %u\n", ret); RegCloseKey(root); @@ -414,6 +439,9 @@ START_TEST(ole_server) return; } + /* Clear from previous crashes */ + unregister_server(); + if (!register_server(argv[0], FALSE)) { win_skip("not enough permissions to create a server CLSID key\n"); @@ -428,11 +456,33 @@ START_TEST(ole_server) WaitForSingleObject(init_done_event, 5000); hr = CoInitializeEx(NULL, COINIT_MULTITHREADED); - ok(hr == S_OK, "OleInitialize error %#x\n", hr); + ok(hr == S_OK, "CoInitializeEx error %#x\n", hr); hr = CoCreateInstance(&clsid, NULL, CLSCTX_INPROC_HANDLER, &IID_IUnknown, (void **)&unknown); ok(hr == REGDB_E_CLASSNOTREG, "expected REGDB_E_CLASSNOTREG, got %#x\n", hr); + if (!register_server(argv[0], FALSE)) + { + win_skip("not enough permissions to create a server CLSID key\n"); + unregister_server(); + return; + } + + trace("call CoCreateInstance(&IID_IUnknown)\n"); + hr = CoCreateInstance(&clsid, NULL, CLSCTX_LOCAL_SERVER, &IID_IUnknown, (void **)&unknown); + trace("ret CoCreateInstance(&IID_IUnknown)\n"); + ok(hr == S_OK, "CoCreateInstance(IID_IUnknown) error %#x\n", hr); + + if (hr == S_OK) + { + trace("call IUnknown_Release\n"); + ret = IUnknown_Release(unknown); + trace("ret IUnknown_Release\n"); + ok(!ret, "expected ref 0, got %u\n", ret); + } + + goto done; + if (!register_server(argv[0], TRUE)) { win_skip("not enough permissions to create a server CLSID key\n"); @@ -546,9 +596,10 @@ test_local_server: trace("ret IClassFactory_Release\n"); ok(!ret, "expected ref 0, got %u\n", ret); +done: trace("signalling termination\n"); SetEvent(done_event); - ret = WaitForSingleObject(process, 10000); + ret = WaitForSingleObject(process, 30000); ok(ret == WAIT_OBJECT_0, "server failed to terminate\n"); OleUninitialize();