Revert 7c35db07c35db0... msiexec: Use CommandLineToArgvW instead of process_args to reduce code duplication.
The previous command line processing is not identical to CommandLineToArgvW and CommandLineToArgvW breaks msi command line processing for things such as Excel Viewer 2003. Specifically the command line created by the Excel Viewer 2003 and passed to msiexec.exe is "c:\windows\system32\msiexec.exe" /I C:\windows\temp\IXP000.TMP\XLVIEW.MSI CDCACHE="2" LAUNCHEDFROMSETUP="1" SETUPEXEPATH="C:\windows\temp\IXP000.TMP\" SETUPEXENAME="SETUP.EXE" /lpiwaeo "C:\windows\temp\Microsoft Office Excel Viewer 2003 Setup(0001)_Task(0001).txt" CDCACH"...
This commit is contained in:
parent
592b53d0a4
commit
54c7b7e81b
|
@ -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
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
#include <msi.h>
|
||||
#include <objbase.h>
|
||||
#include <stdio.h>
|
||||
#include <shellapi.h>
|
||||
|
||||
#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<n; i++ )
|
||||
{
|
||||
argv[i] = p;
|
||||
p += lstrlenW(p) + 1;
|
||||
}
|
||||
argv[i] = NULL;
|
||||
|
||||
*pargc = n;
|
||||
*pargv = argv;
|
||||
}
|
||||
|
||||
static BOOL process_args_from_reg( LPWSTR ident, int *pargc, WCHAR ***pargv )
|
||||
{
|
||||
LONG r;
|
||||
|
@ -384,7 +482,7 @@ static BOOL process_args_from_reg( LPWSTR ident, int *pargc, WCHAR ***pargv )
|
|||
r = RegQueryValueExW(hkey, ident, 0, &type, (LPBYTE)buf, &sz);
|
||||
if( r == ERROR_SUCCESS )
|
||||
{
|
||||
*pargv = CommandLineToArgvW(buf, pargc);
|
||||
process_args(buf, pargc, pargv);
|
||||
ret = TRUE;
|
||||
}
|
||||
}
|
||||
|
@ -430,7 +528,7 @@ int main(int argc, char **argv)
|
|||
LPWSTR *argvW = NULL;
|
||||
|
||||
/* overwrite the command line */
|
||||
argvW = CommandLineToArgvW( GetCommandLineW(), &argc );
|
||||
process_args( GetCommandLineW(), &argc, &argvW );
|
||||
|
||||
/*
|
||||
* If the args begin with /@ IDENT then we need to load the real
|
||||
|
|
Loading…
Reference in New Issue