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:
Hervé Poussineau 2005-12-15 23:24:43 +00:00
parent 9f88e7a94b
commit 4ce3d5c9e8

View file

@ -1619,10 +1619,10 @@ static LONG SETUP_CreateInterfaceList(
/* Find class GUID associated to the device instance */ /* Find class GUID associated to the device instance */
rc = RegOpenKeyExW( rc = RegOpenKeyExW(
HKEY_LOCAL_MACHINE, list->HKLM,
REGSTR_PATH_SYSTEMENUM, REGSTR_PATH_SYSTEMENUM,
0, /* Options */ 0, /* Options */
KEY_ENUMERATE_SUB_KEYS, 0,
&hEnumKey); &hEnumKey);
if (rc != ERROR_SUCCESS) if (rc != ERROR_SUCCESS)
{ {
@ -2670,7 +2670,7 @@ BOOL WINAPI SetupDiGetDeviceRegistryPropertyW(
list->HKLM, list->HKLM,
REGSTR_PATH_SYSTEMENUM, REGSTR_PATH_SYSTEMENUM,
0, /* Options */ 0, /* Options */
KEY_ENUMERATE_SUB_KEYS, 0,
&hEnumKey); &hEnumKey);
if (rc != ERROR_SUCCESS) if (rc != ERROR_SUCCESS)
{ {
@ -3198,7 +3198,7 @@ HKEY WINAPI SetupDiOpenClassRegKeyExW(
rc = RegOpenKeyExW(HKLM, rc = RegOpenKeyExW(HKLM,
lpKeyName, lpKeyName,
0, 0,
ClassGuid ? KEY_ENUMERATE_SUB_KEYS : samDesired, ClassGuid ? 0 : samDesired,
&hClassesKey); &hClassesKey);
if (MachineName != NULL) RegCloseKey(HKLM); if (MachineName != NULL) RegCloseKey(HKLM);
if (rc != ERROR_SUCCESS) if (rc != ERROR_SUCCESS)
@ -4304,6 +4304,63 @@ HKEY WINAPI SetupDiCreateDevRegKeyA(
return ret; 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.@) * SetupDiCreateDevRegKeyW (SETUPAPI.@)
*/ */
@ -4345,7 +4402,6 @@ HKEY WINAPI SetupDiCreateDevRegKeyW(
LPWSTR pDeviceInstance; /* Points into DriverKey, on the Index field */ LPWSTR pDeviceInstance; /* Points into DriverKey, on the Index field */
DWORD Index; /* Index used in the DriverKey name */ DWORD Index; /* Index used in the DriverKey name */
DWORD rc; DWORD rc;
HKEY hHWProfilesKey = INVALID_HANDLE_VALUE;
HKEY hHWProfileKey = INVALID_HANDLE_VALUE; HKEY hHWProfileKey = INVALID_HANDLE_VALUE;
HKEY hEnumKey = INVALID_HANDLE_VALUE; HKEY hEnumKey = INVALID_HANDLE_VALUE;
HKEY hClassKey = INVALID_HANDLE_VALUE; HKEY hClassKey = INVALID_HANDLE_VALUE;
@ -4357,42 +4413,9 @@ HKEY WINAPI SetupDiCreateDevRegKeyW(
RootKey = list->HKLM; RootKey = list->HKLM;
else /* Scope == DICS_FLAG_CONFIGSPECIFIC */ else /* Scope == DICS_FLAG_CONFIGSPECIFIC */
{ {
rc = RegOpenKeyExW(list->HKLM, hHWProfileKey = OpenHardwareProfileKey(list->HKLM, HwProfile, KEY_CREATE_SUB_KEY);
REGSTR_PATH_HWPROFILES, if (hHWProfileKey == INVALID_HANDLE_VALUE)
0,
0,
&hHWProfilesKey);
if (rc != ERROR_SUCCESS)
{
SetLastError(rc);
goto cleanup; 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; RootKey = hHWProfileKey;
} }
@ -4522,8 +4545,6 @@ cleanup:
if (lpGuidString) if (lpGuidString)
RpcStringFreeW(&lpGuidString); RpcStringFreeW(&lpGuidString);
HeapFree(GetProcessHeap(), 0, DriverKey); HeapFree(GetProcessHeap(), 0, DriverKey);
if (hHWProfilesKey != INVALID_HANDLE_VALUE)
RegCloseKey(hHWProfilesKey);
if (hHWProfileKey != INVALID_HANDLE_VALUE) if (hHWProfileKey != INVALID_HANDLE_VALUE)
RegCloseKey(hHWProfileKey); RegCloseKey(hHWProfileKey);
if (hEnumKey != INVALID_HANDLE_VALUE) if (hEnumKey != INVALID_HANDLE_VALUE)
@ -4571,39 +4592,45 @@ HKEY WINAPI SetupDiOpenDevRegKey(
SetLastError(ERROR_INVALID_PARAMETER); SetLastError(ERROR_INVALID_PARAMETER);
else else
{ {
HKEY hKey = INVALID_HANDLE_VALUE;
HKEY hRootKey = INVALID_HANDLE_VALUE;
struct DeviceInfoElement *deviceInfo = (struct DeviceInfoElement *)DeviceInfoData->Reserved; struct DeviceInfoElement *deviceInfo = (struct DeviceInfoElement *)DeviceInfoData->Reserved;
LPWSTR DriverKey = NULL; LPWSTR DriverKey = NULL;
DWORD dwLength = 0; DWORD dwLength = 0;
DWORD dwRegType; DWORD dwRegType;
DWORD rc; 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( rc = RegOpenKeyExW(
list->HKLM, RootKey,
REGSTR_PATH_SYSTEMENUM, REGSTR_PATH_SYSTEMENUM,
0, /* Options */ 0, /* Options */
KEY_ENUMERATE_SUB_KEYS, 0,
&hRootKey); &hEnumKey);
if (rc != ERROR_SUCCESS) if (rc != ERROR_SUCCESS)
{ {
SetLastError(rc); SetLastError(rc);
goto cleanup; goto cleanup;
} }
rc = RegOpenKeyExW( rc = RegOpenKeyExW(
hRootKey, hEnumKey,
deviceInfo->DeviceName, deviceInfo->DeviceName,
0, /* Options */ 0, /* Options */
KeyType == DIREG_DEV ? samDesired : KEY_QUERY_VALUE, KeyType == DIREG_DEV ? samDesired : KEY_QUERY_VALUE,
&hKey); &hKey);
RegCloseKey(hRootKey); RegCloseKey(hEnumKey);
hRootKey = INVALID_HANDLE_VALUE; hEnumKey = INVALID_HANDLE_VALUE;
if (rc != ERROR_SUCCESS) if (rc != ERROR_SUCCESS)
{ {
SetLastError(rc); SetLastError(rc);
@ -4612,6 +4639,7 @@ HKEY WINAPI SetupDiOpenDevRegKey(
if (KeyType == DIREG_DEV) if (KeyType == DIREG_DEV)
{ {
/* We're done. Just return the hKey handle */ /* We're done. Just return the hKey handle */
CHECKPOINT1;
ret = hKey; ret = hKey;
goto cleanup; goto cleanup;
} }
@ -4622,7 +4650,7 @@ HKEY WINAPI SetupDiOpenDevRegKey(
SetLastError(rc); SetLastError(rc);
goto cleanup; goto cleanup;
} }
if (dwRegType != REG_SZ) else if (dwRegType != REG_SZ)
{ {
SetLastError(ERROR_GEN_FAILURE); SetLastError(ERROR_GEN_FAILURE);
goto cleanup; goto cleanup;
@ -4643,18 +4671,18 @@ HKEY WINAPI SetupDiOpenDevRegKey(
hKey = INVALID_HANDLE_VALUE; hKey = INVALID_HANDLE_VALUE;
/* Need to open the driver key */ /* Need to open the driver key */
rc = RegOpenKeyExW( rc = RegOpenKeyExW(
list->HKLM, RootKey,
REGSTR_PATH_CLASS_NT, REGSTR_PATH_CLASS_NT,
0, /* Options */ 0, /* Options */
KEY_ENUMERATE_SUB_KEYS, 0,
&hRootKey); &hEnumKey);
if (rc != ERROR_SUCCESS) if (rc != ERROR_SUCCESS)
{ {
SetLastError(rc); SetLastError(rc);
goto cleanup; goto cleanup;
} }
rc = RegOpenKeyExW( rc = RegOpenKeyExW(
hRootKey, hEnumKey,
DriverKey, DriverKey,
0, /* Options */ 0, /* Options */
samDesired, samDesired,
@ -4665,10 +4693,12 @@ HKEY WINAPI SetupDiOpenDevRegKey(
goto cleanup; goto cleanup;
} }
ret = hKey; ret = hKey;
}
cleanup: cleanup:
if (hRootKey != INVALID_HANDLE_VALUE) if (hHWProfileKey != INVALID_HANDLE_VALUE)
RegCloseKey(hRootKey); RegCloseKey(hHWProfileKey);
if (hEnumKey != INVALID_HANDLE_VALUE)
RegCloseKey(hEnumKey);
if (hKey != INVALID_HANDLE_VALUE && hKey != ret) if (hKey != INVALID_HANDLE_VALUE && hKey != ret)
RegCloseKey(hKey); RegCloseKey(hKey);
} }
@ -5717,7 +5747,7 @@ SetupDiOpenDeviceInfoW(
list->HKLM, list->HKLM,
REGSTR_PATH_SYSTEMENUM, REGSTR_PATH_SYSTEMENUM,
0, /* Options */ 0, /* Options */
KEY_ENUMERATE_SUB_KEYS, 0,
&hEnumKey); &hEnumKey);
if (rc != ERROR_SUCCESS) if (rc != ERROR_SUCCESS)
{ {
@ -6461,11 +6491,39 @@ cleanup:
return hwProfile; 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.@) * SetupDiChangeState (SETUPAPI.@)
*/ */
static BOOL StartDevice(VOID) { FIXME("Stub"); return TRUE; }
static BOOL StopDevice(VOID) { FIXME("Stub"); return TRUE; }
BOOL WINAPI BOOL WINAPI
SetupDiChangeState( SetupDiChangeState(
IN HDEVINFO DeviceInfoSet, IN HDEVINFO DeviceInfoSet,
@ -6503,7 +6561,7 @@ SetupDiChangeState(
/* Enable/disable device in registry */ /* Enable/disable device in registry */
hKey = SetupDiOpenDevRegKey(DeviceInfoSet, DeviceInfoData, PropChange->Scope, PropChange->HwProfile, DIREG_DEV, KEY_QUERY_VALUE | KEY_SET_VALUE); 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) 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) if (hKey == INVALID_HANDLE_VALUE)
break; break;
dwLength = sizeof(DWORD); dwLength = sizeof(DWORD);
@ -6547,9 +6605,9 @@ SetupDiChangeState(
|| PropChange->HwProfile == GetCurrentHwProfile(DeviceInfoSet)) || PropChange->HwProfile == GetCurrentHwProfile(DeviceInfoSet))
{ {
if (PropChange->StateChange == DICS_ENABLE) if (PropChange->StateChange == DICS_ENABLE)
ret = StartDevice(); ret = ResetDevice(DeviceInfoSet, DeviceInfoData);
else else
ret = StopDevice(); ret = StopDevice(DeviceInfoSet, DeviceInfoData);
} }
else else
ret = TRUE; ret = TRUE;
@ -6557,7 +6615,7 @@ SetupDiChangeState(
} }
case DICS_PROPCHANGE: case DICS_PROPCHANGE:
{ {
ret = StopDevice() && StartDevice(); ret = ResetDevice(DeviceInfoSet, DeviceInfoData);
break; break;
} }
default: default:
@ -6837,7 +6895,6 @@ SetupDiInstallDevice(
IN HDEVINFO DeviceInfoSet, IN HDEVINFO DeviceInfoSet,
IN PSP_DEVINFO_DATA DeviceInfoData) IN PSP_DEVINFO_DATA DeviceInfoData)
{ {
struct DeviceInfoElement *DevInfo = (struct DeviceInfoElement *)DeviceInfoData->Reserved;
SP_DEVINSTALL_PARAMS_W InstallParams; SP_DEVINSTALL_PARAMS_W InstallParams;
struct DriverInfoElement *SelectedDriver; struct DriverInfoElement *SelectedDriver;
SYSTEMTIME DriverDate; SYSTEMTIME DriverDate;
@ -7166,13 +7223,7 @@ nextservice:
/* Start the device */ /* Start the device */
if (!RebootRequired && !(InstallParams.Flags & (DI_NEEDRESTART | DI_NEEDREBOOT | DI_DONOTCALLCONFIGMG))) if (!RebootRequired && !(InstallParams.Flags & (DI_NEEDRESTART | DI_NEEDREBOOT | DI_DONOTCALLCONFIGMG)))
{ ret = ResetDevice(DeviceInfoSet, DeviceInfoData);
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);
}
else else
ret = TRUE; ret = TRUE;