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); } /***********************************************************************