Commit 8ca7e0af authored by Alexandre Julliard's avatar Alexandre Julliard

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.
parent d55e7f1e
...@@ -184,7 +184,8 @@ BOOL BUILTIN_IsPresent( LPCSTR name ) ...@@ -184,7 +184,8 @@ BOOL BUILTIN_IsPresent( LPCSTR name )
HMODULE16 BUILTIN_LoadModule( LPCSTR name ) HMODULE16 BUILTIN_LoadModule( LPCSTR name )
{ {
const BUILTIN16_DESCRIPTOR *descr; const BUILTIN16_DESCRIPTOR *descr;
char dllname[20], *p; char error[256], dllname[20], *p;
int file_exists;
void *handle; void *handle;
/* Fix the name in case we have a full path and extension */ /* Fix the name in case we have a full path and extension */
...@@ -202,14 +203,18 @@ HMODULE16 BUILTIN_LoadModule( LPCSTR name ) ...@@ -202,14 +203,18 @@ HMODULE16 BUILTIN_LoadModule( LPCSTR name )
if ((descr = find_dll_descr( dllname ))) if ((descr = find_dll_descr( dllname )))
return BUILTIN_DoLoadModule16( descr ); 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 ))) if ((descr = find_dll_descr( dllname )))
return BUILTIN_DoLoadModule16( descr ); return BUILTIN_DoLoadModule16( descr );
ERR( "loaded .so but dll %s still not found\n", dllname ); 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; return (HMODULE16)2;
} }
......
...@@ -229,7 +229,6 @@ extern void MODULE_AddLoadOrderOption( const char *option ); ...@@ -229,7 +229,6 @@ extern void MODULE_AddLoadOrderOption( const char *option );
/* relay32/builtin.c */ /* relay32/builtin.c */
extern NTSTATUS BUILTIN32_LoadLibraryExA(LPCSTR name, DWORD flags, WINE_MODREF**); extern NTSTATUS BUILTIN32_LoadLibraryExA(LPCSTR name, DWORD flags, WINE_MODREF**);
extern HMODULE BUILTIN32_LoadExeModule( HMODULE main ); extern HMODULE BUILTIN32_LoadExeModule( HMODULE main );
extern NTSTATUS BUILTIN32_dlopen( const char *name, void** handle );
/* if1632/builtin.c */ /* if1632/builtin.c */
extern HMODULE16 BUILTIN_LoadModule( LPCSTR name ); extern HMODULE16 BUILTIN_LoadModule( LPCSTR name );
......
...@@ -38,8 +38,9 @@ extern void *wine_dlopen( const char *filename, int flag, char *error, int error ...@@ -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 void *wine_dlsym( void *handle, const char *symbol, char *error, int errorsize );
extern int wine_dlclose( void *handle, 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_set_callback( load_dll_callback_t load );
extern void *wine_dll_load( const char *filename, char *error, int errorsize ); 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 ); 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 void wine_dll_unload( void *handle );
extern int __wine_main_argc; extern int __wine_main_argc;
......
...@@ -126,7 +126,8 @@ inline static int file_exists( const char *name ) ...@@ -126,7 +126,8 @@ inline static int file_exists( const char *name )
/* open a library for a given dll, searching in the dll path /* open a library for a given dll, searching in the dll path
* 'name' must be the Windows dll name (e.g. "kernel32.dll") */ * '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); int i, namelen = strlen(name);
char *buffer, *p; char *buffer, *p;
...@@ -141,21 +142,15 @@ static void *dlopen_dll( const char *name, char *error, int errorsize, int test_ ...@@ -141,21 +142,15 @@ static void *dlopen_dll( const char *name, char *error, int errorsize, int test_
*p++ = '/'; *p++ = '/';
memcpy( p, name, namelen ); memcpy( p, name, namelen );
strcpy( p + namelen, ".so" ); strcpy( p + namelen, ".so" );
*exists = 0;
for (i = 0; i < nb_dll_paths; i++) for (i = 0; i < nb_dll_paths; i++)
{ {
int len = strlen(dll_paths[i]); int len = strlen(dll_paths[i]);
p = buffer + dll_path_maxlen - len; p = buffer + dll_path_maxlen - len;
memcpy( p, dll_paths[i], len ); memcpy( p, dll_paths[i], len );
if (test_only) /* just test for file existence */ 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 */
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 */
}
} }
free( buffer ); free( buffer );
return ret; return ret;
...@@ -367,7 +362,7 @@ void wine_dll_set_callback( load_dll_callback_t load ) ...@@ -367,7 +362,7 @@ void wine_dll_set_callback( load_dll_callback_t load )
* *
* Load a builtin dll. * 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; int i;
...@@ -384,10 +379,11 @@ void *wine_dll_load( const char *filename, char *error, int errorsize ) ...@@ -384,10 +379,11 @@ void *wine_dll_load( const char *filename, char *error, int errorsize )
const IMAGE_NT_HEADERS *nt = builtin_dlls[i].nt; const IMAGE_NT_HEADERS *nt = builtin_dlls[i].nt;
builtin_dlls[i].nt = NULL; builtin_dlls[i].nt = NULL;
load_dll_callback( map_dll(nt), builtin_dlls[i].filename ); load_dll_callback( map_dll(nt), builtin_dlls[i].filename );
*file_exists = 1;
return (void *)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 ) ...@@ -408,9 +404,10 @@ void wine_dll_unload( void *handle )
* *
* Try to load the .so for the main exe. * 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 ...@@ -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 ) void wine_init( int argc, char *argv[], char *error, int error_size )
{ {
int file_exists;
void *ntdll; void *ntdll;
void (*init_func)(int, char **); 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; if (!(init_func = wine_dlsym( ntdll, "__wine_process_init", error, error_size ))) return;
init_func( argc, argv ); init_func( argc, argv );
} }
......
...@@ -45,37 +45,6 @@ WINE_DECLARE_DEBUG_CHANNEL(relay); ...@@ -45,37 +45,6 @@ WINE_DECLARE_DEBUG_CHANNEL(relay);
static HMODULE main_module; static HMODULE main_module;
static NTSTATUS last_status; /* use to gather all errors in callback */ 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 * load_library
...@@ -151,10 +120,10 @@ static void load_library( void *base, const char *filename ) ...@@ -151,10 +120,10 @@ static void load_library( void *base, const char *filename )
*/ */
NTSTATUS BUILTIN32_LoadLibraryExA(LPCSTR path, DWORD flags, WINE_MODREF** pwm) 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; LPCSTR name;
void *handle; void *handle;
NTSTATUS nts;
/* Fix the name in case we have a full path and extension */ /* Fix the name in case we have a full path and extension */
name = path; name = path;
...@@ -168,8 +137,25 @@ NTSTATUS BUILTIN32_LoadLibraryExA(LPCSTR path, DWORD flags, WINE_MODREF** pwm) ...@@ -168,8 +137,25 @@ NTSTATUS BUILTIN32_LoadLibraryExA(LPCSTR path, DWORD flags, WINE_MODREF** pwm)
if (!p) strcat( dllname, ".dll" ); if (!p) strcat( dllname, ".dll" );
for (p = dllname; *p; p++) *p = FILE_tolower(*p); for (p = dllname; *p; p++) *p = FILE_tolower(*p);
if ((nts = BUILTIN32_dlopen( dllname, &handle )) != STATUS_SUCCESS) last_status = STATUS_SUCCESS;
return nts; /* 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) = MODULE_FindModule( path ))) *pwm = MODULE_FindModule( dllname );
if (!*pwm) if (!*pwm)
......
...@@ -146,7 +146,8 @@ inline static const char *get_basename( const char *name ) ...@@ -146,7 +146,8 @@ inline static const char *get_basename( const char *name )
* *
* Open an exe file for a builtin exe. * 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; char exename[MAX_PATH], *p;
const char *basename = get_basename(name); const char *basename = get_basename(name);
...@@ -154,7 +155,7 @@ static void *open_builtin_exe_file( const char *name, char *error, int error_siz ...@@ -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; if (strlen(basename) >= sizeof(exename)) return NULL;
strcpy( exename, basename ); strcpy( exename, basename );
for (p = exename; *p; p++) *p = FILE_tolower(*p); 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 ) ...@@ -169,7 +170,7 @@ static HANDLE open_exe_file( const char *name )
enum loadorder_type loadorder[LOADORDER_NTYPES]; enum loadorder_type loadorder[LOADORDER_NTYPES];
char buffer[MAX_PATH]; char buffer[MAX_PATH];
HANDLE handle; HANDLE handle;
int i; int i, file_exists;
TRACE("looking for %s\n", debugstr_a(name) ); TRACE("looking for %s\n", debugstr_a(name) );
...@@ -195,7 +196,8 @@ static HANDLE open_exe_file( const char *name ) ...@@ -195,7 +196,8 @@ static HANDLE open_exe_file( const char *name )
break; break;
case LOADORDER_BI: case LOADORDER_BI:
TRACE( "Trying built-in exe %s\n", debugstr_a(name) ); 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); if (handle != INVALID_HANDLE_VALUE) CloseHandle(handle);
return 0; return 0;
...@@ -223,7 +225,7 @@ static HANDLE open_exe_file( const char *name ) ...@@ -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 ) static BOOL find_exe_file( const char *name, char *buffer, int buflen, HANDLE *handle )
{ {
enum loadorder_type loadorder[LOADORDER_NTYPES]; enum loadorder_type loadorder[LOADORDER_NTYPES];
int i; int i, file_exists;
TRACE("looking for %s\n", debugstr_a(name) ); 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 ...@@ -258,7 +260,8 @@ static BOOL find_exe_file( const char *name, char *buffer, int buflen, HANDLE *h
break; break;
case LOADORDER_BI: case LOADORDER_BI:
TRACE( "Trying built-in exe %s\n", debugstr_a(buffer) ); 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; *handle = 0;
return TRUE; return TRUE;
...@@ -473,6 +476,7 @@ void __wine_process_init( int argc, char *argv[] ) ...@@ -473,6 +476,7 @@ void __wine_process_init( int argc, char *argv[] )
{ {
char error[1024], *p; char error[1024], *p;
DWORD stack_size = 0; DWORD stack_size = 0;
int file_exists;
/* Initialize everything */ /* Initialize everything */
if (!process_init( argv )) exit(1); if (!process_init( argv )) exit(1);
...@@ -501,7 +505,7 @@ void __wine_process_init( int argc, char *argv[] ) ...@@ -501,7 +505,7 @@ void __wine_process_init( int argc, char *argv[] )
if (!main_exe_file) /* no file handle -> Winelib app */ if (!main_exe_file) /* no file handle -> Winelib app */
{ {
TRACE( "starting Winelib app %s\n", debugstr_a(main_exe_name) ); 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; goto found;
MESSAGE( "%s: cannot open builtin library for '%s': %s\n", argv0, main_exe_name, error ); MESSAGE( "%s: cannot open builtin library for '%s': %s\n", argv0, main_exe_name, error );
ExitProcess(1); ExitProcess(1);
...@@ -533,7 +537,7 @@ void __wine_process_init( int argc, char *argv[] ) ...@@ -533,7 +537,7 @@ void __wine_process_init( int argc, char *argv[] )
main_exe_file = 0; main_exe_file = 0;
argv--; argv--;
argv[0] = "winevdm.exe"; 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; goto found;
MESSAGE( "%s: trying to run '%s', cannot open builtin library for 'winevdm.exe': %s\n", MESSAGE( "%s: trying to run '%s', cannot open builtin library for 'winevdm.exe': %s\n",
argv0, main_exe_name, error ); argv0, main_exe_name, error );
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment