From c5b54b34e97cd23a04c34b8518c8ac934e6e2dc0 Mon Sep 17 00:00:00 2001 From: Jacek Caban Date: Wed, 21 Oct 2015 16:24:48 +0200 Subject: [PATCH] ole32: Call CoCreateInstanceEx from CoCreateInstance instead of the other way around. Signed-off-by: Jacek Caban Signed-off-by: Alexandre Julliard --- dlls/ole32/compobj.c | 151 +++++++++++++++++++------------------------ 1 file changed, 68 insertions(+), 83 deletions(-) diff --git a/dlls/ole32/compobj.c b/dlls/ole32/compobj.c index c04d2f05767..b3c49d34985 100644 --- a/dlls/ole32/compobj.c +++ b/dlls/ole32/compobj.c @@ -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); } /***********************************************************************