From 1ef584c44653e55b97d0de39a936fa63f36a131a Mon Sep 17 00:00:00 2001 From: Oleg Dubinskiy Date: Fri, 10 Jul 2026 19:04:29 +0200 Subject: [PATCH] [SETUPAPI] Fix the creation of symbolic link passed to SetupDiCreateDeviceInterfaceRegKeyW() (#8967) - Create the actual symbolic link, instead of just instance key name (don't replace all \ by # and don't cut reference string from it) inside CreateSymbolicLink() internal helper of SetupDiInstallDeviceInterfaces(), to pass it in SetupDiCreateDeviceInterfaceRegKeyW() inside InstallOneInterface() internal helper later. - Fix handling the received symbolic link inside SetupDiCreateDeviceInterfaceRegKeyW() itself. Except it to be the fully unmodified one, instead of transformed to an instance key name. - Additionally, change the SetupInstallFromInfSection() call to SetupInstallFromInfSectionW(), since it's actually called with Unicode parameters from Unicode version of SetupDiCreateDeviceInterfaceRegKeyW(). Otherwise, if to not precisely specify Unicode version call, it might call ANSI function instead and hence will obviously not work correctly because of that. This fixes regression with improper writing "CLSID" and "FriendlyName" values in "Device Parameters" subkey of device interfaces in Registry, because of reference key open failure, and therefore it also fixes detection of the audio device name in Sound Proeprties from Control Panel in particular. Follow-up of b205c041735ab98b7825461f32be8ced38c8b05e. CORE-20603 --- dll/win32/setupapi/devinst.c | 28 +++++++++++++----------- dll/win32/setupapi/interface.c | 40 ++++++++++++++++------------------ 2 files changed, 34 insertions(+), 34 deletions(-) diff --git a/dll/win32/setupapi/devinst.c b/dll/win32/setupapi/devinst.c index d0de498923b..93fbd819b52 100644 --- a/dll/win32/setupapi/devinst.c +++ b/dll/win32/setupapi/devinst.c @@ -2689,6 +2689,7 @@ HKEY WINAPI SetupDiCreateDeviceInterfaceRegKeyW( if (SymbolicLink[Index] == L'}' && SymbolicLink[Index + 1] == L'\\') { /* Found it */ + SymbolicLink[Index + 1] = L'#'; break; } /* Replace all '\' backslashes by '#' pounds in symbolic link */ @@ -2709,8 +2710,7 @@ HKEY WINAPI SetupDiCreateDeviceInterfaceRegKeyW( return INVALID_HANDLE_VALUE; } - ReferenceString[0] = L'#'; - wcscpy(ReferenceString + 1, &SymbolicLink[Index + 2]); /* Skip first '\' backslash */ + wcscpy(ReferenceString, &SymbolicLink[Index + 1]); /* Null-terminate symbolic link at the beginning of the reference part, * as we don't need a ref part in key name. */ @@ -2744,17 +2744,19 @@ HKEY WINAPI SetupDiCreateDeviceInterfaceRegKeyW( { if (InfHandle && InfSectionName) { - if (!SetupInstallFromInfSection(NULL /*FIXME */, - InfHandle, - InfSectionName, - SPINST_INIFILES | SPINST_REGISTRY | SPINST_INI2REG | SPINST_FILES | SPINST_BITREG | SPINST_REGSVR | SPINST_UNREGSVR | SPINST_PROFILEITEMS | SPINST_COPYINF, - hDevParamKey, - NULL, - 0, - set->SelectedDevice->InstallParams.InstallMsgHandler, - set->SelectedDevice->InstallParams.InstallMsgHandlerContext, - INVALID_HANDLE_VALUE, - NULL)) + if (!SetupInstallFromInfSectionW(NULL /*FIXME */, + InfHandle, + InfSectionName, + SPINST_INIFILES | SPINST_REGISTRY | SPINST_INI2REG | + SPINST_FILES | SPINST_BITREG | SPINST_REGSVR | + SPINST_UNREGSVR | SPINST_PROFILEITEMS | SPINST_COPYINF, + hDevParamKey, + NULL, + 0, + set->SelectedDevice->InstallParams.InstallMsgHandler, + set->SelectedDevice->InstallParams.InstallMsgHandlerContext, + INVALID_HANDLE_VALUE, + NULL)) { RegCloseKey(hDevParamKey); return INVALID_HANDLE_VALUE; diff --git a/dll/win32/setupapi/interface.c b/dll/win32/setupapi/interface.c index 4fe98c4cd4e..c167e0ad05c 100644 --- a/dll/win32/setupapi/interface.c +++ b/dll/win32/setupapi/interface.c @@ -301,35 +301,33 @@ CreateSymbolicLink( IN LPCWSTR ReferenceString, IN struct DeviceInfo *devInfo) { - DWORD Length, Index, Offset; - LPWSTR Key; + SIZE_T ActualLength, Length; + WCHAR GuidString[MAX_GUID_STRING_LEN]; + LPWSTR SymbolicLink; - Length = wcslen(devInfo->instanceId) + 4 /* prepend ##?# */ + 41 /* #{GUID} + */ + 1 /* zero byte */; + Length = 4 + // "\\\\?\\" + wcslen(devInfo->instanceId) + + 1 + (MAX_GUID_STRING_LEN - 1) + 1 + // "#{GUID}\\" + wcslen(ReferenceString) + + 1; // UNICODE_NULL - Key = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, Length * sizeof(WCHAR)); - if (!Key) + SymbolicLink = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, Length * sizeof(WCHAR)); + if (!SymbolicLink) return NULL; - wcscpy(Key, L"##?#"); - wcscat(Key, devInfo->instanceId); + pSetupStringFromGuid(InterfaceGuid, GuidString, ARRAYSIZE(GuidString)); - for(Index = 4; Index < Length; Index++) - { - if (Key[Index] == L'\\') - { - Key[Index] = L'#'; - } - } + ActualLength = swprintf(SymbolicLink, + Length, + L"\\\\?\\%s#%s\\%s", + devInfo->instanceId, + GuidString, + ReferenceString); + ASSERT(ActualLength == Length - 1); - wcscat(Key, L"#"); - - Offset = wcslen(Key); - pSetupStringFromGuid(InterfaceGuid, Key + Offset, Length - Offset); - - return Key; + return SymbolicLink; } - static BOOL InstallOneInterface( IN LPGUID InterfaceGuid,