Current implementation handles correctly % only at the end of the string. Nothing else matches.
The new implementation while naïve and recursive handles both _ and * correctly.
-- v3: wbemprox: Reimplement LIKE. wbemprox/tests: Test LIKE queries.
From: Arkadiusz Hiler ahiler@codeweavers.com
--- dlls/wbemprox/tests/query.c | 79 +++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+)
diff --git a/dlls/wbemprox/tests/query.c b/dlls/wbemprox/tests/query.c index 825ad2459f5..fb173f5d6f4 100644 --- a/dlls/wbemprox/tests/query.c +++ b/dlls/wbemprox/tests/query.c @@ -140,6 +140,84 @@ static void test_select( IWbemServices *services ) SysFreeString( query ); }
+static void check_explorer_like_query( IWbemServices *services, const WCHAR *str, BOOL expect_success, BOOL todo) +{ + HRESULT hr; + IWbemClassObject *obj[2]; + BSTR wql = SysAllocString( L"wql" ), query = SysAllocString( str ); + LONG flags = WBEM_FLAG_RETURN_IMMEDIATELY | WBEM_FLAG_FORWARD_ONLY; + ULONG count; + IEnumWbemClassObject *result; + + hr = IWbemServices_ExecQuery( services, wql, query, flags, NULL, &result ); + if (hr == S_OK) + { + VARIANT var; + IEnumWbemClassObject_Next( result, 10000, 2, obj, &count ); + + todo_wine_if(todo) + ok( count == (expect_success ? 1 : 0), "expected to get %d results but got %lu\n", + (expect_success ? 1 : 0), count); + + if (count) + { + BSTR caption; + hr = IWbemClassObject_Get( obj[0], L"Caption", 0, &var, NULL, NULL ); + ok( hr == WBEM_S_NO_ERROR, "IWbemClassObject_Get failed %#lx", hr); + caption = V_BSTR(&var); + ok( !wcscmp( caption, L"explorer.exe" ), "%s is not explorer.exe\n", debugstr_w(caption)); + VariantClear( &var ); + } + + while (count--) + IWbemClassObject_Release( obj[count] ); + } + + SysFreeString( wql ); + SysFreeString( query ); +} + + +static void test_like_query( IWbemServices *services ) +{ + int i; + WCHAR query[250]; + + struct { + BOOL todo; + BOOL expect_success; + const WCHAR *str; + } queries[] = { + { FALSE, TRUE, L"explorer%" }, + { FALSE, FALSE, L"xplorer.exe" }, + { TRUE, FALSE, L"explorer.ex" }, + { FALSE, TRUE, L"%explorer%" }, + { FALSE, TRUE, L"explorer.exe%" }, + { FALSE, TRUE, L"%explorer.exe%" }, + { TRUE, TRUE, L"%plorer.exe" }, + { TRUE, TRUE, L"%plorer.exe%" }, + { TRUE, TRUE, L"__plorer.exe" }, + { TRUE, TRUE, L"e_plorer.exe" }, + { FALSE, FALSE, L"_plorer.exe" }, + { TRUE, TRUE, L"%%%plorer.e%" }, + { TRUE, TRUE, L"%plorer.e%" }, + { TRUE, TRUE, L"%plorer.e_e" }, + { TRUE, TRUE, L"%plorer.e_e" }, + { TRUE, TRUE, L"explore%exe" }, + { FALSE, FALSE, L"fancy_explore.exe" }, + { FALSE, FALSE, L"fancy%xplore%exe" }, + { FALSE, FALSE, L"%%%f%xplore%exe" }, + }; + + for (i = 0; i < ARRAYSIZE(queries); i++) + { + wsprintfW( query, L"SELECT * FROM Win32_Process WHERE Caption LIKE '%ls'", queries[i].str ); + trace("%s\n", wine_dbgstr_w(query)); + check_explorer_like_query( services, query, queries[i].expect_success, queries[i].todo ); + } +} + + static void test_associators( IWbemServices *services ) { static const WCHAR *test[] = @@ -2366,6 +2444,7 @@ START_TEST(query) test_query_async( services ); test_query_semisync( services ); test_select( services ); + test_like_query( services );
/* classes */ test_SoftwareLicensingProduct( services );
From: Arkadiusz Hiler ahiler@codeweavers.com
Current implementation handles correctly % only at the end of the string. Nothing else matches.
The new implementation while naïve and recursive handles both _ and * correctly. --- dlls/wbemprox/query.c | 29 ++++++++++++++---------- dlls/wbemprox/tests/query.c | 44 ++++++++++++++++++------------------- 2 files changed, 39 insertions(+), 34 deletions(-)
diff --git a/dlls/wbemprox/query.c b/dlls/wbemprox/query.c index 1087e271837..d7990305003 100644 --- a/dlls/wbemprox/query.c +++ b/dlls/wbemprox/query.c @@ -93,23 +93,30 @@ void destroy_view( struct view *view ) free( view ); }
-static BOOL eval_like( const WCHAR *lstr, const WCHAR *rstr ) +static BOOL eval_like( const WCHAR *text, const WCHAR *pattern ) { - const WCHAR *p = lstr, *q = rstr; + if (wcsstr( pattern, L"[" )) FIXME( "character ranges (i.e. [abc], [^a-z]) are not supported\n" );
- while (*p && *q) + while (*text) { - if (q[0] == '\' && q[1] == '\') q++; - if (*q == '%') + if (pattern[0] == '\' && pattern[1] == '\') pattern++; + + if (*pattern == '%') { - while (*q == '%') q++; - if (!*q) return TRUE; - while (*p && *q && towupper( *p ) == towupper( *q )) { p++; q++; }; - if (!*p && !*q) return TRUE; + while (*pattern == '%') pattern++; + if (!*pattern) return TRUE; + while (!eval_like( text, pattern ) && *text) text++; + + return !!*text; } - if (*q != '%' && towupper( *p++ ) != towupper( *q++ )) return FALSE; + + if (*pattern != '_' && towupper( *text ) != towupper( *pattern )) return FALSE; + text++; pattern++; } - return TRUE; + + while (*pattern == '%') pattern++; + + return *pattern == '\0'; }
static HRESULT eval_strcmp( UINT op, const WCHAR *lstr, const WCHAR *rstr, LONGLONG *val ) diff --git a/dlls/wbemprox/tests/query.c b/dlls/wbemprox/tests/query.c index fb173f5d6f4..f5a3c2a14cd 100644 --- a/dlls/wbemprox/tests/query.c +++ b/dlls/wbemprox/tests/query.c @@ -140,7 +140,7 @@ static void test_select( IWbemServices *services ) SysFreeString( query ); }
-static void check_explorer_like_query( IWbemServices *services, const WCHAR *str, BOOL expect_success, BOOL todo) +static void check_explorer_like_query( IWbemServices *services, const WCHAR *str, BOOL expect_success) { HRESULT hr; IWbemClassObject *obj[2]; @@ -155,7 +155,6 @@ static void check_explorer_like_query( IWbemServices *services, const WCHAR *str VARIANT var; IEnumWbemClassObject_Next( result, 10000, 2, obj, &count );
- todo_wine_if(todo) ok( count == (expect_success ? 1 : 0), "expected to get %d results but got %lu\n", (expect_success ? 1 : 0), count);
@@ -184,36 +183,35 @@ static void test_like_query( IWbemServices *services ) WCHAR query[250];
struct { - BOOL todo; BOOL expect_success; const WCHAR *str; } queries[] = { - { FALSE, TRUE, L"explorer%" }, - { FALSE, FALSE, L"xplorer.exe" }, - { TRUE, FALSE, L"explorer.ex" }, - { FALSE, TRUE, L"%explorer%" }, - { FALSE, TRUE, L"explorer.exe%" }, - { FALSE, TRUE, L"%explorer.exe%" }, - { TRUE, TRUE, L"%plorer.exe" }, - { TRUE, TRUE, L"%plorer.exe%" }, - { TRUE, TRUE, L"__plorer.exe" }, - { TRUE, TRUE, L"e_plorer.exe" }, - { FALSE, FALSE, L"_plorer.exe" }, - { TRUE, TRUE, L"%%%plorer.e%" }, - { TRUE, TRUE, L"%plorer.e%" }, - { TRUE, TRUE, L"%plorer.e_e" }, - { TRUE, TRUE, L"%plorer.e_e" }, - { TRUE, TRUE, L"explore%exe" }, - { FALSE, FALSE, L"fancy_explore.exe" }, - { FALSE, FALSE, L"fancy%xplore%exe" }, - { FALSE, FALSE, L"%%%f%xplore%exe" }, + { TRUE, L"explorer%" }, + { FALSE, L"xplorer.exe" }, + { FALSE, L"explorer.ex" }, + { TRUE, L"%explorer%" }, + { TRUE, L"explorer.exe%" }, + { TRUE, L"%explorer.exe%" }, + { TRUE, L"%plorer.exe" }, + { TRUE, L"%plorer.exe%" }, + { TRUE, L"__plorer.exe" }, + { TRUE, L"e_plorer.exe" }, + { FALSE, L"_plorer.exe" }, + { TRUE, L"%%%plorer.e%" }, + { TRUE, L"%plorer.e%" }, + { TRUE, L"%plorer.e_e" }, + { TRUE, L"%plorer.e_e" }, + { TRUE, L"explore%exe" }, + { FALSE, L"fancy_explore.exe" }, + { FALSE, L"fancy%xplore%exe" }, + { FALSE, L"%%%f%xplore%exe" }, };
for (i = 0; i < ARRAYSIZE(queries); i++) { wsprintfW( query, L"SELECT * FROM Win32_Process WHERE Caption LIKE '%ls'", queries[i].str ); trace("%s\n", wine_dbgstr_w(query)); - check_explorer_like_query( services, query, queries[i].expect_success, queries[i].todo ); + check_explorer_like_query( services, query, queries[i].expect_success ); } }
my bad, forgot to commit the todo removal
all should be good now
This merge request was approved by Hans Leidekker.