Module: wine Branch: master Commit: bc52693f9a87142ed08228d8f23db9f18058ee9e URL: https://gitlab.winehq.org/wine/wine/-/commit/bc52693f9a87142ed08228d8f23db9f...
Author: Hans Leidekker hans@codeweavers.com Date: Tue Apr 2 14:57:59 2024 +0200
wmic: Handle multiple properties separated by whitespace.
---
programs/wmic/main.c | 103 +++++++++++++++++++++++++++------------------------ 1 file changed, 55 insertions(+), 48 deletions(-)
diff --git a/programs/wmic/main.c b/programs/wmic/main.c index 56c57ea45e9..f996d8018f4 100644 --- a/programs/wmic/main.c +++ b/programs/wmic/main.c @@ -107,62 +107,67 @@ static int output_newline( void ) return output_string( L"\n" ); }
-static WCHAR * strip_spaces(WCHAR *start) +static WCHAR *strip_spaces( WCHAR *start ) { - WCHAR *str = start, *end; - - while (*str == ' ') - str++; - - end = start + lstrlenW(start) - 1; - while (end >= start && *end == ' ') - { - *end = '\0'; - end--; - } - + WCHAR *str = start, *end = start + wcslen( start ) - 1; + while (*str == ' ') str++; + while (end >= start && *end == ' ') *end-- = 0; return str; }
-static HRESULT process_property_list( IWbemClassObject *obj, const WCHAR *proplist, WCHAR **ret ) +static HRESULT append_property( IWbemClassObject *obj, const WCHAR *prop, WCHAR *proplist ) { - WCHAR *p, *ctx, *ptr, *stripped; - HRESULT hr = S_OK; + HRESULT hr;
- if (!(p = wcsdup( proplist ))) return E_OUTOFMEMORY; + if (FAILED(hr = IWbemClassObject_Get( obj, prop, 0, NULL, NULL, NULL ))) return hr; + if (*proplist) wcscat( proplist, L"," ); + wcscat( proplist, prop ); + return S_OK; +}
- if (!(stripped = malloc( (wcslen( proplist ) + 1) * sizeof(**ret) ))) - { - free( p ); - return E_OUTOFMEMORY; - } +static HRESULT process_property_list( IWbemClassObject *obj, int argc, WCHAR *argv[], WCHAR **ret ) +{ + WCHAR *str = NULL, *ctx, *ptr, *stripped; + UINT i, len = 0; + HRESULT hr; + + for (i = 0; i < argc; i++) len += wcslen( argv[i] ); + if (!(stripped = malloc( (len + 1) * sizeof(*stripped) ))) return E_OUTOFMEMORY; *stripped = 0;
- /* Validate that every requested property is supported. */ - ptr = wcstok_s( p, L",", &ctx ); - while (ptr) + for (i = 0; i < argc; i++) { - ptr = strip_spaces( ptr ); + if (!(str = wcsdup( argv[i] ))) + { + free( stripped ); + return E_OUTOFMEMORY; + }
- if (FAILED(IWbemClassObject_Get( obj, ptr, 0, NULL, NULL, NULL ))) + /* Validate that every requested property is supported. */ + ptr = wcstok_s( str, L",", &ctx ); + if (!ptr) + { + ptr = strip_spaces( str ); + if (FAILED(hr = append_property( obj, ptr, stripped ))) goto error; + } + else { - hr = E_FAIL; - break; + while (ptr) + { + ptr = strip_spaces( ptr ); + if (FAILED(hr = append_property( obj, ptr, stripped ))) goto error; + ptr = wcstok_s( NULL, L",", &ctx ); + } } - if (*stripped) wcscat( stripped, L"," ); - wcscat( stripped, ptr ); - ptr = wcstok_s( NULL, L",", &ctx ); + free( str ); } - free( p );
- if (SUCCEEDED(hr)) - *ret = stripped; - else - { - free( stripped ); - *ret = NULL; - } + *ret = stripped; + return S_OK;
+error: + free( str ); + free( stripped ); return hr; }
@@ -218,7 +223,7 @@ done: WINE_FIXME( "Could not convert variant, vt %u.\n", vt ); }
-static int query_prop( const WCHAR *class, const WCHAR *propnames ) +static int query_prop( const WCHAR *class, int argc, WCHAR *argv[] ) { HRESULT hr; IWbemLocator *locator = NULL; @@ -231,8 +236,11 @@ static int query_prop( const WCHAR *class, const WCHAR *propnames ) IWbemClassObject *obj; ULONG count, width = 0; VARIANT v; + int i;
- WINE_TRACE("%s, %s\n", debugstr_w(class), debugstr_w(propnames)); + WINE_TRACE( "%s", debugstr_w(class) ); + for (i = 0; i < argc; i++) WINE_TRACE( " %s", debugstr_w(argv[i]) ); + WINE_TRACE( "\n" );
CoInitialize( NULL ); CoInitializeSecurity( NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_DEFAULT, @@ -256,7 +264,7 @@ static int query_prop( const WCHAR *class, const WCHAR *propnames ) }
/* Check that this class supports all requested properties. */ - hr = process_property_list( obj, propnames, &proplist ); + hr = process_property_list( obj, argc, argv, &proplist ); IWbemClassObject_Release( obj ); if (FAILED(hr)) { @@ -337,7 +345,7 @@ done:
static int process_args( int argc, WCHAR *argv[] ) { - const WCHAR *class, *value; + const WCHAR *class; int i;
for (i = 0; i < argc && argv[i][0] == '/'; i++) @@ -383,8 +391,7 @@ static int process_args( int argc, WCHAR *argv[] ) { if (++i >= argc) goto not_supported; - value = argv[i]; - return query_prop( class, value ); + return query_prop( class, argc - i, argv + i ); }
not_supported: @@ -403,14 +410,14 @@ int __cdecl wmain(int argc, WCHAR *argv[]) { fputws( L"wmic:root\cli>", stdout );
- while (fgetws(cmd, sizeof(cmd), stdin) != NULL) + while (fgetws( cmd, sizeof(cmd), stdin ) != NULL) { const WCHAR *stripped;
cmd[wcslen(cmd) - 1] = 0; /* remove trailing '\n' */ stripped = strip_spaces( cmd );
- WINE_TRACE("command: %s\n", debugstr_w(stripped)); + WINE_TRACE( "command: %s\n", debugstr_w(stripped) ); if (!wcsicmp( stripped, L"exit" ) || !wcsicmp( stripped, L"quit" )) return 0;