[PATCH 2/3] kernel32: Store command line inside the process parameters block.

Dmitry Timoshkov dmitry at baikal.ru
Mon Feb 11 02:27:04 CST 2019


Signed-off-by: Dmitry Timoshkov <dmitry at baikal.ru>
---
 dlls/kernel32/process.c | 50 ++++++++++++++++++++++++++++++-----------
 1 file changed, 37 insertions(+), 13 deletions(-)

diff --git a/dlls/kernel32/process.c b/dlls/kernel32/process.c
index 26c576e4f0..14615a568e 100644
--- a/dlls/kernel32/process.c
+++ b/dlls/kernel32/process.c
@@ -934,14 +934,11 @@ static void update_library_argv0( const WCHAR *argv0 )
  *   'a\b'   == 'a\b'
  *   'a\\b'  == 'a\\b'
  */
-static BOOL build_command_line( WCHAR **argv )
+static WCHAR *build_command_line( WCHAR **argv )
 {
     int len;
-    WCHAR **arg;
+    WCHAR **arg, *cmd_line;
     LPWSTR p;
-    RTL_USER_PROCESS_PARAMETERS* rupp = NtCurrentTeb()->Peb->ProcessParameters;
-
-    if (rupp->CommandLine.Buffer) return TRUE; /* already got it from the server */
 
     len = 0;
     for (arg = argv; *arg; arg++)
@@ -975,12 +972,10 @@ static BOOL build_command_line( WCHAR **argv )
             len+=2+bcount; /* for the quotes and doubling of '\' preceding the closing quote */
     }
 
-    if (!(rupp->CommandLine.Buffer = RtlAllocateHeap( GetProcessHeap(), 0, len * sizeof(WCHAR))))
-        return FALSE;
+    if (!(cmd_line = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) )))
+        return NULL;
 
-    p = rupp->CommandLine.Buffer;
-    rupp->CommandLine.Length = (len - 1) * sizeof(WCHAR);
-    rupp->CommandLine.MaximumLength = len * sizeof(WCHAR);
+    p = cmd_line;
     for (arg = argv; *arg; arg++)
     {
         BOOL has_space,has_quote;
@@ -1043,11 +1038,11 @@ static BOOL build_command_line( WCHAR **argv )
         }
         *p++=' ';
     }
-    if (p > rupp->CommandLine.Buffer)
+    if (p > cmd_line)
         p--;  /* remove last space */
     *p = '\0';
 
-    return TRUE;
+    return cmd_line;
 }
 
 
@@ -1395,6 +1390,8 @@ void CDECL __wine_kernel_init(void)
     else
     {
         BOOL is_64bit;
+        WCHAR *cmd_line;
+        RTL_USER_PROCESS_PARAMETERS *params = NtCurrentTeb()->Peb->ProcessParameters;
 
         if (!SearchPathW( NULL, __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 ))
@@ -1403,7 +1400,34 @@ void CDECL __wine_kernel_init(void)
             ExitProcess( GetLastError() );
         }
         update_library_argv0( main_exe_name );
-        if (!build_command_line( __wine_main_wargv )) goto error;
+        if (!params->CommandLine.Buffer) /* haven't already got it from the server */
+        {
+            SIZE_T size;
+            char *ptr;
+
+            if (!(cmd_line = build_command_line( __wine_main_wargv ))) goto error;
+
+            size = sizeof(*params);
+            size += params->CurrentDirectory.DosPath.MaximumLength;
+            /* some apps try to append custom parameters to the command line, so we need more space */
+            size += max(lstrlenW(cmd_line) + 1, MAX_PATH) * sizeof(WCHAR);
+            /* everything else is empty at this point */
+
+            if (!(params = HeapReAlloc( GetProcessHeap(), 0, params, size ))) goto error;
+
+            params->AllocationSize = size;
+            params->Size = size;
+
+            ptr = (char *)(params + 1);
+            ptr += params->CurrentDirectory.DosPath.MaximumLength;
+            strcpyW( (WCHAR *)ptr, cmd_line );
+            RtlInitUnicodeString( &params->CommandLine, (WCHAR *)ptr );
+
+            NtCurrentTeb()->Peb->ProcessParameters = params;
+
+            HeapFree( GetProcessHeap(), 0, cmd_line );
+        }
+
         start_wineboot( boot_events );
     }
 
-- 
2.20.1




More information about the wine-devel mailing list