[SETUPAPI] Fix wrong registry key opened by SetupDiCreateDeviceInterfaceRegKeyW()

The funstion should create/open "Device Parameters" subkey of a device reference key (and return a handle to it), instead of device instance subkey.
- Fix SetupDiCreateDeviceInterfaceRegKeyW() to open (and return a handle to) the correct registry key.
- Fix its usage in internal InstallOneInterface() helper, which is called by SetupDiInstallDeviceInterfaces().
This fixes audio devices enumeration failure of winmm.dll from Windows 2000 SP4 (and unneeded creation of wrong registry keys) when using ReactOS with audio stack replacement from Windows XP/2003.
CORE-19986
This commit is contained in:
Oleg Dubinskiy
2026-04-02 12:03:31 +02:00
parent 9a7f64a0c6
commit b205c04173
2 changed files with 56 additions and 42 deletions
+53 -9
View File
@@ -2618,9 +2618,9 @@ HKEY WINAPI SetupDiCreateDeviceInterfaceRegKeyW(
HINF InfHandle,
PCWSTR InfSectionName)
{
HKEY hKey, hDevKey;
LPWSTR SymbolicLink;
DWORD Length, Index;
HKEY hKey, hDevKey, hRefKey, hDevParamKey;
LPWSTR SymbolicLink, ReferenceString;
DWORD Length, RefLength, Index;
LONG rc;
WCHAR bracedGuidString[39];
struct DeviceInterface *DevItf;
@@ -2681,9 +2681,17 @@ HKEY WINAPI SetupDiCreateDeviceInterfaceRegKeyW(
wcscpy(SymbolicLink, DevItf->SymbolicLink);
/* Enumerate all characters in symbolic link */
Index = 0;
while(SymbolicLink[Index])
while (SymbolicLink[Index])
{
/* Check for a start position of reference string */
if (SymbolicLink[Index] == L'}' && SymbolicLink[Index + 1] == L'\\')
{
/* Found it */
break;
}
/* Replace all '\' backslashes by '#' pounds in symbolic link */
if (SymbolicLink[Index] == L'\\')
{
SymbolicLink[Index] = L'#';
@@ -2691,11 +2699,47 @@ HKEY WINAPI SetupDiCreateDeviceInterfaceRegKeyW(
Index++;
}
rc = RegCreateKeyExW(hKey, SymbolicLink, 0, NULL, 0, samDesired, NULL, &hDevKey, NULL);
/* Create reference string */
RefLength = Length - Index * sizeof(WCHAR);
ReferenceString = HeapAlloc(GetProcessHeap(), 0, RefLength);
if (!ReferenceString)
{
HeapFree(GetProcessHeap(), 0, SymbolicLink);
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return INVALID_HANDLE_VALUE;
}
RegCloseKey(hKey);
ReferenceString[0] = L'#';
wcscpy(ReferenceString + 1, &SymbolicLink[Index + 2]); /* Skip first '\' backslash */
/* Null-terminate symbolic link at the beginning of the reference part,
* as we don't need a ref part in key name. */
SymbolicLink[Index + 1] = UNICODE_NULL;
/* Open device instance key */
rc = RegOpenKeyExW(hKey, SymbolicLink, 0, samDesired, &hDevKey);
HeapFree(GetProcessHeap(), 0, SymbolicLink);
RegCloseKey(hKey);
if (rc != ERROR_SUCCESS)
{
HeapFree(GetProcessHeap(), 0, ReferenceString);
SetLastError(rc);
return INVALID_HANDLE_VALUE;
}
/* Open reference key */
rc = RegOpenKeyExW(hDevKey, ReferenceString, 0, samDesired, &hRefKey);
HeapFree(GetProcessHeap(), 0, ReferenceString);
RegCloseKey(hDevKey);
if (rc != ERROR_SUCCESS)
{
SetLastError(rc);
return INVALID_HANDLE_VALUE;
}
/* Create/open "Device Parameters" subkey */
rc = RegCreateKeyExW(hRefKey, L"Device Parameters", 0, NULL, 0, samDesired, NULL, &hDevParamKey, NULL);
RegCloseKey(hRefKey);
if (rc == ERROR_SUCCESS)
{
if (InfHandle && InfSectionName)
@@ -2704,7 +2748,7 @@ HKEY WINAPI SetupDiCreateDeviceInterfaceRegKeyW(
InfHandle,
InfSectionName,
SPINST_INIFILES | SPINST_REGISTRY | SPINST_INI2REG | SPINST_FILES | SPINST_BITREG | SPINST_REGSVR | SPINST_UNREGSVR | SPINST_PROFILEITEMS | SPINST_COPYINF,
hDevKey,
hDevParamKey,
NULL,
0,
set->SelectedDevice->InstallParams.InstallMsgHandler,
@@ -2712,14 +2756,14 @@ HKEY WINAPI SetupDiCreateDeviceInterfaceRegKeyW(
INVALID_HANDLE_VALUE,
NULL))
{
RegCloseKey(hDevKey);
RegCloseKey(hDevParamKey);
return INVALID_HANDLE_VALUE;
}
}
}
SetLastError(rc);
return hDevKey;
return hDevParamKey;
}
/***********************************************************************
+3 -33
View File
@@ -340,7 +340,7 @@ InstallOneInterface(
IN HDEVINFO DeviceInfoSet,
IN struct DeviceInfo *devInfo)
{
HKEY hKey, hRefKey;
HKEY hKey;
LPWSTR Path;
SP_DEVICE_INTERFACE_DATA DeviceInterfaceData;
struct DeviceInterface *DevItf = NULL;
@@ -371,44 +371,14 @@ InstallOneInterface(
DeviceInterfaceData.Flags = DevItf->Flags;
DeviceInterfaceData.Reserved = (ULONG_PTR)DevItf;
hKey = SetupDiCreateDeviceInterfaceRegKeyW(DeviceInfoSet, &DeviceInterfaceData, 0, KEY_ALL_ACCESS, NULL, 0);
hKey = SetupDiCreateDeviceInterfaceRegKeyW(DeviceInfoSet, &DeviceInterfaceData, 0, KEY_ALL_ACCESS, NULL, NULL);
HeapFree(GetProcessHeap(), 0, DevItf);
if (hKey == INVALID_HANDLE_VALUE)
{
return FALSE;
}
if (ReferenceString)
{
Path = HeapAlloc(GetProcessHeap(), 0, (wcslen(ReferenceString) + 2) * sizeof(WCHAR));
if (!Path)
{
RegCloseKey(hKey);
return FALSE;
}
wcscpy(Path, L"#");
wcscat(Path, ReferenceString);
if (RegCreateKeyExW(hKey, Path, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &hRefKey, NULL) != ERROR_SUCCESS)
{
ERR("failed to create key %s %lx\n", debugstr_w(Path), GetLastError());
HeapFree(GetProcessHeap(), 0, Path);
return FALSE;
}
RegCloseKey(hKey);
hKey = hRefKey;
HeapFree(GetProcessHeap(), 0, Path);
}
if (RegCreateKeyExW(hKey, L"Device Parameters", 0, NULL, 0, KEY_ALL_ACCESS, NULL, &hRefKey, NULL) != ERROR_SUCCESS)
{
RegCloseKey(hKey);
return FALSE;
}
return SetupInstallFromInfSectionW(NULL, /* FIXME */ hInf, InterfaceSection, SPINST_REGISTRY, hRefKey, NULL, 0, NULL, NULL, NULL, NULL);
return SetupInstallFromInfSectionW(NULL, /* FIXME */ hInf, InterfaceSection, SPINST_REGISTRY, hKey, NULL, 0, NULL, NULL, NULL, NULL);
}
/***********************************************************************