Rob Shearman : ole32: Add inproc handler object creation support for CoCreateInstance.
Alexandre Julliard
julliard at winehq.org
Tue Nov 24 12:40:21 CST 2009
Module: wine
Branch: master
Commit: 24cccbf4d1df23db1969cdf32ed6708d2281b627
URL: http://source.winehq.org/git/wine.git/?a=commit;h=24cccbf4d1df23db1969cdf32ed6708d2281b627
Author: Rob Shearman <robertshearman at gmail.com>
Date: Mon Nov 23 15:07:49 2009 +0000
ole32: Add inproc handler object creation support for CoCreateInstance.
---
dlls/ole32/compobj.c | 27 +++++++++++++++
dlls/ole32/compobj_private.h | 3 ++
dlls/ole32/defaulthandler.c | 74 ++++++++++++++++++++++++++++++++++++++++++
dlls/ole32/oleproxy.c | 8 ++++-
dlls/ole32/tests/marshal.c | 1 -
5 files changed, 111 insertions(+), 2 deletions(-)
diff --git a/dlls/ole32/compobj.c b/dlls/ole32/compobj.c
index 580f4d3..7dc1568 100644
--- a/dlls/ole32/compobj.c
+++ b/dlls/ole32/compobj.c
@@ -4106,6 +4106,33 @@ HRESULT WINAPI CoGetContextToken( ULONG_PTR *token )
return S_OK;
}
+HRESULT Handler_DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
+{
+ static const WCHAR wszInprocHandler32[] = {'I','n','p','r','o','c','H','a','n','d','l','e','r','3','2',0};
+ HKEY hkey;
+ HRESULT hres;
+
+ hres = COM_OpenKeyForCLSID(rclsid, wszInprocHandler32, KEY_READ, &hkey);
+ if (SUCCEEDED(hres))
+ {
+ WCHAR dllpath[MAX_PATH+1];
+
+ if (COM_RegReadPath(hkey, NULL, NULL, dllpath, ARRAYSIZE(dllpath)) == ERROR_SUCCESS)
+ {
+ static const WCHAR wszOle32[] = {'o','l','e','3','2','.','d','l','l',0};
+ if (!strcmpiW(dllpath, wszOle32))
+ {
+ RegCloseKey(hkey);
+ return HandlerCF_Create(rclsid, riid, ppv);
+ }
+ }
+ else
+ WARN("not creating object for inproc handler path %s\n", debugstr_w(dllpath));
+ RegCloseKey(hkey);
+ }
+
+ return CLASS_E_CLASSNOTAVAILABLE;
+}
/***********************************************************************
* DllMain (OLE32.@)
diff --git a/dlls/ole32/compobj_private.h b/dlls/ole32/compobj_private.h
index fb05934..076d845 100644
--- a/dlls/ole32/compobj_private.h
+++ b/dlls/ole32/compobj_private.h
@@ -313,6 +313,9 @@ extern HRESULT WINAPI OLE32_DllGetClassObject(REFCLSID rclsid, REFIID iid,LPVOID
extern HRESULT WINAPI OLE32_DllRegisterServer(void) DECLSPEC_HIDDEN;
extern HRESULT WINAPI OLE32_DllUnregisterServer(void) DECLSPEC_HIDDEN;
+extern HRESULT Handler_DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv);
+extern HRESULT HandlerCF_Create(REFCLSID rclsid, REFIID riid, LPVOID *ppv);
+
/* Exported non-interface Data Advise Holder functions */
HRESULT DataAdviseHolder_OnConnect(IDataAdviseHolder *iface, IDataObject *pDelegate);
void DataAdviseHolder_OnDisconnect(IDataAdviseHolder *iface);
diff --git a/dlls/ole32/defaulthandler.c b/dlls/ole32/defaulthandler.c
index 4102d50..a3da0dd 100644
--- a/dlls/ole32/defaulthandler.c
+++ b/dlls/ole32/defaulthandler.c
@@ -2122,3 +2122,77 @@ HRESULT WINAPI OleCreateDefaultHandler(REFCLSID clsid, LPUNKNOWN pUnkOuter,
return OleCreateEmbeddingHelper(clsid, pUnkOuter, EMBDHLP_INPROC_HANDLER | EMBDHLP_CREATENOW,
NULL, riid, ppvObj);
}
+
+typedef struct HandlerCF
+{
+ const IClassFactoryVtbl *lpVtbl;
+ LONG refs;
+ CLSID clsid;
+} HandlerCF;
+
+static HRESULT WINAPI
+HandlerCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid, LPVOID *ppv)
+{
+ *ppv = NULL;
+ if (IsEqualIID(riid,&IID_IUnknown) ||
+ IsEqualIID(riid,&IID_IClassFactory))
+ {
+ *ppv = iface;
+ IClassFactory_AddRef(iface);
+ return S_OK;
+ }
+ return E_NOINTERFACE;
+}
+
+static ULONG WINAPI HandlerCF_AddRef(LPCLASSFACTORY iface)
+{
+ HandlerCF *This = (HandlerCF *)iface;
+ return InterlockedIncrement(&This->refs);
+}
+
+static ULONG WINAPI HandlerCF_Release(LPCLASSFACTORY iface)
+{
+ HandlerCF *This = (HandlerCF *)iface;
+ ULONG refs = InterlockedDecrement(&This->refs);
+ if (!refs)
+ HeapFree(GetProcessHeap(), 0, This);
+ return refs;
+}
+
+static HRESULT WINAPI
+HandlerCF_CreateInstance(LPCLASSFACTORY iface, LPUNKNOWN pUnk,
+ REFIID riid, LPVOID *ppv)
+{
+ HandlerCF *This = (HandlerCF *)iface;
+ return OleCreateDefaultHandler(&This->clsid, pUnk, riid, ppv);
+}
+
+static HRESULT WINAPI HandlerCF_LockServer(LPCLASSFACTORY iface, BOOL fLock)
+{
+ FIXME("(%d), stub!\n",fLock);
+ return S_OK;
+}
+
+static const IClassFactoryVtbl HandlerClassFactoryVtbl = {
+ HandlerCF_QueryInterface,
+ HandlerCF_AddRef,
+ HandlerCF_Release,
+ HandlerCF_CreateInstance,
+ HandlerCF_LockServer
+};
+
+HRESULT HandlerCF_Create(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
+{
+ HRESULT hr;
+ HandlerCF *This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
+ if (!This) return E_OUTOFMEMORY;
+ This->lpVtbl = &HandlerClassFactoryVtbl;
+ This->refs = 0;
+ This->clsid = *rclsid;
+
+ hr = IUnknown_QueryInterface((IUnknown *)&This->lpVtbl, riid, ppv);
+ if (FAILED(hr))
+ HeapFree(GetProcessHeap(), 0, This);
+
+ return hr;
+}
diff --git a/dlls/ole32/oleproxy.c b/dlls/ole32/oleproxy.c
index 11a3ad1..184aca1 100644
--- a/dlls/ole32/oleproxy.c
+++ b/dlls/ole32/oleproxy.c
@@ -46,6 +46,8 @@
*/
HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID iid,LPVOID *ppv)
{
+ HRESULT hr;
+
*ppv = NULL;
if (IsEqualIID(rclsid,&CLSID_DfMarshal)&&(
IsEqualIID(iid,&IID_IClassFactory) ||
@@ -70,5 +72,9 @@ HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID iid,LPVOID *ppv)
if (IsEqualGUID(rclsid, &CLSID_StdComponentCategoriesMgr))
return ComCatCF_Create(iid, ppv);
- return OLE32_DllGetClassObject(rclsid, iid, ppv);
+ hr = OLE32_DllGetClassObject(rclsid, iid, ppv);
+ if (SUCCEEDED(hr))
+ return hr;
+
+ return Handler_DllGetClassObject(rclsid, iid, ppv);
}
diff --git a/dlls/ole32/tests/marshal.c b/dlls/ole32/tests/marshal.c
index bb2b508..b4a2384 100644
--- a/dlls/ole32/tests/marshal.c
+++ b/dlls/ole32/tests/marshal.c
@@ -2314,7 +2314,6 @@ static void test_inproc_handler(void)
reg_unreg_wine_test_class(TRUE);
hr = CoCreateInstance(&CLSID_WineTest, NULL, CLSCTX_INPROC_HANDLER, &IID_IUnknown, (void **)&pObject);
- todo_wine
ok_ole_success(hr, "CoCreateInstance");
if (SUCCEEDED(hr))
More information about the wine-cvs
mailing list