From: Hans Leidekker hans@codeweavers.com
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 ** );
David Kahurani (@kahurani) commented about dlls/wbemprox/services.c:
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;
- }
This notably changes the behaviour of existing code without corresponding tests. Just noting, not being very familiar with wbemprox myself.
On Mon Feb 26 12:22:03 2024 +0000, David Kahurani wrote:
This notably changes the behaviour of existing code without corresponding tests. Just noting, not being very familiar with wbemprox myself.
If you mean returning WBEM_E_INVALID_OBJECT_PATH, I did add a test for it.
On Mon Feb 26 13:23:04 2024 +0000, Hans Leidekker wrote:
If you mean returning WBEM_E_INVALID_OBJECT_PATH, I did add a test for it.
I'm talking about the fact the '.' is getting ignored now. Could be it is not important in this case but it gets me thinking about domains.
On Mon Feb 26 17:16:56 2024 +0000, David Kahurani wrote:
I'm talking about the fact the '.' is getting ignored now. Could be it is not important in this case but it gets me thinking about domains.
Ooh, I am on the wrong. This is not the case. Your changes didn't change that. Sorry, I am a bit new to reviewing code.