2007-01-26 Robert Jordan <robertj@gmx.net>
authorRobert Jordan <robertj@gmx.net>
Fri, 26 Jan 2007 16:10:07 +0000 (16:10 -0000)
committerRobert Jordan <robertj@gmx.net>
Fri, 26 Jan 2007 16:10:07 +0000 (16:10 -0000)
* mono-dl.c (w32_find_symbol): Implement in-proc symbol lookup
for Win32.

svn path=/trunk/mono/; revision=71753

mono/utils/ChangeLog
mono/utils/mono-dl.c

index 26193969fde555329bd470f52dffed4cf5c600a3..485444df54668757d84b2f460a31864761fda2c2 100644 (file)
@@ -1,3 +1,7 @@
+2007-01-26  Robert Jordan  <robertj@gmx.net>
+
+       * mono-dl.c (w32_find_symbol): Implement in-proc symbol lookup
+       for Win32.
 
 Fri Jan 26 13:06:57 CET 2007 Paolo Molaro <lupus@ximian.com>
 
index 18edc792af651111d64fa728dacb5e1700f1a1a8..f424975aaaf8024fcc5634ed67be691590d13a42 100644 (file)
@@ -29,29 +29,15 @@ static const char suffixes [][4] = {
 #ifdef PLATFORM_WIN32
 
 #include <windows.h>
+#include <psapi.h>
 
 #define SO_HANDLE_TYPE HMODULE
 #define LL_SO_OPEN(file,flags) (file)? LoadLibrary ((file)): GetModuleHandle (NULL)
 #define LL_SO_CLOSE(module) do { if (!(module)->main_module) FreeLibrary ((module)->handle); } while (0)
-#define LL_SO_SYMBOL(module, name) GetProcAddress ((module)->handle, (name))
+#define LL_SO_SYMBOL(module, name) w32_find_symbol ((module), (name))
 #define LL_SO_TRFLAGS(flags) 0
 #define LL_SO_ERROR() w32_dlerror ()
 
-static char*
-w32_dlerror (void)
-{
-       char* ret;
-       TCHAR* buf = NULL;
-       DWORD code = GetLastError ();
-
-       FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL,
-               code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), buf, 0, NULL);
-
-       ret = g_strdup (buf);
-       LocalFree (buf);
-       return ret;
-}
-
 #elif defined (HAVE_DL_LOADER)
 
 #include <dlfcn.h>
@@ -80,7 +66,7 @@ convert_flags (int flags)
 }
 
 #else
-/* no duynamic loader supported */
+/* no dynamic loader supported */
 #define SO_HANDLE_TYPE void*
 #define LL_SO_OPEN(file,flags) NULL
 #define LL_SO_CLOSE(module) 
@@ -95,6 +81,81 @@ struct _MonoDl {
        int main_module;
 };
 
+#ifdef PLATFORM_WIN32
+
+static char*
+w32_dlerror (void)
+{
+       char* ret;
+       TCHAR* buf = NULL;
+       DWORD code = GetLastError ();
+
+       FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL,
+               code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), buf, 0, NULL);
+
+       ret = g_strdup (buf);
+       LocalFree (buf);
+       return ret;
+}
+
+static gpointer
+w32_find_symbol (MonoDl *module, const gchar *symbol_name)
+{
+       HMODULE *modules;
+       DWORD buffer_size = sizeof (HMODULE) * 1024;
+       DWORD needed, i;
+       gpointer proc = NULL;
+
+       /* get the symbol directly from the specified module */
+       if (!module->main_module)
+               return GetProcAddress (module->handle, symbol_name);
+
+       /* get the symbol from the main module */
+       proc = GetProcAddress (module->handle, symbol_name);
+       if (proc != NULL)
+               return proc;
+
+       /* get the symbol from the loaded DLLs */
+       modules = (HMODULE *) g_malloc (buffer_size);
+       if (modules == NULL)
+               return NULL;
+
+       if (!EnumProcessModules (GetCurrentProcess (), modules,
+                                buffer_size, &needed)) {
+               g_free (modules);
+               return NULL;
+       }
+
+       /* check whether the supplied buffer was too small, realloc, retry */
+       if (needed > buffer_size) {
+               g_free (modules);
+
+               buffer_size = needed;
+               modules = (HMODULE *) g_malloc (buffer_size);
+
+               if (modules == NULL)
+                       return NULL;
+
+               if (!EnumProcessModules (GetCurrentProcess (), modules,
+                                        buffer_size, &needed)) {
+                       g_free (modules);
+                       return NULL;
+               }
+       }
+
+       for (i = 0; i < needed / sizeof (HANDLE); i++) {
+               proc = GetProcAddress (modules [i], symbol_name);
+               if (proc != NULL) {
+                       g_free (modules);
+                       return proc;
+               }
+       }
+
+       g_free (modules);
+       return NULL;
+}
+
+#endif
 
 /*
  * read a value string from line with any of the following formats: