Signed-off-by: Dmitry Timoshkov dmitry@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( ¶ms->CommandLine, (WCHAR *)ptr ); + + NtCurrentTeb()->Peb->ProcessParameters = params; + + HeapFree( GetProcessHeap(), 0, cmd_line ); + } + start_wineboot( boot_events ); }