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