[WBEMPROX]
[reactos.git] / rostests / winetests / wbemprox / query.c
1 /*
2 * Copyright 2012 Hans Leidekker for CodeWeavers
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17 */
18
19 #define COBJMACROS
20
21 #include <stdio.h>
22 #include "windows.h"
23 #include "ocidl.h"
24 #include "initguid.h"
25 #include "objidl.h"
26 #include "wbemcli.h"
27 #include "wine/test.h"
28
29 static const WCHAR wqlW[] = {'w','q','l',0};
30
31 static HRESULT exec_query( IWbemServices *services, const WCHAR *str, IEnumWbemClassObject **result )
32 {
33 static const WCHAR captionW[] = {'C','a','p','t','i','o','n',0};
34 static const WCHAR descriptionW[] = {'D','e','s','c','r','i','p','t','i','o','n',0};
35 HRESULT hr;
36 IWbemClassObject *obj;
37 BSTR wql = SysAllocString( wqlW ), query = SysAllocString( str );
38 LONG flags = WBEM_FLAG_RETURN_IMMEDIATELY | WBEM_FLAG_FORWARD_ONLY;
39 ULONG count;
40
41 hr = IWbemServices_ExecQuery( services, wql, query, flags, NULL, result );
42 if (hr == S_OK)
43 {
44 trace("%s\n", wine_dbgstr_w(str));
45 for (;;)
46 {
47 VARIANT var;
48
49 IEnumWbemClassObject_Next( *result, 10000, 1, &obj, &count );
50 if (!count) break;
51
52 if (IWbemClassObject_Get( obj, captionW, 0, &var, NULL, NULL ) == WBEM_S_NO_ERROR)
53 {
54 trace("caption: %s\n", wine_dbgstr_w(V_BSTR(&var)));
55 VariantClear( &var );
56 }
57 if (IWbemClassObject_Get( obj, descriptionW, 0, &var, NULL, NULL ) == WBEM_S_NO_ERROR)
58 {
59 trace("description: %s\n", wine_dbgstr_w(V_BSTR(&var)));
60 VariantClear( &var );
61 }
62 IWbemClassObject_Release( obj );
63 }
64 }
65 SysFreeString( wql );
66 SysFreeString( query );
67 return hr;
68 }
69
70 static void test_select( IWbemServices *services )
71 {
72 static const WCHAR emptyW[] = {0};
73 static const WCHAR sqlW[] = {'S','Q','L',0};
74 static const WCHAR query1[] =
75 {'S','E','L','E','C','T',' ','H','O','T','F','I','X','I','D',' ','F','R','O','M',' ',
76 'W','i','n','3','2','_','Q','u','i','c','k','F','i','x','E','n','g','i','n','e','e','r','i','n','g',0};
77 static const WCHAR query2[] =
78 {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','W','i','n','3','2','_','B','I','O','S',0};
79 static const WCHAR query3[] =
80 {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','W','i','n','3','2','_',
81 'L','o','g','i','c','a','l','D','i','s','k',' ','W','H','E','R','E',' ',
82 '\"','N','T','F','S','\"',' ','=',' ','F','i','l','e','S','y','s','t','e','m',0};
83 static const WCHAR query4[] =
84 {'S','E','L','E','C','T',' ','a',' ','F','R','O','M',' ','b',0};
85 static const WCHAR query5[] =
86 {'S','E','L','E','C','T',' ','a',' ','F','R','O','M',' ','W','i','n','3','2','_','B','i','o','s',0};
87 static const WCHAR query6[] =
88 {'S','E','L','E','C','T',' ','D','e','s','c','r','i','p','t','i','o','n',' ','F','R','O','M',' ',
89 'W','i','n','3','2','_','B','i','o','s',0};
90 static const WCHAR query7[] =
91 {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','W','i','n','3','2','_',
92 'P','r','o','c','e','s','s',' ','W','H','E','R','E',' ','C','a','p','t','i','o','n',' ',
93 'L','I','K','E',' ','\'','%','%','R','E','G','E','D','I','T','%','\'',0};
94 static const WCHAR query8[] =
95 {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','W','i','n','3','2','_',
96 'D','i','s','k','D','r','i','v','e',' ','W','H','E','R','E',' ','D','e','v','i','c','e','I','D','=',
97 '\"','\\','\\','\\','\\','.','\\','\\','P','H','Y','S','I','C','A','L','D','R','I','V','E','0','\"',0};
98 static const WCHAR *test[] = { query1, query2, query3, query4, query5, query6, query7, query8 };
99 HRESULT hr;
100 IEnumWbemClassObject *result;
101 BSTR wql = SysAllocString( wqlW );
102 BSTR sql = SysAllocString( sqlW );
103 BSTR query = SysAllocString( query1 );
104 UINT i;
105
106 hr = IWbemServices_ExecQuery( services, NULL, NULL, 0, NULL, &result );
107 ok( hr == WBEM_E_INVALID_PARAMETER, "query failed %08x\n", hr );
108
109 hr = IWbemServices_ExecQuery( services, NULL, query, 0, NULL, &result );
110 ok( hr == WBEM_E_INVALID_PARAMETER, "query failed %08x\n", hr );
111
112 hr = IWbemServices_ExecQuery( services, wql, NULL, 0, NULL, &result );
113 ok( hr == WBEM_E_INVALID_PARAMETER, "query failed %08x\n", hr );
114
115 hr = IWbemServices_ExecQuery( services, sql, query, 0, NULL, &result );
116 ok( hr == WBEM_E_INVALID_QUERY_TYPE, "query failed %08x\n", hr );
117
118 hr = IWbemServices_ExecQuery( services, sql, NULL, 0, NULL, &result );
119 ok( hr == WBEM_E_INVALID_PARAMETER, "query failed %08x\n", hr );
120
121 SysFreeString( query );
122 query = SysAllocString( emptyW );
123 hr = IWbemServices_ExecQuery( services, wql, query, 0, NULL, &result );
124 ok( hr == WBEM_E_INVALID_PARAMETER, "query failed %08x\n", hr );
125
126 for (i = 0; i < sizeof(test)/sizeof(test[0]); i++)
127 {
128 hr = exec_query( services, test[i], &result );
129 ok( hr == S_OK, "query %u failed: %08x\n", i, hr );
130 if (result) IEnumWbemClassObject_Release( result );
131 }
132
133 SysFreeString( wql );
134 SysFreeString( sql );
135 SysFreeString( query );
136 }
137
138 static void test_Win32_Service( IWbemServices *services )
139 {
140 static const WCHAR returnvalueW[] = {'R','e','t','u','r','n','V','a','l','u','e',0};
141 static const WCHAR pauseserviceW[] = {'P','a','u','s','e','S','e','r','v','i','c','e',0};
142 static const WCHAR resumeserviceW[] = {'R','e','s','u','m','e','S','e','r','v','i','c','e',0};
143 static const WCHAR startserviceW[] = {'S','t','a','r','t','S','e','r','v','i','c','e',0};
144 static const WCHAR stopserviceW[] = {'S','t','o','p','S','e','r','v','i','c','e',0};
145 static const WCHAR stateW[] = {'S','t','a','t','e',0};
146 static const WCHAR stoppedW[] = {'S','t','o','p','p','e','d',0};
147 static const WCHAR serviceW[] = {'W','i','n','3','2','_','S','e','r','v','i','c','e','.',
148 'N','a','m','e','=','"','S','p','o','o','l','e','r','"',0};
149 static const WCHAR emptyW[] = {0};
150 BSTR class = SysAllocString( serviceW ), empty = SysAllocString( emptyW ), method;
151 IWbemClassObject *service, *out;
152 VARIANT state, retval;
153 CIMTYPE type;
154 HRESULT hr;
155
156 hr = IWbemServices_GetObject( services, class, 0, NULL, &service, NULL );
157 if (hr != S_OK)
158 {
159 win_skip( "Win32_Service not available\n" );
160 return;
161 }
162 type = 0xdeadbeef;
163 VariantInit( &state );
164 hr = IWbemClassObject_Get( service, stateW, 0, &state, &type, NULL );
165 ok( hr == S_OK, "failed to get service state %08x\n", hr );
166 ok( V_VT( &state ) == VT_BSTR, "unexpected variant type 0x%x\n", V_VT( &state ) );
167 ok( type == CIM_STRING, "unexpected type 0x%x\n", type );
168
169 if (!lstrcmpW( V_BSTR( &state ), stoppedW ))
170 {
171 out = NULL;
172 method = SysAllocString( startserviceW );
173 hr = IWbemServices_ExecMethod( services, class, method, 0, NULL, NULL, &out, NULL );
174 ok( hr == S_OK, "failed to execute method %08x\n", hr );
175 SysFreeString( method );
176
177 VariantInit( &retval );
178 hr = IWbemClassObject_Get( out, returnvalueW, 0, &retval, NULL, NULL );
179 ok( hr == S_OK, "failed to get return value %08x\n", hr );
180 ok( !V_I4( &retval ), "unexpected error %u\n", V_UI4( &retval ) );
181 IWbemClassObject_Release( out );
182 }
183 out = NULL;
184 method = SysAllocString( pauseserviceW );
185 hr = IWbemServices_ExecMethod( services, class, method, 0, NULL, NULL, &out, NULL );
186 ok( hr == S_OK, "failed to execute method %08x\n", hr );
187 SysFreeString( method );
188
189 VariantInit( &retval );
190 hr = IWbemClassObject_Get( out, returnvalueW, 0, &retval, NULL, NULL );
191 ok( hr == S_OK, "failed to get return value %08x\n", hr );
192 ok( V_I4( &retval ), "unexpected success\n" );
193 IWbemClassObject_Release( out );
194
195 out = NULL;
196 method = SysAllocString( resumeserviceW );
197 hr = IWbemServices_ExecMethod( services, class, method, 0, NULL, NULL, &out, NULL );
198 ok( hr == S_OK, "failed to execute method %08x\n", hr );
199 SysFreeString( method );
200
201 VariantInit( &retval );
202 hr = IWbemClassObject_Get( out, returnvalueW, 0, &retval, NULL, NULL );
203 ok( hr == S_OK, "failed to get return value %08x\n", hr );
204 ok( V_I4( &retval ), "unexpected success\n" );
205 IWbemClassObject_Release( out );
206
207 if (!lstrcmpW( V_BSTR( &state ), stoppedW ))
208 {
209 out = NULL;
210 method = SysAllocString( stopserviceW );
211 hr = IWbemServices_ExecMethod( services, class, method, 0, NULL, NULL, &out, NULL );
212 ok( hr == S_OK, "failed to execute method %08x\n", hr );
213 SysFreeString( method );
214
215 VariantInit( &retval );
216 hr = IWbemClassObject_Get( out, returnvalueW, 0, &retval, NULL, NULL );
217 ok( hr == S_OK, "failed to get return value %08x\n", hr );
218 ok( !V_I4( &retval ), "unexpected error %u\n", V_UI4( &retval ) );
219 IWbemClassObject_Release( out );
220 }
221 VariantClear( &state );
222 IWbemClassObject_Release( service );
223
224 service = NULL;
225 hr = IWbemServices_GetObject( services, NULL, 0, NULL, &service, NULL );
226 ok( hr == S_OK, "got %08x\n", hr );
227 if (service) IWbemClassObject_Release( service );
228
229 service = NULL;
230 hr = IWbemServices_GetObject( services, empty, 0, NULL, &service, NULL );
231 ok( hr == S_OK, "got %08x\n", hr );
232 if (service) IWbemClassObject_Release( service );
233
234 SysFreeString( empty );
235 SysFreeString( class );
236 }
237
238 static void test_Win32_Process( IWbemServices *services )
239 {
240 static const WCHAR returnvalueW[] = {'R','e','t','u','r','n','V','a','l','u','e',0};
241 static const WCHAR getownerW[] = {'G','e','t','O','w','n','e','r',0};
242 static const WCHAR userW[] = {'U','s','e','r',0};
243 static const WCHAR domainW[] = {'D','o','m','a','i','n',0};
244 static const WCHAR processW[] = {'W','i','n','3','2','_','P','r','o','c','e','s','s',0};
245 static const WCHAR idW[] = {'I','D',0};
246 static const WCHAR fmtW[] = {'W','i','n','3','2','_','P','r','o','c','e','s','s','.',
247 'H','a','n','d','l','e','=','"','%','u','"',0};
248 static const LONG expected_flavor = WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE |
249 WBEM_FLAVOR_NOT_OVERRIDABLE |
250 WBEM_FLAVOR_ORIGIN_PROPAGATED;
251 BSTR class, method;
252 IWbemClassObject *process, *out;
253 IWbemQualifierSet *qualifiers;
254 VARIANT user, domain, retval, val;
255 LONG flavor;
256 CIMTYPE type;
257 HRESULT hr;
258
259 class = SysAllocString( processW );
260 hr = IWbemServices_GetObject( services, class, 0, NULL, &process, NULL );
261 SysFreeString( class );
262 if (hr != S_OK)
263 {
264 win_skip( "Win32_Process not available\n" );
265 return;
266 }
267 hr = IWbemClassObject_GetMethod( process, getownerW, 0, NULL, NULL );
268 ok( hr == S_OK, "failed to get GetOwner method %08x\n", hr );
269
270 out = NULL;
271 method = SysAllocString( getownerW );
272 class = SysAllocStringLen( NULL, sizeof(fmtW)/sizeof(fmtW[0]) + 10 );
273 wsprintfW( class, fmtW, GetCurrentProcessId() );
274 hr = IWbemServices_ExecMethod( services, class, method, 0, NULL, NULL, &out, NULL );
275 ok( hr == S_OK, "failed to execute method %08x\n", hr );
276 SysFreeString( method );
277 SysFreeString( class );
278
279 type = 0xdeadbeef;
280 VariantInit( &retval );
281 hr = IWbemClassObject_Get( out, returnvalueW, 0, &retval, &type, NULL );
282 ok( hr == S_OK, "failed to get return value %08x\n", hr );
283 ok( V_VT( &retval ) == VT_I4, "unexpected variant type 0x%x\n", V_VT( &retval ) );
284 ok( !V_I4( &retval ), "unexpected error %u\n", V_I4( &retval ) );
285 ok( type == CIM_UINT32, "unexpected type 0x%x\n", type );
286
287 type = 0xdeadbeef;
288 VariantInit( &user );
289 hr = IWbemClassObject_Get( out, userW, 0, &user, &type, NULL );
290 ok( hr == S_OK, "failed to get user %08x\n", hr );
291 ok( V_VT( &user ) == VT_BSTR, "unexpected variant type 0x%x\n", V_VT( &user ) );
292 ok( type == CIM_STRING, "unexpected type 0x%x\n", type );
293 trace("%s\n", wine_dbgstr_w(V_BSTR(&user)));
294
295 type = 0xdeadbeef;
296 VariantInit( &domain );
297 hr = IWbemClassObject_Get( out, domainW, 0, &domain, &type, NULL );
298 ok( hr == S_OK, "failed to get domain %08x\n", hr );
299 ok( V_VT( &domain ) == VT_BSTR, "unexpected variant type 0x%x\n", V_VT( &domain ) );
300 ok( type == CIM_STRING, "unexpected type 0x%x\n", type );
301 trace("%s\n", wine_dbgstr_w(V_BSTR(&domain)));
302
303 hr = IWbemClassObject_GetPropertyQualifierSet( out, userW, &qualifiers );
304 ok( hr == S_OK, "failed to get qualifier set %08x\n", hr );
305
306 flavor = -1;
307 V_I4(&val) = -1;
308 V_VT(&val) = VT_ERROR;
309 hr = IWbemQualifierSet_Get( qualifiers, idW, 0, &val, &flavor );
310 ok( hr == S_OK, "got %08x\n", hr );
311 ok( flavor == expected_flavor, "got %d\n", flavor );
312 ok( V_VT(&val) == VT_I4, "got %u\n", V_VT(&val) );
313 ok( V_I4(&val) == 0, "got %u\n", V_I4(&val) );
314 VariantClear( &val );
315
316 IWbemQualifierSet_Release( qualifiers );
317 hr = IWbemClassObject_GetPropertyQualifierSet( out, domainW, &qualifiers );
318 ok( hr == S_OK, "failed to get qualifier set %08x\n", hr );
319
320 flavor = -1;
321 V_I4(&val) = -1;
322 V_VT(&val) = VT_ERROR;
323 hr = IWbemQualifierSet_Get( qualifiers, idW, 0, &val, &flavor );
324 ok( hr == S_OK, "got %08x\n", hr );
325 ok( flavor == expected_flavor, "got %d\n", flavor );
326 ok( V_VT(&val) == VT_I4, "got %u\n", V_VT(&val) );
327 ok( V_I4(&val) == 1, "got %u\n", V_I4(&val) );
328 VariantClear( &val );
329
330 IWbemQualifierSet_Release( qualifiers );
331 hr = IWbemClassObject_GetPropertyQualifierSet( out, returnvalueW, &qualifiers );
332 ok( hr == S_OK, "failed to get qualifier set %08x\n", hr );
333
334 hr = IWbemQualifierSet_Get( qualifiers, idW, 0, &val, &flavor );
335 ok( hr == WBEM_E_NOT_FOUND, "got %08x\n", hr );
336
337 IWbemQualifierSet_Release( qualifiers );
338 VariantClear( &user );
339 VariantClear( &domain );
340 IWbemClassObject_Release( out );
341 }
342
343 static void test_StdRegProv( IWbemServices *services )
344 {
345 static const WCHAR enumkeyW[] = {'E','n','u','m','K','e','y',0};
346 static const WCHAR enumvaluesW[] = {'E','n','u','m','V','a','l','u','e','s',0};
347 static const WCHAR getstringvalueW[] = {'G','e','t','S','t','r','i','n','g','V','a','l','u','e',0};
348 static const WCHAR stdregprovW[] = {'S','t','d','R','e','g','P','r','o','v',0};
349 static const WCHAR defkeyW[] = {'h','D','e','f','K','e','y',0};
350 static const WCHAR subkeynameW[] = {'s','S','u','b','K','e','y','N','a','m','e',0};
351 static const WCHAR returnvalueW[] = {'R','e','t','u','r','n','V','a','l','u','e',0};
352 static const WCHAR namesW[] = {'s','N','a','m','e','s',0};
353 static const WCHAR typesW[] = {'T','y','p','e','s',0};
354 static const WCHAR valueW[] = {'s','V','a','l','u','e',0};
355 static const WCHAR valuenameW[] = {'s','V','a','l','u','e','N','a','m','e',0};
356 static const WCHAR programfilesW[] = {'P','r','o','g','r','a','m','F','i','l','e','s','D','i','r',0};
357 static const WCHAR windowsW[] =
358 {'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
359 'W','i','n','d','o','w','s','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n',0};
360 BSTR class = SysAllocString( stdregprovW ), method;
361 IWbemClassObject *reg, *sig_in, *in, *out;
362 VARIANT defkey, subkey, retval, names, types, value, valuename;
363 CIMTYPE type;
364 HRESULT hr;
365
366 hr = IWbemServices_GetObject( services, class, 0, NULL, &reg, NULL );
367 if (hr != S_OK)
368 {
369 win_skip( "StdRegProv not available\n" );
370 return;
371 }
372 hr = IWbemClassObject_GetMethod( reg, enumkeyW, 0, &sig_in, NULL );
373 ok( hr == S_OK, "failed to get EnumKey method %08x\n", hr );
374
375 hr = IWbemClassObject_SpawnInstance( sig_in, 0, &in );
376 ok( hr == S_OK, "failed to spawn instance %08x\n", hr );
377
378 V_VT( &defkey ) = VT_I4;
379 V_I4( &defkey ) = 0x80000002;
380 hr = IWbemClassObject_Put( in, defkeyW, 0, &defkey, 0 );
381 ok( hr == S_OK, "failed to set root %08x\n", hr );
382
383 V_VT( &subkey ) = VT_BSTR;
384 V_BSTR( &subkey ) = SysAllocString( windowsW );
385 hr = IWbemClassObject_Put( in, subkeynameW, 0, &subkey, 0 );
386 ok( hr == S_OK, "failed to set subkey %08x\n", hr );
387
388 out = NULL;
389 method = SysAllocString( enumkeyW );
390 hr = IWbemServices_ExecMethod( services, class, method, 0, NULL, in, &out, NULL );
391 ok( hr == S_OK, "failed to execute method %08x\n", hr );
392 SysFreeString( method );
393
394 type = 0xdeadbeef;
395 VariantInit( &retval );
396 hr = IWbemClassObject_Get( out, returnvalueW, 0, &retval, &type, NULL );
397 ok( hr == S_OK, "failed to get return value %08x\n", hr );
398 ok( V_VT( &retval ) == VT_I4, "unexpected variant type 0x%x\n", V_VT( &retval ) );
399 ok( !V_I4( &retval ), "unexpected error %u\n", V_UI4( &retval ) );
400 ok( type == CIM_UINT32, "unexpected type 0x%x\n", type );
401
402 type = 0xdeadbeef;
403 VariantInit( &names );
404 hr = IWbemClassObject_Get( out, namesW, 0, &names, &type, NULL );
405 ok( hr == S_OK, "failed to get names %08x\n", hr );
406 ok( V_VT( &names ) == (VT_BSTR|VT_ARRAY), "unexpected variant type 0x%x\n", V_VT( &names ) );
407 ok( type == (CIM_STRING|CIM_FLAG_ARRAY), "unexpected type 0x%x\n", type );
408
409 VariantClear( &names );
410 VariantClear( &subkey );
411 IWbemClassObject_Release( in );
412 IWbemClassObject_Release( out );
413 IWbemClassObject_Release( sig_in );
414
415 hr = IWbemClassObject_GetMethod( reg, enumvaluesW, 0, &sig_in, NULL );
416 ok( hr == S_OK, "failed to get EnumValues method %08x\n", hr );
417
418 hr = IWbemClassObject_SpawnInstance( sig_in, 0, &in );
419 ok( hr == S_OK, "failed to spawn instance %08x\n", hr );
420
421 V_VT( &defkey ) = VT_I4;
422 V_I4( &defkey ) = 0x80000002;
423 hr = IWbemClassObject_Put( in, defkeyW, 0, &defkey, 0 );
424 ok( hr == S_OK, "failed to set root %08x\n", hr );
425
426 V_VT( &subkey ) = VT_BSTR;
427 V_BSTR( &subkey ) = SysAllocString( windowsW );
428 hr = IWbemClassObject_Put( in, subkeynameW, 0, &subkey, 0 );
429 ok( hr == S_OK, "failed to set subkey %08x\n", hr );
430
431 out = NULL;
432 method = SysAllocString( enumvaluesW );
433 hr = IWbemServices_ExecMethod( services, class, method, 0, NULL, in, &out, NULL );
434 ok( hr == S_OK, "failed to execute method %08x\n", hr );
435 SysFreeString( method );
436
437 type = 0xdeadbeef;
438 VariantInit( &retval );
439 hr = IWbemClassObject_Get( out, returnvalueW, 0, &retval, &type, NULL );
440 ok( hr == S_OK, "failed to get return value %08x\n", hr );
441 ok( V_VT( &retval ) == VT_I4, "unexpected variant type 0x%x\n", V_VT( &retval ) );
442 ok( !V_I4( &retval ), "unexpected error %u\n", V_I4( &retval ) );
443 ok( type == CIM_UINT32, "unexpected type 0x%x\n", type );
444
445 type = 0xdeadbeef;
446 VariantInit( &names );
447 hr = IWbemClassObject_Get( out, namesW, 0, &names, &type, NULL );
448 ok( hr == S_OK, "failed to get names %08x\n", hr );
449 ok( V_VT( &names ) == (VT_BSTR|VT_ARRAY), "unexpected variant type 0x%x\n", V_VT( &names ) );
450 ok( type == (CIM_STRING|CIM_FLAG_ARRAY), "unexpected type 0x%x\n", type );
451
452 type = 0xdeadbeef;
453 VariantInit( &types );
454 hr = IWbemClassObject_Get( out, typesW, 0, &types, &type, NULL );
455 ok( hr == S_OK, "failed to get names %08x\n", hr );
456 ok( V_VT( &types ) == (VT_I4|VT_ARRAY), "unexpected variant type 0x%x\n", V_VT( &types ) );
457 ok( type == (CIM_SINT32|CIM_FLAG_ARRAY), "unexpected type 0x%x\n", type );
458
459 VariantClear( &types );
460 VariantClear( &names );
461 VariantClear( &subkey );
462 IWbemClassObject_Release( in );
463 IWbemClassObject_Release( out );
464 IWbemClassObject_Release( sig_in );
465
466 hr = IWbemClassObject_GetMethod( reg, getstringvalueW, 0, &sig_in, NULL );
467 ok( hr == S_OK, "failed to get GetStringValue method %08x\n", hr );
468
469 hr = IWbemClassObject_SpawnInstance( sig_in, 0, &in );
470 ok( hr == S_OK, "failed to spawn instance %08x\n", hr );
471
472 V_VT( &defkey ) = VT_I4;
473 V_I4( &defkey ) = 0x80000002;
474 hr = IWbemClassObject_Put( in, defkeyW, 0, &defkey, 0 );
475 ok( hr == S_OK, "failed to set root %08x\n", hr );
476
477 V_VT( &subkey ) = VT_BSTR;
478 V_BSTR( &subkey ) = SysAllocString( windowsW );
479 hr = IWbemClassObject_Put( in, subkeynameW, 0, &subkey, 0 );
480 ok( hr == S_OK, "failed to set subkey %08x\n", hr );
481
482 V_VT( &valuename ) = VT_BSTR;
483 V_BSTR( &valuename ) = SysAllocString( programfilesW );
484 hr = IWbemClassObject_Put( in, valuenameW, 0, &valuename, 0 );
485 ok( hr == S_OK, "failed to set value name %08x\n", hr );
486
487 out = NULL;
488 method = SysAllocString( getstringvalueW );
489 hr = IWbemServices_ExecMethod( services, class, method, 0, NULL, in, &out, NULL );
490 ok( hr == S_OK, "failed to execute method %08x\n", hr );
491 SysFreeString( method );
492
493 type = 0xdeadbeef;
494 VariantInit( &retval );
495 hr = IWbemClassObject_Get( out, returnvalueW, 0, &retval, &type, NULL );
496 ok( hr == S_OK, "failed to get return value %08x\n", hr );
497 ok( V_VT( &retval ) == VT_I4, "unexpected variant type 0x%x\n", V_VT( &retval ) );
498 ok( !V_I4( &retval ), "unexpected error %u\n", V_I4( &retval ) );
499 ok( type == CIM_UINT32, "unexpected type 0x%x\n", type );
500
501 type = 0xdeadbeef;
502 VariantInit( &value );
503 hr = IWbemClassObject_Get( out, valueW, 0, &value, &type, NULL );
504 ok( hr == S_OK, "failed to get value %08x\n", hr );
505 ok( V_VT( &value ) == VT_BSTR, "unexpected variant type 0x%x\n", V_VT( &value ) );
506 ok( type == CIM_STRING, "unexpected type 0x%x\n", type );
507
508 VariantClear( &value );
509 VariantClear( &valuename );
510 VariantClear( &subkey );
511 IWbemClassObject_Release( in );
512 IWbemClassObject_Release( out );
513 IWbemClassObject_Release( sig_in );
514
515 IWbemClassObject_Release( reg );
516 SysFreeString( class );
517 }
518
519 static HRESULT WINAPI sink_QueryInterface(
520 IWbemObjectSink *iface, REFIID riid, void **ppv )
521 {
522 *ppv = NULL;
523 if (IsEqualGUID( &IID_IUnknown, riid ) || IsEqualGUID( &IID_IWbemObjectSink, riid ))
524 {
525 *ppv = iface;
526 IWbemObjectSink_AddRef( iface );
527 return S_OK;
528 }
529 return E_NOINTERFACE;
530 }
531
532 static ULONG sink_refs;
533
534 static ULONG WINAPI sink_AddRef(
535 IWbemObjectSink *iface )
536 {
537 return ++sink_refs;
538 }
539
540 static ULONG WINAPI sink_Release(
541 IWbemObjectSink *iface )
542 {
543 return --sink_refs;
544 }
545
546 static HRESULT WINAPI sink_Indicate(
547 IWbemObjectSink *iface, LONG count, IWbemClassObject **objects )
548 {
549 trace("Indicate: %d, %p\n", count, objects);
550 return S_OK;
551 }
552
553 static HRESULT WINAPI sink_SetStatus(
554 IWbemObjectSink *iface, LONG flags, HRESULT hresult, BSTR str_param, IWbemClassObject *obj_param )
555 {
556 trace("SetStatus: %08x, %08x, %s, %p\n", flags, hresult, wine_dbgstr_w(str_param), obj_param);
557 return S_OK;
558 }
559
560 static IWbemObjectSinkVtbl sink_vtbl =
561 {
562 sink_QueryInterface,
563 sink_AddRef,
564 sink_Release,
565 sink_Indicate,
566 sink_SetStatus
567 };
568
569 static IWbemObjectSink sink = { &sink_vtbl };
570
571 static void test_notification_query_async( IWbemServices *services )
572 {
573 static const WCHAR queryW[] =
574 {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','W','i','n','3','2','_',
575 'D','e','v','i','c','e','C','h','a','n','g','e','E','v','e','n','t',0};
576 BSTR wql = SysAllocString( wqlW ), query = SysAllocString( queryW );
577 ULONG prev_sink_refs;
578 HRESULT hr;
579
580 hr = IWbemServices_ExecNotificationQueryAsync( services, wql, query, 0, NULL, NULL );
581 ok( hr == WBEM_E_INVALID_PARAMETER, "got %08x\n", hr );
582
583 prev_sink_refs = sink_refs;
584 hr = IWbemServices_ExecNotificationQueryAsync( services, wql, query, 0, NULL, &sink );
585 ok( hr == S_OK || broken(hr == WBEM_E_NOT_FOUND), "got %08x\n", hr );
586 ok( sink_refs > prev_sink_refs || broken(!sink_refs), "got %u refs\n", sink_refs );
587
588 hr = IWbemServices_CancelAsyncCall( services, &sink );
589 ok( hr == S_OK || broken(hr == WBEM_E_NOT_FOUND), "got %08x\n", hr );
590
591 SysFreeString( wql );
592 SysFreeString( query );
593 }
594
595 static void test_query_async( IWbemServices *services )
596 {
597 static const WCHAR queryW[] =
598 {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','W','i','n','3','2','_',
599 'P','r','o','c','e','s','s',0};
600 BSTR wql = SysAllocString( wqlW ), query = SysAllocString( queryW );
601 HRESULT hr;
602
603 hr = IWbemServices_ExecQueryAsync( services, wql, query, 0, NULL, NULL );
604 ok( hr == WBEM_E_INVALID_PARAMETER, "got %08x\n", hr );
605
606 hr = IWbemServices_ExecQueryAsync( services, wql, query, 0, NULL, &sink );
607 ok( hr == S_OK || broken(hr == WBEM_E_NOT_FOUND), "got %08x\n", hr );
608
609 hr = IWbemServices_CancelAsyncCall( services, NULL );
610 ok( hr == WBEM_E_INVALID_PARAMETER, "got %08x\n", hr );
611
612 hr = IWbemServices_CancelAsyncCall( services, &sink );
613 ok( hr == S_OK, "got %08x\n", hr );
614
615 SysFreeString( wql );
616 SysFreeString( query );
617 }
618
619 static void test_GetNames( IWbemServices *services )
620 {
621 static const WCHAR queryW[] =
622 {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','W','i','n','3','2','_',
623 'O','p','e','r','a','t','i','n','g','S','y','s','t','e','m',0};
624 BSTR wql = SysAllocString( wqlW ), query = SysAllocString( queryW );
625 IEnumWbemClassObject *result;
626 HRESULT hr;
627
628 hr = IWbemServices_ExecQuery( services, wql, query, 0, NULL, &result );
629 ok( hr == S_OK, "got %08x\n", hr );
630
631 for (;;)
632 {
633 IWbemClassObject *obj;
634 SAFEARRAY *names;
635 ULONG count;
636 VARIANT val;
637
638 IEnumWbemClassObject_Next( result, 10000, 1, &obj, &count );
639 if (!count) break;
640
641 VariantInit( &val );
642 hr = IWbemClassObject_GetNames( obj, NULL, WBEM_FLAG_NONSYSTEM_ONLY, &val, &names );
643 ok( hr == S_OK, "got %08x\n", hr );
644
645 SafeArrayDestroy( names );
646 IWbemClassObject_Release( obj );
647 }
648 IEnumWbemClassObject_Release( result );
649 SysFreeString( query );
650 SysFreeString( wql );
651 }
652
653 START_TEST(query)
654 {
655 static const WCHAR cimv2W[] = {'R','O','O','T','\\','C','I','M','V','2',0};
656 BSTR path = SysAllocString( cimv2W );
657 IWbemLocator *locator;
658 IWbemServices *services;
659 HRESULT hr;
660
661 CoInitialize( NULL );
662 CoInitializeSecurity( NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_DEFAULT,
663 RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, NULL );
664 hr = CoCreateInstance( &CLSID_WbemLocator, NULL, CLSCTX_INPROC_SERVER, &IID_IWbemLocator,
665 (void **)&locator );
666 if (hr != S_OK)
667 {
668 win_skip("can't create instance of WbemLocator\n");
669 return;
670 }
671 hr = IWbemLocator_ConnectServer( locator, path, NULL, NULL, NULL, 0, NULL, NULL, &services );
672 ok( hr == S_OK, "failed to get IWbemServices interface %08x\n", hr );
673
674 hr = CoSetProxyBlanket( (IUnknown *)services, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL,
675 RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE );
676 ok( hr == S_OK, "failed to set proxy blanket %08x\n", hr );
677
678 test_select( services );
679 test_Win32_Process( services );
680 test_Win32_Service( services );
681 test_StdRegProv( services );
682 test_notification_query_async( services );
683 test_query_async( services );
684 test_GetNames( services );
685
686 SysFreeString( path );
687 IWbemServices_Release( services );
688 IWbemLocator_Release( locator );
689 CoUninitialize();
690 }