Module: wine Branch: master Commit: 4cc9ee7e6747a4df3c7b93c95eed4f8fcadbf8ec URL: https://gitlab.winehq.org/wine/wine/-/commit/4cc9ee7e6747a4df3c7b93c95eed4f8...
Author: Hans Leidekker hans@codeweavers.com Date: Fri Feb 23 13:37:46 2024 +0100
wbemprox: Handle implicit property in object path.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=55619
---
dlls/wbemprox/services.c | 54 ++++++++++++++++++++++++++++++++-------- dlls/wbemprox/table.c | 21 ++++++++++++++++ dlls/wbemprox/tests/query.c | 14 +++++++++-- dlls/wbemprox/wbemprox_private.h | 5 ++-- 4 files changed, 79 insertions(+), 15 deletions(-)
diff --git a/dlls/wbemprox/services.c b/dlls/wbemprox/services.c index 436097c1e8d..53b731d8b10 100644 --- a/dlls/wbemprox/services.c +++ b/dlls/wbemprox/services.c @@ -336,6 +336,14 @@ static HRESULT WINAPI wbem_services_QueryObjectSink( return WBEM_E_FAILED; }
+void free_path( struct path *path ) +{ + if (!path) return; + free( path->class ); + free( path->filter ); + free( path ); +} + HRESULT parse_path( const WCHAR *str, struct path **ret ) { struct path *path; @@ -391,7 +399,7 @@ HRESULT parse_path( const WCHAR *str, struct path **ret ) }
q = p; - while (*p && *p != '.') p++; + while (*p && *p != '.' && *p != '=') p++;
len = p - q; if (!(path->class = malloc( (len + 1) * sizeof(WCHAR) ))) @@ -411,26 +419,50 @@ HRESULT parse_path( const WCHAR *str, struct path **ret ) len = q - p; if (!(path->filter = malloc( (len + 1) * sizeof(WCHAR) ))) { - free( path->class ); - free( path ); + free_path( path ); return E_OUTOFMEMORY; } memcpy( path->filter, p, len * sizeof(WCHAR) ); path->filter[len] = 0; path->filter_len = len; } + else if (p[0] == '=' && p[1]) + { + WCHAR *key; + UINT len_key; + + while (*q) q++; + len = q - p; + + if (!(key = get_first_key_property( WBEMPROX_NAMESPACE_CIMV2, path->class ))) + { + free_path( path ); + return WBEM_E_INVALID_OBJECT_PATH; + } + len_key = wcslen( key ); + + if (!(path->filter = malloc( (len + len_key + 1) * sizeof(WCHAR) ))) + { + free( key ); + free_path( path ); + return E_OUTOFMEMORY; + } + wcscpy( path->filter, key ); + memcpy( path->filter + len_key, p, len * sizeof(WCHAR) ); + path->filter_len = len + len_key; + path->filter[path->filter_len] = 0; + free( key ); + } + else if (p[0]) + { + free_path( path ); + return WBEM_E_INVALID_OBJECT_PATH; + } + *ret = path; return S_OK; }
-void free_path( struct path *path ) -{ - if (!path) return; - free( path->class ); - free( path->filter ); - free( path ); -} - WCHAR *query_from_path( const struct path *path ) { static const WCHAR selectW[] = L"SELECT * FROM %s WHERE %s"; diff --git a/dlls/wbemprox/table.c b/dlls/wbemprox/table.c index 67f57878ea5..573cf035245 100644 --- a/dlls/wbemprox/table.c +++ b/dlls/wbemprox/table.c @@ -449,3 +449,24 @@ BSTR get_method_name( enum wbm_namespace ns, const WCHAR *class, UINT index ) release_table( table ); return NULL; } + +WCHAR *get_first_key_property( enum wbm_namespace ns, const WCHAR *class ) +{ + struct table *table; + WCHAR *ret = NULL; + UINT i; + + if (!(table = find_table( ns, class ))) return NULL; + + for (i = 0; i < table->num_cols; i++) + { + if (table->columns[i].type & COL_FLAG_KEY) + { + ret = wcsdup( table->columns[i].name ); + break; + } + } + + release_table( table ); + return ret; +} diff --git a/dlls/wbemprox/tests/query.c b/dlls/wbemprox/tests/query.c index f5a3c2a14cd..f06e0a431ea 100644 --- a/dlls/wbemprox/tests/query.c +++ b/dlls/wbemprox/tests/query.c @@ -2286,8 +2286,7 @@ static void test_SystemRestore( IWbemServices *services )
static void test_Win32_LogicalDisk( IWbemServices *services ) { - BSTR wql = SysAllocString( L"wql" ); - BSTR query = SysAllocString( L"SELECT * FROM Win32_LogicalDisk" ); + BSTR wql = SysAllocString( L"wql" ), query = SysAllocString( L"SELECT * FROM Win32_LogicalDisk" ); IEnumWbemClassObject *result; IWbemClassObject *obj; HRESULT hr; @@ -2329,6 +2328,17 @@ static void test_Win32_LogicalDisk( IWbemServices *services ) IWbemClassObject_Release( obj ); IEnumWbemClassObject_Release( result ); SysFreeString( query ); + + query = SysAllocString( L"Win32_LogicalDisk = "C:"" ); + hr = IWbemServices_GetObject( services, query, 0, NULL, &obj, NULL ); + ok( hr == WBEM_E_INVALID_OBJECT_PATH, "got %#lx\n", hr ); + SysFreeString( query ); + + query = SysAllocString( L"Win32_LogicalDisk="C:"" ); + hr = IWbemServices_GetObject( services, query, 0, NULL, &obj, NULL ); + ok( hr == S_OK, "got %#lx\n", hr ); + IWbemClassObject_Release( obj ); + SysFreeString( query ); SysFreeString( wql ); }
diff --git a/dlls/wbemprox/wbemprox_private.h b/dlls/wbemprox/wbemprox_private.h index 8e065bee0b9..655e3db27c2 100644 --- a/dlls/wbemprox/wbemprox_private.h +++ b/dlls/wbemprox/wbemprox_private.h @@ -241,8 +241,9 @@ VARTYPE to_vartype( CIMTYPE ); void destroy_array( struct array *, CIMTYPE ); BOOL is_result_prop( const struct view *, const WCHAR * ); HRESULT get_properties( const struct view *, UINT, LONG, SAFEARRAY ** ); -HRESULT get_object( enum wbm_namespace ns, const WCHAR *, IWbemClassObject ** ); -BSTR get_method_name( enum wbm_namespace ns, const WCHAR *, UINT ); +HRESULT get_object( enum wbm_namespace, const WCHAR *, IWbemClassObject ** ); +BSTR get_method_name( enum wbm_namespace, const WCHAR *, UINT ); +WCHAR *get_first_key_property( enum wbm_namespace, const WCHAR * ); void set_variant( VARTYPE, LONGLONG, void *, VARIANT * ); HRESULT create_signature( enum wbm_namespace ns, const WCHAR *, const WCHAR *, enum param_direction, IWbemClassObject ** );