diff options
author | Ralf Habacker <ralf.habacker@freenet.de> | 2020-08-25 23:34:19 +0200 |
---|---|---|
committer | Ralf Habacker <ralf.habacker@freenet.de> | 2020-09-14 12:26:07 +0200 |
commit | f0ac8495872ee078f18bd349e3db6883ed4106e2 (patch) | |
tree | 0f9b609aa80b924f6b391e1c4b687c0f73eaa7b9 /src | |
parent | 5ead6f2d2c515d3d85c31fffebea55168c1bc1b4 (diff) | |
download | dlfcn-win32-f0ac8495872ee078f18bd349e3db6883ed4106e2.tar.gz dlfcn-win32-f0ac8495872ee078f18bd349e3db6883ed4106e2.tar.bz2 dlfcn-win32-f0ac8495872ee078f18bd349e3db6883ed4106e2.zip |
Move cmake targets into sub directories
Diffstat (limited to 'src')
-rw-r--r-- | src/CMakeLists.txt | 43 | ||||
-rw-r--r-- | src/dlfcn.c | 478 | ||||
-rw-r--r-- | src/dlfcn.h | 78 |
3 files changed, 599 insertions, 0 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 0000000..d5296b1 --- /dev/null +++ b/src/CMakeLists.txt | |||
@@ -0,0 +1,43 @@ | |||
1 | set(headers dlfcn.h) | ||
2 | set(sources dlfcn.c) | ||
3 | |||
4 | if (BUILD_SHARED_LIBS) | ||
5 | add_definitions(-DSHARED) | ||
6 | endif (BUILD_SHARED_LIBS) | ||
7 | |||
8 | add_library(dl ${sources}) | ||
9 | |||
10 | # Correctly export the location of installed includes in the target | ||
11 | target_include_directories(dl INTERFACE $<INSTALL_INTERFACE:include>) | ||
12 | |||
13 | install (TARGETS dl EXPORT dlfcn-win32-targets | ||
14 | RUNTIME DESTINATION bin | ||
15 | LIBRARY DESTINATION lib${LIB_SUFFIX} | ||
16 | ARCHIVE DESTINATION lib${LIB_SUFFIX}) | ||
17 | |||
18 | install (FILES ${headers} DESTINATION include) | ||
19 | |||
20 | # Export the targets (build tree) | ||
21 | export(EXPORT dlfcn-win32-targets | ||
22 | FILE "${CMAKE_BINARY_DIR}/dlfcn-win32-targets.cmake" | ||
23 | NAMESPACE dlfcn-win32:: | ||
24 | ) | ||
25 | |||
26 | # Write the CMake config file | ||
27 | set(CMAKE_CONF_INSTALL_DIR share/dlfcn-win32) | ||
28 | set(INCLUDE_INSTALL_DIR include) | ||
29 | include(CMakePackageConfigHelpers) | ||
30 | configure_package_config_file(../dlfcn-win32-config.cmake.in ${CMAKE_BINARY_DIR}/dlfcn-win32-config.cmake | ||
31 | INSTALL_DESTINATION ${CMAKE_CONF_INSTALL_DIR} | ||
32 | PATH_VARS INCLUDE_INSTALL_DIR | ||
33 | NO_CHECK_REQUIRED_COMPONENTS_MACRO) | ||
34 | |||
35 | # Install the targets (install) | ||
36 | install(EXPORT dlfcn-win32-targets | ||
37 | FILE dlfcn-win32-targets.cmake | ||
38 | NAMESPACE dlfcn-win32:: | ||
39 | DESTINATION ${CMAKE_CONF_INSTALL_DIR}) | ||
40 | |||
41 | # Install the CMake config file | ||
42 | install(FILES ${CMAKE_BINARY_DIR}/dlfcn-win32-config.cmake | ||
43 | DESTINATION ${CMAKE_CONF_INSTALL_DIR}) | ||
diff --git a/src/dlfcn.c b/src/dlfcn.c new file mode 100644 index 0000000..532af91 --- /dev/null +++ b/src/dlfcn.c | |||
@@ -0,0 +1,478 @@ | |||
1 | /* | ||
2 | * dlfcn-win32 | ||
3 | * Copyright (c) 2007 Ramiro Polla | ||
4 | * Copyright (c) 2015 Tiancheng "Timothy" Gu | ||
5 | * Copyright (c) 2019 Pali Rohár <pali.rohar@gmail.com> | ||
6 | * | ||
7 | * Permission is hereby granted, free of charge, to any person obtaining a copy | ||
8 | * of this software and associated documentation files (the "Software"), to deal | ||
9 | * in the Software without restriction, including without limitation the rights | ||
10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
11 | * copies of the Software, and to permit persons to whom the Software is | ||
12 | * furnished to do so, subject to the following conditions: | ||
13 | * | ||
14 | * The above copyright notice and this permission notice shall be included in | ||
15 | * all copies or substantial portions of the Software. | ||
16 | * | ||
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
20 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
23 | * THE SOFTWARE. | ||
24 | */ | ||
25 | |||
26 | #ifndef _WIN32_WINNT | ||
27 | #define _WIN32_WINNT 0x0501 | ||
28 | #endif | ||
29 | #ifdef _DEBUG | ||
30 | #define _CRTDBG_MAP_ALLOC | ||
31 | #include <stdlib.h> | ||
32 | #include <crtdbg.h> | ||
33 | #endif | ||
34 | #include <windows.h> | ||
35 | #include <stdio.h> | ||
36 | #include <stdlib.h> | ||
37 | |||
38 | #ifdef _MSC_VER | ||
39 | /* https://docs.microsoft.com/en-us/cpp/intrinsics/returnaddress */ | ||
40 | #pragma intrinsic(_ReturnAddress) | ||
41 | #else | ||
42 | /* https://gcc.gnu.org/onlinedocs/gcc/Return-Address.html */ | ||
43 | #ifndef _ReturnAddress | ||
44 | #define _ReturnAddress() (__builtin_extract_return_addr(__builtin_return_address(0))) | ||
45 | #endif | ||
46 | #endif | ||
47 | |||
48 | #ifdef SHARED | ||
49 | #define DLFCN_WIN32_EXPORTS | ||
50 | #endif | ||
51 | #include "dlfcn.h" | ||
52 | |||
53 | /* Note: | ||
54 | * MSDN says these functions are not thread-safe. We make no efforts to have | ||
55 | * any kind of thread safety. | ||
56 | */ | ||
57 | |||
58 | typedef struct local_object { | ||
59 | HMODULE hModule; | ||
60 | struct local_object *previous; | ||
61 | struct local_object *next; | ||
62 | } local_object; | ||
63 | |||
64 | static local_object first_object; | ||
65 | |||
66 | /* These functions implement a double linked list for the local objects. */ | ||
67 | static local_object *local_search( HMODULE hModule ) | ||
68 | { | ||
69 | local_object *pobject; | ||
70 | |||
71 | if( hModule == NULL ) | ||
72 | return NULL; | ||
73 | |||
74 | for( pobject = &first_object; pobject; pobject = pobject->next ) | ||
75 | if( pobject->hModule == hModule ) | ||
76 | return pobject; | ||
77 | |||
78 | return NULL; | ||
79 | } | ||
80 | |||
81 | static BOOL local_add( HMODULE hModule ) | ||
82 | { | ||
83 | local_object *pobject; | ||
84 | local_object *nobject; | ||
85 | |||
86 | if( hModule == NULL ) | ||
87 | return TRUE; | ||
88 | |||
89 | pobject = local_search( hModule ); | ||
90 | |||
91 | /* Do not add object again if it's already on the list */ | ||
92 | if( pobject ) | ||
93 | return TRUE; | ||
94 | |||
95 | for( pobject = &first_object; pobject->next; pobject = pobject->next ); | ||
96 | |||
97 | nobject = (local_object*) malloc( sizeof( local_object ) ); | ||
98 | |||
99 | if( !nobject ) | ||
100 | { | ||
101 | SetLastError( ERROR_NOT_ENOUGH_MEMORY ); | ||
102 | return FALSE; | ||
103 | } | ||
104 | |||
105 | pobject->next = nobject; | ||
106 | nobject->next = NULL; | ||
107 | nobject->previous = pobject; | ||
108 | nobject->hModule = hModule; | ||
109 | |||
110 | return TRUE; | ||
111 | } | ||
112 | |||
113 | static void local_rem( HMODULE hModule ) | ||
114 | { | ||
115 | local_object *pobject; | ||
116 | |||
117 | if( hModule == NULL ) | ||
118 | return; | ||
119 | |||
120 | pobject = local_search( hModule ); | ||
121 | |||
122 | if( !pobject ) | ||
123 | return; | ||
124 | |||
125 | if( pobject->next ) | ||
126 | pobject->next->previous = pobject->previous; | ||
127 | if( pobject->previous ) | ||
128 | pobject->previous->next = pobject->next; | ||
129 | |||
130 | free( pobject ); | ||
131 | } | ||
132 | |||
133 | /* POSIX says dlerror( ) doesn't have to be thread-safe, so we use one | ||
134 | * static buffer. | ||
135 | * MSDN says the buffer cannot be larger than 64K bytes, so we set it to | ||
136 | * the limit. | ||
137 | */ | ||
138 | static char error_buffer[65535]; | ||
139 | static BOOL error_occurred; | ||
140 | |||
141 | static void save_err_str( const char *str ) | ||
142 | { | ||
143 | DWORD dwMessageId; | ||
144 | DWORD ret; | ||
145 | size_t pos, len; | ||
146 | |||
147 | dwMessageId = GetLastError( ); | ||
148 | |||
149 | if( dwMessageId == 0 ) | ||
150 | return; | ||
151 | |||
152 | len = strlen( str ); | ||
153 | if( len > sizeof( error_buffer ) - 5 ) | ||
154 | len = sizeof( error_buffer ) - 5; | ||
155 | |||
156 | /* Format error message to: | ||
157 | * "<argument to function that failed>": <Windows localized error message> | ||
158 | */ | ||
159 | pos = 0; | ||
160 | error_buffer[pos++] = '"'; | ||
161 | memcpy( error_buffer+pos, str, len ); | ||
162 | pos += len; | ||
163 | error_buffer[pos++] = '"'; | ||
164 | error_buffer[pos++] = ':'; | ||
165 | error_buffer[pos++] = ' '; | ||
166 | |||
167 | ret = FormatMessageA( FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, dwMessageId, | ||
168 | MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ), | ||
169 | error_buffer+pos, (DWORD) (sizeof(error_buffer)-pos), NULL ); | ||
170 | pos += ret; | ||
171 | |||
172 | /* When FormatMessageA() fails it returns zero and does not touch buffer | ||
173 | * so add trailing null byte */ | ||
174 | if( ret == 0 ) | ||
175 | error_buffer[pos] = '\0'; | ||
176 | |||
177 | if( pos > 1 ) | ||
178 | { | ||
179 | /* POSIX says the string must not have trailing <newline> */ | ||
180 | if( error_buffer[pos-2] == '\r' && error_buffer[pos-1] == '\n' ) | ||
181 | error_buffer[pos-2] = '\0'; | ||
182 | } | ||
183 | |||
184 | error_occurred = TRUE; | ||
185 | } | ||
186 | |||
187 | static void save_err_ptr_str( const void *ptr ) | ||
188 | { | ||
189 | char ptr_buf[19]; /* 0x<pointer> up to 64 bits. */ | ||
190 | |||
191 | #ifdef _MSC_VER | ||
192 | /* Supress warning C4996: 'sprintf': This function or variable may be unsafe */ | ||
193 | #pragma warning( suppress: 4996 ) | ||
194 | #endif | ||
195 | sprintf( ptr_buf, "0x%p", ptr ); | ||
196 | |||
197 | save_err_str( ptr_buf ); | ||
198 | } | ||
199 | |||
200 | /* Load Psapi.dll at runtime, this avoids linking caveat */ | ||
201 | static BOOL MyEnumProcessModules( HANDLE hProcess, HMODULE *lphModule, DWORD cb, LPDWORD lpcbNeeded ) | ||
202 | { | ||
203 | static BOOL (WINAPI *EnumProcessModulesPtr)(HANDLE, HMODULE *, DWORD, LPDWORD); | ||
204 | HMODULE psapi; | ||
205 | |||
206 | if( !EnumProcessModulesPtr ) | ||
207 | { | ||
208 | psapi = LoadLibraryA( "Psapi.dll" ); | ||
209 | if( psapi ) | ||
210 | EnumProcessModulesPtr = (BOOL (WINAPI *)(HANDLE, HMODULE *, DWORD, LPDWORD)) GetProcAddress( psapi, "EnumProcessModules" ); | ||
211 | if( !EnumProcessModulesPtr ) | ||
212 | return 0; | ||
213 | } | ||
214 | |||
215 | return EnumProcessModulesPtr( hProcess, lphModule, cb, lpcbNeeded ); | ||
216 | } | ||
217 | |||
218 | void *dlopen( const char *file, int mode ) | ||
219 | { | ||
220 | HMODULE hModule; | ||
221 | UINT uMode; | ||
222 | |||
223 | error_occurred = FALSE; | ||
224 | |||
225 | /* Do not let Windows display the critical-error-handler message box */ | ||
226 | uMode = SetErrorMode( SEM_FAILCRITICALERRORS ); | ||
227 | |||
228 | if( file == 0 ) | ||
229 | { | ||
230 | /* POSIX says that if the value of file is 0, a handle on a global | ||
231 | * symbol object must be provided. That object must be able to access | ||
232 | * all symbols from the original program file, and any objects loaded | ||
233 | * with the RTLD_GLOBAL flag. | ||
234 | * The return value from GetModuleHandle( ) allows us to retrieve | ||
235 | * symbols only from the original program file. EnumProcessModules() is | ||
236 | * used to access symbols from other libraries. For objects loaded | ||
237 | * with the RTLD_LOCAL flag, we create our own list later on. They are | ||
238 | * excluded from EnumProcessModules() iteration. | ||
239 | */ | ||
240 | hModule = GetModuleHandle( NULL ); | ||
241 | |||
242 | if( !hModule ) | ||
243 | save_err_str( "(null)" ); | ||
244 | } | ||
245 | else | ||
246 | { | ||
247 | HANDLE hCurrentProc; | ||
248 | DWORD dwProcModsBefore, dwProcModsAfter; | ||
249 | char lpFileName[MAX_PATH]; | ||
250 | size_t i, len; | ||
251 | |||
252 | len = strlen( file ); | ||
253 | |||
254 | if( len >= sizeof( lpFileName ) ) | ||
255 | { | ||
256 | SetLastError( ERROR_FILENAME_EXCED_RANGE ); | ||
257 | save_err_str( file ); | ||
258 | hModule = NULL; | ||
259 | } | ||
260 | else | ||
261 | { | ||
262 | /* MSDN says backslashes *must* be used instead of forward slashes. */ | ||
263 | for( i = 0; i < len; i++ ) | ||
264 | { | ||
265 | if( file[i] == '/' ) | ||
266 | lpFileName[i] = '\\'; | ||
267 | else | ||
268 | lpFileName[i] = file[i]; | ||
269 | } | ||
270 | lpFileName[len] = '\0'; | ||
271 | |||
272 | hCurrentProc = GetCurrentProcess( ); | ||
273 | |||
274 | if( MyEnumProcessModules( hCurrentProc, NULL, 0, &dwProcModsBefore ) == 0 ) | ||
275 | dwProcModsBefore = 0; | ||
276 | |||
277 | /* POSIX says the search path is implementation-defined. | ||
278 | * LOAD_WITH_ALTERED_SEARCH_PATH is used to make it behave more closely | ||
279 | * to UNIX's search paths (start with system folders instead of current | ||
280 | * folder). | ||
281 | */ | ||
282 | hModule = LoadLibraryExA( lpFileName, NULL, LOAD_WITH_ALTERED_SEARCH_PATH ); | ||
283 | |||
284 | if( !hModule ) | ||
285 | { | ||
286 | save_err_str( lpFileName ); | ||
287 | } | ||
288 | else | ||
289 | { | ||
290 | if( MyEnumProcessModules( hCurrentProc, NULL, 0, &dwProcModsAfter ) == 0 ) | ||
291 | dwProcModsAfter = 0; | ||
292 | |||
293 | /* If the object was loaded with RTLD_LOCAL, add it to list of local | ||
294 | * objects, so that its symbols cannot be retrieved even if the handle for | ||
295 | * the original program file is passed. POSIX says that if the same | ||
296 | * file is specified in multiple invocations, and any of them are | ||
297 | * RTLD_GLOBAL, even if any further invocations use RTLD_LOCAL, the | ||
298 | * symbols will remain global. If number of loaded modules was not | ||
299 | * changed after calling LoadLibraryEx(), it means that library was | ||
300 | * already loaded. | ||
301 | */ | ||
302 | if( (mode & RTLD_LOCAL) && dwProcModsBefore != dwProcModsAfter ) | ||
303 | { | ||
304 | if( !local_add( hModule ) ) | ||
305 | { | ||
306 | save_err_str( lpFileName ); | ||
307 | FreeLibrary( hModule ); | ||
308 | hModule = NULL; | ||
309 | } | ||
310 | } | ||
311 | else if( !(mode & RTLD_LOCAL) && dwProcModsBefore == dwProcModsAfter ) | ||
312 | { | ||
313 | local_rem( hModule ); | ||
314 | } | ||
315 | } | ||
316 | } | ||
317 | } | ||
318 | |||
319 | /* Return to previous state of the error-mode bit flags. */ | ||
320 | SetErrorMode( uMode ); | ||
321 | |||
322 | return (void *) hModule; | ||
323 | } | ||
324 | |||
325 | int dlclose( void *handle ) | ||
326 | { | ||
327 | HMODULE hModule = (HMODULE) handle; | ||
328 | BOOL ret; | ||
329 | |||
330 | error_occurred = FALSE; | ||
331 | |||
332 | ret = FreeLibrary( hModule ); | ||
333 | |||
334 | /* If the object was loaded with RTLD_LOCAL, remove it from list of local | ||
335 | * objects. | ||
336 | */ | ||
337 | if( ret ) | ||
338 | local_rem( hModule ); | ||
339 | else | ||
340 | save_err_ptr_str( handle ); | ||
341 | |||
342 | /* dlclose's return value in inverted in relation to FreeLibrary's. */ | ||
343 | ret = !ret; | ||
344 | |||
345 | return (int) ret; | ||
346 | } | ||
347 | |||
348 | __declspec(noinline) /* Needed for _ReturnAddress() */ | ||
349 | void *dlsym( void *handle, const char *name ) | ||
350 | { | ||
351 | FARPROC symbol; | ||
352 | HMODULE hCaller; | ||
353 | HMODULE hModule; | ||
354 | HANDLE hCurrentProc; | ||
355 | |||
356 | error_occurred = FALSE; | ||
357 | |||
358 | symbol = NULL; | ||
359 | hCaller = NULL; | ||
360 | hModule = GetModuleHandle( NULL ); | ||
361 | hCurrentProc = GetCurrentProcess( ); | ||
362 | |||
363 | if( handle == RTLD_DEFAULT ) | ||
364 | { | ||
365 | /* The symbol lookup happens in the normal global scope; that is, | ||
366 | * a search for a symbol using this handle would find the same | ||
367 | * definition as a direct use of this symbol in the program code. | ||
368 | * So use same lookup procedure as when filename is NULL. | ||
369 | */ | ||
370 | handle = hModule; | ||
371 | } | ||
372 | else if( handle == RTLD_NEXT ) | ||
373 | { | ||
374 | /* Specifies the next object after this one that defines name. | ||
375 | * This one refers to the object containing the invocation of dlsym(). | ||
376 | * The next object is the one found upon the application of a load | ||
377 | * order symbol resolution algorithm. To get caller function of dlsym() | ||
378 | * use _ReturnAddress() intrinsic. To get HMODULE of caller function | ||
379 | * use standard GetModuleHandleExA() function. | ||
380 | */ | ||
381 | if( !GetModuleHandleExA( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, (LPCSTR) _ReturnAddress( ), &hCaller ) ) | ||
382 | goto end; | ||
383 | } | ||
384 | |||
385 | if( handle != RTLD_NEXT ) | ||
386 | { | ||
387 | symbol = GetProcAddress( (HMODULE) handle, name ); | ||
388 | |||
389 | if( symbol != NULL ) | ||
390 | goto end; | ||
391 | } | ||
392 | |||
393 | /* If the handle for the original program file is passed, also search | ||
394 | * in all globally loaded objects. | ||
395 | */ | ||
396 | |||
397 | if( hModule == handle || handle == RTLD_NEXT ) | ||
398 | { | ||
399 | HMODULE *modules; | ||
400 | DWORD cbNeeded; | ||
401 | DWORD dwSize; | ||
402 | size_t i; | ||
403 | |||
404 | /* GetModuleHandle( NULL ) only returns the current program file. So | ||
405 | * if we want to get ALL loaded module including those in linked DLLs, | ||
406 | * we have to use EnumProcessModules( ). | ||
407 | */ | ||
408 | if( MyEnumProcessModules( hCurrentProc, NULL, 0, &dwSize ) != 0 ) | ||
409 | { | ||
410 | modules = malloc( dwSize ); | ||
411 | if( modules ) | ||
412 | { | ||
413 | if( MyEnumProcessModules( hCurrentProc, modules, dwSize, &cbNeeded ) != 0 && dwSize == cbNeeded ) | ||
414 | { | ||
415 | for( i = 0; i < dwSize / sizeof( HMODULE ); i++ ) | ||
416 | { | ||
417 | if( handle == RTLD_NEXT && hCaller ) | ||
418 | { | ||
419 | /* Next modules can be used for RTLD_NEXT */ | ||
420 | if( hCaller == modules[i] ) | ||
421 | hCaller = NULL; | ||
422 | continue; | ||
423 | } | ||
424 | if( local_search( modules[i] ) ) | ||
425 | continue; | ||
426 | symbol = GetProcAddress( modules[i], name ); | ||
427 | if( symbol != NULL ) | ||
428 | { | ||
429 | free( modules ); | ||
430 | goto end; | ||
431 | } | ||
432 | } | ||
433 | |||
434 | } | ||
435 | free( modules ); | ||
436 | } | ||
437 | else | ||
438 | { | ||
439 | SetLastError( ERROR_NOT_ENOUGH_MEMORY ); | ||
440 | goto end; | ||
441 | } | ||
442 | } | ||
443 | } | ||
444 | |||
445 | end: | ||
446 | if( symbol == NULL ) | ||
447 | { | ||
448 | if( GetLastError() == 0 ) | ||
449 | SetLastError( ERROR_PROC_NOT_FOUND ); | ||
450 | save_err_str( name ); | ||
451 | } | ||
452 | |||
453 | return *(void **) (&symbol); | ||
454 | } | ||
455 | |||
456 | char *dlerror( void ) | ||
457 | { | ||
458 | /* If this is the second consecutive call to dlerror, return NULL */ | ||
459 | if( !error_occurred ) | ||
460 | return NULL; | ||
461 | |||
462 | /* POSIX says that invoking dlerror( ) a second time, immediately following | ||
463 | * a prior invocation, shall result in NULL being returned. | ||
464 | */ | ||
465 | error_occurred = FALSE; | ||
466 | |||
467 | return error_buffer; | ||
468 | } | ||
469 | |||
470 | #ifdef SHARED | ||
471 | BOOL WINAPI DllMain( HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved ) | ||
472 | { | ||
473 | (void) hinstDLL; | ||
474 | (void) fdwReason; | ||
475 | (void) lpvReserved; | ||
476 | return TRUE; | ||
477 | } | ||
478 | #endif | ||
diff --git a/src/dlfcn.h b/src/dlfcn.h new file mode 100644 index 0000000..9ddbba3 --- /dev/null +++ b/src/dlfcn.h | |||
@@ -0,0 +1,78 @@ | |||
1 | /* | ||
2 | * dlfcn-win32 | ||
3 | * Copyright (c) 2007 Ramiro Polla | ||
4 | * | ||
5 | * Permission is hereby granted, free of charge, to any person obtaining a copy | ||
6 | * of this software and associated documentation files (the "Software"), to deal | ||
7 | * in the Software without restriction, including without limitation the rights | ||
8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
9 | * copies of the Software, and to permit persons to whom the Software is | ||
10 | * furnished to do so, subject to the following conditions: | ||
11 | * | ||
12 | * The above copyright notice and this permission notice shall be included in | ||
13 | * all copies or substantial portions of the Software. | ||
14 | * | ||
15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
18 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
21 | * THE SOFTWARE. | ||
22 | */ | ||
23 | |||
24 | #ifndef DLFCN_H | ||
25 | #define DLFCN_H | ||
26 | |||
27 | #ifdef __cplusplus | ||
28 | extern "C" { | ||
29 | #endif | ||
30 | |||
31 | #if defined(DLFCN_WIN32_EXPORTS) | ||
32 | # define DLFCN_EXPORT __declspec(dllexport) | ||
33 | #else | ||
34 | # define DLFCN_EXPORT | ||
35 | #endif | ||
36 | |||
37 | /* Relocations are performed when the object is loaded. */ | ||
38 | #define RTLD_NOW 0 | ||
39 | |||
40 | /* Relocations are performed at an implementation-defined time. | ||
41 | * Windows API does not support lazy symbol resolving (when first reference | ||
42 | * to a given symbol occurs). So RTLD_LAZY implementation is same as RTLD_NOW. | ||
43 | */ | ||
44 | #define RTLD_LAZY RTLD_NOW | ||
45 | |||
46 | /* All symbols are available for relocation processing of other modules. */ | ||
47 | #define RTLD_GLOBAL (1 << 1) | ||
48 | |||
49 | /* All symbols are not made available for relocation processing by other modules. */ | ||
50 | #define RTLD_LOCAL (1 << 2) | ||
51 | |||
52 | /* These two were added in The Open Group Base Specifications Issue 6. | ||
53 | * Note: All other RTLD_* flags in any dlfcn.h are not standard compliant. | ||
54 | */ | ||
55 | |||
56 | /* The symbol lookup happens in the normal global scope. */ | ||
57 | #define RTLD_DEFAULT ((void *)0) | ||
58 | |||
59 | /* Specifies the next object after this one that defines name. */ | ||
60 | #define RTLD_NEXT ((void *)-1) | ||
61 | |||
62 | /* Open a symbol table handle. */ | ||
63 | DLFCN_EXPORT void *dlopen(const char *file, int mode); | ||
64 | |||
65 | /* Close a symbol table handle. */ | ||
66 | DLFCN_EXPORT int dlclose(void *handle); | ||
67 | |||
68 | /* Get the address of a symbol from a symbol table handle. */ | ||
69 | DLFCN_EXPORT void *dlsym(void *handle, const char *name); | ||
70 | |||
71 | /* Get diagnostic information. */ | ||
72 | DLFCN_EXPORT char *dlerror(void); | ||
73 | |||
74 | #ifdef __cplusplus | ||
75 | } | ||
76 | #endif | ||
77 | |||
78 | #endif /* DLFCN_H */ | ||