Alexandre Julliard : ntdll: Support loading builtins from the architecture-specific PE directory.
Alexandre Julliard
julliard at winehq.org
Mon Apr 26 15:51:31 CDT 2021
Module: wine
Branch: master
Commit: f93713b157411efabfa6ceabf137364b249106f6
URL: https://source.winehq.org/git/wine.git/?a=commit;h=f93713b157411efabfa6ceabf137364b249106f6
Author: Alexandre Julliard <julliard at winehq.org>
Date: Mon Apr 26 12:43:10 2021 +0200
ntdll: Support loading builtins from the architecture-specific PE directory.
Based on a patch by Jacek Caban.
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/ntdll/loader.c | 21 ++++++++++++++++++++-
dlls/ntdll/unix/loader.c | 43 +++++++++++++++++++++++++++++++++++++++++--
2 files changed, 61 insertions(+), 3 deletions(-)
diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c
index 38dd276608b..85ae6aac15f 100644
--- a/dlls/ntdll/loader.c
+++ b/dlls/ntdll/loader.c
@@ -51,6 +51,18 @@ WINE_DECLARE_DEBUG_CHANNEL(imports);
#define DEFAULT_SECURITY_COOKIE_32 0xbb40e64e
#define DEFAULT_SECURITY_COOKIE_16 (DEFAULT_SECURITY_COOKIE_32 >> 16)
+#ifdef __i386__
+static const WCHAR pe_dir[] = L"\\i386-windows";
+#elif defined __x86_64__
+static const WCHAR pe_dir[] = L"\\x86_64-windows";
+#elif defined __arm__
+static const WCHAR pe_dir[] = L"\\arm-windows";
+#elif defined __aarch64__
+static const WCHAR pe_dir[] = L"\\aarch64-windows";
+#else
+static const WCHAR pe_dir[] = L"";
+#endif
+
/* we don't want to include winuser.h */
#define RT_MANIFEST ((ULONG_PTR)24)
#define ISOLATIONAWARE_MANIFEST_RESOURCE_ID ((ULONG_PTR)2)
@@ -2640,11 +2652,18 @@ static NTSTATUS find_builtin_without_file( const WCHAR *name, UNICODE_STRING *ne
if (status != STATUS_DLL_NOT_FOUND) goto done;
RtlFreeUnicodeString( new_name );
}
+
for (i = 0; ; i++)
{
swprintf( dllpath, ARRAY_SIZE(dllpath), L"WINEDLLDIR%u", i );
- if (get_env_var( dllpath, 20 + wcslen(name), new_name )) break;
+ if (get_env_var( dllpath, wcslen(pe_dir) + wcslen(name) + 1, new_name )) break;
len = new_name->Length;
+ RtlAppendUnicodeToString( new_name, pe_dir );
+ RtlAppendUnicodeToString( new_name, L"\\" );
+ RtlAppendUnicodeToString( new_name, name );
+ status = open_dll_file( new_name, pwm, mapping, image_info, id );
+ if (status != STATUS_DLL_NOT_FOUND) goto done;
+ new_name->Length = len;
RtlAppendUnicodeToString( new_name, L"\\" );
RtlAppendUnicodeToString( new_name, name );
status = open_dll_file( new_name, pwm, mapping, image_info, id );
diff --git a/dlls/ntdll/unix/loader.c b/dlls/ntdll/unix/loader.c
index 9947ff2f447..30e1f972ae1 100644
--- a/dlls/ntdll/unix/loader.c
+++ b/dlls/ntdll/unix/loader.c
@@ -237,10 +237,27 @@ static char *build_path( const char *dir, const char *name )
memcpy( ret, dir, len );
if (len && ret[len - 1] != '/') ret[len++] = '/';
+ if (name[0] == '/') name++;
strcpy( ret + len, name );
return ret;
}
+
+static const char *get_pe_dir( WORD machine )
+{
+ if (!machine) machine = current_machine;
+
+ switch(machine)
+ {
+ case IMAGE_FILE_MACHINE_I386: return "/i386-windows";
+ case IMAGE_FILE_MACHINE_AMD64: return "/x86_64-windows";
+ case IMAGE_FILE_MACHINE_ARMNT: return "/arm-windows";
+ case IMAGE_FILE_MACHINE_ARM64: return "/aarch64-windows";
+ default: return "";
+ }
+}
+
+
static void set_dll_path(void)
{
char *p, *path = getenv( "WINEDLLPATH" );
@@ -1257,6 +1274,7 @@ static NTSTATUS find_builtin_dll( UNICODE_STRING *nt_name, void **module, SIZE_T
unsigned int i, pos, namepos, namelen, maxlen = 0;
unsigned int len = nt_name->Length / sizeof(WCHAR);
char *ptr = NULL, *file, *ext = NULL;
+ const char *pe_dir = get_pe_dir( machine );
OBJECT_ATTRIBUTES attr;
NTSTATUS status = STATUS_DLL_NOT_FOUND;
BOOL found_image = FALSE;
@@ -1268,7 +1286,7 @@ static NTSTATUS find_builtin_dll( UNICODE_STRING *nt_name, void **module, SIZE_T
InitializeObjectAttributes( &attr, nt_name, 0, 0, NULL );
if (build_dir) maxlen = strlen(build_dir) + sizeof("/programs/") + len;
- maxlen = max( maxlen, dll_path_maxlen + 1 ) + len + sizeof(".so");
+ maxlen = max( maxlen, dll_path_maxlen + 1 ) + len + sizeof("/aarch64-windows") + sizeof(".so");
if (!(file = malloc( maxlen ))) return STATUS_NO_MEMORY;
@@ -1310,8 +1328,16 @@ static NTSTATUS find_builtin_dll( UNICODE_STRING *nt_name, void **module, SIZE_T
for (i = 0; dll_paths[i]; i++)
{
+ ptr = file + pos;
+ file[pos + len + 1] = 0;
+ ptr = prepend( ptr, pe_dir, strlen(pe_dir) );
+ ptr = prepend( ptr, dll_paths[i], strlen(dll_paths[i]) );
+ status = open_builtin_file( ptr, &attr, module, size_ptr, image_info, machine, prefer_native );
+ /* use so dir for unix lib */
+ ptr = file + pos;
file[pos + len + 1] = 0;
ptr = prepend( file + pos, dll_paths[i], strlen(dll_paths[i]) );
+ if (status != STATUS_DLL_NOT_FOUND) goto done;
status = open_builtin_file( ptr, &attr, module, size_ptr, image_info, machine, prefer_native );
if (status == STATUS_IMAGE_MACHINE_TYPE_MISMATCH) found_image = TRUE;
else if (status != STATUS_DLL_NOT_FOUND) goto done;
@@ -1652,13 +1678,26 @@ static void load_ntdll(void)
UNICODE_STRING str;
void *module;
SIZE_T size = 0;
- char *name = build_path( dll_dir, "ntdll.dll.so" );
+ char *name;
+
+ if (!build_dir)
+ {
+ char *dir = build_path( dll_dir, get_pe_dir(current_machine) );
+ name = build_path( dir, "ntdll.dll.so" );
+ free( dir );
+ }
+ else name = build_path( build_dir, "dlls/ntdll/ntdll.dll.so" );
init_unicode_string( &str, path );
InitializeObjectAttributes( &attr, &str, 0, 0, NULL );
name[strlen(name) - 3] = 0; /* remove .so */
status = open_builtin_file( name, &attr, &module, &size, &info, current_machine, FALSE );
if (status == STATUS_IMAGE_NOT_AT_BASE) relocate_ntdll( module );
+ else if (status == STATUS_DLL_NOT_FOUND)
+ {
+ free( name );
+ name = build_path( dll_dir, "ntdll.dll.so" );
+ }
else if (status) fatal_error( "failed to load %s error %x\n", name, status );
free( name );
load_ntdll_functions( module );
More information about the wine-cvs
mailing list