From 40f18c0bac68ed6ccdd8564d7ea42a1d936f469e Mon Sep 17 00:00:00 2001 From: Tk-Glitch Date: Sat, 8 May 2021 12:20:30 +0200 Subject: [PATCH] Hotfixer: Update steamclient breaker revert patchset for e9bc48e --- proton-tkg/PKGBUILD | 2 +- wine-tkg-git/PKGBUILD | 4 +- .../wine-tkg-patches/hotfixes/hotfixer | 4 +- .../revert_steamclient_breaker9.myrevert | 908 ++++++++++++++++++ 4 files changed, 914 insertions(+), 4 deletions(-) create mode 100644 wine-tkg-git/wine-tkg-patches/hotfixes/steamclient_swap/revert_steamclient_breaker9.myrevert diff --git a/proton-tkg/PKGBUILD b/proton-tkg/PKGBUILD index db0880b0b..d72f7f801 100644 --- a/proton-tkg/PKGBUILD +++ b/proton-tkg/PKGBUILD @@ -1,7 +1,7 @@ # Created by: Tk-Glitch pkgname=proton-tkg-git -pkgver=6.7.r17.g50d26744 +pkgver=6.8.r0.g0f00e37c pkgrel=1 _frogwhere="$PWD" # Arch chroot workaround diff --git a/wine-tkg-git/PKGBUILD b/wine-tkg-git/PKGBUILD index 06a232a3e..412992583 100644 --- a/wine-tkg-git/PKGBUILD +++ b/wine-tkg-git/PKGBUILD @@ -1,7 +1,7 @@ # Created by: Tk-Glitch pkgname=wine-tkg-git -pkgver=6.7.r17.g50d26744 +pkgver=6.8.r0.g0f00e37c # workaround for pkgrel overwritten on regen pkgrel=1 @@ -416,7 +416,7 @@ md5sums=('SKIP' '6f7cc6eb54f700d57006897e8c50a6a3' '6e41445463244e148407c13c4b898f8d' '7d9a7cf523c7283c64266148707b8bac' - 'df8e00c90467ddbdd7c902fb5091e549' + 'e8ee6cb684e8b2bd29818649155e665b' 'f404adafc8648495270e01241cd0601e' '1cbe40048415b8cd541f355e94c4b6e3' '3d5518c89320a59400774a86b9a1cf2f' diff --git a/wine-tkg-git/wine-tkg-patches/hotfixes/hotfixer b/wine-tkg-git/wine-tkg-patches/hotfixes/hotfixer index 18005a96b..776192a73 100755 --- a/wine-tkg-git/wine-tkg-patches/hotfixes/hotfixer +++ b/wine-tkg-git/wine-tkg-patches/hotfixes/hotfixer @@ -550,7 +550,9 @@ fi # Selective reverts to fix steamclient swap on proton - Unsure how to port the hack over, so any help is appreciated if [ "$_EXTERNAL_INSTALL" = "proton" ] && ( cd "${srcdir}"/"${_winesrcdir}" && git merge-base --is-ancestor bb065801a693e1cd305d2a507c206f1b21a142d3 HEAD ); then warning "Hotfix: Fix for steamclient swap breakage" - if ( cd "${srcdir}"/"${_winesrcdir}" && git merge-base --is-ancestor d47a711e986342a0f6b9fe520f2a34378877cd61 HEAD ); then + if ( cd "${srcdir}"/"${_winesrcdir}" && git merge-base --is-ancestor e9bc48e90a7f31820e3c1171cc6bbdc13a650b8f HEAD ); then + _hotfixes+=("$_where"/wine-tkg-patches/hotfixes/steamclient_swap/revert_steamclient_breaker9) + elif ( cd "${srcdir}"/"${_winesrcdir}" && git merge-base --is-ancestor d47a711e986342a0f6b9fe520f2a34378877cd61 HEAD ); then _hotfixes+=("$_where"/wine-tkg-patches/hotfixes/steamclient_swap/revert_steamclient_breaker8) elif ( cd "${srcdir}"/"${_winesrcdir}" && git merge-base --is-ancestor 620c0818bfa4554ee6d44ec2433c25ece598746b HEAD ); then _hotfixes+=("$_where"/wine-tkg-patches/hotfixes/steamclient_swap/revert_steamclient_breaker7) diff --git a/wine-tkg-git/wine-tkg-patches/hotfixes/steamclient_swap/revert_steamclient_breaker9.myrevert b/wine-tkg-git/wine-tkg-patches/hotfixes/steamclient_swap/revert_steamclient_breaker9.myrevert new file mode 100644 index 000000000..ccab9a7d9 --- /dev/null +++ b/wine-tkg-git/wine-tkg-patches/hotfixes/steamclient_swap/revert_steamclient_breaker9.myrevert @@ -0,0 +1,908 @@ +diff --git a/dlls/ntdll/unix/env.c b/dlls/ntdll/unix/env.c +index 3ac1ed9ab63..5d8c14625f9 100644 +--- a/dlls/ntdll/unix/env.c ++++ b/dlls/ntdll/unix/env.c +@@ -1954,6 +1954,8 @@ static RTL_USER_PROCESS_PARAMETERS *build_initial_params(void) + if (!status) + { + if (main_image_info.ImageCharacteristics & IMAGE_FILE_DLL) status = STATUS_INVALID_IMAGE_FORMAT; ++ if (main_image_info.ImageFlags & IMAGE_FLAGS_ComPlusNativeReady) ++ main_image_info.Machine = native_machine; + if (main_image_info.Machine != current_machine) status = STATUS_INVALID_IMAGE_FORMAT; + } + +diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c +index e919d7e2671..160a16daff8 100644 +--- a/dlls/ntdll/loader.c ++++ b/dlls/ntdll/loader.c +@@ -2730,6 +2730,12 @@ static NTSTATUS find_dll_file( const WCHAR *load_path, const WCHAR *libname, con + status = STATUS_SUCCESS; + goto done; + } ++ /* 16-bit files can't be loaded from the prefix */ ++ if (libname[0] && libname[1] && !wcscmp( libname + wcslen(libname) - 2, L"16" )) ++ { ++ status = find_builtin_without_file( libname, nt_name, pwm, mapping, image_info, id ); ++ goto done; ++ } + } + } + +diff --git a/programs/services/services.c b/programs/services/services.c +index d9c4e484e425..39cd9ee4ffa8 100644 +--- a/programs/services/services.c ++++ b/programs/services/services.c +@@ -25,6 +25,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -1069,7 +1070,16 @@ static DWORD service_start_process(struct service_entry *service_entry, struct p + + if (!environment && OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY | TOKEN_DUPLICATE, &token)) + { ++ WCHAR val[16]; + CreateEnvironmentBlock(&environment, token, FALSE); ++ if (GetEnvironmentVariableW( L"WINEBOOTSTRAPMODE", val, ARRAY_SIZE(val) )) ++ { ++ UNICODE_STRING name, value; ++ ++ RtlInitUnicodeString( &name, L"WINEBOOTSTRAPMODE" ); ++ RtlInitUnicodeString( &value, val ); ++ RtlSetEnvironmentVariable( (WCHAR **)&environment, &name, &value ); ++ } + CloseHandle(token); + } + +diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c +index e1810bc5ab9..e919d7e2671 100644 +--- a/dlls/ntdll/loader.c ++++ b/dlls/ntdll/loader.c +@@ -1926,14 +1926,10 @@ static NTSTATUS build_module( LPCWSTR load_path, const UNICODE_STRING *nt_name, + static void build_ntdll_module(void) + { + MEMORY_BASIC_INFORMATION meminfo; +- FILE_BASIC_INFORMATION basic_info; + UNICODE_STRING nt_name; +- OBJECT_ATTRIBUTES attr; + WINE_MODREF *wm; + + RtlInitUnicodeString( &nt_name, L"\\??\\C:\\windows\\system32\\ntdll.dll" ); +- InitializeObjectAttributes( &attr, &nt_name, OBJ_CASE_INSENSITIVE, 0, NULL ); +- is_prefix_bootstrap = NtQueryAttributesFile( &attr, &basic_info) != STATUS_SUCCESS; + NtQueryVirtualMemory( GetCurrentProcess(), build_ntdll_module, MemoryBasicInformation, + &meminfo, sizeof(meminfo), NULL ); + wm = alloc_module( meminfo.AllocationBase, &nt_name, TRUE ); +@@ -2672,7 +2668,7 @@ static NTSTATUS search_dll_file( LPCWSTR paths, LPCWSTR search, UNICODE_STRING * + + if (found_image) + status = STATUS_IMAGE_MACHINE_TYPE_MISMATCH; +- else if (is_prefix_bootstrap && !wcspbrk( search, L":/\\" )) ++ else if (is_prefix_bootstrap && !contains_path( search )) + status = find_builtin_without_file( search, nt_name, pwm, mapping, image_info, id ); + + done: +@@ -3498,10 +3494,14 @@ static void process_breakpoint(void) + static void load_global_options(void) + { + OBJECT_ATTRIBUTES attr; +- UNICODE_STRING name_str; ++ UNICODE_STRING name_str, val_str; + HANDLE hkey; + ULONG value; + ++ RtlInitUnicodeString( &name_str, L"WINEBOOTSTRAPMODE" ); ++ val_str.MaximumLength = 0; ++ is_prefix_bootstrap = RtlQueryEnvironmentVariable_U( NULL, &name_str, &val_str ) != STATUS_VARIABLE_NOT_FOUND; ++ + attr.Length = sizeof(attr); + attr.RootDirectory = 0; + attr.ObjectName = &name_str; +diff --git a/dlls/ntdll/unix/env.c b/dlls/ntdll/unix/env.c +index 10089a740c2..01d4f3ea418 100644 +--- a/dlls/ntdll/unix/env.c ++++ b/dlls/ntdll/unix/env.c +@@ -64,6 +64,9 @@ WINE_DEFAULT_DEBUG_CHANNEL(environ); + + USHORT *uctable = NULL, *lctable = NULL; + SIZE_T startup_info_size = 0; ++BOOL is_prefix_bootstrap = FALSE; ++ ++static const WCHAR bootstrapW[] = {'W','I','N','E','B','O','O','T','S','T','R','A','P','M','O','D','E'}; + + int main_argc = 0; + char **main_argv = NULL; +@@ -1211,6 +1214,18 @@ static WCHAR *find_env_var( WCHAR *env, SIZE_T size, const WCHAR *name, SIZE_T n + return NULL; + } + ++static WCHAR *get_env_var( WCHAR *env, SIZE_T size, const WCHAR *name, SIZE_T namelen ) ++{ ++ WCHAR *ret = NULL, *var = find_env_var( env, size, name, namelen ); ++ ++ if (var) ++ { ++ var += namelen + 1; /* skip name */ ++ if ((ret = malloc( (wcslen(var) + 1) * sizeof(WCHAR) ))) wcscpy( ret, var ); ++ } ++ return ret; ++} ++ + /* set an environment variable, replacing it if it exists */ + static void set_env_var( WCHAR **env, SIZE_T *pos, SIZE_T *size, + const WCHAR *name, SIZE_T namelen, const WCHAR *value ) +@@ -1889,29 +1904,32 @@ static inline WCHAR *get_dos_path( WCHAR *nt_path ) + */ + static RTL_USER_PROCESS_PARAMETERS *build_initial_params(void) + { ++ static const WCHAR valueW[] = {'1',0}; + static const WCHAR pathW[] = {'P','A','T','H'}; + RTL_USER_PROCESS_PARAMETERS *params = NULL; + SIZE_T size, env_pos, env_size; +- WCHAR *dst, *image, *cmdline, *p, *path = NULL; ++ WCHAR *dst, *image, *cmdline, *path, *bootstrap; + WCHAR *env = get_initial_environment( &env_pos, &env_size ); + WCHAR *curdir = get_initial_directory(); + void *module = NULL; + NTSTATUS status; + + /* store the initial PATH value */ +- if ((p = find_env_var( env, env_pos, pathW, 4 ))) +- { +- path = malloc( (wcslen(p + 5) + 1) * sizeof(WCHAR) ); +- wcscpy( path, p + 5 ); +- } ++ path = get_env_var( env, env_pos, pathW, 4 ); + add_dynamic_environment( &env, &env_pos, &env_size ); + add_registry_environment( &env, &env_pos, &env_size ); ++ bootstrap = get_env_var( env, env_pos, bootstrapW, ARRAY_SIZE(bootstrapW) ); ++ set_env_var( &env, &env_pos, &env_size, bootstrapW, ARRAY_SIZE(bootstrapW), valueW ); ++ is_prefix_bootstrap = TRUE; + env[env_pos] = 0; + run_wineboot( env, env_pos ); + + /* reload environment now that wineboot has run */ + set_env_var( &env, &env_pos, &env_size, pathW, 4, path ); /* reset PATH */ + free( path ); ++ set_env_var( &env, &env_pos, &env_size, bootstrapW, ARRAY_SIZE(bootstrapW), bootstrap ); ++ is_prefix_bootstrap = !!bootstrap; ++ free( bootstrap ); + add_registry_environment( &env, &env_pos, &env_size ); + env[env_pos++] = 0; + +@@ -2012,6 +2030,7 @@ void init_startup_info(void) + memcpy( env, (char *)info + info_size, env_size * sizeof(WCHAR) ); + env_pos = env_size - 1; + add_dynamic_environment( &env, &env_pos, &env_size ); ++ is_prefix_bootstrap = !!find_env_var( env, env_pos, bootstrapW, ARRAY_SIZE(bootstrapW) ); + env[env_pos++] = 0; + + size = (sizeof(*params) +diff --git a/dlls/ntdll/unix/loader.c b/dlls/ntdll/unix/loader.c +index e362f5eb4db..cbafa0d8882 100644 +--- a/dlls/ntdll/unix/loader.c ++++ b/dlls/ntdll/unix/loader.c +@@ -1387,10 +1387,10 @@ BOOL is_builtin_path( const UNICODE_STRING *path, WORD *machine ) + */ + BOOL is_builtin_path( const UNICODE_STRING *path, WORD *machine ) + { +- BOOL is_prefix_bootstrap; + unsigned int i, len = path->Length / sizeof(WCHAR), dirlen; + const WCHAR *sysdir, *p = path->Buffer; +- struct stat st; +- char *ntdll; ++ ++ /* only fake builtin existence during prefix bootstrap */ ++ if (!is_prefix_bootstrap) return FALSE; + + for (i = 0; i < supported_machines_count; i++) + { +@@ -1413,14 +1413,7 @@ BOOL is_builtin_path( const UNICODE_STRING *path, WORD *machine ) + return TRUE; + } + return FALSE; +- +- /* if the corresponding ntdll exists, don't fake the existence of the builtin */ +- ntdll = build_path( config_dir, *machine == IMAGE_FILE_MACHINE_I386 ? +- "dosdevices/c:/windows/syswow64/ntdll.dll" : +- "dosdevices/c:/windows/system32/ntdll.dll" ); +- is_prefix_bootstrap = stat( ntdll, &st ) == -1; +- free( ntdll ); +- return is_prefix_bootstrap; ++ return (len == path->Length / sizeof(WCHAR)); + } + + +diff --git a/dlls/ntdll/unix/unix_private.h b/dlls/ntdll/unix/unix_private.h +index d0fa7a54f49..0f14e69f2be 100644 +--- a/dlls/ntdll/unix/unix_private.h ++++ b/dlls/ntdll/unix/unix_private.h +@@ -120,6 +120,7 @@ extern const char **dll_paths DECLSPEC_HIDDEN; + extern USHORT *uctable DECLSPEC_HIDDEN; + extern USHORT *lctable DECLSPEC_HIDDEN; + extern SIZE_T startup_info_size DECLSPEC_HIDDEN; ++extern BOOL is_prefix_bootstrap DECLSPEC_HIDDEN; + extern SECTION_IMAGE_INFORMATION main_image_info DECLSPEC_HIDDEN; + extern int main_argc DECLSPEC_HIDDEN; + extern char **main_argv DECLSPEC_HIDDEN; +From 7512c53b89308c16a512cb8f0c1d0fd6ff02b17b Mon Sep 17 00:00:00 2001 +From: Alexandre Julliard +Date: Wed, 7 Apr 2021 10:46:34 +0200 +Subject: [PATCH] ntdll: Cache the main image section information. + +Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=50937 +Signed-off-by: Alexandre Julliard +--- + dlls/ntdll/unix/env.c | 14 ++++++-------- + dlls/ntdll/unix/loader.c | 13 +++++++------ + dlls/ntdll/unix/server.c | 4 ++-- + dlls/ntdll/unix/unix_private.h | 11 +++-------- + dlls/ntdll/unix/virtual.c | 8 ++------ + 5 files changed, 20 insertions(+), 30 deletions(-) + +diff --git a/dlls/ntdll/unix/env.c b/dlls/ntdll/unix/env.c +index 5b4a2254659d..10089a740c22 100644 +--- a/dlls/ntdll/unix/env.c ++++ b/dlls/ntdll/unix/env.c +@@ -1891,7 +1891,6 @@ static RTL_USER_PROCESS_PARAMETERS *build_initial_params(void) + { + static const WCHAR pathW[] = {'P','A','T','H'}; + RTL_USER_PROCESS_PARAMETERS *params = NULL; +- SECTION_IMAGE_INFORMATION image_info; + SIZE_T size, env_pos, env_size; + WCHAR *dst, *image, *cmdline, *p, *path = NULL; + WCHAR *env = get_initial_environment( &env_pos, &env_size ); +@@ -1916,11 +1915,11 @@ static RTL_USER_PROCESS_PARAMETERS *build_initial_params(void) + add_registry_environment( &env, &env_pos, &env_size ); + env[env_pos++] = 0; + +- status = load_main_exe( NULL, main_argv[1], curdir, &image, &module, &image_info ); ++ status = load_main_exe( NULL, main_argv[1], curdir, &image, &module ); + if (!status) + { +- if (image_info.ImageCharacteristics & IMAGE_FILE_DLL) status = STATUS_INVALID_IMAGE_FORMAT; +- if (image_info.Machine != current_machine) status = STATUS_INVALID_IMAGE_FORMAT; ++ if (main_image_info.ImageCharacteristics & IMAGE_FILE_DLL) status = STATUS_INVALID_IMAGE_FORMAT; ++ if (main_image_info.Machine != current_machine) status = STATUS_INVALID_IMAGE_FORMAT; + } + + if (status) /* try launching it through start.exe */ +@@ -1928,7 +1927,7 @@ static RTL_USER_PROCESS_PARAMETERS *build_initial_params(void) + static const char *args[] = { "start.exe", "/exec" }; + free( image ); + if (module) NtUnmapViewOfSection( GetCurrentProcess(), module ); +- load_start_exe( &image, &module, &image_info ); ++ load_start_exe( &image, &module ); + prepend_argv( args, 2 ); + } + else rebuild_argv(); +@@ -1989,7 +1988,6 @@ void init_startup_info(void) + NTSTATUS status; + SIZE_T size, info_size, env_size, env_pos; + RTL_USER_PROCESS_PARAMETERS *params = NULL; +- SECTION_IMAGE_INFORMATION image_info; + startup_info_t *info; + + if (!startup_info_size) +@@ -2082,8 +2080,8 @@ void init_startup_info(void) + free( info ); + NtCurrentTeb()->Peb->ProcessParameters = params; + +- status = load_main_exe( params->ImagePathName.Buffer, NULL, params->CommandLine.Buffer, +- &image, &module, &image_info ); ++ status = load_main_exe( params->ImagePathName.Buffer, NULL, ++ params->CommandLine.Buffer, &image, &module ); + if (status) + { + MESSAGE( "wine: failed to start %s\n", debugstr_us(¶ms->ImagePathName) ); +diff --git a/dlls/ntdll/unix/loader.c b/dlls/ntdll/unix/loader.c +index 3d613425b689..e362f5eb4dbd 100644 +--- a/dlls/ntdll/unix/loader.c ++++ b/dlls/ntdll/unix/loader.c +@@ -122,6 +122,7 @@ const char *build_dir = NULL; + const char *config_dir = NULL; + const char **dll_paths = NULL; + const char *user_name = NULL; ++SECTION_IMAGE_INFORMATION main_image_info = { NULL }; + static HMODULE ntdll_module; + static const IMAGE_EXPORT_DIRECTORY *ntdll_exports; + +@@ -1473,7 +1474,7 @@ static NTSTATUS open_main_image( WCHAR *image, void **module, SECTION_IMAGE_INFO + * load_main_exe + */ + NTSTATUS load_main_exe( const WCHAR *dos_name, const char *unix_name, const WCHAR *curdir, +- WCHAR **image, void **module, SECTION_IMAGE_INFORMATION *image_info ) ++ WCHAR **image, void **module ) + { + UNICODE_STRING nt_name; + WCHAR *tmp = NULL; +@@ -1509,7 +1509,7 @@ NTSTATUS load_main_exe( const WCHAR *dos_name, const char *unix_name, const WCHA + { + if ((status = unix_to_nt_file_name( unix_name, image ))) goto failed; + loadorder = get_load_order( &nt_name ); ++ status = open_main_image( *image, module, &main_image_info, loadorder ); +- status = open_main_image( *image, module, image_info, loadorder ); + if (status != STATUS_DLL_NOT_FOUND) return status; + free( *image ); + } +@@ -1529,13 +1529,13 @@ NTSTATUS load_main_exe( const WCHAR *dos_name, const char *unix_name, const WCHA + init_unicode_string( &nt_name, *image ); + if (loadorder == LO_INVALID) loadorder = get_load_order( &nt_name ); + ++ status = open_main_image( *image, module, &main_image_info, loadorder ); +- status = open_main_image( *image, module, image_info, loadorder ); + if (status != STATUS_DLL_NOT_FOUND) return status; + + /* if path is in system dir, we can load the builtin even if the file itself doesn't exist */ + if (loadorder != LO_NATIVE && is_builtin_path( &nt_name, &machine )) + { ++ status = find_builtin_dll( &nt_name, module, &size, &main_image_info, machine, FALSE ); +- status = find_builtin_dll( &nt_name, module, &size, image_info, machine, FALSE ); + if (status != STATUS_DLL_NOT_FOUND) return status; + } + if (!contains_path) return STATUS_DLL_NOT_FOUND; +@@ -1529,7 +1530,7 @@ NTSTATUS load_main_exe( const WCHAR *dos_name, const char *unix_name, const WCHA + * + * Load start.exe as main image. + */ +-NTSTATUS load_start_exe( WCHAR **image, void **module, SECTION_IMAGE_INFORMATION *image_info ) ++NTSTATUS load_start_exe( WCHAR **image, void **module ) + { + static const WCHAR startW[] = {'\\','?','?','\\','C',':','\\','w','i','n','d','o','w','s','\\', + 's','y','s','t','e','m','3','2','\\','s','t','a','r','t','.','e','x','e',0}; +@@ -1538,7 +1539,7 @@ NTSTATUS load_start_exe( WCHAR **image, void **module, SECTION_IMAGE_INFORMATION + wcscpy( *image, get_machine_wow64_dir( current_machine )); + wcscat( *image, startW ); + init_unicode_string( &nt_name, *image ); +- status = find_builtin_dll( &nt_name, module, &size, image_info, current_machine, FALSE ); ++ status = find_builtin_dll( &nt_name, module, &size, &main_image_info, current_machine, FALSE ); + if (status) + { + MESSAGE( "wine: failed to load start.exe: %x\n", status ); +diff --git a/dlls/ntdll/unix/server.c b/dlls/ntdll/unix/server.c +index 65863f54c4b8..a108ce004825 100644 +--- a/dlls/ntdll/unix/server.c ++++ b/dlls/ntdll/unix/server.c +@@ -1605,7 +1605,6 @@ size_t server_init_process(void) + void server_init_process_done(void) + { + PEB *peb = NtCurrentTeb()->Peb; +- IMAGE_NT_HEADERS *nt = get_exe_nt_header(); + void *entry; + NTSTATUS status; + int suspend, needs_close, unixdir; +@@ -1678,7 +1678,7 @@ void server_init_process_done(void) + #ifdef __APPLE__ + send_server_task_port(); + #endif ++ if (main_image_info.ImageCharacteristics & IMAGE_FILE_LARGE_ADDRESS_AWARE +- if (nt->FileHeader.Characteristics & IMAGE_FILE_LARGE_ADDRESS_AWARE + || __wine_needs_override_large_address_aware()) virtual_set_large_address_space(); + + /* Install signal handlers; this cannot be done earlier, since we cannot +diff --git a/dlls/ntdll/unix/unix_private.h b/dlls/ntdll/unix/unix_private.h +index 257566ce9764..d0fa7a54f49e 100644 +--- a/dlls/ntdll/unix/unix_private.h ++++ b/dlls/ntdll/unix/unix_private.h +@@ -120,6 +120,7 @@ extern const char **dll_paths DECLSPEC_HIDDEN; + extern USHORT *uctable DECLSPEC_HIDDEN; + extern USHORT *lctable DECLSPEC_HIDDEN; + extern SIZE_T startup_info_size DECLSPEC_HIDDEN; ++extern SECTION_IMAGE_INFORMATION main_image_info DECLSPEC_HIDDEN; + extern int main_argc DECLSPEC_HIDDEN; + extern char **main_argv DECLSPEC_HIDDEN; + extern char **main_envp DECLSPEC_HIDDEN; +@@ -147,8 +148,8 @@ extern NTSTATUS load_builtin( const pe_image_info_t *image_info, WCHAR *filename + void **addr_ptr, SIZE_T *size_ptr ) DECLSPEC_HIDDEN; + extern BOOL is_builtin_path( const UNICODE_STRING *path, WORD *machine ) DECLSPEC_HIDDEN; + extern NTSTATUS load_main_exe( const WCHAR *name, const char *unix_name, const WCHAR *curdir, WCHAR **image, +- void **module, SECTION_IMAGE_INFORMATION *image_info ) DECLSPEC_HIDDEN; +-extern NTSTATUS load_start_exe( WCHAR **image, void **module, SECTION_IMAGE_INFORMATION *image_info ) DECLSPEC_HIDDEN; ++ void **module ) DECLSPEC_HIDDEN; ++extern NTSTATUS load_start_exe( WCHAR **image, void **module ) DECLSPEC_HIDDEN; + extern void start_server( BOOL debug ) DECLSPEC_HIDDEN; + extern ULONG_PTR get_image_address(void) DECLSPEC_HIDDEN; + +@@ -295,12 +296,6 @@ static inline void ascii_to_unicode( WCHAR *dst, const char *src, size_t len ) + while (len--) *dst++ = (unsigned char)*src++; + } + +-static inline IMAGE_NT_HEADERS *get_exe_nt_header(void) +-{ +- IMAGE_DOS_HEADER *module = (IMAGE_DOS_HEADER *)NtCurrentTeb()->Peb->ImageBaseAddress; +- return (IMAGE_NT_HEADERS *)((char *)module + module->e_lfanew); +-} +- + static inline void *get_signal_stack(void) + { + return (char *)NtCurrentTeb() + teb_size - teb_offset; +diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c +index 149555f4fce2..659ad2421d4c 100644 +--- a/dlls/ntdll/unix/virtual.c ++++ b/dlls/ntdll/unix/virtual.c +@@ -3006,12 +3006,8 @@ NTSTATUS virtual_alloc_thread_stack( INITIAL_TEB *stack, SIZE_T reserve_size, SI + sigset_t sigset; + SIZE_T size, extra_size = 0; + +- if (!reserve_size || !commit_size) +- { +- IMAGE_NT_HEADERS *nt = get_exe_nt_header(); +- if (!reserve_size) reserve_size = nt->OptionalHeader.SizeOfStackReserve; +- if (!commit_size) commit_size = nt->OptionalHeader.SizeOfStackCommit; +- } ++ if (!reserve_size) reserve_size = main_image_info.MaximumStackSize; ++ if (!commit_size) commit_size = main_image_info.CommittedStackSize; + + size = max( reserve_size, commit_size ); + if (size < 1024 * 1024) size = 1024 * 1024; /* Xlib needs a large stack */ +From 89db25afda90d1d5d57787398ba80fcf4f5abb5f Mon Sep 17 00:00:00 2001 +From: Alexandre Julliard +Date: Tue, 6 Apr 2021 12:24:38 +0200 +Subject: [PATCH] ntdll: Check for DLL files when creating new processes. + +Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=50912 +Signed-off-by: Alexandre Julliard +--- + dlls/ntdll/unix/env.c | 6 +++++- + dlls/ntdll/unix/process.c | 1 + + 2 files changed, 6 insertions(+), 1 deletion(-) + +diff --git a/dlls/ntdll/unix/env.c b/dlls/ntdll/unix/env.c +index ab2e828dacdf..5b4a2254659d 100644 +--- a/dlls/ntdll/unix/env.c ++++ b/dlls/ntdll/unix/env.c +@@ -1917,7 +1917,11 @@ static RTL_USER_PROCESS_PARAMETERS *build_initial_params(void) + env[env_pos++] = 0; + + status = load_main_exe( NULL, main_argv[1], curdir, &image, &module, &image_info ); +- if (!status && image_info.Machine != current_machine) status = STATUS_INVALID_IMAGE_FORMAT; ++ if (!status) ++ { ++ if (image_info.ImageCharacteristics & IMAGE_FILE_DLL) status = STATUS_INVALID_IMAGE_FORMAT; ++ if (image_info.Machine != current_machine) status = STATUS_INVALID_IMAGE_FORMAT; ++ } + + if (status) /* try launching it through start.exe */ + { +diff --git a/dlls/ntdll/unix/process.c b/dlls/ntdll/unix/process.c +index b020e15eaee4..54410261c911 100644 +--- a/dlls/ntdll/unix/process.c ++++ b/dlls/ntdll/unix/process.c +@@ -365,6 +365,7 @@ static NTSTATUS get_pe_file_info( UNICODE_STRING *path, HANDLE *handle, pe_image + } + SERVER_END_REQ; + NtClose( mapping ); ++ if (info->image_charact & IMAGE_FILE_DLL) return STATUS_INVALID_IMAGE_FORMAT; + } + else if (status == STATUS_INVALID_IMAGE_NOT_MZ) + { + +diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c +index 964a3e0eaa4..5edccd6a29e 100644 +--- a/dlls/ntdll/loader.c ++++ b/dlls/ntdll/loader.c +@@ -2577,10 +2577,10 @@ static NTSTATUS find_builtin_without_file( const WCHAR *name, UNICODE_STRING *ne + 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) return status; ++ if (status != STATUS_DLL_NOT_FOUND) goto done; + RtlAppendUnicodeToString( new_name, L".fake" ); + status = open_dll_file( new_name, pwm, mapping, image_info, id ); +- if (status != STATUS_DLL_NOT_FOUND) return status; ++ if (status != STATUS_DLL_NOT_FOUND) goto done; + RtlFreeUnicodeString( new_name ); + } + for (i = 0; ; i++) +@@ -2592,10 +2592,21 @@ static NTSTATUS find_builtin_without_file( const WCHAR *name, UNICODE_STRING *ne + RtlAppendUnicodeToString( new_name, name ); + status = open_dll_file( new_name, pwm, mapping, image_info, id ); + if (status == STATUS_IMAGE_MACHINE_TYPE_MISMATCH) found_image = TRUE; +- else if (status != STATUS_DLL_NOT_FOUND) return status; ++ else if (status != STATUS_DLL_NOT_FOUND) goto done; + RtlFreeUnicodeString( new_name ); + } + if (found_image) status = STATUS_IMAGE_MACHINE_TYPE_MISMATCH; ++ ++done: ++ RtlFreeUnicodeString( new_name ); ++ if (!status) ++ { ++ new_name->Length = (4 + wcslen(system_dir) + wcslen(name)) * sizeof(WCHAR); ++ new_name->Buffer = RtlAllocateHeap( GetProcessHeap(), 0, new_name->Length + sizeof(WCHAR) ); ++ wcscpy( new_name->Buffer, L"\\??\\" ); ++ wcscat( new_name->Buffer, system_dir ); ++ wcscat( new_name->Buffer, name ); ++ } + return status; + } + +diff --git a/dlls/kernel32/tests/module.c b/dlls/kernel32/tests/module.c +index 96577989431..0066f7de5a8 100644 +--- a/dlls/kernel32/tests/module.c ++++ b/dlls/kernel32/tests/module.c +@@ -1093,7 +1093,7 @@ static void test_SetDefaultDllDirectories(void) + ret = pSetDefaultDllDirectories( LOAD_LIBRARY_SEARCH_USER_DIRS ); + ok( ret, "SetDefaultDllDirectories failed err %u\n", GetLastError() ); + mod = LoadLibraryA( "authz.dll" ); +- todo_wine ok( !mod, "loading authz succeeded\n" ); ++ ok( !mod, "loading authz succeeded\n" ); + FreeLibrary( mod ); + ret = pSetDefaultDllDirectories( LOAD_LIBRARY_SEARCH_SYSTEM32 ); + ok( ret, "SetDefaultDllDirectories failed err %u\n", GetLastError() ); +@@ -1101,12 +1101,12 @@ static void test_SetDefaultDllDirectories(void) + ok( mod != NULL, "loading authz failed\n" ); + FreeLibrary( mod ); + mod = LoadLibraryExA( "authz.dll", 0, LOAD_LIBRARY_SEARCH_APPLICATION_DIR ); +- todo_wine ok( !mod, "loading authz succeeded\n" ); ++ ok( !mod, "loading authz succeeded\n" ); + FreeLibrary( mod ); + ret = pSetDefaultDllDirectories( LOAD_LIBRARY_SEARCH_APPLICATION_DIR ); + ok( ret, "SetDefaultDllDirectories failed err %u\n", GetLastError() ); + mod = LoadLibraryA( "authz.dll" ); +- todo_wine ok( !mod, "loading authz succeeded\n" ); ++ ok( !mod, "loading authz succeeded\n" ); + FreeLibrary( mod ); + ret = pSetDefaultDllDirectories( LOAD_LIBRARY_SEARCH_DEFAULT_DIRS ); + ok( ret, "SetDefaultDllDirectories failed err %u\n", GetLastError() ); +diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c +index e8b53778284..964a3e0eaa4 100644 +--- a/dlls/ntdll/loader.c ++++ b/dlls/ntdll/loader.c +@@ -73,6 +73,7 @@ BOOL is_wow64 = FALSE; + /* system search path */ + static const WCHAR system_path[] = L"C:\\windows\\system32;C:\\windows\\system;C:\\windows"; + ++static BOOL is_prefix_bootstrap; /* are we bootstrapping the prefix? */ + static BOOL imports_fixup_done = FALSE; /* set once the imports have been fixed up, before attaching them */ + static BOOL process_detaching = FALSE; /* set on process detach to avoid deadlocks with thread detach */ + static int free_lib_count; /* recursion depth of LdrUnloadDll calls */ +@@ -1918,10 +1919,14 @@ static NTSTATUS build_module( LPCWSTR load_path, const UNICODE_STRING *nt_name, + static void build_ntdll_module(void) + { + MEMORY_BASIC_INFORMATION meminfo; ++ FILE_BASIC_INFORMATION basic_info; + UNICODE_STRING nt_name; ++ OBJECT_ATTRIBUTES attr; + WINE_MODREF *wm; + + RtlInitUnicodeString( &nt_name, L"\\??\\C:\\windows\\system32\\ntdll.dll" ); ++ InitializeObjectAttributes( &attr, &nt_name, OBJ_CASE_INSENSITIVE, 0, NULL ); ++ is_prefix_bootstrap = NtQueryAttributesFile( &attr, &basic_info) != STATUS_SUCCESS; + NtQueryVirtualMemory( GetCurrentProcess(), build_ntdll_module, MemoryBasicInformation, + &meminfo, sizeof(meminfo), NULL ); + wm = alloc_module( meminfo.AllocationBase, &nt_name, TRUE ); +@@ -2647,7 +2652,7 @@ static NTSTATUS search_dll_file( LPCWSTR paths, LPCWSTR search, UNICODE_STRING * + + if (found_image) + status = STATUS_IMAGE_MACHINE_TYPE_MISMATCH; +- else if (!wcspbrk( search, L":/\\" )) ++ else if (is_prefix_bootstrap && !wcspbrk( search, L":/\\" )) + status = find_builtin_without_file( search, nt_name, pwm, mapping, image_info, id ); + + done: +diff --git a/dlls/ntdll/unix/loader.c b/dlls/ntdll/unix/loader.c +index 7c4572e6b0e..4c76865019b 100644 +--- a/dlls/ntdll/unix/loader.c ++++ b/dlls/ntdll/unix/loader.c +@@ -1374,21 +1374,6 @@ static NTSTATUS find_builtin_dll( UNICODE_STRING *nt_name, void **module, SIZE_T + } + + +-/*********************************************************************** +- * load_builtin_dll +- */ +-static NTSTATUS CDECL load_builtin_dll( UNICODE_STRING *nt_name, void **module, +- SECTION_IMAGE_INFORMATION *image_info, BOOL prefer_native ) +-{ +- SIZE_T size; +- NTSTATUS status; +- +- status = find_builtin_dll( nt_name, module, &size, image_info, current_machine, prefer_native ); +- if (status == STATUS_IMAGE_NOT_AT_BASE) status = STATUS_SUCCESS; +- return status; +-} +- +- + /*********************************************************************** + * load_builtin + * +@@ -1794,11 +1779,9 @@ static struct unix_funcs unix_funcs = + ntdll_tan, + virtual_release_address_space, + load_so_dll, +- load_builtin_dll, + init_builtin_dll, + init_unix_lib, + unwind_builtin_dll, +- get_load_order, + __wine_dbg_get_channel_flags, + __wine_dbg_strdup, + __wine_dbg_output, +diff --git a/dlls/ntdll/unix/loadorder.c b/dlls/ntdll/unix/loadorder.c +index 67a7473dc7f..49af8eb6adb 100644 +--- a/dlls/ntdll/unix/loadorder.c ++++ b/dlls/ntdll/unix/loadorder.c +@@ -378,7 +378,7 @@ static enum loadorder get_load_order_value( HANDLE std_key, HANDLE app_key, WCHA + * Return the loadorder of a module. + * The system directory and '.dll' extension is stripped from the path. + */ +-enum loadorder CDECL get_load_order( const UNICODE_STRING *nt_name ) ++enum loadorder get_load_order( const UNICODE_STRING *nt_name ) + { + static const WCHAR prefixW[] = {'\\','?','?','\\'}; + enum loadorder ret = LO_INVALID; +diff --git a/dlls/ntdll/unix/unix_private.h b/dlls/ntdll/unix/unix_private.h +index 05ba8202ee7..3987cc6c4d0 100644 +--- a/dlls/ntdll/unix/unix_private.h ++++ b/dlls/ntdll/unix/unix_private.h +@@ -400,8 +400,19 @@ static inline void context_init_xstate( CONTEXT *context, void *xstate_buffer ) + } + #endif + +-extern enum loadorder CDECL get_load_order( const UNICODE_STRING *nt_name ) DECLSPEC_HIDDEN; ++enum loadorder ++{ ++ LO_INVALID, ++ LO_DISABLED, ++ LO_NATIVE, ++ LO_BUILTIN, ++ LO_NATIVE_BUILTIN, /* native then builtin */ ++ LO_BUILTIN_NATIVE, /* builtin then native */ ++ LO_DEFAULT /* nothing specified, use default strategy */ ++}; ++ + extern void set_load_order_app_name( const WCHAR *app_name ) DECLSPEC_HIDDEN; ++extern enum loadorder get_load_order( const UNICODE_STRING *nt_name ) DECLSPEC_HIDDEN; + + static inline size_t ntdll_wcslen( const WCHAR *str ) + { +diff --git a/dlls/ntdll/unixlib.h b/dlls/ntdll/unixlib.h +index 80e4eaefc75..04ae8230b1a 100644 +--- a/dlls/ntdll/unixlib.h ++++ b/dlls/ntdll/unixlib.h +@@ -25,19 +25,8 @@ + + struct _DISPATCHER_CONTEXT; + +-enum loadorder +-{ +- LO_INVALID, +- LO_DISABLED, +- LO_NATIVE, +- LO_BUILTIN, +- LO_NATIVE_BUILTIN, /* native then builtin */ +- LO_BUILTIN_NATIVE, /* builtin then native */ +- LO_DEFAULT /* nothing specified, use default strategy */ +-}; +- + /* increment this when you change the function table */ +-#define NTDLL_UNIXLIB_VERSION 119 ++#define NTDLL_UNIXLIB_VERSION 120 + + struct unix_funcs + { +@@ -85,13 +74,10 @@ 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, +- SECTION_IMAGE_INFORMATION *image_info, BOOL prefer_native ); + void (CDECL *init_builtin_dll)( void *module ); + NTSTATUS (CDECL *init_unix_lib)( void *module, DWORD reason, const void *ptr_in, void *ptr_out ); + NTSTATUS (CDECL *unwind_builtin_dll)( ULONG type, struct _DISPATCHER_CONTEXT *dispatch, + CONTEXT *context ); +- enum loadorder (CDECL *get_load_order)( const UNICODE_STRING *nt_name ); + + /* debugging functions */ + unsigned char (CDECL *dbg_get_channel_flags)( struct __wine_debug_channel *channel ); +diff --git a/dlls/mscoree/tests/mscoree.c b/dlls/mscoree/tests/mscoree.c +index 9974eff63354..92126339ef08 100644 +--- a/dlls/mscoree/tests/mscoree.c ++++ b/dlls/mscoree/tests/mscoree.c +@@ -368,7 +368,7 @@ static void test_loadlibraryshim(void) + } + + hr = pLoadLibraryShim(fusion, vbogus, NULL, &hdll); +- todo_wine ok(hr == E_HANDLE, "LoadLibraryShim failed, hr=%x\n", hr); ++ ok(hr == E_HANDLE, "LoadLibraryShim failed, hr=%x\n", hr); + if (SUCCEEDED(hr)) + FreeLibrary(hdll); + +@@ -406,7 +406,7 @@ static void test_loadlibraryshim(void) + FreeLibrary(hdll); + + hr = pLoadLibraryShim(gdidll, latest, NULL, &hdll); +- todo_wine ok(hr == E_HANDLE, "LoadLibraryShim failed, hr=%x\n", hr); ++ ok(hr == E_HANDLE, "LoadLibraryShim failed, hr=%x\n", hr); + if (SUCCEEDED(hr)) + FreeLibrary(hdll); + } +diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c +index 7dada146044b..e8b537782847 100644 +--- a/dlls/ntdll/loader.c ++++ b/dlls/ntdll/loader.c +@@ -2378,38 +2378,6 @@ 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, BOOL prefer_native ) +-{ +- NTSTATUS status; +- void *module; +- SECTION_IMAGE_INFORMATION image_info; +- +- TRACE("Trying built-in %s\n", debugstr_us(nt_name)); +- +- status = unix_funcs->load_builtin_dll( nt_name, &module, &image_info, prefer_native ); +- if (status) return status; +- +- if ((*pwm = find_existing_module( module ))) /* already loaded */ +- { +- if ((*pwm)->ldr.LoadCount != -1) (*pwm)->ldr.LoadCount++; +- TRACE( "Found %s for %s at %p, count=%d\n", +- debugstr_us(&(*pwm)->ldr.FullDllName), debugstr_us(nt_name), +- (*pwm)->ldr.DllBase, (*pwm)->ldr.LoadCount); +- if (module != (*pwm)->ldr.DllBase) NtUnmapViewOfSection( NtCurrentProcess(), module ); +- return STATUS_SUCCESS; +- } +- +- TRACE( "loading %s\n", debugstr_us(nt_name) ); +- status = build_module( load_path, nt_name, &module, &image_info, NULL, flags, pwm ); +- if (status && module) NtUnmapViewOfSection( NtCurrentProcess(), module ); +- return status; +-} +- +- + /************************************************************************* + * build_main_module + * +@@ -2553,6 +2521,91 @@ static NTSTATUS find_actctx_dll( LPCWSTR libname, LPWSTR *fullname ) + } + + ++/*********************************************************************** ++ * get_env_var ++ */ ++static NTSTATUS get_env_var( const WCHAR *name, SIZE_T extra, UNICODE_STRING *ret ) ++{ ++ NTSTATUS status; ++ SIZE_T len, size = 1024 + extra; ++ ++ for (;;) ++ { ++ ret->Buffer = RtlAllocateHeap( GetProcessHeap(), 0, size * sizeof(WCHAR) ); ++ status = RtlQueryEnvironmentVariable( NULL, name, wcslen(name), ++ ret->Buffer, size - extra - 1, &len ); ++ if (!status) ++ { ++ ret->Buffer[len] = 0; ++ ret->Length = len * sizeof(WCHAR); ++ ret->MaximumLength = size * sizeof(WCHAR); ++ return status; ++ } ++ RtlFreeHeap( GetProcessHeap(), 0, ret->Buffer ); ++ if (status != STATUS_BUFFER_TOO_SMALL) ++ { ++ ret->Buffer = NULL; ++ return status; ++ } ++ size = len + 1 + extra; ++ } ++} ++ ++ ++/*********************************************************************** ++ * find_builtin_without_file ++ * ++ * Find a builtin dll when the corresponding file cannot be found in the prefix. ++ * This is used during prefix bootstrap. ++ */ ++static NTSTATUS find_builtin_without_file( const WCHAR *name, UNICODE_STRING *new_name, ++ WINE_MODREF **pwm, HANDLE *mapping, ++ SECTION_IMAGE_INFORMATION *image_info, struct file_id *id ) ++{ ++ const WCHAR *ext; ++ WCHAR dllpath[32]; ++ DWORD i, len; ++ NTSTATUS status = STATUS_DLL_NOT_FOUND; ++ BOOL found_image = FALSE; ++ ++ if (!get_env_var( L"WINEBUILDDIR", 20 + 2 * wcslen(name), new_name )) ++ { ++ RtlAppendUnicodeToString( new_name, L"\\dlls\\" ); ++ RtlAppendUnicodeToString( new_name, name ); ++ if ((ext = wcsrchr( name, '.' )) && !wcscmp( ext, L".dll" )) new_name->Length -= 4 * sizeof(WCHAR); ++ 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) return status; ++ RtlAppendUnicodeToString( new_name, L".fake" ); ++ status = open_dll_file( new_name, pwm, mapping, image_info, id ); ++ if (status != STATUS_DLL_NOT_FOUND) return status; ++ RtlFreeUnicodeString( new_name ); ++ } ++ ++ for (i = 0; ; i++) ++ { ++ swprintf( dllpath, ARRAY_SIZE(dllpath), L"WINEDLLDIR%u", i ); ++ 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 ); ++ if (status == STATUS_IMAGE_MACHINE_TYPE_MISMATCH) found_image = TRUE; ++ else if (status != STATUS_DLL_NOT_FOUND) return status; ++ RtlFreeUnicodeString( new_name ); ++ } ++ if (found_image) status = STATUS_IMAGE_MACHINE_TYPE_MISMATCH; ++ return status; ++} ++ ++ + /*********************************************************************** + * search_dll_file + * +@@ -2597,14 +2645,10 @@ static NTSTATUS search_dll_file( LPCWSTR paths, LPCWSTR search, UNICODE_STRING * + paths = ptr; + } + +- if (!found_image) +- { +- /* not found, return file in the system dir to be loaded as builtin */ +- wcscpy( name, system_dir ); +- wcscat( name, search ); +- if (!RtlDosPathNameToNtPathName_U( name, nt_name, NULL, NULL )) status = STATUS_NO_MEMORY; +- } +- else status = STATUS_IMAGE_MACHINE_TYPE_MISMATCH; ++ if (found_image) ++ status = STATUS_IMAGE_MACHINE_TYPE_MISMATCH; ++ else if (!wcspbrk( search, L":/\\" )) ++ status = find_builtin_without_file( search, nt_name, pwm, mapping, image_info, id ); + + done: + RtlFreeHeap( GetProcessHeap(), 0, name ); +@@ -2713,7 +2757,7 @@ static NTSTATUS load_dll( const WCHAR *load_path, const WCHAR *libname, const WC + return STATUS_SUCCESS; + } + +- if (nts && nts != STATUS_DLL_NOT_FOUND && nts != STATUS_INVALID_IMAGE_NOT_MZ) goto done; ++ if (nts && nts != STATUS_INVALID_IMAGE_NOT_MZ) goto done; + + prev = NtCurrentTeb()->Tib.ArbitraryUserPointer; + NtCurrentTeb()->Tib.ArbitraryUserPointer = nt_name.Buffer + 4; +@@ -2727,21 +2771,6 @@ static NTSTATUS load_dll( const WCHAR *load_path, const WCHAR *libname, const WC + case STATUS_SUCCESS: /* valid PE file */ + nts = load_native_dll( load_path, &nt_name, mapping, &image_info, &id, flags, pwm ); + break; +- +- case STATUS_DLL_NOT_FOUND: /* no file found, try builtin */ +- switch (unix_funcs->get_load_order( &nt_name )) +- { +- case LO_NATIVE_BUILTIN: +- case LO_BUILTIN: +- case LO_BUILTIN_NATIVE: +- case LO_DEFAULT: +- nts = load_builtin_dll( load_path, &nt_name, flags, pwm, FALSE ); +- break; +- default: +- nts = STATUS_DLL_NOT_FOUND; +- break; +- } +- break; + } + NtCurrentTeb()->Tib.ArbitraryUserPointer = prev; +