diff --git a/programs/msiexec/Makefile.in b/programs/msiexec/Makefile.in index 10e1cc4f647..c2bd981581f 100644 --- a/programs/msiexec/Makefile.in +++ b/programs/msiexec/Makefile.in @@ -4,7 +4,7 @@ SRCDIR = @srcdir@ VPATH = @srcdir@ MODULE = msiexec.exe APPMODE = -mconsole -IMPORTS = msi shell32 ole32 advapi32 user32 kernel32 +IMPORTS = msi ole32 advapi32 user32 kernel32 C_SRCS = \ msiexec.c diff --git a/programs/msiexec/msiexec.c b/programs/msiexec/msiexec.c index 2d2728c8e82..810dd70bcc8 100644 --- a/programs/msiexec/msiexec.c +++ b/programs/msiexec/msiexec.c @@ -25,7 +25,6 @@ #include #include #include -#include #include "wine/debug.h" #include "wine/unicode.h" @@ -211,6 +210,14 @@ static DWORD msi_atou(LPCWSTR str) return 0; } +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 */ static BOOL msi_strequal(LPCWSTR str1, LPCSTR str2) { @@ -366,6 +373,97 @@ static INT DoEmbedding( LPWSTR key ) return 1; } +/* + * state machine to break up the command line properly + */ + +enum chomp_state +{ + cs_whitespace, + cs_token, + cs_quote +}; + +static int chomp( WCHAR *str ) +{ + enum chomp_state state = cs_whitespace; + WCHAR *p, *out; + int count = 0, ignore; + + for( p = str, out = str; *p; p++ ) + { + ignore = 1; + switch( state ) + { + case cs_whitespace: + switch( *p ) + { + case ' ': + break; + case '"': + state = cs_quote; + count++; + break; + default: + count++; + ignore = 0; + state = cs_token; + } + break; + + case cs_token: + switch( *p ) + { + case '"': + state = cs_quote; + break; + case ' ': + state = cs_whitespace; + *out++ = 0; + break; + default: + ignore = 0; + } + break; + + case cs_quote: + switch( *p ) + { + case '"': + state = cs_token; + break; + default: + ignore = 0; + } + break; + } + if( !ignore ) + *out++ = *p; + } + + *out = 0; + + return count; +} + +static void process_args( WCHAR *cmdline, int *pargc, WCHAR ***pargv ) +{ + WCHAR **argv, *p = msi_strdup(cmdline); + int i, n; + + n = chomp( p ); + argv = HeapAlloc(GetProcessHeap(), 0, sizeof (WCHAR*)*(n+1)); + for( i=0; i