From 8ca7e0af781e26f59dcfe9dcbfd3b4a68093d581 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Thu, 3 Jul 2003 18:23:10 +0000 Subject: [PATCH] Added a file_exists argument to wine_dll_load to allow checking whether a failed dll load is because the file didn't exist; more robust than trying to guess the contents of the error string... Get rid of BUILTIN32_dlopen. --- if1632/builtin.c | 11 ++++++--- include/module.h | 1 - include/wine/library.h | 5 ++-- libs/wine/loader.c | 28 ++++++++++----------- relay32/builtin32.c | 56 ++++++++++++++++-------------------------- scheduler/process.c | 20 +++++++++------ 6 files changed, 57 insertions(+), 64 deletions(-) diff --git a/if1632/builtin.c b/if1632/builtin.c index a746791f990..206d056308e 100644 --- a/if1632/builtin.c +++ b/if1632/builtin.c @@ -184,7 +184,8 @@ BOOL BUILTIN_IsPresent( LPCSTR name ) HMODULE16 BUILTIN_LoadModule( LPCSTR name ) { const BUILTIN16_DESCRIPTOR *descr; - char dllname[20], *p; + char error[256], dllname[20], *p; + int file_exists; void *handle; /* Fix the name in case we have a full path and extension */ @@ -202,14 +203,18 @@ HMODULE16 BUILTIN_LoadModule( LPCSTR name ) if ((descr = find_dll_descr( dllname ))) return BUILTIN_DoLoadModule16( descr ); - if (BUILTIN32_dlopen( dllname, &handle ) == STATUS_SUCCESS) + if ((handle = wine_dll_load( dllname, error, sizeof(error), &file_exists ))) { if ((descr = find_dll_descr( dllname ))) return BUILTIN_DoLoadModule16( descr ); ERR( "loaded .so but dll %s still not found\n", dllname ); } - + else + { + if (!file_exists) WARN("cannot open .so lib for 16-bit builtin %s: %s\n", name, error); + else ERR("failed to load .so lib for 16-bit builtin %s: %s\n", name, error ); + } return (HMODULE16)2; } diff --git a/include/module.h b/include/module.h index ca860e66679..56b4b6fbe0c 100644 --- a/include/module.h +++ b/include/module.h @@ -229,7 +229,6 @@ extern void MODULE_AddLoadOrderOption( const char *option ); /* relay32/builtin.c */ extern NTSTATUS BUILTIN32_LoadLibraryExA(LPCSTR name, DWORD flags, WINE_MODREF**); extern HMODULE BUILTIN32_LoadExeModule( HMODULE main ); -extern NTSTATUS BUILTIN32_dlopen( const char *name, void** handle ); /* if1632/builtin.c */ extern HMODULE16 BUILTIN_LoadModule( LPCSTR name ); diff --git a/include/wine/library.h b/include/wine/library.h index 93d61bf78a8..676c75b2140 100644 --- a/include/wine/library.h +++ b/include/wine/library.h @@ -38,8 +38,9 @@ extern void *wine_dlopen( const char *filename, int flag, char *error, int error extern void *wine_dlsym( void *handle, const char *symbol, char *error, int errorsize ); extern int wine_dlclose( void *handle, char *error, int errorsize ); extern void wine_dll_set_callback( load_dll_callback_t load ); -extern void *wine_dll_load( const char *filename, char *error, int errorsize ); -extern void *wine_dll_load_main_exe( const char *name, char *error, int errorsize, int test_only ); +extern void *wine_dll_load( const char *filename, char *error, int errorsize, int *file_exists ); +extern void *wine_dll_load_main_exe( const char *name, char *error, int errorsize, + int test_only, int *file_exists ); extern void wine_dll_unload( void *handle ); extern int __wine_main_argc; diff --git a/libs/wine/loader.c b/libs/wine/loader.c index dbac56bf8a7..2164657504d 100644 --- a/libs/wine/loader.c +++ b/libs/wine/loader.c @@ -126,7 +126,8 @@ inline static int file_exists( const char *name ) /* open a library for a given dll, searching in the dll path * 'name' must be the Windows dll name (e.g. "kernel32.dll") */ -static void *dlopen_dll( const char *name, char *error, int errorsize, int test_only ) +static void *dlopen_dll( const char *name, char *error, int errorsize, + int test_only, int *exists ) { int i, namelen = strlen(name); char *buffer, *p; @@ -141,21 +142,15 @@ static void *dlopen_dll( const char *name, char *error, int errorsize, int test_ *p++ = '/'; memcpy( p, name, namelen ); strcpy( p + namelen, ".so" ); + *exists = 0; for (i = 0; i < nb_dll_paths; i++) { int len = strlen(dll_paths[i]); p = buffer + dll_path_maxlen - len; memcpy( p, dll_paths[i], len ); - if (test_only) /* just test for file existence */ - { - if ((ret = (void *)file_exists( p ))) break; - } - else - { - if ((ret = wine_dlopen( p, RTLD_NOW, error, errorsize ))) break; - if (file_exists( p )) break; /* exists but cannot be loaded, return the error */ - } + if (!test_only && (ret = wine_dlopen( p, RTLD_NOW, error, errorsize ))) break; + if ((*exists = file_exists( p ))) break; /* exists but cannot be loaded, return the error */ } free( buffer ); return ret; @@ -367,7 +362,7 @@ void wine_dll_set_callback( load_dll_callback_t load ) * * Load a builtin dll. */ -void *wine_dll_load( const char *filename, char *error, int errorsize ) +void *wine_dll_load( const char *filename, char *error, int errorsize, int *file_exists ) { int i; @@ -384,10 +379,11 @@ void *wine_dll_load( const char *filename, char *error, int errorsize ) const IMAGE_NT_HEADERS *nt = builtin_dlls[i].nt; builtin_dlls[i].nt = NULL; load_dll_callback( map_dll(nt), builtin_dlls[i].filename ); + *file_exists = 1; return (void *)1; } } - return dlopen_dll( filename, error, errorsize, 0 ); + return dlopen_dll( filename, error, errorsize, 0, file_exists ); } @@ -408,9 +404,10 @@ void wine_dll_unload( void *handle ) * * Try to load the .so for the main exe. */ -void *wine_dll_load_main_exe( const char *name, char *error, int errorsize, int test_only ) +void *wine_dll_load_main_exe( const char *name, char *error, int errorsize, + int test_only, int *file_exists ) { - return dlopen_dll( name, error, errorsize, test_only ); + return dlopen_dll( name, error, errorsize, test_only, file_exists ); } @@ -421,10 +418,11 @@ void *wine_dll_load_main_exe( const char *name, char *error, int errorsize, int */ void wine_init( int argc, char *argv[], char *error, int error_size ) { + int file_exists; void *ntdll; void (*init_func)(int, char **); - if (!(ntdll = dlopen_dll( "ntdll.dll", error, error_size, 0 ))) return; + if (!(ntdll = dlopen_dll( "ntdll.dll", error, error_size, 0, &file_exists ))) return; if (!(init_func = wine_dlsym( ntdll, "__wine_process_init", error, error_size ))) return; init_func( argc, argv ); } diff --git a/relay32/builtin32.c b/relay32/builtin32.c index 3bcbb1be76b..0d9dfb862e1 100644 --- a/relay32/builtin32.c +++ b/relay32/builtin32.c @@ -45,37 +45,6 @@ WINE_DECLARE_DEBUG_CHANNEL(relay); static HMODULE main_module; static NTSTATUS last_status; /* use to gather all errors in callback */ -/*********************************************************************** - * BUILTIN32_dlopen - * - * The loader critical section must be locked while calling this function - */ -NTSTATUS BUILTIN32_dlopen( const char *name, void** handle) -{ - char error[256]; - - last_status = STATUS_SUCCESS; - /* load_library will modify last_status. Note also that load_library can be - * called several times, if the .so file we're loading has dependencies. - * last_status will gather all the errors we may get while loading all these - * libraries - */ - if (!(*handle = wine_dll_load( name, error, sizeof(error) ))) - { - if (strstr(error, "cannot open") || strstr(error, "open failed") || - (strstr(error, "Shared object") && strstr(error, "not found"))) { - /* The file does not exist -> WARN() */ - WARN("cannot open .so lib for builtin %s: %s\n", name, error); - last_status = STATUS_NO_SUCH_FILE; - } else { - /* ERR() for all other errors (missing functions, ...) */ - ERR("failed to load .so lib for builtin %s: %s\n", name, error ); - last_status = STATUS_PROCEDURE_NOT_FOUND; - } - } - return last_status; -} - /*********************************************************************** * load_library @@ -151,10 +120,10 @@ static void load_library( void *base, const char *filename ) */ NTSTATUS BUILTIN32_LoadLibraryExA(LPCSTR path, DWORD flags, WINE_MODREF** pwm) { - char dllname[20], *p; + char error[256], dllname[20], *p; + int file_exists; LPCSTR name; void *handle; - NTSTATUS nts; /* Fix the name in case we have a full path and extension */ name = path; @@ -168,8 +137,25 @@ NTSTATUS BUILTIN32_LoadLibraryExA(LPCSTR path, DWORD flags, WINE_MODREF** pwm) if (!p) strcat( dllname, ".dll" ); for (p = dllname; *p; p++) *p = FILE_tolower(*p); - if ((nts = BUILTIN32_dlopen( dllname, &handle )) != STATUS_SUCCESS) - return nts; + last_status = STATUS_SUCCESS; + /* load_library will modify last_status. Note also that load_library can be + * called several times, if the .so file we're loading has dependencies. + * last_status will gather all the errors we may get while loading all these + * libraries + */ + if (!(handle = wine_dll_load( dllname, error, sizeof(error), &file_exists ))) + { + if (!file_exists) + { + /* The file does not exist -> WARN() */ + WARN("cannot open .so lib for builtin %s: %s\n", name, error); + return STATUS_NO_SUCH_FILE; + } + /* ERR() for all other errors (missing functions, ...) */ + ERR("failed to load .so lib for builtin %s: %s\n", name, error ); + return STATUS_PROCEDURE_NOT_FOUND; + } + if (last_status != STATUS_SUCCESS) return last_status; if (!((*pwm) = MODULE_FindModule( path ))) *pwm = MODULE_FindModule( dllname ); if (!*pwm) diff --git a/scheduler/process.c b/scheduler/process.c index 34831a62a36..88b5201f9a0 100644 --- a/scheduler/process.c +++ b/scheduler/process.c @@ -146,7 +146,8 @@ inline static const char *get_basename( const char *name ) * * Open an exe file for a builtin exe. */ -static void *open_builtin_exe_file( const char *name, char *error, int error_size, int test_only ) +static void *open_builtin_exe_file( const char *name, char *error, int error_size, + int test_only, int *file_exists ) { char exename[MAX_PATH], *p; const char *basename = get_basename(name); @@ -154,7 +155,7 @@ static void *open_builtin_exe_file( const char *name, char *error, int error_siz if (strlen(basename) >= sizeof(exename)) return NULL; strcpy( exename, basename ); for (p = exename; *p; p++) *p = FILE_tolower(*p); - return wine_dll_load_main_exe( exename, error, error_size, test_only ); + return wine_dll_load_main_exe( exename, error, error_size, test_only, file_exists ); } @@ -169,7 +170,7 @@ static HANDLE open_exe_file( const char *name ) enum loadorder_type loadorder[LOADORDER_NTYPES]; char buffer[MAX_PATH]; HANDLE handle; - int i; + int i, file_exists; TRACE("looking for %s\n", debugstr_a(name) ); @@ -195,7 +196,8 @@ static HANDLE open_exe_file( const char *name ) break; case LOADORDER_BI: TRACE( "Trying built-in exe %s\n", debugstr_a(name) ); - if (open_builtin_exe_file( name, NULL, 0, 1 )) + open_builtin_exe_file( name, NULL, 0, 1, &file_exists ); + if (file_exists) { if (handle != INVALID_HANDLE_VALUE) CloseHandle(handle); return 0; @@ -223,7 +225,7 @@ static HANDLE open_exe_file( const char *name ) static BOOL find_exe_file( const char *name, char *buffer, int buflen, HANDLE *handle ) { enum loadorder_type loadorder[LOADORDER_NTYPES]; - int i; + int i, file_exists; TRACE("looking for %s\n", debugstr_a(name) ); @@ -258,7 +260,8 @@ static BOOL find_exe_file( const char *name, char *buffer, int buflen, HANDLE *h break; case LOADORDER_BI: TRACE( "Trying built-in exe %s\n", debugstr_a(buffer) ); - if (open_builtin_exe_file( buffer, NULL, 0, 1 )) + open_builtin_exe_file( buffer, NULL, 0, 1, &file_exists ); + if (file_exists) { *handle = 0; return TRUE; @@ -473,6 +476,7 @@ void __wine_process_init( int argc, char *argv[] ) { char error[1024], *p; DWORD stack_size = 0; + int file_exists; /* Initialize everything */ if (!process_init( argv )) exit(1); @@ -501,7 +505,7 @@ void __wine_process_init( int argc, char *argv[] ) if (!main_exe_file) /* no file handle -> Winelib app */ { TRACE( "starting Winelib app %s\n", debugstr_a(main_exe_name) ); - if (open_builtin_exe_file( main_exe_name, error, sizeof(error), 0 )) + if (open_builtin_exe_file( main_exe_name, error, sizeof(error), 0, &file_exists )) goto found; MESSAGE( "%s: cannot open builtin library for '%s': %s\n", argv0, main_exe_name, error ); ExitProcess(1); @@ -533,7 +537,7 @@ void __wine_process_init( int argc, char *argv[] ) main_exe_file = 0; argv--; argv[0] = "winevdm.exe"; - if (open_builtin_exe_file( "winevdm.exe", error, sizeof(error), 0 )) + if (open_builtin_exe_file( "winevdm.exe", error, sizeof(error), 0, &file_exists )) goto found; MESSAGE( "%s: trying to run '%s', cannot open builtin library for 'winevdm.exe': %s\n", argv0, main_exe_name, error );