[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_Win32_ComputerSystem( IWbemServices *services )
344 {
345 static const WCHAR nameW[] = {'N','a','m','e',0};
346 static const WCHAR usernameW[] = {'U','s','e','r','N','a','m','e',0};
347 static const WCHAR backslashW[] = {'\\',0};
348 static const WCHAR queryW[] =
349 {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','W','i','n','3','2','_',
350 'C','o','m','p','u','t','e','r','S','y','s','t','e','m',0};
351 BSTR wql = SysAllocString( wqlW ), query = SysAllocString( queryW );
352 IEnumWbemClassObject *result;
353 IWbemClassObject *service;
354 VARIANT value;
355 CIMTYPE type;
356 HRESULT hr;
357 WCHAR compname[MAX_COMPUTERNAME_LENGTH + 1];
358 WCHAR username[128];
359 DWORD len, count;
360
361 len = sizeof(compname) / sizeof(compname[0]);
362 if (!GetComputerNameW( compname, &len ))
363 compname[0] = 0;
364
365 lstrcpyW( username, compname );
366 lstrcatW( username, backslashW );
367 len = sizeof(username) / sizeof(username[0]) - lstrlenW( username );
368 if (!GetUserNameW( username + lstrlenW( username ), &len ))
369 username[0] = 0;
370
371 if (!compname[0] || !username[0])
372 {
373 skip( "Failed to get user or computer name\n" );
374 return;
375 }
376
377 hr = IWbemServices_ExecQuery( services, wql, query, 0, NULL, &result );
378 if (hr != S_OK)
379 {
380 win_skip( "Win32_ComputerSystem not available\n" );
381 return;
382 }
383
384 IEnumWbemClassObject_Next( result, 10000, 1, &service, &count );
385 ok( hr == S_OK, "got %08x\n", hr );
386
387 type = 0xdeadbeef;
388 VariantInit( &value );
389 hr = IWbemClassObject_Get( service, nameW, 0, &value, &type, NULL );
390 ok( hr == S_OK, "failed to get computer name %08x\n", hr );
391 ok( V_VT( &value ) == VT_BSTR, "unexpected variant type 0x%x\n", V_VT( &value ) );
392 ok( type == CIM_STRING, "unexpected type 0x%x\n", type );
393 ok( !lstrcmpiW( V_BSTR( &value ), compname ), "got %s, expected %s\n", wine_dbgstr_w(V_BSTR(&value)), wine_dbgstr_w(compname) );
394 VariantClear( &value );
395
396 type = 0xdeadbeef;
397 VariantInit( &value );
398 hr = IWbemClassObject_Get( service, usernameW, 0, &value, &type, NULL );
399 ok( hr == S_OK, "failed to get computer name %08x\n", hr );
400 ok( V_VT( &value ) == VT_BSTR, "unexpected variant type 0x%x\n", V_VT( &value ) );
401 ok( type == CIM_STRING, "unexpected type 0x%x\n", type );
402 ok( !lstrcmpiW( V_BSTR( &value ), username ), "got %s, expected %s\n", wine_dbgstr_w(V_BSTR(&value)), wine_dbgstr_w(username) );
403 VariantClear( &value );
404
405 IWbemClassObject_Release( service );
406 IEnumWbemClassObject_Release( result );
407 SysFreeString( query );
408 SysFreeString( wql );
409 }
410
411 static void test_StdRegProv( IWbemServices *services )
412 {
413 static const WCHAR enumkeyW[] = {'E','n','u','m','K','e','y',0};
414 static const WCHAR enumvaluesW[] = {'E','n','u','m','V','a','l','u','e','s',0};
415 static const WCHAR getstringvalueW[] = {'G','e','t','S','t','r','i','n','g','V','a','l','u','e',0};
416 static const WCHAR stdregprovW[] = {'S','t','d','R','e','g','P','r','o','v',0};
417 static const WCHAR defkeyW[] = {'h','D','e','f','K','e','y',0};
418 static const WCHAR subkeynameW[] = {'s','S','u','b','K','e','y','N','a','m','e',0};
419 static const WCHAR returnvalueW[] = {'R','e','t','u','r','n','V','a','l','u','e',0};
420 static const WCHAR namesW[] = {'s','N','a','m','e','s',0};
421 static const WCHAR typesW[] = {'T','y','p','e','s',0};
422 static const WCHAR valueW[] = {'s','V','a','l','u','e',0};
423 static const WCHAR valuenameW[] = {'s','V','a','l','u','e','N','a','m','e',0};
424 static const WCHAR programfilesW[] = {'P','r','o','g','r','a','m','F','i','l','e','s','D','i','r',0};
425 static const WCHAR windowsW[] =
426 {'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
427 'W','i','n','d','o','w','s','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n',0};
428 BSTR class = SysAllocString( stdregprovW ), method;
429 IWbemClassObject *reg, *sig_in, *in, *out;
430 VARIANT defkey, subkey, retval, names, types, value, valuename;
431 CIMTYPE type;
432 HRESULT hr;
433
434 hr = IWbemServices_GetObject( services, class, 0, NULL, &reg, NULL );
435 if (hr != S_OK)
436 {
437 win_skip( "StdRegProv not available\n" );
438 return;
439 }
440 hr = IWbemClassObject_GetMethod( reg, enumkeyW, 0, &sig_in, NULL );
441 ok( hr == S_OK, "failed to get EnumKey method %08x\n", hr );
442
443 hr = IWbemClassObject_SpawnInstance( sig_in, 0, &in );
444 ok( hr == S_OK, "failed to spawn instance %08x\n", hr );
445
446 V_VT( &defkey ) = VT_I4;
447 V_I4( &defkey ) = 0x80000002;
448 hr = IWbemClassObject_Put( in, defkeyW, 0, &defkey, 0 );
449 ok( hr == S_OK, "failed to set root %08x\n", hr );
450
451 V_VT( &subkey ) = VT_BSTR;
452 V_BSTR( &subkey ) = SysAllocString( windowsW );
453 hr = IWbemClassObject_Put( in, subkeynameW, 0, &subkey, 0 );
454 ok( hr == S_OK, "failed to set subkey %08x\n", hr );
455
456 out = NULL;
457 method = SysAllocString( enumkeyW );
458 hr = IWbemServices_ExecMethod( services, class, method, 0, NULL, in, &out, NULL );
459 ok( hr == S_OK, "failed to execute method %08x\n", hr );
460 SysFreeString( method );
461
462 type = 0xdeadbeef;
463 VariantInit( &retval );
464 hr = IWbemClassObject_Get( out, returnvalueW, 0, &retval, &type, NULL );
465 ok( hr == S_OK, "failed to get return value %08x\n", hr );
466 ok( V_VT( &retval ) == VT_I4, "unexpected variant type 0x%x\n", V_VT( &retval ) );
467 ok( !V_I4( &retval ), "unexpected error %u\n", V_UI4( &retval ) );
468 ok( type == CIM_UINT32, "unexpected type 0x%x\n", type );
469
470 type = 0xdeadbeef;
471 VariantInit( &names );
472 hr = IWbemClassObject_Get( out, namesW, 0, &names, &type, NULL );
473 ok( hr == S_OK, "failed to get names %08x\n", hr );
474 ok( V_VT( &names ) == (VT_BSTR|VT_ARRAY), "unexpected variant type 0x%x\n", V_VT( &names ) );
475 ok( type == (CIM_STRING|CIM_FLAG_ARRAY), "unexpected type 0x%x\n", type );
476
477 VariantClear( &names );
478 VariantClear( &subkey );
479 IWbemClassObject_Release( in );
480 IWbemClassObject_Release( out );
481 IWbemClassObject_Release( sig_in );
482
483 hr = IWbemClassObject_GetMethod( reg, enumvaluesW, 0, &sig_in, NULL );
484 ok( hr == S_OK, "failed to get EnumValues method %08x\n", hr );
485
486 hr = IWbemClassObject_SpawnInstance( sig_in, 0, &in );
487 ok( hr == S_OK, "failed to spawn instance %08x\n", hr );
488
489 V_VT( &defkey ) = VT_I4;
490 V_I4( &defkey ) = 0x80000002;
491 hr = IWbemClassObject_Put( in, defkeyW, 0, &defkey, 0 );
492 ok( hr == S_OK, "failed to set root %08x\n", hr );
493
494 V_VT( &subkey ) = VT_BSTR;
495 V_BSTR( &subkey ) = SysAllocString( windowsW );
496 hr = IWbemClassObject_Put( in, subkeynameW, 0, &subkey, 0 );
497 ok( hr == S_OK, "failed to set subkey %08x\n", hr );
498
499 out = NULL;
500 method = SysAllocString( enumvaluesW );
501 hr = IWbemServices_ExecMethod( services, class, method, 0, NULL, in, &out, NULL );
502 ok( hr == S_OK, "failed to execute method %08x\n", hr );
503 SysFreeString( method );
504
505 type = 0xdeadbeef;
506 VariantInit( &retval );
507 hr = IWbemClassObject_Get( out, returnvalueW, 0, &retval, &type, NULL );
508 ok( hr == S_OK, "failed to get return value %08x\n", hr );
509 ok( V_VT( &retval ) == VT_I4, "unexpected variant type 0x%x\n", V_VT( &retval ) );
510 ok( !V_I4( &retval ), "unexpected error %u\n", V_I4( &retval ) );
511 ok( type == CIM_UINT32, "unexpected type 0x%x\n", type );
512
513 type = 0xdeadbeef;
514 VariantInit( &names );
515 hr = IWbemClassObject_Get( out, namesW, 0, &names, &type, NULL );
516 ok( hr == S_OK, "failed to get names %08x\n", hr );
517 ok( V_VT( &names ) == (VT_BSTR|VT_ARRAY), "unexpected variant type 0x%x\n", V_VT( &names ) );
518 ok( type == (CIM_STRING|CIM_FLAG_ARRAY), "unexpected type 0x%x\n", type );
519
520 type = 0xdeadbeef;
521 VariantInit( &types );
522 hr = IWbemClassObject_Get( out, typesW, 0, &types, &type, NULL );
523 ok( hr == S_OK, "failed to get names %08x\n", hr );
524 ok( V_VT( &types ) == (VT_I4|VT_ARRAY), "unexpected variant type 0x%x\n", V_VT( &types ) );
525 ok( type == (CIM_SINT32|CIM_FLAG_ARRAY), "unexpected type 0x%x\n", type );
526
527 VariantClear( &types );
528 VariantClear( &names );
529 VariantClear( &subkey );
530 IWbemClassObject_Release( in );
531 IWbemClassObject_Release( out );
532 IWbemClassObject_Release( sig_in );
533
534 hr = IWbemClassObject_GetMethod( reg, getstringvalueW, 0, &sig_in, NULL );
535 ok( hr == S_OK, "failed to get GetStringValue method %08x\n", hr );
536
537 hr = IWbemClassObject_SpawnInstance( sig_in, 0, &in );
538 ok( hr == S_OK, "failed to spawn instance %08x\n", hr );
539
540 V_VT( &defkey ) = VT_I4;
541 V_I4( &defkey ) = 0x80000002;
542 hr = IWbemClassObject_Put( in, defkeyW, 0, &defkey, 0 );
543 ok( hr == S_OK, "failed to set root %08x\n", hr );
544
545 V_VT( &subkey ) = VT_BSTR;
546 V_BSTR( &subkey ) = SysAllocString( windowsW );
547 hr = IWbemClassObject_Put( in, subkeynameW, 0, &subkey, 0 );
548 ok( hr == S_OK, "failed to set subkey %08x\n", hr );
549
550 V_VT( &valuename ) = VT_BSTR;
551 V_BSTR( &valuename ) = SysAllocString( programfilesW );
552 hr = IWbemClassObject_Put( in, valuenameW, 0, &valuename, 0 );
553 ok( hr == S_OK, "failed to set value name %08x\n", hr );
554
555 out = NULL;
556 method = SysAllocString( getstringvalueW );
557 hr = IWbemServices_ExecMethod( services, class, method, 0, NULL, in, &out, NULL );
558 ok( hr == S_OK, "failed to execute method %08x\n", hr );
559 SysFreeString( method );
560
561 type = 0xdeadbeef;
562 VariantInit( &retval );
563 hr = IWbemClassObject_Get( out, returnvalueW, 0, &retval, &type, NULL );
564 ok( hr == S_OK, "failed to get return value %08x\n", hr );
565 ok( V_VT( &retval ) == VT_I4, "unexpected variant type 0x%x\n", V_VT( &retval ) );
566 ok( !V_I4( &retval ), "unexpected error %u\n", V_I4( &retval ) );
567 ok( type == CIM_UINT32, "unexpected type 0x%x\n", type );
568
569 type = 0xdeadbeef;
570 VariantInit( &value );
571 hr = IWbemClassObject_Get( out, valueW, 0, &value, &type, NULL );
572 ok( hr == S_OK, "failed to get value %08x\n", hr );
573 ok( V_VT( &value ) == VT_BSTR, "unexpected variant type 0x%x\n", V_VT( &value ) );
574 ok( type == CIM_STRING, "unexpected type 0x%x\n", type );
575
576 VariantClear( &value );
577 VariantClear( &valuename );
578 VariantClear( &subkey );
579 IWbemClassObject_Release( in );
580 IWbemClassObject_Release( out );
581 IWbemClassObject_Release( sig_in );
582
583 IWbemClassObject_Release( reg );
584 SysFreeString( class );
585 }
586
587 static HRESULT WINAPI sink_QueryInterface(
588 IWbemObjectSink *iface, REFIID riid, void **ppv )
589 {
590 *ppv = NULL;
591 if (IsEqualGUID( &IID_IUnknown, riid ) || IsEqualGUID( &IID_IWbemObjectSink, riid ))
592 {
593 *ppv = iface;
594 IWbemObjectSink_AddRef( iface );
595 return S_OK;
596 }
597 return E_NOINTERFACE;
598 }
599
600 static ULONG sink_refs;
601
602 static ULONG WINAPI sink_AddRef(
603 IWbemObjectSink *iface )
604 {
605 return ++sink_refs;
606 }
607
608 static ULONG WINAPI sink_Release(
609 IWbemObjectSink *iface )
610 {
611 return --sink_refs;
612 }
613
614 static HRESULT WINAPI sink_Indicate(
615 IWbemObjectSink *iface, LONG count, IWbemClassObject **objects )
616 {
617 trace("Indicate: %d, %p\n", count, objects);
618 return S_OK;
619 }
620
621 static HRESULT WINAPI sink_SetStatus(
622 IWbemObjectSink *iface, LONG flags, HRESULT hresult, BSTR str_param, IWbemClassObject *obj_param )
623 {
624 trace("SetStatus: %08x, %08x, %s, %p\n", flags, hresult, wine_dbgstr_w(str_param), obj_param);
625 return S_OK;
626 }
627
628 static IWbemObjectSinkVtbl sink_vtbl =
629 {
630 sink_QueryInterface,
631 sink_AddRef,
632 sink_Release,
633 sink_Indicate,
634 sink_SetStatus
635 };
636
637 static IWbemObjectSink sink = { &sink_vtbl };
638
639 static void test_notification_query_async( IWbemServices *services )
640 {
641 static const WCHAR queryW[] =
642 {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','W','i','n','3','2','_',
643 'D','e','v','i','c','e','C','h','a','n','g','e','E','v','e','n','t',0};
644 BSTR wql = SysAllocString( wqlW ), query = SysAllocString( queryW );
645 ULONG prev_sink_refs;
646 HRESULT hr;
647
648 hr = IWbemServices_ExecNotificationQueryAsync( services, wql, query, 0, NULL, NULL );
649 ok( hr == WBEM_E_INVALID_PARAMETER, "got %08x\n", hr );
650
651 prev_sink_refs = sink_refs;
652 hr = IWbemServices_ExecNotificationQueryAsync( services, wql, query, 0, NULL, &sink );
653 ok( hr == S_OK || broken(hr == WBEM_E_NOT_FOUND), "got %08x\n", hr );
654 ok( sink_refs > prev_sink_refs || broken(!sink_refs), "got %u refs\n", sink_refs );
655
656 hr = IWbemServices_CancelAsyncCall( services, &sink );
657 ok( hr == S_OK || broken(hr == WBEM_E_NOT_FOUND), "got %08x\n", hr );
658
659 SysFreeString( wql );
660 SysFreeString( query );
661 }
662
663 static void test_query_async( IWbemServices *services )
664 {
665 static const WCHAR queryW[] =
666 {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','W','i','n','3','2','_',
667 'P','r','o','c','e','s','s',0};
668 BSTR wql = SysAllocString( wqlW ), query = SysAllocString( queryW );
669 HRESULT hr;
670
671 hr = IWbemServices_ExecQueryAsync( services, wql, query, 0, NULL, NULL );
672 ok( hr == WBEM_E_INVALID_PARAMETER, "got %08x\n", hr );
673
674 hr = IWbemServices_ExecQueryAsync( services, wql, query, 0, NULL, &sink );
675 ok( hr == S_OK || broken(hr == WBEM_E_NOT_FOUND), "got %08x\n", hr );
676
677 hr = IWbemServices_CancelAsyncCall( services, NULL );
678 ok( hr == WBEM_E_INVALID_PARAMETER, "got %08x\n", hr );
679
680 hr = IWbemServices_CancelAsyncCall( services, &sink );
681 ok( hr == S_OK, "got %08x\n", hr );
682
683 SysFreeString( wql );
684 SysFreeString( query );
685 }
686
687 static void test_GetNames( IWbemServices *services )
688 {
689 static const WCHAR queryW[] =
690 {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','W','i','n','3','2','_',
691 'O','p','e','r','a','t','i','n','g','S','y','s','t','e','m',0};
692 BSTR wql = SysAllocString( wqlW ), query = SysAllocString( queryW );
693 IEnumWbemClassObject *result;
694 HRESULT hr;
695
696 hr = IWbemServices_ExecQuery( services, wql, query, 0, NULL, &result );
697 ok( hr == S_OK, "got %08x\n", hr );
698
699 for (;;)
700 {
701 IWbemClassObject *obj;
702 SAFEARRAY *names;
703 ULONG count;
704 VARIANT val;
705
706 IEnumWbemClassObject_Next( result, 10000, 1, &obj, &count );
707 if (!count) break;
708
709 VariantInit( &val );
710 hr = IWbemClassObject_GetNames( obj, NULL, WBEM_FLAG_NONSYSTEM_ONLY, &val, &names );
711 ok( hr == S_OK, "got %08x\n", hr );
712
713 SafeArrayDestroy( names );
714 IWbemClassObject_Release( obj );
715 }
716 IEnumWbemClassObject_Release( result );
717 SysFreeString( query );
718 SysFreeString( wql );
719 }
720
721 static void test_SystemSecurity( IWbemServices *services )
722 {
723 static const WCHAR systemsecurityW[] = {'_','_','S','y','s','t','e','m','S','e','c','u','r','i','t','y',0};
724 static const WCHAR getsdW[] = {'G','e','t','S','D',0};
725 static const WCHAR returnvalueW[] = {'R','e','t','u','r','n','V','a','l','u','e',0};
726 static const WCHAR sdW[] = {'S','D',0};
727 BSTR class = SysAllocString( systemsecurityW ), method;
728 IWbemClassObject *reg, *out;
729 VARIANT retval, var_sd;
730 void *data;
731 SECURITY_DESCRIPTOR_RELATIVE *sd;
732 CIMTYPE type;
733 HRESULT hr;
734 BYTE sid_admin_buffer[SECURITY_MAX_SID_SIZE];
735 SID *sid_admin = (SID*)sid_admin_buffer;
736 DWORD sid_size;
737 BOOL ret;
738
739 hr = IWbemServices_GetObject( services, class, 0, NULL, &reg, NULL );
740 if (hr != S_OK)
741 {
742 win_skip( "__SystemSecurity not available\n" );
743 return;
744 }
745
746 sid_size = sizeof(sid_admin_buffer);
747 ret = CreateWellKnownSid( WinBuiltinAdministratorsSid, NULL, sid_admin, &sid_size );
748 ok( ret, "CreateWellKnownSid failed\n" );
749
750 out = NULL;
751 method = SysAllocString( getsdW );
752 hr = IWbemServices_ExecMethod( services, class, method, 0, NULL, NULL, &out, NULL );
753 ok( hr == S_OK || hr == WBEM_E_ACCESS_DENIED, "failed to execute method %08x\n", hr );
754 SysFreeString( method );
755
756 if (SUCCEEDED(hr))
757 {
758 type = 0xdeadbeef;
759 VariantInit( &retval );
760 hr = IWbemClassObject_Get( out, returnvalueW, 0, &retval, &type, NULL );
761 ok( hr == S_OK, "failed to get return value %08x\n", hr );
762 ok( V_VT( &retval ) == VT_I4, "unexpected variant type 0x%x\n", V_VT( &retval ) );
763 ok( !V_I4( &retval ), "unexpected error %u\n", V_UI4( &retval ) );
764 ok( type == CIM_UINT32, "unexpected type 0x%x\n", type );
765
766 type = 0xdeadbeef;
767 VariantInit( &var_sd );
768 hr = IWbemClassObject_Get( out, sdW, 0, &var_sd, &type, NULL );
769 ok( hr == S_OK, "failed to get names %08x\n", hr );
770 ok( V_VT( &var_sd ) == (VT_UI1|VT_ARRAY), "unexpected variant type 0x%x\n", V_VT( &var_sd ) );
771 ok( type == (CIM_UINT8|CIM_FLAG_ARRAY), "unexpected type 0x%x\n", type );
772
773 hr = SafeArrayAccessData( V_ARRAY( &var_sd ), &data );
774 ok( hr == S_OK, "SafeArrayAccessData failed %x\n", hr );
775 if (SUCCEEDED(hr))
776 {
777 sd = data;
778
779 ok( (sd->Control & SE_SELF_RELATIVE) == SE_SELF_RELATIVE, "relative flag unset\n" );
780 ok( sd->Owner != 0, "no owner SID\n");
781 ok( sd->Group != 0, "no owner SID\n");
782 ok( EqualSid( (PSID)((LPBYTE)sd + sd->Owner), sid_admin ), "unexpected owner SID\n" );
783 ok( EqualSid( (PSID)((LPBYTE)sd + sd->Group), sid_admin ), "unexpected group SID\n" );
784
785 hr = SafeArrayUnaccessData( V_ARRAY( &var_sd ) );
786 ok( hr == S_OK, "SafeArrayUnaccessData failed %x\n", hr );
787 }
788
789 VariantClear( &var_sd );
790 IWbemClassObject_Release( out );
791 }
792 else if (hr == WBEM_E_ACCESS_DENIED)
793 win_skip( "insufficient privs to test __SystemSecurity\n" );
794
795 SysFreeString( class );
796 }
797
798 START_TEST(query)
799 {
800 static const WCHAR cimv2W[] = {'R','O','O','T','\\','C','I','M','V','2',0};
801 BSTR path = SysAllocString( cimv2W );
802 IWbemLocator *locator;
803 IWbemServices *services;
804 HRESULT hr;
805
806 CoInitialize( NULL );
807 CoInitializeSecurity( NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_DEFAULT,
808 RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, NULL );
809 hr = CoCreateInstance( &CLSID_WbemLocator, NULL, CLSCTX_INPROC_SERVER, &IID_IWbemLocator,
810 (void **)&locator );
811 if (hr != S_OK)
812 {
813 win_skip("can't create instance of WbemLocator\n");
814 return;
815 }
816 hr = IWbemLocator_ConnectServer( locator, path, NULL, NULL, NULL, 0, NULL, NULL, &services );
817 ok( hr == S_OK, "failed to get IWbemServices interface %08x\n", hr );
818
819 hr = CoSetProxyBlanket( (IUnknown *)services, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL,
820 RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE );
821 ok( hr == S_OK, "failed to set proxy blanket %08x\n", hr );
822
823 test_select( services );
824 test_Win32_Process( services );
825 test_Win32_Service( services );
826 test_Win32_ComputerSystem( services );
827 test_StdRegProv( services );
828 test_notification_query_async( services );
829 test_query_async( services );
830 test_GetNames( services );
831 test_SystemSecurity( services );
832
833 SysFreeString( path );
834 IWbemServices_Release( services );
835 IWbemLocator_Release( locator );
836 CoUninitialize();
837 }