Rob Shearman : ole32: Move the handling of loading a dll and getting an in-process object from it to an apartment-specific function .

Alexandre Julliard julliard at wine.codeweavers.com
Wed Apr 4 15:40:08 CDT 2007


Module: wine
Branch: master
Commit: c40f1b665963da138a4fed8568633ea8c2541180
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=c40f1b665963da138a4fed8568633ea8c2541180

Author: Rob Shearman <rob at codeweavers.com>
Date:   Wed Apr  4 18:55:23 2007 +0100

ole32: Move the handling of loading a dll and getting an in-process object from it to an apartment-specific function.

Use it to implement apartment_hostobject in a cleaner way so that it is 
guaranteed to not recurse.

---

 dlls/ole32/compobj.c |   80 ++++++++++++++++++++++++++++++-------------------
 1 files changed, 49 insertions(+), 31 deletions(-)

diff --git a/dlls/ole32/compobj.c b/dlls/ole32/compobj.c
index b77c0c4..b992c4a 100644
--- a/dlls/ole32/compobj.c
+++ b/dlls/ole32/compobj.c
@@ -173,12 +173,16 @@ static CRITICAL_SECTION csOpenDllList = { &dll_cs_debug, -1, 0, 0, 0, 0 };
 static const WCHAR wszAptWinClass[] = {'O','l','e','M','a','i','n','T','h','r','e','a','d','W','n','d','C','l','a','s','s',' ',
                                        '0','x','#','#','#','#','#','#','#','#',' ',0};
 static LRESULT CALLBACK apartment_wndproc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
+static HRESULT apartment_getclassobject(struct apartment *apt, LPCWSTR dllpath,
+                                        REFCLSID rclsid, REFIID riid, void **ppv);
 
 static HRESULT COMPOBJ_DllList_Add(LPCWSTR library_name, OpenDll **ret);
 static OpenDll *COMPOBJ_DllList_Get(LPCWSTR library_name);
 static void COMPOBJ_DllList_ReleaseRef(OpenDll *entry);
 static void COMPOBJ_DllList_FreeUnused(int Timeout);
 
+static DWORD COM_RegReadPath(HKEY hkeyroot, const WCHAR *keyname, const WCHAR *valuename, WCHAR * dst, DWORD dstlen);
+
 static void COMPOBJ_InitProcess( void )
 {
     WNDCLASSW wclass;
@@ -479,15 +483,24 @@ struct host_object_params
     IStream *stream; /* stream that the object will be marshaled into */
 };
 
-static HRESULT apartment_hostobject(const struct host_object_params *params)
+static HRESULT apartment_hostobject(struct apartment *apt,
+                                    const struct host_object_params *params)
 {
     IUnknown *object;
     HRESULT hr;
     static const LARGE_INTEGER llZero;
+    WCHAR dllpath[MAX_PATH+1];
 
     TRACE("\n");
 
-    hr = get_inproc_class_object(params->hkeydll, &params->clsid, &params->iid, (void **)&object);
+    if (COM_RegReadPath(params->hkeydll, NULL, NULL, dllpath, ARRAYSIZE(dllpath)) != ERROR_SUCCESS)
+    {
+        /* failure: CLSID is not found in registry */
+        WARN("class %s not registered inproc\n", debugstr_guid(&params->clsid));
+        return REGDB_E_CLASSNOTREG;
+    }
+
+    hr = apartment_getclassobject(apt, dllpath, &params->clsid, &params->iid, (void **)&object);
     if (FAILED(hr))
         return hr;
 
@@ -507,7 +520,7 @@ static LRESULT CALLBACK apartment_wndproc(HWND hWnd, UINT msg, WPARAM wParam, LP
         RPC_ExecuteCall((struct dispatch_params *)lParam);
         return 0;
     case DM_HOSTOBJECT:
-        return apartment_hostobject((const struct host_object_params *)lParam);
+        return apartment_hostobject(COM_CurrentApt(), (const struct host_object_params *)lParam);
     default:
         return DefWindowProcW(hWnd, msg, wParam, lParam);
     }
@@ -548,6 +561,37 @@ void apartment_joinmta(void)
     COM_CurrentInfo()->apt = MTA;
 }
 
