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 
exec_query(IWbemServices * services,const WCHAR * str,IEnumWbemClassObject ** result)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             IWbemQualifierSet *qualifiers;
50             SAFEARRAY *names;
51 
52             IEnumWbemClassObject_Next( *result, 10000, 1, &obj, &count );
53             if (!count) break;
54 
55             if (IWbemClassObject_Get( obj, captionW, 0, &var, NULL, NULL ) == WBEM_S_NO_ERROR)
56             {
57                 trace("caption: %s\n", wine_dbgstr_w(V_BSTR(&var)));
58                 VariantClear( &var );
59             }
60             if (IWbemClassObject_Get( obj, descriptionW, 0, &var, NULL, NULL ) == WBEM_S_NO_ERROR)
61             {
62                 trace("description: %s\n", wine_dbgstr_w(V_BSTR(&var)));
63                 VariantClear( &var );
64             }
65 
66             hr = IWbemClassObject_GetQualifierSet( obj, &qualifiers );
67             ok( hr == S_OK, "got %08x\n", hr );
68 
69             hr = IWbemQualifierSet_GetNames( qualifiers, 0, &names );
70             ok( hr == S_OK, "got %08x\n", hr );
71 
72             SafeArrayDestroy( names );
73             IWbemQualifierSet_Release( qualifiers );
74             IWbemClassObject_Release( obj );
75         }
76     }
77     SysFreeString( wql );
78     SysFreeString( query );
79     return hr;
80 }
81 
test_select(IWbemServices * services)82 static void test_select( IWbemServices *services )
83 {
84     static const WCHAR emptyW[] = {0};
85     static const WCHAR sqlW[] = {'S','Q','L',0};
86     static const WCHAR query1[] =
87         {'S','E','L','E','C','T',' ','H','O','T','F','I','X','I','D',' ','F','R','O','M',' ',
88          '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};
89     static const WCHAR query2[] =
90         {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','W','i','n','3','2','_','B','I','O','S',0};
91     static const WCHAR query3[] =
92         {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','W','i','n','3','2','_',
93          'L','o','g','i','c','a','l','D','i','s','k',' ','W','H','E','R','E',' ',
94          '\"','N','T','F','S','\"',' ','=',' ','F','i','l','e','S','y','s','t','e','m',0};
95     static const WCHAR query4[] =
96         {'S','E','L','E','C','T',' ','a',' ','F','R','O','M',' ','b',0};
97     static const WCHAR query5[] =
98         {'S','E','L','E','C','T',' ','a',' ','F','R','O','M',' ','W','i','n','3','2','_','B','i','o','s',0};
99     static const WCHAR query6[] =
100         {'S','E','L','E','C','T',' ','D','e','s','c','r','i','p','t','i','o','n',' ','F','R','O','M',' ',
101          'W','i','n','3','2','_','B','i','o','s',0};
102     static const WCHAR query7[] =
103         {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','W','i','n','3','2','_',
104          'P','r','o','c','e','s','s',' ','W','H','E','R','E',' ','C','a','p','t','i','o','n',' ',
105          'L','I','K','E',' ','\'','%','%','R','E','G','E','D','I','T','%','\'',0};
106     static const WCHAR query8[] =
107         {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','W','i','n','3','2','_',
108          'D','i','s','k','D','r','i','v','e',' ','W','H','E','R','E',' ','D','e','v','i','c','e','I','D','=',
109          '\"','\\','\\','\\','\\','.','\\','\\','P','H','Y','S','I','C','A','L','D','R','I','V','E','0','\"',0};
110     static const WCHAR query9[] =
111         {'S','E','L','E','C','T','\n','a','\r','F','R','O','M','\t','b',0};
112     static const WCHAR query10[] =
113         {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','W','i','n','3','2','_',
114          'P','r','o','c','e','s','s',' ','W','H','E','R','E',' ','C','a','p','t','i','o','n',' ',
115          'L','I','K','E',' ','"','%','f','i','r','e','f','o','x','.','e','x','e','"',0};
116     static const WCHAR query11[] =
117         {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
118          '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',' ',
119          'a','v','a','i','l','a','b','i','l','i','t','y',' ','=',' ','\'','3','\'',0};
120     static const WCHAR query12[] =
121         {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','W','i','n','3','2','_','B','I','O','S',
122          ' ','W','H','E','R','E',' ','N','A','M','E',' ','<','>',' ','N','U','L','L', 0};
123     static const WCHAR query13[] =
124         {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','W','i','n','3','2','_','B','I','O','S',
125          ' ','W','H','E','R','E',' ','N','U','L','L',' ','=',' ','N','A','M','E', 0};
126     static const WCHAR query14[] =
127         {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','W','i','n','3','2','_',
128          'L','o','g','i','c','a','l','D','i','s','k','T','o','P','a','r','t','i','t','i','o','n',0};
129     static const WCHAR query15[] =
130         {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','W','i','n','3','2','_',
131          'D','i','s','k','D','r','i','v','e','T','o','D','i','s','k','P','a','r','t','i','t','i','o','n',0};
132     static const WCHAR *test[] = { query1, query2, query3, query4, query5, query6, query7, query8, query9, query10,
133                                    query11, query12, query13, query14, query15 };
134     HRESULT hr;
135     IEnumWbemClassObject *result;
136     BSTR wql = SysAllocString( wqlW );
137     BSTR sql = SysAllocString( sqlW );
138     BSTR query = SysAllocString( query1 );
139     UINT i;
140 
141     hr = IWbemServices_ExecQuery( services, NULL, NULL, 0, NULL, &result );
142     ok( hr == WBEM_E_INVALID_PARAMETER, "query failed %08x\n", hr );
143 
144     hr = IWbemServices_ExecQuery( services, NULL, query, 0, NULL, &result );
145     ok( hr == WBEM_E_INVALID_PARAMETER, "query failed %08x\n", hr );
146 
147     hr = IWbemServices_ExecQuery( services, wql, NULL, 0, NULL, &result );
148     ok( hr == WBEM_E_INVALID_PARAMETER, "query failed %08x\n", hr );
149 
150     hr = IWbemServices_ExecQuery( services, sql, query, 0, NULL, &result );
151     ok( hr == WBEM_E_INVALID_QUERY_TYPE, "query failed %08x\n", hr );
152 
153     hr = IWbemServices_ExecQuery( services, sql, NULL, 0, NULL, &result );
154     ok( hr == WBEM_E_INVALID_PARAMETER, "query failed %08x\n", hr );
155 
156     SysFreeString( query );
157     query = SysAllocString( emptyW );
158     hr = IWbemServices_ExecQuery( services, wql, query, 0, NULL, &result );
159     ok( hr == WBEM_E_INVALID_PARAMETER, "query failed %08x\n", hr );
160 
161     for (i = 0; i < ARRAY_SIZE( test ); i++)
162     {
163         hr = exec_query( services, test[i], &result );
164         ok( hr == S_OK, "query %u failed: %08x\n", i, hr );
165         if (result) IEnumWbemClassObject_Release( result );
166     }
167 
168     SysFreeString( wql );
169     SysFreeString( sql );
170     SysFreeString( query );
171 }
172 
test_associators(IWbemServices * services)173 static void test_associators( IWbemServices *services )
174 {
175     static const WCHAR query1[] =
176         {'A','S','S','O','C','I','A','T','O','R','S',' ',' ','O','F','{','W','i','n','3','2','_',
177          'L','o','g','i','c','a','l','D','i','s','k','.','D','e','v','i','c','e','I','D','=','"','C',':','"','}',0};
178     static const WCHAR query2[] =
179         {'A','S','S','O','C','I','A','T','O','R','S',' ','O','F',' ','{','W','i','n','3','2','_',
180          'L','o','g','i','c','a','l','D','i','s','k','.','D','e','v','i','c','e','I','D','=','"','C',':','"','}',' ',
181          'W','H','E','R','E',' ','A','s','s','o','c','C','l','a','s','s','=','W','i','n','3','2','_',
182          'L','o','g','i','c','a','l','D','i','s','k','T','o','P','a','r','t','i','t','i','o','n',0};
183     static const WCHAR query3[] =
184         {'A','S','S','O','C','I','A','T','O','R','S',' ',' ','O','F',' ','{','W','i','n','3','2','_',
185          'L','o','g','i','c','a','l','D','i','s','k','.','D','e','v','i','c','e','I','D','}',0};
186     static const WCHAR query4[] =
187         {'A','S','S','O','C','I','A','T','O','R','S',' ',' ','O','F',' ','{','W','i','n','3','2','_',
188          'D','i','s','k','D','r','i','v','e','.','D','e','v','i','c','e','I','D','=',
189          '\'','\\','\\','.','\\','P','H','Y','S','I','C','A','L','D','R','I','V','E','0','\'','}',0};
190     static const WCHAR query5[] =
191         {'A','S','S','O','C','I','A','T','O','R','S',' ','O','F',' ','{','W','i','n','3','2','_',
192          'L','o','g','i','c','a','l','D','i','s','k','.','D','e','v','i','c','e','I','D','=','"','C',':','"','}',' ',
193          'W','H','E','R','E',' ','A','s','s','o','c','C','l','a','s','s','=','W','i','n','3','2','_',
194          'L','o','g','i','c','a','l','D','i','s','k','T','o','P','a','r','t','i','t','i','o','n',' ',
195          'C','l','a','s','s','D','e','f','s','O','n','l','y',0};
196     static const WCHAR query6[] =
197         {'A','S','S','O','C','I','A','T','O','R','S',' ','O','F',' ','{','W','i','n','3','2','_',
198          'L','o','g','i','c','a','l','D','i','s','k','.','D','e','v','i','c','e','I','D','=','"','C',':','"','}',' ',
199          'W','H','E','R','E',' ','C','l','a','s','s','D','e','f','s','O','n','l','y',0};
200     static const WCHAR query7[] =
201         {'A','S','S','O','C','I','A','T','O','R','S',' ','O','F',' ','{','W','i','n','3','2','_',
202          'L','o','g','i','c','a','l','D','i','s','k','.','D','e','v','i','c','e','I','D','=','"','C',':','"','}',' ',
203          'W','H','E','R','E',' ','C','l','a','s','s','D','e','f','s','O','n','l','y',' ',
204          'A','s','s','o','c','C','l','a','s','s',' ','=',' ','W','i','n','3','2','_',
205          'L','o','g','i','c','a','l','D','i','s','k','T','o','P','a','r','t','i','t','i','o','n',0};
206     static const WCHAR *test[] = { query1, query2, query3, query4, query5, query6, query7 };
207     HRESULT hr;
208     IEnumWbemClassObject *result;
209     UINT i;
210 
211     for (i = 0; i < ARRAY_SIZE( test ); i++)
212     {
213         hr = exec_query( services, test[i], &result );
214         ok( hr == S_OK, "query %u failed: %08x\n", i, hr );
215         if (result) IEnumWbemClassObject_Release( result );
216     }
217 }
218 
_check_property(ULONG line,IWbemClassObject * obj,const WCHAR * prop,VARTYPE vartype,CIMTYPE cimtype)219 static void _check_property( ULONG line, IWbemClassObject *obj, const WCHAR *prop, VARTYPE vartype, CIMTYPE cimtype )
220 {
221     CIMTYPE type = 0xdeadbeef;
222     VARIANT val;
223     HRESULT hr;
224 
225     VariantInit( &val );
226     hr = IWbemClassObject_Get( obj, prop, 0, &val, &type, NULL );
227     ok( hr == S_OK, "%u: failed to get description %08x\n", line, hr );
228     ok( V_VT( &val ) == vartype, "%u: unexpected variant type 0x%x\n", line, V_VT(&val) );
229     ok( type == cimtype, "%u: unexpected type 0x%x\n", line, type );
230     switch (V_VT(&val))
231     {
232     case VT_BSTR:
233         trace( "%s: %s\n", wine_dbgstr_w(prop), wine_dbgstr_w(V_BSTR(&val)) );
234         break;
235     case VT_I2:
236         trace( "%s: %d\n", wine_dbgstr_w(prop), V_I2(&val) );
237         break;
238     case VT_I4:
239         trace( "%s: %d\n", wine_dbgstr_w(prop), V_I4(&val) );
240         break;
241     case VT_R4:
242         trace( "%s: %f\n", wine_dbgstr_w(prop), V_R4(&val) );
243         break;
244     default:
245         break;
246     }
247     VariantClear( &val );
248 }
249 #define check_property(a,b,c,d) _check_property(__LINE__,a,b,c,d)
250 
test_Win32_Service(IWbemServices * services)251 static void test_Win32_Service( IWbemServices *services )
252 {
253     static const WCHAR pauseserviceW[] = {'P','a','u','s','e','S','e','r','v','i','c','e',0};
254     static const WCHAR processidW[] = {'P','r','o','c','e','s','s','I','D',0};
255     static const WCHAR resumeserviceW[] = {'R','e','s','u','m','e','S','e','r','v','i','c','e',0};
256     static const WCHAR returnvalueW[] = {'R','e','t','u','r','n','V','a','l','u','e',0};
257     static const WCHAR serviceW[] = {'W','i','n','3','2','_','S','e','r','v','i','c','e','.',
258         'N','a','m','e','=','"','S','p','o','o','l','e','r','"',0};
259     static const WCHAR startserviceW[] = {'S','t','a','r','t','S','e','r','v','i','c','e',0};
260     static const WCHAR stateW[] = {'S','t','a','t','e',0};
261     static const WCHAR stoppedW[] = {'S','t','o','p','p','e','d',0};
262     static const WCHAR stopserviceW[] = {'S','t','o','p','S','e','r','v','i','c','e',0};
263     static const WCHAR emptyW[] = {0};
264     BSTR class = SysAllocString( serviceW ), empty = SysAllocString( emptyW ), method;
265     IWbemClassObject *service, *out;
266     VARIANT state, retval;
267     CIMTYPE type;
268     HRESULT hr;
269 
270     hr = IWbemServices_GetObject( services, class, 0, NULL, &service, NULL );
271     if (hr != S_OK)
272     {
273         win_skip( "Win32_Service not available\n" );
274         goto out;
275     }
276 
277     check_property( service, processidW, VT_I4, CIM_UINT32 );
278     type = 0xdeadbeef;
279     VariantInit( &state );
280     hr = IWbemClassObject_Get( service, stateW, 0, &state, &type, NULL );
281     ok( hr == S_OK, "failed to get service state %08x\n", hr );
282     ok( V_VT( &state ) == VT_BSTR, "unexpected variant type 0x%x\n", V_VT( &state ) );
283     ok( type == CIM_STRING, "unexpected type 0x%x\n", type );
284 
285     if (!lstrcmpW( V_BSTR( &state ), stoppedW ))
286     {
287         out = NULL;
288         method = SysAllocString( startserviceW );
289         hr = IWbemServices_ExecMethod( services, class, method, 0, NULL, NULL, &out, NULL );
290         ok( hr == S_OK, "failed to execute method %08x\n", hr );
291         SysFreeString( method );
292 
293         VariantInit( &retval );
294         hr = IWbemClassObject_Get( out, returnvalueW, 0, &retval, NULL, NULL );
295         ok( hr == S_OK, "failed to get return value %08x\n", hr );
296         ok( !V_I4( &retval ), "unexpected error %u\n", V_UI4( &retval ) );
297         IWbemClassObject_Release( out );
298     }
299     out = NULL;
300     method = SysAllocString( pauseserviceW );
301     hr = IWbemServices_ExecMethod( services, class, method, 0, NULL, NULL, &out, NULL );
302     ok( hr == S_OK, "failed to execute method %08x\n", hr );
303     SysFreeString( method );
304 
305     VariantInit( &retval );
306     hr = IWbemClassObject_Get( out, returnvalueW, 0, &retval, NULL, NULL );
307     ok( hr == S_OK, "failed to get return value %08x\n", hr );
308     ok( V_I4( &retval ), "unexpected success\n" );
309     IWbemClassObject_Release( out );
310 
311     out = NULL;
312     method = SysAllocString( resumeserviceW );
313     hr = IWbemServices_ExecMethod( services, class, method, 0, NULL, NULL, &out, NULL );
314     ok( hr == S_OK, "failed to execute method %08x\n", hr );
315     SysFreeString( method );
316 
317     VariantInit( &retval );
318     hr = IWbemClassObject_Get( out, returnvalueW, 0, &retval, NULL, NULL );
319     ok( hr == S_OK, "failed to get return value %08x\n", hr );
320     ok( V_I4( &retval ), "unexpected success\n" );
321     IWbemClassObject_Release( out );
322 
323     if (!lstrcmpW( V_BSTR( &state ), stoppedW ))
324     {
325         out = NULL;
326         method = SysAllocString( stopserviceW );
327         hr = IWbemServices_ExecMethod( services, class, method, 0, NULL, NULL, &out, NULL );
328         ok( hr == S_OK, "failed to execute method %08x\n", hr );
329         SysFreeString( method );
330 
331         VariantInit( &retval );
332         hr = IWbemClassObject_Get( out, returnvalueW, 0, &retval, NULL, NULL );
333         ok( hr == S_OK, "failed to get return value %08x\n", hr );
334         ok( !V_I4( &retval ), "unexpected error %u\n", V_UI4( &retval ) );
335         IWbemClassObject_Release( out );
336     }
337     VariantClear( &state );
338     IWbemClassObject_Release( service );
339 
340     service = NULL;
341     hr = IWbemServices_GetObject( services, NULL, 0, NULL, &service, NULL );
342     ok( hr == S_OK, "got %08x\n", hr );
343     if (service) IWbemClassObject_Release( service );
344 
345     service = NULL;
346     hr = IWbemServices_GetObject( services, empty, 0, NULL, &service, NULL );
347     ok( hr == S_OK, "got %08x\n", hr );
348     if (service) IWbemClassObject_Release( service );
349 
350 out:
351     SysFreeString( empty );
352     SysFreeString( class );
353 }
354 
test_Win32_Bios(IWbemServices * services)355 static void test_Win32_Bios( IWbemServices *services )
356 {
357     static const WCHAR queryW[] =
358         {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','W','i','n','3','2','_','B','i','o','s',0};
359     static const WCHAR descriptionW[] = {'D','e','s','c','r','i','p','t','i','o','n',0};
360     static const WCHAR identificationcodeW[] = {'I','d','e','n','t','i','f','i','c','a','t','i','o','n','C','o','d','e',0};
361     static const WCHAR manufacturerW[] = {'M','a','n','u','f','a','c','t','u','r','e','r',0};
362     static const WCHAR nameW[] = {'N','a','m','e',0};
363     static const WCHAR releasedateW[] = {'R','e','l','e','a','s','e','D','a','t','e',0};
364     static const WCHAR serialnumberW[] = {'S','e','r','i','a','l','N','u','m','b','e','r',0};
365     static const WCHAR smbiosbiosversionW[] = {'S','M','B','I','O','S','B','I','O','S','V','e','r','s','i','o','n',0};
366     static const WCHAR smbiosmajorversionW[] = {'S','M','B','I','O','S','M','a','j','o','r','V','e','r','s','i','o','n',0};
367     static const WCHAR smbiosminorversionW[] = {'S','M','B','I','O','S','M','i','n','o','r','V','e','r','s','i','o','n',0};
368     static const WCHAR versionW[] = {'V','e','r','s','i','o','n',0};
369     BSTR wql = SysAllocString( wqlW ), query = SysAllocString( queryW );
370     IEnumWbemClassObject *result;
371     IWbemClassObject *obj;
372     CIMTYPE type;
373     ULONG count;
374     VARIANT val;
375     HRESULT hr;
376 
377     hr = IWbemServices_ExecQuery( services, wql, query, 0, NULL, &result );
378     ok( hr == S_OK, "IWbemServices_ExecQuery failed %08x\n", hr );
379 
380     hr = IEnumWbemClassObject_Next( result, 10000, 1, &obj, &count );
381     ok( hr == S_OK, "IEnumWbemClassObject_Next failed %08x\n", hr );
382 
383     check_property( obj, descriptionW, VT_BSTR, CIM_STRING );
384     check_property( obj, identificationcodeW, VT_NULL, CIM_STRING );
385     check_property( obj, manufacturerW, VT_BSTR, CIM_STRING );
386     check_property( obj, nameW, VT_BSTR, CIM_STRING );
387     check_property( obj, releasedateW, VT_BSTR, CIM_DATETIME );
388 
389     type = 0xdeadbeef;
390     VariantInit( &val );
391     hr = IWbemClassObject_Get( obj, serialnumberW, 0, &val, &type, NULL );
392     ok( hr == S_OK, "failed to get serial number %08x\n", hr );
393     ok( V_VT( &val ) == VT_BSTR || V_VT( &val ) == VT_NULL /* Testbot VMs */,
394         "unexpected variant type 0x%x\n", V_VT( &val ) );
395     ok( type == CIM_STRING, "unexpected type 0x%x\n", type );
396     VariantClear( &val );
397 
398     check_property( obj, smbiosbiosversionW, VT_BSTR, CIM_STRING );
399     check_property( obj, smbiosmajorversionW, VT_I4, CIM_UINT16 );
400     check_property( obj, smbiosminorversionW, VT_I4, CIM_UINT16 );
401     check_property( obj, versionW, VT_BSTR, CIM_STRING );
402 
403     IWbemClassObject_Release( obj );
404     IEnumWbemClassObject_Release( result );
405     SysFreeString( query );
406     SysFreeString( wql );
407 }
408 
test_Win32_Baseboard(IWbemServices * services)409 static void test_Win32_Baseboard( IWbemServices *services )
410 {
411     static const WCHAR queryW[] =
412         {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','W','i','n','3','2','_','B','a','s','e','b','o','a','r','d',0};
413     static const WCHAR manufacturerW[] = {'M','a','n','u','f','a','c','t','u','r','e','r',0};
414     static const WCHAR modelW[] = {'M','o','d','e','l',0};
415     static const WCHAR nameW[] = {'N','a','m','e',0};
416     static const WCHAR productW[] = {'P','r','o','d','u','c','t',0};
417     static const WCHAR tagW[] = {'T','a','g',0};
418     static const WCHAR versionW[] = {'V','e','r','s','i','o','n',0};
419     BSTR wql = SysAllocString( wqlW ), query = SysAllocString( queryW );
420     IEnumWbemClassObject *result;
421     IWbemClassObject *obj;
422     CIMTYPE type;
423     ULONG count;
424     VARIANT val;
425     HRESULT hr;
426 
427     hr = IWbemServices_ExecQuery( services, wql, query, 0, NULL, &result );
428     ok( hr == S_OK, "IWbemServices_ExecQuery failed %08x\n", hr );
429 
430     hr = IEnumWbemClassObject_Next( result, 10000, 1, &obj, &count );
431     if (hr != S_OK)
432     {
433         win_skip( "Win32_Baseboard not available\n" );
434         return;
435     }
436     ok( hr == S_OK, "IEnumWbemClassObject_Next failed %08x\n", hr );
437 
438     check_property( obj, manufacturerW, VT_BSTR, CIM_STRING );
439 
440     type = 0xdeadbeef;
441     VariantInit( &val );
442     hr = IWbemClassObject_Get( obj, modelW, 0, &val, &type, NULL );
443     ok( hr == S_OK, "failed to get model %08x\n", hr );
444     ok( V_VT( &val ) == VT_BSTR || V_VT( &val ) == VT_NULL, "unexpected variant type 0x%x\n", V_VT( &val ) );
445     ok( type == CIM_STRING, "unexpected type 0x%x\n", type );
446     trace( "model: %s\n", wine_dbgstr_w(V_BSTR(&val)) );
447     VariantClear( &val );
448 
449     check_property( obj, nameW, VT_BSTR, CIM_STRING );
450     check_property( obj, productW, VT_BSTR, CIM_STRING );
451     check_property( obj, tagW, VT_BSTR, CIM_STRING );
452     check_property( obj, versionW, VT_BSTR, CIM_STRING );
453 
454     IWbemClassObject_Release( obj );
455     IEnumWbemClassObject_Release( result );
456     SysFreeString( query );
457     SysFreeString( wql );
458 }
459 
test_Win32_Process(IWbemServices * services,BOOL use_full_path)460 static void test_Win32_Process( IWbemServices *services, BOOL use_full_path )
461 {
462     static const WCHAR returnvalueW[] = {'R','e','t','u','r','n','V','a','l','u','e',0};
463     static const WCHAR getownerW[] = {'G','e','t','O','w','n','e','r',0};
464     static const WCHAR userW[] = {'U','s','e','r',0};
465     static const WCHAR domainW[] = {'D','o','m','a','i','n',0};
466     static const WCHAR processW[] = {'W','i','n','3','2','_','P','r','o','c','e','s','s',0};
467     static const WCHAR idW[] = {'I','D',0};
468     static const WCHAR fmtW[] = {'W','i','n','3','2','_','P','r','o','c','e','s','s','.',
469         'H','a','n','d','l','e','=','"','%','u','"',0};
470     static const WCHAR full_path_fmt[] =
471         {'\\','\\','%','s','\\','R','O','O','T','\\','C','I','M','V','2',':',0};
472     static const LONG expected_flavor = WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE |
473                                         WBEM_FLAVOR_NOT_OVERRIDABLE |
474                                         WBEM_FLAVOR_ORIGIN_PROPAGATED;
475     WCHAR full_path[MAX_COMPUTERNAME_LENGTH + ARRAY_SIZE(full_path_fmt)];
476     BSTR class, method;
477     IWbemClassObject *process, *sig_in, *out;
478     IWbemQualifierSet *qualifiers;
479     VARIANT retval, val;
480     DWORD full_path_len = 0;
481     LONG flavor;
482     CIMTYPE type;
483     HRESULT hr;
484 
485     if (use_full_path)
486     {
487         WCHAR server[MAX_COMPUTERNAME_LENGTH+1];
488 
489         full_path_len = ARRAY_SIZE(server);
490         ok( GetComputerNameW(server, &full_path_len), "GetComputerName failed\n" );
491         full_path_len = wsprintfW(full_path, full_path_fmt, server);
492     }
493 
494     class = SysAllocStringLen( NULL, full_path_len + ARRAY_SIZE( processW ) );
495     memcpy( class, full_path, full_path_len * sizeof(WCHAR) );
496     memcpy( class + full_path_len, processW, sizeof(processW) );
497     hr = IWbemServices_GetObject( services, class, 0, NULL, &process, NULL );
498     SysFreeString( class );
499     if (hr != S_OK)
500     {
501         win_skip( "Win32_Process not available\n" );
502         return;
503     }
504     sig_in = (void*)0xdeadbeef;
505     hr = IWbemClassObject_GetMethod( process, getownerW, 0, &sig_in, NULL );
506     ok( hr == S_OK, "failed to get GetOwner method %08x\n", hr );
507     ok( !sig_in, "sig_in != NULL\n");
508     IWbemClassObject_Release( process );
509 
510     out = NULL;
511     method = SysAllocString( getownerW );
512     class = SysAllocStringLen( NULL, full_path_len + ARRAY_SIZE( fmtW ) + 10 );
513     memcpy( class, full_path, full_path_len * sizeof(WCHAR) );
514     wsprintfW( class + full_path_len, fmtW, GetCurrentProcessId() );
515     hr = IWbemServices_ExecMethod( services, class, method, 0, NULL, NULL, &out, NULL );
516     ok( hr == S_OK, "failed to execute method %08x\n", hr );
517     SysFreeString( method );
518     SysFreeString( class );
519 
520     type = 0xdeadbeef;
521     VariantInit( &retval );
522     hr = IWbemClassObject_Get( out, returnvalueW, 0, &retval, &type, NULL );
523     ok( hr == S_OK, "failed to get return value %08x\n", hr );
524     ok( V_VT( &retval ) == VT_I4, "unexpected variant type 0x%x\n", V_VT( &retval ) );
525     ok( !V_I4( &retval ), "unexpected error %u\n", V_I4( &retval ) );
526     ok( type == CIM_UINT32, "unexpected type 0x%x\n", type );
527 
528     check_property( out, userW, VT_BSTR, CIM_STRING );
529     check_property( out, domainW, VT_BSTR, CIM_STRING );
530 
531     hr = IWbemClassObject_GetPropertyQualifierSet( out, userW, &qualifiers );
532     ok( hr == S_OK, "failed to get qualifier set %08x\n", hr );
533 
534     flavor = -1;
535     V_I4(&val) = -1;
536     V_VT(&val) = VT_ERROR;
537     hr = IWbemQualifierSet_Get( qualifiers, idW, 0, &val, &flavor );
538     ok( hr == S_OK, "got %08x\n", hr );
539     ok( flavor == expected_flavor, "got %d\n", flavor );
540     ok( V_VT(&val) == VT_I4, "got %u\n", V_VT(&val) );
541     ok( V_I4(&val) == 0, "got %u\n", V_I4(&val) );
542     VariantClear( &val );
543 
544     IWbemQualifierSet_Release( qualifiers );
545     hr = IWbemClassObject_GetPropertyQualifierSet( out, domainW, &qualifiers );
546     ok( hr == S_OK, "failed to get qualifier set %08x\n", hr );
547 
548     flavor = -1;
549     V_I4(&val) = -1;
550     V_VT(&val) = VT_ERROR;
551     hr = IWbemQualifierSet_Get( qualifiers, idW, 0, &val, &flavor );
552     ok( hr == S_OK, "got %08x\n", hr );
553     ok( flavor == expected_flavor, "got %d\n", flavor );
554     ok( V_VT(&val) == VT_I4, "got %u\n", V_VT(&val) );
555     ok( V_I4(&val) == 1, "got %u\n", V_I4(&val) );
556     VariantClear( &val );
557 
558     IWbemQualifierSet_Release( qualifiers );
559     hr = IWbemClassObject_GetPropertyQualifierSet( out, returnvalueW, &qualifiers );
560     ok( hr == S_OK, "failed to get qualifier set %08x\n", hr );
561 
562     hr = IWbemQualifierSet_Get( qualifiers, idW, 0, &val, &flavor );
563     ok( hr == WBEM_E_NOT_FOUND, "got %08x\n", hr );
564 
565     IWbemQualifierSet_Release( qualifiers );
566     IWbemClassObject_Release( out );
567 }
568 
test_Win32_ComputerSystem(IWbemServices * services)569 static void test_Win32_ComputerSystem( IWbemServices *services )
570 {
571     static const WCHAR backslashW[] = {'\\',0};
572     static const WCHAR memorytypeW[] = {'M','e','m','o','r','y','T','y','p','e',0};
573     static const WCHAR modelW[] = {'M','o','d','e','l',0};
574     static const WCHAR nameW[] = {'N','a','m','e',0};
575     static const WCHAR usernameW[] = {'U','s','e','r','N','a','m','e',0};
576     static const WCHAR numprocessorsW[] =
577         {'N','u','m','b','e','r','O','f','P','r','o','c','e','s','s','o','r','s',0};
578     static const WCHAR numlogicalprocessorsW[] =
579         {'N','u','m','b','e','r','O','f','L','o','g','i','c','a','l','P','r','o','c','e','s','s','o','r','s',0};
580     static const WCHAR queryW[] =
581         {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','W','i','n','3','2','_',
582          'C','o','m','p','u','t','e','r','S','y','s','t','e','m',0};
583     BSTR wql = SysAllocString( wqlW ), query = SysAllocString( queryW );
584     IEnumWbemClassObject *result;
585     IWbemClassObject *obj;
586     VARIANT value;
587     CIMTYPE type;
588     HRESULT hr;
589     WCHAR compname[MAX_COMPUTERNAME_LENGTH + 1];
590     WCHAR username[128];
591     DWORD len, count;
592 
593     len = ARRAY_SIZE( compname );
594     if (!GetComputerNameW( compname, &len ))
595         compname[0] = 0;
596 
597     lstrcpyW( username, compname );
598     lstrcatW( username, backslashW );
599     len = ARRAY_SIZE( username ) - lstrlenW( username );
600     if (!GetUserNameW( username + lstrlenW( username ), &len ))
601         username[0] = 0;
602 
603     if (!compname[0] || !username[0])
604     {
605         skip( "Failed to get user or computer name\n" );
606         goto out;
607     }
608 
609     hr = IWbemServices_ExecQuery( services, wql, query, 0, NULL, &result );
610     if (hr != S_OK)
611     {
612         win_skip( "Win32_ComputerSystem not available\n" );
613         goto out;
614     }
615 
616     hr = IEnumWbemClassObject_Next( result, 10000, 1, &obj, &count );
617     ok( hr == S_OK, "got %08x\n", hr );
618 
619     type = 0xdeadbeef;
620     VariantInit( &value );
621     hr = IWbemClassObject_Get( obj, memorytypeW, 0, &value, &type, NULL );
622     ok( hr == WBEM_E_NOT_FOUND, "got %08x\n", hr );
623 
624     check_property( obj, modelW, VT_BSTR, CIM_STRING );
625 
626     type = 0xdeadbeef;
627     VariantInit( &value );
628     hr = IWbemClassObject_Get( obj, nameW, 0, &value, &type, NULL );
629     ok( hr == S_OK, "failed to get computer name %08x\n", hr );
630     ok( V_VT( &value ) == VT_BSTR, "unexpected variant type 0x%x\n", V_VT( &value ) );
631     ok( type == CIM_STRING, "unexpected type 0x%x\n", type );
632     ok( !lstrcmpiW( V_BSTR( &value ), compname ), "got %s, expected %s\n", wine_dbgstr_w(V_BSTR(&value)), wine_dbgstr_w(compname) );
633     VariantClear( &value );
634 
635     type = 0xdeadbeef;
636     VariantInit( &value );
637     hr = IWbemClassObject_Get( obj, numlogicalprocessorsW, 0, &value, &type, NULL );
638     ok( hr == S_OK || broken(hr == WBEM_E_NOT_FOUND) /* win2k3 */, "got %08x\n", hr );
639     if (hr == S_OK)
640     {
641         ok( V_VT( &value ) == VT_I4, "unexpected variant type 0x%x\n", V_VT( &value ) );
642         ok( type == CIM_UINT32, "unexpected type 0x%x\n", type );
643         trace( "numlogicalprocessors %u\n", V_I4( &value ) );
644     }
645 
646     check_property( obj, numprocessorsW, VT_I4, CIM_UINT32 );
647 
648     type = 0xdeadbeef;
649     VariantInit( &value );
650     hr = IWbemClassObject_Get( obj, usernameW, 0, &value, &type, NULL );
651     ok( hr == S_OK, "failed to get computer name %08x\n", hr );
652     ok( V_VT( &value ) == VT_BSTR, "unexpected variant type 0x%x\n", V_VT( &value ) );
653     ok( type == CIM_STRING, "unexpected type 0x%x\n", type );
654     ok( !lstrcmpiW( V_BSTR( &value ), username ), "got %s, expected %s\n", wine_dbgstr_w(V_BSTR(&value)), wine_dbgstr_w(username) );
655     VariantClear( &value );
656 
657     IWbemClassObject_Release( obj );
658     IEnumWbemClassObject_Release( result );
659 out:
660     SysFreeString( query );
661     SysFreeString( wql );
662 }
663 
test_Win32_SystemEnclosure(IWbemServices * services)664 static void test_Win32_SystemEnclosure( IWbemServices *services )
665 {
666     static const WCHAR queryW[] =
667         {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','W','i','n','3','2','_',
668          'S','y','s','t','e','m','E','n','c','l','o','s','u','r','e',0};
669     static const WCHAR captionW[] = {'C','a','p','t','i','o','n',0};
670     static const WCHAR chassistypesW[] = {'C','h','a','s','s','i','s','T','y','p','e','s',0};
671     static const WCHAR descriptionW[] = {'D','e','s','c','r','i','p','t','i','o','n',0};
672     static const WCHAR lockpresentW[] = {'L','o','c','k','P','r','e','s','e','n','t',0};
673     static const WCHAR manufacturerW[] = {'M','a','n','u','f','a','c','t','u','r','e','r',0};
674     static const WCHAR nameW[] = {'N','a','m','e',0};
675     static const WCHAR tagW[] = {'T','a','g',0};
676     BSTR wql = SysAllocString( wqlW ), query = SysAllocString( queryW );
677     IEnumWbemClassObject *result;
678     IWbemClassObject *obj;
679     CIMTYPE type;
680     ULONG count;
681     VARIANT val;
682     DWORD *data;
683     HRESULT hr;
684 
685     hr = IWbemServices_ExecQuery( services, wql, query, 0, NULL, &result );
686     ok( hr == S_OK, "IWbemServices_ExecQuery failed %08x\n", hr );
687 
688     hr = IEnumWbemClassObject_Next( result, 10000, 1, &obj, &count );
689     ok( hr == S_OK, "IEnumWbemClassObject_Next failed %08x\n", hr );
690 
691     check_property( obj, captionW, VT_BSTR, CIM_STRING );
692 
693     type = 0xdeadbeef;
694     VariantInit( &val );
695     hr = IWbemClassObject_Get( obj, chassistypesW, 0, &val, &type, NULL );
696     ok( hr == S_OK, "failed to get chassis types %08x\n", hr );
697     ok( V_VT( &val ) == (VT_I4|VT_ARRAY), "unexpected variant type 0x%x\n", V_VT( &val ) );
698     ok( type == (CIM_UINT16|CIM_FLAG_ARRAY), "unexpected type 0x%x\n", type );
699     hr = SafeArrayAccessData( V_ARRAY( &val ), (void **)&data );
700     ok( hr == S_OK, "SafeArrayAccessData failed %x\n", hr );
701     if (SUCCEEDED(hr))
702     {
703         LONG i, lower, upper;
704 
705         hr = SafeArrayGetLBound( V_ARRAY( &val ), 1, &lower );
706         ok( hr == S_OK, "SafeArrayGetLBound failed %x\n", hr );
707         hr = SafeArrayGetUBound( V_ARRAY( &val ), 1, &upper );
708         ok( hr == S_OK, "SafeArrayGetUBound failed %x\n", hr );
709         if (V_VT( &val ) == (VT_I4|VT_ARRAY))
710         {
711             for (i = 0; i < upper - lower + 1; i++)
712                 trace( "chassis type: %u\n", data[i] );
713         }
714         hr = SafeArrayUnaccessData( V_ARRAY( &val ) );
715         ok( hr == S_OK, "SafeArrayUnaccessData failed %x\n", hr );
716     }
717     VariantClear( &val );
718 
719     check_property( obj, descriptionW, VT_BSTR, CIM_STRING );
720     check_property( obj, lockpresentW, VT_BOOL, CIM_BOOLEAN );
721     check_property( obj, manufacturerW, VT_BSTR, CIM_STRING );
722     check_property( obj, nameW, VT_BSTR, CIM_STRING );
723     check_property( obj, tagW, VT_BSTR, CIM_STRING );
724 
725     IWbemClassObject_Release( obj );
726     IEnumWbemClassObject_Release( result );
727     SysFreeString( query );
728     SysFreeString( wql );
729 }
730 
test_StdRegProv(IWbemServices * services)731 static void test_StdRegProv( IWbemServices *services )
732 {
733     static const WCHAR createkeyW[] = {'C','r','e','a','t','e','K','e','y',0};
734     static const WCHAR enumkeyW[] = {'E','n','u','m','K','e','y',0};
735     static const WCHAR enumvaluesW[] = {'E','n','u','m','V','a','l','u','e','s',0};
736     static const WCHAR getstringvalueW[] = {'G','e','t','S','t','r','i','n','g','V','a','l','u','e',0};
737     static const WCHAR stdregprovW[] = {'S','t','d','R','e','g','P','r','o','v',0};
738     static const WCHAR defkeyW[] = {'h','D','e','f','K','e','y',0};
739     static const WCHAR subkeynameW[] = {'s','S','u','b','K','e','y','N','a','m','e',0};
740     static const WCHAR returnvalueW[] = {'R','e','t','u','r','n','V','a','l','u','e',0};
741     static const WCHAR namesW[] = {'s','N','a','m','e','s',0};
742     static const WCHAR typesW[] = {'T','y','p','e','s',0};
743     static const WCHAR valueW[] = {'s','V','a','l','u','e',0};
744     static const WCHAR valuenameW[] = {'s','V','a','l','u','e','N','a','m','e',0};
745     static const WCHAR programfilesW[] = {'P','r','o','g','r','a','m','F','i','l','e','s','D','i','r',0};
746     static const WCHAR windowsW[] =
747         {'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
748          'W','i','n','d','o','w','s','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n',0};
749     static const WCHAR regtestW[] =
750         {'S','o','f','t','w','a','r','e','\\','S','t','d','R','e','g','P','r','o','v','T','e','s','t',0};
751     BSTR class = SysAllocString( stdregprovW ), method, name;
752     IWbemClassObject *reg, *sig_in, *sig_out, *in, *out;
753     VARIANT defkey, subkey, retval, valuename;
754     CIMTYPE type;
755     HRESULT hr;
756     LONG res;
757 
758     hr = IWbemServices_GetObject( services, class, 0, NULL, &reg, NULL );
759     if (hr != S_OK)
760     {
761         win_skip( "StdRegProv not available\n" );
762         return;
763     }
764 
765     hr = IWbemClassObject_BeginMethodEnumeration( reg, 0 );
766     ok( hr == S_OK, "got %08x\n", hr );
767 
768     while (IWbemClassObject_NextMethod( reg, 0, &name, &sig_in, &sig_out ) == S_OK)
769     {
770         SysFreeString( name );
771         IWbemClassObject_Release( sig_in );
772         IWbemClassObject_Release( sig_out );
773     }
774 
775     hr = IWbemClassObject_EndMethodEnumeration( reg );
776     ok( hr == S_OK, "got %08x\n", hr );
777 
778     hr = IWbemClassObject_BeginEnumeration( reg, 0 );
779     ok( hr == S_OK, "got %08x\n", hr );
780 
781     while (IWbemClassObject_Next( reg, 0, &name, NULL, NULL, NULL ) == S_OK)
782         SysFreeString( name );
783 
784     hr = IWbemClassObject_EndEnumeration( reg );
785     ok( hr == S_OK, "got %08x\n", hr );
786 
787     hr = IWbemClassObject_GetMethod( reg, createkeyW, 0, &sig_in, NULL );
788     ok( hr == S_OK, "failed to get CreateKey method %08x\n", hr );
789 
790     hr = IWbemClassObject_SpawnInstance( sig_in, 0, &in );
791     ok( hr == S_OK, "failed to spawn instance %08x\n", hr );
792 
793     V_VT( &defkey ) = VT_I4;
794     V_I4( &defkey ) = 0x80000001;
795     hr = IWbemClassObject_Put( in, defkeyW, 0, &defkey, 0 );
796     ok( hr == S_OK, "failed to set root %08x\n", hr );
797 
798     V_VT( &subkey ) = VT_BSTR;
799     V_BSTR( &subkey ) = SysAllocString( regtestW );
800     hr = IWbemClassObject_Put( in, subkeynameW, 0, &subkey, 0 );
801     ok( hr == S_OK, "failed to set subkey %08x\n", hr );
802 
803     out = NULL;
804     method = SysAllocString( createkeyW );
805     hr = IWbemServices_ExecMethod( services, class, method, 0, NULL, in, &out, NULL );
806     ok( hr == S_OK, "failed to execute method %08x\n", hr );
807     SysFreeString( method );
808 
809     type = 0xdeadbeef;
810     VariantInit( &retval );
811     hr = IWbemClassObject_Get( out, returnvalueW, 0, &retval, &type, NULL );
812     ok( hr == S_OK, "failed to get return value %08x\n", hr );
813     ok( V_VT( &retval ) == VT_I4, "unexpected variant type 0x%x\n", V_VT( &retval ) );
814     ok( !V_I4( &retval ), "unexpected error %u\n", V_UI4( &retval ) );
815     ok( type == CIM_UINT32, "unexpected type 0x%x\n", type );
816 
817     res = RegDeleteKeyW( HKEY_CURRENT_USER, regtestW );
818     ok( !res, "got %d\n", res );
819 
820     VariantClear( &subkey );
821     IWbemClassObject_Release( in );
822     IWbemClassObject_Release( out );
823     IWbemClassObject_Release( sig_in );
824 
825     hr = IWbemClassObject_GetMethod( reg, enumkeyW, 0, &sig_in, NULL );
826     ok( hr == S_OK, "failed to get EnumKey method %08x\n", hr );
827 
828     hr = IWbemClassObject_SpawnInstance( sig_in, 0, &in );
829     ok( hr == S_OK, "failed to spawn instance %08x\n", hr );
830 
831     V_VT( &defkey ) = VT_I4;
832     V_I4( &defkey ) = 0x80000002;
833     hr = IWbemClassObject_Put( in, defkeyW, 0, &defkey, 0 );
834     ok( hr == S_OK, "failed to set root %08x\n", hr );
835 
836     V_VT( &subkey ) = VT_BSTR;
837     V_BSTR( &subkey ) = SysAllocString( windowsW );
838     hr = IWbemClassObject_Put( in, subkeynameW, 0, &subkey, 0 );
839     ok( hr == S_OK, "failed to set subkey %08x\n", hr );
840 
841     out = NULL;
842     method = SysAllocString( enumkeyW );
843     hr = IWbemServices_ExecMethod( services, class, method, 0, NULL, in, &out, NULL );
844     ok( hr == S_OK, "failed to execute method %08x\n", hr );
845     SysFreeString( method );
846 
847     type = 0xdeadbeef;
848     VariantInit( &retval );
849     hr = IWbemClassObject_Get( out, returnvalueW, 0, &retval, &type, NULL );
850     ok( hr == S_OK, "failed to get return value %08x\n", hr );
851     ok( V_VT( &retval ) == VT_I4, "unexpected variant type 0x%x\n", V_VT( &retval ) );
852     ok( !V_I4( &retval ), "unexpected error %u\n", V_UI4( &retval ) );
853     ok( type == CIM_UINT32, "unexpected type 0x%x\n", type );
854 
855     check_property( out, namesW, VT_BSTR|VT_ARRAY, CIM_STRING|CIM_FLAG_ARRAY );
856 
857     VariantClear( &subkey );
858     IWbemClassObject_Release( in );
859     IWbemClassObject_Release( out );
860     IWbemClassObject_Release( sig_in );
861 
862     hr = IWbemClassObject_GetMethod( reg, enumvaluesW, 0, &sig_in, NULL );
863     ok( hr == S_OK, "failed to get EnumValues method %08x\n", hr );
864 
865     hr = IWbemClassObject_SpawnInstance( sig_in, 0, &in );
866     ok( hr == S_OK, "failed to spawn instance %08x\n", hr );
867 
868     V_VT( &defkey ) = VT_I4;
869     V_I4( &defkey ) = 0x80000002;
870     hr = IWbemClassObject_Put( in, defkeyW, 0, &defkey, 0 );
871     ok( hr == S_OK, "failed to set root %08x\n", hr );
872 
873     V_VT( &subkey ) = VT_BSTR;
874     V_BSTR( &subkey ) = SysAllocString( windowsW );
875     hr = IWbemClassObject_Put( in, subkeynameW, 0, &subkey, 0 );
876     ok( hr == S_OK, "failed to set subkey %08x\n", hr );
877 
878     out = NULL;
879     method = SysAllocString( enumvaluesW );
880     hr = IWbemServices_ExecMethod( services, class, method, 0, NULL, in, &out, NULL );
881     ok( hr == S_OK, "failed to execute method %08x\n", hr );
882     SysFreeString( method );
883 
884     type = 0xdeadbeef;
885     VariantInit( &retval );
886     hr = IWbemClassObject_Get( out, returnvalueW, 0, &retval, &type, NULL );
887     ok( hr == S_OK, "failed to get return value %08x\n", hr );
888     ok( V_VT( &retval ) == VT_I4, "unexpected variant type 0x%x\n", V_VT( &retval ) );
889     ok( !V_I4( &retval ), "unexpected error %u\n", V_I4( &retval ) );
890     ok( type == CIM_UINT32, "unexpected type 0x%x\n", type );
891 
892     check_property( out, namesW, VT_BSTR|VT_ARRAY, CIM_STRING|CIM_FLAG_ARRAY );
893     check_property( out, typesW, VT_I4|VT_ARRAY, CIM_SINT32|CIM_FLAG_ARRAY );
894 
895     VariantClear( &subkey );
896     IWbemClassObject_Release( in );
897     IWbemClassObject_Release( out );
898     IWbemClassObject_Release( sig_in );
899 
900     hr = IWbemClassObject_GetMethod( reg, getstringvalueW, 0, &sig_in, NULL );
901     ok( hr == S_OK, "failed to get GetStringValue method %08x\n", hr );
902 
903     hr = IWbemClassObject_SpawnInstance( sig_in, 0, &in );
904     ok( hr == S_OK, "failed to spawn instance %08x\n", hr );
905 
906     V_VT( &defkey ) = VT_I4;
907     V_I4( &defkey ) = 0x80000002;
908     hr = IWbemClassObject_Put( in, defkeyW, 0, &defkey, 0 );
909     ok( hr == S_OK, "failed to set root %08x\n", hr );
910 
911     V_VT( &subkey ) = VT_BSTR;
912     V_BSTR( &subkey ) = SysAllocString( windowsW );
913     hr = IWbemClassObject_Put( in, subkeynameW, 0, &subkey, 0 );
914     ok( hr == S_OK, "failed to set subkey %08x\n", hr );
915 
916     V_VT( &valuename ) = VT_BSTR;
917     V_BSTR( &valuename ) = SysAllocString( programfilesW );
918     hr = IWbemClassObject_Put( in, valuenameW, 0, &valuename, 0 );
919     ok( hr == S_OK, "failed to set value name %08x\n", hr );
920 
921     out = NULL;
922     method = SysAllocString( getstringvalueW );
923     hr = IWbemServices_ExecMethod( services, class, method, 0, NULL, in, &out, NULL );
924     ok( hr == S_OK, "failed to execute method %08x\n", hr );
925     SysFreeString( method );
926 
927     type = 0xdeadbeef;
928     VariantInit( &retval );
929     hr = IWbemClassObject_Get( out, returnvalueW, 0, &retval, &type, NULL );
930     ok( hr == S_OK, "failed to get return value %08x\n", hr );
931     ok( V_VT( &retval ) == VT_I4, "unexpected variant type 0x%x\n", V_VT( &retval ) );
932     ok( !V_I4( &retval ), "unexpected error %u\n", V_I4( &retval ) );
933     ok( type == CIM_UINT32, "unexpected type 0x%x\n", type );
934 
935     check_property( out, valueW, VT_BSTR, CIM_STRING );
936 
937     VariantClear( &valuename );
938     VariantClear( &subkey );
939     IWbemClassObject_Release( in );
940     IWbemClassObject_Release( out );
941     IWbemClassObject_Release( sig_in );
942 
943     IWbemClassObject_Release( reg );
944     SysFreeString( class );
945 }
946 
sink_QueryInterface(IWbemObjectSink * iface,REFIID riid,void ** ppv)947 static HRESULT WINAPI sink_QueryInterface(
948     IWbemObjectSink *iface, REFIID riid, void **ppv )
949 {
950     *ppv = NULL;
951     if (IsEqualGUID( &IID_IUnknown, riid ) || IsEqualGUID( &IID_IWbemObjectSink, riid ))
952     {
953         *ppv = iface;
954         IWbemObjectSink_AddRef( iface );
955         return S_OK;
956     }
957     return E_NOINTERFACE;
958 }
959 
960 static ULONG sink_refs;
961 
sink_AddRef(IWbemObjectSink * iface)962 static ULONG WINAPI sink_AddRef(
963     IWbemObjectSink *iface )
964 {
965     return ++sink_refs;
966 }
967 
sink_Release(IWbemObjectSink * iface)968 static ULONG WINAPI sink_Release(
969     IWbemObjectSink *iface )
970 {
971     return --sink_refs;
972 }
973 
sink_Indicate(IWbemObjectSink * iface,LONG count,IWbemClassObject ** objects)974 static HRESULT WINAPI sink_Indicate(
975     IWbemObjectSink *iface, LONG count, IWbemClassObject **objects )
976 {
977     trace("Indicate: %d, %p\n", count, objects);
978     return S_OK;
979 }
980 
sink_SetStatus(IWbemObjectSink * iface,LONG flags,HRESULT hresult,BSTR str_param,IWbemClassObject * obj_param)981 static HRESULT WINAPI sink_SetStatus(
982     IWbemObjectSink *iface, LONG flags, HRESULT hresult, BSTR str_param, IWbemClassObject *obj_param )
983 {
984     trace("SetStatus: %08x, %08x, %s, %p\n", flags, hresult, wine_dbgstr_w(str_param), obj_param);
985     return S_OK;
986 }
987 
988 static IWbemObjectSinkVtbl sink_vtbl =
989 {
990     sink_QueryInterface,
991     sink_AddRef,
992     sink_Release,
993     sink_Indicate,
994     sink_SetStatus
995 };
996 
997 static IWbemObjectSink sink = { &sink_vtbl };
998 
test_notification_query_async(IWbemServices * services)999 static void test_notification_query_async( IWbemServices *services )
1000 {
1001     static const WCHAR queryW[] =
1002         {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','W','i','n','3','2','_',
1003          'D','e','v','i','c','e','C','h','a','n','g','e','E','v','e','n','t',0};
1004     BSTR wql = SysAllocString( wqlW ), query = SysAllocString( queryW );
1005     ULONG prev_sink_refs;
1006     HRESULT hr;
1007 
1008     hr = IWbemServices_ExecNotificationQueryAsync( services, wql, query, 0, NULL, NULL );
1009     ok( hr == WBEM_E_INVALID_PARAMETER, "got %08x\n", hr );
1010 
1011     prev_sink_refs = sink_refs;
1012     hr = IWbemServices_ExecNotificationQueryAsync( services, wql, query, 0, NULL, &sink );
1013     ok( hr == S_OK || broken(hr == WBEM_E_NOT_FOUND), "got %08x\n", hr );
1014     ok( sink_refs > prev_sink_refs || broken(!sink_refs), "got %u refs\n", sink_refs );
1015 
1016     hr =  IWbemServices_CancelAsyncCall( services, &sink );
1017     ok( hr == S_OK || broken(hr == WBEM_E_NOT_FOUND), "got %08x\n", hr );
1018 
1019     SysFreeString( wql );
1020     SysFreeString( query );
1021 }
1022 
test_query_async(IWbemServices * services)1023 static void test_query_async( IWbemServices *services )
1024 {
1025     static const WCHAR queryW[] =
1026         {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','W','i','n','3','2','_',
1027          'P','r','o','c','e','s','s',0};
1028     BSTR wql = SysAllocString( wqlW ), query = SysAllocString( queryW );
1029     HRESULT hr;
1030 
1031     hr = IWbemServices_ExecQueryAsync( services, wql, query, 0, NULL, NULL );
1032     ok( hr == WBEM_E_INVALID_PARAMETER, "got %08x\n", hr );
1033 
1034     hr = IWbemServices_ExecQueryAsync( services, wql, query, 0, NULL, &sink );
1035     ok( hr == S_OK || broken(hr == WBEM_E_NOT_FOUND), "got %08x\n", hr );
1036 
1037     hr =  IWbemServices_CancelAsyncCall( services, NULL );
1038     ok( hr == WBEM_E_INVALID_PARAMETER, "got %08x\n", hr );
1039 
1040     hr =  IWbemServices_CancelAsyncCall( services, &sink );
1041     ok( hr == S_OK, "got %08x\n", hr );
1042 
1043     SysFreeString( wql );
1044     SysFreeString( query );
1045 }
1046 
test_query_semisync(IWbemServices * services)1047 static void test_query_semisync( IWbemServices *services )
1048 {
1049     static const WCHAR queryW[] =
1050         {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','W','i','n','3','2','_','D','u','m','m','y',0};
1051     BSTR wql = SysAllocString( wqlW ), query = SysAllocString( queryW );
1052     IEnumWbemClassObject *result;
1053     IWbemClassObject *obj;
1054     ULONG count;
1055     HRESULT hr;
1056 
1057     hr = IWbemServices_ExecQuery( services, wql, query, WBEM_FLAG_RETURN_IMMEDIATELY | WBEM_FLAG_FORWARD_ONLY,
1058             NULL, &result );
1059     ok( hr == S_OK, "got %08x\n", hr );
1060 
1061     count = 1;
1062     obj = (void *)0xdeadbeef;
1063     hr = IEnumWbemClassObject_Next( result, -1, 1, &obj, &count );
1064 todo_wine
1065     ok( hr == WBEM_E_INVALID_CLASS, "Unexpected hr %#x.\n", hr );
1066     ok( count == 0, "Unexpected count %u.\n", count );
1067     ok( obj == (void *)0xdeadbeef, "Got object %p\n", obj );
1068 
1069     IEnumWbemClassObject_Release( result );
1070 
1071     SysFreeString( wql );
1072     SysFreeString( query );
1073 }
1074 
test_GetNames(IWbemServices * services)1075 static void test_GetNames( IWbemServices *services )
1076 {
1077     static const WCHAR queryW[] =
1078         {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','W','i','n','3','2','_',
1079          'O','p','e','r','a','t','i','n','g','S','y','s','t','e','m',0};
1080     BSTR wql = SysAllocString( wqlW ), query = SysAllocString( queryW );
1081     IEnumWbemClassObject *result;
1082     HRESULT hr;
1083 
1084     hr = IWbemServices_ExecQuery( services, wql, query, 0, NULL, &result );
1085     ok( hr == S_OK, "got %08x\n", hr );
1086 
1087     for (;;)
1088     {
1089         IWbemClassObject *obj;
1090         SAFEARRAY *names;
1091         ULONG count;
1092         VARIANT val;
1093 
1094         IEnumWbemClassObject_Next( result, 10000, 1, &obj, &count );
1095         if (!count) break;
1096 
1097         VariantInit( &val );
1098         hr = IWbemClassObject_GetNames( obj, NULL, WBEM_FLAG_NONSYSTEM_ONLY, &val, &names );
1099         ok( hr == S_OK, "got %08x\n", hr );
1100 
1101         SafeArrayDestroy( names );
1102         IWbemClassObject_Release( obj );
1103     }
1104     IEnumWbemClassObject_Release( result );
1105     SysFreeString( query );
1106     SysFreeString( wql );
1107 }
1108 
test_SystemSecurity(IWbemServices * services)1109 static void test_SystemSecurity( IWbemServices *services )
1110 {
1111     static const WCHAR systemsecurityW[] = {'_','_','S','y','s','t','e','m','S','e','c','u','r','i','t','y',0};
1112     static const WCHAR getsdW[] = {'G','e','t','S','D',0};
1113     static const WCHAR returnvalueW[] = {'R','e','t','u','r','n','V','a','l','u','e',0};
1114     static const WCHAR sdW[] = {'S','D',0};
1115     BSTR class = SysAllocString( systemsecurityW ), method;
1116     IWbemClassObject *reg, *out;
1117     VARIANT retval, var_sd;
1118     void *data;
1119     SECURITY_DESCRIPTOR_RELATIVE *sd;
1120     CIMTYPE type;
1121     HRESULT hr;
1122     BYTE sid_admin_buffer[SECURITY_MAX_SID_SIZE];
1123     SID *sid_admin = (SID*)sid_admin_buffer;
1124     DWORD sid_size;
1125     BOOL ret;
1126 
1127     hr = IWbemServices_GetObject( services, class, 0, NULL, &reg, NULL );
1128     if (hr != S_OK)
1129     {
1130         win_skip( "__SystemSecurity not available\n" );
1131         return;
1132     }
1133     IWbemClassObject_Release( reg );
1134 
1135     sid_size = sizeof(sid_admin_buffer);
1136     ret = CreateWellKnownSid( WinBuiltinAdministratorsSid, NULL, sid_admin, &sid_size );
1137     ok( ret, "CreateWellKnownSid failed\n" );
1138 
1139     out = NULL;
1140     method = SysAllocString( getsdW );
1141     hr = IWbemServices_ExecMethod( services, class, method, 0, NULL, NULL, &out, NULL );
1142     ok( hr == S_OK || hr == WBEM_E_ACCESS_DENIED, "failed to execute method %08x\n", hr );
1143     SysFreeString( method );
1144 
1145     if (SUCCEEDED(hr))
1146     {
1147         type = 0xdeadbeef;
1148         VariantInit( &retval );
1149         hr = IWbemClassObject_Get( out, returnvalueW, 0, &retval, &type, NULL );
1150         ok( hr == S_OK, "failed to get return value %08x\n", hr );
1151         ok( V_VT( &retval ) == VT_I4, "unexpected variant type 0x%x\n", V_VT( &retval ) );
1152         ok( !V_I4( &retval ), "unexpected error %u\n", V_UI4( &retval ) );
1153         ok( type == CIM_UINT32, "unexpected type 0x%x\n", type );
1154 
1155         type = 0xdeadbeef;
1156         VariantInit( &var_sd );
1157         hr = IWbemClassObject_Get( out, sdW, 0, &var_sd, &type, NULL );
1158         ok( hr == S_OK, "failed to get names %08x\n", hr );
1159         ok( V_VT( &var_sd ) == (VT_UI1|VT_ARRAY), "unexpected variant type 0x%x\n", V_VT( &var_sd ) );
1160         ok( type == (CIM_UINT8|CIM_FLAG_ARRAY), "unexpected type 0x%x\n", type );
1161 
1162         hr = SafeArrayAccessData( V_ARRAY( &var_sd ), &data );
1163         ok( hr == S_OK, "SafeArrayAccessData failed %x\n", hr );
1164         if (SUCCEEDED(hr))
1165         {
1166             sd = data;
1167 
1168             ok( (sd->Control & SE_SELF_RELATIVE) == SE_SELF_RELATIVE, "relative flag unset\n" );
1169             ok( sd->Owner != 0, "no owner SID\n");
1170             ok( sd->Group != 0, "no owner SID\n");
1171             ok( EqualSid( (PSID)((LPBYTE)sd + sd->Owner), sid_admin ), "unexpected owner SID\n" );
1172             ok( EqualSid( (PSID)((LPBYTE)sd + sd->Group), sid_admin ), "unexpected group SID\n" );
1173 
1174             hr = SafeArrayUnaccessData( V_ARRAY( &var_sd ) );
1175             ok( hr == S_OK, "SafeArrayUnaccessData failed %x\n", hr );
1176         }
1177 
1178         VariantClear( &var_sd );
1179         IWbemClassObject_Release( out );
1180     }
1181     else if (hr == WBEM_E_ACCESS_DENIED)
1182         win_skip( "insufficient privs to test __SystemSecurity\n" );
1183 
1184     SysFreeString( class );
1185 }
1186 
test_Win32_OperatingSystem(IWbemServices * services)1187 static void test_Win32_OperatingSystem( IWbemServices *services )
1188 {
1189     static const WCHAR queryW[] =
1190         {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','W','i','n','3','2','_',
1191          'O','p','e','r','a','t','i','n','g','S','y','s','t','e','m',0};
1192     static const WCHAR buildnumberW[] = {'B','u','i','l','d','N','u','m','b','e','r',0};
1193     static const WCHAR captionW[] = {'C','a','p','t','i','o','n',0};
1194     static const WCHAR csdversionW[] = {'C','S','D','V','e','r','s','i','o','n',0};
1195     static const WCHAR csnameW[] = {'C','S','N','a','m','e',0};
1196     static const WCHAR currenttimezoneW[] = {'C','u','r','r','e','n','t','T','i','m','e','Z','o','n','e',0};
1197     static const WCHAR freephysicalmemoryW[] = {'F','r','e','e','P','h','y','s','i','c','a','l','M','e','m','o','r','y',0};
1198     static const WCHAR manufacturerW[] = {'M','a','n','u','f','a','c','t','u','r','e','r',0};
1199     static const WCHAR nameW[] = {'N','a','m','e',0};
1200     static const WCHAR operatingsystemskuW[] = {'O','p','e','r','a','t','i','n','g','S','y','s','t','e','m','S','K','U',0};
1201     static const WCHAR osproductsuiteW[] = {'O','S','P','r','o','d','u','c','t','S','u','i','t','e',0};
1202     static const WCHAR ostypeW[] = {'O','S','T','y','p','e',0};
1203     static const WCHAR suitemaskW[] = {'S','u','i','t','e','M','a','s','k',0};
1204     static const WCHAR versionW[] = {'V','e','r','s','i','o','n',0};
1205     static const WCHAR servicepackmajorW[] =
1206         {'S','e','r','v','i','c','e','P','a','c','k','M','a','j','o','r','V','e','r','s','i','o','n',0};
1207     static const WCHAR servicepackminorW[] =
1208         {'S','e','r','v','i','c','e','P','a','c','k','M','i','n','o','r','V','e','r','s','i','o','n',0};
1209     static const WCHAR systemdriveW[] =
1210         {'S','y','s','t','e','m','D','r','i','v','e',0};
1211     static const WCHAR totalvisiblememorysizeW[] =
1212         {'T','o','t','a','l','V','i','s','i','b','l','e','M','e','m','o','r','y','S','i','z','e',0};
1213     static const WCHAR totalvirtualmemorysizeW[] =
1214         {'T','o','t','a','l','V','i','r','t','u','a','l','M','e','m','o','r','y','S','i','z','e',0};
1215     BSTR wql = SysAllocString( wqlW ), query = SysAllocString( queryW );
1216     IEnumWbemClassObject *result;
1217     IWbemClassObject *obj;
1218     CIMTYPE type;
1219     ULONG count;
1220     VARIANT val;
1221     HRESULT hr;
1222 
1223     hr = IWbemServices_ExecQuery( services, wql, query, 0, NULL, &result );
1224     ok( hr == S_OK, "IWbemServices_ExecQuery failed %08x\n", hr );
1225 
1226     hr = IEnumWbemClassObject_Next( result, 10000, 1, &obj, &count );
1227     ok( hr == S_OK, "IEnumWbemClassObject_Next failed %08x\n", hr );
1228 
1229     hr = IWbemClassObject_BeginEnumeration( obj, 0 );
1230     ok( hr == S_OK, "got %08x\n", hr );
1231 
1232     while (IWbemClassObject_Next( obj, 0, NULL, NULL, NULL, NULL ) == S_OK) {}
1233 
1234     hr = IWbemClassObject_EndEnumeration( obj );
1235     ok( hr == S_OK, "got %08x\n", hr );
1236 
1237     check_property( obj, buildnumberW, VT_BSTR, CIM_STRING );
1238     check_property( obj, captionW, VT_BSTR, CIM_STRING );
1239 
1240     type = 0xdeadbeef;
1241     VariantInit( &val );
1242     hr = IWbemClassObject_Get( obj, csdversionW, 0, &val, &type, NULL );
1243     ok( hr == S_OK, "failed to get csdversion %08x\n", hr );
1244     ok( V_VT( &val ) == VT_BSTR || V_VT( &val ) == VT_NULL, "unexpected variant type 0x%x\n", V_VT( &val ) );
1245     ok( type == CIM_STRING, "unexpected type 0x%x\n", type );
1246     trace( "csdversion: %s\n", wine_dbgstr_w(V_BSTR( &val )) );
1247     VariantClear( &val );
1248 
1249     check_property( obj, freephysicalmemoryW, VT_BSTR, CIM_UINT64 );
1250     check_property( obj, nameW, VT_BSTR, CIM_STRING );
1251 
1252     type = 0xdeadbeef;
1253     VariantInit( &val );
1254     hr = IWbemClassObject_Get( obj, operatingsystemskuW, 0, &val, &type, NULL );
1255     ok( hr == S_OK || broken(hr == WBEM_E_NOT_FOUND) /* winxp */, "failed to get operatingsystemsku %08x\n", hr );
1256     if (hr == S_OK)
1257     {
1258         ok( V_VT( &val ) == VT_I4, "unexpected variant type 0x%x\n", V_VT( &val ) );
1259         ok( type == CIM_UINT32, "unexpected type 0x%x\n", type );
1260         trace( "operatingsystemsku: %08x\n", V_I4( &val ) );
1261         VariantClear( &val );
1262     }
1263 
1264     type = 0xdeadbeef;
1265     VariantInit( &val );
1266     hr = IWbemClassObject_Get( obj, osproductsuiteW, 0, &val, &type, NULL );
1267     ok( hr == S_OK, "failed to get osproductsuite %08x\n", hr );
1268     ok( V_VT( &val ) == VT_I4 || broken(V_VT( &val ) == VT_NULL) /* winxp */, "unexpected variant type 0x%x\n", V_VT( &val ) );
1269     ok( type == CIM_UINT32, "unexpected type 0x%x\n", type );
1270     trace( "osproductsuite: %d (%08x)\n", V_I4( &val ), V_I4( &val ) );
1271     VariantClear( &val );
1272 
1273     check_property( obj, csnameW, VT_BSTR, CIM_STRING );
1274     check_property( obj, currenttimezoneW, VT_I2, CIM_SINT16 );
1275     check_property( obj, manufacturerW, VT_BSTR, CIM_STRING );
1276     check_property( obj, ostypeW, VT_I4, CIM_UINT16 );
1277     check_property( obj, servicepackmajorW, VT_I4, CIM_UINT16 );
1278     check_property( obj, servicepackminorW, VT_I4, CIM_UINT16 );
1279     check_property( obj, suitemaskW, VT_I4, CIM_UINT32 );
1280     check_property( obj, versionW, VT_BSTR, CIM_STRING );
1281     check_property( obj, totalvisiblememorysizeW, VT_BSTR, CIM_UINT64 );
1282     check_property( obj, totalvirtualmemorysizeW, VT_BSTR, CIM_UINT64 );
1283     check_property( obj, systemdriveW, VT_BSTR, CIM_STRING );
1284 
1285     IWbemClassObject_Release( obj );
1286     IEnumWbemClassObject_Release( result );
1287     SysFreeString( query );
1288     SysFreeString( wql );
1289 }
1290 
test_Win32_ComputerSystemProduct(IWbemServices * services)1291 static void test_Win32_ComputerSystemProduct( IWbemServices *services )
1292 {
1293     static const WCHAR identifyingnumberW[] =
1294         {'I','d','e','n','t','i','f','y','i','n','g','N','u','m','b','e','r',0};
1295     static const WCHAR nameW[] =
1296         {'N','a','m','e',0};
1297     static const WCHAR skunumberW[] =
1298         {'S','K','U','N','u','m','b','e','r',0};
1299     static const WCHAR uuidW[] =
1300         {'U','U','I','D',0};
1301     static const WCHAR vendorW[] =
1302         {'V','e','n','d','o','r',0};
1303     static const WCHAR versionW[] =
1304         {'V','e','r','s','i','o','n',0};
1305     static const WCHAR queryW[] =
1306         {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','W','i','n','3','2','_',
1307          'C','o','m','p','u','t','e','r','S','y','s','t','e','m','P','r','o','d','u','c','t',0};
1308     BSTR wql = SysAllocString( wqlW ), query = SysAllocString( queryW );
1309     IEnumWbemClassObject *result;
1310     IWbemClassObject *obj;
1311     HRESULT hr;
1312     DWORD count;
1313 
1314     hr = IWbemServices_ExecQuery( services, wql, query, 0, NULL, &result );
1315     if (hr != S_OK)
1316     {
1317         win_skip( "Win32_ComputerSystemProduct not available\n" );
1318         return;
1319     }
1320 
1321     hr = IEnumWbemClassObject_Next( result, 10000, 1, &obj, &count );
1322     ok( hr == S_OK, "got %08x\n", hr );
1323 
1324     check_property( obj, identifyingnumberW, VT_BSTR, CIM_STRING );
1325     check_property( obj, nameW, VT_BSTR, CIM_STRING );
1326     check_property( obj, skunumberW, VT_NULL, CIM_STRING );
1327     check_property( obj, uuidW, VT_BSTR, CIM_STRING );
1328     check_property( obj, vendorW, VT_BSTR, CIM_STRING );
1329     check_property( obj, versionW, VT_BSTR, CIM_STRING );
1330 
1331     IWbemClassObject_Release( obj );
1332     IEnumWbemClassObject_Release( result );
1333     SysFreeString( query );
1334     SysFreeString( wql );
1335 }
1336 
test_Win32_PhysicalMemory(IWbemServices * services)1337 static void test_Win32_PhysicalMemory( IWbemServices *services )
1338 {
1339     static const WCHAR capacityW[] = {'C','a','p','a','c','i','t','y',0};
1340     static const WCHAR memorytypeW[] = {'M','e','m','o','r','y','T','y','p','e',0};
1341     static const WCHAR devicelocatorW[] = {'D','e','v','i','c','e','L','o','c','a','t','o','r',0};
1342     static const WCHAR queryW[] =
1343         {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','W','i','n','3','2','_',
1344          'P','h','y','s','i','c','a','l','M','e','m','o','r','y',0};
1345     BSTR wql = SysAllocString( wqlW ), query = SysAllocString( queryW );
1346     IEnumWbemClassObject *result;
1347     IWbemClassObject *obj;
1348     HRESULT hr;
1349     DWORD count;
1350 
1351     hr = IWbemServices_ExecQuery( services, wql, query, 0, NULL, &result );
1352     if (hr != S_OK)
1353     {
1354         win_skip( "Win32_PhysicalMemory not available\n" );
1355         return;
1356     }
1357 
1358     hr = IEnumWbemClassObject_Next( result, 10000, 1, &obj, &count );
1359     ok( hr == S_OK, "got %08x\n", hr );
1360 
1361     if (count > 0)
1362     {
1363         check_property( obj, capacityW, VT_BSTR, CIM_UINT64 );
1364         check_property( obj, devicelocatorW, VT_BSTR, CIM_STRING );
1365         check_property( obj, memorytypeW, VT_I4, CIM_UINT16 );
1366         IWbemClassObject_Release( obj );
1367     }
1368     IEnumWbemClassObject_Release( result );
1369     SysFreeString( query );
1370     SysFreeString( wql );
1371 }
1372 
test_Win32_IP4RouteTable(IWbemServices * services)1373 static void test_Win32_IP4RouteTable( IWbemServices *services )
1374 {
1375     static const WCHAR destinationW[] = {'D','e','s','t','i','n','a','t','i','o','n',0};
1376     static const WCHAR interfaceindexW[] = {'I','n','t','e','r','f','a','c','e','I','n','d','e','x',0};
1377     static const WCHAR nexthopW[] = {'N','e','x','t','H','o','p',0};
1378     static const WCHAR queryW[] =
1379         {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','W','i','n','3','2','_',
1380          'I','P','4','R','o','u','t','e','T','a','b','l','e',0};
1381     BSTR wql = SysAllocString( wqlW ), query = SysAllocString( queryW );
1382     IEnumWbemClassObject *result;
1383     IWbemClassObject *obj;
1384     HRESULT hr;
1385     DWORD count;
1386 
1387     hr = IWbemServices_ExecQuery( services, wql, query, 0, NULL, &result );
1388     if (hr != S_OK)
1389     {
1390         win_skip( "Win32_IP4RouteTable not available\n" );
1391         return;
1392     }
1393 
1394     for (;;)
1395     {
1396         hr = IEnumWbemClassObject_Next( result, 10000, 1, &obj, &count );
1397         if (hr != S_OK) break;
1398 
1399         check_property( obj, destinationW, VT_BSTR, CIM_STRING );
1400         check_property( obj, interfaceindexW, VT_I4, CIM_SINT32 );
1401         check_property( obj, nexthopW, VT_BSTR, CIM_STRING );
1402         IWbemClassObject_Release( obj );
1403     }
1404 
1405     IEnumWbemClassObject_Release( result );
1406     SysFreeString( query );
1407     SysFreeString( wql );
1408 }
1409 
test_Win32_Processor(IWbemServices * services)1410 static void test_Win32_Processor( IWbemServices *services )
1411 {
1412     static const WCHAR architectureW[] =
1413         {'A','r','c','h','i','t','e','c','t','u','r','e',0};
1414     static const WCHAR captionW[] =
1415         {'C','a','p','t','i','o','n',0};
1416     static const WCHAR cpustatusW[] =
1417         {'C','p','u','S','t','a','t','u','s',0};
1418     static const WCHAR familyW[] =
1419         {'F','a','m','i','l','y',0};
1420     static const WCHAR levelW[] =
1421         {'L','e','v','e','l',0};
1422     static const WCHAR manufacturerW[] =
1423         {'M','a','n','u','f','a','c','t','u','r','e','r',0};
1424     static const WCHAR nameW[] =
1425         {'N','a','m','e',0};
1426     static const WCHAR numcoresW[] =
1427         {'N','u','m','b','e','r','O','f','C','o','r','e','s',0};
1428     static const WCHAR numlogicalprocessorsW[] =
1429         {'N','u','m','b','e','r','O','f','L','o','g','i','c','a','l','P','r','o','c','e','s','s','o','r','s',0};
1430     static const WCHAR processoridW[] =
1431         {'P','r','o','c','e','s','s','o','r','I','d',0};
1432     static const WCHAR revisionW[] =
1433         {'R','e','v','i','s','i','o','n',0};
1434     static const WCHAR versionW[] =
1435         {'V','e','r','s','i','o','n',0};
1436     static const WCHAR queryW[] =
1437         {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','W','i','n','3','2','_',
1438          'P','r','o','c','e','s','s','o','r',0};
1439     BSTR wql = SysAllocString( wqlW ), query = SysAllocString( queryW );
1440     IEnumWbemClassObject *result;
1441     IWbemClassObject *obj;
1442     VARIANT val;
1443     CIMTYPE type;
1444     HRESULT hr;
1445     DWORD count;
1446 
1447     hr = IWbemServices_ExecQuery( services, wql, query, 0, NULL, &result );
1448     ok( hr == S_OK, "got %08x\n", hr );
1449 
1450     for (;;)
1451     {
1452         hr = IEnumWbemClassObject_Next( result, 10000, 1, &obj, &count );
1453         if (hr != S_OK) break;
1454 
1455         check_property( obj, architectureW, VT_I4, CIM_UINT16 );
1456         check_property( obj, captionW, VT_BSTR, CIM_STRING );
1457         check_property( obj, cpustatusW, VT_I4, CIM_UINT16 );
1458         check_property( obj, familyW, VT_I4, CIM_UINT16 );
1459         check_property( obj, levelW, VT_I4, CIM_UINT16 );
1460         check_property( obj, manufacturerW, VT_BSTR, CIM_STRING );
1461         check_property( obj, nameW, VT_BSTR, CIM_STRING );
1462         check_property( obj, processoridW, VT_BSTR, CIM_STRING );
1463         check_property( obj, revisionW, VT_I4, CIM_UINT16 );
1464         check_property( obj, versionW, VT_BSTR, CIM_STRING );
1465 
1466         type = 0xdeadbeef;
1467         VariantInit( &val );
1468         hr = IWbemClassObject_Get( obj, numlogicalprocessorsW, 0, &val, &type, NULL );
1469         ok( hr == S_OK || broken(hr == WBEM_E_NOT_FOUND) /* win2k3 */, "got %08x\n", hr );
1470         if (hr == S_OK)
1471         {
1472             ok( V_VT( &val ) == VT_I4, "unexpected variant type 0x%x\n", V_VT( &val ) );
1473             ok( type == CIM_UINT32, "unexpected type 0x%x\n", type );
1474             trace( "numlogicalprocessors %u\n", V_I4( &val ) );
1475         }
1476 
1477         type = 0xdeadbeef;
1478         VariantInit( &val );
1479         hr = IWbemClassObject_Get( obj, numcoresW, 0, &val, &type, NULL );
1480         ok( hr == S_OK || broken(hr == WBEM_E_NOT_FOUND) /* win2k3 */, "got %08x\n", hr );
1481         if (hr == S_OK)
1482         {
1483             ok( V_VT( &val ) == VT_I4, "unexpected variant type 0x%x\n", V_VT( &val ) );
1484             ok( type == CIM_UINT32, "unexpected type 0x%x\n", type );
1485             trace( "numcores %u\n", V_I4( &val ) );
1486         }
1487 
1488         IWbemClassObject_Release( obj );
1489     }
1490 
1491     IEnumWbemClassObject_Release( result );
1492     SysFreeString( query );
1493     SysFreeString( wql );
1494 }
1495 
test_Win32_VideoController(IWbemServices * services)1496 static void test_Win32_VideoController( IWbemServices *services )
1497 {
1498     static const WCHAR availabilityW[] =
1499         {'A','v','a','i','l','a','b','i','l','i','t','y',0};
1500     static const WCHAR configmanagererrorcodeW[] =
1501         {'C','o','n','f','i','g','M','a','n','a','g','e','r','E','r','r','o','r','C','o','d','e',0};
1502     static const WCHAR driverdateW[] =
1503         {'D','r','i','v','e','r','D','a','t','e',0};
1504     static const WCHAR installeddisplaydriversW[]=
1505         {'I','n','s','t','a','l','l','e','d','D','i','s','p','l','a','y','D','r','i','v','e','r','s',0};
1506     static const WCHAR statusW[] =
1507         {'S','t','a','t','u','s',0};
1508     static const WCHAR queryW[] =
1509         {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','W','i','n','3','2','_',
1510          'V','i','d','e','o','C','o','n','t','r','o','l','l','e','r',0};
1511     BSTR wql = SysAllocString( wqlW ), query = SysAllocString( queryW );
1512     IEnumWbemClassObject *result;
1513     IWbemClassObject *obj;
1514     VARIANT val;
1515     CIMTYPE type;
1516     HRESULT hr;
1517     DWORD count;
1518 
1519     hr = IWbemServices_ExecQuery( services, wql, query, 0, NULL, &result );
1520     if (hr != S_OK)
1521     {
1522         win_skip( "Win32_VideoController not available\n" );
1523         return;
1524     }
1525 
1526     for (;;)
1527     {
1528         hr = IEnumWbemClassObject_Next( result, 10000, 1, &obj, &count );
1529         if (hr != S_OK) break;
1530 
1531         check_property( obj, availabilityW, VT_I4, CIM_UINT16 );
1532         check_property( obj, configmanagererrorcodeW, VT_I4, CIM_UINT32 );
1533         check_property( obj, driverdateW, VT_BSTR, CIM_DATETIME );
1534 
1535         type = 0xdeadbeef;
1536         VariantInit( &val );
1537         hr = IWbemClassObject_Get( obj, installeddisplaydriversW, 0, &val, &type, NULL );
1538         ok( hr == S_OK, "got %08x\n", hr );
1539         ok( V_VT( &val ) == VT_BSTR || V_VT( &val ) == VT_NULL, "unexpected variant type 0x%x\n", V_VT( &val ) );
1540         ok( type == CIM_STRING, "unexpected type 0x%x\n", type );
1541         trace( "installeddisplaydrivers %s\n", wine_dbgstr_w(V_BSTR( &val )) );
1542         VariantClear( &val );
1543 
1544         check_property( obj, statusW, VT_BSTR, CIM_STRING );
1545         IWbemClassObject_Release( obj );
1546     }
1547 
1548     IEnumWbemClassObject_Release( result );
1549     SysFreeString( query );
1550     SysFreeString( wql );
1551 }
1552 
test_Win32_Printer(IWbemServices * services)1553 static void test_Win32_Printer( IWbemServices *services )
1554 {
1555     static const WCHAR attributesW[] =
1556         {'A','t','t','r','i','b','u','t','e','s',0};
1557     static const WCHAR deviceidW[] =
1558         {'D','e','v','i','c','e','I','d',0};
1559     static const WCHAR horizontalresolutionW[] =
1560         {'H','o','r','i','z','o','n','t','a','l','R','e','s','o','l','u','t','i','o','n',0};
1561     static const WCHAR locationW[] =
1562         {'L','o','c','a','t','i','o','n',0};
1563     static const WCHAR portnameW[] =
1564         {'P','o','r','t','N','a','m','e',0};
1565     static const WCHAR queryW[] =
1566         {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','W','i','n','3','2','_',
1567          'P','r','i','n','t','e','r',0};
1568     BSTR wql = SysAllocString( wqlW ), query = SysAllocString( queryW );
1569     IEnumWbemClassObject *result;
1570     IWbemClassObject *obj;
1571     VARIANT val;
1572     CIMTYPE type;
1573     HRESULT hr;
1574     DWORD count;
1575 
1576     hr = IWbemServices_ExecQuery( services, wql, query, 0, NULL, &result );
1577     if (hr != S_OK)
1578     {
1579         win_skip( "Win32_Printer not available\n" );
1580         return;
1581     }
1582 
1583     for (;;)
1584     {
1585         hr = IEnumWbemClassObject_Next( result, 10000, 1, &obj, &count );
1586         if (hr != S_OK) break;
1587 
1588         check_property( obj, attributesW, VT_I4, CIM_UINT32 );
1589         check_property( obj, deviceidW, VT_BSTR, CIM_STRING );
1590         check_property( obj, horizontalresolutionW, VT_I4, CIM_UINT32 );
1591 
1592         type = 0xdeadbeef;
1593         memset( &val, 0, sizeof(val) );
1594         hr = IWbemClassObject_Get( obj, locationW, 0, &val, &type, NULL );
1595         ok( hr == S_OK, "got %08x\n", hr );
1596         ok( V_VT( &val ) == VT_BSTR || V_VT( &val ) == VT_NULL, "unexpected variant type 0x%x\n", V_VT( &val ) );
1597         ok( type == CIM_STRING, "unexpected type 0x%x\n", type );
1598         trace( "location %s\n", wine_dbgstr_w(V_BSTR( &val )) );
1599         VariantClear( &val );
1600 
1601         check_property( obj, portnameW, VT_BSTR, CIM_STRING );
1602         IWbemClassObject_Release( obj );
1603     }
1604 
1605     IEnumWbemClassObject_Release( result );
1606     SysFreeString( query );
1607     SysFreeString( wql );
1608 }
1609 
test_Win32_PnPEntity(IWbemServices * services)1610 static void test_Win32_PnPEntity( IWbemServices *services )
1611 {
1612     HRESULT hr;
1613     IEnumWbemClassObject *enm;
1614     IWbemClassObject *obj;
1615     VARIANT val;
1616     CIMTYPE type;
1617     ULONG count, i;
1618     BSTR bstr;
1619 
1620     static WCHAR win32_pnpentityW[] = {'W','i','n','3','2','_','P','n','P','E','n','t','i','t','y',0};
1621     static const WCHAR deviceidW[] = {'D','e','v','i','c','e','I','d',0};
1622 
1623     bstr = SysAllocString( win32_pnpentityW );
1624 
1625     hr = IWbemServices_CreateInstanceEnum( services, bstr, 0, NULL, &enm );
1626     ok( hr == S_OK, "got %08x\n", hr );
1627 
1628     SysFreeString( bstr );
1629     bstr = SysAllocString( deviceidW );
1630 
1631     while (1)
1632     {
1633         hr = IEnumWbemClassObject_Next( enm, 1000, 1, &obj, &count );
1634         ok( (count == 1 && (hr == WBEM_S_FALSE || hr == WBEM_S_NO_ERROR)) ||
1635                 (count == 0 && (hr == WBEM_S_FALSE || hr == WBEM_S_TIMEDOUT)),
1636                 "got %08x with %u objects returned\n", hr, count );
1637 
1638         if (count == 0)
1639             break;
1640 
1641         for (i = 0; i < count; ++i)
1642         {
1643             hr = IWbemClassObject_Get( obj, bstr, 0, &val, &type, NULL );
1644             ok( hr == S_OK, "got %08x\n", hr );
1645 
1646             if (SUCCEEDED( hr ))
1647             {
1648                 ok( V_VT( &val ) == VT_BSTR, "unexpected variant type 0x%x\n", V_VT( &val ) );
1649                 ok( type == CIM_STRING, "unexpected type 0x%x\n", type );
1650                 VariantClear( &val );
1651             }
1652         }
1653         IWbemClassObject_Release( obj );
1654     }
1655 
1656     SysFreeString( bstr );
1657 
1658     IEnumWbemClassObject_Release( enm );
1659 }
1660 
test_Win32_WinSAT(IWbemServices * services)1661 static void test_Win32_WinSAT( IWbemServices *services )
1662 {
1663     static const WCHAR cpuscoreW[] =
1664         {'C','P','U','S','c','o','r','e',0};
1665     static const WCHAR d3dscoreW[] =
1666         {'D','3','D','S','c','o','r','e',0};
1667     static const WCHAR diskscoreW[] =
1668         {'D','i','s','k','S','c','o','r','e',0};
1669     static const WCHAR graphicsscoreW[] =
1670         {'G','r','a','p','h','i','c','s','S','c','o','r','e',0};
1671     static const WCHAR memoryscoreW[] =
1672         {'M','e','m','o','r','y','S','c','o','r','e',0};
1673     static const WCHAR winsatassessmentstateW[] =
1674         {'W','i','n','S','A','T','A','s','s','e','s','s','m','e','n','t','S','t','a','t','e',0};
1675     static const WCHAR winsprlevelW[] =
1676         {'W','i','n','S','P','R','L','e','v','e','l',0};
1677     static const WCHAR queryW[] =
1678         {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','W','i','n','3','2','_','W','i','n','S','A','T',0};
1679     BSTR wql = SysAllocString( wqlW ), query = SysAllocString( queryW );
1680     IEnumWbemClassObject *result;
1681     IWbemClassObject *obj;
1682     HRESULT hr;
1683     DWORD count;
1684 
1685     hr = IWbemServices_ExecQuery( services, wql, query, 0, NULL, &result );
1686     ok( hr == S_OK || broken(hr == WBEM_E_INVALID_CLASS) /* win2k8 */, "got %08x\n", hr );
1687     if (hr == WBEM_E_INVALID_CLASS)
1688     {
1689         win_skip( "class not found\n" );
1690         return;
1691     }
1692 
1693     for (;;)
1694     {
1695         hr = IEnumWbemClassObject_Next( result, 10000, 1, &obj, &count );
1696         if (hr != S_OK) break;
1697 
1698         check_property( obj, cpuscoreW, VT_R4, CIM_REAL32 );
1699         check_property( obj, d3dscoreW, VT_R4, CIM_REAL32 );
1700         check_property( obj, diskscoreW, VT_R4, CIM_REAL32 );
1701         check_property( obj, graphicsscoreW, VT_R4, CIM_REAL32 );
1702         check_property( obj, memoryscoreW, VT_R4, CIM_REAL32 );
1703         check_property( obj, winsatassessmentstateW, VT_I4, CIM_UINT32 );
1704         check_property( obj, winsprlevelW, VT_R4, CIM_REAL32 );
1705         IWbemClassObject_Release( obj );
1706     }
1707 
1708     IEnumWbemClassObject_Release( result );
1709     SysFreeString( query );
1710     SysFreeString( wql );
1711 }
1712 
test_Win32_DisplayControllerConfiguration(IWbemServices * services)1713 static void test_Win32_DisplayControllerConfiguration( IWbemServices *services )
1714 {
1715     static const WCHAR bitsperpixelW[] =
1716         {'B','i','t','s','P','e','r','P','i','x','e','l',0};
1717     static const WCHAR captionW[] =
1718         {'C','a','p','t','i','o','n',0};
1719     static const WCHAR horizontalresolutionW[] =
1720         {'H','o','r','i','z','o','n','t','a','l','R','e','s','o','l','u','t','i','o','n',0};
1721     static const WCHAR nameW[] =
1722         {'N','a','m','e',0};
1723     static const WCHAR queryW[] =
1724         {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','W','i','n','3','2','_',
1725          'D','i','s','p','l','a','y','C','o','n','t','r','o','l','l','e','r',
1726          'C','o','n','f','i','g','u','r','a','t','i','o','n',0};
1727     static const WCHAR verticalresolutionW[] =
1728         {'V','e','r','t','i','c','a','l','R','e','s','o','l','u','t','i','o','n',0};
1729     BSTR wql = SysAllocString( wqlW ), query = SysAllocString( queryW );
1730     IEnumWbemClassObject *result;
1731     IWbemClassObject *obj;
1732     HRESULT hr;
1733     DWORD count;
1734 
1735     hr = IWbemServices_ExecQuery( services, wql, query, 0, NULL, &result );
1736     ok( hr == S_OK, "got %08x\n", hr );
1737 
1738     for (;;)
1739     {
1740         hr = IEnumWbemClassObject_Next( result, 10000, 1, &obj, &count );
1741         if (hr != S_OK) break;
1742 
1743         check_property( obj, bitsperpixelW, VT_I4, CIM_UINT32 );
1744         check_property( obj, captionW, VT_BSTR, CIM_STRING );
1745         check_property( obj, horizontalresolutionW, VT_I4, CIM_UINT32 );
1746         check_property( obj, nameW, VT_BSTR, CIM_STRING );
1747         check_property( obj, verticalresolutionW, VT_I4, CIM_UINT32 );
1748         IWbemClassObject_Release( obj );
1749     }
1750 
1751     IEnumWbemClassObject_Release( result );
1752     SysFreeString( query );
1753     SysFreeString( wql );
1754 }
1755 
test_Win32_QuickFixEngineering(IWbemServices * services)1756 static void test_Win32_QuickFixEngineering( IWbemServices *services )
1757 {
1758     static const WCHAR captionW[] =
1759         {'C','a','p','t','i','o','n',0};
1760     static const WCHAR hotfixidW[] =
1761         {'H','o','t','F','i','x','I','D',0};
1762     static const WCHAR queryW[] =
1763         {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','W','i','n','3','2','_',
1764          'Q','u','i','c','k','F','i','x','E','n','g','i','n','e','e','r','i','n','g',0};
1765     BSTR wql = SysAllocString( wqlW ), query = SysAllocString( queryW );
1766     IEnumWbemClassObject *result;
1767     IWbemClassObject *obj;
1768     HRESULT hr;
1769     DWORD count, total = 0;
1770     VARIANT caption;
1771     CIMTYPE type;
1772 
1773     hr = IWbemServices_ExecQuery( services, wql, query, 0, NULL, &result );
1774     ok( hr == S_OK, "got %08x\n", hr );
1775 
1776     for (;;)
1777     {
1778         hr = IEnumWbemClassObject_Next( result, 10000, 1, &obj, &count );
1779         if (hr != S_OK) break;
1780 
1781         type = 0xdeadbeef;
1782         VariantInit( &caption );
1783         hr = IWbemClassObject_Get( obj, captionW, 0, &caption, &type, NULL );
1784         ok( hr == S_OK, "failed to get caption %08x\n", hr );
1785         ok( V_VT( &caption ) == VT_BSTR || V_VT( &caption ) == VT_NULL /* winxp */,
1786             "unexpected variant type 0x%x\n", V_VT( &caption ) );
1787         ok( type == CIM_STRING, "unexpected type 0x%x\n", type );
1788 
1789         check_property( obj, hotfixidW, VT_BSTR, CIM_STRING );
1790         IWbemClassObject_Release( obj );
1791         if (total++ >= 10) break;
1792     }
1793 
1794     IEnumWbemClassObject_Release( result );
1795     SysFreeString( query );
1796     SysFreeString( wql );
1797 }
1798 
START_TEST(query)1799 START_TEST(query)
1800 {
1801     static const WCHAR cimv2W[] = {'R','O','O','T','\\','C','I','M','V','2',0};
1802     BSTR path = SysAllocString( cimv2W );
1803     IWbemLocator *locator;
1804     IWbemServices *services;
1805     HRESULT hr;
1806 
1807     CoInitialize( NULL );
1808     CoInitializeSecurity( NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_DEFAULT,
1809                           RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, NULL );
1810     hr = CoCreateInstance( &CLSID_WbemLocator, NULL, CLSCTX_INPROC_SERVER, &IID_IWbemLocator,
1811                            (void **)&locator );
1812     if (hr != S_OK)
1813     {
1814         win_skip("can't create instance of WbemLocator\n");
1815         return;
1816     }
1817     hr = IWbemLocator_ConnectServer( locator, path, NULL, NULL, NULL, 0, NULL, NULL, &services );
1818     ok( hr == S_OK, "failed to get IWbemServices interface %08x\n", hr );
1819 
1820     hr = CoSetProxyBlanket( (IUnknown *)services, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL,
1821                             RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE );
1822     ok( hr == S_OK, "failed to set proxy blanket %08x\n", hr );
1823 
1824     test_GetNames( services );
1825     test_associators( services );
1826     test_notification_query_async( services );
1827     test_query_async( services );
1828     test_query_semisync( services );
1829     test_select( services );
1830 
1831     /* classes */
1832     test_StdRegProv( services );
1833     test_SystemSecurity( services );
1834     test_Win32_Baseboard( services );
1835     test_Win32_ComputerSystem( services );
1836     test_Win32_ComputerSystemProduct( services );
1837     test_Win32_Bios( services );
1838     test_Win32_DisplayControllerConfiguration( services );
1839     test_Win32_IP4RouteTable( services );
1840     test_Win32_OperatingSystem( services );
1841     test_Win32_PhysicalMemory( services );
1842     test_Win32_PnPEntity( services );
1843     test_Win32_Printer( services );
1844     test_Win32_Process( services, FALSE );
1845     test_Win32_Process( services, TRUE );
1846     test_Win32_Processor( services );
1847     test_Win32_QuickFixEngineering( services );
1848     test_Win32_Service( services );
1849     test_Win32_SystemEnclosure( services );
1850     test_Win32_VideoController( services );
1851     test_Win32_WinSAT( services );
1852 
1853     SysFreeString( path );
1854     IWbemServices_Release( services );
1855     IWbemLocator_Release( locator );
1856     CoUninitialize();
1857 }
1858