mirror of
https://github.com/reactos/reactos.git
synced 2025-02-24 09:25:10 +00:00
Implement DICS_FLAG_CONFIGSPECIFIC and DIREG_DEV cases in SetupDiCreateDevRegKeyW
Implement SetupDiChangeState svn path=/trunk/; revision=20201
This commit is contained in:
parent
11dcbab404
commit
89bf2a6dcd
2 changed files with 231 additions and 13 deletions
|
@ -3397,14 +3397,16 @@ done:
|
||||||
|
|
||||||
static BOOL PropertyChangeHandler(
|
static BOOL PropertyChangeHandler(
|
||||||
IN HDEVINFO DeviceInfoSet,
|
IN HDEVINFO DeviceInfoSet,
|
||||||
IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL,
|
IN PSP_DEVINFO_DATA DeviceInfoData,
|
||||||
IN PSP_CLASSINSTALL_HEADER ClassInstallParams OPTIONAL,
|
IN PSP_CLASSINSTALL_HEADER ClassInstallParams OPTIONAL,
|
||||||
IN DWORD ClassInstallParamsSize)
|
IN DWORD ClassInstallParamsSize)
|
||||||
{
|
{
|
||||||
PSP_PROPCHANGE_PARAMS PropChangeParams = (PSP_PROPCHANGE_PARAMS)ClassInstallParams;
|
PSP_PROPCHANGE_PARAMS PropChangeParams = (PSP_PROPCHANGE_PARAMS)ClassInstallParams;
|
||||||
BOOL ret = FALSE;
|
BOOL ret = FALSE;
|
||||||
|
|
||||||
if (ClassInstallParamsSize != sizeof(SP_PROPCHANGE_PARAMS))
|
if (!DeviceInfoData)
|
||||||
|
SetLastError(ERROR_INVALID_PARAMETER);
|
||||||
|
else if (ClassInstallParamsSize != sizeof(SP_PROPCHANGE_PARAMS))
|
||||||
SetLastError(ERROR_INVALID_PARAMETER);
|
SetLastError(ERROR_INVALID_PARAMETER);
|
||||||
else if (PropChangeParams && PropChangeParams->StateChange != DICS_ENABLE
|
else if (PropChangeParams && PropChangeParams->StateChange != DICS_ENABLE
|
||||||
&& PropChangeParams->StateChange != DICS_DISABLE && PropChangeParams->StateChange != DICS_PROPCHANGE
|
&& PropChangeParams->StateChange != DICS_DISABLE && PropChangeParams->StateChange != DICS_PROPCHANGE
|
||||||
|
@ -4362,25 +4364,101 @@ 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 hEnumKey = INVALID_HANDLE_VALUE;
|
||||||
HKEY hClassKey = INVALID_HANDLE_VALUE;
|
HKEY hClassKey = INVALID_HANDLE_VALUE;
|
||||||
HKEY hDeviceKey = INVALID_HANDLE_VALUE;
|
HKEY hDeviceKey = INVALID_HANDLE_VALUE;
|
||||||
HKEY hKey = 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");
|
rc = RegOpenKeyExW(list->HKLM,
|
||||||
goto cleanup;
|
L"SYSTEM\\CurrentControlSet\\Hardware Profiles",
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
RootKey = hHWProfileKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (KeyType == DIREG_DEV)
|
if (KeyType == DIREG_DEV)
|
||||||
{
|
{
|
||||||
FIXME("DIREG_DEV case unimplemented\n");
|
struct DeviceInfoElement *deviceInfo = (struct DeviceInfoElement *)DeviceInfoData->Reserved;
|
||||||
|
|
||||||
|
rc = RegCreateKeyExW(
|
||||||
|
RootKey,
|
||||||
|
EnumKeyName,
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
REG_OPTION_NON_VOLATILE,
|
||||||
|
KEY_CREATE_SUB_KEY,
|
||||||
|
NULL,
|
||||||
|
&hEnumKey,
|
||||||
|
NULL);
|
||||||
|
if (rc != ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
SetLastError(rc);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
rc = RegCreateKeyExW(
|
||||||
|
hEnumKey,
|
||||||
|
deviceInfo->DeviceName,
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
REG_OPTION_NON_VOLATILE,
|
||||||
|
#if _WIN32_WINNT >= 0x502
|
||||||
|
KEY_READ | KEY_WRITE,
|
||||||
|
#else
|
||||||
|
KEY_ALL_ACCESS,
|
||||||
|
#endif
|
||||||
|
NULL,
|
||||||
|
&hKey,
|
||||||
|
NULL);
|
||||||
|
if (rc != ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
SetLastError(rc);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else /* KeyType == DIREG_DRV */
|
else /* KeyType == DIREG_DRV */
|
||||||
{
|
{
|
||||||
if (UuidToStringW((UUID*)&DeviceInfoData->ClassGuid, &lpGuidString) != RPC_S_OK)
|
if (UuidToStringW((UUID*)&DeviceInfoData->ClassGuid, &lpGuidString) != RPC_S_OK)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
/* The driver key is in HKLM\System\CurrentControlSet\Control\Class\{GUID}\Index */
|
/* The driver key is in \System\CurrentControlSet\Control\Class\{GUID}\Index */
|
||||||
DriverKey = HeapAlloc(GetProcessHeap(), 0, (wcslen(lpGuidString) + 7) * sizeof(WCHAR) + sizeof(UNICODE_STRING));
|
DriverKey = HeapAlloc(GetProcessHeap(), 0, (wcslen(lpGuidString) + 7) * sizeof(WCHAR) + sizeof(UNICODE_STRING));
|
||||||
if (!DriverKey)
|
if (!DriverKey)
|
||||||
{
|
{
|
||||||
|
@ -4391,7 +4469,7 @@ HKEY WINAPI SetupDiCreateDevRegKeyW(
|
||||||
wcscat(DriverKey, lpGuidString);
|
wcscat(DriverKey, lpGuidString);
|
||||||
wcscat(DriverKey, L"}\\");
|
wcscat(DriverKey, L"}\\");
|
||||||
pDeviceInstance = &DriverKey[wcslen(DriverKey)];
|
pDeviceInstance = &DriverKey[wcslen(DriverKey)];
|
||||||
rc = RegOpenKeyExW(list->HKLM,
|
rc = RegOpenKeyExW(RootKey,
|
||||||
ControlClass,
|
ControlClass,
|
||||||
0,
|
0,
|
||||||
KEY_CREATE_SUB_KEY,
|
KEY_CREATE_SUB_KEY,
|
||||||
|
@ -4463,6 +4541,12 @@ 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)
|
||||||
|
RegCloseKey(hHWProfileKey);
|
||||||
|
if (hEnumKey != INVALID_HANDLE_VALUE)
|
||||||
|
RegCloseKey(hEnumKey);
|
||||||
if (hClassKey != INVALID_HANDLE_VALUE)
|
if (hClassKey != INVALID_HANDLE_VALUE)
|
||||||
RegCloseKey(hClassKey);
|
RegCloseKey(hClassKey);
|
||||||
if (hDeviceKey != INVALID_HANDLE_VALUE)
|
if (hDeviceKey != INVALID_HANDLE_VALUE)
|
||||||
|
@ -6346,15 +6430,71 @@ SetupDiGetDriverInfoDetailW(
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Return the current hardware profile id, or -1 if error */
|
||||||
|
static DWORD
|
||||||
|
GetCurrentHwProfile(
|
||||||
|
IN HDEVINFO DeviceInfoSet)
|
||||||
|
{
|
||||||
|
HKEY hKey = INVALID_HANDLE_VALUE;
|
||||||
|
DWORD dwRegType, dwLength;
|
||||||
|
DWORD hwProfile;
|
||||||
|
LONG rc;
|
||||||
|
DWORD ret = (DWORD)-1;
|
||||||
|
|
||||||
|
rc = RegOpenKeyExW(
|
||||||
|
((struct DeviceInfoSet *)DeviceInfoSet)->HKLM,
|
||||||
|
REGSTR_PATH_IDCONFIGDB,
|
||||||
|
0, /* Options */
|
||||||
|
KEY_QUERY_VALUE,
|
||||||
|
&hKey);
|
||||||
|
if (rc != ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
SetLastError(rc);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
dwLength = sizeof(DWORD);
|
||||||
|
rc = RegQueryValueExW(
|
||||||
|
hKey,
|
||||||
|
REGSTR_VAL_CURRENTCONFIG,
|
||||||
|
NULL,
|
||||||
|
&dwRegType,
|
||||||
|
(LPBYTE)&hwProfile, &dwLength);
|
||||||
|
if (rc != ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
SetLastError(rc);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
else if (dwRegType != REG_DWORD || dwLength != sizeof(DWORD))
|
||||||
|
{
|
||||||
|
SetLastError(ERROR_GEN_FAILURE);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = hwProfile;
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
if (hKey != INVALID_HANDLE_VALUE)
|
||||||
|
RegCloseKey(hKey);
|
||||||
|
|
||||||
|
return hwProfile;
|
||||||
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* 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,
|
||||||
IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL)
|
IN OUT PSP_DEVINFO_DATA DeviceInfoData OPTIONAL)
|
||||||
{
|
{
|
||||||
PSP_PROPCHANGE_PARAMS PropChange;
|
PSP_PROPCHANGE_PARAMS PropChange;
|
||||||
|
HKEY hKey = INVALID_HANDLE_VALUE;
|
||||||
|
LPCWSTR RegistryValueName;
|
||||||
|
DWORD dwConfigFlags, dwLength, dwRegType;
|
||||||
|
LONG rc;
|
||||||
BOOL ret = FALSE;
|
BOOL ret = FALSE;
|
||||||
|
|
||||||
TRACE("%p %p\n", DeviceInfoSet, DeviceInfoData);
|
TRACE("%p %p\n", DeviceInfoSet, DeviceInfoData);
|
||||||
|
@ -6366,13 +6506,90 @@ SetupDiChangeState(
|
||||||
if (!PropChange)
|
if (!PropChange)
|
||||||
{
|
{
|
||||||
SetLastError(ERROR_INVALID_PARAMETER);
|
SetLastError(ERROR_INVALID_PARAMETER);
|
||||||
goto done;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
FIXME("Stub %p %p\n", DeviceInfoSet, DeviceInfoData);
|
if (PropChange->Scope == DICS_FLAG_GLOBAL)
|
||||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
RegistryValueName = REGSTR_VAL_CONFIGFLAGS;
|
||||||
|
else
|
||||||
|
RegistryValueName = REGSTR_VAL_CSCONFIGFLAGS;
|
||||||
|
|
||||||
|
switch (PropChange->StateChange)
|
||||||
|
{
|
||||||
|
case DICS_ENABLE:
|
||||||
|
case DICS_DISABLE:
|
||||||
|
{
|
||||||
|
/* 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);
|
||||||
|
if (hKey == INVALID_HANDLE_VALUE)
|
||||||
|
break;
|
||||||
|
dwLength = sizeof(DWORD);
|
||||||
|
rc = RegQueryValueExW(
|
||||||
|
hKey,
|
||||||
|
RegistryValueName,
|
||||||
|
NULL,
|
||||||
|
&dwRegType,
|
||||||
|
(LPBYTE)&dwConfigFlags, &dwLength);
|
||||||
|
if (rc == ERROR_FILE_NOT_FOUND)
|
||||||
|
dwConfigFlags = 0;
|
||||||
|
else if (rc != ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
SetLastError(rc);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
else if (dwRegType != REG_DWORD || dwLength != sizeof(DWORD))
|
||||||
|
{
|
||||||
|
SetLastError(ERROR_GEN_FAILURE);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
if (PropChange->StateChange == DICS_ENABLE)
|
||||||
|
dwConfigFlags &= ~(PropChange->Scope == DICS_FLAG_GLOBAL ? CONFIGFLAG_DISABLED : CSCONFIGFLAG_DISABLED);
|
||||||
|
else
|
||||||
|
dwConfigFlags |= (PropChange->Scope == DICS_FLAG_GLOBAL ? CONFIGFLAG_DISABLED : CSCONFIGFLAG_DISABLED);
|
||||||
|
rc = RegSetValueEx(
|
||||||
|
hKey,
|
||||||
|
RegistryValueName,
|
||||||
|
0,
|
||||||
|
REG_DWORD,
|
||||||
|
(LPBYTE)&dwConfigFlags, sizeof(DWORD));
|
||||||
|
if (rc != ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
SetLastError(rc);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Enable/disable device if needed */
|
||||||
|
if (PropChange->Scope == DICS_FLAG_GLOBAL
|
||||||
|
|| PropChange->HwProfile == 0
|
||||||
|
|| PropChange->HwProfile == GetCurrentHwProfile(DeviceInfoSet))
|
||||||
|
{
|
||||||
|
if (PropChange->StateChange == DICS_ENABLE)
|
||||||
|
ret = StartDevice();
|
||||||
|
else
|
||||||
|
ret = StopDevice();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ret = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DICS_PROPCHANGE:
|
||||||
|
{
|
||||||
|
ret = StopDevice() && StartDevice();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
FIXME("Unknown StateChange 0x%lx\n", PropChange->StateChange);
|
||||||
|
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
if (hKey != INVALID_HANDLE_VALUE)
|
||||||
|
RegCloseKey(hKey);
|
||||||
|
|
||||||
done:
|
|
||||||
TRACE("Returning %d\n", ret);
|
TRACE("Returning %d\n", ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <cfgmgr32.h>
|
#include <cfgmgr32.h>
|
||||||
#include <fdi.h>
|
#include <fdi.h>
|
||||||
|
#include <regstr.h>
|
||||||
#include <setupapi.h>
|
#include <setupapi.h>
|
||||||
#include <shlobj.h>
|
#include <shlobj.h>
|
||||||
#include <wine/debug.h>
|
#include <wine/debug.h>
|
||||||
|
|
Loading…
Reference in a new issue