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 <stdarg.h>
22 #include "windows.h"
23 #include "initguid.h"
24 #include "wmiutils.h"
25 #include "wbemcli.h"
26 #include "wine/test.h"
27 
28 static const WCHAR path1[] = {0};
29 static const WCHAR path2[] = {'\\',0};
30 static const WCHAR path3[] = {'\\','\\','s','e','r','v','e','r',0};
31 static const WCHAR path4[] = {'\\','\\','s','e','r','v','e','r','\\',0};
32 static const WCHAR path5[] = {'\\','\\','.','\\',0};
33 static const WCHAR path6[] = {'/','/','.','/','r','o','o','t','/','c','i','m','v','2',0};
34 static const WCHAR path7[] =
35     {'/','/','.','/','r','o','o','t','/','c','i','m','v','2',':','W','i','n','3','2','_',
36      'O','p','e','r','a','t','i','n','g','S','y','s','t','e','m',0};
37 static const WCHAR path8[] =
38     {'/','r','o','o','t','/','c','i','m','v','2',':','W','i','n','3','2','_',
39      'O','p','e','r','a','t','i','n','g','S','y','s','t','e','m',0};
40 static const WCHAR path9[] =
41     {'\\','\\','.','\\','r','o','o','t','\\','c','i','m','v','2',':','W','i','n','3','2','_',
42      'O','p','e','r','a','t','i','n','g','S','y','s','t','e','m',0};
43 static const WCHAR path10[] =
44     {'/','\\','.','\\','r','o','o','t','\\','c','i','m','v','2',':','W','i','n','3','2','_',
45      'O','p','e','r','a','t','i','n','g','S','y','s','t','e','m',0};
46 static const WCHAR path11[] =
47     {'/','/','.','\\','r','o','o','t','\\','c','i','m','v','2',':','W','i','n','3','2','_',
48      'O','p','e','r','a','t','i','n','g','S','y','s','t','e','m',0};
49 static const WCHAR path12[] =
50     {'r','o','o','t','\\','c','i','m','v','2',':','W','i','n','3','2','_',
51      'O','p','e','r','a','t','i','n','g','S','y','s','t','e','m',0};
52 static const WCHAR path13[] =
53     {'\\','\\','.','\\','r','o','o','t','\\','c','i','m','v','2',0};
54 static const WCHAR path14[] =
55     {'W','i','n','3','2','_','O','p','e','r','a','t','i','n','g','S','y','s','t','e','m',0};
56 static const WCHAR path15[] =
57     {'r','o','o','t','\\','c','i','m','v','2',0};
58 static const WCHAR path16[] =
59     {'\\','\\','.','\\','r','o','o','t','\\','c','i','m','v','2',0};
60 static const WCHAR path17[] =
61     {'\\','\\','.','\\','r','o','o','t','\\','c','i','m','v','2',':','W','i','n','3','2','_',
62      'L','o','g','i','c','a','l','D','i','s','k','.','D','e','v','i','c','e','I','d','=',
63      '"','C',':','"',0};
64 static const WCHAR path18[] =
65     {'\\','\\','.','\\','r','o','o','t','\\','c','i','m','v','2',':','W','i','n','3','2','_',
66      'L','o','g','i','c','a','l','D','i','s','k','.','D','e','v','i','c','e','I','d','=',
67      '"','C',':','"',',','D','r','i','v','e','T','y','p','e','=','3',0};
68 static const WCHAR path19[] =
69     {'\\','\\','.','\\','r','o','o','t','\\','c','i','m','v','2',':','W','i','n','3','2','_',
70      'L','o','g','i','c','a','l','D','i','s','k','.','D','e','v','i','c','e','I','d','=',0};
71 static const WCHAR path20[] =
72     {'\\','\\','.','\\','r','o','o','t','\\','c','i','m','v','2',':','W','i','n','3','2','_',
73      'L','o','g','i','c','a','l','D','i','s','k','.','D','e','v','i','c','e','I','d',' ','=',' ',
74      '"','C',':','"',0};
75 
76 static IWbemPath *create_path(void)
77 {
78     HRESULT hr;
79     IWbemPath *path;
80 
81     hr = CoCreateInstance( &CLSID_WbemDefPath, NULL, CLSCTX_INPROC_SERVER, &IID_IWbemPath, (void **)&path );
82     if (hr != S_OK)
83     {
84         win_skip( "can't create WbemDefPath instance, skipping tests\n" );
85         return NULL;
86     }
87     return path;
88 }
89 
90 static void test_IWbemPath_SetText(void)
91 {
92     static const struct
93     {
94         const WCHAR *path;
95         ULONG        mode;
96         HRESULT      ret;
97         BOOL         todo;
98     } test[] =
99     {
100         { path1, 0, WBEM_E_INVALID_PARAMETER },
101         { path1, WBEMPATH_CREATE_ACCEPT_ALL, S_OK },
102         { path2, 0, WBEM_E_INVALID_PARAMETER },
103         { path2, WBEMPATH_CREATE_ACCEPT_ALL, S_OK },
104         { path3, 0, WBEM_E_INVALID_PARAMETER },
105         { path3, WBEMPATH_CREATE_ACCEPT_ALL, S_OK },
106         { path4, 0, WBEM_E_INVALID_PARAMETER },
107         { path4, WBEMPATH_CREATE_ACCEPT_ALL, S_OK },
108         { path5, 0, WBEM_E_INVALID_PARAMETER },
109         { path5, WBEMPATH_CREATE_ACCEPT_ALL, S_OK },
110         { path6, 0, WBEM_E_INVALID_PARAMETER },
111         { path6, WBEMPATH_CREATE_ACCEPT_ALL, S_OK },
112         { path7, 0, WBEM_E_INVALID_PARAMETER },
113         { path7, WBEMPATH_CREATE_ACCEPT_RELATIVE, S_OK },
114         { path7, WBEMPATH_CREATE_ACCEPT_ABSOLUTE, S_OK },
115         { path7, WBEMPATH_CREATE_ACCEPT_ALL, S_OK },
116         { path7, WBEMPATH_TREAT_SINGLE_IDENT_AS_NS, WBEM_E_INVALID_PARAMETER, TRUE },
117         { path7, WBEMPATH_TREAT_SINGLE_IDENT_AS_NS + 1, S_OK },
118         { path8, WBEMPATH_CREATE_ACCEPT_RELATIVE, S_OK },
119         { path8, WBEMPATH_CREATE_ACCEPT_ABSOLUTE, WBEM_E_INVALID_PARAMETER, TRUE },
120         { path8, WBEMPATH_CREATE_ACCEPT_ALL, S_OK },
121         { path8, WBEMPATH_TREAT_SINGLE_IDENT_AS_NS, WBEM_E_INVALID_PARAMETER, TRUE },
122         { path8, WBEMPATH_TREAT_SINGLE_IDENT_AS_NS + 1, S_OK },
123         { path9, WBEMPATH_CREATE_ACCEPT_ABSOLUTE, S_OK },
124         { path10, WBEMPATH_CREATE_ACCEPT_ABSOLUTE, WBEM_E_INVALID_PARAMETER, TRUE },
125         { path11, WBEMPATH_CREATE_ACCEPT_ABSOLUTE, S_OK },
126         { path15, WBEMPATH_CREATE_ACCEPT_ALL, S_OK }
127     };
128     IWbemPath *path;
129     HRESULT hr;
130     UINT i;
131 
132     if (!(path = create_path())) return;
133 
134     hr = IWbemPath_SetText( path, 0, NULL );
135     ok( hr == WBEM_E_INVALID_PARAMETER, "got %08x\n", hr );
136 
137     hr = IWbemPath_SetText( path, WBEMPATH_CREATE_ACCEPT_ALL, NULL );
138     ok( hr == WBEM_E_INVALID_PARAMETER, "got %08x\n", hr );
139 
140     for (i = 0; i < sizeof(test)/sizeof(test[0]); i++)
141     {
142         hr = IWbemPath_SetText( path, test[i].mode, test[i].path );
143         todo_wine_if (test[i].todo)
144             ok( hr == test[i].ret, "%u got %08x\n", i, hr );
145 
146         if (test[i].ret == S_OK)
147         {
148             WCHAR buf[128];
149             ULONG len;
150 
151             memset( buf, 0x55, sizeof(buf) );
152             len = sizeof(buf)/sizeof(buf[0]);
153             hr = IWbemPath_GetText( path, WBEMPATH_GET_ORIGINAL, &len, buf );
154             ok( hr == S_OK, "%u got %08x\n", i, hr );
155             ok( !lstrcmpW( buf, test[i].path ), "%u unexpected path %s\n", i, wine_dbgstr_w(buf) );
156             ok( len == lstrlenW( test[i].path ) + 1, "%u unexpected length %u\n", i, len );
157         }
158     }
159     IWbemPath_Release( path );
160 }
161 
162 static void test_IWbemPath_GetText(void)
163 {
164     static const WCHAR serviceW[] =
165         {'W','i','n','3','2','_','S','e','r','v','i','c','e','.','N','a','m','e','=',
166          '\"','S','e','r','v','i','c','e','\"',0};
167     static const WCHAR classW[] =
168         {'W','i','n','3','2','_','C','l','a','s','s',0};
169     static const WCHAR expected1W[] =
170         {'r','o','o','t','\\','c','i','m','v','2',':','W','i','n','3','2','_',
171          'L','o','g','i','c','a','l','D','i','s','k','.','D','e','v','i','c','e','I','d','=',
172          '"','C',':','"',0};
173     static const WCHAR expected2W[] =
174         {'W','i','n','3','2','_','L','o','g','i','c','a','l','D','i','s','k','.',
175          'D','e','v','i','c','e','I','d','=','"','C',':','"',0};
176     static const WCHAR expected3W[] =
177         {'\\','\\','.','\\','r','o','o','t','\\','c','i','m','v','2',0};
178     WCHAR buf[128];
179     ULONG len, count;
180     IWbemPath *path;
181     HRESULT hr;
182 
183     if (!(path = create_path())) return;
184 
185     hr = IWbemPath_GetText( path, 0, NULL, NULL );
186     ok( hr == WBEM_E_INVALID_PARAMETER, "got %08x\n", hr );
187 
188     len = sizeof(buf)/sizeof(buf[0]);
189     hr = IWbemPath_GetText( path, 0, &len, NULL );
190     ok( hr == WBEM_E_INVALID_PARAMETER, "got %08x\n", hr );
191     ok( len == sizeof(buf)/sizeof(buf[0]), "unexpected length %u\n", len );
192 
193     len = sizeof(buf)/sizeof(buf[0]);
194     memset( buf, 0x55, sizeof(buf) );
195     hr = IWbemPath_GetText( path, 0, &len, buf );
196     ok( hr == S_OK, "got %08x\n", hr );
197     ok( !buf[0], "unexpected buffer contents %s\n", wine_dbgstr_w(buf) );
198     ok( len == 1, "unexpected length %u\n", len );
199 
200     hr = IWbemPath_GetText( path, WBEMPATH_GET_ORIGINAL, NULL, NULL );
201     ok( hr == WBEM_E_INVALID_PARAMETER, "got %08x\n", hr );
202 
203     len = sizeof(buf)/sizeof(buf[0]);
204     hr = IWbemPath_GetText( path, WBEMPATH_GET_ORIGINAL, &len, NULL );
205     ok( hr == WBEM_E_INVALID_PARAMETER, "got %08x\n", hr );
206     ok( len == sizeof(buf)/sizeof(buf[0]), "unexpected length %u\n", len );
207 
208     len = sizeof(buf)/sizeof(buf[0]);
209     memset( buf, 0x55, sizeof(buf) );
210     hr = IWbemPath_GetText( path, WBEMPATH_GET_ORIGINAL, &len, buf );
211     ok( hr == S_OK, "got %08x\n", hr );
212     ok( !buf[0], "unexpected buffer contents %s\n", wine_dbgstr_w(buf) );
213     ok( len == 1, "unexpected length %u\n", len );
214 
215     len = sizeof(buf)/sizeof(buf[0]);
216     memset( buf, 0x55, sizeof(buf) );
217     hr = IWbemPath_GetText( path, WBEMPATH_GET_SERVER_TOO, &len, buf );
218     ok( hr == S_OK, "got %08x\n", hr );
219     todo_wine ok( !buf[0], "unexpected buffer contents %s\n", wine_dbgstr_w(buf) );
220     todo_wine ok( len == 1, "unexpected length %u\n", len );
221 
222     hr = IWbemPath_SetText( path, WBEMPATH_CREATE_ACCEPT_ALL, path8 );
223     ok( hr == S_OK, "got %08x\n", hr );
224 
225     count = 0xdeadbeef;
226     hr = IWbemPath_GetNamespaceCount( path, &count );
227     ok( hr == S_OK, "got %08x\n", hr );
228     ok( count == 2, "got %u\n", count );
229 
230     len = sizeof(buf)/sizeof(buf[0]);
231     memset( buf, 0x55, sizeof(buf) );
232     hr = IWbemPath_GetText( path, WBEMPATH_GET_SERVER_TOO, &len, buf );
233     ok( hr == S_OK, "got %08x\n", hr );
234     ok( !lstrcmpW( buf, path9 ), "unexpected buffer contents %s\n", wine_dbgstr_w(buf) );
235     ok( len == lstrlenW( path9 ) + 1, "unexpected length %u\n", len );
236 
237     len = sizeof(buf)/sizeof(buf[0]);
238     memset( buf, 0x55, sizeof(buf) );
239     hr = IWbemPath_GetText( path, WBEMPATH_GET_SERVER_AND_NAMESPACE_ONLY, &len, buf );
240     ok( hr == S_OK, "got %08x\n", hr );
241     ok( !lstrcmpW( buf, path13 ), "unexpected buffer contents %s\n", wine_dbgstr_w(buf) );
242     ok( len == lstrlenW( path13 ) + 1, "unexpected length %u\n", len );
243 
244     len = sizeof(buf)/sizeof(buf[0]);
245     memset( buf, 0x55, sizeof(buf) );
246     hr = IWbemPath_GetText( path, WBEMPATH_GET_RELATIVE_ONLY, &len, buf );
247     ok( hr == S_OK, "got %08x\n", hr );
248     ok( !lstrcmpW( buf, path14 ), "unexpected buffer contents %s\n", wine_dbgstr_w(buf) );
249     ok( len == lstrlenW( path14 ) + 1, "unexpected length %u\n", len );
250 
251     len = sizeof(buf)/sizeof(buf[0]);
252     memset( buf, 0x55, sizeof(buf) );
253     hr = IWbemPath_GetText( path, WBEMPATH_GET_NAMESPACE_ONLY, &len, buf );
254     ok( hr == S_OK, "got %08x\n", hr );
255     ok( !lstrcmpW( buf, path15 ), "unexpected buffer contents %s\n", wine_dbgstr_w(buf) );
256     ok( len == lstrlenW( path15 ) + 1, "unexpected length %u\n", len );
257 
258     len = sizeof(buf)/sizeof(buf[0]);
259     memset( buf, 0x55, sizeof(buf) );
260     hr = IWbemPath_GetText( path, 0, &len, buf );
261     ok( hr == S_OK, "got %08x\n", hr );
262     ok( !lstrcmpW( buf, path12 ), "unexpected buffer contents %s\n", wine_dbgstr_w(buf) );
263     ok( len == lstrlenW( path12 ) + 1, "unexpected length %u\n", len );
264 
265     hr = IWbemPath_SetText( path, WBEMPATH_CREATE_ACCEPT_ALL, path1 );
266     ok( hr == S_OK, "got %08x\n", hr );
267 
268     count = 0xdeadbeef;
269     hr = IWbemPath_GetNamespaceCount( path, &count );
270     ok( hr == S_OK, "got %08x\n", hr );
271     ok( !count, "got %u\n", count );
272 
273     hr = IWbemPath_SetText( path, WBEMPATH_CREATE_ACCEPT_ALL, path6 );
274     ok( hr == S_OK, "got %08x\n", hr );
275 
276     count = 0xdeadbeef;
277     hr = IWbemPath_GetNamespaceCount( path, &count );
278     ok( hr == S_OK, "got %08x\n", hr );
279     ok( count == 2, "got %u\n", count );
280 
281     len = 0;
282     hr = IWbemPath_GetText( path, WBEMPATH_GET_SERVER_TOO, &len, NULL );
283     ok( hr == S_OK, "got %08x\n", hr );
284     ok( len == lstrlenW( path16 ) + 1, "unexpected length %u\n", len );
285 
286     len = sizeof(buf)/sizeof(buf[0]);
287     memset( buf, 0x55, sizeof(buf) );
288     hr = IWbemPath_GetText( path, WBEMPATH_GET_SERVER_TOO, &len, buf );
289     ok( hr == S_OK, "got %08x\n", hr );
290     ok( !lstrcmpW( buf, path16 ), "unexpected buffer contents %s\n", wine_dbgstr_w(buf) );
291     ok( len == lstrlenW( path16 ) + 1, "unexpected length %u\n", len );
292 
293     hr = IWbemPath_SetText( path, WBEMPATH_CREATE_ACCEPT_ALL, path17 );
294     ok( hr == S_OK, "got %08x\n", hr );
295 
296     len = sizeof(buf)/sizeof(buf[0]);
297     memset( buf, 0x55, sizeof(buf) );
298     hr = IWbemPath_GetText( path, WBEMPATH_GET_SERVER_TOO, &len, buf );
299     ok( hr == S_OK, "got %08x\n", hr );
300     ok( !lstrcmpW( buf, path17 ), "unexpected buffer contents %s\n", wine_dbgstr_w(buf) );
301     ok( len == lstrlenW( path17 ) + 1, "unexpected length %u\n", len );
302 
303     len = sizeof(buf)/sizeof(buf[0]);
304     memset( buf, 0x55, sizeof(buf) );
305     hr = IWbemPath_GetText( path, 0, &len, buf );
306     ok( hr == S_OK, "got %08x\n", hr );
307     ok( !lstrcmpW( buf, expected1W ), "unexpected buffer contents %s\n", wine_dbgstr_w(buf) );
308     ok( len == lstrlenW( expected1W ) + 1, "unexpected length %u\n", len );
309 
310     len = sizeof(buf)/sizeof(buf[0]);
311     memset( buf, 0x55, sizeof(buf) );
312     hr = IWbemPath_GetText( path, WBEMPATH_GET_RELATIVE_ONLY, &len, buf );
313     ok( hr == S_OK, "got %08x\n", hr );
314     ok( !lstrcmpW( buf, expected2W ), "unexpected buffer contents %s\n", wine_dbgstr_w(buf) );
315     ok( len == lstrlenW( expected2W ) + 1, "unexpected length %u\n", len );
316 
317     hr = IWbemPath_SetText( path, WBEMPATH_CREATE_ACCEPT_ALL, path15 );
318     ok( hr == S_OK, "got %08x\n", hr );
319 
320     len = sizeof(buf)/sizeof(buf[0]);
321     memset( buf, 0x55, sizeof(buf) );
322     hr = IWbemPath_GetText( path, WBEMPATH_GET_SERVER_TOO, &len, buf );
323     ok( hr == S_OK, "got %08x\n", hr );
324     ok( !lstrcmpW( buf, expected3W ), "unexpected buffer contents %s\n", wine_dbgstr_w(buf) );
325     ok( len == lstrlenW( expected3W ) + 1, "unexpected length %u\n", len );
326 
327     hr = IWbemPath_SetText( path, WBEMPATH_CREATE_ACCEPT_ALL, path18 );
328     ok( hr == S_OK, "got %08x\n", hr );
329 
330     hr = IWbemPath_SetText( path, WBEMPATH_CREATE_ACCEPT_ALL, path19 );
331     ok( hr == WBEM_E_INVALID_PARAMETER, "got %08x\n", hr );
332 
333     hr = IWbemPath_SetText( path, WBEMPATH_CREATE_ACCEPT_ALL, path20 );
334     ok( hr == WBEM_E_INVALID_PARAMETER, "got %08x\n", hr );
335 
336     IWbemPath_Release( path );
337     if (!(path = create_path())) return;
338 
339     hr = IWbemPath_SetText( path, WBEMPATH_CREATE_ACCEPT_ALL, serviceW );
340     ok( hr == S_OK, "got %08x\n", hr );
341 
342     len = sizeof(buf)/sizeof(buf[0]);
343     memset( buf, 0x55, sizeof(buf) );
344     hr = IWbemPath_GetText( path, WBEMPATH_GET_RELATIVE_ONLY, &len, buf );
345     ok( hr == S_OK, "got %08x\n", hr );
346     ok( !lstrcmpW( buf, serviceW ), "unexpected buffer contents %s\n", wine_dbgstr_w(buf) );
347     ok( len == lstrlenW( serviceW ) + 1, "unexpected length %u\n", len );
348 
349     IWbemPath_Release( path );
350     if (!(path = create_path())) return;
351 
352     hr = IWbemPath_SetText( path, WBEMPATH_CREATE_ACCEPT_ALL, classW );
353     ok( hr == S_OK, "got %08x\n", hr );
354 
355     len = sizeof(buf)/sizeof(buf[0]);
356     memset( buf, 0x55, sizeof(buf) );
357     hr = IWbemPath_GetText( path, WBEMPATH_GET_RELATIVE_ONLY, &len, buf );
358     ok( hr == S_OK, "got %08x\n", hr );
359     ok( !lstrcmpW( buf, classW ), "unexpected buffer contents %s\n", wine_dbgstr_w(buf) );
360     ok( len == lstrlenW( classW ) + 1, "unexpected length %u\n", len );
361 
362     IWbemPath_Release( path );
363 }
364 
365 static void test_IWbemPath_GetClassName(void)
366 {
367     static const WCHAR classW[] = {'W','i','n','3','2','_','L','o','g','i','c','a','l','D','i','s','k',0};
368     IWbemPath *path;
369     HRESULT hr;
370     WCHAR buf[32];
371     ULONG len;
372 
373     if (!(path = create_path())) return;
374 
375     hr = IWbemPath_GetClassName( path, NULL, NULL );
376     ok( hr == WBEM_E_INVALID_PARAMETER, "got %08x\n", hr );
377 
378     len = 0;
379     hr = IWbemPath_GetClassName( path, &len, NULL );
380     ok( hr == WBEM_E_INVALID_OBJECT_PATH, "got %08x\n", hr );
381 
382     len = sizeof(buf) / sizeof(buf[0]);
383     hr = IWbemPath_GetClassName( path, &len, buf );
384     ok( hr == WBEM_E_INVALID_OBJECT_PATH, "got %08x\n", hr );
385 
386     len = sizeof(buf) / sizeof(buf[0]);
387     hr = IWbemPath_GetClassName( path, &len, NULL );
388     ok( hr == WBEM_E_INVALID_PARAMETER, "got %08x\n", hr );
389     ok( len == sizeof(buf) / sizeof(buf[0]), "unexpected length %u\n", len );
390 
391     hr = IWbemPath_SetText( path, WBEMPATH_CREATE_ACCEPT_ALL, path17 );
392     ok( hr == S_OK, "got %08x\n", hr );
393 
394     len = 0;
395     hr = IWbemPath_GetClassName( path, &len, NULL );
396     ok( hr == S_OK, "got %08x\n", hr );
397 
398     len = sizeof(buf) / sizeof(buf[0]);
399     hr = IWbemPath_GetClassName( path, &len, NULL );
400     ok( hr == WBEM_E_INVALID_PARAMETER, "got %08x\n", hr );
401     ok( len == sizeof(buf) / sizeof(buf[0]), "unexpected length %u\n", len );
402 
403     buf[0] = 0;
404     len = sizeof(buf) / sizeof(buf[0]);
405     hr = IWbemPath_GetClassName( path, &len, buf );
406     ok( hr == S_OK, "got %08x\n", hr );
407     ok( !lstrcmpW( buf, classW ), "unexpected buffer contents %s\n", wine_dbgstr_w(buf) );
408     ok( len == lstrlenW( classW ) + 1, "unexpected length %u\n", len );
409 
410     IWbemPath_Release( path );
411 }
412 
413 static void test_IWbemPath_SetClassName(void)
414 {
415     static const WCHAR classW[] = {'c','l','a','s','s',0};
416     static const WCHAR emptyW[] = {0};
417     IWbemPath *path;
418     WCHAR buf[16];
419     ULONG len;
420     ULONGLONG flags;
421     HRESULT hr;
422 
423     if (!(path = create_path())) return;
424 
425     hr = IWbemPath_SetClassName( path, NULL );
426     ok( hr == WBEM_E_INVALID_PARAMETER, "got %08x\n", hr );
427 
428     hr = IWbemPath_SetClassName( path, emptyW );
429     ok( hr == S_OK, "got %08x\n", hr );
430 
431     hr = IWbemPath_SetClassName( path, classW );
432     ok( hr == S_OK, "got %08x\n", hr );
433 
434     buf[0] = 0;
435     len = sizeof(buf) / sizeof(buf[0]);
436     hr = IWbemPath_GetClassName( path, &len, buf );
437     ok( hr == S_OK, "got %08x\n", hr );
438     ok( !lstrcmpW( buf, classW ), "unexpected buffer contents %s\n", wine_dbgstr_w(buf) );
439 
440     flags = 0;
441     hr = IWbemPath_GetInfo( path, 0, &flags );
442     ok( hr == S_OK, "got %08x\n", hr );
443     ok( flags == (WBEMPATH_INFO_ANON_LOCAL_MACHINE | WBEMPATH_INFO_IS_CLASS_REF |
444                   WBEMPATH_INFO_HAS_SUBSCOPES | WBEMPATH_INFO_V2_COMPLIANT |
445                   WBEMPATH_INFO_CIM_COMPLIANT),
446         "got %lx%08lx\n", (unsigned long)(flags >> 32), (unsigned long)flags );
447 
448     IWbemPath_Release( path );
449 }
450 
451 static void test_IWbemPath_GetServer(void)
452 {
453     static const WCHAR dotW[] = {'.',0};
454     IWbemPath *path;
455     HRESULT hr;
456     WCHAR buf[32];
457     ULONG len;
458 
459     if (!(path = create_path())) return;
460 
461     hr = IWbemPath_GetServer( path, NULL, NULL );
462     ok( hr == WBEM_E_INVALID_PARAMETER, "got %08x\n", hr );
463 
464     len = 0;
465     hr = IWbemPath_GetServer( path, &len, NULL );
466     ok( hr == WBEM_E_NOT_AVAILABLE, "got %08x\n", hr );
467 
468     len = sizeof(buf) / sizeof(buf[0]);
469     hr = IWbemPath_GetServer( path, &len, buf );
470     ok( hr == WBEM_E_NOT_AVAILABLE, "got %08x\n", hr );
471 
472     len = sizeof(buf) / sizeof(buf[0]);
473     hr = IWbemPath_GetServer( path, &len, NULL );
474     ok( hr == WBEM_E_INVALID_PARAMETER, "got %08x\n", hr );
475     ok( len == sizeof(buf) / sizeof(buf[0]), "unexpected length %u\n", len );
476 
477     hr = IWbemPath_SetText( path, WBEMPATH_CREATE_ACCEPT_ALL, path17 );
478     ok( hr == S_OK, "got %08x\n", hr );
479 
480     len = 0;
481     hr = IWbemPath_GetServer( path, &len, NULL );
482     ok( hr == S_OK, "got %08x\n", hr );
483 
484     len = sizeof(buf) / sizeof(buf[0]);
485     hr = IWbemPath_GetServer( path, &len, NULL );
486     ok( hr == WBEM_E_INVALID_PARAMETER, "got %08x\n", hr );
487     ok( len == sizeof(buf) / sizeof(buf[0]), "unexpected length %u\n", len );
488 
489     buf[0] = 0;
490     len = sizeof(buf) / sizeof(buf[0]);
491     hr = IWbemPath_GetServer( path, &len, buf );
492     ok( hr == S_OK, "got %08x\n", hr );
493     ok( !lstrcmpW( buf, dotW ), "unexpected buffer contents %s\n", wine_dbgstr_w(buf) );
494     ok( len == lstrlenW( dotW ) + 1, "unexpected length %u\n", len );
495 
496     IWbemPath_Release( path );
497 }
498 
499 static void test_IWbemPath_GetInfo(void)
500 {
501     IWbemPath *path;
502     HRESULT hr;
503     ULONGLONG resp;
504 
505     if (!(path = create_path())) return;
506 
507     hr = IWbemPath_GetInfo( path, 0, NULL );
508     ok( hr == WBEM_E_INVALID_PARAMETER, "got %08x\n", hr );
509 
510     hr = IWbemPath_GetInfo( path, 1, NULL );
511     ok( hr == WBEM_E_INVALID_PARAMETER, "got %08x\n", hr );
512 
513     resp = 0xdeadbeef;
514     hr = IWbemPath_GetInfo( path, 0, &resp );
515     ok( hr == S_OK, "got %08x\n", hr );
516     ok( resp == (WBEMPATH_INFO_ANON_LOCAL_MACHINE | WBEMPATH_INFO_SERVER_NAMESPACE_ONLY),
517         "got %lx%08lx\n", (unsigned long)(resp >> 32), (unsigned long)resp );
518 
519     hr = IWbemPath_SetText( path, WBEMPATH_CREATE_ACCEPT_ALL, path17 );
520     ok( hr == S_OK, "got %08x\n", hr );
521 
522     hr = IWbemPath_GetInfo( path, 0, NULL );
523     ok( hr == WBEM_E_INVALID_PARAMETER, "got %08x\n", hr );
524 
525     hr = IWbemPath_GetInfo( path, 1, NULL );
526     ok( hr == WBEM_E_INVALID_PARAMETER, "got %08x\n", hr );
527 
528     resp = 0xdeadbeef;
529     hr = IWbemPath_GetInfo( path, 0, &resp );
530     ok( hr == S_OK, "got %08x\n", hr );
531     ok( resp == (WBEMPATH_INFO_ANON_LOCAL_MACHINE | WBEMPATH_INFO_IS_INST_REF |
532                  WBEMPATH_INFO_HAS_SUBSCOPES | WBEMPATH_INFO_V2_COMPLIANT |
533                  WBEMPATH_INFO_CIM_COMPLIANT | WBEMPATH_INFO_PATH_HAD_SERVER),
534         "got %lx%08lx\n", (unsigned long)(resp >> 32), (unsigned long)resp );
535 
536     IWbemPath_Release( path );
537     if (!(path = create_path())) return;
538 
539     hr = IWbemPath_SetText( path, WBEMPATH_CREATE_ACCEPT_ALL, path12 );
540     ok( hr == S_OK, "got %08x\n", hr );
541 
542     resp = 0xdeadbeef;
543     hr = IWbemPath_GetInfo( path, 0, &resp );
544     ok( hr == S_OK, "got %08x\n", hr );
545     ok( resp == (WBEMPATH_INFO_ANON_LOCAL_MACHINE | WBEMPATH_INFO_IS_CLASS_REF |
546                  WBEMPATH_INFO_HAS_SUBSCOPES | WBEMPATH_INFO_V2_COMPLIANT |
547                  WBEMPATH_INFO_CIM_COMPLIANT),
548         "got %lx%08lx\n", (unsigned long)(resp >> 32), (unsigned long)resp );
549 
550     hr = IWbemPath_SetText( path, WBEMPATH_CREATE_ACCEPT_ALL, path1 );
551     ok( hr == S_OK, "got %08x\n", hr );
552 
553     resp = 0xdeadbeef;
554     hr = IWbemPath_GetInfo( path, 0, &resp );
555     ok( hr == S_OK, "got %08x\n", hr );
556     ok( resp == (WBEMPATH_INFO_ANON_LOCAL_MACHINE | WBEMPATH_INFO_SERVER_NAMESPACE_ONLY),
557         "got %lx%08lx\n", (unsigned long)(resp >> 32), (unsigned long)resp );
558 
559     IWbemPath_Release( path );
560 }
561 
562 static void test_IWbemPath_SetServer(void)
563 {
564     static const WCHAR serverW[] = {'s','e','r','v','e','r',0};
565     static const WCHAR emptyW[] = {0};
566     IWbemPath *path;
567     WCHAR buf[16];
568     ULONG len;
569     ULONGLONG flags;
570     HRESULT hr;
571 
572     if (!(path = create_path())) return;
573 
574     hr = IWbemPath_SetServer( path, NULL );
575     ok( hr == S_OK, "got %08x\n", hr );
576 
577     len = sizeof(buf) / sizeof(buf[0]);
578     hr = IWbemPath_GetServer( path, &len, buf );
579     ok( hr == WBEM_E_NOT_AVAILABLE, "got %08x\n", hr );
580 
581     hr = IWbemPath_SetServer( path, emptyW );
582     ok( hr == S_OK, "got %08x\n", hr );
583 
584     hr = IWbemPath_SetServer( path, serverW );
585     ok( hr == S_OK, "got %08x\n", hr );
586 
587     buf[0] = 0;
588     len = sizeof(buf) / sizeof(buf[0]);
589     hr = IWbemPath_GetServer( path, &len, buf );
590     ok( hr == S_OK, "got %08x\n", hr );
591     ok( !lstrcmpW( buf, serverW ), "unexpected buffer contents %s\n", wine_dbgstr_w(buf) );
592 
593     flags = 0;
594     hr = IWbemPath_GetInfo( path, 0, &flags );
595     ok( hr == S_OK, "got %08x\n", hr );
596     ok( flags == (WBEMPATH_INFO_HAS_MACHINE_NAME | WBEMPATH_INFO_V1_COMPLIANT |
597                   WBEMPATH_INFO_V2_COMPLIANT | WBEMPATH_INFO_CIM_COMPLIANT |
598                   WBEMPATH_INFO_SERVER_NAMESPACE_ONLY | WBEMPATH_INFO_PATH_HAD_SERVER),
599         "got %lx%08lx\n", (unsigned long)(flags >> 32), (unsigned long)flags );
600 
601     hr = IWbemPath_SetServer( path, NULL );
602     ok( hr == S_OK, "got %08x\n", hr );
603 
604     len = sizeof(buf) / sizeof(buf[0]);
605     hr = IWbemPath_GetServer( path, &len, buf );
606     ok( hr == WBEM_E_NOT_AVAILABLE, "got %08x\n", hr );
607 
608     flags = 0;
609     hr = IWbemPath_GetInfo( path, 0, &flags );
610     ok( hr == S_OK, "got %08x\n", hr );
611     ok( flags == (WBEMPATH_INFO_ANON_LOCAL_MACHINE | WBEMPATH_INFO_SERVER_NAMESPACE_ONLY),
612         "got %lx%08lx\n", (unsigned long)(flags >> 32), (unsigned long)flags );
613 
614     IWbemPath_Release( path );
615 }
616 
617 static void test_IWbemPath_GetNamespaceAt(void)
618 {
619     static const WCHAR rootW[] = {'r','o','o','t',0};
620     static const WCHAR cimv2W[] = {'c','i','m','v','2',0};
621     IWbemPath *path;
622     HRESULT hr;
623     WCHAR buf[32];
624     ULONG len;
625 
626     if (!(path = create_path())) return;
627 
628     hr = IWbemPath_GetNamespaceAt( path, 0, NULL, NULL );
629     ok( hr == WBEM_E_INVALID_PARAMETER, "got %08x\n", hr );
630 
631     len = 0;
632     hr = IWbemPath_GetNamespaceAt( path, 0, &len, NULL );
633     ok( hr == WBEM_E_INVALID_PARAMETER, "got %08x\n", hr );
634 
635     len = sizeof(buf) / sizeof(buf[0]);
636     hr = IWbemPath_GetNamespaceAt( path, 0, &len, buf );
637     ok( hr == WBEM_E_INVALID_PARAMETER, "got %08x\n", hr );
638 
639     len = sizeof(buf) / sizeof(buf[0]);
640     hr = IWbemPath_GetNamespaceAt( path, 0, &len, NULL );
641     ok( hr == WBEM_E_INVALID_PARAMETER, "got %08x\n", hr );
642     ok( len == sizeof(buf) / sizeof(buf[0]), "unexpected length %u\n", len );
643 
644     hr = IWbemPath_SetText( path, WBEMPATH_CREATE_ACCEPT_ALL, path17 );
645     ok( hr == S_OK, "got %08x\n", hr );
646 
647     len = 0;
648     hr = IWbemPath_GetNamespaceAt( path, 2, &len, NULL );
649     ok( hr == WBEM_E_INVALID_PARAMETER, "got %08x\n", hr );
650 
651     len = sizeof(buf) / sizeof(buf[0]);
652     hr = IWbemPath_GetNamespaceAt( path, 0, &len, NULL );
653     ok( hr == WBEM_E_INVALID_PARAMETER, "got %08x\n", hr );
654     ok( len == sizeof(buf) / sizeof(buf[0]), "unexpected length %u\n", len );
655 
656     buf[0] = 0;
657     len = sizeof(buf) / sizeof(buf[0]);
658     hr = IWbemPath_GetNamespaceAt( path, 0, &len, buf );
659     ok( hr == S_OK, "got %08x\n", hr );
660     ok( !lstrcmpW( buf, rootW ), "unexpected buffer contents %s\n", wine_dbgstr_w(buf) );
661     ok( len == lstrlenW( rootW ) + 1, "unexpected length %u\n", len );
662 
663     buf[0] = 0;
664     len = sizeof(buf) / sizeof(buf[0]);
665     hr = IWbemPath_GetNamespaceAt( path, 1, &len, buf );
666     ok( hr == S_OK, "got %08x\n", hr );
667     ok( !lstrcmpW( buf, cimv2W ), "unexpected buffer contents %s\n", wine_dbgstr_w(buf) );
668     ok( len == lstrlenW( cimv2W ) + 1, "unexpected length %u\n", len );
669 
670     IWbemPath_Release( path );
671 }
672 
673 static void test_IWbemPath_RemoveAllNamespaces(void)
674 {
675     static const ULONGLONG expected_flags =
676         WBEMPATH_INFO_ANON_LOCAL_MACHINE | WBEMPATH_INFO_IS_INST_REF |
677         WBEMPATH_INFO_HAS_SUBSCOPES | WBEMPATH_INFO_V2_COMPLIANT |
678         WBEMPATH_INFO_CIM_COMPLIANT | WBEMPATH_INFO_PATH_HAD_SERVER;
679     IWbemPath *path;
680     WCHAR buf[16];
681     ULONG len;
682     ULONGLONG flags;
683     HRESULT hr;
684 
685     if (!(path = create_path())) return;
686 
687     hr = IWbemPath_RemoveAllNamespaces( path );
688     ok( hr == S_OK, "got %08x\n", hr );
689 
690     hr = IWbemPath_SetText( path, WBEMPATH_CREATE_ACCEPT_ALL, path17 );
691     ok( hr == S_OK, "got %08x\n", hr );
692 
693     flags = 0;
694     hr = IWbemPath_GetInfo( path, 0, &flags );
695     ok( hr == S_OK, "got %08x\n", hr );
696     ok( flags == expected_flags,
697         "got %lx%08lx\n", (unsigned long)(flags >> 32), (unsigned long)flags );
698 
699     hr = IWbemPath_RemoveAllNamespaces( path );
700     ok( hr == S_OK, "got %08x\n", hr );
701 
702     flags = 0;
703     hr = IWbemPath_GetInfo( path, 0, &flags );
704     ok( hr == S_OK, "got %08x\n", hr );
705     ok( flags == expected_flags,
706         "got %lx%08lx\n", (unsigned long)(flags >> 32), (unsigned long)flags );
707 
708     buf[0] = 0;
709     len = sizeof(buf) / sizeof(buf[0]);
710     hr = IWbemPath_GetNamespaceAt( path, 0, &len, buf );
711     ok( hr == WBEM_E_INVALID_PARAMETER, "got %08x\n", hr );
712 
713     IWbemPath_Release( path );
714 }
715 
716 static void test_IWbemPath_RemoveNamespaceAt(void)
717 {
718     static const ULONGLONG expected_flags =
719         WBEMPATH_INFO_ANON_LOCAL_MACHINE | WBEMPATH_INFO_IS_INST_REF |
720         WBEMPATH_INFO_HAS_SUBSCOPES | WBEMPATH_INFO_V2_COMPLIANT |
721         WBEMPATH_INFO_CIM_COMPLIANT | WBEMPATH_INFO_PATH_HAD_SERVER;
722     static const WCHAR cimv2W[] = {'c','i','m','v','2',0};
723     IWbemPath *path;
724     WCHAR buf[16];
725     ULONG len, count;
726     ULONGLONG flags;
727     HRESULT hr;
728 
729     if (!(path = create_path())) return;
730 
731     hr = IWbemPath_RemoveNamespaceAt( path, 0 );
732     ok( hr == WBEM_E_INVALID_PARAMETER, "got %08x\n", hr );
733 
734     hr = IWbemPath_SetText( path, WBEMPATH_CREATE_ACCEPT_ALL, path17 );
735     ok( hr == S_OK, "got %08x\n", hr );
736 
737     flags = 0;
738     hr = IWbemPath_GetInfo( path, 0, &flags );
739     ok( hr == S_OK, "got %08x\n", hr );
740     ok( flags == expected_flags,
741         "got %lx%08lx\n", (unsigned long)(flags >> 32), (unsigned long)flags );
742 
743     count = 0xdeadbeef;
744     hr = IWbemPath_GetNamespaceCount( path, &count );
745     ok( hr == S_OK, "got %08x\n", hr );
746     ok( count == 2, "got %u\n", count );
747 
748     hr = IWbemPath_RemoveNamespaceAt( path, 0 );
749     ok( hr == S_OK, "got %08x\n", hr );
750 
751     flags = 0;
752     hr = IWbemPath_GetInfo( path, 0, &flags );
753     ok( hr == S_OK, "got %08x\n", hr );
754     ok( flags == expected_flags,
755         "got %lx%08lx\n", (unsigned long)(flags >> 32), (unsigned long)flags );
756 
757     count = 0xdeadbeef;
758     hr = IWbemPath_GetNamespaceCount( path, &count );
759     ok( hr == S_OK, "got %08x\n", hr );
760     ok( count == 1, "got %u\n", count );
761 
762     buf[0] = 0;
763     len = sizeof(buf) / sizeof(buf[0]);
764     hr = IWbemPath_GetNamespaceAt( path, 0, &len, buf );
765     ok( hr == S_OK, "got %08x\n", hr );
766     ok( !lstrcmpW( buf, cimv2W ), "unexpected buffer contents %s\n", wine_dbgstr_w(buf) );
767     ok( len == lstrlenW( cimv2W ) + 1, "unexpected length %u\n", len );
768 
769     hr = IWbemPath_RemoveNamespaceAt( path, 0 );
770     ok( hr == S_OK, "got %08x\n", hr );
771 
772     flags = 0;
773     hr = IWbemPath_GetInfo( path, 0, &flags );
774     ok( hr == S_OK, "got %08x\n", hr );
775     ok( flags == expected_flags,
776         "got %lx%08lx\n", (unsigned long)(flags >> 32), (unsigned long)flags );
777 
778     count = 0xdeadbeef;
779     hr = IWbemPath_GetNamespaceCount( path, &count );
780     ok( hr == S_OK, "got %08x\n", hr );
781     ok( !count, "got %u\n", count );
782 
783     buf[0] = 0;
784     len = sizeof(buf) / sizeof(buf[0]);
785     hr = IWbemPath_GetNamespaceAt( path, 0, &len, buf );
786     ok( hr == WBEM_E_INVALID_PARAMETER, "got %08x\n", hr );
787 
788     IWbemPath_Release( path );
789 }
790 
791 static void test_IWbemPath_SetNamespaceAt(void)
792 {
793     static const ULONGLONG expected_flags =
794         WBEMPATH_INFO_ANON_LOCAL_MACHINE | WBEMPATH_INFO_V1_COMPLIANT |
795         WBEMPATH_INFO_V2_COMPLIANT | WBEMPATH_INFO_CIM_COMPLIANT |
796         WBEMPATH_INFO_SERVER_NAMESPACE_ONLY;
797     static const WCHAR rootW[] = {'r','o','o','t',0};
798     static const WCHAR cimv2W[] = {'c','i','m','v','2',0};
799     IWbemPath *path;
800     WCHAR buf[16];
801     ULONG len, count;
802     ULONGLONG flags;
803     HRESULT hr;
804 
805     if (!(path = create_path())) return;
806 
807     hr = IWbemPath_SetNamespaceAt( path, 0, NULL );
808     ok( hr == WBEM_E_INVALID_PARAMETER, "got %08x\n", hr );
809 
810     hr = IWbemPath_SetNamespaceAt( path, 1, cimv2W );
811     ok( hr == WBEM_E_INVALID_PARAMETER, "got %08x\n", hr );
812 
813     hr = IWbemPath_SetNamespaceAt( path, 0, cimv2W );
814     ok( hr == S_OK, "got %08x\n", hr );
815 
816     count = 0xdeadbeef;
817     hr = IWbemPath_GetNamespaceCount( path, &count );
818     ok( hr == S_OK, "got %08x\n", hr );
819     ok( count == 1, "got %u\n", count );
820 
821     flags = 0;
822     hr = IWbemPath_GetInfo( path, 0, &flags );
823     ok( hr == S_OK, "got %08x\n", hr );
824     ok( flags == expected_flags,
825         "got %lx%08lx\n", (unsigned long)(flags >> 32), (unsigned long)flags );
826 
827     buf[0] = 0;
828     len = sizeof(buf) / sizeof(buf[0]);
829     hr = IWbemPath_GetNamespaceAt( path, 0, &len, buf );
830     ok( hr == S_OK, "got %08x\n", hr );
831     ok( !lstrcmpW( buf, cimv2W ), "unexpected buffer contents %s\n", wine_dbgstr_w(buf) );
832     ok( len == lstrlenW( cimv2W ) + 1, "unexpected length %u\n", len );
833 
834     hr = IWbemPath_SetNamespaceAt( path, 0, rootW );
835     ok( hr == S_OK, "got %08x\n", hr );
836 
837     flags = 0;
838     hr = IWbemPath_GetInfo( path, 0, &flags );
839     ok( hr == S_OK, "got %08x\n", hr );
840     ok( flags == expected_flags,
841         "got %lx%08lx\n", (unsigned long)(flags >> 32), (unsigned long)flags );
842 
843     count = 0xdeadbeef;
844     hr = IWbemPath_GetNamespaceCount( path, &count );
845     ok( hr == S_OK, "got %08x\n", hr );
846     ok( count == 2, "got %u\n", count );
847 
848     buf[0] = 0;
849     len = sizeof(buf) / sizeof(buf[0]);
850     hr = IWbemPath_GetNamespaceAt( path, 0, &len, buf );
851     ok( hr == S_OK, "got %08x\n", hr );
852     ok( !lstrcmpW( buf, rootW ), "unexpected buffer contents %s\n", wine_dbgstr_w(buf) );
853     ok( len == lstrlenW( rootW ) + 1, "unexpected length %u\n", len );
854 
855     buf[0] = 0;
856     len = sizeof(buf) / sizeof(buf[0]);
857     hr = IWbemPath_GetNamespaceAt( path, 1, &len, buf );
858     ok( hr == S_OK, "got %08x\n", hr );
859     ok( !lstrcmpW( buf, cimv2W ), "unexpected buffer contents %s\n", wine_dbgstr_w(buf) );
860     ok( len == lstrlenW( cimv2W ) + 1, "unexpected length %u\n", len );
861 
862     IWbemPath_Release( path );
863 }
864 
865 START_TEST (path)
866 {
867     CoInitialize( NULL );
868 
869     test_IWbemPath_SetText();
870     test_IWbemPath_GetText();
871     test_IWbemPath_GetClassName();
872     test_IWbemPath_SetClassName();
873     test_IWbemPath_GetServer();
874     test_IWbemPath_GetInfo();
875     test_IWbemPath_SetServer();
876     test_IWbemPath_GetNamespaceAt();
877     test_IWbemPath_RemoveAllNamespaces();
878     test_IWbemPath_RemoveNamespaceAt();
879     test_IWbemPath_SetNamespaceAt();
880 
881     CoUninitialize();
882 }
883