ole32: Use existing MTA in CoGetContextToken and CoGetObjectContext.
This commit is contained in:
parent
44db8883f8
commit
6986d97f18
|
@ -4049,10 +4049,14 @@ HRESULT WINAPI CoGetObjectContext(REFIID riid, void **ppv)
|
||||||
|
|
||||||
*ppv = NULL;
|
*ppv = NULL;
|
||||||
if (!apt)
|
if (!apt)
|
||||||
|
{
|
||||||
|
if (!(apt = apartment_find_multi_threaded()))
|
||||||
{
|
{
|
||||||
ERR("apartment not initialised\n");
|
ERR("apartment not initialised\n");
|
||||||
return CO_E_NOTINITIALIZED;
|
return CO_E_NOTINITIALIZED;
|
||||||
}
|
}
|
||||||
|
apartment_release(apt);
|
||||||
|
}
|
||||||
|
|
||||||
context = HeapAlloc(GetProcessHeap(), 0, sizeof(*context));
|
context = HeapAlloc(GetProcessHeap(), 0, sizeof(*context));
|
||||||
if (!context)
|
if (!context)
|
||||||
|
@ -4089,7 +4093,15 @@ HRESULT WINAPI CoGetContextToken( ULONG_PTR *token )
|
||||||
return E_OUTOFMEMORY;
|
return E_OUTOFMEMORY;
|
||||||
|
|
||||||
if (!info->apt)
|
if (!info->apt)
|
||||||
|
{
|
||||||
|
APARTMENT *apt;
|
||||||
|
if (!(apt = apartment_find_multi_threaded()))
|
||||||
|
{
|
||||||
|
ERR("apartment not initialised\n");
|
||||||
return CO_E_NOTINITIALIZED;
|
return CO_E_NOTINITIALIZED;
|
||||||
|
}
|
||||||
|
apartment_release(apt);
|
||||||
|
}
|
||||||
|
|
||||||
if (!token)
|
if (!token)
|
||||||
return E_POINTER;
|
return E_POINTER;
|
||||||
|
|
|
@ -1082,6 +1082,9 @@ static void test_CoGetObjectContext(void)
|
||||||
IObjContext *pObjContext;
|
IObjContext *pObjContext;
|
||||||
APTTYPE apttype;
|
APTTYPE apttype;
|
||||||
THDTYPE thdtype;
|
THDTYPE thdtype;
|
||||||
|
struct info info;
|
||||||
|
HANDLE thread;
|
||||||
|
DWORD tid, exitcode;
|
||||||
|
|
||||||
if (!pCoGetObjectContext)
|
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(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");
|
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);
|
pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
|
||||||
|
|
||||||
hr = pCoGetObjectContext(&IID_IComThreadingInfo, (void **)&pComThreadingInfo);
|
hr = pCoGetObjectContext(&IID_IComThreadingInfo, (void **)&pComThreadingInfo);
|
||||||
|
@ -1260,6 +1293,9 @@ static void test_CoGetContextToken(void)
|
||||||
ULONG refs;
|
ULONG refs;
|
||||||
ULONG_PTR token;
|
ULONG_PTR token;
|
||||||
IObjContext *ctx;
|
IObjContext *ctx;
|
||||||
|
struct info info;
|
||||||
|
HANDLE thread;
|
||||||
|
DWORD tid, exitcode;
|
||||||
|
|
||||||
if (!pCoGetContextToken)
|
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(hr == CO_E_NOTINITIALIZED, "Expected CO_E_NOTINITIALIZED, got 0x%08x\n", hr);
|
||||||
ok(token == 0xdeadbeef, "Expected 0, got 0x%lx\n", token);
|
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);
|
CoInitialize(NULL);
|
||||||
|
|
||||||
hr = pCoGetContextToken(NULL);
|
hr = pCoGetContextToken(NULL);
|
||||||
|
@ -1283,10 +1349,10 @@ static void test_CoGetContextToken(void)
|
||||||
ok(token, "Expected token != 0\n");
|
ok(token, "Expected token != 0\n");
|
||||||
|
|
||||||
refs = IUnknown_AddRef((IUnknown *)token);
|
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);
|
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);
|
hr = pCoGetObjectContext(&IID_IObjContext, (void **)&ctx);
|
||||||
ok(hr == S_OK, "Expected S_OK, got 0x%08x\n", hr);
|
ok(hr == S_OK, "Expected S_OK, got 0x%08x\n", hr);
|
||||||
|
|
Loading…
Reference in New Issue