From 0b45d42b25aecc86e19aba20d9114b4c76947c9c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Sat, 15 Aug 2015 03:58:04 +0200
Subject: dxdiagn: Calling GetChildContainer with an empty string on a leaf
 container returns the object itself

---
 dlls/dxdiagn/container.c       | 12 ++++++++++--
 dlls/dxdiagn/tests/container.c | 25 +++++++++++++++++++++++--
 2 files changed, 33 insertions(+), 4 deletions(-)

diff --git a/dlls/dxdiagn/container.c b/dlls/dxdiagn/container.c
index d167043..6e068e5 100644
--- a/dlls/dxdiagn/container.c
+++ b/dlls/dxdiagn/container.c
@@ -162,6 +162,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 = strchrW(tmp, '.');
   while (NULL != cur) {
     *cur = '\0'; /* cut tmp string to '.' */
@@ -169,7 +177,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 = strchrW(tmp, '.');
@@ -183,7 +191,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 2ffe0fb..aab6122 100644
--- a/dlls/dxdiagn/tests/container.c
+++ b/dlls/dxdiagn/tests/container.c
@@ -901,7 +901,8 @@ static void test_DxDiag_SystemInfo(void)
         {szProcessorEnglish, VT_BSTR},
     };
 
-    IDxDiagContainer *container;
+    IDxDiagContainer *container, *container2;
+    static const WCHAR empty[] = {0};
     HRESULT hr;
 
     if (!create_root_IDxDiagContainer())
@@ -910,6 +911,9 @@ static void test_DxDiag_SystemInfo(void)
         return;
     }
 
+    hr = IDxDiagContainer_GetChildContainer(pddc, empty, &container2);
+    ok(hr == E_INVALIDARG, "Expected IDxDiagContainer::GetChildContainer to return E_INVALIDARG, got 0x%08x\n", hr);
+
     hr = IDxDiagContainer_GetChildContainer(pddc, DxDiag_SystemInfo, &container);
     ok(hr == S_OK, "Expected IDxDiagContainer::GetChildContainer to return S_OK, got 0x%08x\n", hr);
 
@@ -917,6 +921,14 @@ static void test_DxDiag_SystemInfo(void)
     {
         trace("Testing container DxDiag_SystemInfo\n");
         test_container_properties(container, property_tests, sizeof(property_tests)/sizeof(property_tests[0]));
+
+        container2 = NULL;
+        hr = IDxDiagContainer_GetChildContainer(container, empty, &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");
+        if (hr == S_OK) IDxDiagContainer_Release(container2);
+
         IDxDiagContainer_Release(container);
     }
 
@@ -1031,6 +1043,7 @@ static void test_DxDiag_SoundDevices(void)
     static const WCHAR szGuidDeviceID[] = {'s','z','G','u','i','d','D','e','v','i','c','e','I','D',0};
     static const WCHAR szDriverPath[] = {'s','z','D','r','i','v','e','r','P','a','t','h',0};
     static const WCHAR szDriverName[] = {'s','z','D','r','i','v','e','r','N','a','m','e',0};
+    static const WCHAR empty[] = {0};
 
     static const struct property_test property_tests[] =
     {
@@ -1070,7 +1083,7 @@ static void test_DxDiag_SoundDevices(void)
     for (i = 0; i < count; i++)
     {
         WCHAR child_container[256];
-        IDxDiagContainer *child;
+        IDxDiagContainer *child, *child2;
 
         hr = IDxDiagContainer_EnumChildContainerNames(sound_cont, i, child_container, sizeof(child_container)/sizeof(WCHAR));
         ok(hr == S_OK, "Expected IDxDiagContainer::EnumChildContainerNames to return S_OK, got 0x%08x\n", hr);
@@ -1083,6 +1096,14 @@ static void test_DxDiag_SoundDevices(void)
             trace("Testing container %s\n", wine_dbgstr_w(child_container));
             test_container_properties(child, property_tests, sizeof(property_tests)/sizeof(property_tests[0]));
         }
+
+        child2 = NULL;
+        hr = IDxDiagContainer_GetChildContainer(child, empty, &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");
+        if (hr == S_OK) IDxDiagContainer_Release(child2);
+
         IDxDiagContainer_Release(child);
     }
 
-- 
2.5.0

