ole32: Call CoCreateInstanceEx from CoCreateInstance instead of the other way around.

Signed-off-by: Jacek Caban <jacek@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Jacek Caban 2015-10-21 16:24:48 +02:00 committed by Alexandre Julliard
parent dedcd30cb8
commit c5b54b34e9
1 changed files with 68 additions and 83 deletions

View File

@ -3187,10 +3187,8 @@ HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstance(
REFIID iid,
LPVOID *ppv)
{
MULTI_QI multi_qi = { iid };
HRESULT hres;
LPCLASSFACTORY lpclf = 0;
APARTMENT *apt;
CLSID clsid;
TRACE("(rclsid=%s, pUnkOuter=%p, dwClsContext=%08x, riid=%s, ppv=%p)\n", debugstr_guid(rclsid),
pUnkOuter, dwClsContext, debugstr_guid(iid), ppv);
@ -3198,65 +3196,8 @@ HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstance(
if (ppv==0)
return E_POINTER;
hres = CoGetTreatAsClass(rclsid, &clsid);
if(FAILED(hres))
clsid = *rclsid;
*ppv = 0;
if (!(apt = COM_CurrentApt()))
{
if (!(apt = apartment_find_multi_threaded()))
{
ERR("apartment not initialised\n");
return CO_E_NOTINITIALIZED;
}
apartment_release(apt);
}
/*
* The Standard Global Interface Table (GIT) object is a process-wide singleton.
*/
if (IsEqualIID(&clsid, &CLSID_StdGlobalInterfaceTable))
{
IGlobalInterfaceTable *git = get_std_git();
hres = IGlobalInterfaceTable_QueryInterface(git, iid, ppv);
if (hres != S_OK) return hres;
TRACE("Retrieved GIT (%p)\n", *ppv);
return S_OK;
}
if (IsEqualCLSID(&clsid, &CLSID_ManualResetEvent))
return ManualResetEvent_Construct(pUnkOuter, iid, ppv);
/*
* Get a class factory to construct the object we want.
*/
hres = CoGetClassObject(&clsid,
dwClsContext,
NULL,
&IID_IClassFactory,
(LPVOID)&lpclf);
if (FAILED(hres))
return hres;
/*
* Create the object and don't forget to release the factory
*/
hres = IClassFactory_CreateInstance(lpclf, pUnkOuter, iid, ppv);
IClassFactory_Release(lpclf);
if (FAILED(hres))
{
if (hres == CLASS_E_NOAGGREGATION && pUnkOuter)
FIXME("Class %s does not support aggregation\n", debugstr_guid(&clsid));
else
FIXME("no instance created for interface %s of class %s, hres is 0x%08x\n",
debugstr_guid(iid),
debugstr_guid(&clsid),hres);
}
hres = CoCreateInstanceEx(rclsid, pUnkOuter, dwClsContext, NULL, 1, &multi_qi);
*ppv = multi_qi.pItf;
return hres;
}
@ -3309,33 +3250,77 @@ HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstanceEx(
ULONG cmq,
MULTI_QI* pResults)
{
IUnknown* pUnk = NULL;
HRESULT hr;
IUnknown *unk = NULL;
IClassFactory *cf;
APARTMENT *apt;
CLSID clsid;
HRESULT hres;
/*
* Sanity check
*/
if ( (cmq==0) || (pResults==NULL))
return E_INVALIDARG;
TRACE("(%s %p %x %p %u %p)\n", debugstr_guid(rclsid), pUnkOuter, dwClsContext, pServerInfo, cmq, pResults);
if (pServerInfo!=NULL)
FIXME("() non-NULL pServerInfo not supported!\n");
if (!cmq || !pResults)
return E_INVALIDARG;
init_multi_qi(cmq, pResults);
if (pServerInfo)
FIXME("() non-NULL pServerInfo not supported!\n");
/*
* Get the object and get its IUnknown pointer.
*/
hr = CoCreateInstance(rclsid,
pUnkOuter,
dwClsContext,
pResults[0].pIID,
(VOID**)&pUnk);
init_multi_qi(cmq, pResults);
if (hr != S_OK)
return hr;
hres = CoGetTreatAsClass(rclsid, &clsid);
if(FAILED(hres))
clsid = *rclsid;
return return_multi_qi(pUnk, cmq, pResults, TRUE);
if (!(apt = COM_CurrentApt()))
{
if (!(apt = apartment_find_multi_threaded()))
{
ERR("apartment not initialised\n");
return CO_E_NOTINITIALIZED;
}
apartment_release(apt);
}
/*
* The Standard Global Interface Table (GIT) object is a process-wide singleton.
*/
if (IsEqualIID(&clsid, &CLSID_StdGlobalInterfaceTable))
{
IGlobalInterfaceTable *git = get_std_git();
TRACE("Retrieving GIT\n");
return return_multi_qi((IUnknown*)git, cmq, pResults, FALSE);
}
if (IsEqualCLSID(&clsid, &CLSID_ManualResetEvent)) {
hres = ManualResetEvent_Construct(pUnkOuter, pResults[0].pIID, (void**)&unk);
if (FAILED(hres))
return hres;
return return_multi_qi(unk, cmq, pResults, TRUE);
}
/*
* Get a class factory to construct the object we want.
*/
hres = CoGetClassObject(&clsid, dwClsContext, NULL, &IID_IClassFactory, (void**)&cf);
if (FAILED(hres))
return hres;
/*
* Create the object and don't forget to release the factory
*/
hres = IClassFactory_CreateInstance(cf, pUnkOuter, pResults[0].pIID, (void**)&unk);
IClassFactory_Release(cf);
if (FAILED(hres))
{
if (hres == CLASS_E_NOAGGREGATION && pUnkOuter)
FIXME("Class %s does not support aggregation\n", debugstr_guid(&clsid));
else
FIXME("no instance created for interface %s of class %s, hres is 0x%08x\n",
debugstr_guid(pResults[0].pIID),
debugstr_guid(&clsid),hres);
return hres;
}
return return_multi_qi(unk, cmq, pResults, TRUE);
}
/***********************************************************************