ole32: Use existing MTA in CoGetContextToken and CoGetObjectContext.
Hans Leidekker
hans at codeweavers.com
Fri Jul 3 04:32:08 CDT 2009
Should fix http://bugs.winehq.org/show_bug.cgi?id=19157
-Hans
diff --git a/dlls/ole32/compobj.c b/dlls/ole32/compobj.c
index 739c86d..7403b95 100644
--- a/dlls/ole32/compobj.c
+++ b/dlls/ole32/compobj.c
@@ -4050,8 +4050,12 @@ HRESULT WINAPI CoGetObjectContext(REFIID riid, void **ppv)
*ppv = NULL;
if (!apt)
{
- ERR("apartment not initialised\n");
- return CO_E_NOTINITIALIZED;
+ if (!(apt = apartment_find_multi_threaded()))
+ {
+ ERR("apartment not initialised\n");
+ return CO_E_NOTINITIALIZED;
+ }
+ apartment_release(apt);
}
context = HeapAlloc(GetProcessHeap(), 0, sizeof(*context));
@@ -4089,7 +4093,15 @@ HRESULT WINAPI CoGetContextToken( ULONG_PTR *token )
return E_OUTOFMEMORY;
if (!info->apt)
- return CO_E_NOTINITIALIZED;
+ {
+ APARTMENT *apt;
+ if (!(apt = apartment_find_multi_threaded()))
+ {
+ ERR("apartment not initialised\n");
+ return CO_E_NOTINITIALIZED;
+ }
+ apartment_release(apt);
+ }
if (!token)
return E_POINTER;
diff --git a/dlls/ole32/tests/compobj.c b/dlls/ole32/tests/compobj.c
index ff2462f..1435984 100644
--- a/dlls/ole32/tests/compobj.c
+++ b/dlls/ole32/tests/compobj.c
@@ -1082,6 +1082,9 @@ static void test_CoGetObjectContext(void)
IObjContext *pObjContext;
APTTYPE apttype;
THDTYPE thdtype;
+ struct info info;
+ HANDLE thread;
+ DWORD tid, exitcode;
if (!pCoGetObjectContext)
{
@@ -1093,6 +1096,36 @@ 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 */
+
+ info.wait = CreateEvent(NULL, TRUE, FALSE, NULL);
+ ok(info.wait != NULL, "CreateEvent failed with error %d\n", GetLastError());
+
+ info.stop = CreateEvent(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());
+
+ WaitForSingleObject(info.wait, INFINITE);
+
+ pComThreadingInfo = NULL;
+ hr = pCoGetObjectContext(&IID_IComThreadingInfo, (void **)&pComThreadingInfo);
+ ok(hr == S_OK, "Expected S_OK, got 0x%08x\n", hr);
+ IComThreadingInfo_Release(pComThreadingInfo);
+
+ SetEvent(info.stop);
+ WaitForSingleObject(thread, INFINITE);
+
+ 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);
+
pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
hr = pCoGetObjectContext(&IID_IComThreadingInfo, (void **)&pComThreadingInfo);
@@ -1260,6 +1293,9 @@ static void test_CoGetContextToken(void)
ULONG refs;
ULONG_PTR token;
IObjContext *ctx;
+ struct info info;
+ HANDLE thread;
+ DWORD tid, exitcode;
if (!pCoGetContextToken)
{
@@ -1272,6 +1308,36 @@ 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 */
+
+ info.wait = CreateEvent(NULL, TRUE, FALSE, NULL);
+ ok(info.wait != NULL, "CreateEvent failed with error %d\n", GetLastError());
+
+ info.stop = CreateEvent(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());
+
+ WaitForSingleObject(info.wait, INFINITE);
+
+ token = 0;
+ hr = pCoGetContextToken(&token);
+ ok(hr == S_OK, "Expected S_OK, got 0x%08x\n", hr);
+ IUnknown_Release((IUnknown *)token);
+
+ SetEvent(info.stop);
+ WaitForSingleObject(thread, INFINITE);
+
+ 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);
+
CoInitialize(NULL);
hr = pCoGetContextToken(NULL);
@@ -1283,10 +1349,10 @@ static void test_CoGetContextToken(void)
ok(token, "Expected token != 0\n");
refs = IUnknown_AddRef((IUnknown *)token);
- todo_wine ok(refs == 1, "Expected 1, got %u\n", refs);
+ ok(refs == 1, "Expected 1, got %u\n", refs);
refs = IUnknown_Release((IUnknown *)token);
- todo_wine ok(refs == 0, "Expected 0, got %u\n", refs);
+ ok(refs == 0, "Expected 0, got %u\n", refs);
hr = pCoGetObjectContext(&IID_IObjContext, (void **)&ctx);
ok(hr == S_OK, "Expected S_OK, got 0x%08x\n", hr);
More information about the wine-patches
mailing list