ntdll: Check the prefer-native flag in the PE header for default load order.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
ad43872669
commit
37600028fc
|
@ -2360,7 +2360,7 @@ static NTSTATUS load_so_dll( LPCWSTR load_path, const UNICODE_STRING *nt_name,
|
|||
* load_builtin_dll
|
||||
*/
|
||||
static NTSTATUS load_builtin_dll( LPCWSTR load_path, UNICODE_STRING *nt_name,
|
||||
DWORD flags, WINE_MODREF** pwm )
|
||||
DWORD flags, WINE_MODREF** pwm, BOOL prefer_native )
|
||||
{
|
||||
NTSTATUS status;
|
||||
void *module, *unix_entry = NULL;
|
||||
|
@ -2368,7 +2368,7 @@ static NTSTATUS load_builtin_dll( LPCWSTR load_path, UNICODE_STRING *nt_name,
|
|||
|
||||
TRACE("Trying built-in %s\n", debugstr_us(nt_name));
|
||||
|
||||
status = unix_funcs->load_builtin_dll( nt_name, &module, &unix_entry, &image_info );
|
||||
status = unix_funcs->load_builtin_dll( nt_name, &module, &unix_entry, &image_info, prefer_native );
|
||||
if (status) return status;
|
||||
|
||||
if ((*pwm = get_modref( module ))) /* already loaded */
|
||||
|
@ -2682,7 +2682,7 @@ static NTSTATUS load_dll( const WCHAR *load_path, const WCHAR *libname, const WC
|
|||
case LO_BUILTIN:
|
||||
case LO_BUILTIN_NATIVE:
|
||||
case LO_DEFAULT:
|
||||
nts = load_builtin_dll( load_path, &nt_name, flags, pwm );
|
||||
nts = load_builtin_dll( load_path, &nt_name, flags, pwm, FALSE );
|
||||
if (nts == STATUS_DLL_NOT_FOUND)
|
||||
nts = load_native_dll( load_path, &nt_name, mapping, &image_info, &id, flags, pwm );
|
||||
break;
|
||||
|
@ -2701,20 +2701,20 @@ static NTSTATUS load_dll( const WCHAR *load_path, const WCHAR *libname, const WC
|
|||
nts = load_native_dll( load_path, &nt_name, mapping, &image_info, &id, flags, pwm );
|
||||
break;
|
||||
case LO_BUILTIN:
|
||||
nts = load_builtin_dll( load_path, &nt_name, flags, pwm );
|
||||
nts = load_builtin_dll( load_path, &nt_name, flags, pwm, FALSE );
|
||||
break;
|
||||
case LO_BUILTIN_NATIVE:
|
||||
case LO_DEFAULT:
|
||||
nts = load_builtin_dll( load_path, &nt_name, flags, pwm );
|
||||
nts = load_builtin_dll( load_path, &nt_name, flags, pwm, loadorder == LO_DEFAULT );
|
||||
if (nts == STATUS_SUCCESS && loadorder == LO_DEFAULT &&
|
||||
(MODULE_InitDLL( *pwm, DLL_WINE_PREATTACH, NULL ) != STATUS_SUCCESS))
|
||||
{
|
||||
/* stub-only dll, try native */
|
||||
TRACE( "%s pre-attach returned FALSE, preferring native\n", debugstr_us(&nt_name) );
|
||||
LdrUnloadDll( (*pwm)->ldr.DllBase );
|
||||
nts = STATUS_DLL_NOT_FOUND;
|
||||
nts = STATUS_IMAGE_ALREADY_LOADED;
|
||||
}
|
||||
if (nts == STATUS_DLL_NOT_FOUND)
|
||||
if (nts == STATUS_DLL_NOT_FOUND || nts == STATUS_IMAGE_ALREADY_LOADED)
|
||||
nts = load_native_dll( load_path, &nt_name, mapping, &image_info, &id, flags, pwm );
|
||||
break;
|
||||
default:
|
||||
|
@ -2733,7 +2733,7 @@ static NTSTATUS load_dll( const WCHAR *load_path, const WCHAR *libname, const WC
|
|||
case LO_BUILTIN:
|
||||
case LO_BUILTIN_NATIVE:
|
||||
case LO_DEFAULT:
|
||||
nts = load_builtin_dll( load_path, &nt_name, flags, pwm );
|
||||
nts = load_builtin_dll( load_path, &nt_name, flags, pwm, FALSE );
|
||||
break;
|
||||
default:
|
||||
nts = STATUS_DLL_NOT_FOUND;
|
||||
|
|
|
@ -94,6 +94,8 @@
|
|||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(module);
|
||||
|
||||
#define IMAGE_DLLCHARACTERISTICS_PREFER_NATIVE 0x0010 /* Wine extension */
|
||||
|
||||
void (WINAPI *pDbgUiRemoteBreakin)( void *arg ) = NULL;
|
||||
NTSTATUS (WINAPI *pKiRaiseUserExceptionDispatcher)(void) = NULL;
|
||||
void (WINAPI *pKiUserApcDispatcher)(CONTEXT*,ULONG_PTR,ULONG_PTR,ULONG_PTR,PNTAPCFUNC) = NULL;
|
||||
|
@ -981,8 +983,8 @@ static void fill_builtin_image_info( void *module, pe_image_info_t *info )
|
|||
/***********************************************************************
|
||||
* dlopen_dll
|
||||
*/
|
||||
static NTSTATUS dlopen_dll( const char *so_name, UNICODE_STRING *nt_name,
|
||||
void **ret_module, pe_image_info_t *image_info )
|
||||
static NTSTATUS dlopen_dll( const char *so_name, UNICODE_STRING *nt_name, void **ret_module,
|
||||
pe_image_info_t *image_info, BOOL prefer_native )
|
||||
{
|
||||
struct builtin_module *builtin;
|
||||
void *module, *handle;
|
||||
|
@ -1023,6 +1025,12 @@ static NTSTATUS dlopen_dll( const char *so_name, UNICODE_STRING *nt_name,
|
|||
}
|
||||
|
||||
fill_builtin_image_info( module, image_info );
|
||||
if (prefer_native && (image_info->dll_charact & IMAGE_DLLCHARACTERISTICS_PREFER_NATIVE))
|
||||
{
|
||||
TRACE( "%s has prefer-native flag, ignoring builtin\n", debugstr_a(so_name) );
|
||||
dlclose( handle );
|
||||
return STATUS_IMAGE_ALREADY_LOADED;
|
||||
}
|
||||
|
||||
if (add_builtin_module( module, handle, NULL ))
|
||||
{
|
||||
|
@ -1108,7 +1116,7 @@ static NTSTATUS CDECL load_so_dll( UNICODE_STRING *nt_name, void **module )
|
|||
len = nt_name->Length / sizeof(WCHAR);
|
||||
if (len > 3 && !wcsicmp( nt_name->Buffer + len - 3, soW )) nt_name->Length -= 3 * sizeof(WCHAR);
|
||||
|
||||
status = dlopen_dll( unix_name, nt_name, module, &info );
|
||||
status = dlopen_dll( unix_name, nt_name, module, &info, FALSE );
|
||||
free( unix_name );
|
||||
return status;
|
||||
}
|
||||
|
@ -1179,7 +1187,7 @@ static inline char *prepend( char *buffer, const char *str, size_t len )
|
|||
* Open a file for a new dll. Helper for open_builtin_file.
|
||||
*/
|
||||
static NTSTATUS open_dll_file( const char *name, OBJECT_ATTRIBUTES *attr, HANDLE *mapping, void **module,
|
||||
SECTION_IMAGE_INFORMATION *image_info, struct stat *st )
|
||||
SECTION_IMAGE_INFORMATION *image_info, struct stat *st, BOOL prefer_native )
|
||||
{
|
||||
struct builtin_module *builtin;
|
||||
LARGE_INTEGER size;
|
||||
|
@ -1228,14 +1236,20 @@ static NTSTATUS open_dll_file( const char *name, OBJECT_ATTRIBUTES *attr, HANDLE
|
|||
if (!(image_info->u.s.WineBuiltin))
|
||||
{
|
||||
WARN( "%s found in WINEDLLPATH but not a builtin, ignoring\n", debugstr_a(name) );
|
||||
status = STATUS_DLL_NOT_FOUND;
|
||||
NtClose( *mapping );
|
||||
return STATUS_DLL_NOT_FOUND;
|
||||
}
|
||||
else if (!is_valid_binary( image_info ))
|
||||
if (!is_valid_binary( image_info ))
|
||||
{
|
||||
TRACE( "%s is for arch %x, continuing search\n", debugstr_a(name), image_info->Machine );
|
||||
status = STATUS_IMAGE_MACHINE_TYPE_MISMATCH;
|
||||
NtClose( *mapping );
|
||||
return STATUS_IMAGE_MACHINE_TYPE_MISMATCH;
|
||||
}
|
||||
if (prefer_native && (image_info->DllCharacteristics & IMAGE_DLLCHARACTERISTICS_PREFER_NATIVE))
|
||||
{
|
||||
TRACE( "%s has prefer-native flag, ignoring builtin\n", debugstr_a(name) );
|
||||
NtClose( *mapping );
|
||||
return STATUS_IMAGE_ALREADY_LOADED;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
@ -1245,12 +1259,13 @@ static NTSTATUS open_dll_file( const char *name, OBJECT_ATTRIBUTES *attr, HANDLE
|
|||
* open_builtin_file
|
||||
*/
|
||||
static NTSTATUS open_builtin_file( char *name, OBJECT_ATTRIBUTES *attr, HANDLE *mapping, void **module,
|
||||
SECTION_IMAGE_INFORMATION *image_info, struct stat *st )
|
||||
SECTION_IMAGE_INFORMATION *image_info, struct stat *st,
|
||||
BOOL prefer_native )
|
||||
{
|
||||
NTSTATUS status;
|
||||
int fd;
|
||||
|
||||
status = open_dll_file( name, attr, mapping, module, image_info, st );
|
||||
status = open_dll_file( name, attr, mapping, module, image_info, st, prefer_native );
|
||||
if (status != STATUS_DLL_NOT_FOUND) return status;
|
||||
|
||||
/* try .so file */
|
||||
|
@ -1262,12 +1277,9 @@ static NTSTATUS open_builtin_file( char *name, OBJECT_ATTRIBUTES *attr, HANDLE *
|
|||
{
|
||||
pe_image_info_t info;
|
||||
|
||||
if (!dlopen_dll( name, attr->ObjectName, module, &info ))
|
||||
{
|
||||
virtual_fill_image_information( &info, image_info );
|
||||
status = STATUS_SUCCESS;
|
||||
}
|
||||
else
|
||||
status = dlopen_dll( name, attr->ObjectName, module, &info, prefer_native );
|
||||
if (!status) virtual_fill_image_information( &info, image_info );
|
||||
else if (status != STATUS_IMAGE_ALREADY_LOADED)
|
||||
{
|
||||
ERR( "failed to load .so lib %s\n", debugstr_a(name) );
|
||||
status = STATUS_PROCEDURE_NOT_FOUND;
|
||||
|
@ -1306,7 +1318,7 @@ static NTSTATUS map_builtin_module( HANDLE mapping, void **module, struct stat *
|
|||
* load_builtin_dll
|
||||
*/
|
||||
static NTSTATUS CDECL load_builtin_dll( UNICODE_STRING *nt_name, void **module, void **unix_entry,
|
||||
SECTION_IMAGE_INFORMATION *image_info )
|
||||
SECTION_IMAGE_INFORMATION *image_info, BOOL prefer_native )
|
||||
{
|
||||
unsigned int i, pos, namepos, namelen, maxlen = 0;
|
||||
unsigned int len = nt_name->Length / sizeof(WCHAR);
|
||||
|
@ -1349,7 +1361,7 @@ static NTSTATUS CDECL load_builtin_dll( UNICODE_STRING *nt_name, void **module,
|
|||
ptr = prepend( ptr, ptr, namelen );
|
||||
ptr = prepend( ptr, "/dlls", sizeof("/dlls") - 1 );
|
||||
ptr = prepend( ptr, build_dir, strlen(build_dir) );
|
||||
status = open_builtin_file( ptr, &attr, &mapping, module, image_info, &st );
|
||||
status = open_builtin_file( ptr, &attr, &mapping, module, image_info, &st, prefer_native );
|
||||
if (status != STATUS_DLL_NOT_FOUND) goto done;
|
||||
|
||||
/* now as a program */
|
||||
|
@ -1360,7 +1372,7 @@ static NTSTATUS CDECL load_builtin_dll( UNICODE_STRING *nt_name, void **module,
|
|||
ptr = prepend( ptr, ptr, namelen );
|
||||
ptr = prepend( ptr, "/programs", sizeof("/programs") - 1 );
|
||||
ptr = prepend( ptr, build_dir, strlen(build_dir) );
|
||||
status = open_builtin_file( ptr, &attr, &mapping, module, image_info, &st );
|
||||
status = open_builtin_file( ptr, &attr, &mapping, module, image_info, &st, prefer_native );
|
||||
if (status != STATUS_DLL_NOT_FOUND) goto done;
|
||||
}
|
||||
|
||||
|
@ -1368,7 +1380,7 @@ static NTSTATUS CDECL load_builtin_dll( UNICODE_STRING *nt_name, void **module,
|
|||
{
|
||||
file[pos + len + 1] = 0;
|
||||
ptr = prepend( file + pos, dll_paths[i], strlen(dll_paths[i]) );
|
||||
status = open_builtin_file( ptr, &attr, &mapping, module, image_info, &st );
|
||||
status = open_builtin_file( ptr, &attr, &mapping, module, image_info, &st, prefer_native );
|
||||
if (status == STATUS_IMAGE_MACHINE_TYPE_MISMATCH) found_image = TRUE;
|
||||
else if (status != STATUS_DLL_NOT_FOUND) goto done;
|
||||
}
|
||||
|
@ -1518,7 +1530,7 @@ static void load_ntdll(void)
|
|||
str.MaximumLength = sizeof(path);
|
||||
InitializeObjectAttributes( &attr, &str, 0, 0, NULL );
|
||||
name[strlen(name) - 3] = 0; /* remove .so */
|
||||
status = open_builtin_file( name, &attr, &mapping, &module, &info, &st );
|
||||
status = open_builtin_file( name, &attr, &mapping, &module, &info, &st, FALSE );
|
||||
if (!status && !module)
|
||||
{
|
||||
status = map_builtin_module( mapping, &module, &st );
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
struct _DISPATCHER_CONTEXT;
|
||||
|
||||
/* increment this when you change the function table */
|
||||
#define NTDLL_UNIXLIB_VERSION 111
|
||||
#define NTDLL_UNIXLIB_VERSION 112
|
||||
|
||||
struct unix_funcs
|
||||
{
|
||||
|
@ -82,7 +82,7 @@ struct unix_funcs
|
|||
/* loader functions */
|
||||
NTSTATUS (CDECL *load_so_dll)( UNICODE_STRING *nt_name, void **module );
|
||||
NTSTATUS (CDECL *load_builtin_dll)( UNICODE_STRING *name, void **module, void **unix_entry,
|
||||
SECTION_IMAGE_INFORMATION *image_info );
|
||||
SECTION_IMAGE_INFORMATION *image_info, BOOL prefer_native );
|
||||
NTSTATUS (CDECL *unload_builtin_dll)( void *module );
|
||||
void (CDECL *init_builtin_dll)( void *module );
|
||||
NTSTATUS (CDECL *unwind_builtin_dll)( ULONG type, struct _DISPATCHER_CONTEXT *dispatch,
|
||||
|
|
Loading…
Reference in New Issue