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 )
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 );
|
||||
|
|
Loading…
Reference in New Issue