[UMPNPMGR] PNP_GetDeviceListSize: Implement the buffer size calculation for given...
authorEric Kohl <eric.kohl@reactos.org>
Sat, 29 Dec 2018 23:39:08 +0000 (00:39 +0100)
committerEric Kohl <eric.kohl@reactos.org>
Sun, 30 Dec 2018 08:06:59 +0000 (09:06 +0100)
base/services/umpnpmgr/umpnpmgr.c

index 3c96571..bae7fdd 100644 (file)
@@ -746,12 +746,73 @@ GetDeviceInstanceListSize(
     RegCloseKey(hDeviceKey);
 
     /* Return the largest possible buffer size */
-    *pulLength = (dwSubKeys * (wcslen(pszDevice) + 1 + dwMaxSubKeyLength + 1)) + 1;
+    *pulLength = dwSubKeys * (wcslen(pszDevice) + 1 + dwMaxSubKeyLength + 1);
 
     return CR_SUCCESS;
 }
 
 
+static
+CONFIGRET
+GetEnumeratorInstanceListSize(
+    _In_ LPCWSTR pszEnumerator,
+    _Out_ PULONG pulLength)
+{
+    WCHAR szDeviceBuffer[MAX_DEVICE_ID_LEN];
+    WCHAR szPathBuffer[512];
+    HKEY hEnumeratorKey;
+    DWORD dwIndex, dwDeviceLength, dwBufferLength;
+    DWORD dwError;
+    CONFIGRET ret = CR_SUCCESS;
+
+    *pulLength = 0;
+
+    /* Open the enumerator key */
+    dwError = RegOpenKeyExW(hEnumKey,
+                            pszEnumerator,
+                            0,
+                            KEY_ENUMERATE_SUB_KEYS,
+                            &hEnumeratorKey);
+    if (dwError != ERROR_SUCCESS)
+    {
+        DPRINT("Failed to open the enumerator key (Error %lu)\n", dwError);
+        return CR_REGISTRY_ERROR;
+    }
+
+    for (dwIndex = 0; ; dwIndex++)
+    {
+        dwDeviceLength = MAX_DEVICE_ID_LEN;
+        dwError = RegEnumKeyExW(hEnumeratorKey,
+                                dwIndex,
+                                szDeviceBuffer,
+                                &dwDeviceLength,
+                                NULL,
+                                NULL,
+                                NULL,
+                                NULL);
+        if (dwError != ERROR_SUCCESS)
+            break;
+
+        wsprintf(szPathBuffer, L"%s\\%s", pszEnumerator, szDeviceBuffer);
+        DPRINT("Path: %S\n", szPathBuffer);
+
+        ret = GetDeviceInstanceListSize(szPathBuffer, &dwBufferLength);
+        if (ret != CR_SUCCESS)
+        {
+            *pulLength = 0;
+            break;
+        }
+
+        *pulLength += dwBufferLength;
+    }
+
+    /* Close the enumerator key */
+    RegCloseKey(hEnumeratorKey);
+
+    return ret;
+}
+
+
 /* Function 11 */
 DWORD
 WINAPI
@@ -840,7 +901,8 @@ PNP_GetDeviceListSize(
         }
         else
         {
-            ret = CR_CALL_NOT_IMPLEMENTED;
+            ret = GetEnumeratorInstanceListSize(pszFilter,
+                                                pulLength);
         }
     }
     else /* CM_GETIDLIST_FILTER_NONE */
@@ -848,6 +910,10 @@ PNP_GetDeviceListSize(
         ret = CR_CALL_NOT_IMPLEMENTED;
     }
 
+    /* Add one character for the terminating double UNICODE_NULL */
+    if (ret == CR_SUCCESS)
+        (*pulLength) += 1;
+
     return ret;
 }