[BRANCHES]
[reactos.git] / rostests / winetests / dxdiagn / container.c
1 /*
2 * Unit tests for IDxDiagContainer
3 *
4 * Copyright 2010 Andrew Nguyen
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 */
20
21 #define COBJMACROS
22
23 #include <stdio.h>
24 #include <wine/dxdiag.h>
25 #include <oleauto.h>
26 #include <wine/test.h>
27
28 struct property_test
29 {
30 const WCHAR *prop;
31 VARTYPE vt;
32 };
33
34 static IDxDiagProvider *pddp;
35 static IDxDiagContainer *pddc;
36
37 static const WCHAR DxDiag_SystemInfo[] = {'D','x','D','i','a','g','_','S','y','s','t','e','m','I','n','f','o',0};
38 static const WCHAR DxDiag_DisplayDevices[] = {'D','x','D','i','a','g','_','D','i','s','p','l','a','y','D','e','v','i','c','e','s',0};
39
40 /* Based on debugstr_variant in dlls/jscript/jsutils.c. */
41 static const char *debugstr_variant(const VARIANT *var)
42 {
43 static char buf[400];
44
45 if (!var)
46 return "(null)";
47
48 switch (V_VT(var))
49 {
50 case VT_EMPTY:
51 return "{VT_EMPTY}";
52 case VT_BSTR:
53 sprintf(buf, "{VT_BSTR: %s}", wine_dbgstr_w(V_BSTR(var)));
54 break;
55 case VT_BOOL:
56 sprintf(buf, "{VT_BOOL: %x}", V_BOOL(var));
57 break;
58 case VT_UI4:
59 sprintf(buf, "{VT_UI4: %u}", V_UI4(var));
60 break;
61 default:
62 sprintf(buf, "{vt %d}", V_VT(var));
63 break;
64 }
65
66 return buf;
67 }
68
69 static BOOL create_root_IDxDiagContainer(void)
70 {
71 HRESULT hr;
72 DXDIAG_INIT_PARAMS params;
73
74 hr = CoCreateInstance(&CLSID_DxDiagProvider, NULL, CLSCTX_INPROC_SERVER,
75 &IID_IDxDiagProvider, (LPVOID*)&pddp);
76 if (SUCCEEDED(hr))
77 {
78 params.dwSize = sizeof(params);
79 params.dwDxDiagHeaderVersion = DXDIAG_DX9_SDK_VERSION;
80 params.bAllowWHQLChecks = FALSE;
81 params.pReserved = NULL;
82 hr = IDxDiagProvider_Initialize(pddp, &params);
83 if (SUCCEEDED(hr))
84 {
85 hr = IDxDiagProvider_GetRootContainer(pddp, &pddc);
86 if (SUCCEEDED(hr))
87 return TRUE;
88 }
89 IDxDiagProvider_Release(pddp);
90 }
91 return FALSE;
92 }
93
94 static void test_GetNumberOfChildContainers(void)
95 {
96 HRESULT hr;
97 DWORD count;
98
99 if (!create_root_IDxDiagContainer())
100 {
101 skip("Unable to create the root IDxDiagContainer\n");
102 return;
103 }
104
105 hr = IDxDiagContainer_GetNumberOfChildContainers(pddc, NULL);
106 ok(hr == E_INVALIDARG,
107 "Expected IDxDiagContainer::GetNumberOfChildContainers to return E_INVALIDARG, got 0x%08x\n", hr);
108
109 hr = IDxDiagContainer_GetNumberOfChildContainers(pddc, &count);
110 ok(hr == S_OK,
111 "Expected IDxDiagContainer::GetNumberOfChildContainers to return S_OK, got 0x%08x\n", hr);
112 if (hr == S_OK)
113 ok(count != 0, "Expected the number of child containers for the root container to be non-zero\n");
114
115 IDxDiagContainer_Release(pddc);
116 IDxDiagProvider_Release(pddp);
117 }
118
119 static void test_GetNumberOfProps(void)
120 {
121 HRESULT hr;
122 DWORD count;
123
124 if (!create_root_IDxDiagContainer())
125 {
126 skip("Unable to create the root IDxDiagContainer\n");
127 return;
128 }
129
130 hr = IDxDiagContainer_GetNumberOfProps(pddc, NULL);
131 ok(hr == E_INVALIDARG, "Expected IDxDiagContainer::GetNumberOfProps to return E_INVALIDARG, got 0x%08x\n", hr);
132
133 hr = IDxDiagContainer_GetNumberOfProps(pddc, &count);
134 ok(hr == S_OK, "Expected IDxDiagContainer::GetNumberOfProps to return S_OK, got 0x%08x\n", hr);
135 if (hr == S_OK)
136 ok(count == 0, "Expected the number of properties for the root container to be zero\n");
137
138 IDxDiagContainer_Release(pddc);
139 IDxDiagProvider_Release(pddp);
140 }
141
142 static void test_EnumChildContainerNames(void)
143 {
144 HRESULT hr;
145 WCHAR container[256];
146 DWORD maxcount, index;
147 static const WCHAR testW[] = {'t','e','s','t',0};
148 static const WCHAR zerotestW[] = {0,'e','s','t',0};
149
150 if (!create_root_IDxDiagContainer())
151 {
152 skip("Unable to create the root IDxDiagContainer\n");
153 return;
154 }
155
156 /* Test various combinations of invalid parameters. */
157 hr = IDxDiagContainer_EnumChildContainerNames(pddc, 0, NULL, 0);
158 ok(hr == E_INVALIDARG,
159 "Expected IDxDiagContainer::EnumChildContainerNames to return E_INVALIDARG, got 0x%08x\n", hr);
160
161 hr = IDxDiagContainer_EnumChildContainerNames(pddc, 0, NULL, sizeof(container)/sizeof(WCHAR));
162 ok(hr == E_INVALIDARG,
163 "Expected IDxDiagContainer::EnumChildContainerNames to return E_INVALIDARG, got 0x%08x\n", hr);
164
165 /* Test the conditions in which the output buffer can be modified. */
166 memcpy(container, testW, sizeof(testW));
167 hr = IDxDiagContainer_EnumChildContainerNames(pddc, 0, container, 0);
168 ok(hr == E_INVALIDARG,
169 "Expected IDxDiagContainer::EnumChildContainerNames to return E_INVALIDARG, got 0x%08x\n", hr);
170 ok(!memcmp(container, testW, sizeof(testW)),
171 "Expected the container buffer to be untouched, got %s\n", wine_dbgstr_w(container));
172
173 memcpy(container, testW, sizeof(testW));
174 hr = IDxDiagContainer_EnumChildContainerNames(pddc, ~0, container, 0);
175 ok(hr == E_INVALIDARG,
176 "Expected IDxDiagContainer::EnumChildContainerNames to return E_INVALIDARG, got 0x%08x\n", hr);
177 ok(!memcmp(container, testW, sizeof(testW)),
178 "Expected the container buffer to be untouched, got %s\n", wine_dbgstr_w(container));
179
180 memcpy(container, testW, sizeof(testW));
181 hr = IDxDiagContainer_EnumChildContainerNames(pddc, ~0, container, sizeof(container)/sizeof(WCHAR));
182 ok(hr == E_INVALIDARG,
183 "Expected IDxDiagContainer::EnumChildContainerNames to return E_INVALIDARG, got 0x%08x\n", hr);
184 ok(!memcmp(container, zerotestW, sizeof(zerotestW)),
185 "Expected the container buffer string to be empty, got %s\n", wine_dbgstr_w(container));
186
187 hr = IDxDiagContainer_GetNumberOfChildContainers(pddc, &maxcount);
188 ok(hr == S_OK, "Expected IDxDiagContainer::GetNumberOfChildContainers to return S_OK, got 0x%08x\n", hr);
189 if (FAILED(hr))
190 {
191 skip("IDxDiagContainer::GetNumberOfChildContainers failed\n");
192 goto cleanup;
193 }
194
195 trace("Starting child container enumeration of the root container:\n");
196
197 /* We should be able to enumerate as many child containers as the value
198 * that IDxDiagContainer::GetNumberOfChildContainers returns. */
199 for (index = 0; index <= maxcount; index++)
200 {
201 /* A buffer size of 1 is unlikely to be valid, as only a null terminator
202 * could be stored, and it is unlikely that a container name could be empty. */
203 DWORD buffersize = 1;
204 memcpy(container, testW, sizeof(testW));
205 hr = IDxDiagContainer_EnumChildContainerNames(pddc, index, container, buffersize);
206 if (hr == E_INVALIDARG)
207 {
208 /* We should get here when index is one more than the maximum index value. */
209 ok(maxcount == index,
210 "Expected IDxDiagContainer::EnumChildContainerNames to return E_INVALIDARG "
211 "on the last index %d, got 0x%08x\n", index, hr);
212 ok(container[0] == '\0',
213 "Expected the container buffer string to be empty, got %s\n", wine_dbgstr_w(container));
214 break;
215 }
216 else if (hr == DXDIAG_E_INSUFFICIENT_BUFFER)
217 {
218 WCHAR temp[256];
219
220 ok(container[0] == '\0',
221 "Expected the container buffer string to be empty, got %s\n", wine_dbgstr_w(container));
222
223 /* Get the container name to compare against. */
224 hr = IDxDiagContainer_EnumChildContainerNames(pddc, index, temp, sizeof(temp)/sizeof(WCHAR));
225 ok(hr == S_OK,
226 "Expected IDxDiagContainer::EnumChildContainerNames to return S_OK, got 0x%08x\n", hr);
227
228 /* Show that the DirectX SDK's stipulation that the buffer be at
229 * least 256 characters long is a mere suggestion, and smaller sizes
230 * can be acceptable also. IDxDiagContainer::EnumChildContainerNames
231 * doesn't provide a way of getting the exact size required, so the
232 * buffersize value will be iterated to at most 256 characters. */
233 for (buffersize = 2; buffersize <= 256; buffersize++)
234 {
235 memcpy(container, testW, sizeof(testW));
236 hr = IDxDiagContainer_EnumChildContainerNames(pddc, index, container, buffersize);
237 if (hr != DXDIAG_E_INSUFFICIENT_BUFFER)
238 break;
239
240 ok(!memcmp(temp, container, sizeof(WCHAR)*(buffersize - 1)),
241 "Expected truncated container name string, got %s\n", wine_dbgstr_w(container));
242 }
243
244 ok(hr == S_OK,
245 "Expected IDxDiagContainer::EnumChildContainerNames to return S_OK, "
246 "got hr = 0x%08x, buffersize = %d\n", hr, buffersize);
247 if (hr == S_OK)
248 trace("pddc[%d] = %s, length = %d\n", index, wine_dbgstr_w(container), buffersize);
249 }
250 else
251 {
252 ok(0, "IDxDiagContainer::EnumChildContainerNames unexpectedly returned 0x%08x\n", hr);
253 break;
254 }
255 }
256
257 cleanup:
258 IDxDiagContainer_Release(pddc);
259 IDxDiagProvider_Release(pddp);
260 }
261
262 static void test_GetChildContainer(void)
263 {
264 HRESULT hr;
265 WCHAR container[256] = {0};
266 IDxDiagContainer *child;
267
268 if (!create_root_IDxDiagContainer())
269 {
270 skip("Unable to create the root IDxDiagContainer\n");
271 return;
272 }
273
274 /* Test various combinations of invalid parameters. */
275 hr = IDxDiagContainer_GetChildContainer(pddc, NULL, NULL);
276 ok(hr == E_INVALIDARG,
277 "Expected IDxDiagContainer::GetChildContainer to return E_INVALIDARG, got 0x%08x\n", hr);
278
279 child = (void*)0xdeadbeef;
280 hr = IDxDiagContainer_GetChildContainer(pddc, NULL, &child);
281 ok(hr == E_INVALIDARG,
282 "Expected IDxDiagContainer::GetChildContainer to return E_INVALIDARG, got 0x%08x\n", hr);
283 ok(child == (void*)0xdeadbeef, "Expected output pointer to be unchanged, got %p\n", child);
284
285 hr = IDxDiagContainer_GetChildContainer(pddc, container, NULL);
286 ok(hr == E_INVALIDARG,
287 "Expected IDxDiagContainer::GetChildContainer to return E_INVALIDARG, got 0x%08x\n", hr);
288
289 child = (void*)0xdeadbeef;
290 hr = IDxDiagContainer_GetChildContainer(pddc, container, &child);
291 ok(hr == E_INVALIDARG,
292 "Expected IDxDiagContainer::GetChildContainer to return E_INVALIDARG, got 0x%08x\n", hr);
293 ok(child == NULL, "Expected output pointer to be NULL, got %p\n", child);
294
295 /* Get the name of a suitable child container. */
296 hr = IDxDiagContainer_EnumChildContainerNames(pddc, 0, container, sizeof(container)/sizeof(WCHAR));
297 ok(hr == S_OK,
298 "Expected IDxDiagContainer::EnumChildContainerNames to return S_OK, got 0x%08x\n", hr);
299 if (FAILED(hr))
300 {
301 skip("IDxDiagContainer::EnumChildContainerNames failed\n");
302 goto cleanup;
303 }
304
305 child = (void*)0xdeadbeef;
306 hr = IDxDiagContainer_GetChildContainer(pddc, container, &child);
307 ok(hr == S_OK,
308 "Expected IDxDiagContainer::GetChildContainer to return S_OK, got 0x%08x\n", hr);
309 ok(child != NULL && child != (void*)0xdeadbeef, "Expected a valid output pointer, got %p\n", child);
310
311 if (SUCCEEDED(hr))
312 {
313 IDxDiagContainer *ptr;
314
315 /* Show that IDxDiagContainer::GetChildContainer returns a different pointer
316 * for multiple calls for the same container name. */
317 hr = IDxDiagContainer_GetChildContainer(pddc, container, &ptr);
318 ok(hr == S_OK,
319 "Expected IDxDiagContainer::GetChildContainer to return S_OK, got 0x%08x\n", hr);
320 if (SUCCEEDED(hr))
321 ok(ptr != child, "Expected the two pointers (%p vs. %p) to be unequal\n", child, ptr);
322
323 IDxDiagContainer_Release(ptr);
324 IDxDiagContainer_Release(child);
325 }
326
327 cleanup:
328 IDxDiagContainer_Release(pddc);
329 IDxDiagProvider_Release(pddp);
330 }
331
332 static void test_dot_parsing(void)
333 {
334 HRESULT hr;
335 WCHAR containerbufW[256] = {0}, childbufW[256] = {0};
336 DWORD count, index;
337 size_t i;
338 static const struct
339 {
340 const char *format;
341 const HRESULT expect;
342 } test_strings[] = {
343 { "%s.%s", S_OK },
344 { "%s.%s.", S_OK },
345 { ".%s.%s", E_INVALIDARG },
346 { "%s.%s..", E_INVALIDARG },
347 { ".%s.%s.", E_INVALIDARG },
348 { "..%s.%s", E_INVALIDARG },
349 };
350
351 if (!create_root_IDxDiagContainer())
352 {
353 skip("Unable to create the root IDxDiagContainer\n");
354 return;
355 }
356
357 /* Find a container with a child container of its own. */
358 hr = IDxDiagContainer_GetNumberOfChildContainers(pddc, &count);
359 ok(hr == S_OK, "Expected IDxDiagContainer::GetNumberOfChildContainers to return S_OK, got 0x%08x\n", hr);
360 if (FAILED(hr))
361 {
362 skip("IDxDiagContainer::GetNumberOfChildContainers failed\n");
363 goto cleanup;
364 }
365
366 for (index = 0; index < count; index++)
367 {
368 IDxDiagContainer *child;
369
370 hr = IDxDiagContainer_EnumChildContainerNames(pddc, index, containerbufW, sizeof(containerbufW)/sizeof(WCHAR));
371 ok(hr == S_OK, "Expected IDxDiagContainer_EnumChildContainerNames to return S_OK, got 0x%08x\n", hr);
372 if (FAILED(hr))
373 {
374 skip("IDxDiagContainer::EnumChildContainerNames failed\n");
375 goto cleanup;
376 }
377
378 hr = IDxDiagContainer_GetChildContainer(pddc, containerbufW, &child);
379 ok(hr == S_OK, "Expected IDxDiagContainer::GetChildContainer to return S_OK, got 0x%08x\n", hr);
380
381 if (SUCCEEDED(hr))
382 {
383 hr = IDxDiagContainer_EnumChildContainerNames(child, 0, childbufW, sizeof(childbufW)/sizeof(WCHAR));
384 ok(hr == S_OK || hr == E_INVALIDARG,
385 "Expected IDxDiagContainer::EnumChildContainerNames to return S_OK or E_INVALIDARG, got 0x%08x\n", hr);
386 IDxDiagContainer_Release(child);
387
388 if (SUCCEEDED(hr))
389 break;
390 }
391 }
392
393 if (!*containerbufW || !*childbufW)
394 {
395 skip("Unable to find a suitable container\n");
396 goto cleanup;
397 }
398
399 trace("Testing IDxDiagContainer::GetChildContainer dot parsing with container %s and child container %s.\n",
400 wine_dbgstr_w(containerbufW), wine_dbgstr_w(childbufW));
401
402 for (i = 0; i < sizeof(test_strings)/sizeof(test_strings[0]); i++)
403 {
404 IDxDiagContainer *child;
405 char containerbufA[256];
406 char childbufA[256];
407 char dotbufferA[255 + 255 + 3 + 1];
408 WCHAR dotbufferW[255 + 255 + 3 + 1]; /* containerbuf + childbuf + dots + null terminator */
409
410 WideCharToMultiByte(CP_ACP, 0, containerbufW, -1, containerbufA, sizeof(containerbufA), NULL, NULL);
411 WideCharToMultiByte(CP_ACP, 0, childbufW, -1, childbufA, sizeof(childbufA), NULL, NULL);
412 sprintf(dotbufferA, test_strings[i].format, containerbufA, childbufA);
413 MultiByteToWideChar(CP_ACP, 0, dotbufferA, -1, dotbufferW, sizeof(dotbufferW)/sizeof(WCHAR));
414
415 trace("Trying container name %s\n", wine_dbgstr_w(dotbufferW));
416 hr = IDxDiagContainer_GetChildContainer(pddc, dotbufferW, &child);
417 ok(hr == test_strings[i].expect,
418 "Expected IDxDiagContainer::GetChildContainer to return 0x%08x for %s, got 0x%08x\n",
419 test_strings[i].expect, wine_dbgstr_w(dotbufferW), hr);
420 if (SUCCEEDED(hr))
421 IDxDiagContainer_Release(child);
422 }
423
424 cleanup:
425 IDxDiagContainer_Release(pddc);
426 IDxDiagProvider_Release(pddp);
427 }
428
429 static void test_EnumPropNames(void)
430 {
431 HRESULT hr;
432 WCHAR container[256], property[256];
433 IDxDiagContainer *child = NULL;
434 DWORD count, index, propcount;
435 static const WCHAR testW[] = {'t','e','s','t',0};
436
437 if (!create_root_IDxDiagContainer())
438 {
439 skip("Unable to create the root IDxDiagContainer\n");
440 return;
441 }
442
443 /* Find a container with a non-zero number of properties. */
444 hr = IDxDiagContainer_GetNumberOfChildContainers(pddc, &count);
445 ok(hr == S_OK, "Expected IDxDiagContainer::GetNumberOfChildContainers to return S_OK, got 0x%08x\n", hr);
446 if (FAILED(hr))
447 {
448 skip("IDxDiagContainer::GetNumberOfChildContainers failed\n");
449 goto cleanup;
450 }
451
452 for (index = 0; index < count; index++)
453 {
454 hr = IDxDiagContainer_EnumChildContainerNames(pddc, index, container, sizeof(container)/sizeof(WCHAR));
455 ok(hr == S_OK, "Expected IDxDiagContainer_EnumChildContainerNames to return S_OK, got 0x%08x\n", hr);
456 if (FAILED(hr))
457 {
458 skip("IDxDiagContainer::EnumChildContainerNames failed\n");
459 goto cleanup;
460 }
461
462 hr = IDxDiagContainer_GetChildContainer(pddc, container, &child);
463 ok(hr == S_OK, "Expected IDxDiagContainer::GetChildContainer to return S_OK, got 0x%08x\n", hr);
464
465 if (SUCCEEDED(hr))
466 {
467 hr = IDxDiagContainer_GetNumberOfProps(child, &propcount);
468 ok(hr == S_OK, "Expected IDxDiagContainer::GetNumberOfProps to return S_OK, got 0x%08x\n", hr);
469
470 if (!propcount)
471 {
472 IDxDiagContainer_Release(child);
473 child = NULL;
474 }
475 else
476 break;
477 }
478 }
479
480 if (!child)
481 {
482 skip("Unable to find a container with non-zero property count\n");
483 goto cleanup;
484 }
485
486 hr = IDxDiagContainer_EnumPropNames(child, ~0, NULL, 0);
487 ok(hr == E_INVALIDARG, "Expected IDxDiagContainer::EnumPropNames to return E_INVALIDARG, got 0x%08x\n", hr);
488
489 memcpy(property, testW, sizeof(testW));
490 hr = IDxDiagContainer_EnumPropNames(child, ~0, property, 0);
491 ok(hr == E_INVALIDARG, "Expected IDxDiagContainer::EnumPropNames to return E_INVALIDARG, got 0x%08x\n", hr);
492 ok(!memcmp(property, testW, sizeof(testW)),
493 "Expected the property buffer to be unchanged, got %s\n", wine_dbgstr_w(property));
494
495 memcpy(property, testW, sizeof(testW));
496 hr = IDxDiagContainer_EnumPropNames(child, ~0, property, sizeof(property)/sizeof(WCHAR));
497 ok(hr == E_INVALIDARG, "Expected IDxDiagContainer::EnumPropNames to return E_INVALIDARG, got 0x%08x\n", hr);
498 ok(!memcmp(property, testW, sizeof(testW)),
499 "Expected the property buffer to be unchanged, got %s\n", wine_dbgstr_w(property));
500
501 trace("Starting property enumeration of the %s container:\n", wine_dbgstr_w(container));
502
503 /* We should be able to enumerate as many properties as the value that
504 * IDxDiagContainer::GetNumberOfProps returns. */
505 for (index = 0; index <= propcount; index++)
506 {
507 /* A buffer size of 1 is unlikely to be valid, as only a null terminator
508 * could be stored, and it is unlikely that a property name could be empty. */
509 DWORD buffersize = 1;
510
511 memcpy(property, testW, sizeof(testW));
512 hr = IDxDiagContainer_EnumPropNames(child, index, property, buffersize);
513 if (hr == E_INVALIDARG)
514 {
515 /* We should get here when index is one more than the maximum index value. */
516 ok(propcount == index,
517 "Expected IDxDiagContainer::EnumPropNames to return E_INVALIDARG "
518 "on the last index %d, got 0x%08x\n", index, hr);
519 ok(!memcmp(property, testW, sizeof(testW)),
520 "Expected the property buffer to be unchanged, got %s\n", wine_dbgstr_w(property));
521 break;
522 }
523 else if (hr == DXDIAG_E_INSUFFICIENT_BUFFER)
524 {
525 WCHAR temp[256];
526
527 ok(property[0] == '\0',
528 "Expected the property buffer string to be empty, got %s\n", wine_dbgstr_w(property));
529 hr = IDxDiagContainer_EnumPropNames(child, index, temp, sizeof(temp)/sizeof(WCHAR));
530 ok(hr == S_OK,
531 "Expected IDxDiagContainer::EnumPropNames to return S_OK, got 0x%08x\n", hr);
532
533 /* Show that the DirectX SDK's stipulation that the buffer be at
534 * least 256 characters long is a mere suggestion, and smaller sizes
535 * can be acceptable also. IDxDiagContainer::EnumPropNames doesn't
536 * provide a way of getting the exact size required, so the buffersize
537 * value will be iterated to at most 256 characters. */
538 for (buffersize = 2; buffersize <= 256; buffersize++)
539 {
540 memcpy(property, testW, sizeof(testW));
541 hr = IDxDiagContainer_EnumPropNames(child, index, property, buffersize);
542 if (hr != DXDIAG_E_INSUFFICIENT_BUFFER)
543 break;
544
545 ok(!memcmp(temp, property, sizeof(WCHAR)*(buffersize - 1)),
546 "Expected truncated property name string, got %s\n", wine_dbgstr_w(property));
547 }
548
549 ok(hr == S_OK,
550 "Expected IDxDiagContainer::EnumPropNames to return S_OK, "
551 "got hr = 0x%08x, buffersize = %d\n", hr, buffersize);
552 if (hr == S_OK)
553 trace("child[%d] = %s, length = %d\n", index, wine_dbgstr_w(property), buffersize);
554 }
555 else
556 {
557 ok(0, "IDxDiagContainer::EnumPropNames unexpectedly returned 0x%08x\n", hr);
558 break;
559 }
560 }
561
562 IDxDiagContainer_Release(child);
563
564 cleanup:
565 IDxDiagContainer_Release(pddc);
566 IDxDiagProvider_Release(pddp);
567 }
568
569 static void test_GetProp(void)
570 {
571 HRESULT hr;
572 WCHAR container[256], property[256];
573 IDxDiagContainer *child = NULL;
574 DWORD count, index;
575 VARIANT var;
576 SAFEARRAY *sa;
577 SAFEARRAYBOUND bound;
578 ULONG ref;
579 static const WCHAR emptyW[] = {0};
580 static const WCHAR testW[] = {'t','e','s','t',0};
581
582 if (!create_root_IDxDiagContainer())
583 {
584 skip("Unable to create the root IDxDiagContainer\n");
585 return;
586 }
587
588 /* Find a container with a property. */
589 hr = IDxDiagContainer_GetNumberOfChildContainers(pddc, &count);
590 ok(hr == S_OK, "Expected IDxDiagContainer::GetNumberOfChildContainers to return S_OK, got 0x%08x\n", hr);
591 if (FAILED(hr))
592 {
593 skip("IDxDiagContainer::GetNumberOfChildContainers failed\n");
594 goto cleanup;
595 }
596
597 for (index = 0; index < count; index++)
598 {
599 hr = IDxDiagContainer_EnumChildContainerNames(pddc, index, container, sizeof(container)/sizeof(WCHAR));
600 ok(hr == S_OK, "Expected IDxDiagContainer_EnumChildContainerNames to return S_OK, got 0x%08x\n", hr);
601 if (FAILED(hr))
602 {
603 skip("IDxDiagContainer::EnumChildContainerNames failed\n");
604 goto cleanup;
605 }
606
607 hr = IDxDiagContainer_GetChildContainer(pddc, container, &child);
608 ok(hr == S_OK, "Expected IDxDiagContainer::GetChildContainer to return S_OK, got 0x%08x\n", hr);
609
610 if (SUCCEEDED(hr))
611 {
612 hr = IDxDiagContainer_EnumPropNames(child, 0, property, sizeof(property)/sizeof(WCHAR));
613 ok(hr == S_OK || hr == E_INVALIDARG,
614 "Expected IDxDiagContainer::EnumPropNames to return S_OK or E_INVALIDARG, got 0x%08x\n", hr);
615
616 if (SUCCEEDED(hr))
617 break;
618 else
619 {
620 IDxDiagContainer_Release(child);
621 child = NULL;
622 }
623 }
624 }
625
626 if (!child)
627 {
628 skip("Unable to find a suitable container\n");
629 goto cleanup;
630 }
631
632 hr = IDxDiagContainer_GetProp(child, NULL, NULL);
633 ok(hr == E_INVALIDARG, "Expected IDxDiagContainer::GetProp to return E_INVALIDARG, got 0x%08x\n", hr);
634
635 V_VT(&var) = 0xdead;
636 hr = IDxDiagContainer_GetProp(child, NULL, &var);
637 ok(hr == E_INVALIDARG, "Expected IDxDiagContainer::GetProp to return E_INVALIDARG, got 0x%08x\n", hr);
638 ok(V_VT(&var) == 0xdead, "Expected the variant to be untouched, got %u\n", V_VT(&var));
639
640 hr = IDxDiagContainer_GetProp(child, emptyW, NULL);
641 ok(hr == E_INVALIDARG, "Expected IDxDiagContainer::GetProp to return E_INVALIDARG, got 0x%08x\n", hr);
642
643 V_VT(&var) = 0xdead;
644 hr = IDxDiagContainer_GetProp(child, emptyW, &var);
645 ok(hr == E_INVALIDARG, "Expected IDxDiagContainer::GetProp to return E_INVALIDARG, got 0x%08x\n", hr);
646 ok(V_VT(&var) == 0xdead, "Expected the variant to be untouched, got %u\n", V_VT(&var));
647
648 hr = IDxDiagContainer_GetProp(child, testW, NULL);
649 ok(hr == E_INVALIDARG, "Expected IDxDiagContainer::GetProp to return E_INVALIDARG, got 0x%08x\n", hr);
650
651 V_VT(&var) = 0xdead;
652 hr = IDxDiagContainer_GetProp(child, testW, &var);
653 ok(hr == E_INVALIDARG, "Expected IDxDiagContainer::GetProp to return E_INVALIDARG, got 0x%08x\n", hr);
654 ok(V_VT(&var) == 0xdead, "Expected the variant to be untouched, got %u\n", V_VT(&var));
655
656 VariantInit(&var);
657 hr = IDxDiagContainer_GetProp(child, property, &var);
658 ok(hr == S_OK, "Expected IDxDiagContainer::GetProp to return S_OK, got 0x%08x\n", hr);
659 ok(V_VT(&var) != VT_EMPTY, "Expected the variant to be modified, got %d\n", V_VT(&var));
660
661 /* Since the documentation for IDxDiagContainer::GetProp claims that the
662 * function reports return values from VariantCopy, try to exercise failure
663 * paths in handling the destination variant. */
664
665 /* Try an invalid variant type. */
666 V_VT(&var) = 0xdead;
667 hr = IDxDiagContainer_GetProp(child, property, &var);
668 ok(hr == S_OK, "Expected IDxDiagContainer::GetProp to return S_OK, got 0x%08x\n", hr);
669 ok(V_VT(&var) != 0xdead, "Expected the variant to be modified, got %d\n", V_VT(&var));
670
671 /* Try passing a variant with a locked SAFEARRAY. */
672 bound.cElements = 1;
673 bound.lLbound = 0;
674 sa = SafeArrayCreate(VT_UI1, 1, &bound);
675 ok(sa != NULL, "Expected SafeArrayCreate to return a valid pointer\n");
676
677 V_VT(&var) = (VT_ARRAY | VT_UI1);
678 V_ARRAY(&var) = sa;
679
680 hr = SafeArrayLock(sa);
681 ok(hr == S_OK, "Expected SafeArrayLock to return S_OK, got 0x%08x\n", hr);
682
683 hr = IDxDiagContainer_GetProp(child, property, &var);
684 ok(hr == S_OK, "Expected IDxDiagContainer::GetProp to return S_OK, got 0x%08x\n", hr);
685 ok(V_VT(&var) != (VT_ARRAY | VT_UI1), "Expected the variant to be modified\n");
686
687 hr = SafeArrayUnlock(sa);
688 ok(hr == S_OK, "Expected SafeArrayUnlock to return S_OK, got 0x%08x\n", hr);
689 hr = SafeArrayDestroy(sa);
690 ok(hr == S_OK, "Expected SafeArrayDestroy to return S_OK, got 0x%08x\n", hr);
691
692 /* Determine whether GetProp calls VariantClear on the passed variant. */
693 V_VT(&var) = VT_UNKNOWN;
694 V_UNKNOWN(&var) = (IUnknown *)child;
695 IDxDiagContainer_AddRef(child);
696
697 hr = IDxDiagContainer_GetProp(child, property, &var);
698 ok(hr == S_OK, "Expected IDxDiagContainer::GetProp to return S_OK, got 0x%08x\n", hr);
699 ok(V_VT(&var) != VT_UNKNOWN, "Expected the variant to be modified\n");
700
701 IDxDiagContainer_AddRef(child);
702 ref = IDxDiagContainer_Release(child);
703 ok(ref == 2, "Expected reference count to be 2, got %u\n", ref);
704
705 IDxDiagContainer_Release(child);
706 cleanup:
707 IDxDiagContainer_Release(pddc);
708 IDxDiagProvider_Release(pddp);
709 }
710
711 static void test_root_children(void)
712 {
713 static const WCHAR DxDiag_DirectSound[] = {'D','x','D','i','a','g','_','D','i','r','e','c','t','S','o','u','n','d',0};
714 static const WCHAR DxDiag_DirectMusic[] = {'D','x','D','i','a','g','_','D','i','r','e','c','t','M','u','s','i','c',0};
715 static const WCHAR DxDiag_DirectInput[] = {'D','x','D','i','a','g','_','D','i','r','e','c','t','I','n','p','u','t',0};
716 static const WCHAR DxDiag_DirectPlay[] = {'D','x','D','i','a','g','_','D','i','r','e','c','t','P','l','a','y',0};
717 static const WCHAR DxDiag_SystemDevices[] = {'D','x','D','i','a','g','_','S','y','s','t','e','m','D','e','v','i','c','e','s',0};
718 static const WCHAR DxDiag_DirectXFiles[] = {'D','x','D','i','a','g','_','D','i','r','e','c','t','X','F','i','l','e','s',0};
719 static const WCHAR DxDiag_DirectShowFilters[] = {'D','x','D','i','a','g','_','D','i','r','e','c','t','S','h','o','w','F','i','l','t','e','r','s',0};
720 static const WCHAR DxDiag_LogicalDisks[] = {'D','x','D','i','a','g','_','L','o','g','i','c','a','l','D','i','s','k','s',0};
721
722 HRESULT hr;
723 DWORD count, index;
724
725 static const WCHAR *root_children[] = {
726 DxDiag_SystemInfo, DxDiag_DisplayDevices, DxDiag_DirectSound,
727 DxDiag_DirectMusic, DxDiag_DirectInput, DxDiag_DirectPlay,
728 DxDiag_SystemDevices, DxDiag_DirectXFiles, DxDiag_DirectShowFilters,
729 DxDiag_LogicalDisks
730 };
731
732 if (!create_root_IDxDiagContainer())
733 {
734 skip("Unable to create the root IDxDiagContainer\n");
735 return;
736 }
737
738 /* Verify the identity and ordering of the root container's children. */
739 hr = IDxDiagContainer_GetNumberOfChildContainers(pddc, &count);
740 ok(hr == S_OK, "Expected IDxDiagContainer::GetNumberOfChildContainers to return S_OK, got 0x%08x\n", hr);
741 if (FAILED(hr))
742 {
743 skip("IDxDiagContainer::GetNumberOfChildContainers failed\n");
744 goto cleanup;
745 }
746
747 ok(count == sizeof(root_children)/sizeof(root_children[0]),
748 "Got unexpected count %u for the number of child containers\n", count);
749
750 if (count != sizeof(root_children)/sizeof(root_children[0]))
751 {
752 skip("Received unexpected number of child containers\n");
753 goto cleanup;
754 }
755
756 for (index = 0; index <= count; index++)
757 {
758 WCHAR container[256];
759
760 hr = IDxDiagContainer_EnumChildContainerNames(pddc, index, container, sizeof(container)/sizeof(WCHAR));
761 if (hr == E_INVALIDARG)
762 {
763 ok(index == count,
764 "Expected IDxDiagContainer::EnumChildContainerNames to return "
765 "E_INVALIDARG on the last index %u\n", count);
766 break;
767 }
768 else if (hr == S_OK)
769 {
770 ok(!lstrcmpW(container, root_children[index]),
771 "Expected container %s for index %u, got %s\n",
772 wine_dbgstr_w(root_children[index]), index, wine_dbgstr_w(container));
773 }
774 else
775 {
776 ok(0, "IDxDiagContainer::EnumChildContainerNames unexpectedly returned 0x%08x\n", hr);
777 break;
778 }
779 }
780
781 cleanup:
782 IDxDiagContainer_Release(pddc);
783 IDxDiagProvider_Release(pddp);
784 }
785
786 static void test_container_properties(IDxDiagContainer *container, const struct property_test *property_tests, size_t len)
787 {
788 HRESULT hr;
789
790 /* Check that the container has no properties if there are no properties to examine. */
791 if (len == 0)
792 {
793 DWORD prop_count;
794
795 hr = IDxDiagContainer_GetNumberOfProps(container, &prop_count);
796 ok(hr == S_OK, "Expected IDxDiagContainer::GetNumberOfProps to return S_OK, got 0x%08x\n", hr);
797 if (hr == S_OK)
798 ok(prop_count == 0, "Expected container property count to be zero, got %u\n", prop_count);
799 }
800 else
801 {
802 VARIANT var;
803 int i;
804
805 VariantInit(&var);
806
807 /* Examine the variant types of obtained property values. */
808 for (i = 0; i < len; i++)
809 {
810 hr = IDxDiagContainer_GetProp(container, property_tests[i].prop, &var);
811 ok(hr == S_OK, "[%d] Expected IDxDiagContainer::GetProp to return S_OK for %s, got 0x%08x\n",
812 i, wine_dbgstr_w(property_tests[i].prop), hr);
813
814 if (hr == S_OK)
815 {
816 ok(V_VT(&var) == property_tests[i].vt,
817 "[%d] Expected variant type %d, got %d\n", i, property_tests[i].vt, V_VT(&var));
818 trace("%s = %s\n", wine_dbgstr_w(property_tests[i].prop), debugstr_variant(&var));
819 VariantClear(&var);
820 }
821 }
822 }
823 }
824
825 static void test_DxDiag_SystemInfo(void)
826 {
827 static const WCHAR dwOSMajorVersion[] = {'d','w','O','S','M','a','j','o','r','V','e','r','s','i','o','n',0};
828 static const WCHAR dwOSMinorVersion[] = {'d','w','O','S','M','i','n','o','r','V','e','r','s','i','o','n',0};
829 static const WCHAR dwOSBuildNumber[] = {'d','w','O','S','B','u','i','l','d','N','u','m','b','e','r',0};
830 static const WCHAR dwOSPlatformID[] = {'d','w','O','S','P','l','a','t','f','o','r','m','I','D',0};
831 static const WCHAR dwDirectXVersionMajor[] = {'d','w','D','i','r','e','c','t','X','V','e','r','s','i','o','n','M','a','j','o','r',0};
832 static const WCHAR dwDirectXVersionMinor[] = {'d','w','D','i','r','e','c','t','X','V','e','r','s','i','o','n','M','i','n','o','r',0};
833 static const WCHAR szDirectXVersionLetter[] = {'s','z','D','i','r','e','c','t','X','V','e','r','s','i','o','n','L','e','t','t','e','r',0};
834 static const WCHAR bDebug[] = {'b','D','e','b','u','g',0};
835 static const WCHAR bNECPC98[] = {'b','N','E','C','P','C','9','8',0};
836 static const WCHAR ullPhysicalMemory[] = {'u','l','l','P','h','y','s','i','c','a','l','M','e','m','o','r','y',0};
837 static const WCHAR ullUsedPageFile[] = {'u','l','l','U','s','e','d','P','a','g','e','F','i','l','e',0};
838 static const WCHAR ullAvailPageFile[] = {'u','l','l','A','v','a','i','l','P','a','g','e','F','i','l','e',0};
839 static const WCHAR szWindowsDir[] = {'s','z','W','i','n','d','o','w','s','D','i','r',0};
840 static const WCHAR szCSDVersion[] = {'s','z','C','S','D','V','e','r','s','i','o','n',0};
841 static const WCHAR szDirectXVersionEnglish[] = {'s','z','D','i','r','e','c','t','X','V','e','r','s','i','o','n','E','n','g','l','i','s','h',0};
842 static const WCHAR szDirectXVersionLongEnglish[] = {'s','z','D','i','r','e','c','t','X','V','e','r','s','i','o','n','L','o','n','g','E','n','g','l','i','s','h',0};
843 static const WCHAR bNetMeetingRunning[] = {'b','N','e','t','M','e','e','t','i','n','g','R','u','n','n','i','n','g',0};
844 static const WCHAR szMachineNameLocalized[] = {'s','z','M','a','c','h','i','n','e','N','a','m','e','L','o','c','a','l','i','z','e','d',0};
845 static const WCHAR szMachineNameEnglish[] = {'s','z','M','a','c','h','i','n','e','N','a','m','e','E','n','g','l','i','s','h',0};
846 static const WCHAR szLanguagesLocalized[] = {'s','z','L','a','n','g','u','a','g','e','s','L','o','c','a','l','i','z','e','d',0};
847 static const WCHAR szLanguagesEnglish[] = {'s','z','L','a','n','g','u','a','g','e','s','E','n','g','l','i','s','h',0};
848 static const WCHAR szTimeLocalized[] = {'s','z','T','i','m','e','L','o','c','a','l','i','z','e','d',0};
849 static const WCHAR szTimeEnglish[] = {'s','z','T','i','m','e','E','n','g','l','i','s','h',0};
850 static const WCHAR szPhysicalMemoryEnglish[] = {'s','z','P','h','y','s','i','c','a','l','M','e','m','o','r','y','E','n','g','l','i','s','h',0};
851 static const WCHAR szPageFileLocalized[] = {'s','z','P','a','g','e','F','i','l','e','L','o','c','a','l','i','z','e','d',0};
852 static const WCHAR szPageFileEnglish[] = {'s','z','P','a','g','e','F','i','l','e','E','n','g','l','i','s','h',0};
853 static const WCHAR szOSLocalized[] = {'s','z','O','S','L','o','c','a','l','i','z','e','d',0};
854 static const WCHAR szOSExLocalized[] = {'s','z','O','S','E','x','L','o','c','a','l','i','z','e','d',0};
855 static const WCHAR szOSExLongLocalized[] = {'s','z','O','S','E','x','L','o','n','g','L','o','c','a','l','i','z','e','d',0};
856 static const WCHAR szOSEnglish[] = {'s','z','O','S','E','n','g','l','i','s','h',0};
857 static const WCHAR szOSExEnglish[] = {'s','z','O','S','E','x','E','n','g','l','i','s','h',0};
858 static const WCHAR szOSExLongEnglish[] = {'s','z','O','S','E','x','L','o','n','g','E','n','g','l','i','s','h',0};
859 static const WCHAR szProcessorEnglish[] = {'s','z','P','r','o','c','e','s','s','o','r','E','n','g','l','i','s','h',0};
860
861 static const struct property_test property_tests[] =
862 {
863 {dwOSMajorVersion, VT_UI4},
864 {dwOSMinorVersion, VT_UI4},
865 {dwOSBuildNumber, VT_UI4},
866 {dwOSPlatformID, VT_UI4},
867 {dwDirectXVersionMajor, VT_UI4},
868 {dwDirectXVersionMinor, VT_UI4},
869 {szDirectXVersionLetter, VT_BSTR},
870 {bDebug, VT_BOOL},
871 {bNECPC98, VT_BOOL},
872 {ullPhysicalMemory, VT_BSTR},
873 {ullUsedPageFile, VT_BSTR},
874 {ullAvailPageFile, VT_BSTR},
875 {szWindowsDir, VT_BSTR},
876 {szCSDVersion, VT_BSTR},
877 {szDirectXVersionEnglish, VT_BSTR},
878 {szDirectXVersionLongEnglish, VT_BSTR},
879 {bNetMeetingRunning, VT_BOOL},
880 {szMachineNameLocalized, VT_BSTR},
881 {szMachineNameEnglish, VT_BSTR},
882 {szLanguagesLocalized, VT_BSTR},
883 {szLanguagesEnglish, VT_BSTR},
884 {szTimeLocalized, VT_BSTR},
885 {szTimeEnglish, VT_BSTR},
886 {szPhysicalMemoryEnglish, VT_BSTR},
887 {szPageFileLocalized, VT_BSTR},
888 {szPageFileEnglish, VT_BSTR},
889 {szOSLocalized, VT_BSTR},
890 {szOSExLocalized, VT_BSTR},
891 {szOSExLongLocalized, VT_BSTR},
892 {szOSEnglish, VT_BSTR},
893 {szOSExEnglish, VT_BSTR},
894 {szOSExLongEnglish, VT_BSTR},
895 {szProcessorEnglish, VT_BSTR},
896 };
897
898 IDxDiagContainer *container;
899 HRESULT hr;
900
901 if (!create_root_IDxDiagContainer())
902 {
903 skip("Unable to create the root IDxDiagContainer\n");
904 return;
905 }
906
907 hr = IDxDiagContainer_GetChildContainer(pddc, DxDiag_SystemInfo, &container);
908 ok(hr == S_OK, "Expected IDxDiagContainer::GetChildContainer to return S_OK, got 0x%08x\n", hr);
909
910 if (hr == S_OK)
911 {
912 trace("Testing container DxDiag_SystemInfo\n");
913 test_container_properties(container, property_tests, sizeof(property_tests)/sizeof(property_tests[0]));
914 IDxDiagContainer_Release(container);
915 }
916
917 IDxDiagContainer_Release(pddc);
918 IDxDiagProvider_Release(pddp);
919 }
920
921 static void test_DxDiag_DisplayDevices(void)
922 {
923 static const WCHAR szDescription[] = {'s','z','D','e','s','c','r','i','p','t','i','o','n',0};
924 static const WCHAR szDeviceName[] = {'s','z','D','e','v','i','c','e','N','a','m','e',0};
925 static const WCHAR szKeyDeviceID[] = {'s','z','K','e','y','D','e','v','i','c','e','I','D',0};
926 static const WCHAR szKeyDeviceKey[] = {'s','z','K','e','y','D','e','v','i','c','e','K','e','y',0};
927 static const WCHAR szVendorId[] = {'s','z','V','e','n','d','o','r','I','d',0};
928 static const WCHAR szDeviceId[] = {'s','z','D','e','v','i','c','e','I','d',0};
929 static const WCHAR szDeviceIdentifier[] = {'s','z','D','e','v','i','c','e','I','d','e','n','t','i','f','i','e','r',0};
930 static const WCHAR dwWidth[] = {'d','w','W','i','d','t','h',0};
931 static const WCHAR dwHeight[] = {'d','w','H','e','i','g','h','t',0};
932 static const WCHAR dwBpp[] = {'d','w','B','p','p',0};
933 static const WCHAR szDisplayMemoryLocalized[] = {'s','z','D','i','s','p','l','a','y','M','e','m','o','r','y','L','o','c','a','l','i','z','e','d',0};
934 static const WCHAR szDisplayMemoryEnglish[] = {'s','z','D','i','s','p','l','a','y','M','e','m','o','r','y','E','n','g','l','i','s','h',0};
935 static const WCHAR szDriverName[] = {'s','z','D','r','i','v','e','r','N','a','m','e',0};
936 static const WCHAR szDriverVersion[] = {'s','z','D','r','i','v','e','r','V','e','r','s','i','o','n',0};
937 static const WCHAR szSubSysId[] = {'s','z','S','u','b','S','y','s','I','d',0};
938 static const WCHAR szRevisionId[] = {'s','z','R','e','v','i','s','i','o','n','I','d',0};
939 static const WCHAR dwRefreshRate[] = {'d','w','R','e','f','r','e','s','h','R','a','t','e',0};
940 static const WCHAR szManufacturer[] = {'s','z','M','a','n','u','f','a','c','t','u','r','e','r',0};
941 static const WCHAR b3DAccelerationExists[] = {'b','3','D','A','c','c','e','l','e','r','a','t','i','o','n','E','x','i','s','t','s',0};
942 static const WCHAR b3DAccelerationEnabled[] = {'b','3','D','A','c','c','e','l','e','r','a','t','i','o','n','E','n','a','b','l','e','d',0};
943 static const WCHAR bDDAccelerationEnabled[] = {'b','D','D','A','c','c','e','l','e','r','a','t','i','o','n','E','n','a','b','l','e','d',0};
944
945 static const struct property_test property_tests[] =
946 {
947 {szDescription, VT_BSTR},
948 {szDeviceName, VT_BSTR},
949 {szKeyDeviceID, VT_BSTR},
950 {szKeyDeviceKey, VT_BSTR},
951 {szVendorId, VT_BSTR},
952 {szDeviceId, VT_BSTR},
953 {szDeviceIdentifier, VT_BSTR},
954 {dwWidth, VT_UI4},
955 {dwHeight, VT_UI4},
956 {dwBpp, VT_UI4},
957 {szDisplayMemoryLocalized, VT_BSTR},
958 {szDisplayMemoryEnglish, VT_BSTR},
959 {szDriverName, VT_BSTR},
960 {szDriverVersion, VT_BSTR},
961 {szSubSysId, VT_BSTR},
962 {szRevisionId, VT_BSTR},
963 {dwRefreshRate, VT_UI4},
964 {szManufacturer, VT_BSTR},
965 {b3DAccelerationExists, VT_BOOL},
966 {b3DAccelerationEnabled, VT_BOOL},
967 {bDDAccelerationEnabled, VT_BOOL},
968 };
969
970 IDxDiagContainer *display_cont = NULL;
971 DWORD count, i;
972 HRESULT hr;
973
974 if (!create_root_IDxDiagContainer())
975 {
976 skip("Unable to create the root IDxDiagContainer\n");
977 return;
978 }
979
980 hr = IDxDiagContainer_GetChildContainer(pddc, DxDiag_DisplayDevices, &display_cont);
981 ok(hr == S_OK, "Expected IDxDiagContainer::GetChildContainer to return S_OK, got 0x%08x\n", hr);
982
983 if (hr != S_OK)
984 goto cleanup;
985
986 hr = IDxDiagContainer_GetNumberOfProps(display_cont, &count);
987 ok(hr == S_OK, "Expected IDxDiagContainer::GetNumberOfProps to return S_OK, got 0x%08x\n", hr);
988 if (hr == S_OK)
989 ok(count == 0, "Expected count to be 0, got %u\n", count);
990
991 hr = IDxDiagContainer_GetNumberOfChildContainers(display_cont, &count);
992 ok(hr == S_OK, "Expected IDxDiagContainer::GetNumberOfChildContainers to return S_OK, got 0x%08x\n", hr);
993
994 if (hr != S_OK)
995 goto cleanup;
996
997 for (i = 0; i < count; i++)
998 {
999 WCHAR child_container[256];
1000 IDxDiagContainer *child;
1001
1002 hr = IDxDiagContainer_EnumChildContainerNames(display_cont, i, child_container, sizeof(child_container)/sizeof(WCHAR));
1003 ok(hr == S_OK, "Expected IDxDiagContainer::EnumChildContainerNames to return S_OK, got 0x%08x\n", hr);
1004
1005 hr = IDxDiagContainer_GetChildContainer(display_cont, child_container, &child);
1006 ok(hr == S_OK, "Expected IDxDiagContainer::GetChildContainer to return S_OK, got 0x%08x\n", hr);
1007
1008 if (hr == S_OK)
1009 {
1010 trace("Testing container %s\n", wine_dbgstr_w(child_container));
1011 test_container_properties(child, property_tests, sizeof(property_tests)/sizeof(property_tests[0]));
1012 }
1013 }
1014
1015 cleanup:
1016 if (display_cont) IDxDiagContainer_Release(display_cont);
1017 IDxDiagContainer_Release(pddc);
1018 IDxDiagProvider_Release(pddp);
1019 }
1020
1021 START_TEST(container)
1022 {
1023 CoInitialize(NULL);
1024 test_GetNumberOfChildContainers();
1025 test_GetNumberOfProps();
1026 test_EnumChildContainerNames();
1027 test_GetChildContainer();
1028 test_dot_parsing();
1029 test_EnumPropNames();
1030 test_GetProp();
1031
1032 test_root_children();
1033 test_DxDiag_SystemInfo();
1034 test_DxDiag_DisplayDevices();
1035 CoUninitialize();
1036 }