ole32: Use existing MTA in CoGetClassObject and CoCreateInstance.
Custom actions in the CS3 installer depend on this.
This commit is contained in:
parent
d2820c0684
commit
bd4975acb0
|
@ -493,6 +493,31 @@ static APARTMENT *apartment_findmain(void)
|
||||||
return result;
|
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
|
struct host_object_params
|
||||||
{
|
{
|
||||||
HKEY hkeydll;
|
HKEY hkeydll;
|
||||||
|
@ -2237,6 +2262,7 @@ HRESULT WINAPI CoGetClassObject(
|
||||||
LPUNKNOWN regClassObject;
|
LPUNKNOWN regClassObject;
|
||||||
HRESULT hres = E_UNEXPECTED;
|
HRESULT hres = E_UNEXPECTED;
|
||||||
APARTMENT *apt;
|
APARTMENT *apt;
|
||||||
|
BOOL release_apt = FALSE;
|
||||||
|
|
||||||
TRACE("\n\tCLSID:\t%s,\n\tIID:\t%s\n", debugstr_guid(rclsid), debugstr_guid(iid));
|
TRACE("\n\tCLSID:\t%s,\n\tIID:\t%s\n", debugstr_guid(rclsid), debugstr_guid(iid));
|
||||||
|
|
||||||
|
@ -2245,12 +2271,15 @@ HRESULT WINAPI CoGetClassObject(
|
||||||
|
|
||||||
*ppv = NULL;
|
*ppv = NULL;
|
||||||
|
|
||||||
apt = COM_CurrentApt();
|
if (!(apt = COM_CurrentApt()))
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
release_apt = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
if (pServerInfo) {
|
if (pServerInfo) {
|
||||||
FIXME("\tpServerInfo: name=%s\n",debugstr_w(pServerInfo->pwszName));
|
FIXME("\tpServerInfo: name=%s\n",debugstr_w(pServerInfo->pwszName));
|
||||||
|
@ -2273,7 +2302,7 @@ HRESULT WINAPI CoGetClassObject(
|
||||||
* is good since we are not returning it in the "out" parameter.
|
* is good since we are not returning it in the "out" parameter.
|
||||||
*/
|
*/
|
||||||
IUnknown_Release(regClassObject);
|
IUnknown_Release(regClassObject);
|
||||||
|
if (release_apt) apartment_release(apt);
|
||||||
return hres;
|
return hres;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2284,7 +2313,10 @@ HRESULT WINAPI CoGetClassObject(
|
||||||
HKEY hkey;
|
HKEY hkey;
|
||||||
|
|
||||||
if (IsEqualCLSID(rclsid, &CLSID_InProcFreeMarshaler))
|
if (IsEqualCLSID(rclsid, &CLSID_InProcFreeMarshaler))
|
||||||
|
{
|
||||||
|
if (release_apt) apartment_release(apt);
|
||||||
return FTMarshalCF_Create(iid, ppv);
|
return FTMarshalCF_Create(iid, ppv);
|
||||||
|
}
|
||||||
|
|
||||||
hres = COM_OpenKeyForCLSID(rclsid, wszInprocServer32, KEY_READ, &hkey);
|
hres = COM_OpenKeyForCLSID(rclsid, wszInprocServer32, KEY_READ, &hkey);
|
||||||
if (FAILED(hres))
|
if (FAILED(hres))
|
||||||
|
@ -2308,8 +2340,11 @@ HRESULT WINAPI CoGetClassObject(
|
||||||
/* return if we got a class, otherwise fall through to one of the
|
/* return if we got a class, otherwise fall through to one of the
|
||||||
* other types */
|
* other types */
|
||||||
if (SUCCEEDED(hres))
|
if (SUCCEEDED(hres))
|
||||||
|
{
|
||||||
|
if (release_apt) apartment_release(apt);
|
||||||
return hres;
|
return hres;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Next try in-process handler */
|
/* Next try in-process handler */
|
||||||
if (CLSCTX_INPROC_HANDLER & dwClsContext)
|
if (CLSCTX_INPROC_HANDLER & dwClsContext)
|
||||||
|
@ -2339,8 +2374,12 @@ HRESULT WINAPI CoGetClassObject(
|
||||||
/* return if we got a class, otherwise fall through to one of the
|
/* return if we got a class, otherwise fall through to one of the
|
||||||
* other types */
|
* other types */
|
||||||
if (SUCCEEDED(hres))
|
if (SUCCEEDED(hres))
|
||||||
|
{
|
||||||
|
if (release_apt) apartment_release(apt);
|
||||||
return hres;
|
return hres;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if (release_apt) apartment_release(apt);
|
||||||
|
|
||||||
/* Next try out of process */
|
/* Next try out of process */
|
||||||
if (CLSCTX_LOCAL_SERVER & dwClsContext)
|
if (CLSCTX_LOCAL_SERVER & dwClsContext)
|
||||||
|
@ -2418,6 +2457,7 @@ HRESULT WINAPI CoCreateInstance(
|
||||||
{
|
{
|
||||||
HRESULT hres;
|
HRESULT hres;
|
||||||
LPCLASSFACTORY lpclf = 0;
|
LPCLASSFACTORY lpclf = 0;
|
||||||
|
APARTMENT *apt;
|
||||||
|
|
||||||
TRACE("(rclsid=%s, pUnkOuter=%p, dwClsContext=%08x, riid=%s, ppv=%p)\n", debugstr_guid(rclsid),
|
TRACE("(rclsid=%s, pUnkOuter=%p, dwClsContext=%08x, riid=%s, ppv=%p)\n", debugstr_guid(rclsid),
|
||||||
pUnkOuter, dwClsContext, debugstr_guid(iid), ppv);
|
pUnkOuter, dwClsContext, debugstr_guid(iid), ppv);
|
||||||
|
@ -2433,11 +2473,15 @@ HRESULT WINAPI CoCreateInstance(
|
||||||
*/
|
*/
|
||||||
*ppv = 0;
|
*ppv = 0;
|
||||||
|
|
||||||
if (!COM_CurrentApt())
|
if (!(apt = COM_CurrentApt()))
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The Standard Global Interface Table (GIT) object is a process-wide singleton.
|
* The Standard Global Interface Table (GIT) object is a process-wide singleton.
|
||||||
|
|
|
@ -276,7 +276,7 @@ static void test_CoCreateInstance(void)
|
||||||
|
|
||||||
pUnk = (IUnknown *)0xdeadbeef;
|
pUnk = (IUnknown *)0xdeadbeef;
|
||||||
hr = CoCreateInstance(rclsid, NULL, CLSCTX_INPROC_SERVER, &IID_IUnknown, (void **)&pUnk);
|
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);
|
if (pUnk) IUnknown_Release(pUnk);
|
||||||
|
|
||||||
SetEvent(info.stop);
|
SetEvent(info.stop);
|
||||||
|
@ -325,7 +325,7 @@ static void test_CoGetClassObject(void)
|
||||||
|
|
||||||
pUnk = (IUnknown *)0xdeadbeef;
|
pUnk = (IUnknown *)0xdeadbeef;
|
||||||
hr = CoGetClassObject(rclsid, CLSCTX_INPROC_SERVER, NULL, &IID_IUnknown, (void **)&pUnk);
|
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);
|
if (pUnk) IUnknown_Release(pUnk);
|
||||||
|
|
||||||
SetEvent(info.stop);
|
SetEvent(info.stop);
|
||||||
|
|
Loading…
Reference in New Issue