Skip to content
Snippets Groups Projects
Commit bd4975ac authored by Hans Leidekker's avatar Hans Leidekker Committed by Alexandre Julliard
Browse files

ole32: Use existing MTA in CoGetClassObject and CoCreateInstance.

Custom actions in the CS3 installer depend on this.
parent d2820c06
No related branches found
No related tags found
No related merge requests found
......@@ -493,6 +493,31 @@ static APARTMENT *apartment_findmain(void)
return result;
}
/* gets the multi-threaded apartment if it exists. The caller must
* release the reference from the apartment as soon as the apartment pointer
* is no longer required. */
static APARTMENT *apartment_find_multi_threaded(void)
{
APARTMENT *result = NULL;
struct list *cursor;
EnterCriticalSection(&csApartment);
LIST_FOR_EACH( cursor, &apts )
{
struct apartment *apt = LIST_ENTRY( cursor, struct apartment, entry );
if (apt->multi_threaded)
{
result = apt;
apartment_addref(result);
break;
}
}
LeaveCriticalSection(&csApartment);
return result;
}
struct host_object_params
{
HKEY hkeydll;
......@@ -2237,6 +2262,7 @@ HRESULT WINAPI CoGetClassObject(
LPUNKNOWN regClassObject;
HRESULT hres = E_UNEXPECTED;
APARTMENT *apt;
BOOL release_apt = FALSE;
TRACE("\n\tCLSID:\t%s,\n\tIID:\t%s\n", debugstr_guid(rclsid), debugstr_guid(iid));
......@@ -2245,11 +2271,14 @@ HRESULT WINAPI CoGetClassObject(
*ppv = NULL;
apt = COM_CurrentApt();
if (!apt)
if (!(apt = COM_CurrentApt()))
{
ERR("apartment not initialised\n");
return CO_E_NOTINITIALIZED;
if (!(apt = apartment_find_multi_threaded()))
{
ERR("apartment not initialised\n");
return CO_E_NOTINITIALIZED;
}
release_apt = TRUE;
}
if (pServerInfo) {
......@@ -2273,7 +2302,7 @@ HRESULT WINAPI CoGetClassObject(
* is good since we are not returning it in the "out" parameter.
*/
IUnknown_Release(regClassObject);
if (release_apt) apartment_release(apt);
return hres;
}
......@@ -2284,7 +2313,10 @@ HRESULT WINAPI CoGetClassObject(
HKEY hkey;
if (IsEqualCLSID(rclsid, &CLSID_InProcFreeMarshaler))
{
if (release_apt) apartment_release(apt);
return FTMarshalCF_Create(iid, ppv);
}
hres = COM_OpenKeyForCLSID(rclsid, wszInprocServer32, KEY_READ, &hkey);
if (FAILED(hres))
......@@ -2308,7 +2340,10 @@ HRESULT WINAPI CoGetClassObject(
/* return if we got a class, otherwise fall through to one of the
* other types */
if (SUCCEEDED(hres))
{
if (release_apt) apartment_release(apt);
return hres;
}
}
/* Next try in-process handler */
......@@ -2339,8 +2374,12 @@ HRESULT WINAPI CoGetClassObject(
/* return if we got a class, otherwise fall through to one of the
* other types */
if (SUCCEEDED(hres))
{
if (release_apt) apartment_release(apt);
return hres;
}
}
if (release_apt) apartment_release(apt);
/* Next try out of process */
if (CLSCTX_LOCAL_SERVER & dwClsContext)
......@@ -2418,6 +2457,7 @@ HRESULT WINAPI CoCreateInstance(
{
HRESULT hres;
LPCLASSFACTORY lpclf = 0;
APARTMENT *apt;
TRACE("(rclsid=%s, pUnkOuter=%p, dwClsContext=%08x, riid=%s, ppv=%p)\n", debugstr_guid(rclsid),
pUnkOuter, dwClsContext, debugstr_guid(iid), ppv);
......@@ -2433,10 +2473,14 @@ HRESULT WINAPI CoCreateInstance(
*/
*ppv = 0;
if (!COM_CurrentApt())
if (!(apt = COM_CurrentApt()))
{
if (!(apt = apartment_find_multi_threaded()))
{
ERR("apartment not initialised\n");
return CO_E_NOTINITIALIZED;
}
apartment_release(apt);
}
/*
......
......@@ -276,7 +276,7 @@ static void test_CoCreateInstance(void)
pUnk = (IUnknown *)0xdeadbeef;
hr = CoCreateInstance(rclsid, NULL, CLSCTX_INPROC_SERVER, &IID_IUnknown, (void **)&pUnk);
todo_wine ok(hr == S_OK, "CoCreateInstance should have returned S_OK instead of 0x%08x\n", hr);
ok(hr == S_OK, "CoCreateInstance should have returned S_OK instead of 0x%08x\n", hr);
if (pUnk) IUnknown_Release(pUnk);
SetEvent(info.stop);
......@@ -325,7 +325,7 @@ static void test_CoGetClassObject(void)
pUnk = (IUnknown *)0xdeadbeef;
hr = CoGetClassObject(rclsid, CLSCTX_INPROC_SERVER, NULL, &IID_IUnknown, (void **)&pUnk);
todo_wine ok(hr == S_OK, "CoGetClassObject should have returned S_OK instead of 0x%08x\n", hr);
ok(hr == S_OK, "CoGetClassObject should have returned S_OK instead of 0x%08x\n", hr);
if (pUnk) IUnknown_Release(pUnk);
SetEvent(info.stop);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment