From b205c041735ab98b7825461f32be8ced38c8b05e Mon Sep 17 00:00:00 2001 From: Oleg Dubinskiy Date: Wed, 5 Feb 2025 23:02:40 +0100 Subject: [PATCH] [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 --- dll/win32/setupapi/devinst.c | 62 +++++++++++++++++++++++++++++----- dll/win32/setupapi/interface.c | 36 ++------------------ 2 files changed, 56 insertions(+), 42 deletions(-) diff --git a/dll/win32/setupapi/devinst.c b/dll/win32/setupapi/devinst.c index 9dbabb48a32..d0de498923b 100644 --- a/dll/win32/setupapi/devinst.c +++ b/dll/win32/setupapi/devinst.c @@ -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; } /*********************************************************************** diff --git a/dll/win32/setupapi/interface.c b/dll/win32/setupapi/interface.c index 6a627d1118e..4fe98c4cd4e 100644 --- a/dll/win32/setupapi/interface.c +++ b/dll/win32/setupapi/interface.c @@ -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); } /***********************************************************************