[WBEMPROX_WINETEST] Sync with Wine Staging 1.9.4. CORE-10912
[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 "sddl.h"
25 #include "initguid.h"
26 #include "objidl.h"
27 #include "wbemcli.h"
28 #include "wine/test.h"
29
30 static const WCHAR wqlW[] = {'w','q','l',0};
31
32 static HRESULT exec_query( IWbemServices *services, const WCHAR *str, IEnumWbemClassObject **result )
33 {
34 static const WCHAR captionW[] = {'C','a','p','t','i','o','n',0};
35 static const WCHAR descriptionW[] = {'D','e','s','c','r','i','p','t','i','o','n',0};
36 HRESULT hr;
37 IWbemClassObject *obj;
38 BSTR wql = SysAllocString( wqlW ), query = SysAllocString( str );
39 LONG flags = WBEM_FLAG_RETURN_IMMEDIATELY | WBEM_FLAG_FORWARD_ONLY;
40 ULONG count;
41
42 hr = IWbemServices_ExecQuery( services, wql, query, flags, NULL, result );
43 if (hr == S_OK)
44 {
45 trace("%s\n", wine_dbgstr_w(str));
46 for (;;)
47 {
48 VARIANT var;
49
50 IEnumWbemClassObject_Next( *result, 10000, 1, &obj, &count );
51 if (!count) break;
52
53 if (IWbemClassObject_Get( obj, captionW, 0, &var, NULL, NULL ) == WBEM_S_NO_ERROR)
54 {
55 trace("caption: %s\n", wine_dbgstr_w(V_BSTR(&var)));
56 VariantClear( &var );
57 }
58 if (IWbemClassObject_Get( obj, descriptionW, 0, &var, NULL, NULL ) == WBEM_S_NO_ERROR)
59 {
60 trace("description: %s\n", wine_dbgstr_w(V_BSTR(&var)));
61 VariantClear( &var );
62 }
63 IWbemClassObject_Release( obj );
64 }
65 }
66 SysFreeString( wql );
67 SysFreeString( query );
68 return hr;
69 }
70
71 static void test_select( IWbemServices *services )
72 {
73 static const WCHAR emptyW[] = {0};
74 static const WCHAR sqlW[] = {'S','Q','L',0};
75 static const WCHAR query1[] =
76 {'S','E','L','E','C','T',' ','H','O','T','F','I','X','I','D',' ','F','R','O','M',' ',
77 '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};
78 static const WCHAR query2[] =
79 {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','W','i','n','3','2','_','B','I','O','S',0};
80 static const WCHAR query3[] =
81 {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','W','i','n','3','2','_',
82 'L','o','g','i','c','a','l','D','i','s','k',' ','W','H','E','R','E',' ',
83 '\"','N','T','F','S','\"',' ','=',' ','F','i','l','e','S','y','s','t','e','m',0};
84 static const WCHAR query4[] =
85 {'S','E','L','E','C','T',' ','a',' ','F','R','O','M',' ','b',0};
86 static const WCHAR query5[] =
87 {'S','E','L','E','C','T',' ','a',' ','F','R','O','M',' ','W','i','n','3','2','_','B','i','o','s',0};
88 static const WCHAR query6[] =
89 {'S','E','L','E','C','T',' ','D','e','s','c','r','i','p','t','i','o','n',' ','F','R','O','M',' ',
90 'W','i','n','3','2','_','B','i','o','s',0};
91 static const WCHAR query7[] =
92 {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','W','i','n','3','2','_',
93 'P','r','o','c','e','s','s',' ','W','H','E','R','E',' ','C','a','p','t','i','o','n',' ',
94 'L','I','K','E',' ','\'','%','%','R','E','G','E','D','I','T','%','\'',0};
95 static const WCHAR query8[] =
96 {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','W','i','n','3','2','_',
97 'D','i','s','k','D','r','i','v','e',' ','W','H','E','R','E',' ','D','e','v','i','c','e','I','D','=',
98 '\"','\\','\\','\\','\\','.','\\','\\','P','H','Y','S','I','C','A','L','D','R','I','V','E','0','\"',0};
99 static const WCHAR query9[] =
100 {'S','E','L','E','C','T','\n','a','\r','F','R','O','M','\t','b',0};
101 static const WCHAR query10[] =
102 {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','W','i','n','3','2','_',
103 'P','r','o','c','e','s','s',' ','W','H','E','R','E',' ','C','a','p','t','i','o','n',' ',
104 'L','I','K','E',' ','"','%','f','i','r','e','f','o','x','.','e','x','e','"',0};
105 static const WCHAR query11[] =
106 {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
107 'W','i','n','3','2','_','V','i','d','e','o','C','o','n','t','r','o','l','l','e','r',' ','w','h','e','r','e',' ',
108 'a','v','a','i','l','a','b','i','l','i','t','y',' ','=',' ','\'','3','\'',0};
109 static const WCHAR *test[] = { query1, query2, query3, query4, query5, query6, query7, query8, query9, query10,
110 query11 };
111 HRESULT hr;
112 IEnumWbemClassObject *result;
113 BSTR wql = SysAllocString( wqlW );
114 BSTR sql = SysAllocString( sqlW );
115 BSTR query = SysAllocString( query1 );
116 UINT i;
117
118 hr = IWbemServices_ExecQuery( services, NULL, NULL, 0, NULL, &result );
119 ok( hr == WBEM_E_INVALID_PARAMETER, "query failed %08x\n", hr );
120
121 hr = IWbemServices_ExecQuery( services, NULL, query, 0, NULL, &result );
122 ok( hr == WBEM_E_INVALID_PARAMETER, "query failed %08x\n", hr );
123
124 hr = IWbemServices_ExecQuery( services, wql, NULL, 0, NULL, &result );
125 ok( hr == WBEM_E_INVALID_PARAMETER, "query failed %08x\n", hr );
126
127 hr = IWbemServices_ExecQuery( services, sql, query, 0, NULL, &result );
128 ok( hr == WBEM_E_INVALID_QUERY_TYPE, "query failed %08x\n", hr );
129
130 hr = IWbemServices_ExecQuery( services, sql, NULL, 0, NULL, &result );
131 ok( hr == WBEM_E_INVALID_PARAMETER, "query failed %08x\n", hr );
132
133 SysFreeString( query );
134 query = SysAllocString( emptyW );
135 hr = IWbemServices_ExecQuery( services, wql, query, 0, NULL, &result );
136 ok( hr == WBEM_E_INVALID_PARAMETER, "query failed %08x\n", hr );
137
138 for (i = 0; i < sizeof(test)/sizeof(test[0]); i++)
139 {
140 hr = exec_query( services, test[i], &result );
141 ok( hr == S_OK, "query %u failed: %08x\n", i, hr );
142 if (result) IEnumWbemClassObject_Release( result );
143 }
144
145 SysFreeString( wql );
146 SysFreeString( sql );
147 SysFreeString( query );
148 }
149
150 static void test_Win32_Service( IWbemServices *services )
151 {
152 static const WCHAR returnvalueW[] = {'R','e','t','u','r','n','V','a','l','u','e',0};
153 static const WCHAR pauseserviceW[] = {'P','a','u','s','e','S','e','r','v','i','c','e',0};
154 static const WCHAR resumeserviceW[] = {'R','e','s','u','m','e','S','e','r','v','i','c','e',0};
155 static const WCHAR startserviceW[] = {'S','t','a','r','t','S','e','r','v','i','c','e',0};
156 static const WCHAR stopserviceW[] = {'S','t','o','p','S','e','r','v','i','c','e',0};
157 static const WCHAR stateW[] = {'S','t','a','t','e',0};
158 static const WCHAR stoppedW[] = {'S','t','o','p','p','e','d',0};
159 static const WCHAR serviceW[] = {'W','i','n','3','2','_','S','e','r','v','i','c','e','.',
160 'N','a','m','e','=','"','S','p','o','o','l','e','r','"',0};
161 static const WCHAR emptyW[] = {0};
162 BSTR class = SysAllocString( serviceW ), empty = SysAllocString( emptyW ), method;
163 IWbemClassObject *service, *out;
164 VARIANT state, retval;
165 CIMTYPE type;
166 HRESULT hr;
167
168 hr = IWbemServices_GetObject( services, class, 0, NULL, &service, NULL );
169 if (hr != S_OK)
170 {
171 win_skip( "Win32_Service not available\n" );
172 goto out;
173 }
174 type = 0xdeadbeef;
175 VariantInit( &state );
176 hr = IWbemClassObject_Get( service, stateW, 0, &state, &type, NULL );
177 ok( hr == S_OK, "failed to get service state %08x\n", hr );
178 ok( V_VT( &state ) == VT_BSTR, "unexpected variant type 0x%x\n", V_VT( &state ) );
179 ok( type == CIM_STRING, "unexpected type 0x%x\n", type );
180
181 if (!lstrcmpW( V_BSTR( &state ), stoppedW ))
182 {
183 out = NULL;
184 method = SysAllocString( startserviceW );
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 error %u\n", V_UI4( &retval ) );
193 IWbemClassObject_Release( out );
194 }
195 out = NULL;
196 method = SysAllocString( pauseserviceW );
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 out = NULL;
208 method = SysAllocString( resumeserviceW );
209 hr = IWbemServices_ExecMethod( services, class, method, 0, NULL, NULL, &out, NULL );
210 ok( hr == S_OK, "failed to execute method %08x\n", hr );
211 SysFreeString( method );
212
213 VariantInit( &retval );
214 hr = IWbemClassObject_Get( out, returnvalueW, 0, &retval, NULL, NULL );
215 ok( hr == S_OK, "failed to get return value %08x\n", hr );
216 ok( V_I4( &retval ), "unexpected success\n" );
217 IWbemClassObject_Release( out );
218
219 if (!lstrcmpW( V_BSTR( &state ), stoppedW ))
220 {
221 out = NULL;
222 method = SysAllocString( stopserviceW );
223 hr = IWbemServices_ExecMethod( services, class, method, 0, NULL, NULL, &out, NULL );
224 ok( hr == S_OK, "failed to execute method %08x\n", hr );
225 SysFreeString( method );
226
227 VariantInit( &retval );
228 hr = IWbemClassObject_Get( out, returnvalueW, 0, &retval, NULL, NULL );
229 ok( hr == S_OK, "failed to get return value %08x\n", hr );
230 ok( !V_I4( &retval ), "unexpected error %u\n", V_UI4( &retval ) );
231 IWbemClassObject_Release( out );
232 }
233 VariantClear( &state );
234 IWbemClassObject_Release( service );
235
236 service = NULL;
237 hr = IWbemServices_GetObject( services, NULL, 0, NULL, &service, NULL );
238 ok( hr == S_OK, "got %08x\n", hr );
239 if (service) IWbemClassObject_Release( service );
240
241 service = NULL;
242 hr = IWbemServices_GetObject( services, empty, 0, NULL, &service, NULL );
243 ok( hr == S_OK, "got %08x\n", hr );
244 if (service) IWbemClassObject_Release( service );
245
246 out:
247 SysFreeString( empty );
248 SysFreeString( class );
249 }
250
251 static void test_Win32_Bios( IWbemServices *services )
252 {
253 static const WCHAR queryW[] =
254 {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','W','i','n','3','2','_', 'B','i','o','s',0};
255 static const WCHAR descriptionW[] = {'D','e','s','c','r','i','p','t','i','o','n',0};
256 static const WCHAR identificationcodeW[] = {'I','d','e','n','t','i','f','i','c','a','t','i','o','n','C','o','d','e',0};
257 static const WCHAR manufacturerW[] = {'M','a','n','u','f','a','c','t','u','r','e','r',0};
258 static const WCHAR nameW[] = {'N','a','m','e',0};
259 static const WCHAR releasedateW[] = {'R','e','l','e','a','s','e','D','a','t','e',0};
260 static const WCHAR serialnumberW[] = {'S','e','r','i','a','l','N','u','m','b','e','r',0};
261 static const WCHAR smbiosbiosversionW[] = {'S','M','B','I','O','S','B','I','O','S','V','e','r','s','i','o','n',0};
262 static const WCHAR versionW[] = {'V','e','r','s','i','o','n',0};
263 BSTR wql = SysAllocString( wqlW ), query = SysAllocString( queryW );
264 IEnumWbemClassObject *result;
265 IWbemClassObject *obj;
266 CIMTYPE type;
267 ULONG count;
268 VARIANT val;
269 HRESULT hr;
270
271 hr = IWbemServices_ExecQuery( services, wql, query, 0, NULL, &result );
272 ok( hr == S_OK, "IWbemServices_ExecQuery failed %08x\n", hr );
273
274 hr = IEnumWbemClassObject_Next( result, 10000, 1, &obj, &count );
275 ok( hr == S_OK, "IEnumWbemClassObject_Next failed %08x\n", hr );
276
277 type = 0xdeadbeef;
278 VariantInit( &val );
279 hr = IWbemClassObject_Get( obj, descriptionW, 0, &val, &type, NULL );
280 ok( hr == S_OK, "failed to get description %08x\n", hr );
281 ok( V_VT( &val ) == VT_BSTR, "unexpected variant type 0x%x\n", V_VT( &val ) );
282 ok( type == CIM_STRING, "unexpected type 0x%x\n", type );
283 trace( "description: %s\n", wine_dbgstr_w(V_BSTR( &val )) );
284 VariantClear( &val );
285
286 type = 0xdeadbeef;
287 VariantInit( &val );
288 hr = IWbemClassObject_Get( obj, identificationcodeW, 0, &val, &type, NULL );
289 ok( hr == S_OK, "failed to get identication code %08x\n", hr );
290 todo_wine
291 ok( V_VT( &val ) == VT_NULL, "unexpected variant type 0x%x\n", V_VT( &val ) );
292 ok( type == CIM_STRING, "unexpected type 0x%x\n", type );
293 VariantClear( &val );
294
295 type = 0xdeadbeef;
296 VariantInit( &val );
297 hr = IWbemClassObject_Get( obj, manufacturerW, 0, &val, &type, NULL );
298 ok( hr == S_OK, "failed to get manufacturer %08x\n", hr );
299 ok( V_VT( &val ) == VT_BSTR, "unexpected variant type 0x%x\n", V_VT( &val ) );
300 ok( type == CIM_STRING, "unexpected type 0x%x\n", type );
301 trace( "manufacturer: %s\n", wine_dbgstr_w(V_BSTR( &val )) );
302 VariantClear( &val );
303
304 type = 0xdeadbeef;
305 VariantInit( &val );
306 hr = IWbemClassObject_Get( obj, nameW, 0, &val, &type, NULL );
307 ok( hr == S_OK, "failed to get name %08x\n", hr );
308 ok( V_VT( &val ) == VT_BSTR, "unexpected variant type 0x%x\n", V_VT( &val ) );
309 ok( type == CIM_STRING, "unexpected type 0x%x\n", type );
310 trace( "name: %s\n", wine_dbgstr_w(V_BSTR( &val )) );
311 VariantClear( &val );
312
313 type = 0xdeadbeef;
314 VariantInit( &val );
315 hr = IWbemClassObject_Get( obj, releasedateW, 0, &val, &type, NULL );
316 ok( hr == S_OK, "failed to get release date %08x\n", hr );
317 ok( V_VT( &val ) == VT_BSTR, "unexpected variant type 0x%x\n", V_VT( &val ) );
318 ok( type == CIM_DATETIME, "unexpected type 0x%x\n", type );
319 trace( "release date: %s\n", wine_dbgstr_w(V_BSTR( &val )) );
320 VariantClear( &val );
321
322 type = 0xdeadbeef;
323 VariantInit( &val );
324 hr = IWbemClassObject_Get( obj, serialnumberW, 0, &val, &type, NULL );
325 ok( hr == S_OK, "failed to get serial number %08x\n", hr );
326 ok( V_VT( &val ) == VT_BSTR || V_VT( &val ) == VT_NULL /* Testbot VMs */,
327 "unexpected variant type 0x%x\n", V_VT( &val ) );
328 ok( type == CIM_STRING, "unexpected type 0x%x\n", type );
329 VariantClear( &val );
330
331 type = 0xdeadbeef;
332 VariantInit( &val );
333 hr = IWbemClassObject_Get( obj, smbiosbiosversionW, 0, &val, &type, NULL );
334 ok( hr == S_OK, "failed to get bios version %08x\n", hr );
335 ok( V_VT( &val ) == VT_BSTR, "unexpected variant type 0x%x\n", V_VT( &val ) );
336 ok( type == CIM_STRING, "unexpected type 0x%x\n", type );
337 trace( "bios version: %s\n", wine_dbgstr_w(V_BSTR( &val )) );
338 VariantClear( &val );
339
340 type = 0xdeadbeef;
341 VariantInit( &val );
342 hr = IWbemClassObject_Get( obj, versionW, 0, &val, &type, NULL );
343 ok( hr == S_OK, "failed to get version %08x\n", hr );
344 ok( V_VT( &val ) == VT_BSTR, "unexpected variant type 0x%x\n", V_VT( &val ) );
345 ok( type == CIM_STRING, "unexpected type 0x%x\n", type );
346 trace( "version: %s\n", wine_dbgstr_w(V_BSTR( &val )) );
347 VariantClear( &val );
348
349 IWbemClassObject_Release( obj );
350 IEnumWbemClassObject_Release( result );
351 SysFreeString( query );
352 SysFreeString( wql );
353 }
354
355 static void test_Win32_Process( IWbemServices *services )
356 {
357 static const WCHAR returnvalueW[] = {'R','e','t','u','r','n','V','a','l','u','e',0};
358 static const WCHAR getownerW[] = {'G','e','t','O','w','n','e','r',0};
359 static const WCHAR userW[] = {'U','s','e','r',0};
360 static const WCHAR domainW[] = {'D','o','m','a','i','n',0};
361 static const WCHAR processW[] = {'W','i','n','3','2','_','P','r','o','c','e','s','s',0};
362 static const WCHAR idW[] = {'I','D',0};
363 static const WCHAR fmtW[] = {'W','i','n','3','2','_','P','r','o','c','e','s','s','.',
364 'H','a','n','d','l','e','=','"','%','u','"',0};
365 static const LONG expected_flavor = WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE |
366 WBEM_FLAVOR_NOT_OVERRIDABLE |
367 WBEM_FLAVOR_ORIGIN_PROPAGATED;
368 BSTR class, method;
369 IWbemClassObject *process, *out;
370 IWbemQualifierSet *qualifiers;
371 VARIANT user, domain, retval, val;
372 LONG flavor;
373 CIMTYPE type;
374 HRESULT hr;
375
376 class = SysAllocString( processW );
377 hr = IWbemServices_GetObject( services, class, 0, NULL, &process, NULL );
378 SysFreeString( class );
379 if (hr != S_OK)
380 {
381 win_skip( "Win32_Process not available\n" );
382 return;
383 }
384 hr = IWbemClassObject_GetMethod( process, getownerW, 0, NULL, NULL );
385 ok( hr == S_OK, "failed to get GetOwner method %08x\n", hr );
386 IWbemClassObject_Release( process );
387
388 out = NULL;
389 method = SysAllocString( getownerW );
390 class = SysAllocStringLen( NULL, sizeof(fmtW)/sizeof(fmtW[0]) + 10 );
391 wsprintfW( class, fmtW, GetCurrentProcessId() );
392 hr = IWbemServices_ExecMethod( services, class, method, 0, NULL, NULL, &out, NULL );
393 ok( hr == S_OK, "failed to execute method %08x\n", hr );
394 SysFreeString( method );
395 SysFreeString( class );
396
397 type = 0xdeadbeef;
398 VariantInit( &retval );
399 hr = IWbemClassObject_Get( out, returnvalueW, 0, &retval, &type, NULL );
400 ok( hr == S_OK, "failed to get return value %08x\n", hr );
401 ok( V_VT( &retval ) == VT_I4, "unexpected variant type 0x%x\n", V_VT( &retval ) );
402 ok( !V_I4( &retval ), "unexpected error %u\n", V_I4( &retval ) );
403 ok( type == CIM_UINT32, "unexpected type 0x%x\n", type );
404
405 type = 0xdeadbeef;
406 VariantInit( &user );
407 hr = IWbemClassObject_Get( out, userW, 0, &user, &type, NULL );
408 ok( hr == S_OK, "failed to get user %08x\n", hr );
409 ok( V_VT( &user ) == VT_BSTR, "unexpected variant type 0x%x\n", V_VT( &user ) );
410 ok( type == CIM_STRING, "unexpected type 0x%x\n", type );
411 trace("%s\n", wine_dbgstr_w(V_BSTR(&user)));
412
413 type = 0xdeadbeef;
414 VariantInit( &domain );
415 hr = IWbemClassObject_Get( out, domainW, 0, &domain, &type, NULL );
416 ok( hr == S_OK, "failed to get domain %08x\n", hr );
417 ok( V_VT( &domain ) == VT_BSTR, "unexpected variant type 0x%x\n", V_VT( &domain ) );
418 ok( type == CIM_STRING, "unexpected type 0x%x\n", type );
419 trace("%s\n", wine_dbgstr_w(V_BSTR(&domain)));
420
421 hr = IWbemClassObject_GetPropertyQualifierSet( out, userW, &qualifiers );
422 ok( hr == S_OK, "failed to get qualifier set %08x\n", hr );
423
424 flavor = -1;
425 V_I4(&val) = -1;
426 V_VT(&val) = VT_ERROR;
427 hr = IWbemQualifierSet_Get( qualifiers, idW, 0, &val, &flavor );
428 ok( hr == S_OK, "got %08x\n", hr );
429 ok( flavor == expected_flavor, "got %d\n", flavor );
430 ok( V_VT(&val) == VT_I4, "got %u\n", V_VT(&val) );
431 ok( V_I4(&val) == 0, "got %u\n", V_I4(&val) );
432 VariantClear( &val );
433
434 IWbemQualifierSet_Release( qualifiers );
435 hr = IWbemClassObject_GetPropertyQualifierSet( out, domainW, &qualifiers );
436 ok( hr == S_OK, "failed to get qualifier set %08x\n", hr );
437
438 flavor = -1;
439 V_I4(&val) = -1;
440 V_VT(&val) = VT_ERROR;
441 hr = IWbemQualifierSet_Get( qualifiers, idW, 0, &val, &flavor );
442 ok( hr == S_OK, "got %08x\n", hr );
443 ok( flavor == expected_flavor, "got %d\n", flavor );
444 ok( V_VT(&val) == VT_I4, "got %u\n", V_VT(&val) );
445 ok( V_I4(&val) == 1, "got %u\n", V_I4(&val) );
446 VariantClear( &val );
447
448 IWbemQualifierSet_Release( qualifiers );
449 hr = IWbemClassObject_GetPropertyQualifierSet( out, returnvalueW, &qualifiers );
450 ok( hr == S_OK, "failed to get qualifier set %08x\n", hr );
451
452 hr = IWbemQualifierSet_Get( qualifiers, idW, 0, &val, &flavor );
453 ok( hr == WBEM_E_NOT_FOUND, "got %08x\n", hr );
454
455 IWbemQualifierSet_Release( qualifiers );
456 VariantClear( &user );
457 VariantClear( &domain );
458 IWbemClassObject_Release( out );
459 }
460
461 static void test_Win32_ComputerSystem( IWbemServices *services )
462 {
463 static const WCHAR nameW[] = {'N','a','m','e',0};
464 static const WCHAR usernameW[] = {'U','s','e','r','N','a','m','e',0};
465 static const WCHAR backslashW[] = {'\\',0};
466 static const WCHAR queryW[] =
467 {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','W','i','n','3','2','_',
468 'C','o','m','p','u','t','e','r','S','y','s','t','e','m',0};
469 BSTR wql = SysAllocString( wqlW ), query = SysAllocString( queryW );
470 IEnumWbemClassObject *result;
471 IWbemClassObject *service;
472 VARIANT value;
473 CIMTYPE type;
474 HRESULT hr;
475 WCHAR compname[MAX_COMPUTERNAME_LENGTH + 1];
476 WCHAR username[128];
477 DWORD len, count;
478
479 len = sizeof(compname) / sizeof(compname[0]);
480 if (!GetComputerNameW( compname, &len ))
481 compname[0] = 0;
482
483 lstrcpyW( username, compname );
484 lstrcatW( username, backslashW );
485 len = sizeof(username) / sizeof(username[0]) - lstrlenW( username );
486 if (!GetUserNameW( username + lstrlenW( username ), &len ))
487 username[0] = 0;
488
489 if (!compname[0] || !username[0])
490 {
491 skip( "Failed to get user or computer name\n" );
492 goto out;
493 }
494
495 hr = IWbemServices_ExecQuery( services, wql, query, 0, NULL, &result );
496 if (hr != S_OK)
497 {
498 win_skip( "Win32_ComputerSystem not available\n" );
499 goto out;
500 }
501
502 hr = IEnumWbemClassObject_Next( result, 10000, 1, &service, &count );
503 ok( hr == S_OK, "got %08x\n", hr );
504
505 type = 0xdeadbeef;
506 VariantInit( &value );
507 hr = IWbemClassObject_Get( service, nameW, 0, &value, &type, NULL );
508 ok( hr == S_OK, "failed to get computer name %08x\n", hr );
509 ok( V_VT( &value ) == VT_BSTR, "unexpected variant type 0x%x\n", V_VT( &value ) );
510 ok( type == CIM_STRING, "unexpected type 0x%x\n", type );
511 ok( !lstrcmpiW( V_BSTR( &value ), compname ), "got %s, expected %s\n", wine_dbgstr_w(V_BSTR(&value)), wine_dbgstr_w(compname) );
512 VariantClear( &value );
513
514 type = 0xdeadbeef;
515 VariantInit( &value );
516 hr = IWbemClassObject_Get( service, usernameW, 0, &value, &type, NULL );
517 ok( hr == S_OK, "failed to get computer name %08x\n", hr );
518 ok( V_VT( &value ) == VT_BSTR, "unexpected variant type 0x%x\n", V_VT( &value ) );
519 ok( type == CIM_STRING, "unexpected type 0x%x\n", type );
520 ok( !lstrcmpiW( V_BSTR( &value ), username ), "got %s, expected %s\n", wine_dbgstr_w(V_BSTR(&value)), wine_dbgstr_w(username) );
521 VariantClear( &value );
522
523 IWbemClassObject_Release( service );
524 IEnumWbemClassObject_Release( result );
525 out:
526 SysFreeString( query );
527 SysFreeString( wql );
528 }
529
530 static void test_Win32_SystemEnclosure( IWbemServices *services )
531 {
532 static const WCHAR queryW[] =
533 {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','W','i','n','3','2','_',
534 'S','y','s','t','e','m','E','n','c','l','o','s','u','r','e',0};
535 static const WCHAR captionW[] = {'C','a','p','t','i','o','n',0};
536 static const WCHAR chassistypesW[] = {'C','h','a','s','s','i','s','T','y','p','e','s',0};
537 static const WCHAR descriptionW[] = {'D','e','s','c','r','i','p','t','i','o','n',0};
538 static const WCHAR lockpresentW[] = {'L','o','c','k','P','r','e','s','e','n','t',0};
539 static const WCHAR manufacturerW[] = {'M','a','n','u','f','a','c','t','u','r','e','r',0};
540 static const WCHAR nameW[] = {'N','a','m','e',0};
541 static const WCHAR tagW[] = {'T','a','g',0};
542 BSTR wql = SysAllocString( wqlW ), query = SysAllocString( queryW );
543 IEnumWbemClassObject *result;
544 IWbemClassObject *obj;
545 CIMTYPE type;
546 ULONG count;
547 VARIANT val;
548 DWORD *data;
549 HRESULT hr;
550
551 hr = IWbemServices_ExecQuery( services, wql, query, 0, NULL, &result );
552 ok( hr == S_OK, "IWbemServices_ExecQuery failed %08x\n", hr );
553
554 hr = IEnumWbemClassObject_Next( result, 10000, 1, &obj, &count );
555 ok( hr == S_OK, "IEnumWbemClassObject_Next failed %08x\n", hr );
556
557 type = 0xdeadbeef;
558 VariantInit( &val );
559 hr = IWbemClassObject_Get( obj, captionW, 0, &val, &type, NULL );
560 ok( hr == S_OK, "failed to get caption %08x\n", hr );
561 ok( V_VT( &val ) == VT_BSTR, "unexpected variant type 0x%x\n", V_VT( &val ) );
562 ok( type == CIM_STRING, "unexpected type 0x%x\n", type );
563 trace( "caption: %s\n", wine_dbgstr_w(V_BSTR( &val )) );
564 VariantClear( &val );
565
566 type = 0xdeadbeef;
567 VariantInit( &val );
568 hr = IWbemClassObject_Get( obj, chassistypesW, 0, &val, &type, NULL );
569 ok( hr == S_OK, "failed to get chassis types %08x\n", hr );
570 todo_wine
571 ok( V_VT( &val ) == (VT_I4|VT_ARRAY), "unexpected variant type 0x%x\n", V_VT( &val ) );
572 ok( type == (CIM_UINT16|CIM_FLAG_ARRAY), "unexpected type 0x%x\n", type );
573 hr = SafeArrayAccessData( V_ARRAY( &val ), (void **)&data );
574 ok( hr == S_OK, "SafeArrayAccessData failed %x\n", hr );
575 if (SUCCEEDED(hr))
576 {
577 LONG i, lower, upper;
578
579 hr = SafeArrayGetLBound( V_ARRAY( &val ), 1, &lower );
580 ok( hr == S_OK, "SafeArrayGetLBound failed %x\n", hr );
581 hr = SafeArrayGetUBound( V_ARRAY( &val ), 1, &upper );
582 ok( hr == S_OK, "SafeArrayGetUBound failed %x\n", hr );
583 if (V_VT( &val ) == (VT_I4|VT_ARRAY))
584 {
585 for (i = 0; i < upper - lower + 1; i++)
586 trace( "chassis type: %u\n", data[i] );
587 }
588 hr = SafeArrayUnaccessData( V_ARRAY( &val ) );
589 ok( hr == S_OK, "SafeArrayUnaccessData failed %x\n", hr );
590 }
591 VariantClear( &val );
592
593 type = 0xdeadbeef;
594 VariantInit( &val );
595 hr = IWbemClassObject_Get( obj, descriptionW, 0, &val, &type, NULL );
596 ok( hr == S_OK, "failed to get description %08x\n", hr );
597 ok( V_VT( &val ) == VT_BSTR, "unexpected variant type 0x%x\n", V_VT( &val ) );
598 ok( type == CIM_STRING, "unexpected type 0x%x\n", type );
599 trace( "description: %s\n", wine_dbgstr_w(V_BSTR( &val )) );
600 VariantClear( &val );
601
602 type = 0xdeadbeef;
603 VariantInit( &val );
604 hr = IWbemClassObject_Get( obj, lockpresentW, 0, &val, &type, NULL );
605 ok( hr == S_OK, "failed to get lockpresent %08x\n", hr );
606 ok( V_VT( &val ) == VT_BOOL, "unexpected variant type 0x%x\n", V_VT( &val ) );
607 ok( type == CIM_BOOLEAN, "unexpected type 0x%x\n", type );
608 trace( "lockpresent: %u\n", V_BOOL( &val ) );
609 VariantClear( &val );
610
611 type = 0xdeadbeef;
612 VariantInit( &val );
613 hr = IWbemClassObject_Get( obj, manufacturerW, 0, &val, &type, NULL );
614 ok( hr == S_OK, "failed to get manufacturer %08x\n", hr );
615 ok( V_VT( &val ) == VT_BSTR, "unexpected variant type 0x%x\n", V_VT( &val ) );
616 ok( type == CIM_STRING, "unexpected type 0x%x\n", type );
617 trace( "manufacturer: %s\n", wine_dbgstr_w(V_BSTR( &val )) );
618 VariantClear( &val );
619
620 type = 0xdeadbeef;
621 VariantInit( &val );
622 hr = IWbemClassObject_Get( obj, nameW, 0, &val, &type, NULL );
623 ok( hr == S_OK, "failed to get name %08x\n", hr );
624 ok( V_VT( &val ) == VT_BSTR, "unexpected variant type 0x%x\n", V_VT( &val ) );
625 ok( type == CIM_STRING, "unexpected type 0x%x\n", type );
626 trace( "name: %s\n", wine_dbgstr_w(V_BSTR( &val )) );
627 VariantClear( &val );
628
629 type = 0xdeadbeef;
630 VariantInit( &val );
631 hr = IWbemClassObject_Get( obj, tagW, 0, &val, &type, NULL );
632 ok( hr == S_OK, "failed to get tag %08x\n", hr );
633 ok( V_VT( &val ) == VT_BSTR, "unexpected variant type 0x%x\n", V_VT( &val ) );
634 ok( type == CIM_STRING, "unexpected type 0x%x\n", type );
635 trace( "tag: %s\n", wine_dbgstr_w(V_BSTR( &val )) );
636 VariantClear( &val );
637
638 IWbemClassObject_Release( obj );
639 IEnumWbemClassObject_Release( result );
640 SysFreeString( query );
641 SysFreeString( wql );
642 }
643
644 static void test_StdRegProv( IWbemServices *services )
645 {
646 static const WCHAR enumkeyW[] = {'E','n','u','m','K','e','y',0};
647 static const WCHAR enumvaluesW[] = {'E','n','u','m','V','a','l','u','e','s',0};
648 static const WCHAR getstringvalueW[] = {'G','e','t','S','t','r','i','n','g','V','a','l','u','e',0};
649 static const WCHAR stdregprovW[] = {'S','t','d','R','e','g','P','r','o','v',0};
650 static const WCHAR defkeyW[] = {'h','D','e','f','K','e','y',0};
651 static const WCHAR subkeynameW[] = {'s','S','u','b','K','e','y','N','a','m','e',0};
652 static const WCHAR returnvalueW[] = {'R','e','t','u','r','n','V','a','l','u','e',0};
653 static const WCHAR namesW[] = {'s','N','a','m','e','s',0};
654 static const WCHAR typesW[] = {'T','y','p','e','s',0};
655 static const WCHAR valueW[] = {'s','V','a','l','u','e',0};
656 static const WCHAR valuenameW[] = {'s','V','a','l','u','e','N','a','m','e',0};
657 static const WCHAR programfilesW[] = {'P','r','o','g','r','a','m','F','i','l','e','s','D','i','r',0};
658 static const WCHAR windowsW[] =
659 {'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
660 'W','i','n','d','o','w','s','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n',0};
661 BSTR class = SysAllocString( stdregprovW ), method;
662 IWbemClassObject *reg, *sig_in, *in, *out;
663 VARIANT defkey, subkey, retval, names, types, value, valuename;
664 CIMTYPE type;
665 HRESULT hr;
666
667 hr = IWbemServices_GetObject( services, class, 0, NULL, &reg, NULL );
668 if (hr != S_OK)
669 {
670 win_skip( "StdRegProv not available\n" );
671 return;
672 }
673 hr = IWbemClassObject_GetMethod( reg, enumkeyW, 0, &sig_in, NULL );
674 ok( hr == S_OK, "failed to get EnumKey method %08x\n", hr );
675
676 hr = IWbemClassObject_SpawnInstance( sig_in, 0, &in );
677 ok( hr == S_OK, "failed to spawn instance %08x\n", hr );
678
679 V_VT( &defkey ) = VT_I4;
680 V_I4( &defkey ) = 0x80000002;
681 hr = IWbemClassObject_Put( in, defkeyW, 0, &defkey, 0 );
682 ok( hr == S_OK, "failed to set root %08x\n", hr );
683
684 V_VT( &subkey ) = VT_BSTR;
685 V_BSTR( &subkey ) = SysAllocString( windowsW );
686 hr = IWbemClassObject_Put( in, subkeynameW, 0, &subkey, 0 );
687 ok( hr == S_OK, "failed to set subkey %08x\n", hr );
688
689 out = NULL;
690 method = SysAllocString( enumkeyW );
691 hr = IWbemServices_ExecMethod( services, class, method, 0, NULL, in, &out, NULL );
692 ok( hr == S_OK, "failed to execute method %08x\n", hr );
693 SysFreeString( method );
694
695 type = 0xdeadbeef;
696 VariantInit( &retval );
697 hr = IWbemClassObject_Get( out, returnvalueW, 0, &retval, &type, NULL );
698 ok( hr == S_OK, "failed to get return value %08x\n", hr );
699 ok( V_VT( &retval ) == VT_I4, "unexpected variant type 0x%x\n", V_VT( &retval ) );
700 ok( !V_I4( &retval ), "unexpected error %u\n", V_UI4( &retval ) );
701 ok( type == CIM_UINT32, "unexpected type 0x%x\n", type );
702
703 type = 0xdeadbeef;
704 VariantInit( &names );
705 hr = IWbemClassObject_Get( out, namesW, 0, &names, &type, NULL );
706 ok( hr == S_OK, "failed to get names %08x\n", hr );
707 ok( V_VT( &names ) == (VT_BSTR|VT_ARRAY), "unexpected variant type 0x%x\n", V_VT( &names ) );
708 ok( type == (CIM_STRING|CIM_FLAG_ARRAY), "unexpected type 0x%x\n", type );
709
710 VariantClear( &names );
711 VariantClear( &subkey );
712 IWbemClassObject_Release( in );
713 IWbemClassObject_Release( out );
714 IWbemClassObject_Release( sig_in );
715
716 hr = IWbemClassObject_GetMethod( reg, enumvaluesW, 0, &sig_in, NULL );
717 ok( hr == S_OK, "failed to get EnumValues method %08x\n", hr );
718
719 hr = IWbemClassObject_SpawnInstance( sig_in, 0, &in );
720 ok( hr == S_OK, "failed to spawn instance %08x\n", hr );
721
722 V_VT( &defkey ) = VT_I4;
723 V_I4( &defkey ) = 0x80000002;
724 hr = IWbemClassObject_Put( in, defkeyW, 0, &defkey, 0 );
725 ok( hr == S_OK, "failed to set root %08x\n", hr );
726
727 V_VT( &subkey ) = VT_BSTR;
728 V_BSTR( &subkey ) = SysAllocString( windowsW );
729 hr = IWbemClassObject_Put( in, subkeynameW, 0, &subkey, 0 );
730 ok( hr == S_OK, "failed to set subkey %08x\n", hr );
731
732 out = NULL;
733 method = SysAllocString( enumvaluesW );
734 hr = IWbemServices_ExecMethod( services, class, method, 0, NULL, in, &out, NULL );
735 ok( hr == S_OK, "failed to execute method %08x\n", hr );
736 SysFreeString( method );
737
738 type = 0xdeadbeef;
739 VariantInit( &retval );
740 hr = IWbemClassObject_Get( out, returnvalueW, 0, &retval, &type, NULL );
741 ok( hr == S_OK, "failed to get return value %08x\n", hr );
742 ok( V_VT( &retval ) == VT_I4, "unexpected variant type 0x%x\n", V_VT( &retval ) );
743 ok( !V_I4( &retval ), "unexpected error %u\n", V_I4( &retval ) );
744 ok( type == CIM_UINT32, "unexpected type 0x%x\n", type );
745
746 type = 0xdeadbeef;
747 VariantInit( &names );
748 hr = IWbemClassObject_Get( out, namesW, 0, &names, &type, NULL );
749 ok( hr == S_OK, "failed to get names %08x\n", hr );
750 ok( V_VT( &names ) == (VT_BSTR|VT_ARRAY), "unexpected variant type 0x%x\n", V_VT( &names ) );
751 ok( type == (CIM_STRING|CIM_FLAG_ARRAY), "unexpected type 0x%x\n", type );
752
753 type = 0xdeadbeef;
754 VariantInit( &types );
755 hr = IWbemClassObject_Get( out, typesW, 0, &types, &type, NULL );
756 ok( hr == S_OK, "failed to get names %08x\n", hr );
757 ok( V_VT( &types ) == (VT_I4|VT_ARRAY), "unexpected variant type 0x%x\n", V_VT( &types ) );
758 ok( type == (CIM_SINT32|CIM_FLAG_ARRAY), "unexpected type 0x%x\n", type );
759
760 VariantClear( &types );
761 VariantClear( &names );
762 VariantClear( &subkey );
763 IWbemClassObject_Release( in );
764 IWbemClassObject_Release( out );
765 IWbemClassObject_Release( sig_in );
766
767 hr = IWbemClassObject_GetMethod( reg, getstringvalueW, 0, &sig_in, NULL );
768 ok( hr == S_OK, "failed to get GetStringValue method %08x\n", hr );
769
770 hr = IWbemClassObject_SpawnInstance( sig_in, 0, &in );
771 ok( hr == S_OK, "failed to spawn instance %08x\n", hr );
772
773 V_VT( &defkey ) = VT_I4;
774 V_I4( &defkey ) = 0x80000002;
775 hr = IWbemClassObject_Put( in, defkeyW, 0, &defkey, 0 );
776 ok( hr == S_OK, "failed to set root %08x\n", hr );
777
778 V_VT( &subkey ) = VT_BSTR;
779 V_BSTR( &subkey ) = SysAllocString( windowsW );
780 hr = IWbemClassObject_Put( in, subkeynameW, 0, &subkey, 0 );
781 ok( hr == S_OK, "failed to set subkey %08x\n", hr );
782
783 V_VT( &valuename ) = VT_BSTR;
784 V_BSTR( &valuename ) = SysAllocString( programfilesW );
785 hr = IWbemClassObject_Put( in, valuenameW, 0, &valuename, 0 );
786 ok( hr == S_OK, "failed to set value name %08x\n", hr );
787
788 out = NULL;
789 method = SysAllocString( getstringvalueW );
790 hr = IWbemServices_ExecMethod( services, class, method, 0, NULL, in, &out, NULL );
791 ok( hr == S_OK, "failed to execute method %08x\n", hr );
792 SysFreeString( method );
793
794 type = 0xdeadbeef;
795 VariantInit( &retval );
796 hr = IWbemClassObject_Get( out, returnvalueW, 0, &retval, &type, NULL );
797 ok( hr == S_OK, "failed to get return value %08x\n", hr );
798 ok( V_VT( &retval ) == VT_I4, "unexpected variant type 0x%x\n", V_VT( &retval ) );
799 ok( !V_I4( &retval ), "unexpected error %u\n", V_I4( &retval ) );
800 ok( type == CIM_UINT32, "unexpected type 0x%x\n", type );
801
802 type = 0xdeadbeef;
803 VariantInit( &value );
804 hr = IWbemClassObject_Get( out, valueW, 0, &value, &type, NULL );
805 ok( hr == S_OK, "failed to get value %08x\n", hr );
806 ok( V_VT( &value ) == VT_BSTR, "unexpected variant type 0x%x\n", V_VT( &value ) );
807 ok( type == CIM_STRING, "unexpected type 0x%x\n", type );
808
809 VariantClear( &value );
810 VariantClear( &valuename );
811 VariantClear( &subkey );
812 IWbemClassObject_Release( in );
813 IWbemClassObject_Release( out );
814 IWbemClassObject_Release( sig_in );
815
816 IWbemClassObject_Release( reg );
817 SysFreeString( class );
818 }
819
820 static HRESULT WINAPI sink_QueryInterface(
821 IWbemObjectSink *iface, REFIID riid, void **ppv )
822 {
823 *ppv = NULL;
824 if (IsEqualGUID( &IID_IUnknown, riid ) || IsEqualGUID( &IID_IWbemObjectSink, riid ))
825 {
826 *ppv = iface;
827 IWbemObjectSink_AddRef( iface );
828 return S_OK;
829 }
830 return E_NOINTERFACE;
831 }
832
833 static ULONG sink_refs;
834
835 static ULONG WINAPI sink_AddRef(
836 IWbemObjectSink *iface )
837 {
838 return ++sink_refs;
839 }
840
841 static ULONG WINAPI sink_Release(
842 IWbemObjectSink *iface )
843 {
844 return --sink_refs;
845 }
846
847 static HRESULT WINAPI sink_Indicate(
848 IWbemObjectSink *iface, LONG count, IWbemClassObject **objects )
849 {
850 trace("Indicate: %d, %p\n", count, objects);
851 return S_OK;
852 }
853
854 static HRESULT WINAPI sink_SetStatus(
855 IWbemObjectSink *iface, LONG flags, HRESULT hresult, BSTR str_param, IWbemClassObject *obj_param )
856 {
857 trace("SetStatus: %08x, %08x, %s, %p\n", flags, hresult, wine_dbgstr_w(str_param), obj_param);
858 return S_OK;
859 }
860
861 static IWbemObjectSinkVtbl sink_vtbl =
862 {
863 sink_QueryInterface,
864 sink_AddRef,
865 sink_Release,
866 sink_Indicate,
867 sink_SetStatus
868 };
869
870 static IWbemObjectSink sink = { &sink_vtbl };
871
872 static void test_notification_query_async( IWbemServices *services )
873 {
874 static const WCHAR queryW[] =
875 {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','W','i','n','3','2','_',
876 'D','e','v','i','c','e','C','h','a','n','g','e','E','v','e','n','t',0};
877 BSTR wql = SysAllocString( wqlW ), query = SysAllocString( queryW );
878 ULONG prev_sink_refs;
879 HRESULT hr;
880
881 hr = IWbemServices_ExecNotificationQueryAsync( services, wql, query, 0, NULL, NULL );
882 ok( hr == WBEM_E_INVALID_PARAMETER, "got %08x\n", hr );
883
884 prev_sink_refs = sink_refs;
885 hr = IWbemServices_ExecNotificationQueryAsync( services, wql, query, 0, NULL, &sink );
886 ok( hr == S_OK || broken(hr == WBEM_E_NOT_FOUND), "got %08x\n", hr );
887 ok( sink_refs > prev_sink_refs || broken(!sink_refs), "got %u refs\n", sink_refs );
888
889 hr = IWbemServices_CancelAsyncCall( services, &sink );
890 ok( hr == S_OK || broken(hr == WBEM_E_NOT_FOUND), "got %08x\n", hr );
891
892 SysFreeString( wql );
893 SysFreeString( query );
894 }
895
896 static void test_query_async( IWbemServices *services )
897 {
898 static const WCHAR queryW[] =
899 {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','W','i','n','3','2','_',
900 'P','r','o','c','e','s','s',0};
901 BSTR wql = SysAllocString( wqlW ), query = SysAllocString( queryW );
902 HRESULT hr;
903
904 hr = IWbemServices_ExecQueryAsync( services, wql, query, 0, NULL, NULL );
905 ok( hr == WBEM_E_INVALID_PARAMETER, "got %08x\n", hr );
906
907 hr = IWbemServices_ExecQueryAsync( services, wql, query, 0, NULL, &sink );
908 ok( hr == S_OK || broken(hr == WBEM_E_NOT_FOUND), "got %08x\n", hr );
909
910 hr = IWbemServices_CancelAsyncCall( services, NULL );
911 ok( hr == WBEM_E_INVALID_PARAMETER, "got %08x\n", hr );
912
913 hr = IWbemServices_CancelAsyncCall( services, &sink );
914 ok( hr == S_OK, "got %08x\n", hr );
915
916 SysFreeString( wql );
917 SysFreeString( query );
918 }
919
920 static void test_GetNames( IWbemServices *services )
921 {
922 static const WCHAR queryW[] =
923 {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','W','i','n','3','2','_',
924 'O','p','e','r','a','t','i','n','g','S','y','s','t','e','m',0};
925 BSTR wql = SysAllocString( wqlW ), query = SysAllocString( queryW );
926 IEnumWbemClassObject *result;
927 HRESULT hr;
928
929 hr = IWbemServices_ExecQuery( services, wql, query, 0, NULL, &result );
930 ok( hr == S_OK, "got %08x\n", hr );
931
932 for (;;)
933 {
934 IWbemClassObject *obj;
935 SAFEARRAY *names;
936 ULONG count;
937 VARIANT val;
938
939 IEnumWbemClassObject_Next( result, 10000, 1, &obj, &count );
940 if (!count) break;
941
942 VariantInit( &val );
943 hr = IWbemClassObject_GetNames( obj, NULL, WBEM_FLAG_NONSYSTEM_ONLY, &val, &names );
944 ok( hr == S_OK, "got %08x\n", hr );
945
946 SafeArrayDestroy( names );
947 IWbemClassObject_Release( obj );
948 }
949 IEnumWbemClassObject_Release( result );
950 SysFreeString( query );
951 SysFreeString( wql );
952 }
953
954 static void test_SystemSecurity( IWbemServices *services )
955 {
956 static const WCHAR systemsecurityW[] = {'_','_','S','y','s','t','e','m','S','e','c','u','r','i','t','y',0};
957 static const WCHAR getsdW[] = {'G','e','t','S','D',0};
958 static const WCHAR returnvalueW[] = {'R','e','t','u','r','n','V','a','l','u','e',0};
959 static const WCHAR sdW[] = {'S','D',0};
960 BSTR class = SysAllocString( systemsecurityW ), method;
961 IWbemClassObject *reg, *out;
962 VARIANT retval, var_sd;
963 void *data;
964 SECURITY_DESCRIPTOR_RELATIVE *sd;
965 CIMTYPE type;
966 HRESULT hr;
967 BYTE sid_admin_buffer[SECURITY_MAX_SID_SIZE];
968 SID *sid_admin = (SID*)sid_admin_buffer;
969 DWORD sid_size;
970 BOOL ret;
971
972 hr = IWbemServices_GetObject( services, class, 0, NULL, &reg, NULL );
973 if (hr != S_OK)
974 {
975 win_skip( "__SystemSecurity not available\n" );
976 return;
977 }
978
979 sid_size = sizeof(sid_admin_buffer);
980 ret = CreateWellKnownSid( WinBuiltinAdministratorsSid, NULL, sid_admin, &sid_size );
981 ok( ret, "CreateWellKnownSid failed\n" );
982
983 out = NULL;
984 method = SysAllocString( getsdW );
985 hr = IWbemServices_ExecMethod( services, class, method, 0, NULL, NULL, &out, NULL );
986 ok( hr == S_OK || hr == WBEM_E_ACCESS_DENIED, "failed to execute method %08x\n", hr );
987 SysFreeString( method );
988
989 if (SUCCEEDED(hr))
990 {
991 type = 0xdeadbeef;
992 VariantInit( &retval );
993 hr = IWbemClassObject_Get( out, returnvalueW, 0, &retval, &type, NULL );
994 ok( hr == S_OK, "failed to get return value %08x\n", hr );
995 ok( V_VT( &retval ) == VT_I4, "unexpected variant type 0x%x\n", V_VT( &retval ) );
996 ok( !V_I4( &retval ), "unexpected error %u\n", V_UI4( &retval ) );
997 ok( type == CIM_UINT32, "unexpected type 0x%x\n", type );
998
999 type = 0xdeadbeef;
1000 VariantInit( &var_sd );
1001 hr = IWbemClassObject_Get( out, sdW, 0, &var_sd, &type, NULL );
1002 ok( hr == S_OK, "failed to get names %08x\n", hr );
1003 ok( V_VT( &var_sd ) == (VT_UI1|VT_ARRAY), "unexpected variant type 0x%x\n", V_VT( &var_sd ) );
1004 ok( type == (CIM_UINT8|CIM_FLAG_ARRAY), "unexpected type 0x%x\n", type );
1005
1006 hr = SafeArrayAccessData( V_ARRAY( &var_sd ), &data );
1007 ok( hr == S_OK, "SafeArrayAccessData failed %x\n", hr );
1008 if (SUCCEEDED(hr))
1009 {
1010 sd = data;
1011
1012 ok( (sd->Control & SE_SELF_RELATIVE) == SE_SELF_RELATIVE, "relative flag unset\n" );
1013 ok( sd->Owner != 0, "no owner SID\n");
1014 ok( sd->Group != 0, "no owner SID\n");
1015 ok( EqualSid( (PSID)((LPBYTE)sd + sd->Owner), sid_admin ), "unexpected owner SID\n" );
1016 ok( EqualSid( (PSID)((LPBYTE)sd + sd->Group), sid_admin ), "unexpected group SID\n" );
1017
1018 hr = SafeArrayUnaccessData( V_ARRAY( &var_sd ) );
1019 ok( hr == S_OK, "SafeArrayUnaccessData failed %x\n", hr );
1020 }
1021
1022 VariantClear( &var_sd );
1023 IWbemClassObject_Release( out );
1024 }
1025 else if (hr == WBEM_E_ACCESS_DENIED)
1026 win_skip( "insufficient privs to test __SystemSecurity\n" );
1027
1028 SysFreeString( class );
1029 }
1030
1031 START_TEST(query)
1032 {
1033 static const WCHAR cimv2W[] = {'R','O','O','T','\\','C','I','M','V','2',0};
1034 BSTR path = SysAllocString( cimv2W );
1035 IWbemLocator *locator;
1036 IWbemServices *services;
1037 HRESULT hr;
1038
1039 CoInitialize( NULL );
1040 CoInitializeSecurity( NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_DEFAULT,
1041 RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, NULL );
1042 hr = CoCreateInstance( &CLSID_WbemLocator, NULL, CLSCTX_INPROC_SERVER, &IID_IWbemLocator,
1043 (void **)&locator );
1044 if (hr != S_OK)
1045 {
1046 win_skip("can't create instance of WbemLocator\n");
1047 return;
1048 }
1049 hr = IWbemLocator_ConnectServer( locator, path, NULL, NULL, NULL, 0, NULL, NULL, &services );
1050 ok( hr == S_OK, "failed to get IWbemServices interface %08x\n", hr );
1051
1052 hr = CoSetProxyBlanket( (IUnknown *)services, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL,
1053 RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE );
1054 ok( hr == S_OK, "failed to set proxy blanket %08x\n", hr );
1055
1056 test_select( services );
1057 test_Win32_Bios( services );
1058 test_Win32_Process( services );
1059 test_Win32_Service( services );
1060 test_Win32_ComputerSystem( services );
1061 test_Win32_SystemEnclosure( services );
1062 test_StdRegProv( services );
1063 test_notification_query_async( services );
1064 test_query_async( services );
1065 test_GetNames( services );
1066 test_SystemSecurity( services );
1067
1068 SysFreeString( path );
1069 IWbemServices_Release( services );
1070 IWbemLocator_Release( locator );
1071 CoUninitialize();
1072 }