From 4ce3d5c9e82892e73b8a5756fb5a615161d482be Mon Sep 17 00:00:00 2001 From: =?utf8?q?Herv=C3=A9=20Poussineau?= Date: Thu, 15 Dec 2005 23:24:43 +0000 Subject: [PATCH] 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 --- reactos/lib/setupapi/devinst.c | 337 +++++++++++++++++++-------------- 1 file changed, 194 insertions(+), 143 deletions(-) diff --git a/reactos/lib/setupapi/devinst.c b/reactos/lib/setupapi/devinst.c index 46eff4c0616..cd11434e651 100644 --- a/reactos/lib/setupapi/devinst.c +++ b/reactos/lib/setupapi/devinst.c @@ -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; -- 2.17.1