[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