include/mscvpdb.h: Use flexible array members for the rest of structures.
[wine.git] / dlls / dxdiagn / tests / container.c
blob146c83070d8cb6244feda7a0bc7dd0a5c46b4295
1 /*
2 * Unit tests for IDxDiagContainer
4 * Copyright 2010 Andrew Nguyen
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.
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.
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
21 #define COBJMACROS
23 #include <stdio.h>
24 #include "dxdiag.h"
25 #include "oleauto.h"
26 #include "wine/test.h"
28 struct property_test
30 const WCHAR *prop;
31 VARTYPE vt;
34 static IDxDiagProvider *pddp;
35 static IDxDiagContainer *pddc;
37 static BOOL create_root_IDxDiagContainer(void)
39 HRESULT hr;
40 DXDIAG_INIT_PARAMS params;
42 hr = CoCreateInstance(&CLSID_DxDiagProvider, NULL, CLSCTX_INPROC_SERVER,
43 &IID_IDxDiagProvider, (LPVOID*)&pddp);
44 if (SUCCEEDED(hr))
46 params.dwSize = sizeof(params);
47 params.dwDxDiagHeaderVersion = DXDIAG_DX9_SDK_VERSION;
48 params.bAllowWHQLChecks = FALSE;
49 params.pReserved = NULL;
50 hr = IDxDiagProvider_Initialize(pddp, &params);
51 if (SUCCEEDED(hr))
53 hr = IDxDiagProvider_GetRootContainer(pddp, &pddc);
54 if (SUCCEEDED(hr))
55 return TRUE;
57 IDxDiagProvider_Release(pddp);
59 return FALSE;
62 static void test_GetNumberOfChildContainers(void)
64 HRESULT hr;
65 DWORD count;
67 if (!create_root_IDxDiagContainer())
69 skip("Unable to create the root IDxDiagContainer\n");
70 return;
73 hr = IDxDiagContainer_GetNumberOfChildContainers(pddc, NULL);
74 ok(hr == E_INVALIDARG,
75 "Expected IDxDiagContainer::GetNumberOfChildContainers to return E_INVALIDARG, got 0x%08lx\n", hr);
77 hr = IDxDiagContainer_GetNumberOfChildContainers(pddc, &count);
78 ok(hr == S_OK,
79 "Expected IDxDiagContainer::GetNumberOfChildContainers to return S_OK, got 0x%08lx\n", hr);
80 if (hr == S_OK)
81 ok(count != 0, "Expected the number of child containers for the root container to be non-zero\n");
83 IDxDiagContainer_Release(pddc);
84 IDxDiagProvider_Release(pddp);
87 static void test_GetNumberOfProps(void)
89 HRESULT hr;
90 DWORD count;
92 if (!create_root_IDxDiagContainer())
94 skip("Unable to create the root IDxDiagContainer\n");
95 return;
98 hr = IDxDiagContainer_GetNumberOfProps(pddc, NULL);
99 ok(hr == E_INVALIDARG, "Expected IDxDiagContainer::GetNumberOfProps to return E_INVALIDARG, got 0x%08lx\n", hr);
101 hr = IDxDiagContainer_GetNumberOfProps(pddc, &count);
102 ok(hr == S_OK, "Expected IDxDiagContainer::GetNumberOfProps to return S_OK, got 0x%08lx\n", hr);
103 if (hr == S_OK)
104 ok(count == 0, "Expected the number of properties for the root container to be zero\n");
106 IDxDiagContainer_Release(pddc);
107 IDxDiagProvider_Release(pddp);
110 static void test_EnumChildContainerNames(void)
112 HRESULT hr;
113 WCHAR container[256];
114 DWORD maxcount, index;
115 static const WCHAR testW[] = L"test";
117 if (!create_root_IDxDiagContainer())
119 skip("Unable to create the root IDxDiagContainer\n");
120 return;
123 /* Test various combinations of invalid parameters. */
124 hr = IDxDiagContainer_EnumChildContainerNames(pddc, 0, NULL, 0);
125 ok(hr == E_INVALIDARG,
126 "Expected IDxDiagContainer::EnumChildContainerNames to return E_INVALIDARG, got 0x%08lx\n", hr);
128 hr = IDxDiagContainer_EnumChildContainerNames(pddc, 0, NULL, ARRAY_SIZE(container));
129 ok(hr == E_INVALIDARG,
130 "Expected IDxDiagContainer::EnumChildContainerNames to return E_INVALIDARG, got 0x%08lx\n", hr);
132 /* Test the conditions in which the output buffer can be modified. */
133 memcpy(container, testW, sizeof(testW));
134 hr = IDxDiagContainer_EnumChildContainerNames(pddc, 0, container, 0);
135 ok(hr == E_INVALIDARG,
136 "Expected IDxDiagContainer::EnumChildContainerNames to return E_INVALIDARG, got 0x%08lx\n", hr);
137 ok(!memcmp(container, testW, sizeof(testW)),
138 "Expected the container buffer to be untouched, got %s\n", wine_dbgstr_w(container));
140 memcpy(container, testW, sizeof(testW));
141 hr = IDxDiagContainer_EnumChildContainerNames(pddc, ~0, container, 0);
142 ok(hr == E_INVALIDARG,
143 "Expected IDxDiagContainer::EnumChildContainerNames to return E_INVALIDARG, got 0x%08lx\n", hr);
144 ok(!memcmp(container, testW, sizeof(testW)),
145 "Expected the container buffer to be untouched, got %s\n", wine_dbgstr_w(container));
147 memcpy(container, testW, sizeof(testW));
148 hr = IDxDiagContainer_EnumChildContainerNames(pddc, ~0, container, ARRAY_SIZE(container));
149 ok(hr == E_INVALIDARG,
150 "Expected IDxDiagContainer::EnumChildContainerNames to return E_INVALIDARG, got 0x%08lx\n", hr);
151 ok(!memcmp(container, L"\0est", sizeof(L"\0est")),
152 "Expected the container buffer string to be empty, got %s\n", wine_dbgstr_w(container));
154 hr = IDxDiagContainer_GetNumberOfChildContainers(pddc, &maxcount);
155 ok(hr == S_OK, "Expected IDxDiagContainer::GetNumberOfChildContainers to return S_OK, got 0x%08lx\n", hr);
156 if (FAILED(hr))
158 skip("IDxDiagContainer::GetNumberOfChildContainers failed\n");
159 goto cleanup;
162 trace("Starting child container enumeration of the root container:\n");
164 /* We should be able to enumerate as many child containers as the value
165 * that IDxDiagContainer::GetNumberOfChildContainers returns. */
166 for (index = 0; index <= maxcount; index++)
168 /* A buffer size of 1 is unlikely to be valid, as only a null terminator
169 * could be stored, and it is unlikely that a container name could be empty. */
170 DWORD buffersize = 1;
171 memcpy(container, testW, sizeof(testW));
172 hr = IDxDiagContainer_EnumChildContainerNames(pddc, index, container, buffersize);
173 if (hr == E_INVALIDARG)
175 /* We should get here when index is one more than the maximum index value. */
176 ok(maxcount == index,
177 "Expected IDxDiagContainer::EnumChildContainerNames to return E_INVALIDARG "
178 "on the last index %ld, got 0x%08lx\n", index, hr);
179 ok(container[0] == '\0',
180 "Expected the container buffer string to be empty, got %s\n", wine_dbgstr_w(container));
181 break;
183 else if (hr == DXDIAG_E_INSUFFICIENT_BUFFER)
185 WCHAR temp[256];
187 ok(container[0] == '\0',
188 "Expected the container buffer string to be empty, got %s\n", wine_dbgstr_w(container));
190 /* Get the container name to compare against. */
191 hr = IDxDiagContainer_EnumChildContainerNames(pddc, index, temp, ARRAY_SIZE(temp));
192 ok(hr == S_OK,
193 "Expected IDxDiagContainer::EnumChildContainerNames to return S_OK, got 0x%08lx\n", hr);
195 /* Show that the DirectX SDK's stipulation that the buffer be at
196 * least 256 characters long is a mere suggestion, and smaller sizes
197 * can be acceptable also. IDxDiagContainer::EnumChildContainerNames
198 * doesn't provide a way of getting the exact size required, so the
199 * buffersize value will be iterated to at most 256 characters. */
200 for (buffersize = 2; buffersize <= 256; buffersize++)
202 memcpy(container, testW, sizeof(testW));
203 hr = IDxDiagContainer_EnumChildContainerNames(pddc, index, container, buffersize);
204 if (hr != DXDIAG_E_INSUFFICIENT_BUFFER)
205 break;
207 ok(!memcmp(temp, container, sizeof(WCHAR)*(buffersize - 1)),
208 "Expected truncated container name string, got %s\n", wine_dbgstr_w(container));
211 ok(hr == S_OK,
212 "Expected IDxDiagContainer::EnumChildContainerNames to return S_OK, "
213 "got hr = 0x%08lx, buffersize = %ld\n", hr, buffersize);
214 if (hr == S_OK)
215 trace("pddc[%ld] = %s, length = %ld\n", index, wine_dbgstr_w(container), buffersize);
217 else
219 ok(0, "IDxDiagContainer::EnumChildContainerNames unexpectedly returned 0x%08lx\n", hr);
220 break;
224 cleanup:
225 IDxDiagContainer_Release(pddc);
226 IDxDiagProvider_Release(pddp);
229 static void test_GetChildContainer(void)
231 HRESULT hr;
232 WCHAR container[256] = {0};
233 IDxDiagContainer *child;
235 if (!create_root_IDxDiagContainer())
237 skip("Unable to create the root IDxDiagContainer\n");
238 return;
241 /* Test various combinations of invalid parameters. */
242 hr = IDxDiagContainer_GetChildContainer(pddc, NULL, NULL);
243 ok(hr == E_INVALIDARG,
244 "Expected IDxDiagContainer::GetChildContainer to return E_INVALIDARG, got 0x%08lx\n", hr);
246 child = (void*)0xdeadbeef;
247 hr = IDxDiagContainer_GetChildContainer(pddc, NULL, &child);
248 ok(hr == E_INVALIDARG,
249 "Expected IDxDiagContainer::GetChildContainer to return E_INVALIDARG, got 0x%08lx\n", hr);
250 ok(child == (void*)0xdeadbeef, "Expected output pointer to be unchanged, got %p\n", child);
252 hr = IDxDiagContainer_GetChildContainer(pddc, container, NULL);
253 ok(hr == E_INVALIDARG,
254 "Expected IDxDiagContainer::GetChildContainer to return E_INVALIDARG, got 0x%08lx\n", hr);
256 child = (void*)0xdeadbeef;
257 hr = IDxDiagContainer_GetChildContainer(pddc, container, &child);
258 ok(hr == E_INVALIDARG,
259 "Expected IDxDiagContainer::GetChildContainer to return E_INVALIDARG, got 0x%08lx\n", hr);
260 ok(child == NULL, "Expected output pointer to be NULL, got %p\n", child);
262 /* Get the name of a suitable child container. */
263 hr = IDxDiagContainer_EnumChildContainerNames(pddc, 0, container, ARRAY_SIZE(container));
264 ok(hr == S_OK,
265 "Expected IDxDiagContainer::EnumChildContainerNames to return S_OK, got 0x%08lx\n", hr);
266 if (FAILED(hr))
268 skip("IDxDiagContainer::EnumChildContainerNames failed\n");
269 goto cleanup;
272 child = (void*)0xdeadbeef;
273 hr = IDxDiagContainer_GetChildContainer(pddc, container, &child);
274 ok(hr == S_OK,
275 "Expected IDxDiagContainer::GetChildContainer to return S_OK, got 0x%08lx\n", hr);
276 ok(child != NULL && child != (void*)0xdeadbeef, "Expected a valid output pointer, got %p\n", child);
278 if (SUCCEEDED(hr))
280 IDxDiagContainer *ptr;
282 /* Show that IDxDiagContainer::GetChildContainer returns a different pointer
283 * for multiple calls for the same container name. */
284 hr = IDxDiagContainer_GetChildContainer(pddc, container, &ptr);
285 ok(hr == S_OK,
286 "Expected IDxDiagContainer::GetChildContainer to return S_OK, got 0x%08lx\n", hr);
287 if (SUCCEEDED(hr))
288 ok(ptr != child, "Expected the two pointers (%p vs. %p) to be unequal\n", child, ptr);
290 IDxDiagContainer_Release(ptr);
291 IDxDiagContainer_Release(child);
294 cleanup:
295 IDxDiagContainer_Release(pddc);
296 IDxDiagProvider_Release(pddp);
299 static void test_dot_parsing(void)
301 HRESULT hr;
302 WCHAR containerbufW[256] = {0}, childbufW[256] = {0};
303 DWORD count, index;
304 size_t i;
305 static const struct
307 const char *format;
308 const HRESULT expect;
309 } test_strings[] = {
310 { "%s.%s", S_OK },
311 { "%s.%s.", S_OK },
312 { ".%s.%s", E_INVALIDARG },
313 { "%s.%s..", E_INVALIDARG },
314 { ".%s.%s.", E_INVALIDARG },
315 { "..%s.%s", E_INVALIDARG },
318 if (!create_root_IDxDiagContainer())
320 skip("Unable to create the root IDxDiagContainer\n");
321 return;
324 /* Find a container with a child container of its own. */
325 hr = IDxDiagContainer_GetNumberOfChildContainers(pddc, &count);
326 ok(hr == S_OK, "Expected IDxDiagContainer::GetNumberOfChildContainers to return S_OK, got 0x%08lx\n", hr);
327 if (FAILED(hr))
329 skip("IDxDiagContainer::GetNumberOfChildContainers failed\n");
330 goto cleanup;
333 for (index = 0; index < count; index++)
335 IDxDiagContainer *child;
337 hr = IDxDiagContainer_EnumChildContainerNames(pddc, index, containerbufW, ARRAY_SIZE(containerbufW));
338 ok(hr == S_OK, "Expected IDxDiagContainer_EnumChildContainerNames to return S_OK, got 0x%08lx\n", hr);
339 if (FAILED(hr))
341 skip("IDxDiagContainer::EnumChildContainerNames failed\n");
342 goto cleanup;
345 hr = IDxDiagContainer_GetChildContainer(pddc, containerbufW, &child);
346 ok(hr == S_OK, "Expected IDxDiagContainer::GetChildContainer to return S_OK, got 0x%08lx\n", hr);
348 if (SUCCEEDED(hr))
350 hr = IDxDiagContainer_EnumChildContainerNames(child, 0, childbufW, ARRAY_SIZE(childbufW));
351 ok(hr == S_OK || hr == E_INVALIDARG,
352 "Expected IDxDiagContainer::EnumChildContainerNames to return S_OK or E_INVALIDARG, got 0x%08lx\n", hr);
353 IDxDiagContainer_Release(child);
355 if (SUCCEEDED(hr))
356 break;
360 if (!*containerbufW || !*childbufW)
362 skip("Unable to find a suitable container\n");
363 goto cleanup;
366 trace("Testing IDxDiagContainer::GetChildContainer dot parsing with container %s and child container %s.\n",
367 wine_dbgstr_w(containerbufW), wine_dbgstr_w(childbufW));
369 for (i = 0; i < ARRAY_SIZE(test_strings); i++)
371 IDxDiagContainer *child;
372 char containerbufA[256];
373 char childbufA[256];
374 char dotbufferA[255 + 255 + 3 + 1];
375 WCHAR dotbufferW[255 + 255 + 3 + 1]; /* containerbuf + childbuf + dots + null terminator */
377 WideCharToMultiByte(CP_ACP, 0, containerbufW, -1, containerbufA, sizeof(containerbufA), NULL, NULL);
378 WideCharToMultiByte(CP_ACP, 0, childbufW, -1, childbufA, sizeof(childbufA), NULL, NULL);
379 sprintf(dotbufferA, test_strings[i].format, containerbufA, childbufA);
380 MultiByteToWideChar(CP_ACP, 0, dotbufferA, -1, dotbufferW, ARRAY_SIZE(dotbufferW));
382 trace("Trying container name %s\n", wine_dbgstr_w(dotbufferW));
383 hr = IDxDiagContainer_GetChildContainer(pddc, dotbufferW, &child);
384 ok(hr == test_strings[i].expect,
385 "Expected IDxDiagContainer::GetChildContainer to return 0x%08lx for %s, got 0x%08lx\n",
386 test_strings[i].expect, wine_dbgstr_w(dotbufferW), hr);
387 if (SUCCEEDED(hr))
388 IDxDiagContainer_Release(child);
391 cleanup:
392 IDxDiagContainer_Release(pddc);
393 IDxDiagProvider_Release(pddp);
396 static void test_EnumPropNames(void)
398 HRESULT hr;
399 WCHAR container[256], property[256];
400 IDxDiagContainer *child = NULL;
401 DWORD count, index, propcount;
402 static const WCHAR testW[] = L"test";
404 if (!create_root_IDxDiagContainer())
406 skip("Unable to create the root IDxDiagContainer\n");
407 return;
410 /* Find a container with a non-zero number of properties. */
411 hr = IDxDiagContainer_GetNumberOfChildContainers(pddc, &count);
412 ok(hr == S_OK, "Expected IDxDiagContainer::GetNumberOfChildContainers to return S_OK, got 0x%08lx\n", hr);
413 if (FAILED(hr))
415 skip("IDxDiagContainer::GetNumberOfChildContainers failed\n");
416 goto cleanup;
419 for (index = 0; index < count; index++)
421 hr = IDxDiagContainer_EnumChildContainerNames(pddc, index, container, ARRAY_SIZE(container));
422 ok(hr == S_OK, "Expected IDxDiagContainer_EnumChildContainerNames to return S_OK, got 0x%08lx\n", hr);
423 if (FAILED(hr))
425 skip("IDxDiagContainer::EnumChildContainerNames failed\n");
426 goto cleanup;
429 hr = IDxDiagContainer_GetChildContainer(pddc, container, &child);
430 ok(hr == S_OK, "Expected IDxDiagContainer::GetChildContainer to return S_OK, got 0x%08lx\n", hr);
432 if (SUCCEEDED(hr))
434 hr = IDxDiagContainer_GetNumberOfProps(child, &propcount);
435 ok(hr == S_OK, "Expected IDxDiagContainer::GetNumberOfProps to return S_OK, got 0x%08lx\n", hr);
437 if (!propcount)
439 IDxDiagContainer_Release(child);
440 child = NULL;
442 else
443 break;
447 if (!child)
449 skip("Unable to find a container with non-zero property count\n");
450 goto cleanup;
453 hr = IDxDiagContainer_EnumPropNames(child, ~0, NULL, 0);
454 ok(hr == E_INVALIDARG, "Expected IDxDiagContainer::EnumPropNames to return E_INVALIDARG, got 0x%08lx\n", hr);
456 memcpy(property, testW, sizeof(testW));
457 hr = IDxDiagContainer_EnumPropNames(child, ~0, property, 0);
458 ok(hr == E_INVALIDARG, "Expected IDxDiagContainer::EnumPropNames to return E_INVALIDARG, got 0x%08lx\n", hr);
459 ok(!memcmp(property, testW, sizeof(testW)),
460 "Expected the property buffer to be unchanged, got %s\n", wine_dbgstr_w(property));
462 memcpy(property, testW, sizeof(testW));
463 hr = IDxDiagContainer_EnumPropNames(child, ~0, property, ARRAY_SIZE(property));
464 ok(hr == E_INVALIDARG, "Expected IDxDiagContainer::EnumPropNames to return E_INVALIDARG, got 0x%08lx\n", hr);
465 ok(!memcmp(property, testW, sizeof(testW)),
466 "Expected the property buffer to be unchanged, got %s\n", wine_dbgstr_w(property));
468 trace("Starting property enumeration of the %s container:\n", wine_dbgstr_w(container));
470 /* We should be able to enumerate as many properties as the value that
471 * IDxDiagContainer::GetNumberOfProps returns. */
472 for (index = 0; index <= propcount; index++)
474 /* A buffer size of 1 is unlikely to be valid, as only a null terminator
475 * could be stored, and it is unlikely that a property name could be empty. */
476 DWORD buffersize = 1;
478 memcpy(property, testW, sizeof(testW));
479 hr = IDxDiagContainer_EnumPropNames(child, index, property, buffersize);
480 if (hr == E_INVALIDARG)
482 /* We should get here when index is one more than the maximum index value. */
483 ok(propcount == index,
484 "Expected IDxDiagContainer::EnumPropNames to return E_INVALIDARG "
485 "on the last index %ld, got 0x%08lx\n", index, hr);
486 ok(!memcmp(property, testW, sizeof(testW)),
487 "Expected the property buffer to be unchanged, got %s\n", wine_dbgstr_w(property));
488 break;
490 else if (hr == DXDIAG_E_INSUFFICIENT_BUFFER)
492 WCHAR temp[256];
494 ok(property[0] == '\0',
495 "Expected the property buffer string to be empty, got %s\n", wine_dbgstr_w(property));
496 hr = IDxDiagContainer_EnumPropNames(child, index, temp, ARRAY_SIZE(temp));
497 ok(hr == S_OK,
498 "Expected IDxDiagContainer::EnumPropNames to return S_OK, got 0x%08lx\n", hr);
500 /* Show that the DirectX SDK's stipulation that the buffer be at
501 * least 256 characters long is a mere suggestion, and smaller sizes
502 * can be acceptable also. IDxDiagContainer::EnumPropNames doesn't
503 * provide a way of getting the exact size required, so the buffersize
504 * value will be iterated to at most 256 characters. */
505 for (buffersize = 2; buffersize <= 256; buffersize++)
507 memcpy(property, testW, sizeof(testW));
508 hr = IDxDiagContainer_EnumPropNames(child, index, property, buffersize);
509 if (hr != DXDIAG_E_INSUFFICIENT_BUFFER)
510 break;
512 ok(!memcmp(temp, property, sizeof(WCHAR)*(buffersize - 1)),
513 "Expected truncated property name string, got %s\n", wine_dbgstr_w(property));
516 ok(hr == S_OK,
517 "Expected IDxDiagContainer::EnumPropNames to return S_OK, "
518 "got hr = 0x%08lx, buffersize = %ld\n", hr, buffersize);
519 if (hr == S_OK)
520 trace("child[%ld] = %s, length = %ld\n", index, wine_dbgstr_w(property), buffersize);
522 else
524 ok(0, "IDxDiagContainer::EnumPropNames unexpectedly returned 0x%08lx\n", hr);
525 break;
529 IDxDiagContainer_Release(child);
531 cleanup:
532 IDxDiagContainer_Release(pddc);
533 IDxDiagProvider_Release(pddp);
536 static void test_GetProp(void)
538 HRESULT hr;
539 WCHAR container[256], property[256];
540 IDxDiagContainer *child = NULL;
541 DWORD count, index;
542 VARIANT var;
543 SAFEARRAY *sa;
544 SAFEARRAYBOUND bound;
545 ULONG ref;
546 static const WCHAR testW[] = L"test";
548 if (!create_root_IDxDiagContainer())
550 skip("Unable to create the root IDxDiagContainer\n");
551 return;
554 /* Find a container with a property. */
555 hr = IDxDiagContainer_GetNumberOfChildContainers(pddc, &count);
556 ok(hr == S_OK, "Expected IDxDiagContainer::GetNumberOfChildContainers to return S_OK, got 0x%08lx\n", hr);
557 if (FAILED(hr))
559 skip("IDxDiagContainer::GetNumberOfChildContainers failed\n");
560 goto cleanup;
563 for (index = 0; index < count; index++)
565 hr = IDxDiagContainer_EnumChildContainerNames(pddc, index, container, ARRAY_SIZE(container));
566 ok(hr == S_OK, "Expected IDxDiagContainer_EnumChildContainerNames to return S_OK, got 0x%08lx\n", hr);
567 if (FAILED(hr))
569 skip("IDxDiagContainer::EnumChildContainerNames failed\n");
570 goto cleanup;
573 hr = IDxDiagContainer_GetChildContainer(pddc, container, &child);
574 ok(hr == S_OK, "Expected IDxDiagContainer::GetChildContainer to return S_OK, got 0x%08lx\n", hr);
576 if (SUCCEEDED(hr))
578 hr = IDxDiagContainer_EnumPropNames(child, 0, property, ARRAY_SIZE(property));
579 ok(hr == S_OK || hr == E_INVALIDARG,
580 "Expected IDxDiagContainer::EnumPropNames to return S_OK or E_INVALIDARG, got 0x%08lx\n", hr);
582 if (SUCCEEDED(hr))
583 break;
584 else
586 IDxDiagContainer_Release(child);
587 child = NULL;
592 if (!child)
594 skip("Unable to find a suitable container\n");
595 goto cleanup;
598 hr = IDxDiagContainer_GetProp(child, NULL, NULL);
599 ok(hr == E_INVALIDARG, "Expected IDxDiagContainer::GetProp to return E_INVALIDARG, got 0x%08lx\n", hr);
601 V_VT(&var) = 0xdead;
602 hr = IDxDiagContainer_GetProp(child, NULL, &var);
603 ok(hr == E_INVALIDARG, "Expected IDxDiagContainer::GetProp to return E_INVALIDARG, got 0x%08lx\n", hr);
604 ok(V_VT(&var) == 0xdead, "Expected the variant to be untouched, got %u\n", V_VT(&var));
606 hr = IDxDiagContainer_GetProp(child, L"", NULL);
607 ok(hr == E_INVALIDARG, "Expected IDxDiagContainer::GetProp to return E_INVALIDARG, got 0x%08lx\n", hr);
609 V_VT(&var) = 0xdead;
610 hr = IDxDiagContainer_GetProp(child, L"", &var);
611 ok(hr == E_INVALIDARG, "Expected IDxDiagContainer::GetProp to return E_INVALIDARG, got 0x%08lx\n", hr);
612 ok(V_VT(&var) == 0xdead, "Expected the variant to be untouched, got %u\n", V_VT(&var));
614 hr = IDxDiagContainer_GetProp(child, testW, NULL);
615 ok(hr == E_INVALIDARG, "Expected IDxDiagContainer::GetProp to return E_INVALIDARG, got 0x%08lx\n", hr);
617 V_VT(&var) = 0xdead;
618 hr = IDxDiagContainer_GetProp(child, testW, &var);
619 ok(hr == E_INVALIDARG, "Expected IDxDiagContainer::GetProp to return E_INVALIDARG, got 0x%08lx\n", hr);
620 ok(V_VT(&var) == 0xdead, "Expected the variant to be untouched, got %u\n", V_VT(&var));
622 VariantInit(&var);
623 hr = IDxDiagContainer_GetProp(child, property, &var);
624 ok(hr == S_OK, "Expected IDxDiagContainer::GetProp to return S_OK, got 0x%08lx\n", hr);
625 ok(V_VT(&var) != VT_EMPTY, "Expected the variant to be modified, got %d\n", V_VT(&var));
627 /* Since the documentation for IDxDiagContainer::GetProp claims that the
628 * function reports return values from VariantCopy, try to exercise failure
629 * paths in handling the destination variant. */
631 /* Try an invalid variant type. */
632 V_VT(&var) = 0xdead;
633 hr = IDxDiagContainer_GetProp(child, property, &var);
634 ok(hr == S_OK, "Expected IDxDiagContainer::GetProp to return S_OK, got 0x%08lx\n", hr);
635 ok(V_VT(&var) != 0xdead, "Expected the variant to be modified, got %d\n", V_VT(&var));
637 /* Try passing a variant with a locked SAFEARRAY. */
638 bound.cElements = 1;
639 bound.lLbound = 0;
640 sa = SafeArrayCreate(VT_UI1, 1, &bound);
641 ok(sa != NULL, "Expected SafeArrayCreate to return a valid pointer\n");
643 V_VT(&var) = (VT_ARRAY | VT_UI1);
644 V_ARRAY(&var) = sa;
646 hr = SafeArrayLock(sa);
647 ok(hr == S_OK, "Expected SafeArrayLock to return S_OK, got 0x%08lx\n", hr);
649 hr = IDxDiagContainer_GetProp(child, property, &var);
650 ok(hr == S_OK, "Expected IDxDiagContainer::GetProp to return S_OK, got 0x%08lx\n", hr);
651 ok(V_VT(&var) != (VT_ARRAY | VT_UI1), "Expected the variant to be modified\n");
653 hr = SafeArrayUnlock(sa);
654 ok(hr == S_OK, "Expected SafeArrayUnlock to return S_OK, got 0x%08lx\n", hr);
655 hr = SafeArrayDestroy(sa);
656 ok(hr == S_OK, "Expected SafeArrayDestroy to return S_OK, got 0x%08lx\n", hr);
658 /* Determine whether GetProp calls VariantClear on the passed variant. */
659 V_VT(&var) = VT_UNKNOWN;
660 V_UNKNOWN(&var) = (IUnknown *)child;
661 IDxDiagContainer_AddRef(child);
663 hr = IDxDiagContainer_GetProp(child, property, &var);
664 ok(hr == S_OK, "Expected IDxDiagContainer::GetProp to return S_OK, got 0x%08lx\n", hr);
665 ok(V_VT(&var) != VT_UNKNOWN, "Expected the variant to be modified\n");
667 IDxDiagContainer_AddRef(child);
668 ref = IDxDiagContainer_Release(child);
669 ok(ref == 2, "Expected reference count to be 2, got %lu\n", ref);
670 IDxDiagContainer_Release(child);
672 IDxDiagContainer_Release(child);
673 cleanup:
674 IDxDiagContainer_Release(pddc);
675 IDxDiagProvider_Release(pddp);
678 static void test_root_children(void)
680 HRESULT hr;
681 DWORD count, index;
683 static const WCHAR *root_children[] = {
684 L"DxDiag_SystemInfo", L"DxDiag_DisplayDevices", L"DxDiag_DirectSound",
685 L"DxDiag_DirectMusic", L"DxDiag_DirectInput", L"DxDiag_DirectPlay",
686 L"DxDiag_SystemDevices", L"DxDiag_DirectXFiles", L"DxDiag_DirectShowFilters",
687 L"DxDiag_LogicalDisks"
690 if (!create_root_IDxDiagContainer())
692 skip("Unable to create the root IDxDiagContainer\n");
693 return;
696 /* Verify the identity and ordering of the root container's children. */
697 hr = IDxDiagContainer_GetNumberOfChildContainers(pddc, &count);
698 ok(hr == S_OK, "Expected IDxDiagContainer::GetNumberOfChildContainers to return S_OK, got 0x%08lx\n", hr);
699 if (FAILED(hr))
701 skip("IDxDiagContainer::GetNumberOfChildContainers failed\n");
702 goto cleanup;
705 ok(count == ARRAY_SIZE(root_children),
706 "Got unexpected count %lu for the number of child containers\n", count);
708 if (count != ARRAY_SIZE(root_children))
710 skip("Received unexpected number of child containers\n");
711 goto cleanup;
714 for (index = 0; index <= count; index++)
716 WCHAR container[256];
718 hr = IDxDiagContainer_EnumChildContainerNames(pddc, index, container, ARRAY_SIZE(container));
719 if (hr == E_INVALIDARG)
721 ok(index == count,
722 "Expected IDxDiagContainer::EnumChildContainerNames to return "
723 "E_INVALIDARG on the last index %lu\n", count);
724 break;
726 else if (hr == S_OK)
728 ok(!lstrcmpW(container, root_children[index]),
729 "Expected container %s for index %lu, got %s\n",
730 wine_dbgstr_w(root_children[index]), index, wine_dbgstr_w(container));
732 else
734 ok(0, "IDxDiagContainer::EnumChildContainerNames unexpectedly returned 0x%08lx\n", hr);
735 break;
739 cleanup:
740 IDxDiagContainer_Release(pddc);
741 IDxDiagProvider_Release(pddp);
744 static void test_container_properties(IDxDiagContainer *container, const struct property_test *property_tests, size_t len)
746 HRESULT hr;
748 /* Check that the container has no properties if there are no properties to examine. */
749 if (len == 0)
751 DWORD prop_count;
753 hr = IDxDiagContainer_GetNumberOfProps(container, &prop_count);
754 ok(hr == S_OK, "Expected IDxDiagContainer::GetNumberOfProps to return S_OK, got 0x%08lx\n", hr);
755 if (hr == S_OK)
756 ok(prop_count == 0, "Expected container property count to be zero, got %lu\n", prop_count);
758 else
760 VARIANT var;
761 int i;
763 VariantInit(&var);
765 /* Examine the variant types of obtained property values. */
766 for (i = 0; i < len; i++)
768 hr = IDxDiagContainer_GetProp(container, property_tests[i].prop, &var);
769 ok(hr == S_OK, "[%d] Expected IDxDiagContainer::GetProp to return S_OK for %s, got 0x%08lx\n",
770 i, wine_dbgstr_w(property_tests[i].prop), hr);
772 if (hr == S_OK)
774 ok(V_VT(&var) == property_tests[i].vt,
775 "[%d] Expected variant type %d, got %d\n", i, property_tests[i].vt, V_VT(&var));
776 trace("%s = %s\n", wine_dbgstr_w(property_tests[i].prop), debugstr_variant(&var));
777 VariantClear(&var);
783 static void test_DxDiag_SystemInfo(void)
785 static const struct property_test property_tests[] =
787 {L"dwOSMajorVersion", VT_UI4},
788 {L"dwOSMinorVersion", VT_UI4},
789 {L"dwOSBuildNumber", VT_UI4},
790 {L"dwOSPlatformID", VT_UI4},
791 {L"dwDirectXVersionMajor", VT_UI4},
792 {L"dwDirectXVersionMinor", VT_UI4},
793 {L"szDirectXVersionLetter", VT_BSTR},
794 {L"bDebug", VT_BOOL},
795 {L"bIsD3DDebugRuntime", VT_BOOL},
796 {L"bNECPC98", VT_BOOL},
797 {L"ullPhysicalMemory", VT_BSTR},
798 {L"ullUsedPageFile", VT_BSTR},
799 {L"ullAvailPageFile", VT_BSTR},
800 {L"szWindowsDir", VT_BSTR},
801 {L"szCSDVersion", VT_BSTR},
802 {L"szDirectXVersionEnglish", VT_BSTR},
803 {L"szDirectXVersionLongEnglish", VT_BSTR},
804 {L"bNetMeetingRunning", VT_BOOL},
805 {L"szMachineNameLocalized", VT_BSTR},
806 {L"szMachineNameEnglish", VT_BSTR},
807 {L"szLanguagesLocalized", VT_BSTR},
808 {L"szLanguagesEnglish", VT_BSTR},
809 {L"szTimeLocalized", VT_BSTR},
810 {L"szTimeEnglish", VT_BSTR},
811 {L"szPhysicalMemoryEnglish", VT_BSTR},
812 {L"szPageFileLocalized", VT_BSTR},
813 {L"szPageFileEnglish", VT_BSTR},
814 {L"szOSLocalized", VT_BSTR},
815 {L"szOSExLocalized", VT_BSTR},
816 {L"szOSExLongLocalized", VT_BSTR},
817 {L"szOSEnglish", VT_BSTR},
818 {L"szOSExEnglish", VT_BSTR},
819 {L"szOSExLongEnglish", VT_BSTR},
820 {L"szProcessorEnglish", VT_BSTR},
823 IDxDiagContainer *container, *container2;
824 HRESULT hr;
826 if (!create_root_IDxDiagContainer())
828 skip("Unable to create the root IDxDiagContainer\n");
829 return;
832 hr = IDxDiagContainer_GetChildContainer(pddc, L"", &container2);
833 ok(hr == E_INVALIDARG, "Expected IDxDiagContainer::GetChildContainer to return E_INVALIDARG, got 0x%08lx\n", hr);
835 hr = IDxDiagContainer_GetChildContainer(pddc, L"DxDiag_SystemInfo", &container);
836 ok(hr == S_OK, "Expected IDxDiagContainer::GetChildContainer to return S_OK, got 0x%08lx\n", hr);
838 if (hr == S_OK)
840 trace("Testing container DxDiag_SystemInfo\n");
841 test_container_properties(container, property_tests, ARRAY_SIZE(property_tests));
843 container2 = NULL;
844 hr = IDxDiagContainer_GetChildContainer(container, L"", &container2);
845 ok(hr == S_OK, "Expected IDxDiagContainer::GetChildContainer to return S_OK, got 0x%08lx\n", hr);
846 ok(container2 != NULL, "Expected container2 != NULL\n");
847 ok(container2 != container, "Expected container != container2\n");
849 IDxDiagContainer_Release(container2);
850 IDxDiagContainer_Release(container);
853 IDxDiagContainer_Release(pddc);
854 IDxDiagProvider_Release(pddp);
857 static void test_DxDiag_DisplayDevices(void)
859 static const struct property_test property_tests[] =
861 {L"szDescription", VT_BSTR},
862 {L"szDeviceName", VT_BSTR},
863 {L"szKeyDeviceID", VT_BSTR},
864 {L"szKeyDeviceKey", VT_BSTR},
865 {L"szVendorId", VT_BSTR},
866 {L"szDeviceId", VT_BSTR},
867 {L"szDeviceIdentifier", VT_BSTR},
868 {L"dwWidth", VT_UI4},
869 {L"dwHeight", VT_UI4},
870 {L"dwBpp", VT_UI4},
871 {L"szDisplayMemoryLocalized", VT_BSTR},
872 {L"szDisplayMemoryEnglish", VT_BSTR},
873 {L"szDriverName", VT_BSTR},
874 {L"szDriverVersion", VT_BSTR},
875 {L"szSubSysId", VT_BSTR},
876 {L"szRevisionId", VT_BSTR},
877 {L"dwRefreshRate", VT_UI4},
878 {L"szManufacturer", VT_BSTR},
879 {L"b3DAccelerationExists", VT_BOOL},
880 {L"b3DAccelerationEnabled", VT_BOOL},
881 {L"bAGPEnabled", VT_BOOL},
882 {L"bAGPExistenceValid", VT_BOOL},
883 {L"bAGPExists", VT_BOOL},
884 {L"bDDAccelerationEnabled", VT_BOOL},
885 {L"iAdapter", VT_UI4},
888 IDxDiagContainer *display_cont = NULL;
889 DWORD count, i;
890 HRESULT hr;
892 if (!create_root_IDxDiagContainer())
894 skip("Unable to create the root IDxDiagContainer\n");
895 return;
898 hr = IDxDiagContainer_GetChildContainer(pddc, L"DxDiag_DisplayDevices", &display_cont);
899 ok(hr == S_OK, "Expected IDxDiagContainer::GetChildContainer to return S_OK, got 0x%08lx\n", hr);
901 if (hr != S_OK)
902 goto cleanup;
904 hr = IDxDiagContainer_GetNumberOfProps(display_cont, &count);
905 ok(hr == S_OK, "Expected IDxDiagContainer::GetNumberOfProps to return S_OK, got 0x%08lx\n", hr);
906 if (hr == S_OK)
907 ok(count == 0, "Expected count to be 0, got %lu\n", count);
909 hr = IDxDiagContainer_GetNumberOfChildContainers(display_cont, &count);
910 ok(hr == S_OK, "Expected IDxDiagContainer::GetNumberOfChildContainers to return S_OK, got 0x%08lx\n", hr);
912 if (hr != S_OK)
913 goto cleanup;
915 for (i = 0; i < count; i++)
917 WCHAR child_container[256];
918 IDxDiagContainer *child;
920 hr = IDxDiagContainer_EnumChildContainerNames(display_cont, i, child_container, ARRAY_SIZE(child_container));
921 ok(hr == S_OK, "Expected IDxDiagContainer::EnumChildContainerNames to return S_OK, got 0x%08lx\n", hr);
923 hr = IDxDiagContainer_GetChildContainer(display_cont, child_container, &child);
924 ok(hr == S_OK, "Expected IDxDiagContainer::GetChildContainer to return S_OK, got 0x%08lx\n", hr);
926 if (hr == S_OK)
928 trace("Testing container %s\n", wine_dbgstr_w(child_container));
929 test_container_properties(child, property_tests, ARRAY_SIZE(property_tests));
931 IDxDiagContainer_Release(child);
934 cleanup:
935 if (display_cont) IDxDiagContainer_Release(display_cont);
936 IDxDiagContainer_Release(pddc);
937 IDxDiagProvider_Release(pddp);
940 static void test_DxDiag_SoundDevices(void)
942 static const struct property_test property_tests[] =
944 {L"szDescription", VT_BSTR},
945 {L"szGuidDeviceID", VT_BSTR},
946 {L"szDriverName", VT_BSTR},
947 {L"szDriverPath", VT_BSTR},
950 IDxDiagContainer *sound_cont = NULL;
951 DWORD count, i;
952 HRESULT hr;
954 if (!create_root_IDxDiagContainer())
956 skip("Unable to create the root IDxDiagContainer\n");
957 return;
960 hr = IDxDiagContainer_GetChildContainer(pddc, L"DxDiag_DirectSound.DxDiag_SoundDevices", &sound_cont);
961 ok(hr == S_OK, "Expected IDxDiagContainer::GetChildContainer to return S_OK, got 0x%08lx\n", hr);
963 hr = IDxDiagContainer_GetNumberOfProps(sound_cont, &count);
964 ok(hr == S_OK, "Expected IDxDiagContainer::GetNumberOfProps to return S_OK, got 0x%08lx\n", hr);
965 ok(count == 0, "Expected count to be 0, got %lu\n", count);
967 hr = IDxDiagContainer_GetNumberOfChildContainers(sound_cont, &count);
968 ok(hr == S_OK, "Expected IDxDiagContainer::GetNumberOfChildContainers to return S_OK, got 0x%08lx\n", hr);
970 for (i = 0; i < count; i++)
972 IDxDiagContainer *child, *child2;
973 WCHAR child_container[256];
975 hr = IDxDiagContainer_EnumChildContainerNames(sound_cont, i, child_container, ARRAY_SIZE(child_container));
976 ok(hr == S_OK, "Expected IDxDiagContainer::EnumChildContainerNames to return S_OK, got 0x%08lx\n", hr);
978 hr = IDxDiagContainer_GetChildContainer(sound_cont, child_container, &child);
979 ok(hr == S_OK, "Expected IDxDiagContainer::GetChildContainer to return S_OK, got 0x%08lx\n", hr);
981 trace("Testing container %s\n", wine_dbgstr_w(child_container));
982 test_container_properties(child, property_tests, ARRAY_SIZE(property_tests));
984 child2 = NULL;
985 hr = IDxDiagContainer_GetChildContainer(child, L"", &child2);
986 ok(hr == S_OK, "Expected IDxDiagContainer::GetChildContainer to return S_OK, got 0x%08lx\n", hr);
987 ok(child2 != NULL, "Expected child2 != NULL\n");
988 ok(child2 != child, "Expected child != child2\n");
990 IDxDiagContainer_Release(child2);
991 IDxDiagContainer_Release(child);
994 IDxDiagContainer_Release(sound_cont);
995 IDxDiagContainer_Release(pddc);
996 IDxDiagProvider_Release(pddp);
999 static void test_DxDiag_SoundCaptureDevices(void)
1001 static const struct property_test property_tests[] =
1003 {L"szDescription", VT_BSTR},
1004 {L"szGuidDeviceID", VT_BSTR},
1005 {L"szDriverName", VT_BSTR},
1006 {L"szDriverPath", VT_BSTR},
1009 IDxDiagContainer *sound_cont = NULL;
1010 DWORD count, i;
1011 HRESULT hr;
1013 if (!create_root_IDxDiagContainer())
1015 skip("Unable to create the root IDxDiagContainer\n");
1016 return;
1019 hr = IDxDiagContainer_GetChildContainer(pddc, L"DxDiag_DirectSound.DxDiag_SoundCaptureDevices", &sound_cont);
1020 ok(hr == S_OK, "Expected IDxDiagContainer::GetChildContainer to return S_OK, got 0x%08lx\n", hr);
1022 hr = IDxDiagContainer_GetNumberOfProps(sound_cont, &count);
1023 ok(hr == S_OK, "Expected IDxDiagContainer::GetNumberOfProps to return S_OK, got 0x%08lx\n", hr);
1024 ok(count == 0, "Expected count to be 0, got %lu\n", count);
1026 hr = IDxDiagContainer_GetNumberOfChildContainers(sound_cont, &count);
1027 ok(hr == S_OK, "Expected IDxDiagContainer::GetNumberOfChildContainers to return S_OK, got 0x%08lx\n", hr);
1029 for (i = 0; i < count; i++)
1031 WCHAR child_container[256];
1032 IDxDiagContainer *child;
1034 hr = IDxDiagContainer_EnumChildContainerNames(sound_cont, i, child_container, ARRAY_SIZE(child_container));
1035 ok(hr == S_OK, "Expected IDxDiagContainer::EnumChildContainerNames to return S_OK, got 0x%08lx\n", hr);
1037 hr = IDxDiagContainer_GetChildContainer(sound_cont, child_container, &child);
1038 ok(hr == S_OK, "Expected IDxDiagContainer::GetChildContainer to return S_OK, got 0x%08lx\n", hr);
1040 trace("Testing container %s\n", wine_dbgstr_w(child_container));
1041 test_container_properties(child, property_tests, ARRAY_SIZE(property_tests));
1043 IDxDiagContainer_Release(child);
1046 IDxDiagContainer_Release(sound_cont);
1047 IDxDiagContainer_Release(pddc);
1048 IDxDiagProvider_Release(pddp);
1051 START_TEST(container)
1053 CoInitialize(NULL);
1054 test_GetNumberOfChildContainers();
1055 test_GetNumberOfProps();
1056 test_EnumChildContainerNames();
1057 test_GetChildContainer();
1058 test_dot_parsing();
1059 test_EnumPropNames();
1060 test_GetProp();
1062 test_root_children();
1063 test_DxDiag_SystemInfo();
1064 test_DxDiag_DisplayDevices();
1065 test_DxDiag_SoundDevices();
1066 test_DxDiag_SoundCaptureDevices();
1067 CoUninitialize();