Rob Shearman : ole32: Cache the address for the library' s DllGetClassObject and DllCanUnloadNow in the OpenDll list entry.

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


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

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

ole32: Cache the address for the library's DllGetClassObject and DllCanUnloadNow in the OpenDll list entry.

---

 dlls/ole32/compobj.c |   42 +++++++++++++++++++++++-------------------
 1 files changed, 23 insertions(+), 19 deletions(-)

diff --git a/dlls/ole32/compobj.c b/dlls/ole32/compobj.c
index b992c4a..b990a69 100644
--- a/dlls/ole32/compobj.c
+++ b/dlls/ole32/compobj.c
@@ -151,11 +151,16 @@ static CRITICAL_SECTION csRegisteredClassList = { &class_cs_debug, -1, 0, 0, 0,
  * next unload-call but not before 600 sec.
  */
 
+typedef HRESULT (CALLBACK *DllGetClassObjectFunc)(REFCLSID clsid, REFIID iid, LPVOID *ppv);
+typedef HRESULT (WINAPI *DllCanUnloadNowFunc)(void);
+
 typedef struct tagOpenDll
 {
   LONG refs;
   LPWSTR library_name;
   HANDLE library;
+  DllGetClassObjectFunc DllGetClassObject;
+  DllCanUnloadNowFunc DllCanUnloadNow;
   struct list entry;
 } OpenDll;
 
@@ -564,27 +569,14 @@ void apartment_joinmta(void)
 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);
+    hr = open_dll_entry->DllGetClassObject(rclsid, riid, ppv);
 
     if (hr != S_OK)
         ERR("DllGetClassObject returned error 0x%08x\n", hr);
@@ -603,6 +595,8 @@ static HRESULT COMPOBJ_DllList_Add(LPCWSTR library_name, OpenDll **ret)
     int len;
     HRESULT hr = S_OK;
     HANDLE hLibrary;
+    DllCanUnloadNowFunc DllCanUnloadNow;
+    DllGetClassObjectFunc DllGetClassObject;
 
     TRACE("\n");
 
@@ -614,10 +608,22 @@ static HRESULT COMPOBJ_DllList_Add(LPCWSTR library_name, OpenDll **ret)
     hLibrary = LoadLibraryExW(library_name, 0, LOAD_WITH_ALTERED_SEARCH_PATH);
     if (!hLibrary)
     {
+        ERR("couldn't load in-process dll %s\n", debugstr_w(library_name));
         /* failure: DLL could not be loaded */
         return E_ACCESSDENIED; /* FIXME: or should this be CO_E_DLLNOTFOUND? */
     }
 
+    DllCanUnloadNow = GetProcAddress(hLibrary, "DllCanUnloadNow");
+    /* Note: failing to find DllCanUnloadNow is not a failure */
+    DllGetClassObject = GetProcAddress(hLibrary, "DllGetClassObject");
+    if (!DllGetClassObject)
+    {
+        /* failure: the dll did not export DllGetClassObject */
+        ERR("couldn't find function DllGetClassObject in %s\n", debugstr_w(library_name));
+        FreeLibrary(hLibrary);
+        return CO_E_DLLNOTFOUND;
+    }
+
     EnterCriticalSection( &csOpenDllList );
 
     *ret = COMPOBJ_DllList_Get(library_name);
@@ -638,6 +644,8 @@ static HRESULT COMPOBJ_DllList_Add(LPCWSTR library_name, OpenDll **ret)
             memcpy(entry->library_name, library_name, (len + 1)*sizeof(WCHAR));
             entry->library = hLibrary;
             entry->refs = 1;
+            entry->DllCanUnloadNow = DllCanUnloadNow;
+            entry->DllGetClassObject = DllGetClassObject;
             list_add_tail(&openDllList, &entry->entry);
         }
         else
@@ -689,8 +697,6 @@ static void COMPOBJ_DllList_ReleaseRef(OpenDll *entry)
 static void COMPOBJ_DllList_FreeUnused(int Timeout)
 {
     OpenDll *curr, *next;
-    typedef HRESULT (WINAPI *DllCanUnloadNowFunc)(void);
-    DllCanUnloadNowFunc DllCanUnloadNow;
 
     TRACE("\n");
 
@@ -698,9 +704,7 @@ static void COMPOBJ_DllList_FreeUnused(int Timeout)
 
     LIST_FOR_EACH_ENTRY_SAFE(curr, next, &openDllList, OpenDll, entry)
     {
-	DllCanUnloadNow = (DllCanUnloadNowFunc) GetProcAddress(curr->library, "DllCanUnloadNow");
-
-	if ( (DllCanUnloadNow != NULL) && (DllCanUnloadNow() == S_OK) )
+	if ( (curr->DllCanUnloadNow != NULL) && (curr->DllCanUnloadNow() == S_OK) )
             COMPOBJ_DllList_ReleaseRef(curr);
     }
 




More information about the wine-cvs mailing list