combase: Ensure MTA existence in RoGetActivationFactory().

This commit is contained in:
Paul Gofman 2023-09-12 12:53:27 -06:00 committed by Alexandre Julliard
parent 2f1b288a3f
commit b46eafe3d2
6 changed files with 48 additions and 6 deletions

View file

@ -1157,6 +1157,11 @@ void leave_apartment(struct tlsdata *data)
if (data->ole_inits)
WARN( "Uninitializing apartment while Ole is still initialized\n" );
apartment_release(data->apt);
if (data->implicit_mta_cookie)
{
apartment_decrement_mta_usage(data->implicit_mta_cookie);
data->implicit_mta_cookie = NULL;
}
data->apt = NULL;
data->flags &= ~(OLETLS_DISABLE_OLE1DDE | OLETLS_APARTMENTTHREADED | OLETLS_MULTITHREADED);
}
@ -1288,3 +1293,29 @@ void apartment_global_cleanup(void)
apartment_release_dlls();
DeleteCriticalSection(&apt_cs);
}
HRESULT ensure_mta(void)
{
struct apartment *apt;
struct tlsdata *data;
HRESULT hr;
if (FAILED(hr = com_get_tlsdata(&data)))
return hr;
if ((apt = data->apt) && (data->implicit_mta_cookie || apt->multi_threaded))
return S_OK;
EnterCriticalSection(&apt_cs);
if (apt || mta)
hr = apartment_increment_mta_usage(&data->implicit_mta_cookie);
else
hr = CO_E_NOTINITIALIZED;
LeaveCriticalSection(&apt_cs);
if (FAILED(hr))
{
ERR("Failed, hr %#lx.\n", hr);
return hr;
}
return S_OK;
}

View file

@ -407,6 +407,9 @@ static void com_cleanup_tlsdata(void)
if (tlsdata->apt)
apartment_release(tlsdata->apt);
if (tlsdata->implicit_mta_cookie)
apartment_decrement_mta_usage(tlsdata->implicit_mta_cookie);
if (tlsdata->errorinfo)
IErrorInfo_Release(tlsdata->errorinfo);
if (tlsdata->state)

View file

@ -92,6 +92,7 @@ struct tlsdata
struct list spies; /* Spies installed with CoRegisterInitializeSpy */
DWORD spies_lock;
DWORD cancelcount;
CO_MTA_USAGE_COOKIE implicit_mta_cookie; /* mta referenced by roapi from sta thread */
};
extern HRESULT WINAPI InternalTlsAllocData(struct tlsdata **data);
@ -161,6 +162,7 @@ void apartment_release(struct apartment *apt);
struct apartment * apartment_get_current_or_mta(void);
HRESULT apartment_increment_mta_usage(CO_MTA_USAGE_COOKIE *cookie);
void apartment_decrement_mta_usage(CO_MTA_USAGE_COOKIE cookie);
HRESULT ensure_mta(void);
struct apartment * apartment_get_mta(void);
HRESULT apartment_get_inproc_class_object(struct apartment *apt, const struct class_reg_data *regdata,
REFCLSID rclsid, REFIID riid, DWORD class_context, void **ppv);

View file

@ -24,6 +24,8 @@
#include "roerrorapi.h"
#include "winstring.h"
#include "combase_private.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(combase);
@ -154,6 +156,9 @@ HRESULT WINAPI RoGetActivationFactory(HSTRING classid, REFIID iid, void **class_
if (!iid || !class_factory)
return E_INVALIDARG;
if (FAILED(hr = ensure_mta()))
return hr;
hr = get_library_for_classid(WindowsGetStringRawBuffer(classid, NULL), &library);
if (FAILED(hr))
{

View file

@ -211,7 +211,7 @@ static void test_implicit_mta(void)
ok(hr == S_OK, "got %#lx.\n", hr);
/* RoGetActivationFactory doesn't implicitly initialize COM. */
hr = RoGetActivationFactory(str, &IID_IActivationFactory, (void **)&factory);
todo_wine ok(hr == CO_E_NOTINITIALIZED, "got %#lx.\n", hr);
ok(hr == CO_E_NOTINITIALIZED, "got %#lx.\n", hr);
check_thread_apartment(CO_E_NOTINITIALIZED);
@ -227,10 +227,10 @@ static void test_implicit_mta(void)
check_thread_apartment(tests[i].mta ? S_OK : CO_E_NOTINITIALIZED);
hr = RoGetActivationFactory(str, &IID_IActivationFactory, (void **)&factory);
ok(hr == REGDB_E_CLASSNOTREG, "got %#lx.\n", hr);
todo_wine_if(!tests[i].mta) check_thread_apartment_broken(S_OK); /* Broken on Win8. */
check_thread_apartment_broken(S_OK); /* Broken on Win8. */
hr = RoGetActivationFactory(str, &IID_IActivationFactory, (void **)&factory);
ok(hr == REGDB_E_CLASSNOTREG, "got %#lx.\n", hr);
todo_wine_if(!tests[i].mta) check_thread_apartment_broken(S_OK); /* Broken on Win8. */
check_thread_apartment_broken(S_OK); /* Broken on Win8. */
if (tests[i].ro_init)
RoUninitialize();
else
@ -270,7 +270,7 @@ static void test_implicit_mta(void)
SetEvent(mta_init_thread_done_event);
WaitForSingleObject(thread, INFINITE);
CloseHandle(thread);
todo_wine check_thread_apartment_broken(S_OK); /* Broken on Win8. */
check_thread_apartment_broken(S_OK); /* Broken on Win8. */
CoUninitialize();
check_thread_apartment(CO_E_NOTINITIALIZED);
@ -292,7 +292,7 @@ static void test_implicit_mta(void)
SetEvent(mta_init_thread_done_event);
WaitForSingleObject(thread, INFINITE);
CloseHandle(thread);
todo_wine check_thread_apartment_broken(S_OK); /* Broken on Win8. */
check_thread_apartment_broken(S_OK); /* Broken on Win8. */
CoUninitialize();
check_thread_apartment(CO_E_NOTINITIALIZED);
@ -300,7 +300,7 @@ static void test_implicit_mta(void)
thread = CreateThread(NULL, 0, mta_init_implicit_thread, NULL, 0, NULL);
ok(!!thread, "failed.\n");
WaitForSingleObject(mta_init_thread_init_done_event, INFINITE);
todo_wine check_thread_apartment_broken(S_OK); /* Broken on Win8. */
check_thread_apartment_broken(S_OK); /* Broken on Win8. */
SetEvent(mta_init_thread_done_event);
WaitForSingleObject(thread, INFINITE);
CloseHandle(thread);

View file

@ -63,6 +63,7 @@ struct oletls
struct list spies; /* Spies installed with CoRegisterInitializeSpy */
DWORD spies_lock;
DWORD cancelcount;
CO_MTA_USAGE_COOKIE implicit_mta_cookie; /* mta referenced by roapi from sta thread */
};
/* Global Interface Table Functions */