Jacek Caban : ole32: Call CoCreateInstanceEx from CoCreateInstance instead of the other way around.
Alexandre Julliard
julliard at wine.codeweavers.com
Thu Oct 22 10:22:07 CDT 2015
Module: wine
Branch: master
Commit: c5b54b34e97cd23a04c34b8518c8ac934e6e2dc0
URL: http://source.winehq.org/git/wine.git/?a=commit;h=c5b54b34e97cd23a04c34b8518c8ac934e6e2dc0
Author: Jacek Caban <jacek at codeweavers.com>
Date: Wed Oct 21 16:24:48 2015 +0200
ole32: Call CoCreateInstanceEx from CoCreateInstance instead of the other way around.
Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
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 c04d2f0..b3c49d3 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;
+
+ 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(pUnk, cmq, pResults, TRUE);
+ return return_multi_qi(unk, cmq, pResults, TRUE);
}
/***********************************************************************
More information about the wine-cvs
mailing list