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, ¶ms); 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 static const WCHAR iAdapter[] = {'i','A','d','a','p','t','e','r',0}; 963 964 static const struct property_test property_tests[] = 965 { 966 {szDescription, VT_BSTR}, 967 {szDeviceName, VT_BSTR}, 968 {szKeyDeviceID, VT_BSTR}, 969 {szKeyDeviceKey, VT_BSTR}, 970 {szVendorId, VT_BSTR}, 971 {szDeviceId, VT_BSTR}, 972 {szDeviceIdentifier, VT_BSTR}, 973 {dwWidth, VT_UI4}, 974 {dwHeight, VT_UI4}, 975 {dwBpp, VT_UI4}, 976 {szDisplayMemoryLocalized, VT_BSTR}, 977 {szDisplayMemoryEnglish, VT_BSTR}, 978 {szDriverName, VT_BSTR}, 979 {szDriverVersion, VT_BSTR}, 980 {szSubSysId, VT_BSTR}, 981 {szRevisionId, VT_BSTR}, 982 {dwRefreshRate, VT_UI4}, 983 {szManufacturer, VT_BSTR}, 984 {b3DAccelerationExists, VT_BOOL}, 985 {b3DAccelerationEnabled, VT_BOOL}, 986 {bDDAccelerationEnabled, VT_BOOL}, 987 {iAdapter, VT_UI4}, 988 }; 989 990 IDxDiagContainer *display_cont = NULL; 991 DWORD count, i; 992 HRESULT hr; 993 994 if (!create_root_IDxDiagContainer()) 995 { 996 skip("Unable to create the root IDxDiagContainer\n"); 997 return; 998 } 999 1000 hr = IDxDiagContainer_GetChildContainer(pddc, DxDiag_DisplayDevices, &display_cont); 1001 ok(hr == S_OK, "Expected IDxDiagContainer::GetChildContainer to return S_OK, got 0x%08x\n", hr); 1002 1003 if (hr != S_OK) 1004 goto cleanup; 1005 1006 hr = IDxDiagContainer_GetNumberOfProps(display_cont, &count); 1007 ok(hr == S_OK, "Expected IDxDiagContainer::GetNumberOfProps to return S_OK, got 0x%08x\n", hr); 1008 if (hr == S_OK) 1009 ok(count == 0, "Expected count to be 0, got %u\n", count); 1010 1011 hr = IDxDiagContainer_GetNumberOfChildContainers(display_cont, &count); 1012 ok(hr == S_OK, "Expected IDxDiagContainer::GetNumberOfChildContainers to return S_OK, got 0x%08x\n", hr); 1013 1014 if (hr != S_OK) 1015 goto cleanup; 1016 1017 for (i = 0; i < count; i++) 1018 { 1019 WCHAR child_container[256]; 1020 IDxDiagContainer *child; 1021 1022 hr = IDxDiagContainer_EnumChildContainerNames(display_cont, i, child_container, sizeof(child_container)/sizeof(WCHAR)); 1023 ok(hr == S_OK, "Expected IDxDiagContainer::EnumChildContainerNames to return S_OK, got 0x%08x\n", hr); 1024 1025 hr = IDxDiagContainer_GetChildContainer(display_cont, child_container, &child); 1026 ok(hr == S_OK, "Expected IDxDiagContainer::GetChildContainer to return S_OK, got 0x%08x\n", hr); 1027 1028 if (hr == S_OK) 1029 { 1030 trace("Testing container %s\n", wine_dbgstr_w(child_container)); 1031 test_container_properties(child, property_tests, sizeof(property_tests)/sizeof(property_tests[0])); 1032 } 1033 IDxDiagContainer_Release(child); 1034 } 1035 1036 cleanup: 1037 if (display_cont) IDxDiagContainer_Release(display_cont); 1038 IDxDiagContainer_Release(pddc); 1039 IDxDiagProvider_Release(pddp); 1040 } 1041 1042 static void test_DxDiag_SoundDevices(void) 1043 { 1044 static const WCHAR szDescription[] = {'s','z','D','e','s','c','r','i','p','t','i','o','n',0}; 1045 static const WCHAR szGuidDeviceID[] = {'s','z','G','u','i','d','D','e','v','i','c','e','I','D',0}; 1046 static const WCHAR szDriverPath[] = {'s','z','D','r','i','v','e','r','P','a','t','h',0}; 1047 static const WCHAR szDriverName[] = {'s','z','D','r','i','v','e','r','N','a','m','e',0}; 1048 static const WCHAR empty[] = {0}; 1049 1050 static const struct property_test property_tests[] = 1051 { 1052 {szDescription, VT_BSTR}, 1053 {szGuidDeviceID, VT_BSTR}, 1054 {szDriverName, VT_BSTR}, 1055 {szDriverPath, VT_BSTR}, 1056 }; 1057 1058 IDxDiagContainer *sound_cont = NULL; 1059 DWORD count, i; 1060 HRESULT hr; 1061 1062 if (!create_root_IDxDiagContainer()) 1063 { 1064 skip("Unable to create the root IDxDiagContainer\n"); 1065 return; 1066 } 1067 1068 hr = IDxDiagContainer_GetChildContainer(pddc, DxDiag_SoundDevices, &sound_cont); 1069 ok(hr == S_OK, "Expected IDxDiagContainer::GetChildContainer to return S_OK, got 0x%08x\n", hr); 1070 1071 if (hr != S_OK) 1072 goto cleanup; 1073 1074 hr = IDxDiagContainer_GetNumberOfProps(sound_cont, &count); 1075 ok(hr == S_OK, "Expected IDxDiagContainer::GetNumberOfProps to return S_OK, got 0x%08x\n", hr); 1076 if (hr == S_OK) 1077 ok(count == 0, "Expected count to be 0, got %u\n", count); 1078 1079 hr = IDxDiagContainer_GetNumberOfChildContainers(sound_cont, &count); 1080 ok(hr == S_OK, "Expected IDxDiagContainer::GetNumberOfChildContainers to return S_OK, got 0x%08x\n", hr); 1081 1082 if (hr != S_OK) 1083 goto cleanup; 1084 1085 for (i = 0; i < count; i++) 1086 { 1087 WCHAR child_container[256]; 1088 IDxDiagContainer *child, *child2; 1089 1090 hr = IDxDiagContainer_EnumChildContainerNames(sound_cont, i, child_container, sizeof(child_container)/sizeof(WCHAR)); 1091 ok(hr == S_OK, "Expected IDxDiagContainer::EnumChildContainerNames to return S_OK, got 0x%08x\n", hr); 1092 1093 hr = IDxDiagContainer_GetChildContainer(sound_cont, child_container, &child); 1094 ok(hr == S_OK, "Expected IDxDiagContainer::GetChildContainer to return S_OK, got 0x%08x\n", hr); 1095 1096 if (hr == S_OK) 1097 { 1098 trace("Testing container %s\n", wine_dbgstr_w(child_container)); 1099 test_container_properties(child, property_tests, sizeof(property_tests)/sizeof(property_tests[0])); 1100 } 1101 1102 child2 = NULL; 1103 hr = IDxDiagContainer_GetChildContainer(child, empty, &child2); 1104 ok(hr == S_OK, "Expected IDxDiagContainer::GetChildContainer to return S_OK, got 0x%08x\n", hr); 1105 ok(child2 != NULL, "Expected child2 != NULL\n"); 1106 ok(child2 != child, "Expected child != child2\n"); 1107 if (hr == S_OK) IDxDiagContainer_Release(child2); 1108 1109 IDxDiagContainer_Release(child); 1110 } 1111 1112 cleanup: 1113 if (sound_cont) IDxDiagContainer_Release(sound_cont); 1114 IDxDiagContainer_Release(pddc); 1115 IDxDiagProvider_Release(pddp); 1116 } 1117 1118 static void test_DxDiag_SoundCaptureDevices(void) 1119 { 1120 static const WCHAR szDescription[] = {'s','z','D','e','s','c','r','i','p','t','i','o','n',0}; 1121 static const WCHAR szGuidDeviceID[] = {'s','z','G','u','i','d','D','e','v','i','c','e','I','D',0}; 1122 static const WCHAR szDriverPath[] = {'s','z','D','r','i','v','e','r','P','a','t','h',0}; 1123 static const WCHAR szDriverName[] = {'s','z','D','r','i','v','e','r','N','a','m','e',0}; 1124 1125 static const struct property_test property_tests[] = 1126 { 1127 {szDescription, VT_BSTR}, 1128 {szGuidDeviceID, VT_BSTR}, 1129 {szDriverName, VT_BSTR}, 1130 {szDriverPath, VT_BSTR}, 1131 }; 1132 1133 IDxDiagContainer *sound_cont = NULL; 1134 DWORD count, i; 1135 HRESULT hr; 1136 1137 if (!create_root_IDxDiagContainer()) 1138 { 1139 skip("Unable to create the root IDxDiagContainer\n"); 1140 return; 1141 } 1142 1143 hr = IDxDiagContainer_GetChildContainer(pddc, DxDiag_SoundCaptureDevices, &sound_cont); 1144 ok(hr == S_OK, "Expected IDxDiagContainer::GetChildContainer to return S_OK, got 0x%08x\n", hr); 1145 1146 if (hr != S_OK) 1147 goto cleanup; 1148 1149 hr = IDxDiagContainer_GetNumberOfProps(sound_cont, &count); 1150 ok(hr == S_OK, "Expected IDxDiagContainer::GetNumberOfProps to return S_OK, got 0x%08x\n", hr); 1151 if (hr == S_OK) 1152 ok(count == 0, "Expected count to be 0, got %u\n", count); 1153 1154 hr = IDxDiagContainer_GetNumberOfChildContainers(sound_cont, &count); 1155 ok(hr == S_OK, "Expected IDxDiagContainer::GetNumberOfChildContainers to return S_OK, got 0x%08x\n", hr); 1156 1157 if (hr != S_OK) 1158 goto cleanup; 1159 1160 for (i = 0; i < count; i++) 1161 { 1162 WCHAR child_container[256]; 1163 IDxDiagContainer *child; 1164 1165 hr = IDxDiagContainer_EnumChildContainerNames(sound_cont, i, child_container, sizeof(child_container)/sizeof(WCHAR)); 1166 ok(hr == S_OK, "Expected IDxDiagContainer::EnumChildContainerNames to return S_OK, got 0x%08x\n", hr); 1167 1168 hr = IDxDiagContainer_GetChildContainer(sound_cont, child_container, &child); 1169 ok(hr == S_OK, "Expected IDxDiagContainer::GetChildContainer to return S_OK, got 0x%08x\n", hr); 1170 1171 if (hr == S_OK) 1172 { 1173 trace("Testing container %s\n", wine_dbgstr_w(child_container)); 1174 test_container_properties(child, property_tests, sizeof(property_tests)/sizeof(property_tests[0])); 1175 } 1176 IDxDiagContainer_Release(child); 1177 } 1178 1179 cleanup: 1180 if (sound_cont) IDxDiagContainer_Release(sound_cont); 1181 IDxDiagContainer_Release(pddc); 1182 IDxDiagProvider_Release(pddp); 1183 } 1184 1185 START_TEST(container) 1186 { 1187 CoInitialize(NULL); 1188 test_GetNumberOfChildContainers(); 1189 test_GetNumberOfProps(); 1190 test_EnumChildContainerNames(); 1191 test_GetChildContainer(); 1192 test_dot_parsing(); 1193 test_EnumPropNames(); 1194 test_GetProp(); 1195 1196 test_root_children(); 1197 test_DxDiag_SystemInfo(); 1198 test_DxDiag_DisplayDevices(); 1199 test_DxDiag_SoundDevices(); 1200 test_DxDiag_SoundCaptureDevices(); 1201 CoUninitialize(); 1202 } 1203