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:
Alexandre Julliard 2003-07-03 18:23:10 +00:00
parent d55e7f1e9b
commit 8ca7e0af78
6 changed files with 57 additions and 64 deletions

View file

@ -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;
}

View file

@ -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 );

View file

@ -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;

View file

@ -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 );
}

View file

@ -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)

View file

@ -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 );