diff options
author | Pali Rohár <pali.rohar@gmail.com> | 2019-05-23 20:22:44 +0200 |
---|---|---|
committer | Pali Rohár <pali.rohar@gmail.com> | 2019-05-23 20:22:44 +0200 |
commit | a5c0031ec4ac648261553128894e157ee41889cb (patch) | |
tree | 7c9b78c218bf3a9dc4ed9d1c94a18c8637a2d28c | |
parent | 1488731c810ed76589170909da9ef07f060cef46 (diff) | |
download | dlfcn-win32-a5c0031ec4ac648261553128894e157ee41889cb.tar.gz dlfcn-win32-a5c0031ec4ac648261553128894e157ee41889cb.tar.bz2 dlfcn-win32-a5c0031ec4ac648261553128894e157ee41889cb.zip |
Correctly process and indicate error from LoadLibraryExA() function
Function save_err_str() checks for error by GetLastError() call. Calling
EnumProcessModules() may change or reset it. So call save_err_str()
immediately after LoadLibraryExA().
-rw-r--r-- | dlfcn.c | 41 |
1 files changed, 25 insertions, 16 deletions
@@ -267,24 +267,33 @@ void *dlopen( const char *file, int mode ) | |||
267 | hModule = LoadLibraryExA(lpFileName, NULL, | 267 | hModule = LoadLibraryExA(lpFileName, NULL, |
268 | LOAD_WITH_ALTERED_SEARCH_PATH ); | 268 | LOAD_WITH_ALTERED_SEARCH_PATH ); |
269 | 269 | ||
270 | if( MyEnumProcessModules( hCurrentProc, NULL, 0, &dwProcModsAfter ) == 0 ) | ||
271 | dwProcModsAfter = 0; | ||
272 | |||
273 | /* If the object was loaded with RTLD_LOCAL, add it to list of local | ||
274 | * objects, so that its symbols cannot be retrieved even if the handle for | ||
275 | * the original program file is passed. POSIX says that if the same | ||
276 | * file is specified in multiple invocations, and any of them are | ||
277 | * RTLD_GLOBAL, even if any further invocations use RTLD_LOCAL, the | ||
278 | * symbols will remain global. If number of loaded modules was not | ||
279 | * changed after calling LoadLibraryEx(), it means that library was | ||
280 | * already loaded. | ||
281 | */ | ||
282 | if( !hModule ) | 270 | if( !hModule ) |
271 | { | ||
283 | save_err_str( lpFileName ); | 272 | save_err_str( lpFileName ); |
284 | else if( (mode & RTLD_LOCAL) && dwProcModsBefore != dwProcModsAfter ) | 273 | } |
285 | local_add( hModule ); | 274 | else |
286 | else if( !(mode & RTLD_LOCAL) && dwProcModsBefore == dwProcModsAfter ) | 275 | { |
287 | local_rem( hModule ); | 276 | if( MyEnumProcessModules( hCurrentProc, NULL, 0, &dwProcModsAfter ) == 0 ) |
277 | dwProcModsAfter = 0; | ||
278 | |||
279 | /* If the object was loaded with RTLD_LOCAL, add it to list of local | ||
280 | * objects, so that its symbols cannot be retrieved even if the handle for | ||
281 | * the original program file is passed. POSIX says that if the same | ||
282 | * file is specified in multiple invocations, and any of them are | ||
283 | * RTLD_GLOBAL, even if any further invocations use RTLD_LOCAL, the | ||
284 | * symbols will remain global. If number of loaded modules was not | ||
285 | * changed after calling LoadLibraryEx(), it means that library was | ||
286 | * already loaded. | ||
287 | */ | ||
288 | if( (mode & RTLD_LOCAL) && dwProcModsBefore != dwProcModsAfter ) | ||
289 | { | ||
290 | local_add( hModule ); | ||
291 | } | ||
292 | else if( !(mode & RTLD_LOCAL) && dwProcModsBefore == dwProcModsAfter ) | ||
293 | { | ||
294 | local_rem( hModule ); | ||
295 | } | ||
296 | } | ||
288 | } | 297 | } |
289 | 298 | ||
290 | /* Return to previous state of the error-mode bit flags. */ | 299 | /* Return to previous state of the error-mode bit flags. */ |