From: Zebediah Figura Subject: [PATCH v4 1/5] compobj.dll16: Implement CoLoadLibrary16 and CoFreeLibrary16. Message-Id: <1487019161-18838-1-git-send-email-z.figura12@gmail.com> Date: Mon, 13 Feb 2017 14:52:40 -0600 v4: remove unnecessary refcounting Signed-off-by: Zebediah Figura --- dlls/compobj.dll16/compobj.c | 79 +++++++++++++++++++++++++++++++++++ dlls/compobj.dll16/compobj.dll16.spec | 4 +- 2 files changed, 81 insertions(+), 2 deletions(-) diff --git a/dlls/compobj.dll16/compobj.c b/dlls/compobj.dll16/compobj.c index b934a06..e49f251 100644 --- a/dlls/compobj.dll16/compobj.c +++ b/dlls/compobj.dll16/compobj.c @@ -42,6 +42,7 @@ #include "wtypes.h" #include "wine/unicode.h" #include "wine/winbase16.h" +#include "wine/list.h" #include "wine/debug.h" @@ -240,6 +241,84 @@ IMalloc16_Constructor(void) return (LPMALLOC16)MapLS( This ); } +/* --- loaded dll list implementation */ +struct open_dll +{ + HMODULE16 library; + FARPROC16 DllCanUnloadNow; + struct list entry; +}; + +static struct list open_dll_list = LIST_INIT(open_dll_list); + +static HRESULT dll_list_add(LPCSTR library_name, struct open_dll **ret) +{ + struct open_dll *dll; + HMODULE16 library; + FARPROC16 DllCanUnloadNow; + + library = LoadLibrary16(library_name); + if (!library) + { + ERR("couldn't load in-process dll %s\n", debugstr_a(library_name)); + return E_ACCESSDENIED; /* FIXME: or should this be CO_E_DLLNOTFOUND? */ + } + + DllCanUnloadNow = GetProcAddress16(library, "DllCanUnloadNow"); + /* Note: failing to find DllCanUnloadNow is not a failure */ + + dll = HeapAlloc(GetProcessHeap(), 0, sizeof(struct open_dll)); + dll->library = library; + dll->DllCanUnloadNow = DllCanUnloadNow; + list_add_tail(&open_dll_list, &dll->entry); + *ret = dll; + TRACE("added new loaded dll %d\n", dll->library); + + return S_OK; +} + +static void dll_list_free(struct open_dll *dll) +{ + TRACE("freeing %d\n", dll->library); + + list_remove(&dll->entry); + FreeLibrary16(dll->library); + HeapFree(GetProcessHeap(), 0, dll); +} + +/****************************************************************************** + * CoLoadLibrary [COMPOBJ.10] + * + * Called internally by CoGetClassObject(). + */ +HINSTANCE16 WINAPI CoLoadLibrary16( + LPOLESTR16 lpszLibName, + BOOL bAutoFree) +{ + struct open_dll *dll; + + if(dll_list_add(lpszLibName, &dll) != S_OK) + return ERROR_INVALID_HANDLE; + + return dll->library; +} + +/****************************************************************************** + * CoFreeLibrary [COMPOBJ.11] + * + * Called internally by CoGetClassObject(). + */ +void WINAPI CoFreeLibrary16( + HINSTANCE16 hInst) +{ + struct open_dll *dll; + + LIST_FOR_EACH_ENTRY(dll, &open_dll_list, struct open_dll, entry) + { + if(hInst == dll->library) + dll_list_free(dll); + } +} /****************************************************************************** * CoBuildVersion [COMPOBJ.1] diff --git a/dlls/compobj.dll16/compobj.dll16.spec b/dlls/compobj.dll16/compobj.dll16.spec index 85dfc42..175b957 100644 --- a/dlls/compobj.dll16/compobj.dll16.spec +++ b/dlls/compobj.dll16/compobj.dll16.spec @@ -7,8 +7,8 @@ 7 pascal CoGetClassObject(ptr long ptr ptr ptr) CoGetClassObject16 8 stub COMARSHALINTERFACE 9 stub COUNMARSHALINTERFACE -10 stub COLOADLIBRARY -11 stub COFREELIBRARY +10 pascal CoLoadLibrary(long long) CoLoadLibrary16 +11 pascal CoFreeLibrary(long) CoFreeLibrary16 12 stub COFREEALLLIBRARIES 13 pascal CoCreateInstance(ptr ptr long ptr ptr) CoCreateInstance16 14 stub STRINGFROMIID -- 2.7.4