X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Futils%2Fmono-dl.c;h=1986112a5d02dd4198b6673384d0d9de4f1a3032;hb=053d1dfd787b5e0151d3d370889a1c06bab72670;hp=c65e380e9228fb6d0d9a967aec44bb879aa74b5f;hpb=cd97c0ad578ccce5557f8b5d9cbfbe10e7c4656a;p=mono.git diff --git a/mono/utils/mono-dl.c b/mono/utils/mono-dl.c index c65e380e922..1986112a5d0 100644 --- a/mono/utils/mono-dl.c +++ b/mono/utils/mono-dl.c @@ -29,29 +29,15 @@ static const char suffixes [][4] = { #ifdef PLATFORM_WIN32 #include +#include #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(handle, name) GetProcAddress ((handle), (name)) +#define LL_SO_OPEN(file,flags) w32_load_module ((file), (flags)) +#define LL_SO_CLOSE(module) do { if (!(module)->main_module) FreeLibrary ((module)->handle); } while (0) +#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 @@ -62,8 +48,8 @@ w32_dlerror (void) #define SO_HANDLE_TYPE void* #define LL_SO_OPEN(file,flags) dlopen ((file), (flags)) -#define LL_SO_CLOSE(handle) dlclose ((handle)) -#define LL_SO_SYMBOL(handle, name) dlsym ((handle), (name)) +#define LL_SO_CLOSE(module) dlclose ((module)->handle) +#define LL_SO_SYMBOL(module, name) dlsym ((module)->handle, (name)) #define LL_SO_TRFLAGS(flags) convert_flags ((flags)) #define LL_SO_ERROR() g_strdup (dlerror ()) @@ -80,11 +66,11 @@ 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(handle) -#define LL_SO_SYMBOL(handle, name) NULL +#define LL_SO_CLOSE(module) +#define LL_SO_SYMBOL(module, name) NULL #define LL_SO_TRFLAGS(flags) (flags) #define LL_SO_ERROR() g_strdup ("No support for dynamic loader") @@ -95,6 +81,101 @@ struct _MonoDl { int main_module; }; +#ifdef PLATFORM_WIN32 + +static char* +w32_dlerror (void) +{ + char* ret = NULL; + wchar_t* buf = NULL; + DWORD code = GetLastError (); + + if (FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, + code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), &buf, 0, NULL)) + { + ret = g_utf16_to_utf8 (buf, wcslen(buf), NULL, NULL, NULL); + LocalFree (buf); + } else { + g_assert_not_reached (); + } + 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; +} + + +static gpointer +w32_load_module (const char* file, int flags) +{ + gpointer hModule = NULL; + if (file) + { + gunichar2* file_utf16 = g_utf8_to_utf16 (file, strlen (file), NULL, NULL, NULL); + hModule = LoadLibrary (file_utf16); + g_free (file_utf16); + } + else + { + hModule = GetModuleHandle (NULL); + } + return hModule; +} +#endif /* * read a value string from line with any of the following formats: @@ -262,11 +343,11 @@ mono_dl_symbol (MonoDl *module, const char *name, void **symbol) char *usname = malloc (strlen (name) + 2); *usname = '_'; strcpy (usname + 1, name); - sym = LL_SO_SYMBOL (module->handle, usname); + sym = LL_SO_SYMBOL (module, usname); free (usname); } #else - sym = LL_SO_SYMBOL (module->handle, name); + sym = LL_SO_SYMBOL (module, name); #endif if (sym) { if (symbol)