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