wbemprox: Add support for parsing ASSOCIATORS OF queries.
Signed-off-by: Hans Leidekker <hans@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
7e14df06f1
commit
d83b71ebfd
|
@ -30,17 +30,17 @@
|
|||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(wbemprox);
|
||||
|
||||
HRESULT create_view( const struct property *proplist, const WCHAR *class,
|
||||
const struct expr *cond, struct view **ret )
|
||||
HRESULT create_view( const WCHAR *path, const struct keyword *keywordlist, const WCHAR *class,
|
||||
const struct property *proplist, const struct expr *cond, struct view **ret )
|
||||
{
|
||||
struct view *view = heap_alloc( sizeof(struct view) );
|
||||
struct view *view = heap_alloc_zero( sizeof(*view) );
|
||||
|
||||
if (!view) return E_OUTOFMEMORY;
|
||||
view->proplist = proplist;
|
||||
view->table = grab_table( class );
|
||||
view->cond = cond;
|
||||
view->result = NULL;
|
||||
view->count = 0;
|
||||
view->path = path;
|
||||
view->keywordlist = keywordlist;
|
||||
view->proplist = proplist;
|
||||
view->table = grab_table( class );
|
||||
view->cond = cond;
|
||||
*ret = view;
|
||||
return S_OK;
|
||||
}
|
||||
|
|
|
@ -357,7 +357,7 @@ struct table *grab_table( const WCHAR *name )
|
|||
|
||||
LIST_FOR_EACH_ENTRY( table, table_list, struct table, entry )
|
||||
{
|
||||
if (!strcmpiW( table->name, name ))
|
||||
if (name && !strcmpiW( table->name, name ))
|
||||
{
|
||||
TRACE("returning %p\n", table);
|
||||
return addref_table( table );
|
||||
|
|
|
@ -156,14 +156,37 @@ static void test_select( IWbemServices *services )
|
|||
static void test_associators( IWbemServices *services )
|
||||
{
|
||||
static const WCHAR query1[] =
|
||||
{'A','S','S','O','C','I','A','T','O','R','S',' ','O','F',' ','{','W','i','n','3','2','_',
|
||||
{'A','S','S','O','C','I','A','T','O','R','S',' ',' ','O','F','{','W','i','n','3','2','_',
|
||||
'L','o','g','i','c','a','l','D','i','s','k','.','D','e','v','i','c','e','I','D','=','"','C',':','"','}',0};
|
||||
static const WCHAR query2[] =
|
||||
{'A','S','S','O','C','I','A','T','O','R','S',' ','O','F',' ','{','W','i','n','3','2','_',
|
||||
'L','o','g','i','c','a','l','D','i','s','k','.','D','e','v','i','c','e','I','D','=','"','C',':','"','}',' ',
|
||||
'W','H','E','R','E',' ','A','s','s','o','c','C','l','a','s','s',' ','=',' ','W','i','n','3','2','_',
|
||||
'W','H','E','R','E',' ','A','s','s','o','c','C','l','a','s','s','=','W','i','n','3','2','_',
|
||||
'L','o','g','i','c','a','l','D','i','s','k','T','o','P','a','r','t','i','t','i','o','n',0};
|
||||
static const WCHAR *test[] = { query1, query2 };
|
||||
static const WCHAR query3[] =
|
||||
{'A','S','S','O','C','I','A','T','O','R','S',' ',' ','O','F',' ','{','W','i','n','3','2','_',
|
||||
'L','o','g','i','c','a','l','D','i','s','k','.','D','e','v','i','c','e','I','D','}',0};
|
||||
static const WCHAR query4[] =
|
||||
{'A','S','S','O','C','I','A','T','O','R','S',' ',' ','O','F',' ','{','W','i','n','3','2','_',
|
||||
'D','i','s','k','D','r','i','v','e','.','D','e','v','i','c','e','I','D','=',
|
||||
'\'','\\','\\','.','\\','P','H','Y','S','I','C','A','L','D','R','I','V','E','0','\'','}',0};
|
||||
static const WCHAR query5[] =
|
||||
{'A','S','S','O','C','I','A','T','O','R','S',' ','O','F',' ','{','W','i','n','3','2','_',
|
||||
'L','o','g','i','c','a','l','D','i','s','k','.','D','e','v','i','c','e','I','D','=','"','C',':','"','}',' ',
|
||||
'W','H','E','R','E',' ','A','s','s','o','c','C','l','a','s','s','=','W','i','n','3','2','_',
|
||||
'L','o','g','i','c','a','l','D','i','s','k','T','o','P','a','r','t','i','t','i','o','n',' ',
|
||||
'C','l','a','s','s','D','e','f','s','O','n','l','y',0};
|
||||
static const WCHAR query6[] =
|
||||
{'A','S','S','O','C','I','A','T','O','R','S',' ','O','F',' ','{','W','i','n','3','2','_',
|
||||
'L','o','g','i','c','a','l','D','i','s','k','.','D','e','v','i','c','e','I','D','=','"','C',':','"','}',' ',
|
||||
'W','H','E','R','E',' ','C','l','a','s','s','D','e','f','s','O','n','l','y',0};
|
||||
static const WCHAR query7[] =
|
||||
{'A','S','S','O','C','I','A','T','O','R','S',' ','O','F',' ','{','W','i','n','3','2','_',
|
||||
'L','o','g','i','c','a','l','D','i','s','k','.','D','e','v','i','c','e','I','D','=','"','C',':','"','}',' ',
|
||||
'W','H','E','R','E',' ','C','l','a','s','s','D','e','f','s','O','n','l','y',' ',
|
||||
'A','s','s','o','c','C','l','a','s','s',' ','=',' ','W','i','n','3','2','_',
|
||||
'L','o','g','i','c','a','l','D','i','s','k','T','o','P','a','r','t','i','t','i','o','n',0};
|
||||
static const WCHAR *test[] = { query1, query2, query3, query4, query5, query6, query7 };
|
||||
HRESULT hr;
|
||||
IEnumWbemClassObject *result;
|
||||
UINT i;
|
||||
|
@ -171,7 +194,7 @@ static void test_associators( IWbemServices *services )
|
|||
for (i = 0; i < ARRAY_SIZE( test ); i++)
|
||||
{
|
||||
hr = exec_query( services, test[i], &result );
|
||||
todo_wine ok( hr == S_OK, "query %u failed: %08x\n", i, hr );
|
||||
ok( hr == S_OK, "query %u failed: %08x\n", i, hr );
|
||||
if (result) IEnumWbemClassObject_Release( result );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -148,8 +148,17 @@ struct record
|
|||
struct table *table;
|
||||
};
|
||||
|
||||
struct keyword
|
||||
{
|
||||
const WCHAR *name;
|
||||
const WCHAR *value;
|
||||
const struct keyword *next;
|
||||
};
|
||||
|
||||
struct view
|
||||
{
|
||||
const WCHAR *path; /* ASSOCIATORS OF query */
|
||||
const struct keyword *keywordlist;
|
||||
const struct property *proplist;
|
||||
struct table *table;
|
||||
const struct expr *cond;
|
||||
|
@ -170,8 +179,8 @@ struct query *addref_query( struct query * ) DECLSPEC_HIDDEN;
|
|||
void release_query( struct query *query ) DECLSPEC_HIDDEN;
|
||||
HRESULT exec_query( const WCHAR *, IEnumWbemClassObject ** ) DECLSPEC_HIDDEN;
|
||||
HRESULT parse_query( const WCHAR *, struct view **, struct list * ) DECLSPEC_HIDDEN;
|
||||
HRESULT create_view( const struct property *, const WCHAR *, const struct expr *,
|
||||
struct view ** ) DECLSPEC_HIDDEN;
|
||||
HRESULT create_view( const WCHAR *, const struct keyword *, const WCHAR *, const struct property *,
|
||||
const struct expr *, struct view ** ) DECLSPEC_HIDDEN;
|
||||
void destroy_view( struct view * ) DECLSPEC_HIDDEN;
|
||||
HRESULT execute_view( struct view * ) DECLSPEC_HIDDEN;
|
||||
void init_table_list( void ) DECLSPEC_HIDDEN;
|
||||
|
|
|
@ -67,6 +67,18 @@ static struct property *alloc_property( struct parser *parser, const WCHAR *clas
|
|||
return prop;
|
||||
}
|
||||
|
||||
static struct keyword *alloc_keyword( struct parser *parser, const WCHAR *name, const WCHAR *value )
|
||||
{
|
||||
struct keyword *keyword = alloc_mem( parser, sizeof(*keyword) );
|
||||
if (keyword)
|
||||
{
|
||||
keyword->name = name;
|
||||
keyword->value = value;
|
||||
keyword->next = NULL;
|
||||
}
|
||||
return keyword;
|
||||
}
|
||||
|
||||
static WCHAR *get_string( struct parser *parser, const struct string *str )
|
||||
{
|
||||
const WCHAR *p = str->data;
|
||||
|
@ -87,6 +99,18 @@ static WCHAR *get_string( struct parser *parser, const struct string *str )
|
|||
return ret;
|
||||
}
|
||||
|
||||
static WCHAR *get_path( struct parser *parser, const struct string *str )
|
||||
{
|
||||
const WCHAR *p = str->data;
|
||||
int len = str->len;
|
||||
WCHAR *ret;
|
||||
|
||||
if (!(ret = alloc_mem( parser, (len + 1) * sizeof(WCHAR) ))) return NULL;
|
||||
memcpy( ret, p, len * sizeof(WCHAR) );
|
||||
ret[len] = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int get_int( struct parser *parser )
|
||||
{
|
||||
const WCHAR *p = &parser->cmd[parser->idx];
|
||||
|
@ -195,28 +219,92 @@ static int wql_lex( void *val, struct parser *parser );
|
|||
struct string str;
|
||||
WCHAR *string;
|
||||
struct property *proplist;
|
||||
struct keyword *keywordlist;
|
||||
struct view *view;
|
||||
struct expr *expr;
|
||||
int integer;
|
||||
}
|
||||
|
||||
%token TK_SELECT TK_FROM TK_STAR TK_COMMA TK_DOT TK_IS TK_LP TK_RP TK_NULL TK_FALSE TK_TRUE
|
||||
%token TK_INTEGER TK_WHERE TK_SPACE TK_MINUS TK_ILLEGAL TK_BY
|
||||
%token <str> TK_STRING TK_ID
|
||||
%token TK_INTEGER TK_WHERE TK_SPACE TK_MINUS TK_ILLEGAL TK_BY TK_ASSOCIATORS TK_OF
|
||||
%token <str> TK_STRING TK_ID TK_PATH
|
||||
|
||||
%type <string> id
|
||||
%type <string> id path
|
||||
%type <proplist> prop proplist
|
||||
%type <view> select
|
||||
%type <keywordlist> keyword keywordlist
|
||||
%type <view> query select associatorsof
|
||||
%type <expr> expr prop_val const_val string_val
|
||||
%type <integer> number
|
||||
|
||||
%left TK_OR
|
||||
%left TK_AND
|
||||
%left TK_NOT
|
||||
%left TK_EQ TK_NE TK_LT TK_GT TK_LE TK_GE TK_LIKE
|
||||
%left TK_OR TK_AND TK_NOT TK_EQ TK_NE TK_LT TK_GT TK_LE TK_GE TK_LIKE
|
||||
|
||||
%%
|
||||
|
||||
query:
|
||||
select
|
||||
|
|
||||
associatorsof
|
||||
;
|
||||
|
||||
path:
|
||||
TK_PATH
|
||||
{
|
||||
$$ = get_path( ctx, &$1 );
|
||||
if (!$$)
|
||||
YYABORT;
|
||||
}
|
||||
;
|
||||
|
||||
keyword:
|
||||
id
|
||||
{
|
||||
$$ = alloc_keyword( ctx, $1, NULL );
|
||||
if (!$$)
|
||||
YYABORT;
|
||||
}
|
||||
| id TK_EQ id
|
||||
{
|
||||
$$ = alloc_keyword( ctx, $1, $3 );
|
||||
if (!$$)
|
||||
YYABORT;
|
||||
}
|
||||
;
|
||||
|
||||
keywordlist:
|
||||
keyword
|
||||
| keyword keywordlist
|
||||
{
|
||||
$1->next = $2;
|
||||
}
|
||||
;
|
||||
|
||||
associatorsof:
|
||||
TK_ASSOCIATORS TK_OF path
|
||||
{
|
||||
HRESULT hr;
|
||||
struct parser *parser = ctx;
|
||||
struct view *view;
|
||||
|
||||
hr = create_view( $3, NULL, NULL, NULL, NULL, &view );
|
||||
if (hr != S_OK)
|
||||
YYABORT;
|
||||
|
||||
PARSER_BUBBLE_UP_VIEW( parser, $$, view );
|
||||
}
|
||||
| TK_ASSOCIATORS TK_OF path TK_WHERE keywordlist
|
||||
{
|
||||
HRESULT hr;
|
||||
struct parser *parser = ctx;
|
||||
struct view *view;
|
||||
|
||||
hr = create_view( $3, $5, NULL, NULL, NULL, &view );
|
||||
if (hr != S_OK)
|
||||
YYABORT;
|
||||
|
||||
PARSER_BUBBLE_UP_VIEW( parser, $$, view );
|
||||
}
|
||||
;
|
||||
|
||||
select:
|
||||
TK_SELECT TK_FROM id
|
||||
{
|
||||
|
@ -224,7 +312,7 @@ select:
|
|||
struct parser *parser = ctx;
|
||||
struct view *view;
|
||||
|
||||
hr = create_view( NULL, $3, NULL, &view );
|
||||
hr = create_view( NULL, NULL, $3, NULL, NULL, &view );
|
||||
if (hr != S_OK)
|
||||
YYABORT;
|
||||
|
||||
|
@ -236,7 +324,7 @@ select:
|
|||
struct parser *parser = ctx;
|
||||
struct view *view;
|
||||
|
||||
hr = create_view( $2, $4, NULL, &view );
|
||||
hr = create_view( NULL, NULL, $4, $2, NULL, &view );
|
||||
if (hr != S_OK)
|
||||
YYABORT;
|
||||
|
||||
|
@ -248,7 +336,7 @@ select:
|
|||
struct parser *parser = ctx;
|
||||
struct view *view;
|
||||
|
||||
hr = create_view( $2, $4, $6, &view );
|
||||
hr = create_view( NULL, NULL, $4, $2, $6, &view );
|
||||
if (hr != S_OK)
|
||||
YYABORT;
|
||||
|
||||
|
@ -535,16 +623,18 @@ static const char id_char[] =
|
|||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
};
|
||||
|
||||
struct keyword
|
||||
struct wql_keyword
|
||||
{
|
||||
const WCHAR *name;
|
||||
unsigned int len;
|
||||
int type;
|
||||
};
|
||||
|
||||
#define MAX_TOKEN_LEN 6
|
||||
#define MIN_TOKEN_LEN 2
|
||||
#define MAX_TOKEN_LEN 11
|
||||
|
||||
static const WCHAR andW[] = {'A','N','D'};
|
||||
static const WCHAR associatorsW[] = {'A','S','S','O','C','I','A','T','O','R','S'};
|
||||
static const WCHAR byW[] = {'B','Y'};
|
||||
static const WCHAR falseW[] = {'F','A','L','S','E'};
|
||||
static const WCHAR fromW[] = {'F','R','O','M'};
|
||||
|
@ -552,30 +642,33 @@ static const WCHAR isW[] = {'I','S'};
|
|||
static const WCHAR likeW[] = {'L','I','K','E'};
|
||||
static const WCHAR notW[] = {'N','O','T'};
|
||||
static const WCHAR nullW[] = {'N','U','L','L'};
|
||||
static const WCHAR ofW[] = {'O','F'};
|
||||
static const WCHAR orW[] = {'O','R'};
|
||||
static const WCHAR selectW[] = {'S','E','L','E','C','T'};
|
||||
static const WCHAR trueW[] = {'T','R','U','E'};
|
||||
static const WCHAR whereW[] = {'W','H','E','R','E'};
|
||||
|
||||
static const struct keyword keyword_table[] =
|
||||
static const struct wql_keyword keyword_table[] =
|
||||
{
|
||||
{ andW, ARRAY_SIZE(andW), TK_AND },
|
||||
{ byW, ARRAY_SIZE(byW), TK_BY },
|
||||
{ falseW, ARRAY_SIZE(falseW), TK_FALSE },
|
||||
{ fromW, ARRAY_SIZE(fromW), TK_FROM },
|
||||
{ isW, ARRAY_SIZE(isW), TK_IS },
|
||||
{ likeW, ARRAY_SIZE(likeW), TK_LIKE },
|
||||
{ notW, ARRAY_SIZE(notW), TK_NOT },
|
||||
{ nullW, ARRAY_SIZE(nullW), TK_NULL },
|
||||
{ orW, ARRAY_SIZE(orW), TK_OR },
|
||||
{ selectW, ARRAY_SIZE(selectW), TK_SELECT },
|
||||
{ trueW, ARRAY_SIZE(trueW), TK_TRUE },
|
||||
{ whereW, ARRAY_SIZE(whereW), TK_WHERE }
|
||||
{ andW, ARRAY_SIZE(andW), TK_AND },
|
||||
{ associatorsW, ARRAY_SIZE(associatorsW), TK_ASSOCIATORS },
|
||||
{ byW, ARRAY_SIZE(byW), TK_BY },
|
||||
{ falseW, ARRAY_SIZE(falseW), TK_FALSE },
|
||||
{ fromW, ARRAY_SIZE(fromW), TK_FROM },
|
||||
{ isW, ARRAY_SIZE(isW), TK_IS },
|
||||
{ likeW, ARRAY_SIZE(likeW), TK_LIKE },
|
||||
{ notW, ARRAY_SIZE(notW), TK_NOT },
|
||||
{ nullW, ARRAY_SIZE(nullW), TK_NULL },
|
||||
{ ofW, ARRAY_SIZE(ofW), TK_OF },
|
||||
{ orW, ARRAY_SIZE(orW), TK_OR },
|
||||
{ selectW, ARRAY_SIZE(selectW), TK_SELECT },
|
||||
{ trueW, ARRAY_SIZE(trueW), TK_TRUE },
|
||||
{ whereW, ARRAY_SIZE(whereW), TK_WHERE }
|
||||
};
|
||||
|
||||
static int cmp_keyword( const void *arg1, const void *arg2 )
|
||||
{
|
||||
const struct keyword *key1 = arg1, *key2 = arg2;
|
||||
const struct wql_keyword *key1 = arg1, *key2 = arg2;
|
||||
int len = min( key1->len, key2->len );
|
||||
int ret;
|
||||
|
||||
|
@ -587,14 +680,14 @@ static int cmp_keyword( const void *arg1, const void *arg2 )
|
|||
|
||||
static int keyword_type( const WCHAR *str, unsigned int len )
|
||||
{
|
||||
struct keyword key, *ret;
|
||||
struct wql_keyword key, *ret;
|
||||
|
||||
if (len > MAX_TOKEN_LEN) return TK_ID;
|
||||
if (len < MIN_TOKEN_LEN || len > MAX_TOKEN_LEN) return TK_ID;
|
||||
|
||||
key.name = str;
|
||||
key.len = len;
|
||||
key.type = 0;
|
||||
ret = bsearch( &key, keyword_table, ARRAY_SIZE(keyword_table), sizeof(struct keyword), cmp_keyword );
|
||||
ret = bsearch( &key, keyword_table, ARRAY_SIZE(keyword_table), sizeof(struct wql_keyword), cmp_keyword );
|
||||
if (ret) return ret->type;
|
||||
return TK_ID;
|
||||
}
|
||||
|
@ -622,6 +715,15 @@ static int get_token( const WCHAR *s, int *token )
|
|||
case ')':
|
||||
*token = TK_RP;
|
||||
return 1;
|
||||
case '{':
|
||||
for (i = 1; s[i] && s[i] != '}'; i++) {}
|
||||
if (s[i] != '}')
|
||||
{
|
||||
*token = TK_ILLEGAL;
|
||||
return i;
|
||||
}
|
||||
*token = TK_PATH;
|
||||
return i + 1;
|
||||
case '*':
|
||||
*token = TK_STAR;
|
||||
return 1;
|
||||
|
|
Loading…
Reference in New Issue