comparison loader/module.c @ 2069:ce45cce7f7a5

sync with avifile
author arpi
date Thu, 04 Oct 2001 02:21:47 +0000
parents d8c1b0b38edc
children 958d10763c34
comparison
equal deleted inserted replaced
2068:3189c317dfc1 2069:ce45cce7f7a5
10 #include <fcntl.h> 10 #include <fcntl.h>
11 #include <stdio.h> 11 #include <stdio.h>
12 #include <stdlib.h> 12 #include <stdlib.h>
13 #include <string.h> 13 #include <string.h>
14 #include <unistd.h> 14 #include <unistd.h>
15
16 #include <sys/mman.h> 15 #include <sys/mman.h>
17 #include <sys/types.h> 16 #include <sys/types.h>
18 #ifdef HAVE_LIBDL
19 #include <wine/elfdll.h>
20 #include <dlfcn.h>
21 #endif
22
23 /* 17 /*
24 #ifdef __linux__ 18 #ifdef __linux__
25 #include <asm/unistd.h> 19 #include <asm/unistd.h>
26 #include <asm/ldt.h> 20 #include <asm/ldt.h>
27 #else 21 #else
51 #include <wine/winerror.h> 45 #include <wine/winerror.h>
52 #include <wine/heap.h> 46 #include <wine/heap.h>
53 #include <wine/module.h> 47 #include <wine/module.h>
54 #include <wine/pe_image.h> 48 #include <wine/pe_image.h>
55 #include <wine/debugtools.h> 49 #include <wine/debugtools.h>
50 #ifdef HAVE_LIBDL
51 #include <dlfcn.h>
52 #include <wine/elfdll.h>
53 #endif
56 #include "win32.h" 54 #include "win32.h"
57 55
58 struct modref_list_t; 56 struct modref_list_t;
59 57
60 typedef struct modref_list_t 58 typedef struct modref_list_t
61 { 59 {
62 WINE_MODREF* wm; 60 WINE_MODREF* wm;
63 struct modref_list_t *next; 61 struct modref_list_t *next;
64 struct modref_list_t *prev; 62 struct modref_list_t *prev;
65 } 63 }
66 modref_list; 64 modref_list;
67 65
68 //WINE_MODREF *local_wm=NULL; 66 //WINE_MODREF *local_wm=NULL;
69 modref_list* local_wm=NULL; 67 modref_list* local_wm=NULL;
68
69 //HANDLE SegptrHeap; // unused?
70 70
71 WINE_MODREF *MODULE_FindModule(LPCSTR m) 71 WINE_MODREF *MODULE_FindModule(LPCSTR m)
72 { 72 {
73 modref_list* list=local_wm; 73 modref_list* list=local_wm;
74 TRACE("Module %s request\n", m); 74 TRACE("Module %s request\n", m);
78 { 78 {
79 TRACE("%s: %x\n", list->wm->filename, list->wm->module); 79 TRACE("%s: %x\n", list->wm->filename, list->wm->module);
80 list=list->prev; 80 list=list->prev;
81 if(list==NULL) 81 if(list==NULL)
82 return NULL; 82 return NULL;
83 } 83 }
84 TRACE("Resolved to %s\n", list->wm->filename); 84 TRACE("Resolved to %s\n", list->wm->filename);
85 return list->wm; 85 return list->wm;
86 } 86 }
87 87
88 static void MODULE_RemoveFromList(WINE_MODREF *mod) 88 static void MODULE_RemoveFromList(WINE_MODREF *mod)
89 { 89 {
90 modref_list* list=local_wm; 90 modref_list* list=local_wm;
91 if(list==0) 91 if(list==0)
111 local_wm=list->prev; 111 local_wm=list->prev;
112 free(list); 112 free(list);
113 return; 113 return;
114 } 114 }
115 } 115 }
116 } 116 }
117 117
118 WINE_MODREF *MODULE32_LookupHMODULE(HMODULE m) 118 WINE_MODREF *MODULE32_LookupHMODULE(HMODULE m)
119 { 119 {
120 modref_list* list=local_wm; 120 modref_list* list=local_wm;
121 TRACE("Module %X request\n", m); 121 TRACE("Module %X request\n", m);
122 if(list==NULL) 122 if(list==NULL)
126 // printf("Checking list %X wm %X module %X\n", 126 // printf("Checking list %X wm %X module %X\n",
127 // list, list->wm, list->wm->module); 127 // list, list->wm, list->wm->module);
128 list=list->prev; 128 list=list->prev;
129 if(list==NULL) 129 if(list==NULL)
130 return NULL; 130 return NULL;
131 } 131 }
132 TRACE("LookupHMODULE hit %X\n", list->wm); 132 TRACE("LookupHMODULE hit %p\n", list->wm);
133 return list->wm; 133 return list->wm;
134 } 134 }
135 135
136 /************************************************************************* 136 /*************************************************************************
137 * MODULE_InitDll 137 * MODULE_InitDll
138 */ 138 */
139 static WIN_BOOL MODULE_InitDll( WINE_MODREF *wm, DWORD type, LPVOID lpReserved ) 139 static WIN_BOOL MODULE_InitDll( WINE_MODREF *wm, DWORD type, LPVOID lpReserved )
140 { 140 {
141 WIN_BOOL retv = TRUE; 141 WIN_BOOL retv = TRUE;
142 142
143 static LPCSTR typeName[] = { "PROCESS_DETACH", "PROCESS_ATTACH", 143 static LPCSTR typeName[] = { "PROCESS_DETACH", "PROCESS_ATTACH",
144 "THREAD_ATTACH", "THREAD_DETACH" }; 144 "THREAD_ATTACH", "THREAD_DETACH" };
145 assert( wm ); 145 assert( wm );
146 146
147 147
148 /* Skip calls for modules loaded with special load flags */ 148 /* Skip calls for modules loaded with special load flags */
179 return retv; 179 return retv;
180 } 180 }
181 181
182 /************************************************************************* 182 /*************************************************************************
183 * MODULE_DllProcessAttach 183 * MODULE_DllProcessAttach
184 * 184 *
185 * Send the process attach notification to all DLLs the given module 185 * Send the process attach notification to all DLLs the given module
186 * depends on (recursively). This is somewhat complicated due to the fact that 186 * depends on (recursively). This is somewhat complicated due to the fact that
187 * 187 *
188 * - we have to respect the module dependencies, i.e. modules implicitly 188 * - we have to respect the module dependencies, i.e. modules implicitly
189 * referenced by another module have to be initialized before the module 189 * referenced by another module have to be initialized before the module
190 * itself can be initialized 190 * itself can be initialized
191 * 191 *
192 * - the initialization routine of a DLL can itself call LoadLibrary, 192 * - the initialization routine of a DLL can itself call LoadLibrary,
193 * thereby introducing a whole new set of dependencies (even involving 193 * thereby introducing a whole new set of dependencies (even involving
194 * the 'old' modules) at any time during the whole process 194 * the 'old' modules) at any time during the whole process
195 * 195 *
196 * (Note that this routine can be recursively entered not only directly 196 * (Note that this routine can be recursively entered not only directly
197 * from itself, but also via LoadLibrary from one of the called initialization 197 * from itself, but also via LoadLibrary from one of the called initialization
198 * routines.) 198 * routines.)
199 * 199 *
200 * Furthermore, we need to rearrange the main WINE_MODREF list to allow 200 * Furthermore, we need to rearrange the main WINE_MODREF list to allow
201 * the process *detach* notifications to be sent in the correct order. 201 * the process *detach* notifications to be sent in the correct order.
202 * This must not only take into account module dependencies, but also 202 * This must not only take into account module dependencies, but also
203 * 'hidden' dependencies created by modules calling LoadLibrary in their 203 * 'hidden' dependencies created by modules calling LoadLibrary in their
204 * attach notification routine. 204 * attach notification routine.
205 * 205 *
206 * The strategy is rather simple: we move a WINE_MODREF to the head of the 206 * The strategy is rather simple: we move a WINE_MODREF to the head of the
207 * list after the attach notification has returned. This implies that the 207 * list after the attach notification has returned. This implies that the
246 else 246 else
247 { 247 {
248 local_wm=malloc(sizeof(modref_list)); 248 local_wm=malloc(sizeof(modref_list));
249 local_wm->next=local_wm->prev=NULL; 249 local_wm->next=local_wm->prev=NULL;
250 local_wm->wm=wm; 250 local_wm->wm=wm;
251 } 251 }
252 /* Remove recursion flag */ 252 /* Remove recursion flag */
253 wm->flags &= ~WINE_MODREF_MARKER; 253 wm->flags &= ~WINE_MODREF_MARKER;
254 254
255 if ( retv ) 255 if ( retv )
256 { 256 {
257 retv = MODULE_InitDll( wm, DLL_PROCESS_ATTACH, lpReserved ); 257 retv = MODULE_InitDll( wm, DLL_PROCESS_ATTACH, lpReserved );
258 if ( retv ) 258 if ( retv )
259 wm->flags |= WINE_MODREF_PROCESS_ATTACHED; 259 wm->flags |= WINE_MODREF_PROCESS_ATTACHED;
265 return retv; 265 return retv;
266 } 266 }
267 267
268 /************************************************************************* 268 /*************************************************************************
269 * MODULE_DllProcessDetach 269 * MODULE_DllProcessDetach
270 * 270 *
271 * Send DLL process detach notifications. See the comment about calling 271 * Send DLL process detach notifications. See the comment about calling
272 * sequence at MODULE_DllProcessAttach. Unless the bForceDetach flag 272 * sequence at MODULE_DllProcessAttach. Unless the bForceDetach flag
273 * is set, only DLLs with zero refcount are notified. 273 * is set, only DLLs with zero refcount are notified.
274 */ 274 */
275 void MODULE_DllProcessDetach( WINE_MODREF* wm, WIN_BOOL bForceDetach, LPVOID lpReserved ) 275 void MODULE_DllProcessDetach( WINE_MODREF* wm, WIN_BOOL bForceDetach, LPVOID lpReserved )
276 { 276 {
283 /*********************************************************************** 283 /***********************************************************************
284 * LoadLibraryExA (KERNEL32) 284 * LoadLibraryExA (KERNEL32)
285 */ 285 */
286 HMODULE WINAPI LoadLibraryExA(LPCSTR libname, HANDLE hfile, DWORD flags) 286 HMODULE WINAPI LoadLibraryExA(LPCSTR libname, HANDLE hfile, DWORD flags)
287 { 287 {
288 WINE_MODREF *wm; 288 WINE_MODREF *wm = 0;
289 289 char* listpath[] = { "", "", "/usr/lib/win32", "/usr/local/lib/win32", 0 };
290 extern char* def_path;
291 char path[512];
292 char checked[2000];
293 int i = -1;
294
295 checked[0] = 0;
290 if(!libname) 296 if(!libname)
291 { 297 {
292 SetLastError(ERROR_INVALID_PARAMETER); 298 SetLastError(ERROR_INVALID_PARAMETER);
293 return 0; 299 return 0;
294 } 300 }
301
302 printf("Loading DLL: '%s'\n", libname);
303
295 // if(fs_installed==0) 304 // if(fs_installed==0)
296 // install_fs(); 305 // install_fs();
297 306
298 307 while (wm == 0 && listpath[++i])
299 wm = MODULE_LoadLibraryExA( libname, hfile, flags ); 308 {
309 if (i < 2)
310 {
311 if (i == 0)
312 /* check just original file name */
313 strncpy(path, libname, 511);
314 else
315 /* check default user path */
316 strncpy(path, def_path, 300);
317 }
318 else if (strcmp(def_path, listpath[i]))
319 /* path from the list */
320 strncpy(path, listpath[i], 300);
321 else
322 continue;
323
324 if (i > 0)
325 {
326 strcat(path, "/");
327 strncat(path, libname, 100);
328 }
329 path[511] = 0;
330 wm = MODULE_LoadLibraryExA( path, hfile, flags );
331
332 if (!wm)
333 {
334 if (checked[0])
335 strcat(checked, ", ");
336 strcat(checked, path);
337 checked[1500] = 0;
338
339 }
340 }
300 if ( wm ) 341 if ( wm )
301 { 342 {
302 if ( !MODULE_DllProcessAttach( wm, NULL ) ) 343 if ( !MODULE_DllProcessAttach( wm, NULL ) )
303 { 344 {
304 WARN_(module)("Attach failed for module '%s', \n", libname); 345 WARN_(module)("Attach failed for module '%s', \n", libname);
307 MODULE_RemoveFromList(wm); 348 MODULE_RemoveFromList(wm);
308 wm = NULL; 349 wm = NULL;
309 } 350 }
310 } 351 }
311 352
353 if (!wm)
354 printf("Win32 LoadLibrary failed to load: %s\n", checked);
355
356
312 return wm ? wm->module : 0; 357 return wm ? wm->module : 0;
313 } 358 }
314 359
315 360
316 /*********************************************************************** 361 /***********************************************************************
328 { 373 {
329 DWORD err = GetLastError(); 374 DWORD err = GetLastError();
330 WINE_MODREF *pwm; 375 WINE_MODREF *pwm;
331 int i; 376 int i;
332 // module_loadorder_t *plo; 377 // module_loadorder_t *plo;
333
334 378
335 SetLastError( ERROR_FILE_NOT_FOUND ); 379 SetLastError( ERROR_FILE_NOT_FOUND );
336 TRACE("Trying native dll '%s'\n", libname); 380 TRACE("Trying native dll '%s'\n", libname);
337 pwm = PE_LoadLibraryExA(libname, flags); 381 pwm = PE_LoadLibraryExA(libname, flags);
338 #ifdef HAVE_LIBDL 382 #ifdef HAVE_LIBDL
339 if(!pwm) 383 if(!pwm)
340 { 384 {
341 TRACE("Trying ELF dll '%s'\n", libname); 385 TRACE("Trying ELF dll '%s'\n", libname);
342 pwm=(WINE_MODREF*)ELFDLL_LoadLibraryExA(libname, flags); 386 pwm=(WINE_MODREF*)ELFDLL_LoadLibraryExA(libname, flags);
343 } 387 }
344 #endif 388 #endif
345 // printf("0x%08x\n", pwm); 389 // printf("0x%08x\n", pwm);
346 // break; 390 // break;
347 if(pwm) 391 if(pwm)
348 { 392 {
349 /* Initialize DLL just loaded */ 393 /* Initialize DLL just loaded */
354 398
355 SetLastError( err ); /* restore last error */ 399 SetLastError( err ); /* restore last error */
356 return pwm; 400 return pwm;
357 } 401 }
358 402
359 403
360 WARN("Failed to load module '%s'; error=0x%08lx, \n", libname, GetLastError()); 404 WARN("Failed to load module '%s'; error=0x%08lx, \n", libname, GetLastError());
361 return NULL; 405 return NULL;
362 } 406 }
363 407
364 /*********************************************************************** 408 /***********************************************************************
382 426
383 if ( !wm || !hLibModule ) 427 if ( !wm || !hLibModule )
384 { 428 {
385 SetLastError( ERROR_INVALID_HANDLE ); 429 SetLastError( ERROR_INVALID_HANDLE );
386 return 0; 430 return 0;
387 } 431 }
388 else 432 else
389 retv = MODULE_FreeLibrary( wm ); 433 retv = MODULE_FreeLibrary( wm );
390 434
391 MODULE_RemoveFromList(wm); 435 MODULE_RemoveFromList(wm);
392 436
393 /* garbage... */ 437 /* garbage... */
394 if (local_wm == NULL) my_garbagecollection(); 438 if (local_wm == NULL) my_garbagecollection();
395 439
457 } 501 }
458 502
459 /*********************************************************************** 503 /***********************************************************************
460 * MODULE_GetProcAddress (internal) 504 * MODULE_GetProcAddress (internal)
461 */ 505 */
462 FARPROC MODULE_GetProcAddress( 506 FARPROC MODULE_GetProcAddress(
463 HMODULE hModule, /* [in] current module handle */ 507 HMODULE hModule, /* [in] current module handle */
464 LPCSTR function, /* [in] function to be looked up */ 508 LPCSTR function, /* [in] function to be looked up */
465 WIN_BOOL snoop ) 509 WIN_BOOL snoop )
466 { 510 {
467 WINE_MODREF *wm = MODULE32_LookupHMODULE( hModule ); 511 WINE_MODREF *wm = MODULE32_LookupHMODULE( hModule );
468 // WINE_MODREF *wm=local_wm; 512 // WINE_MODREF *wm=local_wm;
469 FARPROC retproc; 513 FARPROC retproc;
470 514
471 if (HIWORD(function)) 515 if (HIWORD(function))
472 TRACE_(win32)("(%08lx,%s)\n",(DWORD)hModule,function); 516 TRACE_(win32)("(%08lx,%s)\n",(DWORD)hModule,function);
473 else 517 else
480 { 524 {
481 case MODULE32_PE: 525 case MODULE32_PE:
482 retproc = PE_FindExportedFunction( wm, function, snoop ); 526 retproc = PE_FindExportedFunction( wm, function, snoop );
483 if (!retproc) SetLastError(ERROR_PROC_NOT_FOUND); 527 if (!retproc) SetLastError(ERROR_PROC_NOT_FOUND);
484 return retproc; 528 return retproc;
485 #ifdef HAVE_LIBDL 529 #ifdef HAVE_LIBDL
486 case MODULE32_ELF: 530 case MODULE32_ELF:
487 retproc = (FARPROC) dlsym( (void*)wm->module, function); 531 retproc = (FARPROC) dlsym( (void*) wm->module, function);
488 if (!retproc) SetLastError(ERROR_PROC_NOT_FOUND); 532 if (!retproc) SetLastError(ERROR_PROC_NOT_FOUND);
489 return retproc; 533 return retproc;
490 #endif 534 #endif
491 default: 535 default:
492 ERR("wine_modref type %d not handled.\n",wm->type); 536 ERR("wine_modref type %d not handled.\n",wm->type);