summaryrefslogtreecommitdiff
path: root/gmodule
diff options
context:
space:
mode:
authorTor Lillqvist <tml@iki.fi>2000-03-22 22:34:48 +0000
committerTor Lillqvist <tml@src.gnome.org>2000-03-22 22:34:48 +0000
commit28bd47860b8129d76699d11796928fa148541036 (patch)
tree8b123c465cf810bf4e479b4de0b68b8c5d366597 /gmodule
parente0786b05e6b9ed0bec42d780624832c4232b2d7c (diff)
downloadglib-28bd47860b8129d76699d11796928fa148541036.tar.gz
When looking for symbols in the "main" module we must search both the main
2000-03-23 Tor Lillqvist <tml@iki.fi> * gmodule-win32.c (_g_module_symbol): When looking for symbols in the "main" module we must search both the main program and all currently loaded DLLs. Not only the main program, or even just the DLLs loaded as gmodules. Libglade requires this. Thus we need to get a list of all modules in the current process. There are two alternative APIs to do this: PSAPI and Toolhelp. The former is only available on NT (including Win2k), the latter on Win9x and Win2k. Check which one works, and use that. Code for using PSAPI and Toolhelp was borrowed from the Dr. Mingw tool written by José Fonseca <em96115@fe.up.pt>. Thanks.
Diffstat (limited to 'gmodule')
-rw-r--r--gmodule/ChangeLog16
-rw-r--r--gmodule/gmodule-win32.c135
2 files changed, 141 insertions, 10 deletions
diff --git a/gmodule/ChangeLog b/gmodule/ChangeLog
index fa58bd49b..b40bbfd89 100644
--- a/gmodule/ChangeLog
+++ b/gmodule/ChangeLog
@@ -1,3 +1,19 @@
+2000-03-23 Tor Lillqvist <tml@iki.fi>
+
+ * gmodule-win32.c (_g_module_symbol): When looking for symbols in
+ the "main" module we must search both the main program and all
+ currently loaded DLLs. Not only the main program, or even just the
+ DLLs loaded as gmodules. Libglade requires this.
+
+ Thus we need to get a list of all modules in the current
+ process. There are two alternative APIs to do this: PSAPI and
+ Toolhelp. The former is only available on NT (including Win2k),
+ the latter on Win9x and Win2k. Check which one works, and use
+ that.
+
+ Code for using PSAPI and Toolhelp was borrowed from the Dr. Mingw
+ tool written by José Fonseca <em96115@fe.up.pt>. Thanks.
+
2000-03-04 Tor Lillqvist <tml@iki.fi>
* gmodule-win32.c: Call g_win32_error_message() to get the error
diff --git a/gmodule/gmodule-win32.c b/gmodule/gmodule-win32.c
index 5654ce089..6bcef9ff1 100644
--- a/gmodule/gmodule-win32.c
+++ b/gmodule/gmodule-win32.c
@@ -33,6 +33,8 @@
#include <stdio.h>
#include <windows.h>
+#include <psapi.h>
+#include <tlhelp32.h>
static void
set_error (void)
@@ -57,24 +59,133 @@ _g_module_open (const gchar *file_name,
return handle;
}
+static gint dummy;
+static gpointer null_module_handle = &dummy;
+
static gpointer
_g_module_self (void)
{
- HMODULE handle;
-
- handle = GetModuleHandle (NULL);
- if (!handle)
- set_error ();
-
- return handle;
+ return null_module_handle;
}
static void
_g_module_close (gpointer handle,
gboolean is_unref)
{
- if (!FreeLibrary (handle))
- set_error ();
+ if (handle != null_module_handle)
+ if (!FreeLibrary (handle))
+ set_error ();
+}
+
+static gpointer
+find_in_any_module_using_toolhelp (const gchar *symbol_name)
+{
+ typedef HANDLE (WINAPI *PFNCREATETOOLHELP32SNAPSHOT)(DWORD, DWORD);
+ static PFNCREATETOOLHELP32SNAPSHOT pfnCreateToolhelp32Snapshot = NULL;
+
+ typedef BOOL (WINAPI *PFNMODULE32FIRST)(HANDLE, LPMODULEENTRY32);
+ static PFNMODULE32FIRST pfnModule32First= NULL;
+
+ typedef BOOL (WINAPI *PFNMODULE32NEXT)(HANDLE, LPMODULEENTRY32);
+ static PFNMODULE32NEXT pfnModule32Next = NULL;
+
+ static HMODULE kernel32;
+
+ HANDLE snapshot;
+ MODULEENTRY32 me32;
+
+ gpointer p;
+
+ if (!pfnCreateToolhelp32Snapshot || !pfnModule32First || !pfnModule32Next)
+ {
+ if (!kernel32)
+ if (!(kernel32 = GetModuleHandle ("kernel32.dll")))
+ return NULL;
+
+ if (!(pfnCreateToolhelp32Snapshot = (PFNCREATETOOLHELP32SNAPSHOT) GetProcAddress (kernel32, "CreateToolhelp32Snapshot"))
+ || !(pfnModule32First = (PFNMODULE32FIRST) GetProcAddress (kernel32, "Module32First"))
+ || !(pfnModule32Next = (PFNMODULE32NEXT) GetProcAddress (kernel32, "Module32Next")))
+ return NULL;
+ }
+
+ if ((snapshot = (*pfnCreateToolhelp32Snapshot) (TH32CS_SNAPMODULE, 0)) == (HANDLE) -1)
+ return NULL;
+
+ me32.dwSize = sizeof (me32);
+ p = NULL;
+ if ((*pfnModule32First) (snapshot, &me32))
+ {
+ do {
+ if ((p = GetProcAddress (me32.hModule, symbol_name)) != NULL)
+ break;
+ } while ((*pfnModule32Next) (snapshot, &me32));
+ }
+
+ CloseHandle (snapshot);
+
+ return p;
+}
+
+static gpointer
+find_in_any_module_using_psapi (const gchar *symbol_name)
+{
+ static HMODULE psapi = NULL;
+
+ typedef BOOL (WINAPI *PFNENUMPROCESSMODULES) (HANDLE, HMODULE *, DWORD, LPDWORD) ;
+ static PFNENUMPROCESSMODULES pfnEnumProcessModules = NULL;
+
+ HMODULE *modules;
+ HMODULE dummy;
+ gint i, size;
+ DWORD needed;
+
+ gpointer p;
+
+ if (!pfnEnumProcessModules)
+ {
+ if (!psapi)
+ if ((psapi = LoadLibrary ("psapi.dll")) == NULL)
+ return NULL;
+
+ if (!(pfnEnumProcessModules = (PFNENUMPROCESSMODULES) GetProcAddress (psapi, "EnumProcessModules")))
+ return NULL;
+ }
+
+ if (!(*pfnEnumProcessModules) (GetCurrentProcess (), &dummy,
+ sizeof (HMODULE), &needed))
+ return NULL;
+
+ size = needed + 10 * sizeof (HMODULE);
+ modules = g_malloc (size);
+
+ if (!(*pfnEnumProcessModules) (GetCurrentProcess (), modules,
+ size, &needed)
+ || needed > size)
+ {
+ g_free (modules);
+ return NULL;
+ }
+
+ p = NULL;
+ for (i = 0; i < needed / sizeof (HMODULE); i++)
+ if ((p = GetProcAddress (modules[i], symbol_name)) != NULL)
+ break;
+
+ g_free (modules);
+
+ return p;
+}
+
+static gpointer
+find_in_any_module (const gchar *symbol_name)
+{
+ gpointer result;
+
+ if ((result = find_in_any_module_using_toolhelp (symbol_name)) == NULL
+ && (result = find_in_any_module_using_psapi (symbol_name)) == NULL)
+ return NULL;
+ else
+ return result;
}
static gpointer
@@ -83,7 +194,11 @@ _g_module_symbol (gpointer handle,
{
gpointer p;
- p = GetProcAddress (handle, symbol_name);
+ if (handle == null_module_handle)
+ p = find_in_any_module (symbol_name);
+ else
+ p = GetProcAddress (handle, symbol_name);
+
if (!p)
set_error ();