aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTimothy Gu <timothygu99@gmail.com>2015-08-06 14:33:43 +0800
committerTimothy Gu <timothygu99@gmail.com>2015-08-06 14:33:43 +0800
commit7cea745e8fd471c649b281b4e7236d83cdd4f413 (patch)
tree52e0768ff21b2ce1b2f2442e56c992cc16f17b06
parente419539b122715a970fc825d980b6fba5b0ff935 (diff)
parentaa1401bf7cf45262f10c5318f99ce5be3ea767ae (diff)
downloaddlfcn-win32-7cea745e8fd471c649b281b4e7236d83cdd4f413.tar.gz
dlfcn-win32-7cea745e8fd471c649b281b4e7236d83cdd4f413.tar.bz2
dlfcn-win32-7cea745e8fd471c649b281b4e7236d83cdd4f413.zip
Merge pull request #20 from robertwgh/unicode
Added support for unicode character set.
-rw-r--r--dlfcn.c112
1 files changed, 90 insertions, 22 deletions
diff --git a/dlfcn.c b/dlfcn.c
index 26b0970..4367bd7 100644
--- a/dlfcn.c
+++ b/dlfcn.c
@@ -33,6 +33,19 @@
33#endif 33#endif
34#include "dlfcn.h" 34#include "dlfcn.h"
35 35
36#if ((defined(_WIN32) || defined(WIN32)) && (defined(_MSC_VER)) )
37#define snprintf sprintf_s
38#endif
39
40#ifdef UNICODE
41#include <wchar.h>
42#define CHAR wchar_t
43#define UNICODE_L(s) L##s
44#else
45#define CHAR char
46#define UNICODE_L(s) s
47#endif
48
36/* Note: 49/* Note:
37 * MSDN says these functions are not thread-safe. We make no efforts to have 50 * MSDN says these functions are not thread-safe. We make no efforts to have
38 * any kind of thread safety. 51 * any kind of thread safety.
@@ -86,7 +99,7 @@ static void global_add( global_object *start, HMODULE hModule )
86 99
87 for( pobject = start; pobject->next; pobject = pobject->next ); 100 for( pobject = start; pobject->next; pobject = pobject->next );
88 101
89 nobject = malloc( sizeof( global_object ) ); 102 nobject = (global_object*) malloc( sizeof( global_object ) );
90 103
91 /* Should this be enough to fail global_add, and therefore also fail 104 /* Should this be enough to fail global_add, and therefore also fail
92 * dlopen? 105 * dlopen?
@@ -125,10 +138,11 @@ static void global_rem( global_object *start, HMODULE hModule )
125 * MSDN says the buffer cannot be larger than 64K bytes, so we set it to 138 * MSDN says the buffer cannot be larger than 64K bytes, so we set it to
126 * the limit. 139 * the limit.
127 */ 140 */
128static char error_buffer[65535]; 141static CHAR error_buffer[65535];
129static char *current_error; 142static CHAR *current_error;
143static char dlerror_buffer[65536];
130 144
131static int copy_string( char *dest, int dest_size, const char *src ) 145static int copy_string( CHAR *dest, int dest_size, const CHAR *src )
132{ 146{
133 int i = 0; 147 int i = 0;
134 148
@@ -148,7 +162,7 @@ static int copy_string( char *dest, int dest_size, const char *src )
148 return i; 162 return i;
149} 163}
150 164
151static void save_err_str( const char *str ) 165static void save_err_str( const CHAR *str )
152{ 166{
153 DWORD dwMessageId; 167 DWORD dwMessageId;
154 DWORD pos; 168 DWORD pos;
@@ -160,13 +174,13 @@ static void save_err_str( const char *str )
160 174
161 /* Format error message to: 175 /* Format error message to:
162 * "<argument to function that failed>": <Windows localized error message> 176 * "<argument to function that failed>": <Windows localized error message>
163 */ 177 */
164 pos = copy_string( error_buffer, sizeof(error_buffer), "\"" ); 178 pos = copy_string( error_buffer, sizeof(error_buffer), UNICODE_L("\"") );
165 pos += copy_string( error_buffer+pos, sizeof(error_buffer)-pos, str ); 179 pos += copy_string( error_buffer+pos, sizeof(error_buffer)-pos, str );
166 pos += copy_string( error_buffer+pos, sizeof(error_buffer)-pos, "\": " ); 180 pos += copy_string( error_buffer+pos, sizeof(error_buffer)-pos, UNICODE_L("\": ") );
167 pos += FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM, NULL, dwMessageId, 181 pos += FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM, NULL, dwMessageId,
168 MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ), 182 MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ),
169 error_buffer+pos, sizeof(error_buffer)-pos, NULL ); 183 error_buffer+pos, sizeof(error_buffer)-pos, NULL );
170 184
171 if( pos > 1 ) 185 if( pos > 1 )
172 { 186 {
@@ -180,9 +194,19 @@ static void save_err_str( const char *str )
180 194
181static void save_err_ptr_str( const void *ptr ) 195static void save_err_ptr_str( const void *ptr )
182{ 196{
183 char ptr_buf[19]; /* 0x<pointer> up to 64 bits. */ 197 CHAR ptr_buf[19]; /* 0x<pointer> up to 64 bits. */
198
199#ifdef UNICODE
184 200
185 sprintf_s( ptr_buf, 19, "0x%p", ptr ); 201# if ((defined(_WIN32) || defined(WIN32)) && (defined(_MSC_VER)) )
202 swprintf_s( ptr_buf, 19, UNICODE_L("0x%p"), ptr );
203# else
204 swprintf(ptr_buf, 19, UNICODE_L("0x%p"), ptr);
205# endif
206
207#else
208 snprintf( ptr_buf, 19, "0x%p", ptr );
209#endif
186 210
187 save_err_str( ptr_buf ); 211 save_err_str( ptr_buf );
188} 212}
@@ -220,11 +244,11 @@ void *dlopen( const char *file, int mode )
220 244
221 245
222 /* GetModuleHandle( NULL ) only returns the current program file. So 246 /* GetModuleHandle( NULL ) only returns the current program file. So
223 * if we want to get ALL loaded module including those in linked DLLs, 247 * if we want to get ALL loaded module including those in linked DLLs,
224 * we have to use EnumProcessModules( ). 248 * we have to use EnumProcessModules( ).
225 */ 249 */
226 if( EnumProcessModules( hCurrentProc, hAddtnlMods, 250 if( EnumProcessModules( hCurrentProc, hAddtnlMods,
227 sizeof( hAddtnlMods ), &cbNeeded ) != 0 ) 251 sizeof( hAddtnlMods ), &cbNeeded ) != 0 )
228 { 252 {
229 DWORD i; 253 DWORD i;
230 for( i = 0; i < cbNeeded / sizeof( HMODULE ); i++ ) 254 for( i = 0; i < cbNeeded / sizeof( HMODULE ); i++ )
@@ -236,11 +260,11 @@ void *dlopen( const char *file, int mode )
236 } 260 }
237 else 261 else
238 { 262 {
239 char lpFileName[MAX_PATH]; 263 CHAR lpFileName[MAX_PATH];
240 int i; 264 int i;
241 265
242 /* MSDN says backslashes *must* be used instead of forward slashes. */ 266 /* MSDN says backslashes *must* be used instead of forward slashes. */
243 for( i = 0 ; i < sizeof(lpFileName)-1 ; i++ ) 267 for( i = 0 ; i < sizeof(lpFileName) - 1 ; i ++ )
244 { 268 {
245 if( !file[i] ) 269 if( !file[i] )
246 break; 270 break;
@@ -256,8 +280,8 @@ void *dlopen( const char *file, int mode )
256 * to UNIX's search paths (start with system folders instead of current 280 * to UNIX's search paths (start with system folders instead of current
257 * folder). 281 * folder).
258 */ 282 */
259 hModule = LoadLibraryEx( (LPSTR) lpFileName, NULL, 283 hModule = LoadLibraryEx(lpFileName, NULL,
260 LOAD_WITH_ALTERED_SEARCH_PATH ); 284 LOAD_WITH_ALTERED_SEARCH_PATH );
261 285
262 /* If the object was loaded with RTLD_GLOBAL, add it to list of global 286 /* If the object was loaded with RTLD_GLOBAL, add it to list of global
263 * objects, so that its symbols may be retrieved even if the handle for 287 * objects, so that its symbols may be retrieved even if the handle for
@@ -332,9 +356,14 @@ void *dlsym( void *handle, const char *name )
332 FARPROC symbol; 356 FARPROC symbol;
333 HMODULE hModule; 357 HMODULE hModule;
334 358
359#ifdef UNICODE
360 wchar_t namew[MAX_PATH];
361 wmemset(namew, 0, MAX_PATH);
362#endif
363
335 current_error = NULL; 364 current_error = NULL;
336 365
337 symbol = GetProcAddress( handle, name ); 366 symbol = GetProcAddress( (HMODULE) handle, name );
338 367
339 if( symbol != NULL ) 368 if( symbol != NULL )
340 goto end; 369 goto end;
@@ -372,9 +401,27 @@ void *dlsym( void *handle, const char *name )
372 401
373end: 402end:
374 if( symbol == NULL ) 403 if( symbol == NULL )
404 {
405#ifdef UNICODE
406 size_t converted_chars;
407
408 size_t str_len = strlen(name) + 1;
409
410#if ((defined(_WIN32) || defined(WIN32)) && (defined(_MSC_VER)) )
411 errno_t err = mbstowcs_s(&converted_chars, namew, str_len, name, str_len);
412 if (err != 0)
413 return NULL;
414#else
415 mbstowcs(namew, name, str_len);
416#endif
417
418 save_err_str( namew );
419#else
375 save_err_str( name ); 420 save_err_str( name );
421#endif
422 }
376 423
377// warning C4054: 'type cast' : from function pointer 'FARPROC' to data pointer 'void *' 424 // warning C4054: 'type cast' : from function pointer 'FARPROC' to data pointer 'void *'
378#ifdef _MSC_VER 425#ifdef _MSC_VER
379#pragma warning( suppress: 4054 ) 426#pragma warning( suppress: 4054 )
380#endif 427#endif
@@ -383,7 +430,28 @@ end:
383 430
384char *dlerror( void ) 431char *dlerror( void )
385{ 432{
386 char *error_pointer = current_error; 433 char *error_pointer = dlerror_buffer;
434
435#ifdef UNICODE
436 errno_t err = 0;
437 size_t converted_chars = 0;
438 size_t str_len = wcslen(current_error) + 1;
439 memset(error_pointer, 0, 65535);
440
441# if ((defined(_WIN32) || defined(WIN32)) && (defined(_MSC_VER)) )
442 err = wcstombs_s(&converted_chars,
443 error_pointer, str_len * sizeof(char),
444 current_error, str_len * sizeof(wchar_t));
445
446 if (err != 0)
447 return NULL;
448# else
449 wcstombs(error_pointer, current_error, str_len);
450# endif
451
452#else
453 memcpy(error_pointer, current_error, strlen(current_error) + 1);
454#endif
387 455
388 /* POSIX says that invoking dlerror( ) a second time, immediately following 456 /* POSIX says that invoking dlerror( ) a second time, immediately following
389 * a prior invocation, shall result in NULL being returned. 457 * a prior invocation, shall result in NULL being returned.