[PATCH v4 1/5] compobj.dll16: Implement CoLoadLibrary16 and CoFreeLibrary16.

Zebediah Figura z.figura12 at gmail.com
Mon Feb 13 14:52:40 CST 2017


v4: remove unnecessary refcounting
Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
---
 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




More information about the wine-patches mailing list