Mercurial > mplayer.hg
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); |