Merge pull request #5714 from alexischr/update_bockbuild
[mono.git] / mono / utils / mono-dl-windows.c
1 /**
2  * \file
3  * Interface to the dynamic linker
4  *
5  * Author:
6  *    Mono Team (http://www.mono-project.com)
7  *
8  * Copyright 2001-2004 Ximian, Inc.
9  * Copyright 2004-2009 Novell, Inc.
10  * Licensed under the MIT license. See LICENSE file in the project root for full license information.
11  */
12 #include <config.h>
13
14 #if defined(HOST_WIN32)
15
16 #include "mono/utils/mono-dl.h"
17 #include "mono/utils/mono-dl-windows-internals.h"
18 #include "mono/utils/mono-embed.h"
19 #include "mono/utils/mono-path.h"
20
21 #include <stdlib.h>
22 #include <stdio.h>
23 #include <ctype.h>
24 #include <string.h>
25 #include <glib.h>
26
27 #include <windows.h>
28 #include <psapi.h>
29
30 const char*
31 mono_dl_get_so_prefix (void)
32 {
33         return "";
34 }
35
36 const char**
37 mono_dl_get_so_suffixes (void)
38 {
39         static const char *suffixes[] = {
40                 ".dll",
41                 "",
42         };
43         return suffixes;
44 }
45
46 void*
47 mono_dl_open_file (const char *file, int flags)
48 {
49         gpointer hModule = NULL;
50         if (file) {
51                 gunichar2* file_utf16 = g_utf8_to_utf16 (file, strlen (file), NULL, NULL, NULL);
52
53 #if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
54                 guint last_sem = SetErrorMode (SEM_FAILCRITICALERRORS);
55 #endif
56                 guint32 last_error = 0;
57
58                 hModule = LoadLibrary (file_utf16);
59                 if (!hModule)
60                         last_error = GetLastError ();
61
62 #if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
63                 SetErrorMode (last_sem);
64 #endif
65
66                 g_free (file_utf16);
67
68                 if (!hModule)
69                         SetLastError (last_error);
70         } else {
71                 hModule = GetModuleHandle (NULL);
72         }
73         return hModule;
74 }
75
76 void
77 mono_dl_close_handle (MonoDl *module)
78 {
79         if (!module->main_module)
80                 FreeLibrary (module->handle);
81 }
82
83 #if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
84 void*
85 mono_dl_lookup_symbol_in_process (const char *symbol_name)
86 {
87         HMODULE *modules;
88         DWORD buffer_size = sizeof (HMODULE) * 1024;
89         DWORD needed, i;
90         gpointer proc = NULL;
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 #endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
132
133 void*
134 mono_dl_lookup_symbol (MonoDl *module, const char *symbol_name)
135 {
136         gpointer proc = NULL;
137
138         /* get the symbol directly from the specified module */
139         if (!module->main_module)
140                 return GetProcAddress (module->handle, symbol_name);
141
142         /* get the symbol from the main module */
143         proc = GetProcAddress (module->handle, symbol_name);
144         if (proc != NULL)
145                 return proc;
146
147         /* get the symbol from the loaded DLLs */
148         return mono_dl_lookup_symbol_in_process (symbol_name);
149 }
150
151 int
152 mono_dl_convert_flags (int flags)
153 {
154         return 0;
155 }
156
157 #if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
158 char*
159 mono_dl_current_error_string (void)
160 {
161         char* ret = NULL;
162         wchar_t* buf = NULL;
163         DWORD code = GetLastError ();
164
165         if (FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS, NULL,
166                 code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&buf, 0, NULL))
167         {
168                 ret = g_utf16_to_utf8 (buf, wcslen(buf), NULL, NULL, NULL);
169                 LocalFree (buf);
170         } else {
171                 g_assert_not_reached ();
172         }
173         return ret;
174 }
175 #endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
176
177 int
178 mono_dl_get_executable_path (char *buf, int buflen)
179 {
180         return -1; //TODO
181 }
182
183 const char*
184 mono_dl_get_system_dir (void)
185 {
186         return NULL;
187 }
188 #endif