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