msiexec: Fix parsing of command lines where quoted strings and properties are not separated by whitespace.
Signed-off-by: Hans Leidekker <hans@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
20c627d58c
commit
d73c38fe9a
|
@ -216,14 +216,6 @@ static DWORD msi_atou(LPCWSTR str)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static LPWSTR msi_strdup(LPCWSTR str)
|
|
||||||
{
|
|
||||||
DWORD len = lstrlenW(str)+1;
|
|
||||||
LPWSTR ret = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*len);
|
|
||||||
lstrcpyW(ret, str);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* str1 is the same as str2, ignoring case */
|
/* str1 is the same as str2, ignoring case */
|
||||||
static BOOL msi_strequal(LPCWSTR str1, LPCSTR str2)
|
static BOOL msi_strequal(LPCWSTR str1, LPCSTR str2)
|
||||||
{
|
{
|
||||||
|
@ -413,90 +405,103 @@ static INT DoEmbedding( LPWSTR key )
|
||||||
|
|
||||||
enum chomp_state
|
enum chomp_state
|
||||||
{
|
{
|
||||||
cs_whitespace,
|
CS_WHITESPACE,
|
||||||
cs_token,
|
CS_TOKEN,
|
||||||
cs_quote
|
CS_QUOTE
|
||||||
};
|
};
|
||||||
|
|
||||||
static int chomp( WCHAR *str )
|
static int chomp( const WCHAR *in, WCHAR *out )
|
||||||
{
|
{
|
||||||
enum chomp_state state = cs_token;
|
enum chomp_state state = CS_TOKEN;
|
||||||
WCHAR *p, *out;
|
const WCHAR *p;
|
||||||
int count = 1;
|
int count = 1;
|
||||||
BOOL ignore;
|
BOOL ignore;
|
||||||
|
|
||||||
for( p = str, out = str; *p; p++ )
|
for (p = in; *p; p++)
|
||||||
{
|
{
|
||||||
ignore = TRUE;
|
ignore = TRUE;
|
||||||
switch( state )
|
switch (state)
|
||||||
{
|
{
|
||||||
case cs_whitespace:
|
case CS_WHITESPACE:
|
||||||
switch( *p )
|
switch (*p)
|
||||||
{
|
{
|
||||||
case ' ':
|
case ' ':
|
||||||
break;
|
break;
|
||||||
case '"':
|
case '"':
|
||||||
state = cs_quote;
|
state = CS_QUOTE;
|
||||||
count++;
|
count++;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
count++;
|
count++;
|
||||||
ignore = FALSE;
|
ignore = FALSE;
|
||||||
state = cs_token;
|
state = CS_TOKEN;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case cs_token:
|
case CS_TOKEN:
|
||||||
switch( *p )
|
switch (*p)
|
||||||
{
|
{
|
||||||
case '"':
|
case '"':
|
||||||
state = cs_quote;
|
state = CS_QUOTE;
|
||||||
break;
|
break;
|
||||||
case ' ':
|
case ' ':
|
||||||
state = cs_whitespace;
|
state = CS_WHITESPACE;
|
||||||
*out++ = 0;
|
if (out) *out++ = 0;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ignore = FALSE;
|
if (p > in && p[-1] == '"')
|
||||||
}
|
{
|
||||||
break;
|
if (out) *out++ = 0;
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
ignore = FALSE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case cs_quote:
|
case CS_QUOTE:
|
||||||
switch( *p )
|
switch (*p)
|
||||||
{
|
{
|
||||||
case '"':
|
case '"':
|
||||||
state = cs_token;
|
state = CS_TOKEN;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ignore = FALSE;
|
ignore = FALSE;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if( !ignore )
|
if (!ignore && out) *out++ = *p;
|
||||||
*out++ = *p;
|
}
|
||||||
}
|
if (out) *out = 0;
|
||||||
|
return count;
|
||||||
*out = 0;
|
|
||||||
|
|
||||||
return count;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void process_args( WCHAR *cmdline, int *pargc, WCHAR ***pargv )
|
static void process_args( WCHAR *cmdline, int *pargc, WCHAR ***pargv )
|
||||||
{
|
{
|
||||||
WCHAR **argv, *p = msi_strdup(cmdline);
|
WCHAR **argv, *p;
|
||||||
int i, n;
|
int i, count;
|
||||||
|
|
||||||
n = chomp( p );
|
*pargc = 0;
|
||||||
argv = HeapAlloc(GetProcessHeap(), 0, sizeof (WCHAR*)*(n+1));
|
*pargv = NULL;
|
||||||
for( i=0; i<n; i++ )
|
|
||||||
{
|
|
||||||
argv[i] = p;
|
|
||||||
p += lstrlenW(p) + 1;
|
|
||||||
}
|
|
||||||
argv[i] = NULL;
|
|
||||||
|
|
||||||
*pargc = n;
|
count = chomp( cmdline, NULL );
|
||||||
*pargv = argv;
|
if (!(p = HeapAlloc( GetProcessHeap(), 0, (lstrlenW(cmdline) + count + 1) * sizeof(WCHAR) )))
|
||||||
|
return;
|
||||||
|
|
||||||
|
count = chomp( cmdline, p );
|
||||||
|
if (!(argv = HeapAlloc( GetProcessHeap(), 0, (count + 1) * sizeof(WCHAR *) )))
|
||||||
|
{
|
||||||
|
HeapFree( GetProcessHeap(), 0, p );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
argv[i] = p;
|
||||||
|
p += lstrlenW( p ) + 1;
|
||||||
|
}
|
||||||
|
argv[i] = NULL;
|
||||||
|
|
||||||
|
*pargc = count;
|
||||||
|
*pargv = argv;
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL process_args_from_reg( const WCHAR *ident, int *pargc, WCHAR ***pargv )
|
static BOOL process_args_from_reg( const WCHAR *ident, int *pargc, WCHAR ***pargv )
|
||||||
|
|
Loading…
Reference in New Issue