https://git.reactos.org/?p=reactos.git;a=commitdiff;h=5da008c33837c03c1c186…
commit 5da008c33837c03c1c186604aff1b6aec462bfb8
Author:     Eric Kohl <eric.kohl(a)reactos.org>
AuthorDate: Mon Dec 31 16:14:04 2018 +0100
Commit:     Eric Kohl <eric.kohl(a)reactos.org>
CommitDate: Mon Dec 31 16:15:16 2018 +0100
    [UMPNPMGR] PNP_GetDeviceListSize: Implement the buffer size calculation for the
enumeration of services instances.
---
 base/services/umpnpmgr/umpnpmgr.c | 116 +++++++++++++++++++++++++++++++++++++-
 1 file changed, 115 insertions(+), 1 deletion(-)
diff --git a/base/services/umpnpmgr/umpnpmgr.c b/base/services/umpnpmgr/umpnpmgr.c
index e7d1d42bdf..11911cbb11 100644
--- a/base/services/umpnpmgr/umpnpmgr.c
+++ b/base/services/umpnpmgr/umpnpmgr.c
@@ -580,6 +580,17 @@ GetRelationsInstanceList(
 }
+static
+CONFIGRET
+GetServiceInstanceList(
+    _In_ PWSTR pszService,
+    _Inout_ PWSTR pszBuffer,
+    _Inout_ PDWORD pulLength)
+{
+    return CR_CALL_NOT_IMPLEMENTED;
+}
+
+
 static
 CONFIGRET
 GetDeviceInstanceList(
@@ -810,6 +821,9 @@ PNP_GetDeviceList(
     }
     else if (ulFlags & CM_GETIDLIST_FILTER_SERVICE)
     {
+        ret = GetServiceInstanceList(pszFilter,
+                                     Buffer,
+                                     pulLength);
         ret = CR_CALL_NOT_IMPLEMENTED;
     }
     else if (ulFlags & CM_GETIDLIST_FILTER_ENUMERATOR)
@@ -892,6 +906,105 @@ GetRelationsInstanceListSize(
 }
+static
+CONFIGRET
+GetServiceInstanceListSize(
+    _In_ PWSTR pszService,
+    _Out_ PDWORD pulLength)
+{
+    HKEY hServicesKey = NULL, hServiceKey = NULL, hEnumKey = NULL;
+    DWORD dwValues, dwMaxValueLength, dwSize;
+    DWORD dwError;
+    CONFIGRET ret = CR_SUCCESS;
+
+    /* Open the device key */
+    dwError = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
+                            L"System\\CurrentControlSet\\Services",
+                            0,
+                            KEY_READ,
+                            &hServicesKey);
+    if (dwError != ERROR_SUCCESS)
+    {
+        DPRINT("Failed to open the services key (Error %lu)\n", dwError);
+        return CR_REGISTRY_ERROR;
+    }
+
+    dwError = RegOpenKeyExW(hServicesKey,
+                            pszService,
+                            0,
+                            KEY_READ,
+                            &hServiceKey);
+    if (dwError != ERROR_SUCCESS)
+    {
+        DPRINT("Failed to open the service key (Error %lu)\n", dwError);
+        ret = CR_REGISTRY_ERROR;
+        goto Done;
+    }
+
+    dwError = RegOpenKeyExW(hServiceKey,
+                            L"Enum",
+                            0,
+                            KEY_READ,
+                            &hEnumKey);
+    if (dwError != ERROR_SUCCESS)
+    {
+        DPRINT("Failed to open the service enum key (Error %lu)\n", dwError);
+        ret = CR_REGISTRY_ERROR;
+        goto Done;
+    }
+
+    /* Retrieve the number of device instances */
+    dwSize = sizeof(DWORD);
+    dwError = RegQueryValueExW(hEnumKey,
+                               L"Count",
+                               NULL,
+                               NULL,
+                               (LPBYTE)&dwValues,
+                               &dwSize);
+    if (dwError != ERROR_SUCCESS)
+    {
+        DPRINT("RegQueryValueExW failed (Error %lu)\n", dwError);
+        dwValues = 1;
+    }
+
+    /* Retrieve the maximum instance name length */
+    dwError = RegQueryInfoKeyW(hEnumKey,
+                               NULL,
+                               NULL,
+                               NULL,
+                               NULL,
+                               NULL,
+                               NULL,
+                               NULL,
+                               NULL,
+                               &dwMaxValueLength,
+                               NULL,
+                               NULL);
+    if (dwError != ERROR_SUCCESS)
+    {
+        DPRINT("RegQueryInfoKeyW failed (Error %lu)\n", dwError);
+        dwMaxValueLength = MAX_DEVICE_ID_LEN;
+    }
+
+    DPRINT("dwValues %lu  dwMaxValueLength %lu\n", dwValues, dwMaxValueLength /
sizeof(WCHAR));
+
+    /* Return the largest possible buffer size */
+    *pulLength = dwValues * dwMaxValueLength / sizeof(WCHAR) + 2;
+
+Done:
+    if (hEnumKey != NULL)
+        RegCloseKey(hEnumKey);
+
+    if (hServiceKey != NULL)
+        RegCloseKey(hServiceKey);
+
+    if (hServicesKey != NULL)
+        RegCloseKey(hServicesKey);
+
+    return ret;
+}
+
+
 static
 CONFIGRET
 GetDeviceInstanceListSize(
@@ -1080,7 +1193,8 @@ PNP_GetDeviceListSize(
     }
     else if (ulFlags & CM_GETIDLIST_FILTER_SERVICE)
     {
-        ret = CR_CALL_NOT_IMPLEMENTED;
+        ret = GetServiceInstanceListSize(pszFilter,
+                                         pulLength);
     }
     else if (ulFlags & CM_GETIDLIST_FILTER_ENUMERATOR)
     {