Module: wine Branch: master Commit: 075741b681553df08e8248e44148e531dfece408 URL: https://source.winehq.org/git/wine.git/?a=commit;h=075741b681553df08e8248e44...
Author: Alexandre Julliard julliard@winehq.org Date: Tue Oct 22 10:15:28 2019 +0200
kernel32: Move image path name initialization to ntdll.
Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/kernel32/process.c | 17 ++---------- dlls/ntdll/env.c | 74 +++++++++++++++++++++++++++++++++++++++++++++++++ dlls/ntdll/loader.c | 2 ++ dlls/ntdll/ntdll_misc.h | 1 + 4 files changed, 79 insertions(+), 15 deletions(-)
diff --git a/dlls/kernel32/process.c b/dlls/kernel32/process.c index 27dd77606a..74382722bb 100644 --- a/dlls/kernel32/process.c +++ b/dlls/kernel32/process.c @@ -1236,28 +1236,15 @@ void * CDECL __wine_kernel_init(void) set_library_wargv( __wine_main_argv ); boot_events[0] = boot_events[1] = 0;
- if (peb->ProcessParameters->ImagePathName.Buffer) - { - strcpyW( main_exe_name, peb->ProcessParameters->ImagePathName.Buffer ); - } - else + if (!peb->ProcessParameters->WindowTitle.Buffer) { - BOOL is_64bit; - - RtlGetExePath( __wine_main_wargv[0], &load_path ); - if (!SearchPathW( load_path, __wine_main_wargv[0], exeW, MAX_PATH, main_exe_name, NULL ) && - !get_builtin_path( __wine_main_wargv[0], exeW, main_exe_name, MAX_PATH, &is_64bit )) - { - MESSAGE( "wine: cannot find '%s'\n", __wine_main_argv[0] ); - ExitProcess( GetLastError() ); - } - RtlReleasePath( load_path ); update_library_argv0( main_exe_name ); if (!build_command_line( __wine_main_wargv )) goto error; start_wineboot( boot_events ); }
/* if there's no extension, append a dot to prevent LoadLibrary from appending .dll */ + strcpyW( main_exe_name, peb->ProcessParameters->ImagePathName.Buffer ); p = strrchrW( main_exe_name, '.' ); if (!p || strchrW( p, '/' ) || strchrW( p, '\' )) strcatW( main_exe_name, dotW );
diff --git a/dlls/ntdll/env.c b/dlls/ntdll/env.c index 1b7d848f30..e41836bacc 100644 --- a/dlls/ntdll/env.c +++ b/dlls/ntdll/env.c @@ -47,6 +47,8 @@ static WCHAR empty[] = {0}; static const UNICODE_STRING empty_str = { 0, sizeof(empty), empty }; static const UNICODE_STRING null_str = { 0, 0, NULL };
+static const BOOL is_win64 = (sizeof(void *) > sizeof(int)); + static const WCHAR windows_dir[] = {'C',':','\','w','i','n','d','o','w','s',0};
static inline SIZE_T get_env_length( const WCHAR *env ) @@ -440,6 +442,77 @@ static void get_current_directory( UNICODE_STRING *dir ) }
+/*********************************************************************** + * is_path_prefix + */ +static inline BOOL is_path_prefix( const WCHAR *prefix, const WCHAR *path, const WCHAR *file ) +{ + DWORD len = strlenW( prefix ); + + if (strncmpiW( path, prefix, len )) return FALSE; + while (path[len] == '\') len++; + return path + len == file; +} + + +/*********************************************************************** + * get_image_path + */ +static void get_image_path( const char *argv0, UNICODE_STRING *path ) +{ + static const WCHAR exeW[] = {'.','e','x','e',0}; + WCHAR *load_path, *file_part, *name, full_name[MAX_PATH]; + DWORD len; + + len = ntdll_umbstowcs( 0, argv0, strlen(argv0) + 1, NULL, 0 ); + if (!(name = RtlAllocateHeap( GetProcessHeap(), 0, len * sizeof(WCHAR) ))) goto failed; + ntdll_umbstowcs( 0, argv0, strlen(argv0) + 1, name, len ); + + if (RtlDetermineDosPathNameType_U( name ) != RELATIVE_PATH || + strchrW( name, '/' ) || strchrW( name, '\' )) + { + len = RtlGetFullPathName_U( name, sizeof(full_name), full_name, &file_part ); + if (!len || len > sizeof(full_name)) goto failed; + /* try first without extension */ + if (RtlDoesFileExists_U( full_name )) goto done; + if (len < (MAX_PATH - 4) * sizeof(WCHAR) && !strchrW( file_part, '.' )) + { + strcatW( file_part, exeW ); + if (RtlDoesFileExists_U( full_name )) goto done; + } + /* check for builtin path inside system directory */ + if (!is_path_prefix( system_dir, full_name, file_part )) + { + if (!is_win64 && !is_wow64) goto failed; + if (!is_path_prefix( syswow64_dir, full_name, file_part )) goto failed; + } + } + else + { + RtlGetExePath( name, &load_path ); + len = RtlDosSearchPath_U( load_path, name, exeW, sizeof(full_name), full_name, &file_part ); + RtlReleasePath( load_path ); + if (!len || len > sizeof(full_name)) + { + /* build builtin path inside system directory */ + len = strlenW( system_dir ); + if (strlenW( name ) >= MAX_PATH - 4 - len) goto failed; + strcpyW( full_name, system_dir ); + strcatW( full_name, name ); + if (!strchrW( name, '.' )) strcatW( full_name, exeW ); + } + } +done: + RtlCreateUnicodeString( path, full_name ); + RtlFreeHeap( GetProcessHeap(), 0, name ); + return; + +failed: + MESSAGE( "wine: cannot find '%s'\n", argv0 ); + RtlExitUserProcess( GetLastError() ); +} + + /****************************************************************************** * NtQuerySystemEnvironmentValue [NTDLL.@] */ @@ -960,6 +1033,7 @@ void init_user_process_params( SIZE_T data_size ) NtCurrentTeb()->Peb->ProcessParameters = params; params->Environment = build_initial_environment( __wine_get_main_environment() ); get_current_directory( ¶ms->CurrentDirectory.DosPath ); + get_image_path( __wine_main_argv[0], ¶ms->ImagePathName );
if (isatty(0) || isatty(1) || isatty(2)) params->ConsoleHandle = (HANDLE)2; /* see kernel32/kernel_private.h */ diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c index e33c24d7af..2bae3c7bd5 100644 --- a/dlls/ntdll/loader.c +++ b/dlls/ntdll/loader.c @@ -67,6 +67,8 @@ typedef void (CALLBACK *LDRENUMPROC)(LDR_MODULE *, void *, BOOLEAN *); /* system directory with trailing backslash */ const WCHAR system_dir[] = {'C',':','\','w','i','n','d','o','w','s','\', 's','y','s','t','e','m','3','2','\',0}; +const WCHAR syswow64_dir[] = {'C',':','\','w','i','n','d','o','w','s','\', + 's','y','s','w','o','w','6','4','\',0};
/* system search path */ static const WCHAR system_path[] = diff --git a/dlls/ntdll/ntdll_misc.h b/dlls/ntdll/ntdll_misc.h index 04aa15636d..20e64c80c7 100644 --- a/dlls/ntdll/ntdll_misc.h +++ b/dlls/ntdll/ntdll_misc.h @@ -123,6 +123,7 @@ extern FARPROC SNOOP_GetProcAddress( HMODULE hmod, const IMAGE_EXPORT_DIRECTORY extern void RELAY_SetupDLL( HMODULE hmod ) DECLSPEC_HIDDEN; extern void SNOOP_SetupDLL( HMODULE hmod ) DECLSPEC_HIDDEN; extern const WCHAR system_dir[] DECLSPEC_HIDDEN; +extern const WCHAR syswow64_dir[] DECLSPEC_HIDDEN;
extern void (WINAPI *kernel32_start_process)(LPTHREAD_START_ROUTINE,void*) DECLSPEC_HIDDEN;