diff --git a/dlls/ole32/tests/compobj.c b/dlls/ole32/tests/compobj.c index f1e0134731c..0ce941bda49 100644 --- a/dlls/ole32/tests/compobj.c +++ b/dlls/ole32/tests/compobj.c @@ -602,25 +602,6 @@ static void test_StringFromGUID2(void) ok(len == 0, "len: %d (expected 0)\n", len); } -struct info -{ - HANDLE wait, stop; -}; - -static DWORD CALLBACK ole_initialize_thread(LPVOID pv) -{ - HRESULT hr; - struct info *info = pv; - - hr = pCoInitializeEx(NULL, COINIT_MULTITHREADED); - - SetEvent(info->wait); - WaitForSingleObject(info->stop, 10000); - - CoUninitialize(); - return hr; -} - #define test_apt_type(t, q, t_t, t_q) _test_apt_type(t, q, t_t, t_q, __LINE__) static void _test_apt_type(APTTYPE expected_type, APTTYPEQUALIFIER expected_qualifier, BOOL todo_type, BOOL todo_qualifier, int line) @@ -644,10 +625,7 @@ todo_wine_if(todo_qualifier) static void test_CoCreateInstance(void) { HRESULT hr; - HANDLE thread; - DWORD tid, exitcode; IUnknown *pUnk; - struct info info; REFCLSID rclsid = &CLSID_InternetZoneManager; pUnk = (IUnknown *)0xdeadbeef; @@ -682,51 +660,15 @@ static void test_CoCreateInstance(void) hr = CoCreateInstance(rclsid, NULL, CLSCTX_INPROC_SERVER, &IID_IUnknown, (void **)&pUnk); ok(hr == CO_E_NOTINITIALIZED, "CoCreateInstance should have returned CO_E_NOTINITIALIZED instead of 0x%08x\n", hr); - /* show that COM doesn't have to be initialized for multi-threaded apartments if another - thread has already done so */ - - test_apt_type(APTTYPE_CURRENT, APTTYPEQUALIFIER_NONE, FALSE, FALSE); - - info.wait = CreateEventA(NULL, TRUE, FALSE, NULL); - ok(info.wait != NULL, "CreateEvent failed with error %d\n", GetLastError()); - - info.stop = CreateEventA(NULL, TRUE, FALSE, NULL); - ok(info.stop != NULL, "CreateEvent failed with error %d\n", GetLastError()); - - thread = CreateThread(NULL, 0, ole_initialize_thread, &info, 0, &tid); - ok(thread != NULL, "CreateThread failed with error %d\n", GetLastError()); - - ok( !WaitForSingleObject(info.wait, 10000 ), "wait timed out\n" ); - - test_apt_type(APTTYPE_MTA, APTTYPEQUALIFIER_IMPLICIT_MTA, TRUE, TRUE); - - pUnk = (IUnknown *)0xdeadbeef; - hr = CoCreateInstance(rclsid, NULL, CLSCTX_INPROC_SERVER, &IID_IUnknown, (void **)&pUnk); - ok(hr == S_OK, "CoCreateInstance should have returned S_OK instead of 0x%08x\n", hr); - if (pUnk) IUnknown_Release(pUnk); - - SetEvent(info.stop); - ok( !WaitForSingleObject(thread, 10000), "wait timed out\n" ); - - GetExitCodeThread(thread, &exitcode); - hr = exitcode; - ok(hr == S_OK, "thread should have returned S_OK instead of 0x%08x\n", hr); - - CloseHandle(thread); - CloseHandle(info.wait); - CloseHandle(info.stop); - test_apt_type(APTTYPE_CURRENT, APTTYPEQUALIFIER_NONE, FALSE, FALSE); } static void test_CoGetClassObject(void) { HRESULT hr; - HANDLE thread, handle; - DWORD tid, exitcode; + HANDLE handle; ULONG_PTR cookie; IUnknown *pUnk; - struct info info; REFCLSID rclsid = &CLSID_InternetZoneManager; HKEY hkey; LONG res; @@ -740,45 +682,6 @@ static void test_CoGetClassObject(void) broken(hr == CO_E_NOTINITIALIZED), /* win9x */ "CoGetClassObject should have returned E_INVALIDARG instead of 0x%08x\n", hr); - /* show that COM doesn't have to be initialized for multi-threaded apartments if another - thread has already done so */ - - test_apt_type(APTTYPE_CURRENT, APTTYPEQUALIFIER_NONE, FALSE, FALSE); - - info.wait = CreateEventA(NULL, TRUE, FALSE, NULL); - ok(info.wait != NULL, "CreateEvent failed with error %d\n", GetLastError()); - - info.stop = CreateEventA(NULL, TRUE, FALSE, NULL); - ok(info.stop != NULL, "CreateEvent failed with error %d\n", GetLastError()); - - thread = CreateThread(NULL, 0, ole_initialize_thread, &info, 0, &tid); - ok(thread != NULL, "CreateThread failed with error %d\n", GetLastError()); - - ok( !WaitForSingleObject(info.wait, 10000), "wait timed out\n" ); - - test_apt_type(APTTYPE_MTA, APTTYPEQUALIFIER_IMPLICIT_MTA, TRUE, TRUE); - - pUnk = (IUnknown *)0xdeadbeef; - hr = CoGetClassObject(rclsid, CLSCTX_INPROC_SERVER, NULL, &IID_IUnknown, (void **)&pUnk); - if(hr == REGDB_E_CLASSNOTREG) - skip("IE not installed so can't test CoGetClassObject\n"); - else - { - ok(hr == S_OK, "CoGetClassObject should have returned S_OK instead of 0x%08x\n", hr); - if (pUnk) IUnknown_Release(pUnk); - } - - SetEvent(info.stop); - ok( !WaitForSingleObject(thread, 10000), "wait timed out\n" ); - - GetExitCodeThread(thread, &exitcode); - hr = exitcode; - ok(hr == S_OK, "thread should have returned S_OK instead of 0x%08x\n", hr); - - CloseHandle(thread); - CloseHandle(info.wait); - CloseHandle(info.stop); - test_apt_type(APTTYPE_CURRENT, APTTYPEQUALIFIER_NONE, FALSE, FALSE); if (!pRegOverridePredefKey) @@ -1880,9 +1783,6 @@ static void test_CoGetObjectContext(void) IObjContext *pObjContext; APTTYPE apttype; THDTYPE thdtype; - struct info info; - HANDLE thread; - DWORD tid, exitcode; GUID id, id2; if (!pCoGetObjectContext) @@ -1895,27 +1795,12 @@ static void test_CoGetObjectContext(void) ok(hr == CO_E_NOTINITIALIZED, "CoGetObjectContext should have returned CO_E_NOTINITIALIZED instead of 0x%08x\n", hr); ok(pComThreadingInfo == NULL, "pComThreadingInfo should have been set to NULL\n"); - /* show that COM doesn't have to be initialized for multi-threaded apartments if another - thread has already done so */ + pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED); - test_apt_type(APTTYPE_CURRENT, APTTYPEQUALIFIER_NONE, FALSE, FALSE); + test_apt_type(APTTYPE_MAINSTA, APTTYPEQUALIFIER_NONE, FALSE, FALSE); - info.wait = CreateEventA(NULL, TRUE, FALSE, NULL); - ok(info.wait != NULL, "CreateEvent failed with error %d\n", GetLastError()); - - info.stop = CreateEventA(NULL, TRUE, FALSE, NULL); - ok(info.stop != NULL, "CreateEvent failed with error %d\n", GetLastError()); - - thread = CreateThread(NULL, 0, ole_initialize_thread, &info, 0, &tid); - ok(thread != NULL, "CreateThread failed with error %d\n", GetLastError()); - - ok( !WaitForSingleObject(info.wait, 10000), "wait timed out\n" ); - - test_apt_type(APTTYPE_MTA, APTTYPEQUALIFIER_IMPLICIT_MTA, TRUE, TRUE); - - pComThreadingInfo = NULL; hr = pCoGetObjectContext(&IID_IComThreadingInfo, (void **)&pComThreadingInfo); - ok(hr == S_OK, "Expected S_OK, got 0x%08x\n", hr); + ok_ole_success(hr, "CoGetObjectContext"); threadinginfo2 = NULL; hr = pCoGetObjectContext(&IID_IComThreadingInfo, (void **)&threadinginfo2); @@ -1933,28 +1818,6 @@ static void test_CoGetObjectContext(void) hr = CoGetCurrentLogicalThreadId(&id2); ok(IsEqualGUID(&id, &id2), "got %s, expected %s\n", wine_dbgstr_guid(&id), wine_dbgstr_guid(&id2)); - IComThreadingInfo_Release(pComThreadingInfo); - - SetEvent(info.stop); - ok( !WaitForSingleObject(thread, 10000), "wait timed out\n" ); - - GetExitCodeThread(thread, &exitcode); - hr = exitcode; - ok(hr == S_OK, "thread should have returned S_OK instead of 0x%08x\n", hr); - - CloseHandle(thread); - CloseHandle(info.wait); - CloseHandle(info.stop); - - test_apt_type(APTTYPE_CURRENT, APTTYPEQUALIFIER_NONE, FALSE, FALSE); - - pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED); - - test_apt_type(APTTYPE_MAINSTA, APTTYPEQUALIFIER_NONE, FALSE, FALSE); - - hr = pCoGetObjectContext(&IID_IComThreadingInfo, (void **)&pComThreadingInfo); - ok_ole_success(hr, "CoGetObjectContext"); - hr = IComThreadingInfo_GetCurrentApartmentType(pComThreadingInfo, &apttype); ok_ole_success(hr, "IComThreadingInfo_GetCurrentApartmentType"); ok(apttype == APTTYPE_MAINSTA, "apartment type should be APTTYPE_MAINSTA instead of %d\n", apttype); @@ -2118,9 +1981,6 @@ static void test_CoGetContextToken(void) ULONG refs; ULONG_PTR token, token2; IObjContext *ctx; - struct info info; - HANDLE thread; - DWORD tid, exitcode; if (!pCoGetContextToken) { @@ -2133,44 +1993,6 @@ static void test_CoGetContextToken(void) ok(hr == CO_E_NOTINITIALIZED, "Expected CO_E_NOTINITIALIZED, got 0x%08x\n", hr); ok(token == 0xdeadbeef, "Expected 0, got 0x%lx\n", token); - /* show that COM doesn't have to be initialized for multi-threaded apartments if another - thread has already done so */ - - test_apt_type(APTTYPE_CURRENT, APTTYPEQUALIFIER_NONE, FALSE, FALSE); - - info.wait = CreateEventA(NULL, TRUE, FALSE, NULL); - ok(info.wait != NULL, "CreateEvent failed with error %d\n", GetLastError()); - - info.stop = CreateEventA(NULL, TRUE, FALSE, NULL); - ok(info.stop != NULL, "CreateEvent failed with error %d\n", GetLastError()); - - thread = CreateThread(NULL, 0, ole_initialize_thread, &info, 0, &tid); - ok(thread != NULL, "CreateThread failed with error %d\n", GetLastError()); - - ok( !WaitForSingleObject(info.wait, 10000), "wait timed out\n" ); - - test_apt_type(APTTYPE_MTA, APTTYPEQUALIFIER_IMPLICIT_MTA, TRUE, TRUE); - - token = 0; - hr = pCoGetContextToken(&token); - ok(hr == S_OK, "Expected S_OK, got 0x%08x\n", hr); - - token2 = 0; - hr = pCoGetContextToken(&token2); - ok(hr == S_OK, "Expected S_OK, got 0x%08x\n", hr); - ok(token == token2, "got different token\n"); - - SetEvent(info.stop); - ok( !WaitForSingleObject(thread, 10000), "wait timed out\n" ); - - GetExitCodeThread(thread, &exitcode); - hr = exitcode; - ok(hr == S_OK, "thread should have returned S_OK instead of 0x%08x\n", hr); - - CloseHandle(thread); - CloseHandle(info.wait); - CloseHandle(info.stop); - test_apt_type(APTTYPE_CURRENT, APTTYPEQUALIFIER_NONE, FALSE, FALSE); CoInitialize(NULL); @@ -3874,6 +3696,47 @@ static void init_funcs(void) pReleaseActCtx = (void*)GetProcAddress(hkernel32, "ReleaseActCtx"); } +static DWORD CALLBACK implicit_mta_proc(void *param) +{ + IComThreadingInfo *threading_info; + ULONG_PTR token; + IUnknown *unk; + HRESULT hr; + + test_apt_type(APTTYPE_MTA, APTTYPEQUALIFIER_IMPLICIT_MTA, TRUE, TRUE); + + hr = CoCreateInstance(&CLSID_InternetZoneManager, NULL, CLSCTX_INPROC_SERVER, &IID_IUnknown, (void **)&unk); + ok_ole_success(hr, "CoCreateInstance"); + IUnknown_Release(unk); + + hr = CoGetClassObject(&CLSID_InternetZoneManager, CLSCTX_INPROC_SERVER, NULL, &IID_IUnknown, (void **)&unk); + ok_ole_success(hr, "CoGetClassObject"); + IUnknown_Release(unk); + + hr = CoGetObjectContext(&IID_IComThreadingInfo, (void **)&threading_info); + ok_ole_success(hr, "CoGetObjectContext"); + IComThreadingInfo_Release(threading_info); + + hr = CoGetContextToken(&token); + ok_ole_success(hr, "CoGetContextToken"); + + return 0; +} + +/* Some COM functions (perhaps even all of them?) can make use of an "implicit" + * multi-threaded apartment created by another thread in the same process. */ +static void test_implicit_mta(void) +{ + HANDLE thread; + + CoInitializeEx(NULL, COINIT_MULTITHREADED); + + thread = CreateThread(NULL, 0, implicit_mta_proc, NULL, 0, NULL); + ok(!WaitForSingleObject(thread, 1000), "wait failed\n"); + + CoUninitialize(); +} + START_TEST(compobj) { init_funcs(); @@ -3923,4 +3786,5 @@ START_TEST(compobj) test_IInitializeSpy(); test_CoGetInstanceFromFile(); test_GlobalOptions(); + test_implicit_mta(); }