https://git.reactos.org/?p=reactos.git;a=commitdiff;h=986ce63c4c17e354c56aab...
commit 986ce63c4c17e354c56aab068be87d32bbadb653 Author: Eric Kohl eric.kohl@reactos.org AuthorDate: Wed Sep 26 23:42:00 2018 +0200 Commit: Eric Kohl eric.kohl@reactos.org CommitDate: Wed Sep 26 23:49:01 2018 +0200
[SETUPAPI] SetupDiGetClassDevPropertySheetsW: Support class property sheet providers. --- dll/win32/setupapi/devclass.c | 157 ++++++++++++++++++++++++++---------------- 1 file changed, 97 insertions(+), 60 deletions(-)
diff --git a/dll/win32/setupapi/devclass.c b/dll/win32/setupapi/devclass.c index 5f88f40ab8..cc7446fdfd 100644 --- a/dll/win32/setupapi/devclass.c +++ b/dll/win32/setupapi/devclass.c @@ -1228,6 +1228,42 @@ SETUP_GetClassDevPropertySheetsCallback( return PropPageData->DontCancel; }
+static DWORD +SETUP_GetValueString( + IN HKEY hKey, + IN LPWSTR lpValueName, + OUT LPWSTR *lpString) +{ + LPWSTR lpBuffer; + DWORD dwLength = 0; + DWORD dwRegType; + DWORD rc; + + *lpString = NULL; + + RegQueryValueExW(hKey, lpValueName, NULL, &dwRegType, NULL, &dwLength); + + if (dwLength == 0 || dwRegType != REG_SZ) + return ERROR_FILE_NOT_FOUND; + + lpBuffer = HeapAlloc(GetProcessHeap(), 0, dwLength + sizeof(WCHAR)); + if (lpBuffer == NULL) + return ERROR_NOT_ENOUGH_MEMORY; + + rc = RegQueryValueExW(hKey, lpValueName, NULL, NULL, (LPBYTE)lpBuffer, &dwLength); + if (rc != ERROR_SUCCESS) + { + HeapFree(GetProcessHeap(), 0, lpBuffer); + return rc; + } + + lpBuffer[dwLength / sizeof(WCHAR)] = UNICODE_NULL; + + *lpString = lpBuffer; + + return ERROR_SUCCESS; +} + /*********************************************************************** * SetupDiGetClassDevPropertySheetsW(SETUPAPI.@) */ @@ -1240,7 +1276,8 @@ SetupDiGetClassDevPropertySheetsW( OUT PDWORD RequiredSize OPTIONAL, IN DWORD PropertySheetType) { - struct DeviceInfoSet *list; + struct DeviceInfoSet *devInfoSet = NULL; + struct DeviceInfo *devInfo = NULL; BOOL ret = FALSE;
TRACE("%p %p %p 0%lx %p 0x%lx\n", DeviceInfoSet, DeviceInfoData, @@ -1251,7 +1288,7 @@ SetupDiGetClassDevPropertySheetsW( SetLastError(ERROR_INVALID_HANDLE); else if (((struct DeviceInfoSet *)DeviceInfoSet)->magic != SETUP_DEVICE_INFO_SET_MAGIC) SetLastError(ERROR_INVALID_HANDLE); - else if ((list = (struct DeviceInfoSet *)DeviceInfoSet)->magic != SETUP_DEVICE_INFO_SET_MAGIC) + else if ((devInfoSet = (struct DeviceInfoSet *)DeviceInfoSet)->magic != SETUP_DEVICE_INFO_SET_MAGIC) SetLastError(ERROR_INVALID_HANDLE); else if (!PropertySheetHeader) SetLastError(ERROR_INVALID_PARAMETER); @@ -1259,7 +1296,7 @@ SetupDiGetClassDevPropertySheetsW( SetLastError(ERROR_INVALID_FLAGS); else if (DeviceInfoData && DeviceInfoData->cbSize != sizeof(SP_DEVINFO_DATA)) SetLastError(ERROR_INVALID_USER_BUFFER); - else if (!DeviceInfoData && IsEqualIID(&list->ClassGuid, &GUID_NULL)) + else if (!DeviceInfoData && IsEqualIID(&devInfoSet->ClassGuid, &GUID_NULL)) SetLastError(ERROR_INVALID_PARAMETER); else if (PropertySheetType != DIGCDP_FLAG_ADVANCED && PropertySheetType != DIGCDP_FLAG_BASIC @@ -1274,74 +1311,66 @@ SetupDiGetClassDevPropertySheetsW( HMODULE hModule = NULL; PROPERTY_PAGE_PROVIDER pPropPageProvider = NULL; struct ClassDevPropertySheetsData PropPageData; - DWORD dwLength, dwRegType; DWORD InitialNumberOfPages; DWORD rc;
if (DeviceInfoData) - hKey = SETUPDI_OpenDrvKey(list->HKLM, (struct DeviceInfo *)DeviceInfoData->Reserved, KEY_QUERY_VALUE); - else - { - hKey = SetupDiOpenClassRegKeyExW(&list->ClassGuid, KEY_QUERY_VALUE, - DIOCR_INSTALLER, list->MachineName + 2, NULL); - } - if (hKey == INVALID_HANDLE_VALUE) - goto cleanup; + devInfo = (struct DeviceInfo *)DeviceInfoData->Reserved;
- rc = RegQueryValueExW(hKey, REGSTR_VAL_ENUMPROPPAGES_32, NULL, &dwRegType, NULL, &dwLength); - if (rc == ERROR_FILE_NOT_FOUND) - { - /* No registry key. As it is optional, don't say it's a bad error */ - if (RequiredSize) - *RequiredSize = 0; - ret = TRUE; - goto cleanup; - } - else if (rc != ERROR_SUCCESS && dwRegType != REG_SZ) - { - SetLastError(rc); - goto cleanup; - } - - PropPageProvider = HeapAlloc(GetProcessHeap(), 0, dwLength + sizeof(WCHAR)); - if (!PropPageProvider) - { - SetLastError(ERROR_NOT_ENOUGH_MEMORY); - goto cleanup; - } - rc = RegQueryValueExW(hKey, REGSTR_VAL_ENUMPROPPAGES_32, NULL, NULL, (LPBYTE)PropPageProvider, &dwLength); - if (rc != ERROR_SUCCESS) + /* Get the class property page provider */ + if (devInfoSet->hmodClassPropPageProvider == NULL) { - SetLastError(rc); - goto cleanup; - } - PropPageProvider[dwLength / sizeof(WCHAR)] = 0; + hKey = SetupDiOpenClassRegKeyExW(devInfo ? &devInfo->ClassGuid : &devInfoSet->ClassGuid, KEY_QUERY_VALUE, + DIOCR_INSTALLER, NULL/*devInfoSet->MachineName + 2*/, NULL); + if (hKey != INVALID_HANDLE_VALUE) + { + rc = SETUP_GetValueString(hKey, REGSTR_VAL_ENUMPROPPAGES_32, &PropPageProvider); + if (rc == ERROR_SUCCESS) + { + rc = GetFunctionPointer(PropPageProvider, &hModule, (PVOID*)&pPropPageProvider); + if (rc != ERROR_SUCCESS) + { + SetLastError(ERROR_INVALID_PROPPAGE_PROVIDER); + goto cleanup; + }
- rc = GetFunctionPointer(PropPageProvider, &hModule, (PVOID*)&pPropPageProvider); - if (rc != ERROR_SUCCESS) - { - SetLastError(ERROR_INVALID_PROPPAGE_PROVIDER); - goto cleanup; - } + devInfoSet->hmodClassPropPageProvider = hModule; + devInfoSet->pClassPropPageProvider = pPropPageProvider;
- if (DeviceInfoData) - { - struct DeviceInfo *devInfo = (struct DeviceInfo *)DeviceInfoData->Reserved; + HeapFree(GetProcessHeap(), 0, PropPageProvider); + PropPageProvider = NULL; + }
- if (devInfo->hmodDevicePropPageProvider == NULL) - { - devInfo->hmodDevicePropPageProvider = hModule; - devInfo->pDevicePropPageProvider = pPropPageProvider; + RegCloseKey(hKey); + hKey = INVALID_HANDLE_VALUE; } } - else - { - struct DeviceInfoSet *devInfoSet = (struct DeviceInfoSet *)DeviceInfoSet;
- if (devInfoSet->hmodClassPropPageProvider == NULL) + /* Get the device property page provider */ + if (devInfo != NULL && devInfo->hmodDevicePropPageProvider == NULL) + { + hKey = SETUPDI_OpenDrvKey(devInfoSet->HKLM, devInfo, KEY_QUERY_VALUE); + if (hKey != INVALID_HANDLE_VALUE) { - devInfoSet->hmodClassPropPageProvider = hModule; - devInfoSet->pClassPropPageProvider = pPropPageProvider; + rc = SETUP_GetValueString(hKey, REGSTR_VAL_ENUMPROPPAGES_32, &PropPageProvider); + if (rc == ERROR_SUCCESS) + { + rc = GetFunctionPointer(PropPageProvider, &hModule, (PVOID*)&pPropPageProvider); + if (rc != ERROR_SUCCESS) + { + SetLastError(ERROR_INVALID_PROPPAGE_PROVIDER); + goto cleanup; + } + + devInfo->hmodDevicePropPageProvider = hModule; + devInfo->pDevicePropPageProvider = pPropPageProvider; + + HeapFree(GetProcessHeap(), 0, PropPageProvider); + PropPageProvider = NULL; + } + + RegCloseKey(hKey); + hKey = INVALID_HANDLE_VALUE; } }
@@ -1357,7 +1386,13 @@ SetupDiGetClassDevPropertySheetsW( PropPageData.NumberOfPages = 0; PropPageData.DontCancel = (RequiredSize != NULL) ? TRUE : FALSE;
- pPropPageProvider(&Request, SETUP_GetClassDevPropertySheetsCallback, (LPARAM)&PropPageData); + /* Call the class property page provider */ + if (devInfoSet->pClassPropPageProvider != NULL) + ((PROPERTY_PAGE_PROVIDER)devInfoSet->pClassPropPageProvider)(&Request, SETUP_GetClassDevPropertySheetsCallback, (LPARAM)&PropPageData); + + /* Call the device property page provider */ + if (devInfo != NULL && devInfo->pDevicePropPageProvider != NULL) + ((PROPERTY_PAGE_PROVIDER)devInfo->pDevicePropPageProvider)(&Request, SETUP_GetClassDevPropertySheetsCallback, (LPARAM)&PropPageData);
if (RequiredSize) *RequiredSize = PropPageData.NumberOfPages; @@ -1374,7 +1409,9 @@ SetupDiGetClassDevPropertySheetsW( cleanup: if (hKey != INVALID_HANDLE_VALUE) RegCloseKey(hKey); - HeapFree(GetProcessHeap(), 0, PropPageProvider); + + if (PropPageProvider != NULL) + HeapFree(GetProcessHeap(), 0, PropPageProvider); }
TRACE("Returning %d\n", ret);