https://git.reactos.org/?p=reactos.git;a=commitdiff;h=986ce63c4c17e354c56aa…
commit 986ce63c4c17e354c56aab068be87d32bbadb653
Author: Eric Kohl <eric.kohl(a)reactos.org>
AuthorDate: Wed Sep 26 23:42:00 2018 +0200
Commit: Eric Kohl <eric.kohl(a)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);