From: Michael Müller michael@fds-team.de
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=32613 Signed-off-by: Gijs Vermeulen gijsvrm@gmail.com --- dlls/dxdiagn/Makefile.in | 2 +- dlls/dxdiagn/provider.c | 79 ++++++++++++++++++++++++ dlls/dxdiagn/tests/container.c | 106 +++++++++++++++++++++++++++++++++ 3 files changed, 186 insertions(+), 1 deletion(-)
diff --git a/dlls/dxdiagn/Makefile.in b/dlls/dxdiagn/Makefile.in index fa4b611f245..88c99803b06 100644 --- a/dlls/dxdiagn/Makefile.in +++ b/dlls/dxdiagn/Makefile.in @@ -1,5 +1,5 @@ MODULE = dxdiagn.dll -IMPORTS = strmiids dxguid uuid d3d9 ddraw version ole32 oleaut32 user32 advapi32 +IMPORTS = strmiids dxguid uuid d3d9 ddraw version ole32 oleaut32 user32 advapi32 dsound
EXTRADLLFLAGS = -mno-cygwin
diff --git a/dlls/dxdiagn/provider.c b/dlls/dxdiagn/provider.c index 6b6f4e640cc..7515f72002d 100644 --- a/dlls/dxdiagn/provider.c +++ b/dlls/dxdiagn/provider.c @@ -36,6 +36,7 @@ #include "wine/fil_data.h" #include "psapi.h" #include "wbemcli.h" +#include "dsound.h"
#include "wine/debug.h"
@@ -1364,11 +1365,73 @@ static HRESULT build_displaydevices_tree(IDxDiagContainerImpl_Container *node) return fill_display_information_fallback(node); }
+struct enum_context +{ + IDxDiagContainerImpl_Container *cont; + HRESULT hr; + int index; +}; + +static LPWSTR guid_to_string(LPWSTR lpwstr, REFGUID lpcguid) +{ + wsprintfW(lpwstr, L"%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", lpcguid->Data1, lpcguid->Data2, + lpcguid->Data3, lpcguid->Data4[0], lpcguid->Data4[1], lpcguid->Data4[2], lpcguid->Data4[3], lpcguid->Data4[4], + lpcguid->Data4[5], lpcguid->Data4[6], lpcguid->Data4[7]); + + return lpwstr; +} + +BOOL CALLBACK dsound_enum(LPGUID guid, LPCWSTR desc, LPCWSTR module, LPVOID context) +{ + struct enum_context *enum_ctx = context; + IDxDiagContainerImpl_Container *device; + WCHAR buffer[256]; + const WCHAR *p, *name; + + /* the default device is enumerated twice, one time without GUID */ + if (!guid) return TRUE; + + swprintf(buffer, ARRAY_SIZE(buffer), L"%u", enum_ctx->index); + device = allocate_information_node(buffer); + if (!device) + { + enum_ctx->hr = E_OUTOFMEMORY; + return FALSE; + } + + add_subcontainer(enum_ctx->cont, device); + + guid_to_string(buffer, guid); + enum_ctx->hr = add_bstr_property(device, L"szGuidDeviceID", buffer); + if (FAILED(enum_ctx->hr)) + return FALSE; + + enum_ctx->hr = add_bstr_property(device, szDescription, desc); + if (FAILED(enum_ctx->hr)) + return FALSE; + + enum_ctx->hr = add_bstr_property(device, L"szDriverPath", module); + if (FAILED(enum_ctx->hr)) + return FALSE; + + name = module; + if ((p = wcsrchr(name, '\'))) name = p + 1; + if ((p = wcsrchr(name, '/'))) name = p + 1; + + enum_ctx->hr = add_bstr_property(device, szDriverName, name); + if (FAILED(enum_ctx->hr)) + return FALSE; + + enum_ctx->index++; + return TRUE; +} + static HRESULT build_directsound_tree(IDxDiagContainerImpl_Container *node) { static const WCHAR DxDiag_SoundDevices[] = {'D','x','D','i','a','g','_','S','o','u','n','d','D','e','v','i','c','e','s',0}; static const WCHAR DxDiag_SoundCaptureDevices[] = {'D','x','D','i','a','g','_','S','o','u','n','d','C','a','p','t','u','r','e','D','e','v','i','c','e','s',0};
+ struct enum_context enum_ctx; IDxDiagContainerImpl_Container *cont;
cont = allocate_information_node(DxDiag_SoundDevices); @@ -1377,12 +1440,28 @@ static HRESULT build_directsound_tree(IDxDiagContainerImpl_Container *node)
add_subcontainer(node, cont);
+ enum_ctx.cont = cont; + enum_ctx.hr = S_OK; + enum_ctx.index = 0; + + DirectSoundEnumerateW(dsound_enum, &enum_ctx); + if (FAILED(enum_ctx.hr)) + return enum_ctx.hr; + cont = allocate_information_node(DxDiag_SoundCaptureDevices); if (!cont) return E_OUTOFMEMORY;
add_subcontainer(node, cont);
+ enum_ctx.cont = cont; + enum_ctx.hr = S_OK; + enum_ctx.index = 0; + + DirectSoundCaptureEnumerateW(dsound_enum, &enum_ctx); + if (FAILED(enum_ctx.hr)) + return enum_ctx.hr; + return S_OK; }
diff --git a/dlls/dxdiagn/tests/container.c b/dlls/dxdiagn/tests/container.c index c011ff9cc07..e335cf5b42e 100644 --- a/dlls/dxdiagn/tests/container.c +++ b/dlls/dxdiagn/tests/container.c @@ -922,6 +922,110 @@ cleanup: IDxDiagProvider_Release(pddp); }
+static void test_DxDiag_SoundDevices(void) +{ + static const struct property_test property_tests[] = + { + {L"szDescription", VT_BSTR}, + {L"szGuidDeviceID", VT_BSTR}, + {L"szDriverName", VT_BSTR}, + {L"szDriverPath", VT_BSTR}, + }; + + IDxDiagContainer *sound_cont = NULL; + DWORD count, i; + HRESULT hr; + + if (!create_root_IDxDiagContainer()) + { + skip("Unable to create the root IDxDiagContainer\n"); + return; + } + + hr = IDxDiagContainer_GetChildContainer(pddc, L"DxDiag_DirectSound.DxDiag_SoundDevices", &sound_cont); + ok(hr == S_OK, "Expected IDxDiagContainer::GetChildContainer to return S_OK, got 0x%08x\n", hr); + + hr = IDxDiagContainer_GetNumberOfProps(sound_cont, &count); + ok(hr == S_OK, "Expected IDxDiagContainer::GetNumberOfProps to return S_OK, got 0x%08x\n", hr); + ok(count == 0, "Expected count to be 0, got %u\n", count); + + hr = IDxDiagContainer_GetNumberOfChildContainers(sound_cont, &count); + ok(hr == S_OK, "Expected IDxDiagContainer::GetNumberOfChildContainers to return S_OK, got 0x%08x\n", hr); + + for (i = 0; i < count; i++) + { + WCHAR child_container[256]; + IDxDiagContainer *child; + + hr = IDxDiagContainer_EnumChildContainerNames(sound_cont, i, child_container, ARRAY_SIZE(child_container)); + ok(hr == S_OK, "Expected IDxDiagContainer::EnumChildContainerNames to return S_OK, got 0x%08x\n", hr); + + hr = IDxDiagContainer_GetChildContainer(sound_cont, child_container, &child); + ok(hr == S_OK, "Expected IDxDiagContainer::GetChildContainer to return S_OK, got 0x%08x\n", hr); + + trace("Testing container %s\n", wine_dbgstr_w(child_container)); + test_container_properties(child, property_tests, ARRAY_SIZE(property_tests)); + + IDxDiagContainer_Release(child); + } + + IDxDiagContainer_Release(sound_cont); + IDxDiagContainer_Release(pddc); + IDxDiagProvider_Release(pddp); +} + +static void test_DxDiag_SoundCaptureDevices(void) +{ + static const struct property_test property_tests[] = + { + {L"szDescription", VT_BSTR}, + {L"szGuidDeviceID", VT_BSTR}, + {L"szDriverName", VT_BSTR}, + {L"szDriverPath", VT_BSTR}, + }; + + IDxDiagContainer *sound_cont = NULL; + DWORD count, i; + HRESULT hr; + + if (!create_root_IDxDiagContainer()) + { + skip("Unable to create the root IDxDiagContainer\n"); + return; + } + + hr = IDxDiagContainer_GetChildContainer(pddc, L"DxDiag_DirectSound.DxDiag_SoundCaptureDevices", &sound_cont); + ok(hr == S_OK, "Expected IDxDiagContainer::GetChildContainer to return S_OK, got 0x%08x\n", hr); + + hr = IDxDiagContainer_GetNumberOfProps(sound_cont, &count); + ok(hr == S_OK, "Expected IDxDiagContainer::GetNumberOfProps to return S_OK, got 0x%08x\n", hr); + ok(count == 0, "Expected count to be 0, got %u\n", count); + + hr = IDxDiagContainer_GetNumberOfChildContainers(sound_cont, &count); + ok(hr == S_OK, "Expected IDxDiagContainer::GetNumberOfChildContainers to return S_OK, got 0x%08x\n", hr); + + for (i = 0; i < count; i++) + { + WCHAR child_container[256]; + IDxDiagContainer *child; + + hr = IDxDiagContainer_EnumChildContainerNames(sound_cont, i, child_container, ARRAY_SIZE(child_container)); + ok(hr == S_OK, "Expected IDxDiagContainer::EnumChildContainerNames to return S_OK, got 0x%08x\n", hr); + + hr = IDxDiagContainer_GetChildContainer(sound_cont, child_container, &child); + ok(hr == S_OK, "Expected IDxDiagContainer::GetChildContainer to return S_OK, got 0x%08x\n", hr); + + trace("Testing container %s\n", wine_dbgstr_w(child_container)); + test_container_properties(child, property_tests, ARRAY_SIZE(property_tests)); + + IDxDiagContainer_Release(child); + } + + IDxDiagContainer_Release(sound_cont); + IDxDiagContainer_Release(pddc); + IDxDiagProvider_Release(pddp); +} + START_TEST(container) { CoInitialize(NULL); @@ -936,5 +1040,7 @@ START_TEST(container) test_root_children(); test_DxDiag_SystemInfo(); test_DxDiag_DisplayDevices(); + test_DxDiag_SoundDevices(); + test_DxDiag_SoundCaptureDevices(); CoUninitialize(); }
From: Michael Müller michael@fds-team.de
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=38014 Signed-off-by: Gijs Vermeulen gijsvrm@gmail.com --- dlls/dxdiagn/container.c | 12 ++++++++++-- dlls/dxdiagn/tests/container.c | 22 ++++++++++++++++++++-- 2 files changed, 30 insertions(+), 4 deletions(-)
diff --git a/dlls/dxdiagn/container.c b/dlls/dxdiagn/container.c index 87d593a15a7..7a5a7e9d0a5 100644 --- a/dlls/dxdiagn/container.c +++ b/dlls/dxdiagn/container.c @@ -160,6 +160,14 @@ static HRESULT WINAPI IDxDiagContainerImpl_GetChildContainer(IDxDiagContainer *i if (NULL == tmp) return E_FAIL; lstrcpynW(tmp, pwszContainer, tmp_len);
+ /* special handling for an empty string and leaf container */ + if (!tmp[0] && list_empty(&pContainer->subContainers)) { + hr = DXDiag_CreateDXDiagContainer(&IID_IDxDiagContainer, pContainer, This->pProv, (void **)ppInstance); + if (SUCCEEDED(hr)) + TRACE("Succeeded in getting the container instance\n"); + goto out; + } + cur = wcschr(tmp, '.'); while (NULL != cur) { *cur = '\0'; /* cut tmp string to '.' */ @@ -167,7 +175,7 @@ static HRESULT WINAPI IDxDiagContainerImpl_GetChildContainer(IDxDiagContainer *i TRACE("Trying to get parent container %s\n", debugstr_w(tmp)); hr = IDxDiagContainerImpl_GetChildContainerInternal(pContainer, tmp, &pContainer); if (FAILED(hr)) - goto on_error; + goto out; cur++; /* go after '.' (just replaced by \0) */ tmp = cur; cur = wcschr(tmp, '.'); @@ -181,7 +189,7 @@ static HRESULT WINAPI IDxDiagContainerImpl_GetChildContainer(IDxDiagContainer *i TRACE("Succeeded in getting the container instance\n"); }
-on_error: +out: HeapFree(GetProcessHeap(), 0, orig_tmp); return hr; } diff --git a/dlls/dxdiagn/tests/container.c b/dlls/dxdiagn/tests/container.c index e335cf5b42e..a43324b3e8f 100644 --- a/dlls/dxdiagn/tests/container.c +++ b/dlls/dxdiagn/tests/container.c @@ -819,7 +819,7 @@ static void test_DxDiag_SystemInfo(void) {L"szProcessorEnglish", VT_BSTR}, };
- IDxDiagContainer *container; + IDxDiagContainer *container, *container2; HRESULT hr;
if (!create_root_IDxDiagContainer()) @@ -828,6 +828,9 @@ static void test_DxDiag_SystemInfo(void) return; }
+ hr = IDxDiagContainer_GetChildContainer(pddc, L"", &container2); + ok(hr == E_INVALIDARG, "Expected IDxDiagContainer::GetChildContainer to return E_INVALIDARG, got 0x%08x\n", hr); + hr = IDxDiagContainer_GetChildContainer(pddc, L"DxDiag_SystemInfo", &container); ok(hr == S_OK, "Expected IDxDiagContainer::GetChildContainer to return S_OK, got 0x%08x\n", hr);
@@ -835,6 +838,14 @@ static void test_DxDiag_SystemInfo(void) { trace("Testing container DxDiag_SystemInfo\n"); test_container_properties(container, property_tests, ARRAY_SIZE(property_tests)); + + container2 = NULL; + hr = IDxDiagContainer_GetChildContainer(container, L"", &container2); + ok(hr == S_OK, "Expected IDxDiagContainer::GetChildContainer to return S_OK, got 0x%08x\n", hr); + ok(container2 != NULL, "Expected container2 != NULL\n"); + ok(container2 != container, "Expected container != container2\n"); + + IDxDiagContainer_Release(container2); IDxDiagContainer_Release(container); }
@@ -954,8 +965,8 @@ static void test_DxDiag_SoundDevices(void)
for (i = 0; i < count; i++) { + IDxDiagContainer *child, *child2; WCHAR child_container[256]; - IDxDiagContainer *child;
hr = IDxDiagContainer_EnumChildContainerNames(sound_cont, i, child_container, ARRAY_SIZE(child_container)); ok(hr == S_OK, "Expected IDxDiagContainer::EnumChildContainerNames to return S_OK, got 0x%08x\n", hr); @@ -966,6 +977,13 @@ static void test_DxDiag_SoundDevices(void) trace("Testing container %s\n", wine_dbgstr_w(child_container)); test_container_properties(child, property_tests, ARRAY_SIZE(property_tests));
+ child2 = NULL; + hr = IDxDiagContainer_GetChildContainer(child, L"", &child2); + ok(hr == S_OK, "Expected IDxDiagContainer::GetChildContainer to return S_OK, got 0x%08x\n", hr); + ok(child2 != NULL, "Expected child2 != NULL\n"); + ok(child2 != child, "Expected child != child2\n"); + + IDxDiagContainer_Release(child2); IDxDiagContainer_Release(child); }