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