[SETUPAPI] SetupDiGetClassDevPropertySheetsW: Support class property sheet providers.

This commit is contained in:
Eric Kohl 2018-09-26 23:42:00 +02:00
parent 68c6641781
commit 986ce63c4c

View file

@ -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)
/* Get the class property page provider */
if (devInfoSet->hmodClassPropPageProvider == NULL)
{
/* 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)
{
SetLastError(rc);
goto cleanup;
}
PropPageProvider[dwLength / sizeof(WCHAR)] = 0;
rc = GetFunctionPointer(PropPageProvider, &hModule, (PVOID*)&pPropPageProvider);
if (rc != ERROR_SUCCESS)
{
SetLastError(ERROR_INVALID_PROPPAGE_PROVIDER);
goto cleanup;
}
if (DeviceInfoData)
{
struct DeviceInfo *devInfo = (struct DeviceInfo *)DeviceInfoData->Reserved;
if (devInfo->hmodDevicePropPageProvider == NULL)
hKey = SetupDiOpenClassRegKeyExW(devInfo ? &devInfo->ClassGuid : &devInfoSet->ClassGuid, KEY_QUERY_VALUE,
DIOCR_INSTALLER, NULL/*devInfoSet->MachineName + 2*/, NULL);
if (hKey != INVALID_HANDLE_VALUE)
{
devInfo->hmodDevicePropPageProvider = hModule;
devInfo->pDevicePropPageProvider = 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;
}
devInfoSet->hmodClassPropPageProvider = hModule;
devInfoSet->pClassPropPageProvider = pPropPageProvider;
HeapFree(GetProcessHeap(), 0, PropPageProvider);
PropPageProvider = NULL;
}
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);