From 4246b64dcb8ae6478f516bfe934d5c749b77deb0 Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Sun, 10 May 2020 20:45:11 +0200 Subject: [PATCH] [UMPNPMGR] Implement PNP_GetFirstLogConf and PNP_GetNextLogConf (WIP) - PNP_GetFirstLogConf only works for resources lists. - PNP_GetNextLogConf does not return a valid tag yet. --- base/services/umpnpmgr/rpcserver.c | 291 ++++++++++++++++++++++++++++- 1 file changed, 287 insertions(+), 4 deletions(-) diff --git a/base/services/umpnpmgr/rpcserver.c b/base/services/umpnpmgr/rpcserver.c index 313ca1c8076..e88d3cc123d 100644 --- a/base/services/umpnpmgr/rpcserver.c +++ b/base/services/umpnpmgr/rpcserver.c @@ -410,6 +410,131 @@ IsRootDeviceInstanceID( } +static +CONFIGRET +OpenConfigurationKey( + _In_ LPCWSTR pszDeviceID, + _Out_ PHKEY phKey) +{ + WCHAR szKeyName[MAX_PATH]; + HKEY hInstanceKey; + DWORD dwError; + + /* Build the full device instance key name */ + wcscpy(szKeyName, L"System\\CurrentControlSet\\Enum\\"); + wcscat(szKeyName, pszDeviceID); + + /* Open the device instance key */ + dwError = RegOpenKeyExW(HKEY_LOCAL_MACHINE, + szKeyName, + 0, + KEY_QUERY_VALUE | KEY_SET_VALUE | KEY_CREATE_SUB_KEY, + &hInstanceKey); + if (dwError != ERROR_SUCCESS) + return CR_INVALID_DEVINST; + + /* Create or open the LogConf key */ + dwError = RegCreateKeyExW(hInstanceKey, + L"LogConf", + 0, + NULL, + REG_OPTION_NON_VOLATILE, + KEY_ALL_ACCESS, + NULL, + phKey, + NULL); + + /* Close the device instance key */ + RegCloseKey(hInstanceKey); + + if (dwError != ERROR_SUCCESS) + return CR_REGISTRY_ERROR; + + return CR_SUCCESS; +} + + +static +CONFIGRET +GetConfigurationData( + _In_ HKEY hKey, + _In_ ULONG ulLogConfType, + _Out_ PULONG pulRegDataType, + _Out_ PULONG pulDataSize, + _Out_ LPBYTE *ppBuffer) +{ + LPCWSTR pszValueName; + + switch (ulLogConfType) + { + case BOOT_LOG_CONF: + pszValueName = L"BootConfig"; + *pulRegDataType = REG_RESOURCE_LIST; + break; + + case ALLOC_LOG_CONF: + pszValueName = L"AllocConfig"; + *pulRegDataType = REG_RESOURCE_LIST; + break; + + case FORCED_LOG_CONF: + pszValueName = L"ForcedConfig"; + *pulRegDataType = REG_RESOURCE_LIST; + break; + + case FILTERED_LOG_CONF: + pszValueName = L"FilteredConfigVector"; + *pulRegDataType = REG_RESOURCE_REQUIREMENTS_LIST; + break; + + case BASIC_LOG_CONF: + pszValueName = L"BasicConfigVector"; + *pulRegDataType = REG_RESOURCE_REQUIREMENTS_LIST; + break; + + case OVERRIDE_LOG_CONF: + pszValueName = L"OverrideConfigVector"; + *pulRegDataType = REG_RESOURCE_REQUIREMENTS_LIST; + break; + + default: + DPRINT1("Unsupported configuration type!\n"); + return CR_FAILURE; + } + + /* Get the configuration data size */ + if (RegQueryValueExW(hKey, + pszValueName, + NULL, + NULL, + NULL, + pulDataSize) != ERROR_SUCCESS) + { + return CR_INVALID_LOG_CONF; + } + + /* Allocate the buffer */ + *ppBuffer = HeapAlloc(GetProcessHeap(), 0, *pulDataSize); + if (*ppBuffer == NULL) + { + return CR_OUT_OF_MEMORY; + } + + /* Retrieve the configuration data */ + if (RegQueryValueExW(hKey, + pszValueName, + NULL, + NULL, + (LPBYTE)*ppBuffer, + pulDataSize) != ERROR_SUCCESS) + { + return CR_INVALID_LOG_CONF; + } + + return CR_SUCCESS; +} + + /* PUBLIC FUNCTIONS **********************************************************/ /* Function 0 */ @@ -3732,8 +3857,92 @@ PNP_GetFirstLogConf( DWORD *pulLogConfTag, DWORD ulFlags) { - UNIMPLEMENTED; - return CR_CALL_NOT_IMPLEMENTED; + HKEY hConfigKey = NULL; + DWORD RegDataType = 0; + ULONG ulDataSize = 0; + LPBYTE lpData = NULL; + CONFIGRET ret = CR_SUCCESS; + + DPRINT("PNP_GetFirstLogConf(%p %S %lu %p 0x%08lx)\n", + hBinding, pDeviceID, ulLogConfType, pulLogConfTag, ulFlags); + + if (pulLogConfTag == NULL) + return CR_INVALID_POINTER; + + *pulLogConfTag = (DWORD)0; + + if (ulFlags & ~LOG_CONF_BITS) + return CR_INVALID_FLAG; + + if (!IsValidDeviceInstanceID(pDeviceID)) + return CR_INVALID_DEVINST; + + ret = OpenConfigurationKey(pDeviceID, + &hConfigKey); + if (ret != CR_SUCCESS) + { + DPRINT1("OpenConfigurationKey() failed (Error %lu)\n", ret); + ret = CR_NO_MORE_LOG_CONF; + goto done; + } + + ret = GetConfigurationData(hConfigKey, + ulLogConfType, + &RegDataType, + &ulDataSize, + &lpData); + if (ret != CR_SUCCESS) + { + DPRINT1("GetConfigurationData() failed (Error %lu)\n", ret); + ret = CR_NO_MORE_LOG_CONF; + goto done; + } + + DPRINT("Data size %lu\n", ulDataSize); + if (ulDataSize == 0 || lpData == NULL) + { + DPRINT1("No config data available!\n"); + ret = CR_NO_MORE_LOG_CONF; + goto done; + } + + /* Get the first tag */ + if (RegDataType == REG_RESOURCE_LIST) + { + DPRINT("REG_RESOURCE_LIST\n"); + + DPRINT("ResourceList->Count %lu\n", ((PCM_RESOURCE_LIST)lpData)->Count); + if (((PCM_RESOURCE_LIST)lpData)->Count == 0) + { + DPRINT1("No resource descriptors!\n"); + ret = CR_NO_MORE_LOG_CONF; + goto done; + } + + DPRINT("lpData %p\n", lpData); + DPRINT("&List[0] %p\n", &(((PCM_RESOURCE_LIST)lpData)->List[0])); + + *pulLogConfTag = (DWORD)((DWORD_PTR)&(((PCM_RESOURCE_LIST)lpData)->List[0]) - (DWORD_PTR)lpData); + DPRINT("Offset (Tag): 0x%08lx\n", *pulLogConfTag); + } + else if (RegDataType == REG_RESOURCE_REQUIREMENTS_LIST) + { + DPRINT1("FIXME: REG_RESOURCE_REQUIREMENTS_LIST\n"); + /* FIXME */ + ret = CR_NO_MORE_LOG_CONF; + goto done; + } + +done: + if (lpData != NULL) + HeapFree(GetProcessHeap(), 0, lpData); + + if (hConfigKey != NULL) + RegCloseKey(hConfigKey); + + DPRINT("PNP_GetFirstLogConf() returns %lu\n", ret); + + return ret; } @@ -3748,8 +3957,82 @@ PNP_GetNextLogConf( DWORD *pulNextTag, DWORD ulFlags) { - UNIMPLEMENTED; - return CR_CALL_NOT_IMPLEMENTED; + HKEY hConfigKey = NULL; + DWORD RegDataType = 0; + ULONG ulDataSize = 0; + LPBYTE lpData = NULL; + CONFIGRET ret = CR_SUCCESS; + + DPRINT("PNP_GetNextLogConf(%p %S %lu %ul %p 0x%08lx)\n", + hBinding, pDeviceID, ulLogConfType, ulCurrentTag, pulNextTag, ulFlags); + + if (pulNextTag == NULL) + return CR_INVALID_POINTER; + + *pulNextTag = (DWORD)0; + + if (ulFlags != 0) + return CR_INVALID_FLAG; + + if (!IsValidDeviceInstanceID(pDeviceID)) + return CR_INVALID_DEVINST; + + ret = OpenConfigurationKey(pDeviceID, + &hConfigKey); + if (ret != CR_SUCCESS) + { + DPRINT1("OpenConfigurationKey() failed (Error %lu)\n", ret); + ret = CR_NO_MORE_LOG_CONF; + goto done; + } + + ret = GetConfigurationData(hConfigKey, + ulLogConfType, + &RegDataType, + &ulDataSize, + &lpData); + if (ret != CR_SUCCESS) + { + DPRINT1("GetConfigurationData() failed (Error %lu)\n", ret); + ret = CR_NO_MORE_LOG_CONF; + goto done; + } + + DPRINT("Data size %lu\n", ulDataSize); + + if (ulDataSize == 0 || lpData == NULL) + { + DPRINT1("No config data available!\n"); + ret = CR_NO_MORE_LOG_CONF; + goto done; + } + + /* FIXME: Get the next tag */ + if (RegDataType == REG_RESOURCE_LIST) + { + DPRINT1("FIXME: REG_RESOURCE_LIST\n"); + /* FIXME */ + ret = CR_NO_MORE_LOG_CONF; + goto done; + } + else if (RegDataType == REG_RESOURCE_REQUIREMENTS_LIST) + { + DPRINT1("FIXME: REG_RESOURCE_REQUIREMENTS_LIST\n"); + /* FIXME */ + ret = CR_NO_MORE_LOG_CONF; + goto done; + } + +done: + if (lpData != NULL) + HeapFree(GetProcessHeap(), 0, lpData); + + if (hConfigKey != NULL) + RegCloseKey(hConfigKey); + + DPRINT("PNP_GetNextLogConf() returns %lu\n", ret); + + return ret; }