https://git.reactos.org/?p=reactos.git;a=commitdiff;h=0c6498fa67f32d83ccf55…
commit 0c6498fa67f32d83ccf5505f2dc9ac6e5c1c2541
Author: Amine Khaldi <amine.khaldi(a)reactos.org>
AuthorDate: Sun Oct 8 09:33:23 2017 +0100
[MSIEXEC] Sync with Wine Staging 2.16. CORE-13762
d73c38f msiexec: Fix parsing of command lines where quoted strings and properties are
not separated by whitespace.
---
base/system/msiexec/msiexec.c | 169 ++++++++++++++++++++++--------------------
media/doc/README.WINE | 2 +-
2 files changed, 88 insertions(+), 83 deletions(-)
diff --git a/base/system/msiexec/msiexec.c b/base/system/msiexec/msiexec.c
index 44f1f28862..f2155622de 100644
--- a/base/system/msiexec/msiexec.c
+++ b/base/system/msiexec/msiexec.c
@@ -212,14 +212,6 @@ static DWORD msi_atou(LPCWSTR str)
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 */
static BOOL msi_strequal(LPCWSTR str1, LPCSTR str2)
{
@@ -409,90 +401,103 @@ static INT DoEmbedding( LPWSTR key )
enum chomp_state
{
- cs_whitespace,
- cs_token,
- cs_quote
+ CS_WHITESPACE,
+ CS_TOKEN,
+ CS_QUOTE
};
-static int chomp( WCHAR *str )
+static int chomp( const WCHAR *in, WCHAR *out )
{
- enum chomp_state state = cs_token;
- WCHAR *p, *out;
- int count = 1;
- BOOL ignore;
-
- for( p = str, out = str; *p; p++ )
- {
- ignore = TRUE;
- switch( state )
- {
- case cs_whitespace:
- switch( *p )
- {
- case ' ':
- break;
- case '"':
- state = cs_quote;
- count++;
- break;
- default:
- count++;
- ignore = FALSE;
- state = cs_token;
- }
- break;
-
- case cs_token:
- switch( *p )
- {
- case '"':
- state = cs_quote;
- break;
- case ' ':
- state = cs_whitespace;
- *out++ = 0;
- break;
- default:
- ignore = FALSE;
- }
- break;
-
- case cs_quote:
- switch( *p )
- {
- case '"':
- state = cs_token;
- break;
- default:
- ignore = FALSE;
- }
- break;
- }
- if( !ignore )
- *out++ = *p;
- }
-
- *out = 0;
+ enum chomp_state state = CS_TOKEN;
+ const WCHAR *p;
+ int count = 1;
+ BOOL ignore;
- return count;
+ for (p = in; *p; p++)
+ {
+ ignore = TRUE;
+ switch (state)
+ {
+ case CS_WHITESPACE:
+ switch (*p)
+ {
+ case ' ':
+ break;
+ case '"':
+ state = CS_QUOTE;
+ count++;
+ break;
+ default:
+ count++;
+ ignore = FALSE;
+ state = CS_TOKEN;
+ }
+ break;
+
+ case CS_TOKEN:
+ switch (*p)
+ {
+ case '"':
+ state = CS_QUOTE;
+ break;
+ case ' ':
+ state = CS_WHITESPACE;
+ if (out) *out++ = 0;
+ break;
+ default:
+ if (p > in && p[-1] == '"')
+ {
+ if (out) *out++ = 0;
+ count++;
+ }
+ ignore = FALSE;
+ }
+ break;
+
+ case CS_QUOTE:
+ switch (*p)
+ {
+ case '"':
+ state = CS_TOKEN;
+ break;
+ default:
+ ignore = FALSE;
+ }
+ break;
+ }
+ if (!ignore && out) *out++ = *p;
+ }
+ if (out) *out = 0;
+ return count;
}
static void process_args( WCHAR *cmdline, int *pargc, WCHAR ***pargv )
{
- WCHAR **argv, *p = msi_strdup(cmdline);
- int i, n;
+ WCHAR **argv, *p;
+ int i, count;
- 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 = 0;
+ *pargv = NULL;
+
+ count = chomp( cmdline, NULL );
+ 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 = n;
- *pargv = argv;
+ *pargc = count;
+ *pargv = argv;
}
static BOOL process_args_from_reg( const WCHAR *ident, int *pargc, WCHAR ***pargv )
diff --git a/media/doc/README.WINE b/media/doc/README.WINE
index 778f42f7b4..1eca9ef9cc 100644
--- a/media/doc/README.WINE
+++ b/media/doc/README.WINE
@@ -243,7 +243,7 @@ reactos/base/applications/wordpad # Synced to
WineStaging-1.9.16
reactos/base/applications/write # Synced to WineStaging-2.9
reactos/base/services/rpcss # Synced to WineStaging-1.9.16
reactos/base/system/expand # Synced to WineStaging-2.9
-reactos/base/system/msiexec # Synced to WineStaging-2.9
+reactos/base/system/msiexec # Synced to WineStaging-2.16
reactos/modules/rosapps/winfile # Autosync
In addition the following libs, dlls and source files are mostly based on code ported