Commit b46eafe3 authored by Paul Gofman's avatar Paul Gofman Committed by Alexandre Julliard

combase: Ensure MTA existence in RoGetActivationFactory().

parent 2f1b288a
...@@ -1157,6 +1157,11 @@ void leave_apartment(struct tlsdata *data) ...@@ -1157,6 +1157,11 @@ void leave_apartment(struct tlsdata *data)
if (data->ole_inits) if (data->ole_inits)
WARN( "Uninitializing apartment while Ole is still initialized\n" ); WARN( "Uninitializing apartment while Ole is still initialized\n" );
apartment_release(data->apt); 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->apt = NULL;
data->flags &= ~(OLETLS_DISABLE_OLE1DDE | OLETLS_APARTMENTTHREADED | OLETLS_MULTITHREADED); data->flags &= ~(OLETLS_DISABLE_OLE1DDE | OLETLS_APARTMENTTHREADED | OLETLS_MULTITHREADED);
} }
...@@ -1288,3 +1293,29 @@ void apartment_global_cleanup(void) ...@@ -1288,3 +1293,29 @@ void apartment_global_cleanup(void)
apartment_release_dlls(); apartment_release_dlls();
DeleteCriticalSection(&apt_cs); 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;
}
...@@ -407,6 +407,9 @@ static void com_cleanup_tlsdata(void) ...@@ -407,6 +407,9 @@ static void com_cleanup_tlsdata(void)
if (tlsdata->apt) if (tlsdata->apt)
apartment_release(tlsdata->apt); apartment_release(tlsdata->apt);
if (tlsdata->implicit_mta_cookie)
apartment_decrement_mta_usage(tlsdata->implicit_mta_cookie);
if (tlsdata->errorinfo) if (tlsdata->errorinfo)
IErrorInfo_Release(tlsdata->errorinfo); IErrorInfo_Release(tlsdata->errorinfo);
if (tlsdata->state) if (tlsdata->state)
......
...@@ -92,6 +92,7 @@ struct tlsdata ...@@ -92,6 +92,7 @@ struct tlsdata
struct list spies; /* Spies installed with CoRegisterInitializeSpy */ struct list spies; /* Spies installed with CoRegisterInitializeSpy */
DWORD spies_lock; DWORD spies_lock;
DWORD cancelcount; DWORD cancelcount;
CO_MTA_USAGE_COOKIE implicit_mta_cookie; /* mta referenced by roapi from sta thread */
}; };
extern HRESULT WINAPI InternalTlsAllocData(struct tlsdata **data); extern HRESULT WINAPI InternalTlsAllocData(struct tlsdata **data);
...@@ -161,6 +162,7 @@ void apartment_release(struct apartment *apt); ...@@ -161,6 +162,7 @@ void apartment_release(struct apartment *apt);
struct apartment * apartment_get_current_or_mta(void); struct apartment * apartment_get_current_or_mta(void);
HRESULT apartment_increment_mta_usage(CO_MTA_USAGE_COOKIE *cookie); HRESULT apartment_increment_mta_usage(CO_MTA_USAGE_COOKIE *cookie);
void apartment_decrement_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); struct apartment * apartment_get_mta(void);
HRESULT apartment_get_inproc_class_object(struct apartment *apt, const struct class_reg_data *regdata, HRESULT apartment_get_inproc_class_object(struct apartment *apt, const struct class_reg_data *regdata,
REFCLSID rclsid, REFIID riid, DWORD class_context, void **ppv); REFCLSID rclsid, REFIID riid, DWORD class_context, void **ppv);
......
...@@ -24,6 +24,8 @@ ...@@ -24,6 +24,8 @@
#include "roerrorapi.h" #include "roerrorapi.h"
#include "winstring.h" #include "winstring.h"
#include "combase_private.h"
#include "wine/debug.h" #include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(combase); WINE_DEFAULT_DEBUG_CHANNEL(combase);
...@@ -154,6 +156,9 @@ HRESULT WINAPI RoGetActivationFactory(HSTRING classid, REFIID iid, void **class_ ...@@ -154,6 +156,9 @@ HRESULT WINAPI RoGetActivationFactory(HSTRING classid, REFIID iid, void **class_
if (!iid || !class_factory) if (!iid || !class_factory)
return E_INVALIDARG; return E_INVALIDARG;
if (FAILED(hr = ensure_mta()))
return hr;
hr = get_library_for_classid(WindowsGetStringRawBuffer(classid, NULL), &library); hr = get_library_for_classid(WindowsGetStringRawBuffer(classid, NULL), &library);
if (FAILED(hr)) if (FAILED(hr))
{ {
......
...@@ -211,7 +211,7 @@ static void test_implicit_mta(void) ...@@ -211,7 +211,7 @@ static void test_implicit_mta(void)
ok(hr == S_OK, "got %#lx.\n", hr); ok(hr == S_OK, "got %#lx.\n", hr);
/* RoGetActivationFactory doesn't implicitly initialize COM. */ /* RoGetActivationFactory doesn't implicitly initialize COM. */
hr = RoGetActivationFactory(str, &IID_IActivationFactory, (void **)&factory); 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); check_thread_apartment(CO_E_NOTINITIALIZED);
...@@ -227,10 +227,10 @@ static void test_implicit_mta(void) ...@@ -227,10 +227,10 @@ static void test_implicit_mta(void)
check_thread_apartment(tests[i].mta ? S_OK : CO_E_NOTINITIALIZED); check_thread_apartment(tests[i].mta ? S_OK : CO_E_NOTINITIALIZED);
hr = RoGetActivationFactory(str, &IID_IActivationFactory, (void **)&factory); hr = RoGetActivationFactory(str, &IID_IActivationFactory, (void **)&factory);
ok(hr == REGDB_E_CLASSNOTREG, "got %#lx.\n", hr); 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); hr = RoGetActivationFactory(str, &IID_IActivationFactory, (void **)&factory);
ok(hr == REGDB_E_CLASSNOTREG, "got %#lx.\n", hr); 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) if (tests[i].ro_init)
RoUninitialize(); RoUninitialize();
else else
...@@ -270,7 +270,7 @@ static void test_implicit_mta(void) ...@@ -270,7 +270,7 @@ static void test_implicit_mta(void)
SetEvent(mta_init_thread_done_event); SetEvent(mta_init_thread_done_event);
WaitForSingleObject(thread, INFINITE); WaitForSingleObject(thread, INFINITE);
CloseHandle(thread); CloseHandle(thread);
todo_wine check_thread_apartment_broken(S_OK); /* Broken on Win8. */ check_thread_apartment_broken(S_OK); /* Broken on Win8. */
CoUninitialize(); CoUninitialize();
check_thread_apartment(CO_E_NOTINITIALIZED); check_thread_apartment(CO_E_NOTINITIALIZED);
...@@ -292,7 +292,7 @@ static void test_implicit_mta(void) ...@@ -292,7 +292,7 @@ static void test_implicit_mta(void)
SetEvent(mta_init_thread_done_event); SetEvent(mta_init_thread_done_event);
WaitForSingleObject(thread, INFINITE); WaitForSingleObject(thread, INFINITE);
CloseHandle(thread); CloseHandle(thread);
todo_wine check_thread_apartment_broken(S_OK); /* Broken on Win8. */ check_thread_apartment_broken(S_OK); /* Broken on Win8. */
CoUninitialize(); CoUninitialize();
check_thread_apartment(CO_E_NOTINITIALIZED); check_thread_apartment(CO_E_NOTINITIALIZED);
...@@ -300,7 +300,7 @@ static void test_implicit_mta(void) ...@@ -300,7 +300,7 @@ static void test_implicit_mta(void)
thread = CreateThread(NULL, 0, mta_init_implicit_thread, NULL, 0, NULL); thread = CreateThread(NULL, 0, mta_init_implicit_thread, NULL, 0, NULL);
ok(!!thread, "failed.\n"); ok(!!thread, "failed.\n");
WaitForSingleObject(mta_init_thread_init_done_event, INFINITE); 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); SetEvent(mta_init_thread_done_event);
WaitForSingleObject(thread, INFINITE); WaitForSingleObject(thread, INFINITE);
CloseHandle(thread); CloseHandle(thread);
......
...@@ -63,6 +63,7 @@ struct oletls ...@@ -63,6 +63,7 @@ struct oletls
struct list spies; /* Spies installed with CoRegisterInitializeSpy */ struct list spies; /* Spies installed with CoRegisterInitializeSpy */
DWORD spies_lock; DWORD spies_lock;
DWORD cancelcount; DWORD cancelcount;
CO_MTA_USAGE_COOKIE implicit_mta_cookie; /* mta referenced by roapi from sta thread */
}; };
/* Global Interface Table Functions */ /* Global Interface Table Functions */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment