mirror of
https://github.com/reactos/reactos.git
synced 2025-07-31 18:22:35 +00:00
Implement DICS_FLAG_CONFIGSPECIFIC case in SetupDiOpenDevRegKey, by factorizing some code from SetupDiCreateDevRegKeyW to OpenHardwareProfileKey
Don't ask for KEY_ENUMERATE_SUB_KEYS access right when not needed Implemenent internal function ResetDevice() svn path=/trunk/; revision=20203
This commit is contained in:
parent
9f88e7a94b
commit
4ce3d5c9e8
1 changed files with 194 additions and 143 deletions
|
@ -1619,10 +1619,10 @@ static LONG SETUP_CreateInterfaceList(
|
|||
|
||||
/* Find class GUID associated to the device instance */
|
||||
rc = RegOpenKeyExW(
|
||||
HKEY_LOCAL_MACHINE,
|
||||
list->HKLM,
|
||||
REGSTR_PATH_SYSTEMENUM,
|
||||
0, /* Options */
|
||||
KEY_ENUMERATE_SUB_KEYS,
|
||||
0,
|
||||
&hEnumKey);
|
||||
if (rc != ERROR_SUCCESS)
|
||||
{
|
||||
|
@ -2670,7 +2670,7 @@ BOOL WINAPI SetupDiGetDeviceRegistryPropertyW(
|
|||
list->HKLM,
|
||||
REGSTR_PATH_SYSTEMENUM,
|
||||
0, /* Options */
|
||||
KEY_ENUMERATE_SUB_KEYS,
|
||||
0,
|
||||
&hEnumKey);
|
||||
if (rc != ERROR_SUCCESS)
|
||||
{
|
||||
|
@ -3198,7 +3198,7 @@ HKEY WINAPI SetupDiOpenClassRegKeyExW(
|
|||
rc = RegOpenKeyExW(HKLM,
|
||||
lpKeyName,
|
||||
0,
|
||||
ClassGuid ? KEY_ENUMERATE_SUB_KEYS : samDesired,
|
||||
ClassGuid ? 0 : samDesired,
|
||||
&hClassesKey);
|
||||
if (MachineName != NULL) RegCloseKey(HKLM);
|
||||
if (rc != ERROR_SUCCESS)
|
||||
|
@ -4304,6 +4304,63 @@ HKEY WINAPI SetupDiCreateDevRegKeyA(
|
|||
return ret;
|
||||
}
|
||||
|
||||
static HKEY
|
||||
OpenHardwareProfileKey(
|
||||
IN HKEY HKLM,
|
||||
IN DWORD HwProfile,
|
||||
IN DWORD samDesired)
|
||||
{
|
||||
HKEY hHWProfilesKey = INVALID_HANDLE_VALUE;
|
||||
HKEY hHWProfileKey = INVALID_HANDLE_VALUE;
|
||||
HKEY ret = INVALID_HANDLE_VALUE;
|
||||
LONG rc;
|
||||
|
||||
rc = RegOpenKeyExW(HKLM,
|
||||
REGSTR_PATH_HWPROFILES,
|
||||
0,
|
||||
0,
|
||||
&hHWProfilesKey);
|
||||
if (rc != ERROR_SUCCESS)
|
||||
{
|
||||
SetLastError(rc);
|
||||
goto cleanup;
|
||||
}
|
||||
if (HwProfile == 0)
|
||||
{
|
||||
rc = RegOpenKeyExW(
|
||||
hHWProfilesKey,
|
||||
REGSTR_KEY_CURRENT,
|
||||
0,
|
||||
KEY_CREATE_SUB_KEY,
|
||||
&hHWProfileKey);
|
||||
}
|
||||
else
|
||||
{
|
||||
WCHAR subKey[5];
|
||||
snprintfW(subKey, 4, L"%04lu", HwProfile);
|
||||
subKey[4] = '\0';
|
||||
rc = RegOpenKeyExW(
|
||||
hHWProfilesKey,
|
||||
subKey,
|
||||
0,
|
||||
KEY_CREATE_SUB_KEY,
|
||||
&hHWProfileKey);
|
||||
}
|
||||
if (rc != ERROR_SUCCESS)
|
||||
{
|
||||
SetLastError(rc);
|
||||
goto cleanup;
|
||||
}
|
||||
ret = hHWProfileKey;
|
||||
|
||||
cleanup:
|
||||
if (hHWProfilesKey != INVALID_HANDLE_VALUE)
|
||||
RegCloseKey(hHWProfilesKey);
|
||||
if (hHWProfileKey != INVALID_HANDLE_VALUE && hHWProfileKey != ret)
|
||||
RegCloseKey(hHWProfileKey);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* SetupDiCreateDevRegKeyW (SETUPAPI.@)
|
||||
*/
|
||||
|
@ -4345,7 +4402,6 @@ HKEY WINAPI SetupDiCreateDevRegKeyW(
|
|||
LPWSTR pDeviceInstance; /* Points into DriverKey, on the Index field */
|
||||
DWORD Index; /* Index used in the DriverKey name */
|
||||
DWORD rc;
|
||||
HKEY hHWProfilesKey = INVALID_HANDLE_VALUE;
|
||||
HKEY hHWProfileKey = INVALID_HANDLE_VALUE;
|
||||
HKEY hEnumKey = INVALID_HANDLE_VALUE;
|
||||
HKEY hClassKey = INVALID_HANDLE_VALUE;
|
||||
|
@ -4357,42 +4413,9 @@ HKEY WINAPI SetupDiCreateDevRegKeyW(
|
|||
RootKey = list->HKLM;
|
||||
else /* Scope == DICS_FLAG_CONFIGSPECIFIC */
|
||||
{
|
||||
rc = RegOpenKeyExW(list->HKLM,
|
||||
REGSTR_PATH_HWPROFILES,
|
||||
0,
|
||||
0,
|
||||
&hHWProfilesKey);
|
||||
if (rc != ERROR_SUCCESS)
|
||||
{
|
||||
SetLastError(rc);
|
||||
hHWProfileKey = OpenHardwareProfileKey(list->HKLM, HwProfile, KEY_CREATE_SUB_KEY);
|
||||
if (hHWProfileKey == INVALID_HANDLE_VALUE)
|
||||
goto cleanup;
|
||||
}
|
||||
if (HwProfile == 0)
|
||||
{
|
||||
rc = RegOpenKeyExW(
|
||||
hHWProfilesKey,
|
||||
REGSTR_KEY_CURRENT,
|
||||
0,
|
||||
KEY_CREATE_SUB_KEY,
|
||||
&hHWProfileKey);
|
||||
}
|
||||
else
|
||||
{
|
||||
WCHAR subKey[5];
|
||||
snprintfW(subKey, 4, L"%04lu", HwProfile);
|
||||
subKey[4] = '\0';
|
||||
rc = RegOpenKeyExW(
|
||||
hHWProfilesKey,
|
||||
subKey,
|
||||
0,
|
||||
KEY_CREATE_SUB_KEY,
|
||||
&hHWProfileKey);
|
||||
}
|
||||
if (rc != ERROR_SUCCESS)
|
||||
{
|
||||
SetLastError(rc);
|
||||
goto cleanup;
|
||||
}
|
||||
RootKey = hHWProfileKey;
|
||||
}
|
||||
|
||||
|
@ -4522,8 +4545,6 @@ cleanup:
|
|||
if (lpGuidString)
|
||||
RpcStringFreeW(&lpGuidString);
|
||||
HeapFree(GetProcessHeap(), 0, DriverKey);
|
||||
if (hHWProfilesKey != INVALID_HANDLE_VALUE)
|
||||
RegCloseKey(hHWProfilesKey);
|
||||
if (hHWProfileKey != INVALID_HANDLE_VALUE)
|
||||
RegCloseKey(hHWProfileKey);
|
||||
if (hEnumKey != INVALID_HANDLE_VALUE)
|
||||
|
@ -4571,104 +4592,113 @@ HKEY WINAPI SetupDiOpenDevRegKey(
|
|||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
else
|
||||
{
|
||||
HKEY hKey = INVALID_HANDLE_VALUE;
|
||||
HKEY hRootKey = INVALID_HANDLE_VALUE;
|
||||
struct DeviceInfoElement *deviceInfo = (struct DeviceInfoElement *)DeviceInfoData->Reserved;
|
||||
LPWSTR DriverKey = NULL;
|
||||
DWORD dwLength = 0;
|
||||
DWORD dwRegType;
|
||||
DWORD rc;
|
||||
HKEY hHWProfileKey = INVALID_HANDLE_VALUE;
|
||||
HKEY hEnumKey = INVALID_HANDLE_VALUE;
|
||||
HKEY hKey = INVALID_HANDLE_VALUE;
|
||||
HKEY RootKey;
|
||||
|
||||
if (Scope == DICS_FLAG_CONFIGSPECIFIC)
|
||||
if (Scope == DICS_FLAG_GLOBAL)
|
||||
RootKey = list->HKLM;
|
||||
else /* Scope == DICS_FLAG_CONFIGSPECIFIC */
|
||||
{
|
||||
FIXME("DICS_FLAG_CONFIGSPECIFIC case unimplemented\n");
|
||||
hHWProfileKey = OpenHardwareProfileKey(list->HKLM, HwProfile, 0);
|
||||
if (hHWProfileKey == INVALID_HANDLE_VALUE)
|
||||
goto cleanup;
|
||||
RootKey = hHWProfileKey;
|
||||
}
|
||||
else /* Scope == DICS_FLAG_GLOBAL */
|
||||
|
||||
rc = RegOpenKeyExW(
|
||||
RootKey,
|
||||
REGSTR_PATH_SYSTEMENUM,
|
||||
0, /* Options */
|
||||
0,
|
||||
&hEnumKey);
|
||||
if (rc != ERROR_SUCCESS)
|
||||
{
|
||||
rc = RegOpenKeyExW(
|
||||
list->HKLM,
|
||||
REGSTR_PATH_SYSTEMENUM,
|
||||
0, /* Options */
|
||||
KEY_ENUMERATE_SUB_KEYS,
|
||||
&hRootKey);
|
||||
if (rc != ERROR_SUCCESS)
|
||||
{
|
||||
SetLastError(rc);
|
||||
goto cleanup;
|
||||
}
|
||||
rc = RegOpenKeyExW(
|
||||
hRootKey,
|
||||
deviceInfo->DeviceName,
|
||||
0, /* Options */
|
||||
KeyType == DIREG_DEV ? samDesired : KEY_QUERY_VALUE,
|
||||
&hKey);
|
||||
RegCloseKey(hRootKey);
|
||||
hRootKey = INVALID_HANDLE_VALUE;
|
||||
if (rc != ERROR_SUCCESS)
|
||||
{
|
||||
SetLastError(rc);
|
||||
goto cleanup;
|
||||
}
|
||||
if (KeyType == DIREG_DEV)
|
||||
{
|
||||
/* We're done. Just return the hKey handle */
|
||||
ret = hKey;
|
||||
goto cleanup;
|
||||
}
|
||||
/* Read the 'Driver' key */
|
||||
rc = RegQueryValueExW(hKey, REGSTR_VAL_DRIVER, NULL, &dwRegType, NULL, &dwLength);
|
||||
if (rc != ERROR_SUCCESS)
|
||||
{
|
||||
SetLastError(rc);
|
||||
goto cleanup;
|
||||
}
|
||||
if (dwRegType != REG_SZ)
|
||||
{
|
||||
SetLastError(ERROR_GEN_FAILURE);
|
||||
goto cleanup;
|
||||
}
|
||||
DriverKey = HeapAlloc(GetProcessHeap(), 0, dwLength);
|
||||
if (!DriverKey)
|
||||
{
|
||||
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
||||
goto cleanup;
|
||||
}
|
||||
rc = RegQueryValueExW(hKey, REGSTR_VAL_DRIVER, NULL, &dwRegType, (LPBYTE)DriverKey, &dwLength);
|
||||
if (rc != ERROR_SUCCESS)
|
||||
{
|
||||
SetLastError(rc);
|
||||
goto cleanup;
|
||||
}
|
||||
RegCloseKey(hKey);
|
||||
hKey = INVALID_HANDLE_VALUE;
|
||||
/* Need to open the driver key */
|
||||
rc = RegOpenKeyExW(
|
||||
list->HKLM,
|
||||
REGSTR_PATH_CLASS_NT,
|
||||
0, /* Options */
|
||||
KEY_ENUMERATE_SUB_KEYS,
|
||||
&hRootKey);
|
||||
if (rc != ERROR_SUCCESS)
|
||||
{
|
||||
SetLastError(rc);
|
||||
goto cleanup;
|
||||
}
|
||||
rc = RegOpenKeyExW(
|
||||
hRootKey,
|
||||
DriverKey,
|
||||
0, /* Options */
|
||||
samDesired,
|
||||
&hKey);
|
||||
if (rc != ERROR_SUCCESS)
|
||||
{
|
||||
SetLastError(rc);
|
||||
goto cleanup;
|
||||
}
|
||||
SetLastError(rc);
|
||||
goto cleanup;
|
||||
}
|
||||
rc = RegOpenKeyExW(
|
||||
hEnumKey,
|
||||
deviceInfo->DeviceName,
|
||||
0, /* Options */
|
||||
KeyType == DIREG_DEV ? samDesired : KEY_QUERY_VALUE,
|
||||
&hKey);
|
||||
RegCloseKey(hEnumKey);
|
||||
hEnumKey = INVALID_HANDLE_VALUE;
|
||||
if (rc != ERROR_SUCCESS)
|
||||
{
|
||||
SetLastError(rc);
|
||||
goto cleanup;
|
||||
}
|
||||
if (KeyType == DIREG_DEV)
|
||||
{
|
||||
/* We're done. Just return the hKey handle */
|
||||
CHECKPOINT1;
|
||||
ret = hKey;
|
||||
goto cleanup;
|
||||
}
|
||||
/* Read the 'Driver' key */
|
||||
rc = RegQueryValueExW(hKey, REGSTR_VAL_DRIVER, NULL, &dwRegType, NULL, &dwLength);
|
||||
if (rc != ERROR_SUCCESS)
|
||||
{
|
||||
SetLastError(rc);
|
||||
goto cleanup;
|
||||
}
|
||||
else if (dwRegType != REG_SZ)
|
||||
{
|
||||
SetLastError(ERROR_GEN_FAILURE);
|
||||
goto cleanup;
|
||||
}
|
||||
DriverKey = HeapAlloc(GetProcessHeap(), 0, dwLength);
|
||||
if (!DriverKey)
|
||||
{
|
||||
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
||||
goto cleanup;
|
||||
}
|
||||
rc = RegQueryValueExW(hKey, REGSTR_VAL_DRIVER, NULL, &dwRegType, (LPBYTE)DriverKey, &dwLength);
|
||||
if (rc != ERROR_SUCCESS)
|
||||
{
|
||||
SetLastError(rc);
|
||||
goto cleanup;
|
||||
}
|
||||
RegCloseKey(hKey);
|
||||
hKey = INVALID_HANDLE_VALUE;
|
||||
/* Need to open the driver key */
|
||||
rc = RegOpenKeyExW(
|
||||
RootKey,
|
||||
REGSTR_PATH_CLASS_NT,
|
||||
0, /* Options */
|
||||
0,
|
||||
&hEnumKey);
|
||||
if (rc != ERROR_SUCCESS)
|
||||
{
|
||||
SetLastError(rc);
|
||||
goto cleanup;
|
||||
}
|
||||
rc = RegOpenKeyExW(
|
||||
hEnumKey,
|
||||
DriverKey,
|
||||
0, /* Options */
|
||||
samDesired,
|
||||
&hKey);
|
||||
if (rc != ERROR_SUCCESS)
|
||||
{
|
||||
SetLastError(rc);
|
||||
goto cleanup;
|
||||
}
|
||||
ret = hKey;
|
||||
|
||||
cleanup:
|
||||
if (hRootKey != INVALID_HANDLE_VALUE)
|
||||
RegCloseKey(hRootKey);
|
||||
if (hHWProfileKey != INVALID_HANDLE_VALUE)
|
||||
RegCloseKey(hHWProfileKey);
|
||||
if (hEnumKey != INVALID_HANDLE_VALUE)
|
||||
RegCloseKey(hEnumKey);
|
||||
if (hKey != INVALID_HANDLE_VALUE && hKey != ret)
|
||||
RegCloseKey(hKey);
|
||||
}
|
||||
|
@ -5717,7 +5747,7 @@ SetupDiOpenDeviceInfoW(
|
|||
list->HKLM,
|
||||
REGSTR_PATH_SYSTEMENUM,
|
||||
0, /* Options */
|
||||
KEY_ENUMERATE_SUB_KEYS,
|
||||
0,
|
||||
&hEnumKey);
|
||||
if (rc != ERROR_SUCCESS)
|
||||
{
|
||||
|
@ -6461,11 +6491,39 @@ cleanup:
|
|||
return hwProfile;
|
||||
}
|
||||
|
||||
static BOOL
|
||||
ResetDevice(
|
||||
IN HDEVINFO DeviceInfoSet,
|
||||
IN PSP_DEVINFO_DATA DeviceInfoData)
|
||||
{
|
||||
PLUGPLAY_CONTROL_RESET_DEVICE_DATA ResetDeviceData;
|
||||
struct DeviceInfoElement *deviceInfo = (struct DeviceInfoElement *)DeviceInfoData->Reserved;
|
||||
NTSTATUS Status;
|
||||
|
||||
if (((struct DeviceInfoSet *)DeviceInfoSet)->HKLM != HKEY_LOCAL_MACHINE)
|
||||
{
|
||||
/* At the moment, I only know how to start local devices */
|
||||
SetLastError(ERROR_INVALID_COMPUTERNAME);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
RtlInitUnicodeString(&ResetDeviceData.DeviceInstance, deviceInfo->DeviceName);
|
||||
Status = NtPlugPlayControl(PlugPlayControlResetDevice, &ResetDeviceData, sizeof(PLUGPLAY_CONTROL_RESET_DEVICE_DATA));
|
||||
SetLastError(RtlNtStatusToDosError(Status));
|
||||
return NT_SUCCESS(Status);
|
||||
}
|
||||
|
||||
static BOOL StopDevice(
|
||||
IN HDEVINFO DeviceInfoSet,
|
||||
IN PSP_DEVINFO_DATA DeviceInfoData)
|
||||
{
|
||||
FIXME("Stub %p %p\n", DeviceInfoSet, DeviceInfoData);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* SetupDiChangeState (SETUPAPI.@)
|
||||
*/
|
||||
static BOOL StartDevice(VOID) { FIXME("Stub"); return TRUE; }
|
||||
static BOOL StopDevice(VOID) { FIXME("Stub"); return TRUE; }
|
||||
BOOL WINAPI
|
||||
SetupDiChangeState(
|
||||
IN HDEVINFO DeviceInfoSet,
|
||||
|
@ -6503,7 +6561,7 @@ SetupDiChangeState(
|
|||
/* Enable/disable device in registry */
|
||||
hKey = SetupDiOpenDevRegKey(DeviceInfoSet, DeviceInfoData, PropChange->Scope, PropChange->HwProfile, DIREG_DEV, KEY_QUERY_VALUE | KEY_SET_VALUE);
|
||||
if (hKey == INVALID_HANDLE_VALUE && GetLastError() == ERROR_FILE_NOT_FOUND)
|
||||
hKey = SetupDiCreateDevRegKey(DeviceInfoSet, DeviceInfoData, PropChange->Scope, PropChange->HwProfile, DIREG_DEV, NULL, NULL);
|
||||
hKey = SetupDiCreateDevRegKeyW(DeviceInfoSet, DeviceInfoData, PropChange->Scope, PropChange->HwProfile, DIREG_DEV, NULL, NULL);
|
||||
if (hKey == INVALID_HANDLE_VALUE)
|
||||
break;
|
||||
dwLength = sizeof(DWORD);
|
||||
|
@ -6547,9 +6605,9 @@ SetupDiChangeState(
|
|||
|| PropChange->HwProfile == GetCurrentHwProfile(DeviceInfoSet))
|
||||
{
|
||||
if (PropChange->StateChange == DICS_ENABLE)
|
||||
ret = StartDevice();
|
||||
ret = ResetDevice(DeviceInfoSet, DeviceInfoData);
|
||||
else
|
||||
ret = StopDevice();
|
||||
ret = StopDevice(DeviceInfoSet, DeviceInfoData);
|
||||
}
|
||||
else
|
||||
ret = TRUE;
|
||||
|
@ -6557,7 +6615,7 @@ SetupDiChangeState(
|
|||
}
|
||||
case DICS_PROPCHANGE:
|
||||
{
|
||||
ret = StopDevice() && StartDevice();
|
||||
ret = ResetDevice(DeviceInfoSet, DeviceInfoData);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
@ -6837,7 +6895,6 @@ SetupDiInstallDevice(
|
|||
IN HDEVINFO DeviceInfoSet,
|
||||
IN PSP_DEVINFO_DATA DeviceInfoData)
|
||||
{
|
||||
struct DeviceInfoElement *DevInfo = (struct DeviceInfoElement *)DeviceInfoData->Reserved;
|
||||
SP_DEVINSTALL_PARAMS_W InstallParams;
|
||||
struct DriverInfoElement *SelectedDriver;
|
||||
SYSTEMTIME DriverDate;
|
||||
|
@ -7166,13 +7223,7 @@ nextservice:
|
|||
|
||||
/* Start the device */
|
||||
if (!RebootRequired && !(InstallParams.Flags & (DI_NEEDRESTART | DI_NEEDREBOOT | DI_DONOTCALLCONFIGMG)))
|
||||
{
|
||||
PLUGPLAY_CONTROL_RESET_DEVICE_DATA ResetDeviceData;
|
||||
NTSTATUS Status;
|
||||
RtlInitUnicodeString(&ResetDeviceData.DeviceInstance, DevInfo->DeviceName);
|
||||
Status = NtPlugPlayControl(PlugPlayControlResetDevice, &ResetDeviceData, sizeof(PLUGPLAY_CONTROL_RESET_DEVICE_DATA));
|
||||
ret = NT_SUCCESS(Status);
|
||||
}
|
||||
ret = ResetDevice(DeviceInfoSet, DeviceInfoData);
|
||||
else
|
||||
ret = TRUE;
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue