pop b0283e26815279d45d201d5585820bb1d1997663
[wine/hacks.git] / dlls / dxdiagn / tests / container.c
blobe5257091ccfb41f7057ec5ae871eda36c532ff37
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 "wine/test.h"
27 static IDxDiagProvider *pddp;
28 static IDxDiagContainer *pddc;
30 static BOOL create_root_IDxDiagContainer(void)
32 HRESULT hr;
33 DXDIAG_INIT_PARAMS params;
35 hr = CoCreateInstance(&CLSID_DxDiagProvider, NULL, CLSCTX_INPROC_SERVER,
36 &IID_IDxDiagProvider, (LPVOID*)&pddp);
37 if (SUCCEEDED(hr))
39 params.dwSize = sizeof(params);
40 params.dwDxDiagHeaderVersion = DXDIAG_DX9_SDK_VERSION;
41 params.bAllowWHQLChecks = FALSE;
42 params.pReserved = NULL;
43 hr = IDxDiagProvider_Initialize(pddp, &params);
44 if (SUCCEEDED(hr))
46 hr = IDxDiagProvider_GetRootContainer(pddp, &pddc);
47 if (SUCCEEDED(hr))
48 return TRUE;
50 IDxDiagProvider_Release(pddp);
52 return FALSE;
55 static void test_GetNumberOfChildContainers(void)
57 HRESULT hr;
58 DWORD count;
60 if (!create_root_IDxDiagContainer())
62 skip("Unable to create the root IDxDiagContainer\n");
63 return;
66 hr = IDxDiagContainer_GetNumberOfChildContainers(pddc, NULL);
67 ok(hr == E_INVALIDARG,
68 "Expected IDxDiagContainer::GetNumberOfChildContainers to return E_INVALIDARG, got 0x%08x\n", hr);
70 hr = IDxDiagContainer_GetNumberOfChildContainers(pddc, &count);
71 ok(hr == S_OK,
72 "Expected IDxDiagContainer::GetNumberOfChildContainers to return S_OK, got 0x%08x\n", hr);
73 if (hr == S_OK)
74 ok(count != 0, "Expected the number of child containers for the root container to be non-zero\n");
76 IDxDiagContainer_Release(pddc);
77 IDxDiagProvider_Release(pddp);
80 static void test_GetNumberOfProps(void)
82 HRESULT hr;
83 DWORD count;
85 if (!create_root_IDxDiagContainer())
87 skip("Unable to create the root IDxDiagContainer\n");
88 return;
91 hr = IDxDiagContainer_GetNumberOfProps(pddc, NULL);
92 ok(hr == E_INVALIDARG, "Expected IDxDiagContainer::GetNumberOfProps to return E_INVALIDARG, got 0x%08x\n", hr);
94 hr = IDxDiagContainer_GetNumberOfProps(pddc, &count);
95 ok(hr == S_OK, "Expected IDxDiagContainer::GetNumberOfProps to return S_OK, got 0x%08x\n", hr);
96 if (hr == S_OK)
97 ok(count == 0, "Expected the number of properties for the root container to be zero\n");
99 IDxDiagContainer_Release(pddc);
100 IDxDiagProvider_Release(pddp);
103 static void test_EnumChildContainerNames(void)
105 HRESULT hr;
106 WCHAR container[256];
107 DWORD maxcount, index;
108 static const WCHAR testW[] = {'t','e','s','t',0};
109 static const WCHAR zerotestW[] = {0,'e','s','t',0};
111 if (!create_root_IDxDiagContainer())
113 skip("Unable to create the root IDxDiagContainer\n");
114 return;
117 /* Test various combinations of invalid parameters. */
118 hr = IDxDiagContainer_EnumChildContainerNames(pddc, 0, NULL, 0);
119 ok(hr == E_INVALIDARG,
120 "Expected IDxDiagContainer::EnumChildContainerNames to return E_INVALIDARG, got 0x%08x\n", hr);
122 hr = IDxDiagContainer_EnumChildContainerNames(pddc, 0, NULL, sizeof(container)/sizeof(WCHAR));
123 ok(hr == E_INVALIDARG,
124 "Expected IDxDiagContainer::EnumChildContainerNames to return E_INVALIDARG, got 0x%08x\n", hr);
126 /* Test the conditions in which the output buffer can be modified. */
127 memcpy(container, testW, sizeof(testW));
128 hr = IDxDiagContainer_EnumChildContainerNames(pddc, 0, container, 0);
129 ok(hr == E_INVALIDARG,
130 "Expected IDxDiagContainer::EnumChildContainerNames to return E_INVALIDARG, got 0x%08x\n", hr);
131 ok(!memcmp(container, testW, sizeof(testW)),
132 "Expected the container buffer to be untouched, got %s\n", wine_dbgstr_w(container));
134 memcpy(container, testW, sizeof(testW));
135 hr = IDxDiagContainer_EnumChildContainerNames(pddc, ~0, container, 0);
136 ok(hr == E_INVALIDARG,
137 "Expected IDxDiagContainer::EnumChildContainerNames to return E_INVALIDARG, got 0x%08x\n", hr);
138 ok(!memcmp(container, testW, sizeof(testW)),
139 "Expected the container buffer to be untouched, got %s\n", wine_dbgstr_w(container));
141 memcpy(container, testW, sizeof(testW));
142 hr = IDxDiagContainer_EnumChildContainerNames(pddc, ~0, container, sizeof(container)/sizeof(WCHAR));
143 ok(hr == E_INVALIDARG,
144 "Expected IDxDiagContainer::EnumChildContainerNames to return E_INVALIDARG, got 0x%08x\n", hr);
145 ok(!memcmp(container, zerotestW, sizeof(zerotestW)),
146 "Expected the container buffer string to be empty, got %s\n", wine_dbgstr_w(container));
148 hr = IDxDiagContainer_GetNumberOfChildContainers(pddc, &maxcount);
149 ok(hr == S_OK, "Expected IDxDiagContainer::GetNumberOfChildContainers to return S_OK, got 0x%08x\n", hr);
150 if (FAILED(hr))
152 skip("IDxDiagContainer::GetNumberOfChildContainers failed\n");
153 goto cleanup;
156 trace("Starting child container enumeration of the root container:\n");
158 /* We should be able to enumerate as many child containers as the value
159 * that IDxDiagContainer::GetNumberOfChildContainers returns. */
160 for (index = 0; index <= maxcount; index++)
162 /* A buffer size of 1 is unlikely to be valid, as only a null terminator
163 * could be stored, and it is unlikely that a container name could be empty. */
164 DWORD buffersize = 1;
165 memcpy(container, testW, sizeof(testW));
166 hr = IDxDiagContainer_EnumChildContainerNames(pddc, index, container, buffersize);
167 if (hr == E_INVALIDARG)
169 /* We should get here when index is one more than the maximum index value. */
170 ok(maxcount == index,
171 "Expected IDxDiagContainer::EnumChildContainerNames to return E_INVALIDARG "
172 "on the last index %d, got 0x%08x\n", index, hr);
173 ok(container[0] == '\0',
174 "Expected the container buffer string to be empty, got %s\n", wine_dbgstr_w(container));
175 break;
177 else if (hr == DXDIAG_E_INSUFFICIENT_BUFFER)
179 WCHAR temp[256];
181 ok(container[0] == '\0',
182 "Expected the container buffer string to be empty, got %s\n", wine_dbgstr_w(container));
184 /* Get the container name to compare against. */
185 hr = IDxDiagContainer_EnumChildContainerNames(pddc, index, temp, sizeof(temp)/sizeof(WCHAR));
186 ok(hr == S_OK,
187 "Expected IDxDiagContainer::EnumChildContainerNames to return S_OK, got 0x%08x\n", hr);
189 /* Show that the DirectX SDK's stipulation that the buffer be at
190 * least 256 characters long is a mere suggestion, and smaller sizes
191 * can be acceptable also. IDxDiagContainer::EnumChildContainerNames
192 * doesn't provide a way of getting the exact size required, so the
193 * buffersize value will be iterated to at most 256 characters. */
194 for (buffersize = 2; buffersize <= 256; buffersize++)
196 memcpy(container, testW, sizeof(testW));
197 hr = IDxDiagContainer_EnumChildContainerNames(pddc, index, container, buffersize);
198 if (hr != DXDIAG_E_INSUFFICIENT_BUFFER)
199 break;
201 ok(!memcmp(temp, container, sizeof(WCHAR)*(buffersize - 1)),
202 "Expected truncated container name string, got %s\n", wine_dbgstr_w(container));
205 ok(hr == S_OK,
206 "Expected IDxDiagContainer::EnumChildContainerNames to return S_OK, "
207 "got hr = 0x%08x, buffersize = %d\n", hr, buffersize);
208 if (hr == S_OK)
209 trace("pddc[%d] = %s, length = %d\n", index, wine_dbgstr_w(container), buffersize);
211 else
213 ok(0, "IDxDiagContainer::EnumChildContainerNames unexpectedly returned 0x%08x\n", hr);
214 break;
218 cleanup:
219 IDxDiagContainer_Release(pddc);
220 IDxDiagProvider_Release(pddp);
223 static void test_GetChildContainer(void)
225 HRESULT hr;
226 WCHAR container[256] = {0};
227 IDxDiagContainer *child;
229 if (!create_root_IDxDiagContainer())
231 skip("Unable to create the root IDxDiagContainer\n");
232 return;
235 /* Test various combinations of invalid parameters. */
236 hr = IDxDiagContainer_GetChildContainer(pddc, NULL, NULL);
237 ok(hr == E_INVALIDARG,
238 "Expected IDxDiagContainer::GetChildContainer to return E_INVALIDARG, got 0x%08x\n", hr);
240 child = (void*)0xdeadbeef;
241 hr = IDxDiagContainer_GetChildContainer(pddc, NULL, &child);
242 ok(hr == E_INVALIDARG,
243 "Expected IDxDiagContainer::GetChildContainer to return E_INVALIDARG, got 0x%08x\n", hr);
244 ok(child == (void*)0xdeadbeef, "Expected output pointer to be unchanged, got %p\n", child);
246 hr = IDxDiagContainer_GetChildContainer(pddc, container, NULL);
247 ok(hr == E_INVALIDARG,
248 "Expected IDxDiagContainer::GetChildContainer to return E_INVALIDARG, got 0x%08x\n", hr);
250 child = (void*)0xdeadbeef;
251 hr = IDxDiagContainer_GetChildContainer(pddc, container, &child);
252 ok(hr == E_INVALIDARG,
253 "Expected IDxDiagContainer::GetChildContainer to return E_INVALIDARG, got 0x%08x\n", hr);
254 ok(child == NULL, "Expected output pointer to be NULL, got %p\n", child);
256 /* Get the name of a suitable child container. */
257 hr = IDxDiagContainer_EnumChildContainerNames(pddc, 0, container, sizeof(container)/sizeof(WCHAR));
258 ok(hr == S_OK,
259 "Expected IDxDiagContainer::EnumChildContainerNames to return S_OK, got 0x%08x\n", hr);
260 if (FAILED(hr))
262 skip("IDxDiagContainer::EnumChildContainerNames failed\n");
263 goto cleanup;
266 child = (void*)0xdeadbeef;
267 hr = IDxDiagContainer_GetChildContainer(pddc, container, &child);
268 ok(hr == S_OK,
269 "Expected IDxDiagContainer::GetChildContainer to return S_OK, got 0x%08x\n", hr);
270 ok(child != NULL && child != (void*)0xdeadbeef, "Expected a valid output pointer, got %p\n", child);
272 if (SUCCEEDED(hr))
274 IDxDiagContainer *ptr;
276 /* Show that IDxDiagContainer::GetChildContainer returns a different pointer
277 * for multiple calls for the same container name. */
278 hr = IDxDiagContainer_GetChildContainer(pddc, container, &ptr);
279 ok(hr == S_OK,
280 "Expected IDxDiagContainer::GetChildContainer to return S_OK, got 0x%08x\n", hr);
281 if (SUCCEEDED(hr))
282 todo_wine ok(ptr != child, "Expected the two pointers (%p vs. %p) to be unequal", child, ptr);
284 IDxDiagContainer_Release(ptr);
285 IDxDiagContainer_Release(child);
288 cleanup:
289 IDxDiagContainer_Release(pddc);
290 IDxDiagProvider_Release(pddp);
293 static void test_dot_parsing(void)
295 HRESULT hr;
296 WCHAR containerbufW[256] = {0}, childbufW[256] = {0};
297 DWORD count, index;
298 size_t i;
299 static const struct
301 const char *format;
302 const HRESULT expect;
303 } test_strings[] = {
304 { "%s.%s", S_OK },
305 { "%s.%s.", S_OK },
306 { ".%s.%s", E_INVALIDARG },
307 { "%s.%s..", E_INVALIDARG },
308 { ".%s.%s.", E_INVALIDARG },
309 { "..%s.%s", E_INVALIDARG },
312 if (!create_root_IDxDiagContainer())
314 skip("Unable to create the root IDxDiagContainer\n");
315 return;
318 /* Find a container with a child container of its own. */
319 hr = IDxDiagContainer_GetNumberOfChildContainers(pddc, &count);
320 ok(hr == S_OK, "Expected IDxDiagContainer::GetNumberOfChildContainers to return S_OK, got 0x%08x\n", hr);
321 if (FAILED(hr))
323 skip("IDxDiagContainer::GetNumberOfChildContainers failed\n");
324 goto cleanup;
327 for (index = 0; index < count; index++)
329 IDxDiagContainer *child;
331 hr = IDxDiagContainer_EnumChildContainerNames(pddc, index, containerbufW, sizeof(containerbufW)/sizeof(WCHAR));
332 ok(hr == S_OK, "Expected IDxDiagContainer_EnumChildContainerNames to return S_OK, got 0x%08x\n", hr);
333 if (FAILED(hr))
335 skip("IDxDiagContainer::EnumChildContainerNames failed\n");
336 goto cleanup;
339 hr = IDxDiagContainer_GetChildContainer(pddc, containerbufW, &child);
340 ok(hr == S_OK, "Expected IDxDiagContainer::GetChildContainer to return S_OK, got 0x%08x\n", hr);
342 if (SUCCEEDED(hr))
344 hr = IDxDiagContainer_EnumChildContainerNames(child, 0, childbufW, sizeof(childbufW)/sizeof(WCHAR));
345 ok(hr == S_OK || hr == E_INVALIDARG,
346 "Expected IDxDiagContainer::EnumChildContainerNames to return S_OK or E_INVALIDARG, got 0x%08x\n", hr);
347 IDxDiagContainer_Release(child);
349 if (SUCCEEDED(hr))
350 break;
354 if (!*containerbufW || !*childbufW)
356 skip("Unable to find a suitable container\n");
357 goto cleanup;
360 trace("Testing IDxDiagContainer::GetChildContainer dot parsing with container %s and child container %s.\n",
361 wine_dbgstr_w(containerbufW), wine_dbgstr_w(childbufW));
363 for (i = 0; i < sizeof(test_strings)/sizeof(test_strings[0]); i++)
365 IDxDiagContainer *child;
366 char containerbufA[256];
367 char childbufA[256];
368 char dotbufferA[255 + 255 + 3 + 1];
369 WCHAR dotbufferW[255 + 255 + 3 + 1]; /* containerbuf + childbuf + dots + null terminator */
371 WideCharToMultiByte(CP_ACP, 0, containerbufW, -1, containerbufA, sizeof(containerbufA), NULL, NULL);
372 WideCharToMultiByte(CP_ACP, 0, childbufW, -1, childbufA, sizeof(childbufA), NULL, NULL);
373 sprintf(dotbufferA, test_strings[i].format, containerbufA, childbufA);
374 MultiByteToWideChar(CP_ACP, 0, dotbufferA, -1, dotbufferW, sizeof(dotbufferW)/sizeof(WCHAR));
376 trace("Trying container name %s\n", wine_dbgstr_w(dotbufferW));
377 hr = IDxDiagContainer_GetChildContainer(pddc, dotbufferW, &child);
378 ok(hr == test_strings[i].expect,
379 "Expected IDxDiagContainer::GetChildContainer to return 0x%08x for %s, got 0x%08x\n",
380 test_strings[i].expect, wine_dbgstr_w(dotbufferW), hr);
381 if (SUCCEEDED(hr))
382 IDxDiagContainer_Release(child);
385 cleanup:
386 IDxDiagContainer_Release(pddc);
387 IDxDiagProvider_Release(pddp);
390 static void test_EnumPropNames(void)
392 HRESULT hr;
393 WCHAR container[256], property[256];
394 IDxDiagContainer *child = NULL;
395 DWORD count, index, propcount;
396 static const WCHAR testW[] = {'t','e','s','t',0};
398 if (!create_root_IDxDiagContainer())
400 skip("Unable to create the root IDxDiagContainer\n");
401 return;
404 /* Find a container with a non-zero number of properties. */
405 hr = IDxDiagContainer_GetNumberOfChildContainers(pddc, &count);
406 ok(hr == S_OK, "Expected IDxDiagContainer::GetNumberOfChildContainers to return S_OK, got 0x%08x\n", hr);
407 if (FAILED(hr))
409 skip("IDxDiagContainer::GetNumberOfChildContainers failed\n");
410 goto cleanup;
413 for (index = 0; index < count; index++)
415 hr = IDxDiagContainer_EnumChildContainerNames(pddc, index, container, sizeof(container)/sizeof(WCHAR));
416 ok(hr == S_OK, "Expected IDxDiagContainer_EnumChildContainerNames to return S_OK, got 0x%08x\n", hr);
417 if (FAILED(hr))
419 skip("IDxDiagContainer::EnumChildContainerNames failed\n");
420 goto cleanup;
423 hr = IDxDiagContainer_GetChildContainer(pddc, container, &child);
424 ok(hr == S_OK, "Expected IDxDiagContainer::GetChildContainer to return S_OK, got 0x%08x\n", hr);
426 if (SUCCEEDED(hr))
428 hr = IDxDiagContainer_GetNumberOfProps(child, &propcount);
429 ok(hr == S_OK, "Expected IDxDiagContainer::GetNumberOfProps to return S_OK, got 0x%08x\n", hr);
431 if (!propcount)
433 IDxDiagContainer_Release(child);
434 child = NULL;
436 else
437 break;
441 if (!child)
443 skip("Unable to find a container with non-zero property count\n");
444 goto cleanup;
447 hr = IDxDiagContainer_EnumPropNames(child, ~0, NULL, 0);
448 ok(hr == E_INVALIDARG, "Expected IDxDiagContainer::EnumPropNames to return E_INVALIDARG, got 0x%08x\n", hr);
450 memcpy(property, testW, sizeof(testW));
451 hr = IDxDiagContainer_EnumPropNames(child, ~0, property, 0);
452 ok(hr == E_INVALIDARG, "Expected IDxDiagContainer::EnumPropNames to return E_INVALIDARG, got 0x%08x\n", hr);
453 ok(!memcmp(property, testW, sizeof(testW)),
454 "Expected the property buffer to be unchanged, got %s\n", wine_dbgstr_w(property));
456 memcpy(property, testW, sizeof(testW));
457 hr = IDxDiagContainer_EnumPropNames(child, ~0, property, sizeof(property)/sizeof(WCHAR));
458 ok(hr == E_INVALIDARG, "Expected IDxDiagContainer::EnumPropNames to return E_INVALIDARG, got 0x%08x\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 trace("Starting property enumeration of the %s container:\n", wine_dbgstr_w(container));
464 /* We should be able to enumerate as many properties as the value that
465 * IDxDiagContainer::GetNumberOfProps returns. */
466 for (index = 0; index <= propcount; index++)
468 /* A buffer size of 1 is unlikely to be valid, as only a null terminator
469 * could be stored, and it is unlikely that a property name could be empty. */
470 DWORD buffersize = 1;
472 memcpy(property, testW, sizeof(testW));
473 hr = IDxDiagContainer_EnumPropNames(child, index, property, buffersize);
474 if (hr == E_INVALIDARG)
476 /* We should get here when index is one more than the maximum index value. */
477 ok(propcount == index,
478 "Expected IDxDiagContainer::EnumPropNames to return E_INVALIDARG "
479 "on the last index %d, got 0x%08x\n", index, hr);
480 ok(!memcmp(property, testW, sizeof(testW)),
481 "Expected the property buffer to be unchanged, got %s\n", wine_dbgstr_w(property));
482 break;
484 else if (hr == DXDIAG_E_INSUFFICIENT_BUFFER)
486 WCHAR temp[256];
488 ok(property[0] == '\0',
489 "Expected the property buffer string to be empty, got %s\n", wine_dbgstr_w(property));
490 hr = IDxDiagContainer_EnumPropNames(child, index, temp, sizeof(temp)/sizeof(WCHAR));
491 ok(hr == S_OK,
492 "Expected IDxDiagContainer::EnumPropNames to return S_OK, got 0x%08x\n", hr);
494 /* Show that the DirectX SDK's stipulation that the buffer be at
495 * least 256 characters long is a mere suggestion, and smaller sizes
496 * can be acceptable also. IDxDiagContainer::EnumPropNames doesn't
497 * provide a way of getting the exact size required, so the buffersize
498 * value will be iterated to at most 256 characters. */
499 for (buffersize = 2; buffersize <= 256; buffersize++)
501 memcpy(property, testW, sizeof(testW));
502 hr = IDxDiagContainer_EnumPropNames(child, index, property, buffersize);
503 if (hr != DXDIAG_E_INSUFFICIENT_BUFFER)
504 break;
506 ok(!memcmp(temp, property, sizeof(WCHAR)*(buffersize - 1)),
507 "Expected truncated property name string, got %s\n", wine_dbgstr_w(property));
510 ok(hr == S_OK,
511 "Expected IDxDiagContainer::EnumPropNames to return S_OK, "
512 "got hr = 0x%08x, buffersize = %d\n", hr, buffersize);
513 if (hr == S_OK)
514 trace("child[%d] = %s, length = %d\n", index, wine_dbgstr_w(property), buffersize);
516 else
518 ok(0, "IDxDiagContainer::EnumPropNames unexpectedly returned 0x%08x\n", hr);
519 break;
523 IDxDiagContainer_Release(child);
525 cleanup:
526 IDxDiagContainer_Release(pddc);
527 IDxDiagProvider_Release(pddp);
530 START_TEST(container)
532 CoInitialize(NULL);
533 test_GetNumberOfChildContainers();
534 test_GetNumberOfProps();
535 test_EnumChildContainerNames();
536 test_GetChildContainer();
537 test_dot_parsing();
538 test_EnumPropNames();
539 CoUninitialize();