This source file includes following definitions.
- get_vtable
- vl_exit
- vm_open
- vm_close
- vm_sym
- loadlibraryerror
- wrap_getthreaderrormode
- fallback_getthreaderrormode
- wrap_setthreaderrormode
- fallback_setthreaderrormode
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32 #include "lt__private.h"
33 #include "lt_dlloader.h"
34
35 #if defined(__CYGWIN__)
36 # include <sys/cygwin.h>
37 #endif
38
39
40
41
42
43 #define get_vtable loadlibrary_LTX_get_vtable
44
45 LT_BEGIN_C_DECLS
46 LT_SCOPE lt_dlvtable *get_vtable (lt_user_data loader_data);
47 LT_END_C_DECLS
48
49
50
51
52 static int vl_exit (lt_user_data loader_data);
53 static lt_module vm_open (lt_user_data loader_data, const char *filename,
54 lt_dladvise advise);
55 static int vm_close (lt_user_data loader_data, lt_module module);
56 static void * vm_sym (lt_user_data loader_data, lt_module module,
57 const char *symbolname);
58
59 static lt_dlinterface_id iface_id = 0;
60 static lt_dlvtable *vtable = 0;
61
62
63
64
65 lt_dlvtable *
66 get_vtable (lt_user_data loader_data)
67 {
68 if (!vtable)
69 {
70 vtable = (lt_dlvtable *) lt__zalloc (sizeof *vtable);
71 iface_id = lt_dlinterface_register ("ltdl loadlibrary", NULL);
72 }
73
74 if (vtable && !vtable->name)
75 {
76 vtable->name = "lt_loadlibrary";
77 vtable->module_open = vm_open;
78 vtable->module_close = vm_close;
79 vtable->find_sym = vm_sym;
80 vtable->dlloader_exit = vl_exit;
81 vtable->dlloader_data = loader_data;
82 vtable->priority = LT_DLLOADER_APPEND;
83 }
84
85 if (vtable && (vtable->dlloader_data != loader_data))
86 {
87 LT__SETERROR (INIT_LOADER);
88 return 0;
89 }
90
91 return vtable;
92 }
93
94
95
96
97
98
99 #include <windows.h>
100
101 #define LOCALFREE(mem) LT_STMT_START { \
102 if (mem) { LocalFree ((void *)mem); mem = NULL; } } LT_STMT_END
103 #define LOADLIB__SETERROR(errmsg) LT__SETERRORSTR (loadlibraryerror (errmsg))
104 #define LOADLIB_SETERROR(errcode) LOADLIB__SETERROR (LT__STRERROR (errcode))
105
106 static const char *loadlibraryerror (const char *default_errmsg);
107 static DWORD WINAPI wrap_getthreaderrormode (void);
108 static DWORD WINAPI fallback_getthreaderrormode (void);
109 static BOOL WINAPI wrap_setthreaderrormode (DWORD mode, DWORD *oldmode);
110 static BOOL WINAPI fallback_setthreaderrormode (DWORD mode, DWORD *oldmode);
111
112 typedef DWORD (WINAPI getthreaderrormode_type) (void);
113 typedef BOOL (WINAPI setthreaderrormode_type) (DWORD, DWORD *);
114
115 static getthreaderrormode_type *getthreaderrormode = wrap_getthreaderrormode;
116 static setthreaderrormode_type *setthreaderrormode = wrap_setthreaderrormode;
117 static char *error_message = 0;
118
119
120
121
122 static int
123 vl_exit (lt_user_data LT__UNUSED loader_data)
124 {
125 vtable = NULL;
126 LOCALFREE (error_message);
127 return 0;
128 }
129
130
131
132
133 static lt_module
134 vm_open (lt_user_data LT__UNUSED loader_data, const char *filename,
135 lt_dladvise LT__UNUSED advise)
136 {
137 lt_module module = 0;
138 char *ext;
139 char wpath[MAX_PATH];
140 size_t len;
141
142 if (!filename)
143 {
144
145 *wpath = 0;
146 GetModuleFileName (NULL, wpath, sizeof (wpath));
147 filename = wpath;
148 }
149 else
150 {
151 len = LT_STRLEN (filename);
152
153 if (len >= MAX_PATH)
154 {
155 LT__SETERROR (CANNOT_OPEN);
156 return 0;
157 }
158
159 #if HAVE_DECL_CYGWIN_CONV_PATH
160 if (cygwin_conv_path (CCP_POSIX_TO_WIN_A, filename, wpath, MAX_PATH))
161 {
162 LT__SETERROR (CANNOT_OPEN);
163 return 0;
164 }
165 len = 0;
166 #elif defined(__CYGWIN__)
167 cygwin_conv_to_full_win32_path (filename, wpath);
168 len = 0;
169 #else
170 strcpy(wpath, filename);
171 #endif
172
173 ext = strrchr (wpath, '.');
174 if (!ext)
175 {
176
177
178 if (!len)
179 len = strlen (wpath);
180
181 if (len + 1 >= MAX_PATH)
182 {
183 LT__SETERROR (CANNOT_OPEN);
184 return 0;
185 }
186
187 wpath[len] = '.';
188 wpath[len+1] = '\0';
189 }
190 }
191
192 {
193
194 DWORD errormode = getthreaderrormode ();
195 DWORD last_error;
196
197 setthreaderrormode (errormode | SEM_FAILCRITICALERRORS, NULL);
198
199 module = LoadLibrary (wpath);
200
201
202 last_error = GetLastError ();
203 setthreaderrormode (errormode, NULL);
204 SetLastError (last_error);
205 }
206
207
208
209
210
211
212
213
214
215 {
216 lt_dlhandle cur = 0;
217
218 while ((cur = lt_dlhandle_iterate (iface_id, cur)))
219 {
220 if (!cur->module)
221 {
222 cur = 0;
223 break;
224 }
225
226 if (cur->module == module)
227 {
228 break;
229 }
230 }
231
232 if (!module)
233 LOADLIB_SETERROR (CANNOT_OPEN);
234 else if (cur)
235 {
236 LT__SETERROR (CANNOT_OPEN);
237 module = 0;
238 }
239 }
240
241 return module;
242 }
243
244
245
246
247 static int
248 vm_close (lt_user_data LT__UNUSED loader_data, lt_module module)
249 {
250 int errors = 0;
251
252 if (FreeLibrary ((HMODULE) module) == 0)
253 {
254 LOADLIB_SETERROR (CANNOT_CLOSE);
255 ++errors;
256 }
257
258 return errors;
259 }
260
261
262
263
264 static void *
265 vm_sym (lt_user_data LT__UNUSED loader_data, lt_module module, const char *name)
266 {
267 void *address = (void *) GetProcAddress ((HMODULE) module, name);
268
269 if (!address)
270 {
271 LOADLIB_SETERROR (SYMBOL_NOT_FOUND);
272 }
273
274 return address;
275 }
276
277
278
279
280
281
282
283
284 static const char *
285 loadlibraryerror (const char *default_errmsg)
286 {
287 size_t len;
288 LOCALFREE (error_message);
289
290 FormatMessageA (FORMAT_MESSAGE_ALLOCATE_BUFFER |
291 FORMAT_MESSAGE_FROM_SYSTEM |
292 FORMAT_MESSAGE_IGNORE_INSERTS,
293 NULL,
294 GetLastError (),
295 0,
296 (char *) &error_message,
297 0, NULL);
298
299
300 len = LT_STRLEN (error_message);
301 if (len && error_message[len - 1] == '\n')
302 error_message[--len] = LT_EOS_CHAR;
303 if (len && error_message[len - 1] == '\r')
304 error_message[--len] = LT_EOS_CHAR;
305
306 return len ? error_message : default_errmsg;
307 }
308
309
310
311
312
313 static DWORD WINAPI
314 wrap_getthreaderrormode (void)
315 {
316 HMODULE kernel32 = GetModuleHandleA ("kernel32.dll");
317 getthreaderrormode
318 = (getthreaderrormode_type *) GetProcAddress (kernel32,
319 "GetThreadErrorMode");
320 if (!getthreaderrormode)
321 getthreaderrormode
322 = (getthreaderrormode_type *) GetProcAddress (kernel32,
323 "GetErrorMode");
324 if (!getthreaderrormode)
325 getthreaderrormode = fallback_getthreaderrormode;
326 return getthreaderrormode ();
327 }
328
329
330
331 static DWORD WINAPI
332 fallback_getthreaderrormode (void)
333 {
334
335
336
337
338
339 return (DWORD) SetErrorMode (SEM_FAILCRITICALERRORS);
340 }
341
342
343
344
345
346 static BOOL WINAPI
347 wrap_setthreaderrormode (DWORD mode, DWORD *oldmode)
348 {
349 HMODULE kernel32 = GetModuleHandleA ("kernel32.dll");
350 setthreaderrormode
351 = (setthreaderrormode_type *) GetProcAddress (kernel32,
352 "SetThreadErrorMode");
353 if (!setthreaderrormode)
354 setthreaderrormode = fallback_setthreaderrormode;
355 return setthreaderrormode (mode, oldmode);
356 }
357
358
359
360 static BOOL WINAPI
361 fallback_setthreaderrormode (DWORD mode, DWORD *oldmode)
362 {
363
364
365 DWORD old = (DWORD) SetErrorMode (mode);
366 if (oldmode)
367 *oldmode = old;
368 return TRUE;
369 }