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( &params->CurrentDirectory.DosPath );
+        get_image_path( __wine_main_argv[0], &params->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