kernel32: Move command line initialization to ntdll.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
ee56be3fcd
commit
2607bfa28f
|
@ -867,149 +867,6 @@ static void set_library_argv( WCHAR **wargv )
|
|||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* build_command_line
|
||||
*
|
||||
* Build the command line of a process from the argv array.
|
||||
*
|
||||
* Note that it does NOT necessarily include the file name.
|
||||
* Sometimes we don't even have any command line options at all.
|
||||
*
|
||||
* We must quote and escape characters so that the argv array can be rebuilt
|
||||
* from the command line:
|
||||
* - spaces and tabs must be quoted
|
||||
* 'a b' -> '"a b"'
|
||||
* - quotes must be escaped
|
||||
* '"' -> '\"'
|
||||
* - if '\'s are followed by a '"', they must be doubled and followed by '\"',
|
||||
* resulting in an odd number of '\' followed by a '"'
|
||||
* '\"' -> '\\\"'
|
||||
* '\\"' -> '\\\\\"'
|
||||
* - '\'s are followed by the closing '"' must be doubled,
|
||||
* resulting in an even number of '\' followed by a '"'
|
||||
* ' \' -> '" \\"'
|
||||
* ' \\' -> '" \\\\"'
|
||||
* - '\'s that are not followed by a '"' can be left as is
|
||||
* 'a\b' == 'a\b'
|
||||
* 'a\\b' == 'a\\b'
|
||||
*/
|
||||
static BOOL build_command_line( WCHAR **argv )
|
||||
{
|
||||
int len;
|
||||
WCHAR **arg;
|
||||
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++)
|
||||
{
|
||||
BOOL has_space;
|
||||
int bcount;
|
||||
WCHAR* a;
|
||||
|
||||
has_space=FALSE;
|
||||
bcount=0;
|
||||
a=*arg;
|
||||
if( arg == argv || !*a ) has_space=TRUE;
|
||||
while (*a!='\0') {
|
||||
if (*a=='\\') {
|
||||
bcount++;
|
||||
} else {
|
||||
if (*a==' ' || *a=='\t') {
|
||||
has_space=TRUE;
|
||||
} else if (*a=='"') {
|
||||
/* doubling of '\' preceding a '"',
|
||||
* plus escaping of said '"'
|
||||
*/
|
||||
len+=2*bcount+1;
|
||||
}
|
||||
bcount=0;
|
||||
}
|
||||
a++;
|
||||
}
|
||||
len+=(a-*arg)+1 /* for the separating space */;
|
||||
if (has_space)
|
||||
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;
|
||||
|
||||
p = rupp->CommandLine.Buffer;
|
||||
rupp->CommandLine.Length = (len - 1) * sizeof(WCHAR);
|
||||
rupp->CommandLine.MaximumLength = len * sizeof(WCHAR);
|
||||
for (arg = argv; *arg; arg++)
|
||||
{
|
||||
BOOL has_space,has_quote;
|
||||
WCHAR* a;
|
||||
int bcount;
|
||||
|
||||
/* Check for quotes and spaces in this argument */
|
||||
has_space=has_quote=FALSE;
|
||||
a=*arg;
|
||||
if( arg == argv || !*a ) has_space=TRUE;
|
||||
while (*a!='\0') {
|
||||
if (*a==' ' || *a=='\t') {
|
||||
has_space=TRUE;
|
||||
if (has_quote)
|
||||
break;
|
||||
} else if (*a=='"') {
|
||||
has_quote=TRUE;
|
||||
if (has_space)
|
||||
break;
|
||||
}
|
||||
a++;
|
||||
}
|
||||
|
||||
/* Now transfer it to the command line */
|
||||
if (has_space)
|
||||
*p++='"';
|
||||
if (has_quote || has_space) {
|
||||
bcount=0;
|
||||
a=*arg;
|
||||
while (*a!='\0') {
|
||||
if (*a=='\\') {
|
||||
*p++=*a;
|
||||
bcount++;
|
||||
} else {
|
||||
if (*a=='"') {
|
||||
int i;
|
||||
|
||||
/* Double all the '\\' preceding this '"', plus one */
|
||||
for (i=0;i<=bcount;i++)
|
||||
*p++='\\';
|
||||
*p++='"';
|
||||
} else {
|
||||
*p++=*a;
|
||||
}
|
||||
bcount=0;
|
||||
}
|
||||
a++;
|
||||
}
|
||||
} else {
|
||||
WCHAR* x = *arg;
|
||||
while ((*p=*x++)) p++;
|
||||
}
|
||||
if (has_space) {
|
||||
int i;
|
||||
|
||||
/* Double all the '\' preceding the closing quote */
|
||||
for (i=0;i<bcount;i++)
|
||||
*p++='\\';
|
||||
*p++='"';
|
||||
}
|
||||
*p++=' ';
|
||||
}
|
||||
if (p > rupp->CommandLine.Buffer)
|
||||
p--; /* remove last space */
|
||||
*p = '\0';
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* init_windows_dirs
|
||||
*/
|
||||
|
@ -1182,20 +1039,14 @@ void * CDECL __wine_kernel_init(void)
|
|||
RtlSetUnhandledExceptionFilter( UnhandledExceptionFilter );
|
||||
|
||||
LOCALE_Init();
|
||||
init_windows_dirs();
|
||||
boot_events[0] = boot_events[1] = 0;
|
||||
|
||||
if (!peb->ProcessParameters->WindowTitle.Buffer)
|
||||
{
|
||||
/* convert old configuration to new format */
|
||||
convert_old_config();
|
||||
got_environment = has_registry_environment();
|
||||
}
|
||||
|
||||
init_windows_dirs();
|
||||
boot_events[0] = boot_events[1] = 0;
|
||||
|
||||
if (!peb->ProcessParameters->WindowTitle.Buffer)
|
||||
{
|
||||
if (!build_command_line( __wine_main_wargv )) goto error;
|
||||
start_wineboot( boot_events );
|
||||
}
|
||||
|
||||
|
@ -1265,9 +1116,6 @@ void * CDECL __wine_kernel_init(void)
|
|||
if (!params->CurrentDirectory.Handle) chdir("/"); /* avoid locking removable devices */
|
||||
|
||||
return start_process_wrapper;
|
||||
|
||||
error:
|
||||
ExitProcess( GetLastError() );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -552,6 +552,91 @@ static void set_library_wargv( char **argv, const UNICODE_STRING *image )
|
|||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* build_command_line
|
||||
*
|
||||
* Build the command line of a process from the argv array.
|
||||
*
|
||||
* Note that it does NOT necessarily include the file name.
|
||||
* Sometimes we don't even have any command line options at all.
|
||||
*
|
||||
* We must quote and escape characters so that the argv array can be rebuilt
|
||||
* from the command line:
|
||||
* - spaces and tabs must be quoted
|
||||
* 'a b' -> '"a b"'
|
||||
* - quotes must be escaped
|
||||
* '"' -> '\"'
|
||||
* - if '\'s are followed by a '"', they must be doubled and followed by '\"',
|
||||
* resulting in an odd number of '\' followed by a '"'
|
||||
* '\"' -> '\\\"'
|
||||
* '\\"' -> '\\\\\"'
|
||||
* - '\'s are followed by the closing '"' must be doubled,
|
||||
* resulting in an even number of '\' followed by a '"'
|
||||
* ' \' -> '" \\"'
|
||||
* ' \\' -> '" \\\\"'
|
||||
* - '\'s that are not followed by a '"' can be left as is
|
||||
* 'a\b' == 'a\b'
|
||||
* 'a\\b' == 'a\\b'
|
||||
*/
|
||||
static void build_command_line( WCHAR **argv, UNICODE_STRING *cmdline )
|
||||
{
|
||||
int len;
|
||||
WCHAR **arg;
|
||||
LPWSTR p;
|
||||
|
||||
len = 1;
|
||||
for (arg = argv; *arg; arg++) len += 3 + 2 * strlenW( *arg );
|
||||
cmdline->MaximumLength = len * sizeof(WCHAR);
|
||||
if (!(cmdline->Buffer = RtlAllocateHeap( GetProcessHeap(), 0, cmdline->MaximumLength ))) return;
|
||||
|
||||
p = cmdline->Buffer;
|
||||
for (arg = argv; *arg; arg++)
|
||||
{
|
||||
BOOL has_space, has_quote;
|
||||
int i, bcount;
|
||||
WCHAR *a;
|
||||
|
||||
/* check for quotes and spaces in this argument */
|
||||
if (arg == argv || !**arg) has_space = TRUE;
|
||||
else has_space = strchrW( *arg, ' ' ) || strchrW( *arg, '\t' );
|
||||
has_quote = strchrW( *arg, '"' ) != NULL;
|
||||
|
||||
/* now transfer it to the command line */
|
||||
if (has_space) *p++ = '"';
|
||||
if (has_quote || has_space)
|
||||
{
|
||||
bcount = 0;
|
||||
for (a = *arg; *a; a++)
|
||||
{
|
||||
if (*a == '\\') bcount++;
|
||||
else
|
||||
{
|
||||
if (*a == '"') /* double all the '\\' preceding this '"', plus one */
|
||||
for (i = 0; i <= bcount; i++) *p++ = '\\';
|
||||
bcount = 0;
|
||||
}
|
||||
*p++ = *a;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
strcpyW( p, *arg );
|
||||
p += strlenW( p );
|
||||
}
|
||||
if (has_space)
|
||||
{
|
||||
/* Double all the '\' preceding the closing quote */
|
||||
for (i = 0; i < bcount; i++) *p++ = '\\';
|
||||
*p++ = '"';
|
||||
}
|
||||
*p++ = ' ';
|
||||
}
|
||||
if (p > cmdline->Buffer) p--; /* remove last space */
|
||||
*p = 0;
|
||||
cmdline->Length = (p - cmdline->Buffer) * sizeof(WCHAR);
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* NtQuerySystemEnvironmentValue [NTDLL.@]
|
||||
*/
|
||||
|
@ -1074,6 +1159,7 @@ void init_user_process_params( SIZE_T data_size )
|
|||
get_current_directory( ¶ms->CurrentDirectory.DosPath );
|
||||
get_image_path( __wine_main_argv[0], ¶ms->ImagePathName );
|
||||
set_library_wargv( __wine_main_argv, ¶ms->ImagePathName );
|
||||
build_command_line( __wine_main_wargv, ¶ms->CommandLine );
|
||||
|
||||
if (isatty(0) || isatty(1) || isatty(2))
|
||||
params->ConsoleHandle = (HANDLE)2; /* see kernel32/kernel_private.h */
|
||||
|
|
Loading…
Reference in New Issue