2010-04-06 Rodrigo Kumpera <rkumpera@novell.com>
[mono.git] / eglib / src / gmodule-win32.c
bloba51d50064e712d78381a8fd518794c10da23cbf5
1 /*
2 * gmodule.c: dl* functions, glib style
4 * Author:
5 * Gonzalo Paniagua Javier (gonzalo@novell.com)
6 * Jonathan Chambers (joncham@gmail.com)
7 * Robert Jordan (robertj@gmx.net)
9 * (C) 2006 Novell, Inc.
10 * (C) 2006 Jonathan Chambers
12 * Permission is hereby granted, free of charge, to any person obtaining
13 * a copy of this software and associated documentation files (the
14 * "Software"), to deal in the Software without restriction, including
15 * without limitation the rights to use, copy, modify, merge, publish,
16 * distribute, sublicense, and/or sell copies of the Software, and to
17 * permit persons to whom the Software is furnished to do so, subject to
18 * the following conditions:
20 * The above copyright notice and this permission notice shall be
21 * included in all copies or substantial portions of the Software.
23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
27 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
28 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
29 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 #include <glib.h>
32 #include <gmodule.h>
33 #include <windows.h>
34 #include <psapi.h>
36 #define LIBSUFFIX ".dll"
37 #define LIBPREFIX ""
39 struct _GModule {
40 HMODULE handle;
41 int main_module;
44 GModule *
45 g_module_open (const gchar *file, GModuleFlags flags)
47 GModule *module;
48 module = g_malloc (sizeof (GModule));
49 if (module == NULL)
50 return NULL;
52 if (file != NULL) {
53 gunichar2 *file16;
54 file16 = u8to16(file);
55 module->main_module = FALSE;
56 module->handle = LoadLibrary (file16);
57 g_free(file16);
58 if (!module->handle) {
59 g_free (module);
60 return NULL;
63 } else {
64 module->main_module = TRUE;
65 module->handle = GetModuleHandle (NULL);
68 return module;
71 static gpointer
72 w32_find_symbol (const gchar *symbol_name)
74 HMODULE *modules;
75 DWORD buffer_size = sizeof (HMODULE) * 1024;
76 DWORD needed, i;
78 modules = (HMODULE *) g_malloc (buffer_size);
80 if (modules == NULL)
81 return NULL;
83 if (!EnumProcessModules (GetCurrentProcess (), modules,
84 buffer_size, &needed)) {
85 g_free (modules);
86 return NULL;
89 /* check whether the supplied buffer was too small, realloc, retry */
90 if (needed > buffer_size) {
91 g_free (modules);
93 buffer_size = needed;
94 modules = (HMODULE *) g_malloc (buffer_size);
96 if (modules == NULL)
97 return NULL;
99 if (!EnumProcessModules (GetCurrentProcess (), modules,
100 buffer_size, &needed)) {
101 g_free (modules);
102 return NULL;
106 for (i = 0; i < needed / sizeof (HANDLE); i++) {
107 gpointer proc = (gpointer)(intptr_t)GetProcAddress (modules [i], symbol_name);
108 if (proc != NULL) {
109 g_free (modules);
110 return proc;
114 g_free (modules);
115 return NULL;
118 gboolean
119 g_module_symbol (GModule *module, const gchar *symbol_name, gpointer *symbol)
121 if (module == NULL || symbol_name == NULL || symbol == NULL)
122 return FALSE;
124 if (module->main_module) {
125 *symbol = (gpointer)(intptr_t)GetProcAddress (module->handle, symbol_name);
126 if (*symbol != NULL)
127 return TRUE;
129 *symbol = w32_find_symbol (symbol_name);
130 return *symbol != NULL;
131 } else {
132 *symbol = (gpointer)(intptr_t)GetProcAddress (module->handle, symbol_name);
133 return *symbol != NULL;
137 const gchar *
138 g_module_error (void)
140 gchar* ret = NULL;
141 TCHAR* buf = NULL;
142 DWORD code = GetLastError ();
144 FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL,
145 code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), buf, 0, NULL);
147 ret = u16to8 (buf);
148 LocalFree(buf);
150 return ret;
153 gboolean
154 g_module_close (GModule *module)
156 HMODULE handle;
157 int main_module;
159 if (module == NULL || module->handle == NULL)
160 return FALSE;
162 handle = module->handle;
163 main_module = module->main_module;
164 module->handle = NULL;
165 g_free (module);
166 return (main_module ? 1 : (0 == FreeLibrary (handle)));
169 gchar *
170 g_module_build_path (const gchar *directory, const gchar *module_name)
172 char *lib_prefix = "";
174 if (module_name == NULL)
175 return NULL;
177 if (strncmp (module_name, "lib", 3) != 0)
178 lib_prefix = LIBPREFIX;
180 if (directory && *directory){
182 return g_strdup_printf ("%s/%s%s" LIBSUFFIX, directory, lib_prefix, module_name);
184 return g_strdup_printf ("%s%s" LIBSUFFIX, lib_prefix, module_name);