+static HRESULT apartment_getclassobject(struct apartment *apt, LPCWSTR dllpath,
+                                        REFCLSID rclsid, REFIID riid, void **ppv)
+{
+    typedef HRESULT (CALLBACK *DllGetClassObjectFunc)(REFCLSID clsid, REFIID iid, LPVOID *ppv);
+    DllGetClassObjectFunc DllGetClassObject;
+    OpenDll *open_dll_entry;
+    HRESULT hr;
+
+    hr = COMPOBJ_DllList_Add( dllpath, &open_dll_entry );
+    if (FAILED(hr))
+    {
+        ERR("couldn't load in-process dll %s\n", debugstr_w(dllpath));
+        return hr;
+    }
+
+    if (!(DllGetClassObject = (DllGetClassObjectFunc)GetProcAddress(open_dll_entry->library, "DllGetClassObject")))
+    {
+        /* failure: the dll did not export DllGetClassObject */
+        ERR("couldn't find function DllGetClassObject in %s\n", debugstr_w(dllpath));
+        return CO_E_DLLNOTFOUND;
+    }
+
+    /* OK: get the ClassObject */
+    hr = DllGetClassObject(rclsid, riid, ppv);
+
+    if (hr != S_OK)
+        ERR("DllGetClassObject returned error 0x%08x\n", hr);
+
+    return hr;
+}
+
 /*****************************************************************************
  * This section contains OpenDllList implementation
  */
@@ -1769,18 +1813,15 @@ static HRESULT get_inproc_class_object(HKEY hkeydll, REFCLSID rclsid, REFIID rii
     static const WCHAR wszApartment[] = {'A','p','a','r','t','m','e','n','t',0};
     static const WCHAR wszFree[] = {'F','r','e','e',0};
     static const WCHAR wszBoth[] = {'B','o','t','h',0};
-    typedef HRESULT (CALLBACK *DllGetClassObjectFunc)(REFCLSID clsid, REFIID iid, LPVOID *ppv);
-    DllGetClassObjectFunc DllGetClassObject;
     WCHAR dllpath[MAX_PATH+1];
     WCHAR threading_model[10 /* strlenW(L"apartment")+1 */];
     HRESULT hr;
-    OpenDll *open_dll_entry;
+    APARTMENT *apt = COM_CurrentApt();
 
     get_threading_model(hkeydll, threading_model, ARRAYSIZE(threading_model));
     /* "Apartment" */
     if (!strcmpiW(threading_model, wszApartment))
     {
-        APARTMENT *apt = COM_CurrentApt();
         if (apt->multi_threaded)
         {
             /* try to find an STA */
@@ -1809,7 +1850,6 @@ static HRESULT get_inproc_class_object(HKEY hkeydll, REFCLSID rclsid, REFIID rii
     /* "Free" */
     else if (!strcmpiW(threading_model, wszFree))
     {
-        APARTMENT *apt = COM_CurrentApt();
         if (!apt->multi_threaded)
         {
             FIXME("should create object %s in multi-threaded apartment\n",
@@ -1819,8 +1859,6 @@ static HRESULT get_inproc_class_object(HKEY hkeydll, REFCLSID rclsid, REFIID rii
     /* everything except "Apartment", "Free" and "Both" */
     else if (strcmpiW(threading_model, wszBoth))
     {
-        APARTMENT *apt = COM_CurrentApt();
-
         /* everything else is main-threaded */
         if (threading_model[0])
             FIXME("unrecognised threading model %s for object %s, should be main-threaded?\n",
@@ -1859,27 +1897,7 @@ static HRESULT get_inproc_class_object(HKEY hkeydll, REFCLSID rclsid, REFIID rii
         return REGDB_E_CLASSNOTREG;
     }
 
-    hr = COMPOBJ_DllList_Add( dllpath, &open_dll_entry );
-    if (FAILED(hr))
-    {
-        ERR("couldn't load in-process dll %s\n", debugstr_w(dllpath));
-        return hr;
-    }
-
-    if (!(DllGetClassObject = (DllGetClassObjectFunc)GetProcAddress(open_dll_entry->library, "DllGetClassObject")))
-    {
-        /* failure: the dll did not export DllGetClassObject */
-        ERR("couldn't find function DllGetClassObject in %s\n", debugstr_w(dllpath));
-        return CO_E_DLLNOTFOUND;
-    }
-
-    /* OK: get the ClassObject */
-    hr = DllGetClassObject(rclsid, riid, ppv);
-
-    if (hr != S_OK)
-        ERR("DllGetClassObject returned error 0x%08x\n", hr);
-
-    return hr;
+    return apartment_getclassobject(apt, dllpath, rclsid, riid, ppv);
 }
 
 /***********************************************************************




More information about the wine-cvs mailing list