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.
This commit is contained in:
parent
d55e7f1e9b
commit
8ca7e0af78
|
@ -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 )
|
||||||
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 );
|
||||||
/* 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
|
||||||
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 )
|
||||||
|
|
||||||
/* 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_
|
||||||
*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 )
|
||||||
*
|
*
|
||||||
* 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 )
|
||||||
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 )
|
||||||
*
|
*
|
||||||
* 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
|
||||||
*/
|
*/
|
||||||
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);
|
||||||
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 )
|
||||||
*/
|
*/
|
||||||
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)
|
||||||
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 )
|
||||||
*
|
*
|
||||||
* 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
|
||||||
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 )
|
||||||
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 )
|
||||||
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 )
|
||||||
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
|
||||||
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[] )
|
||||||
{
|
{
|
||||||
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[] )
|
||||||
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[] )
|
||||||
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 );
|
||||||
|
|
Loading…
Reference in New Issue