00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <windows.h>
00021 #include <stdio.h>
00022 #include<AtlBase.h>
00023 #include<AtlConv.h>
00024 #include "dlfcn-win32.h"
00025
00026
00027
00028
00029
00030
00031 typedef struct global_object {
00032 HMODULE hModule;
00033 struct global_object *previous;
00034 struct global_object *next;
00035 } global_object;
00036
00037 static global_object first_object;
00038
00039
00040 static global_object *global_search( HMODULE hModule )
00041 {
00042 global_object *pobject;
00043
00044 if( hModule == NULL )
00045 return NULL;
00046
00047 for( pobject = &first_object; pobject ; pobject = pobject->next )
00048 if( pobject->hModule == hModule )
00049 return pobject;
00050
00051 return NULL;
00052 }
00053
00054 static void global_add( HMODULE hModule )
00055 {
00056 global_object *pobject;
00057 global_object *nobject;
00058
00059 if( hModule == NULL )
00060 return;
00061
00062 pobject = global_search( hModule );
00063
00064
00065 if( pobject )
00066 return;
00067
00068 for( pobject = &first_object; pobject->next ; pobject = pobject->next );
00069
00070 nobject = static_cast<global_object *>(malloc( sizeof(global_object) ));
00071
00072
00073
00074
00075 if( !nobject )
00076 return;
00077
00078 pobject->next = nobject;
00079 nobject->next = NULL;
00080 nobject->previous = pobject;
00081 nobject->hModule = hModule;
00082 }
00083
00084 static void global_rem( HMODULE hModule )
00085 {
00086 global_object *pobject;
00087
00088 if( hModule == NULL )
00089 return;
00090
00091 pobject = global_search( hModule );
00092
00093 if( !pobject )
00094 return;
00095
00096 if( pobject->next )
00097 pobject->next->previous = pobject->previous;
00098 if( pobject->previous )
00099 pobject->previous->next = pobject->next;
00100
00101 free( pobject );
00102 }
00103
00104
00105
00106
00107
00108
00109 static char error_buffer[65535];
00110 static char *current_error;
00111
00112 static int copy_string( char *dest, int dest_size, const char *src )
00113 {
00114 int i = 0;
00115
00116
00117 if( !src && !dest )
00118 return 0;
00119
00120 for( i = 0 ; i < dest_size-1 ; i++ )
00121 {
00122 if( !src[i] )
00123 break;
00124 else
00125 dest[i] = src[i];
00126 }
00127 dest[i] = '\0';
00128
00129 return i;
00130 }
00131
00132 static void save_err_str( const char *str )
00133 {
00134 USES_CONVERSION;
00135 DWORD dwMessageId;
00136 DWORD pos;
00137
00138 dwMessageId = GetLastError( );
00139
00140 if( dwMessageId == 0 )
00141 return;
00142
00143
00144
00145
00146 pos = copy_string( error_buffer, sizeof(error_buffer), "\"" );
00147 pos += copy_string( error_buffer+pos, sizeof(error_buffer)-pos, str );
00148 pos += copy_string( error_buffer+pos, sizeof(error_buffer)-pos, "\": " );
00149 pos += FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM, NULL, dwMessageId,
00150 MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ),
00151 A2W(error_buffer+pos), sizeof(error_buffer)-pos, NULL );
00152
00153 if( pos > 1 )
00154 {
00155
00156 if( error_buffer[pos-2] == '\r' && error_buffer[pos-1] == '\n' )
00157 error_buffer[pos-2] = '\0';
00158 }
00159
00160 current_error = error_buffer;
00161 }
00162
00163 static void save_err_ptr_str( const void *ptr )
00164 {
00165 char ptr_buf[19];
00166
00167 sprintf( ptr_buf, "0x%p", ptr );
00168
00169 save_err_str( ptr_buf );
00170 }
00171
00172 void *dlopen( const char *file, int mode )
00173 {
00174 USES_CONVERSION;
00175 HMODULE hModule;
00176 UINT uMode;
00177
00178 current_error = NULL;
00179
00180
00181 uMode = SetErrorMode( SEM_FAILCRITICALERRORS );
00182
00183 if( file == 0 )
00184 {
00185
00186
00187
00188
00189
00190
00191
00192
00193 hModule = GetModuleHandle( NULL );
00194
00195 if( !hModule )
00196 save_err_ptr_str( file );
00197 }
00198 else
00199 {
00200 char lpFileName[MAX_PATH];
00201 int i;
00202
00203
00204 for( i = 0 ; i < sizeof(lpFileName)-1 ; i++ )
00205 {
00206 if( !file[i] )
00207 break;
00208 else if( file[i] == '/' )
00209 lpFileName[i] = '\\';
00210 else
00211 lpFileName[i] = file[i];
00212 }
00213 lpFileName[i] = '\0';
00214
00215
00216
00217
00218
00219
00220 hModule = LoadLibraryEx( A2W(lpFileName), NULL,
00221 LOAD_WITH_ALTERED_SEARCH_PATH );
00222
00223
00224
00225
00226
00227
00228
00229
00230 if( !hModule )
00231 save_err_str( lpFileName );
00232 else if( (mode & RTLD_GLOBAL) )
00233 global_add( hModule );
00234 }
00235
00236
00237 SetErrorMode( uMode );
00238
00239 return (void *) hModule;
00240 }
00241
00242 int dlclose( void *handle )
00243 {
00244 HMODULE hModule = (HMODULE) handle;
00245 BOOL ret;
00246
00247 current_error = NULL;
00248
00249 ret = FreeLibrary( hModule );
00250
00251
00252
00253
00254 if( ret )
00255 global_rem( hModule );
00256 else
00257 save_err_ptr_str( handle );
00258
00259
00260 ret = !ret;
00261
00262 return (int) ret;
00263 }
00264
00265 void *dlsym( void *handle, const char *name )
00266 {
00267 FARPROC symbol;
00268
00269 current_error = NULL;
00270
00271 symbol = GetProcAddress( static_cast<HMODULE>(handle), name );
00272
00273 if( symbol == NULL )
00274 {
00275 HMODULE hModule;
00276
00277
00278
00279
00280
00281 hModule = GetModuleHandle( NULL );
00282
00283 if( hModule == handle )
00284 {
00285 global_object *pobject;
00286
00287 for( pobject = &first_object; pobject ; pobject = pobject->next )
00288 {
00289 if( pobject->hModule )
00290 {
00291 symbol = GetProcAddress( pobject->hModule, name );
00292 if( symbol != NULL )
00293 break;
00294 }
00295 }
00296 }
00297
00298 CloseHandle( hModule );
00299 }
00300
00301 if( symbol == NULL )
00302 save_err_str( name );
00303
00304 return (void*) symbol;
00305 }
00306
00307 char *dlerror( void )
00308 {
00309 char *error_pointer = current_error;
00310
00311
00312
00313
00314 current_error = NULL;
00315
00316 return error_pointer;
00317 }