Make behavior of builtin executables closer to that of builtin dlls.
Fixed case sensitivity of builtin executables.
This commit is contained in:
parent
7887259686
commit
befbb0e441
|
@ -259,6 +259,7 @@ extern BOOL PE_InitDLL( HMODULE module, DWORD type, LPVOID lpReserved );
|
|||
extern DWORD PE_fixup_imports(WINE_MODREF *wm);
|
||||
|
||||
/* loader/loadorder.c */
|
||||
extern BOOL MODULE_GetBuiltinPath( const char *libname, const char *ext, char *filename, UINT size );
|
||||
extern void MODULE_GetLoadOrder( enum loadorder_type plo[], const char *path, BOOL win32 );
|
||||
extern void MODULE_AddLoadOrderOption( const char *option );
|
||||
|
||||
|
|
|
@ -417,6 +417,62 @@ static BOOL get_registry_value( HKEY hkey, const char *module, enum loadorder_ty
|
|||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* MODULE_GetBuiltinPath
|
||||
*
|
||||
* Get the path of a builtin module when the native file does not exist.
|
||||
*/
|
||||
BOOL MODULE_GetBuiltinPath( const char *libname, const char *ext, char *filename, UINT size )
|
||||
{
|
||||
char *p;
|
||||
BOOL ret = FALSE;
|
||||
UINT len = GetSystemDirectoryA( filename, size );
|
||||
|
||||
if (FILE_contains_path( libname ))
|
||||
{
|
||||
char *tmp;
|
||||
|
||||
/* if the library name contains a path and can not be found,
|
||||
* return an error.
|
||||
* exception: if the path is the system directory, proceed,
|
||||
* so that modules which are not PE modules can be loaded.
|
||||
* If the library name does not contain a path and can not
|
||||
* be found, assume the system directory is meant */
|
||||
|
||||
if (strlen(libname) >= size) return FALSE; /* too long */
|
||||
if (strchr( libname, '/' )) /* need to convert slashes */
|
||||
{
|
||||
if (!(tmp = HeapAlloc( GetProcessHeap(), 0, strlen(libname)+1 ))) return FALSE;
|
||||
strcpy( tmp, libname );
|
||||
for (p = tmp; *p; p++) if (*p == '/') *p = '\\';
|
||||
}
|
||||
else tmp = (char *)libname;
|
||||
|
||||
if (!FILE_strncasecmp( filename, tmp, len ) && tmp[len] == '\\')
|
||||
{
|
||||
strcpy( filename, tmp );
|
||||
ret = TRUE;
|
||||
}
|
||||
if (tmp != libname) HeapFree( GetProcessHeap(), 0, tmp );
|
||||
if (!ret) return FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (strlen(libname) >= size - len - 1) return FALSE;
|
||||
filename[len] = '\\';
|
||||
strcpy( filename+len+1, libname );
|
||||
}
|
||||
|
||||
/* if the filename doesn't have an extension, append the default */
|
||||
if (!(p = strrchr( filename, '.')) || strchr( p, '/' ) || strchr( p, '\\'))
|
||||
{
|
||||
if (strlen(filename) + strlen(ext) >= size) return FALSE;
|
||||
strcat( filename, ext );
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* MODULE_GetLoadOrder (internal)
|
||||
*
|
||||
|
|
|
@ -1194,7 +1194,7 @@ WINE_MODREF *MODULE_LoadLibraryExA( LPCSTR libname, HANDLE hfile, DWORD flags )
|
|||
WINE_MODREF *pwm;
|
||||
int i;
|
||||
enum loadorder_type loadorder[LOADORDER_NTYPES];
|
||||
LPSTR filename, p;
|
||||
LPSTR filename;
|
||||
const char *filetype = "";
|
||||
DWORD found;
|
||||
BOOL allocated_libdir = FALSE;
|
||||
|
@ -1222,28 +1222,7 @@ WINE_MODREF *MODULE_LoadLibraryExA( LPCSTR libname, HANDLE hfile, DWORD flags )
|
|||
/* build the modules filename */
|
||||
if (!found)
|
||||
{
|
||||
if ( ! GetSystemDirectoryA ( filename, MAX_PATH ) )
|
||||
goto error;
|
||||
|
||||
/* if the library name contains a path and can not be found,
|
||||
* return an error.
|
||||
* exception: if the path is the system directory, proceed,
|
||||
* so that modules which are not PE modules can be loaded.
|
||||
* If the library name does not contain a path and can not
|
||||
* be found, assume the system directory is meant */
|
||||
|
||||
if ( ! FILE_strncasecmp ( filename, libname, strlen ( filename ) ))
|
||||
strcpy ( filename, libname );
|
||||
else
|
||||
{
|
||||
if (FILE_contains_path(libname)) goto error;
|
||||
strcat ( filename, "\\" );
|
||||
strcat ( filename, libname );
|
||||
}
|
||||
|
||||
/* if the filename doesn't have an extension, append .DLL */
|
||||
if (!(p = strrchr( filename, '.')) || strchr( p, '/' ) || strchr( p, '\\'))
|
||||
strcat( filename, ".dll" );
|
||||
if (!MODULE_GetBuiltinPath( libname, ".dll", filename, MAX_PATH )) goto error;
|
||||
}
|
||||
|
||||
/* Check for already loaded module */
|
||||
|
|
|
@ -254,19 +254,47 @@ inline static const char *get_basename( const char *name )
|
|||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* open_builtin_exe_file
|
||||
*
|
||||
* 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 )
|
||||
{
|
||||
char exename[MAX_PATH], *p;
|
||||
const char *basename = get_basename(name);
|
||||
|
||||
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 );
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* open_exe_file
|
||||
*
|
||||
* Open an exe file, taking load order into account.
|
||||
* Open a specific exe file, taking load order into account.
|
||||
* Returns the file handle or 0 for a builtin exe.
|
||||
*/
|
||||
static HANDLE open_exe_file( const char *name )
|
||||
{
|
||||
enum loadorder_type loadorder[LOADORDER_NTYPES];
|
||||
char buffer[MAX_PATH];
|
||||
HANDLE handle;
|
||||
int i;
|
||||
|
||||
SetLastError( ERROR_FILE_NOT_FOUND );
|
||||
TRACE("looking for %s\n", debugstr_a(name) );
|
||||
|
||||
if ((handle = CreateFileA( name, GENERIC_READ, FILE_SHARE_READ,
|
||||
NULL, OPEN_EXISTING, 0, 0 )) == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
/* file doesn't exist, check for builtin */
|
||||
if (!FILE_contains_path( name )) goto error;
|
||||
if (!MODULE_GetBuiltinPath( name, "", buffer, sizeof(buffer) )) goto error;
|
||||
name = buffer;
|
||||
}
|
||||
|
||||
MODULE_GetLoadOrder( loadorder, name, TRUE );
|
||||
|
||||
for(i = 0; i < LOADORDER_NTYPES; i++)
|
||||
|
@ -276,19 +304,23 @@ static HANDLE open_exe_file( const char *name )
|
|||
{
|
||||
case LOADORDER_DLL:
|
||||
TRACE( "Trying native exe %s\n", debugstr_a(name) );
|
||||
if ((handle = CreateFileA( name, GENERIC_READ, FILE_SHARE_READ,
|
||||
NULL, OPEN_EXISTING, 0, 0 )) != INVALID_HANDLE_VALUE)
|
||||
return handle;
|
||||
if (GetLastError() != ERROR_FILE_NOT_FOUND) return INVALID_HANDLE_VALUE;
|
||||
if (handle != INVALID_HANDLE_VALUE) return handle;
|
||||
break;
|
||||
case LOADORDER_BI:
|
||||
TRACE( "Trying built-in exe %s\n", debugstr_a(name) );
|
||||
if (wine_dll_load_main_exe( get_basename(name), NULL, 0, 1 )) return 0;
|
||||
break;
|
||||
if (open_builtin_exe_file( name, NULL, 0, 1 ))
|
||||
{
|
||||
if (handle != INVALID_HANDLE_VALUE) CloseHandle(handle);
|
||||
return 0;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (handle != INVALID_HANDLE_VALUE) CloseHandle(handle);
|
||||
|
||||
error:
|
||||
SetLastError( ERROR_FILE_NOT_FOUND );
|
||||
return INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
|
@ -308,46 +340,48 @@ static BOOL find_exe_file( const char *name, char *buffer, int buflen, HANDLE *h
|
|||
|
||||
TRACE("looking for %s\n", debugstr_a(name) );
|
||||
|
||||
if (SearchPathA( NULL, name, ".exe", buflen, buffer, NULL ))
|
||||
if (!SearchPathA( NULL, name, ".exe", buflen, buffer, NULL ) &&
|
||||
!MODULE_GetBuiltinPath( name, ".exe", buffer, buflen ))
|
||||
{
|
||||
*handle = open_exe_file( buffer );
|
||||
return TRUE;
|
||||
}
|
||||
/* no builtin found, try native without extension in case it is a Unix app */
|
||||
|
||||
/* no such file in path, try builtin with .exe extension */
|
||||
|
||||
lstrcpynA( buffer, get_basename(name), buflen );
|
||||
if (!strchr( buffer, '.' ))
|
||||
{
|
||||
char *p = buffer + strlen(buffer);
|
||||
lstrcpynA( p, ".exe", buflen - (p - buffer) );
|
||||
if (SearchPathA( NULL, name, NULL, buflen, buffer, NULL ))
|
||||
{
|
||||
TRACE( "Trying native/Unix binary %s\n", debugstr_a(buffer) );
|
||||
if ((*handle = CreateFileA( buffer, GENERIC_READ, FILE_SHARE_READ,
|
||||
NULL, OPEN_EXISTING, 0, 0 )) != INVALID_HANDLE_VALUE)
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
MODULE_GetLoadOrder( loadorder, buffer, TRUE );
|
||||
for (i = 0; i < LOADORDER_NTYPES; i++)
|
||||
|
||||
for(i = 0; i < LOADORDER_NTYPES; i++)
|
||||
{
|
||||
if (loadorder[i] == LOADORDER_BI)
|
||||
if (loadorder[i] == LOADORDER_INVALID) break;
|
||||
switch(loadorder[i])
|
||||
{
|
||||
case LOADORDER_DLL:
|
||||
TRACE( "Trying native exe %s\n", debugstr_a(buffer) );
|
||||
if ((*handle = CreateFileA( buffer, GENERIC_READ, FILE_SHARE_READ,
|
||||
NULL, OPEN_EXISTING, 0, 0 )) != INVALID_HANDLE_VALUE)
|
||||
return TRUE;
|
||||
if (GetLastError() != ERROR_FILE_NOT_FOUND) return TRUE;
|
||||
break;
|
||||
case LOADORDER_BI:
|
||||
TRACE( "Trying built-in exe %s\n", debugstr_a(buffer) );
|
||||
if (wine_dll_load_main_exe( buffer, NULL, 0, 1 ))
|
||||
if (open_builtin_exe_file( buffer, NULL, 0, 1 ))
|
||||
{
|
||||
*handle = 0;
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (loadorder[i] == LOADORDER_INVALID) break;
|
||||
}
|
||||
|
||||
/* no builtin found, try native without extension in case it is a Unix app */
|
||||
|
||||
if (SearchPathA( NULL, name, NULL, buflen, buffer, NULL ))
|
||||
{
|
||||
TRACE( "Trying native/Unix binary %s\n", debugstr_a(buffer) );
|
||||
if ((*handle = CreateFileA( buffer, GENERIC_READ, FILE_SHARE_READ,
|
||||
NULL, OPEN_EXISTING, 0, 0 )) != INVALID_HANDLE_VALUE)
|
||||
return TRUE;
|
||||
}
|
||||
SetLastError( ERROR_FILE_NOT_FOUND );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -569,7 +603,7 @@ void PROCESS_InitWine( int argc, char *argv[], LPSTR win16_exe_name, HANDLE *win
|
|||
if (!main_exe_file) /* no file handle -> Winelib app */
|
||||
{
|
||||
TRACE( "starting Winelib app %s\n", debugstr_a(main_exe_name) );
|
||||
if (wine_dll_load_main_exe( get_basename(main_exe_name), error, sizeof(error), 0 ))
|
||||
if (open_builtin_exe_file( main_exe_name, error, sizeof(error), 0 ))
|
||||
goto found;
|
||||
MESSAGE( "%s: cannot open builtin library for '%s': %s\n", argv0, main_exe_name, error );
|
||||
ExitProcess(1);
|
||||
|
|
Loading…
Reference in New Issue