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

Zebediah Figura z.figura12 at gmail.com
Thu Feb 9 11:56:17 CST 2017


v3: use InterlockedIncrement/Decrement, fix error comitting changes
Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
---
 dlls/compobj.dll16/compobj.c          | 99 +++++++++++++++++++++++++++++++++++
 dlls/compobj.dll16/compobj.dll16.spec |  4 +-
 2 files changed, 101 insertions(+), 2 deletions(-)

diff --git a/dlls/compobj.dll16/compobj.c b/dlls/compobj.dll16/compobj.c
index b934a06..a1acf35 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,104 @@ IMalloc16_Constructor(void)
     return (LPMALLOC16)MapLS( This );
 }
 
+/* --- loaded dll list implementation */
+struct open_dll
+{
+    LONG refs;
+    LPSTR library_name;
+    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;
+
+    LIST_FOR_EACH_ENTRY(dll, &open_dll_list, struct open_dll, entry)
+    {
+        if(!strcasecmp(library_name, dll->library_name))
+        {
+            TRACE("found %s already loaded\n", debugstr_a(library_name));
+            InterlockedIncrement(&dll->refs);
+            *ret = dll;
+            return S_OK;
+        }
+    }
+
+    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_name = HeapAlloc(GetProcessHeap(), 0, (strlen(library_name)+1)*sizeof(char));
+    strcpy(dll->library_name, library_name);
+    dll->library = library;
+    dll->refs = 1;
+    dll->DllCanUnloadNow = DllCanUnloadNow;
+    list_add_tail(&open_dll_list, &dll->entry);
+    *ret = dll;
+    TRACE("added new loaded dll %s\n", debugstr_a(library_name));
+
+    return S_OK;
+}
+
+static void dll_list_free(struct open_dll *entry)
+{
+    TRACE("freeing %s\n", debugstr_a(entry->library_name));
+
+    list_remove(&entry->entry);
+    FreeLibrary16(entry->library);
+    HeapFree(GetProcessHeap(), 0, entry->library_name);
+    HeapFree(GetProcessHeap(), 0, entry);
+}
+
+/******************************************************************************
+ *           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)
+        {
+            if(InterlockedDecrement(&dll->refs) == 0)
+                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