Alexandre Julliard : kernel32: Move image path name initialization to ntdll.
Alexandre Julliard
julliard at winehq.org
Tue Oct 22 16:57:00 CDT 2019
Module: wine
Branch: master
Commit: 075741b681553df08e8248e44148e531dfece408
URL: https://source.winehq.org/git/wine.git/?a=commit;h=075741b681553df08e8248e44148e531dfece408
Author: Alexandre Julliard <julliard at 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 at 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;
More information about the wine-cvs
mailing list