Rob Shearman : ole32: Move the in-process module loading to COMPOBJ_DllList_Add.

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


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

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

ole32: Move the in-process module loading to COMPOBJ_DllList_Add.

---

 dlls/ole32/compobj.c |   40 +++++++++++++++++++++++++++++-----------
 1 files changed, 29 insertions(+), 11 deletions(-)

diff --git a/dlls/ole32/compobj.c b/dlls/ole32/compobj.c
index 177e17f..b77c0c4 100644
--- a/dlls/ole32/compobj.c
+++ b/dlls/ole32/compobj.c
@@ -174,7 +174,7 @@ static const WCHAR wszAptWinClass[] = {'O','l','e','M','a','i','n','T','h','r','
                                        '0','x','#','#','#','#','#','#','#','#',' ',0};
 static LRESULT CALLBACK apartment_wndproc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
 
-static HRESULT COMPOBJ_DllList_Add(LPCWSTR library_name, HANDLE hLibrary, OpenDll **ret);
+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);
@@ -553,18 +553,37 @@ void apartment_joinmta(void)
  */
 
 /* caller must ensure that library_name is not already in the open dll list */
-static HRESULT COMPOBJ_DllList_Add(LPCWSTR library_name, HANDLE hLibrary, OpenDll **ret)
+static HRESULT COMPOBJ_DllList_Add(LPCWSTR library_name, OpenDll **ret)
 {
     OpenDll *entry;
     int len;
     HRESULT hr = S_OK;
+    HANDLE hLibrary;
 
     TRACE("\n");
 
+    *ret = COMPOBJ_DllList_Get(library_name);
+    if (*ret) return S_OK;
+
+    /* do this outside the csOpenDllList to avoid creating a lock dependency on
+     * the loader lock */
+    hLibrary = LoadLibraryExW(library_name, 0, LOAD_WITH_ALTERED_SEARCH_PATH);
+    if (!hLibrary)
+    {
+        /* failure: DLL could not be loaded */
+        return E_ACCESSDENIED; /* FIXME: or should this be CO_E_DLLNOTFOUND? */
+    }
+
     EnterCriticalSection( &csOpenDllList );
 
     *ret = COMPOBJ_DllList_Get(library_name);
-    if (!*ret)
+    if (*ret)
+    {
+        /* another caller to this function already added the dll while we
+         * weren't in the critical section */
+        FreeLibrary(hLibrary);
+    }
+    else
     {
         len = strlenW(library_name);
         entry = HeapAlloc(GetProcessHeap(),0, sizeof(OpenDll));
@@ -578,7 +597,10 @@ static HRESULT COMPOBJ_DllList_Add(LPCWSTR library_name, HANDLE hLibrary, OpenDl
             list_add_tail(&openDllList, &entry->entry);
         }
         else
+        {
             hr = E_OUTOFMEMORY;
+            FreeLibrary(hLibrary);
+        }
         *ret = entry;
     }
 
@@ -1747,7 +1769,6 @@ 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};
-    HINSTANCE hLibrary;
     typedef HRESULT (CALLBACK *DllGetClassObjectFunc)(REFCLSID clsid, REFIID iid, LPVOID *ppv);
     DllGetClassObjectFunc DllGetClassObject;
     WCHAR dllpath[MAX_PATH+1];
@@ -1838,20 +1859,17 @@ static HRESULT get_inproc_class_object(HKEY hkeydll, REFCLSID rclsid, REFIID rii
         return REGDB_E_CLASSNOTREG;
     }
 
-    if ((hLibrary = LoadLibraryExW(dllpath, 0, LOAD_WITH_ALTERED_SEARCH_PATH)) == 0)
+    hr = COMPOBJ_DllList_Add( dllpath, &open_dll_entry );
+    if (FAILED(hr))
     {
-        /* failure: DLL could not be loaded */
         ERR("couldn't load in-process dll %s\n", debugstr_w(dllpath));
-        return E_ACCESSDENIED; /* FIXME: or should this be CO_E_DLLNOTFOUND? */
+        return hr;
     }
 
-    COMPOBJ_DllList_Add( dllpath, hLibrary, &open_dll_entry );
-
-    if (!(DllGetClassObject = (DllGetClassObjectFunc)GetProcAddress(hLibrary, "DllGetClassObject")))
+    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));
-        FreeLibrary( hLibrary );
         return CO_E_DLLNOTFOUND;
     }
 




More information about the wine-cvs mailing list