Merge pull request #1508 from slluis/fix-20966
[mono.git] / mono / utils / mono-dl-windows.c
1 /*
2  * mono-dl.c: Interface to the dynamic linker
3  *
4  * Author:
5  *    Mono Team (http://www.mono-project.com)
6  *
7  * Copyright 2001-2004 Ximian, Inc.
8  * Copyright 2004-2009 Novell, Inc.
9  */
10 #include <config.h>
11
12 #if defined(HOST_WIN32)
13
14 #include "mono/utils/mono-dl.h"
15 #include "mono/utils/mono-embed.h"
16 #include "mono/utils/mono-path.h"
17
18 #include <stdlib.h>
19 #include <stdio.h>
20 #include <ctype.h>
21 #include <string.h>
22 #include <glib.h>
23
24 #include <windows.h>
25 #include <psapi.h>
26
27
28 const char*
29 mono_dl_get_so_prefix (void)
30 {
31         return "";
32 }
33
34 const char**
35 mono_dl_get_so_suffixes (void)
36 {
37         static const char *suffixes[] = {
38                 ".dll",
39                 "",
40         };
41         return suffixes;
42 }
43
44 void*
45 mono_dl_open_file (const char *file, int flags)
46 {
47         gpointer hModule = NULL;
48         if (file) {
49                 gunichar2* file_utf16 = g_utf8_to_utf16 (file, strlen (file), NULL, NULL, NULL);
50                 guint last_sem = SetErrorMode (SEM_FAILCRITICALERRORS);
51                 guint32 last_error = 0;
52
53                 hModule = LoadLibrary (file_utf16);
54                 if (!hModule)
55                         last_error = GetLastError ();
56
57                 SetErrorMode (last_sem);
58                 g_free (file_utf16);
59
60                 if (!hModule)
61                         SetLastError (last_error);
62         } else {
63                 hModule = GetModuleHandle (NULL);
64         }
65         return hModule;
66 }
67
68 void
69 mono_dl_close_handle (MonoDl *module)
70 {
71         if (!module->main_module)
72                 FreeLibrary (module->handle);
73 }
74
75 void*
76 mono_dl_lookup_symbol (MonoDl *module, const char *symbol_name)
77 {
78         HMODULE *modules;
79         DWORD buffer_size = sizeof (HMODULE) * 1024;
80         DWORD needed, i;
81         gpointer proc = NULL;
82
83         /* get the symbol directly from the specified module */
84         if (!module->main_module)
85                 return GetProcAddress (module->handle, symbol_name);
86
87         /* get the symbol from the main module */
88         proc = GetProcAddress (module->handle, symbol_name);
89         if (proc != NULL)
90                 return proc;
91
92         /* get the symbol from the loaded DLLs */
93         modules = (HMODULE *) g_malloc (buffer_size);
94         if (modules == NULL)
95                 return NULL;
96
97         if (!EnumProcessModules (GetCurrentProcess (), modules,
98                                  buffer_size, &needed)) {
99                 g_free (modules);
100                 return NULL;
101         }
102
103         /* check whether the supplied buffer was too small, realloc, retry */
104         if (needed > buffer_size) {
105                 g_free (modules);
106
107                 buffer_size = needed;
108                 modules = (HMODULE *) g_malloc (buffer_size);
109
110                 if (modules == NULL)
111                         return NULL;
112
113                 if (!EnumProcessModules (GetCurrentProcess (), modules,
114                                          buffer_size, &needed)) {
115                         g_free (modules);
116                         return NULL;
117                 }
118         }
119
120         for (i = 0; i < needed / sizeof (HANDLE); i++) {
121                 proc = GetProcAddress (modules [i], symbol_name);
122                 if (proc != NULL) {
123                         g_free (modules);
124                         return proc;
125                 }
126         }
127
128         g_free (modules);
129         return NULL;
130 }
131
132 int
133 mono_dl_convert_flags (int flags)
134 {
135         return 0;
136 }
137
138 char*
139 mono_dl_current_error_string (void)
140 {
141         char* ret = NULL;
142         wchar_t* buf = NULL;
143         DWORD code = GetLastError ();
144
145         if (FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS, NULL,
146                 code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&buf, 0, NULL))
147         {
148                 ret = g_utf16_to_utf8 (buf, wcslen(buf), NULL, NULL, NULL);
149                 LocalFree (buf);
150         } else {
151                 g_assert_not_reached ();
152         }
153         return ret;
154 }
155
156 int
157 mono_dl_get_executable_path (char *buf, int buflen)
158 {
159         return -1; //TODO
160 }
161
162 #endif