Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
d83b71eb
Commit
d83b71eb
authored
Jun 24, 2019
by
Hans Leidekker
Committed by
Alexandre Julliard
Jun 24, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
wbemprox: Add support for parsing ASSOCIATORS OF queries.
Signed-off-by:
Hans Leidekker
<
hans@codeweavers.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
7e14df06
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
179 additions
and
45 deletions
+179
-45
query.c
dlls/wbemprox/query.c
+8
-8
table.c
dlls/wbemprox/table.c
+1
-1
query.c
dlls/wbemprox/tests/query.c
+27
-4
wbemprox_private.h
dlls/wbemprox/wbemprox_private.h
+11
-2
wql.y
dlls/wbemprox/wql.y
+132
-30
No files found.
dlls/wbemprox/query.c
View file @
d83b71eb
...
...
@@ -30,17 +30,17 @@
WINE_DEFAULT_DEBUG_CHANNEL
(
wbemprox
);
HRESULT
create_view
(
const
struct
property
*
prop
list
,
const
WCHAR
*
class
,
const
struct
expr
*
cond
,
struct
view
**
ret
)
HRESULT
create_view
(
const
WCHAR
*
path
,
const
struct
keyword
*
keyword
list
,
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
->
p
roplist
=
proplist
;
view
->
table
=
grab_table
(
class
)
;
view
->
cond
=
cond
;
view
->
result
=
NULL
;
view
->
co
unt
=
0
;
view
->
p
ath
=
path
;
view
->
keywordlist
=
keywordlist
;
view
->
proplist
=
proplist
;
view
->
table
=
grab_table
(
class
)
;
view
->
co
nd
=
cond
;
*
ret
=
view
;
return
S_OK
;
}
...
...
dlls/wbemprox/table.c
View file @
d83b71eb
...
...
@@ -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
);
...
...
dlls/wbemprox/tests/query.c
View file @
d83b71eb
...
...
@@ -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
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
};
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
);
}
}
...
...
dlls/wbemprox/wbemprox_private.h
View file @
d83b71eb
...
...
@@ -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
;
...
...
dlls/wbemprox/wql.y
View file @
d83b71eb
...
...
@@ -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;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment