| /* |
| * Unit tests for IDxDiagContainer |
| * |
| * Copyright 2010 Andrew Nguyen |
| * |
| * This library is free software; you can redistribute it and/or |
| * modify it under the terms of the GNU Lesser General Public |
| * License as published by the Free Software Foundation; either |
| * version 2.1 of the License, or (at your option) any later version. |
| * |
| * This library is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| * Lesser General Public License for more details. |
| * |
| * You should have received a copy of the GNU Lesser General Public |
| * License along with this library; if not, write to the Free Software |
| * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA |
| */ |
| |
| #define COBJMACROS |
| |
| #include <stdio.h> |
| #include "dxdiag.h" |
| #include "oleauto.h" |
| #include "wine/test.h" |
| |
| static IDxDiagProvider *pddp; |
| static IDxDiagContainer *pddc; |
| |
| static BOOL create_root_IDxDiagContainer(void) |
| { |
| HRESULT hr; |
| DXDIAG_INIT_PARAMS params; |
| |
| hr = CoCreateInstance(&CLSID_DxDiagProvider, NULL, CLSCTX_INPROC_SERVER, |
| &IID_IDxDiagProvider, (LPVOID*)&pddp); |
| if (SUCCEEDED(hr)) |
| { |
| params.dwSize = sizeof(params); |
| params.dwDxDiagHeaderVersion = DXDIAG_DX9_SDK_VERSION; |
| params.bAllowWHQLChecks = FALSE; |
| params.pReserved = NULL; |
| hr = IDxDiagProvider_Initialize(pddp, ¶ms); |
| if (SUCCEEDED(hr)) |
| { |
| hr = IDxDiagProvider_GetRootContainer(pddp, &pddc); |
| if (SUCCEEDED(hr)) |
| return TRUE; |
| } |
| IDxDiagProvider_Release(pddp); |
| } |
| return FALSE; |
| } |
| |
| static void test_GetNumberOfChildContainers(void) |
| { |
| HRESULT hr; |
| DWORD count; |
| |
| if (!create_root_IDxDiagContainer()) |
| { |
| skip("Unable to create the root IDxDiagContainer\n"); |
| return; |
| } |
| |
| hr = IDxDiagContainer_GetNumberOfChildContainers(pddc, NULL); |
| ok(hr == E_INVALIDARG, |
| "Expected IDxDiagContainer::GetNumberOfChildContainers to return E_INVALIDARG, got 0x%08x\n", hr); |
| |
| hr = IDxDiagContainer_GetNumberOfChildContainers(pddc, &count); |
| ok(hr == S_OK, |
| "Expected IDxDiagContainer::GetNumberOfChildContainers to return S_OK, got 0x%08x\n", hr); |
| if (hr == S_OK) |
| ok(count != 0, "Expected the number of child containers for the root container to be non-zero\n"); |
| |
| IDxDiagContainer_Release(pddc); |
| IDxDiagProvider_Release(pddp); |
| } |
| |
| static void test_GetNumberOfProps(void) |
| { |
| HRESULT hr; |
| DWORD count; |
| |
| if (!create_root_IDxDiagContainer()) |
| { |
| skip("Unable to create the root IDxDiagContainer\n"); |
| return; |
| } |
| |
| hr = IDxDiagContainer_GetNumberOfProps(pddc, NULL); |
| ok(hr == E_INVALIDARG, "Expected IDxDiagContainer::GetNumberOfProps to return E_INVALIDARG, got 0x%08x\n", hr); |
| |
| hr = IDxDiagContainer_GetNumberOfProps(pddc, &count); |
| ok(hr == S_OK, "Expected IDxDiagContainer::GetNumberOfProps to return S_OK, got 0x%08x\n", hr); |
| if (hr == S_OK) |
| ok(count == 0, "Expected the number of properties for the root container to be zero\n"); |
| |
| IDxDiagContainer_Release(pddc); |
| IDxDiagProvider_Release(pddp); |
| } |
| |
| static void test_EnumChildContainerNames(void) |
| { |
| HRESULT hr; |
| WCHAR container[256]; |
| DWORD maxcount, index; |
| static const WCHAR testW[] = {'t','e','s','t',0}; |
| static const WCHAR zerotestW[] = {0,'e','s','t',0}; |
| |
| if (!create_root_IDxDiagContainer()) |
| { |
| skip("Unable to create the root IDxDiagContainer\n"); |
| return; |
| } |
| |
| /* Test various combinations of invalid parameters. */ |
| hr = IDxDiagContainer_EnumChildContainerNames(pddc, 0, NULL, 0); |
| ok(hr == E_INVALIDARG, |
| "Expected IDxDiagContainer::EnumChildContainerNames to return E_INVALIDARG, got 0x%08x\n", hr); |
| |
| hr = IDxDiagContainer_EnumChildContainerNames(pddc, 0, NULL, sizeof(container)/sizeof(WCHAR)); |
| ok(hr == E_INVALIDARG, |
| "Expected IDxDiagContainer::EnumChildContainerNames to return E_INVALIDARG, got 0x%08x\n", hr); |
| |
| /* Test the conditions in which the output buffer can be modified. */ |
| memcpy(container, testW, sizeof(testW)); |
| hr = IDxDiagContainer_EnumChildContainerNames(pddc, 0, container, 0); |
| ok(hr == E_INVALIDARG, |
| "Expected IDxDiagContainer::EnumChildContainerNames to return E_INVALIDARG, got 0x%08x\n", hr); |
| ok(!memcmp(container, testW, sizeof(testW)), |
| "Expected the container buffer to be untouched, got %s\n", wine_dbgstr_w(container)); |
| |
| memcpy(container, testW, sizeof(testW)); |
| hr = IDxDiagContainer_EnumChildContainerNames(pddc, ~0, container, 0); |
| ok(hr == E_INVALIDARG, |
| "Expected IDxDiagContainer::EnumChildContainerNames to return E_INVALIDARG, got 0x%08x\n", hr); |
| ok(!memcmp(container, testW, sizeof(testW)), |
| "Expected the container buffer to be untouched, got %s\n", wine_dbgstr_w(container)); |
| |
| memcpy(container, testW, sizeof(testW)); |
| hr = IDxDiagContainer_EnumChildContainerNames(pddc, ~0, container, sizeof(container)/sizeof(WCHAR)); |
| ok(hr == E_INVALIDARG, |
| "Expected IDxDiagContainer::EnumChildContainerNames to return E_INVALIDARG, got 0x%08x\n", hr); |
| ok(!memcmp(container, zerotestW, sizeof(zerotestW)), |
| "Expected the container buffer string to be empty, got %s\n", wine_dbgstr_w(container)); |
| |
| hr = IDxDiagContainer_GetNumberOfChildContainers(pddc, &maxcount); |
| ok(hr == S_OK, "Expected IDxDiagContainer::GetNumberOfChildContainers to return S_OK, got 0x%08x\n", hr); |
| if (FAILED(hr)) |
| { |
| skip("IDxDiagContainer::GetNumberOfChildContainers failed\n"); |
| goto cleanup; |
| } |
| |
| trace("Starting child container enumeration of the root container:\n"); |
| |
| /* We should be able to enumerate as many child containers as the value |
| * that IDxDiagContainer::GetNumberOfChildContainers returns. */ |
| for (index = 0; index <= maxcount; index++) |
| { |
| /* A buffer size of 1 is unlikely to be valid, as only a null terminator |
| * could be stored, and it is unlikely that a container name could be empty. */ |
| DWORD buffersize = 1; |
| memcpy(container, testW, sizeof(testW)); |
| hr = IDxDiagContainer_EnumChildContainerNames(pddc, index, container, buffersize); |
| if (hr == E_INVALIDARG) |
| { |
| /* We should get here when index is one more than the maximum index value. */ |
| ok(maxcount == index, |
| "Expected IDxDiagContainer::EnumChildContainerNames to return E_INVALIDARG " |
| "on the last index %d, got 0x%08x\n", index, hr); |
| ok(container[0] == '\0', |
| "Expected the container buffer string to be empty, got %s\n", wine_dbgstr_w(container)); |
| break; |
| } |
| else if (hr == DXDIAG_E_INSUFFICIENT_BUFFER) |
| { |
| WCHAR temp[256]; |
| |
| ok(container[0] == '\0', |
| "Expected the container buffer string to be empty, got %s\n", wine_dbgstr_w(container)); |
| |
| /* Get the container name to compare against. */ |
| hr = IDxDiagContainer_EnumChildContainerNames(pddc, index, temp, sizeof(temp)/sizeof(WCHAR)); |
| ok(hr == S_OK, |
| "Expected IDxDiagContainer::EnumChildContainerNames to return S_OK, got 0x%08x\n", hr); |
| |
| /* Show that the DirectX SDK's stipulation that the buffer be at |
| * least 256 characters long is a mere suggestion, and smaller sizes |
| * can be acceptable also. IDxDiagContainer::EnumChildContainerNames |
| * doesn't provide a way of getting the exact size required, so the |
| * buffersize value will be iterated to at most 256 characters. */ |
| for (buffersize = 2; buffersize <= 256; buffersize++) |
| { |
| memcpy(container, testW, sizeof(testW)); |
| hr = IDxDiagContainer_EnumChildContainerNames(pddc, index, container, buffersize); |
| if (hr != DXDIAG_E_INSUFFICIENT_BUFFER) |
| break; |
| |
| ok(!memcmp(temp, container, sizeof(WCHAR)*(buffersize - 1)), |
| "Expected truncated container name string, got %s\n", wine_dbgstr_w(container)); |
| } |
| |
| ok(hr == S_OK, |
| "Expected IDxDiagContainer::EnumChildContainerNames to return S_OK, " |
| "got hr = 0x%08x, buffersize = %d\n", hr, buffersize); |
| if (hr == S_OK) |
| trace("pddc[%d] = %s, length = %d\n", index, wine_dbgstr_w(container), buffersize); |
| } |
| else |
| { |
| ok(0, "IDxDiagContainer::EnumChildContainerNames unexpectedly returned 0x%08x\n", hr); |
| break; |
| } |
| } |
| |
| cleanup: |
| IDxDiagContainer_Release(pddc); |
| IDxDiagProvider_Release(pddp); |
| } |
| |
| static void test_GetChildContainer(void) |
| { |
| HRESULT hr; |
| WCHAR container[256] = {0}; |
| IDxDiagContainer *child; |
| |
| if (!create_root_IDxDiagContainer()) |
| { |
| skip("Unable to create the root IDxDiagContainer\n"); |
| return; |
| } |
| |
| /* Test various combinations of invalid parameters. */ |
| hr = IDxDiagContainer_GetChildContainer(pddc, NULL, NULL); |
| ok(hr == E_INVALIDARG, |
| "Expected IDxDiagContainer::GetChildContainer to return E_INVALIDARG, got 0x%08x\n", hr); |
| |
| child = (void*)0xdeadbeef; |
| hr = IDxDiagContainer_GetChildContainer(pddc, NULL, &child); |
| ok(hr == E_INVALIDARG, |
| "Expected IDxDiagContainer::GetChildContainer to return E_INVALIDARG, got 0x%08x\n", hr); |
| ok(child == (void*)0xdeadbeef, "Expected output pointer to be unchanged, got %p\n", child); |
| |
| hr = IDxDiagContainer_GetChildContainer(pddc, container, NULL); |
| ok(hr == E_INVALIDARG, |
| "Expected IDxDiagContainer::GetChildContainer to return E_INVALIDARG, got 0x%08x\n", hr); |
| |
| child = (void*)0xdeadbeef; |
| hr = IDxDiagContainer_GetChildContainer(pddc, container, &child); |
| ok(hr == E_INVALIDARG, |
| "Expected IDxDiagContainer::GetChildContainer to return E_INVALIDARG, got 0x%08x\n", hr); |
| ok(child == NULL, "Expected output pointer to be NULL, got %p\n", child); |
| |
| /* Get the name of a suitable child container. */ |
| hr = IDxDiagContainer_EnumChildContainerNames(pddc, 0, container, sizeof(container)/sizeof(WCHAR)); |
| ok(hr == S_OK, |
| "Expected IDxDiagContainer::EnumChildContainerNames to return S_OK, got 0x%08x\n", hr); |
| if (FAILED(hr)) |
| { |
| skip("IDxDiagContainer::EnumChildContainerNames failed\n"); |
| goto cleanup; |
| } |
| |
| child = (void*)0xdeadbeef; |
| hr = IDxDiagContainer_GetChildContainer(pddc, container, &child); |
| ok(hr == S_OK, |
| "Expected IDxDiagContainer::GetChildContainer to return S_OK, got 0x%08x\n", hr); |
| ok(child != NULL && child != (void*)0xdeadbeef, "Expected a valid output pointer, got %p\n", child); |
| |
| if (SUCCEEDED(hr)) |
| { |
| IDxDiagContainer *ptr; |
| |
| /* Show that IDxDiagContainer::GetChildContainer returns a different pointer |
| * for multiple calls for the same container name. */ |
| hr = IDxDiagContainer_GetChildContainer(pddc, container, &ptr); |
| ok(hr == S_OK, |
| "Expected IDxDiagContainer::GetChildContainer to return S_OK, got 0x%08x\n", hr); |
| if (SUCCEEDED(hr)) |
| todo_wine ok(ptr != child, "Expected the two pointers (%p vs. %p) to be unequal\n", child, ptr); |
| |
| IDxDiagContainer_Release(ptr); |
| IDxDiagContainer_Release(child); |
| } |
| |
| cleanup: |
| IDxDiagContainer_Release(pddc); |
| IDxDiagProvider_Release(pddp); |
| } |
| |
| static void test_dot_parsing(void) |
| { |
| HRESULT hr; |
| WCHAR containerbufW[256] = {0}, childbufW[256] = {0}; |
| DWORD count, index; |
| size_t i; |
| static const struct |
| { |
| const char *format; |
| const HRESULT expect; |
| } test_strings[] = { |
| { "%s.%s", S_OK }, |
| { "%s.%s.", S_OK }, |
| { ".%s.%s", E_INVALIDARG }, |
| { "%s.%s..", E_INVALIDARG }, |
| { ".%s.%s.", E_INVALIDARG }, |
| { "..%s.%s", E_INVALIDARG }, |
| }; |
| |
| if (!create_root_IDxDiagContainer()) |
| { |
| skip("Unable to create the root IDxDiagContainer\n"); |
| return; |
| } |
| |
| /* Find a container with a child container of its own. */ |
| hr = IDxDiagContainer_GetNumberOfChildContainers(pddc, &count); |
| ok(hr == S_OK, "Expected IDxDiagContainer::GetNumberOfChildContainers to return S_OK, got 0x%08x\n", hr); |
| if (FAILED(hr)) |
| { |
| skip("IDxDiagContainer::GetNumberOfChildContainers failed\n"); |
| goto cleanup; |
| } |
| |
| for (index = 0; index < count; index++) |
| { |
| IDxDiagContainer *child; |
| |
| hr = IDxDiagContainer_EnumChildContainerNames(pddc, index, containerbufW, sizeof(containerbufW)/sizeof(WCHAR)); |
| ok(hr == S_OK, "Expected IDxDiagContainer_EnumChildContainerNames to return S_OK, got 0x%08x\n", hr); |
| if (FAILED(hr)) |
| { |
| skip("IDxDiagContainer::EnumChildContainerNames failed\n"); |
| goto cleanup; |
| } |
| |
| hr = IDxDiagContainer_GetChildContainer(pddc, containerbufW, &child); |
| ok(hr == S_OK, "Expected IDxDiagContainer::GetChildContainer to return S_OK, got 0x%08x\n", hr); |
| |
| if (SUCCEEDED(hr)) |
| { |
| hr = IDxDiagContainer_EnumChildContainerNames(child, 0, childbufW, sizeof(childbufW)/sizeof(WCHAR)); |
| ok(hr == S_OK || hr == E_INVALIDARG, |
| "Expected IDxDiagContainer::EnumChildContainerNames to return S_OK or E_INVALIDARG, got 0x%08x\n", hr); |
| IDxDiagContainer_Release(child); |
| |
| if (SUCCEEDED(hr)) |
| break; |
| } |
| } |
| |
| if (!*containerbufW || !*childbufW) |
| { |
| skip("Unable to find a suitable container\n"); |
| goto cleanup; |
| } |
| |
| trace("Testing IDxDiagContainer::GetChildContainer dot parsing with container %s and child container %s.\n", |
| wine_dbgstr_w(containerbufW), wine_dbgstr_w(childbufW)); |
| |
| for (i = 0; i < sizeof(test_strings)/sizeof(test_strings[0]); i++) |
| { |
| IDxDiagContainer *child; |
| char containerbufA[256]; |
| char childbufA[256]; |
| char dotbufferA[255 + 255 + 3 + 1]; |
| WCHAR dotbufferW[255 + 255 + 3 + 1]; /* containerbuf + childbuf + dots + null terminator */ |
| |
| WideCharToMultiByte(CP_ACP, 0, containerbufW, -1, containerbufA, sizeof(containerbufA), NULL, NULL); |
| WideCharToMultiByte(CP_ACP, 0, childbufW, -1, childbufA, sizeof(childbufA), NULL, NULL); |
| sprintf(dotbufferA, test_strings[i].format, containerbufA, childbufA); |
| MultiByteToWideChar(CP_ACP, 0, dotbufferA, -1, dotbufferW, sizeof(dotbufferW)/sizeof(WCHAR)); |
| |
| trace("Trying container name %s\n", wine_dbgstr_w(dotbufferW)); |
| hr = IDxDiagContainer_GetChildContainer(pddc, dotbufferW, &child); |
| ok(hr == test_strings[i].expect, |
| "Expected IDxDiagContainer::GetChildContainer to return 0x%08x for %s, got 0x%08x\n", |
| test_strings[i].expect, wine_dbgstr_w(dotbufferW), hr); |
| if (SUCCEEDED(hr)) |
| IDxDiagContainer_Release(child); |
| } |
| |
| cleanup: |
| IDxDiagContainer_Release(pddc); |
| IDxDiagProvider_Release(pddp); |
| } |
| |
| static void test_EnumPropNames(void) |
| { |
| HRESULT hr; |
| WCHAR container[256], property[256]; |
| IDxDiagContainer *child = NULL; |
| DWORD count, index, propcount; |
| static const WCHAR testW[] = {'t','e','s','t',0}; |
| |
| if (!create_root_IDxDiagContainer()) |
| { |
| skip("Unable to create the root IDxDiagContainer\n"); |
| return; |
| } |
| |
| /* Find a container with a non-zero number of properties. */ |
| hr = IDxDiagContainer_GetNumberOfChildContainers(pddc, &count); |
| ok(hr == S_OK, "Expected IDxDiagContainer::GetNumberOfChildContainers to return S_OK, got 0x%08x\n", hr); |
| if (FAILED(hr)) |
| { |
| skip("IDxDiagContainer::GetNumberOfChildContainers failed\n"); |
| goto cleanup; |
| } |
| |
| for (index = 0; index < count; index++) |
| { |
| hr = IDxDiagContainer_EnumChildContainerNames(pddc, index, container, sizeof(container)/sizeof(WCHAR)); |
| ok(hr == S_OK, "Expected IDxDiagContainer_EnumChildContainerNames to return S_OK, got 0x%08x\n", hr); |
| if (FAILED(hr)) |
| { |
| skip("IDxDiagContainer::EnumChildContainerNames failed\n"); |
| goto cleanup; |
| } |
| |
| hr = IDxDiagContainer_GetChildContainer(pddc, container, &child); |
| ok(hr == S_OK, "Expected IDxDiagContainer::GetChildContainer to return S_OK, got 0x%08x\n", hr); |
| |
| if (SUCCEEDED(hr)) |
| { |
| hr = IDxDiagContainer_GetNumberOfProps(child, &propcount); |
| ok(hr == S_OK, "Expected IDxDiagContainer::GetNumberOfProps to return S_OK, got 0x%08x\n", hr); |
| |
| if (!propcount) |
| { |
| IDxDiagContainer_Release(child); |
| child = NULL; |
| } |
| else |
| break; |
| } |
| } |
| |
| if (!child) |
| { |
| skip("Unable to find a container with non-zero property count\n"); |
| goto cleanup; |
| } |
| |
| hr = IDxDiagContainer_EnumPropNames(child, ~0, NULL, 0); |
| ok(hr == E_INVALIDARG, "Expected IDxDiagContainer::EnumPropNames to return E_INVALIDARG, got 0x%08x\n", hr); |
| |
| memcpy(property, testW, sizeof(testW)); |
| hr = IDxDiagContainer_EnumPropNames(child, ~0, property, 0); |
| ok(hr == E_INVALIDARG, "Expected IDxDiagContainer::EnumPropNames to return E_INVALIDARG, got 0x%08x\n", hr); |
| ok(!memcmp(property, testW, sizeof(testW)), |
| "Expected the property buffer to be unchanged, got %s\n", wine_dbgstr_w(property)); |
| |
| memcpy(property, testW, sizeof(testW)); |
| hr = IDxDiagContainer_EnumPropNames(child, ~0, property, sizeof(property)/sizeof(WCHAR)); |
| ok(hr == E_INVALIDARG, "Expected IDxDiagContainer::EnumPropNames to return E_INVALIDARG, got 0x%08x\n", hr); |
| ok(!memcmp(property, testW, sizeof(testW)), |
| "Expected the property buffer to be unchanged, got %s\n", wine_dbgstr_w(property)); |
| |
| trace("Starting property enumeration of the %s container:\n", wine_dbgstr_w(container)); |
| |
| /* We should be able to enumerate as many properties as the value that |
| * IDxDiagContainer::GetNumberOfProps returns. */ |
| for (index = 0; index <= propcount; index++) |
| { |
| /* A buffer size of 1 is unlikely to be valid, as only a null terminator |
| * could be stored, and it is unlikely that a property name could be empty. */ |
| DWORD buffersize = 1; |
| |
| memcpy(property, testW, sizeof(testW)); |
| hr = IDxDiagContainer_EnumPropNames(child, index, property, buffersize); |
| if (hr == E_INVALIDARG) |
| { |
| /* We should get here when index is one more than the maximum index value. */ |
| ok(propcount == index, |
| "Expected IDxDiagContainer::EnumPropNames to return E_INVALIDARG " |
| "on the last index %d, got 0x%08x\n", index, hr); |
| ok(!memcmp(property, testW, sizeof(testW)), |
| "Expected the property buffer to be unchanged, got %s\n", wine_dbgstr_w(property)); |
| break; |
| } |
| else if (hr == DXDIAG_E_INSUFFICIENT_BUFFER) |
| { |
| WCHAR temp[256]; |
| |
| ok(property[0] == '\0', |
| "Expected the property buffer string to be empty, got %s\n", wine_dbgstr_w(property)); |
| hr = IDxDiagContainer_EnumPropNames(child, index, temp, sizeof(temp)/sizeof(WCHAR)); |
| ok(hr == S_OK, |
| "Expected IDxDiagContainer::EnumPropNames to return S_OK, got 0x%08x\n", hr); |
| |
| /* Show that the DirectX SDK's stipulation that the buffer be at |
| * least 256 characters long is a mere suggestion, and smaller sizes |
| * can be acceptable also. IDxDiagContainer::EnumPropNames doesn't |
| * provide a way of getting the exact size required, so the buffersize |
| * value will be iterated to at most 256 characters. */ |
| for (buffersize = 2; buffersize <= 256; buffersize++) |
| { |
| memcpy(property, testW, sizeof(testW)); |
| hr = IDxDiagContainer_EnumPropNames(child, index, property, buffersize); |
| if (hr != DXDIAG_E_INSUFFICIENT_BUFFER) |
| break; |
| |
| ok(!memcmp(temp, property, sizeof(WCHAR)*(buffersize - 1)), |
| "Expected truncated property name string, got %s\n", wine_dbgstr_w(property)); |
| } |
| |
| ok(hr == S_OK, |
| "Expected IDxDiagContainer::EnumPropNames to return S_OK, " |
| "got hr = 0x%08x, buffersize = %d\n", hr, buffersize); |
| if (hr == S_OK) |
| trace("child[%d] = %s, length = %d\n", index, wine_dbgstr_w(property), buffersize); |
| } |
| else |
| { |
| ok(0, "IDxDiagContainer::EnumPropNames unexpectedly returned 0x%08x\n", hr); |
| break; |
| } |
| } |
| |
| IDxDiagContainer_Release(child); |
| |
| cleanup: |
| IDxDiagContainer_Release(pddc); |
| IDxDiagProvider_Release(pddp); |
| } |
| |
| static void test_GetProp(void) |
| { |
| HRESULT hr; |
| WCHAR container[256], property[256]; |
| IDxDiagContainer *child = NULL; |
| DWORD count, index; |
| VARIANT var; |
| SAFEARRAY *sa; |
| SAFEARRAYBOUND bound; |
| static const WCHAR emptyW[] = {0}; |
| static const WCHAR testW[] = {'t','e','s','t',0}; |
| |
| if (!create_root_IDxDiagContainer()) |
| { |
| skip("Unable to create the root IDxDiagContainer\n"); |
| return; |
| } |
| |
| /* Find a container with a property. */ |
| hr = IDxDiagContainer_GetNumberOfChildContainers(pddc, &count); |
| ok(hr == S_OK, "Expected IDxDiagContainer::GetNumberOfChildContainers to return S_OK, got 0x%08x\n", hr); |
| if (FAILED(hr)) |
| { |
| skip("IDxDiagContainer::GetNumberOfChildContainers failed\n"); |
| goto cleanup; |
| } |
| |
| for (index = 0; index < count; index++) |
| { |
| hr = IDxDiagContainer_EnumChildContainerNames(pddc, index, container, sizeof(container)/sizeof(WCHAR)); |
| ok(hr == S_OK, "Expected IDxDiagContainer_EnumChildContainerNames to return S_OK, got 0x%08x\n", hr); |
| if (FAILED(hr)) |
| { |
| skip("IDxDiagContainer::EnumChildContainerNames failed\n"); |
| goto cleanup; |
| } |
| |
| hr = IDxDiagContainer_GetChildContainer(pddc, container, &child); |
| ok(hr == S_OK, "Expected IDxDiagContainer::GetChildContainer to return S_OK, got 0x%08x\n", hr); |
| |
| if (SUCCEEDED(hr)) |
| { |
| hr = IDxDiagContainer_EnumPropNames(child, 0, property, sizeof(property)/sizeof(WCHAR)); |
| ok(hr == S_OK || hr == E_INVALIDARG, |
| "Expected IDxDiagContainer::EnumPropNames to return S_OK or E_INVALIDARG, got 0x%08x\n", hr); |
| |
| if (SUCCEEDED(hr)) |
| break; |
| else |
| { |
| IDxDiagContainer_Release(child); |
| child = NULL; |
| } |
| } |
| } |
| |
| if (!child) |
| { |
| skip("Unable to find a suitable container\n"); |
| goto cleanup; |
| } |
| |
| hr = IDxDiagContainer_GetProp(child, NULL, NULL); |
| ok(hr == E_INVALIDARG, "Expected IDxDiagContainer::GetProp to return E_INVALIDARG, got 0x%08x\n", hr); |
| |
| V_VT(&var) = 0xdead; |
| hr = IDxDiagContainer_GetProp(child, NULL, &var); |
| ok(hr == E_INVALIDARG, "Expected IDxDiagContainer::GetProp to return E_INVALIDARG, got 0x%08x\n", hr); |
| ok(V_VT(&var) == 0xdead, "Expected the variant to be untouched, got %u\n", V_VT(&var)); |
| |
| hr = IDxDiagContainer_GetProp(child, emptyW, NULL); |
| ok(hr == E_INVALIDARG, "Expected IDxDiagContainer::GetProp to return E_INVALIDARG, got 0x%08x\n", hr); |
| |
| V_VT(&var) = 0xdead; |
| hr = IDxDiagContainer_GetProp(child, emptyW, &var); |
| ok(hr == E_INVALIDARG, "Expected IDxDiagContainer::GetProp to return E_INVALIDARG, got 0x%08x\n", hr); |
| ok(V_VT(&var) == 0xdead, "Expected the variant to be untouched, got %u\n", V_VT(&var)); |
| |
| hr = IDxDiagContainer_GetProp(child, testW, NULL); |
| ok(hr == E_INVALIDARG, "Expected IDxDiagContainer::GetProp to return E_INVALIDARG, got 0x%08x\n", hr); |
| |
| V_VT(&var) = 0xdead; |
| hr = IDxDiagContainer_GetProp(child, testW, &var); |
| ok(hr == E_INVALIDARG, "Expected IDxDiagContainer::GetProp to return E_INVALIDARG, got 0x%08x\n", hr); |
| ok(V_VT(&var) == 0xdead, "Expected the variant to be untouched, got %u\n", V_VT(&var)); |
| |
| VariantInit(&var); |
| hr = IDxDiagContainer_GetProp(child, property, &var); |
| ok(hr == S_OK, "Expected IDxDiagContainer::GetProp to return S_OK, got 0x%08x\n", hr); |
| ok(V_VT(&var) != VT_EMPTY, "Expected the variant to be modified, got %d\n", V_VT(&var)); |
| |
| /* Since the documentation for IDxDiagContainer::GetProp claims that the |
| * function reports return values from VariantCopy, try to exercise failure |
| * paths in handling the destination variant. */ |
| |
| /* Try an invalid variant type. */ |
| V_VT(&var) = 0xdead; |
| hr = IDxDiagContainer_GetProp(child, property, &var); |
| ok(hr == S_OK, "Expected IDxDiagContainer::GetProp to return S_OK, got 0x%08x\n", hr); |
| ok(V_VT(&var) != 0xdead, "Expected the variant to be modified, got %d\n", V_VT(&var)); |
| |
| /* Try passing a variant with a locked SAFEARRAY. */ |
| bound.cElements = 1; |
| bound.lLbound = 0; |
| sa = SafeArrayCreate(VT_UI1, 1, &bound); |
| ok(sa != NULL, "Expected SafeArrayCreate to return a valid pointer\n"); |
| |
| V_VT(&var) = (VT_ARRAY | VT_UI1); |
| V_ARRAY(&var) = sa; |
| |
| hr = SafeArrayLock(sa); |
| ok(hr == S_OK, "Expected SafeArrayLock to return S_OK, got 0x%08x\n", hr); |
| |
| hr = IDxDiagContainer_GetProp(child, property, &var); |
| ok(hr == S_OK, "Expected IDxDiagContainer::GetProp to return S_OK, got 0x%08x\n", hr); |
| ok(V_VT(&var) != (VT_ARRAY | VT_UI1), "Expected the variant to be modified\n"); |
| |
| hr = SafeArrayUnlock(sa); |
| ok(hr == S_OK, "Expected SafeArrayUnlock to return S_OK, got 0x%08x\n", hr); |
| hr = SafeArrayDestroy(sa); |
| ok(hr == S_OK, "Expected SafeArrayDestroy to return S_OK, got 0x%08x\n", hr); |
| IDxDiagContainer_Release(child); |
| |
| cleanup: |
| IDxDiagContainer_Release(pddc); |
| IDxDiagProvider_Release(pddp); |
| } |
| |
| START_TEST(container) |
| { |
| CoInitialize(NULL); |
| test_GetNumberOfChildContainers(); |
| test_GetNumberOfProps(); |
| test_EnumChildContainerNames(); |
| test_GetChildContainer(); |
| test_dot_parsing(); |
| test_EnumPropNames(); |
| test_GetProp(); |
| CoUninitialize(); |
| } |