1 /* 2 * COPYRIGHT: See COPYING in the top level directory 3 * PROJECT: ReactOS Configuration of network devices 4 * FILE: dll/win32/netcfgx/installer.c 5 * PURPOSE: Network devices installer 6 * 7 * PROGRAMMERS: Herv� Poussineau (hpoussin@reactos.org) 8 */ 9 10 #include "precomp.h" 11 12 13 /* Append a REG_SZ to an existing REG_MULTI_SZ string in the registry. 14 * If the value doesn't exist, create it. 15 * Returns ERROR_SUCCESS if success. Otherwise, returns an error code 16 */ 17 static 18 LONG 19 AppendStringToMultiSZ( 20 IN HKEY hKey, 21 IN PCWSTR ValueName, 22 IN PCWSTR ValueToAppend) 23 { 24 PWSTR Buffer = NULL; 25 DWORD dwRegType; 26 DWORD dwRequired, dwLength; 27 DWORD dwTmp; 28 LONG rc; 29 30 rc = RegQueryValueExW(hKey, 31 ValueName, 32 NULL, 33 &dwRegType, 34 NULL, 35 &dwRequired); 36 if (rc != ERROR_FILE_NOT_FOUND) 37 { 38 if (rc != ERROR_SUCCESS) 39 goto cleanup; 40 if (dwRegType != REG_MULTI_SZ) 41 { 42 rc = ERROR_GEN_FAILURE; 43 goto cleanup; 44 } 45 46 dwTmp = dwLength = dwRequired + wcslen(ValueToAppend) * sizeof(WCHAR) + sizeof(UNICODE_NULL); 47 Buffer = HeapAlloc(GetProcessHeap(), 0, dwLength); 48 if (!Buffer) 49 { 50 rc = ERROR_NOT_ENOUGH_MEMORY; 51 goto cleanup; 52 } 53 54 rc = RegQueryValueExW(hKey, 55 ValueName, 56 NULL, 57 NULL, 58 (BYTE*)Buffer, 59 &dwTmp); 60 if (rc != ERROR_SUCCESS) 61 goto cleanup; 62 } 63 else 64 { 65 dwRequired = sizeof(WCHAR); 66 dwLength = wcslen(ValueToAppend) * sizeof(WCHAR) + 2 * sizeof(UNICODE_NULL); 67 Buffer = HeapAlloc(GetProcessHeap(), 0, dwLength); 68 if (!Buffer) 69 { 70 rc = ERROR_NOT_ENOUGH_MEMORY; 71 goto cleanup; 72 } 73 } 74 75 /* Append the value */ 76 wcscpy(&Buffer[dwRequired / sizeof(WCHAR) - 1], ValueToAppend); 77 /* Terminate the REG_MULTI_SZ string */ 78 Buffer[dwLength / sizeof(WCHAR) - 1] = UNICODE_NULL; 79 80 rc = RegSetValueExW(hKey, 81 ValueName, 82 0, 83 REG_MULTI_SZ, 84 (const BYTE*)Buffer, 85 dwLength); 86 87 cleanup: 88 HeapFree(GetProcessHeap(), 0, Buffer); 89 return rc; 90 } 91 92 93 static 94 DWORD 95 InstallNetDevice( 96 IN HDEVINFO DeviceInfoSet, 97 IN PSP_DEVINFO_DATA DeviceInfoData, 98 LPCWSTR UuidString, 99 DWORD Characteristics, 100 LPCWSTR BusType) 101 { 102 LPWSTR InstanceId = NULL; 103 LPWSTR DeviceName = NULL; 104 LPWSTR ExportName = NULL; 105 LONG rc; 106 HKEY hKey = NULL; 107 HKEY hNetworkKey = NULL; 108 HKEY hLinkageKey = NULL; 109 HKEY hConnectionKey = NULL; 110 DWORD dwShowIcon, dwLength, dwValue; 111 WCHAR szBuffer[300]; 112 113 /* Get Instance ID */ 114 if (SetupDiGetDeviceInstanceIdW(DeviceInfoSet, DeviceInfoData, NULL, 0, &dwLength)) 115 { 116 ERR("SetupDiGetDeviceInstanceIdW() returned TRUE. FALSE expected\n"); 117 rc = ERROR_GEN_FAILURE; 118 goto cleanup; 119 } 120 121 InstanceId = HeapAlloc(GetProcessHeap(), 0, dwLength * sizeof(WCHAR)); 122 if (!InstanceId) 123 { 124 ERR("HeapAlloc() failed\n"); 125 rc = ERROR_NOT_ENOUGH_MEMORY; 126 goto cleanup; 127 } 128 129 if (!SetupDiGetDeviceInstanceIdW(DeviceInfoSet, DeviceInfoData, InstanceId, dwLength, NULL)) 130 { 131 rc = GetLastError(); 132 ERR("SetupDiGetDeviceInstanceIdW() failed with error 0x%lx\n", rc); 133 goto cleanup; 134 } 135 136 /* Create device name */ 137 DeviceName = HeapAlloc(GetProcessHeap(), 0, (wcslen(L"\\Device\\") + wcslen(UuidString)) * sizeof(WCHAR) + sizeof(UNICODE_NULL)); 138 if (!DeviceName) 139 { 140 ERR("HeapAlloc() failed\n"); 141 rc = ERROR_NOT_ENOUGH_MEMORY; 142 goto cleanup; 143 } 144 wcscpy(DeviceName, L"\\Device\\"); 145 wcscat(DeviceName, UuidString); 146 147 /* Create export name */ 148 ExportName = HeapAlloc(GetProcessHeap(), 0, (wcslen(L"\\Device\\Tcpip_") + wcslen(UuidString)) * sizeof(WCHAR) + sizeof(UNICODE_NULL)); 149 if (!ExportName) 150 { 151 ERR("HeapAlloc() failed\n"); 152 rc = ERROR_NOT_ENOUGH_MEMORY; 153 goto cleanup; 154 } 155 wcscpy(ExportName, L"\\Device\\Tcpip_"); 156 wcscat(ExportName, UuidString); 157 158 /* Write Tcpip parameters in new service Key */ 159 rc = RegCreateKeyExW(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Services", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_CREATE_SUB_KEY, NULL, &hKey, NULL); 160 if (rc != ERROR_SUCCESS) 161 { 162 ERR("RegCreateKeyExW() failed with error 0x%lx\n", rc); 163 goto cleanup; 164 } 165 166 rc = RegCreateKeyExW(hKey, UuidString, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_CREATE_SUB_KEY, NULL, &hNetworkKey, NULL); 167 if (rc != ERROR_SUCCESS) 168 { 169 ERR("RegCreateKeyExW() failed with error 0x%lx\n", rc); 170 goto cleanup; 171 } 172 RegCloseKey(hKey); 173 hKey = NULL; 174 175 rc = RegCreateKeyExW(hNetworkKey, L"Parameters\\Tcpip", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_SET_VALUE, NULL, &hKey, NULL); 176 if (rc != ERROR_SUCCESS) 177 { 178 ERR("RegCreateKeyExW() failed with error 0x%lx\n", rc); 179 goto cleanup; 180 } 181 RegCloseKey(hNetworkKey); 182 hNetworkKey = NULL; 183 184 rc = RegSetValueExW(hKey, L"DefaultGateway", 0, REG_SZ, (const BYTE*)L"0.0.0.0", (wcslen(L"0.0.0.0") + 1) * sizeof(WCHAR)); 185 if (rc != ERROR_SUCCESS) 186 { 187 ERR("RegSetValueExW() failed with error 0x%lx\n", rc); 188 goto cleanup; 189 } 190 191 rc = RegSetValueExW(hKey, L"IPAddress", 0, REG_SZ, (const BYTE*)L"0.0.0.0", (wcslen(L"0.0.0.0") + 1) * sizeof(WCHAR)); 192 if (rc != ERROR_SUCCESS) 193 { 194 ERR("RegSetValueExW() failed with error 0x%lx\n", rc); 195 goto cleanup; 196 } 197 198 rc = RegSetValueExW(hKey, L"SubnetMask", 0, REG_SZ, (const BYTE*)L"0.0.0.0", (wcslen(L"0.0.0.0") + 1) * sizeof(WCHAR)); 199 if (rc != ERROR_SUCCESS) 200 { 201 ERR("RegSetValueExW() failed with error 0x%lx\n", rc); 202 goto cleanup; 203 } 204 205 dwValue = 1; 206 rc = RegSetValueExW(hKey, L"EnableDHCP", 0, REG_DWORD, (const BYTE*)&dwValue, sizeof(DWORD)); 207 if (rc != ERROR_SUCCESS) 208 { 209 ERR("RegSetValueExW() failed with error 0x%lx\n", rc); 210 goto cleanup; 211 } 212 RegCloseKey(hKey); 213 hKey = NULL; 214 215 /* Write 'Linkage' key in hardware key */ 216 #if _WIN32_WINNT >= 0x502 217 hKey = SetupDiOpenDevRegKey(DeviceInfoSet, DeviceInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DRV, KEY_READ | KEY_WRITE); 218 #else 219 hKey = SetupDiOpenDevRegKey(DeviceInfoSet, DeviceInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DRV, KEY_ALL_ACCESS); 220 #endif 221 if (hKey == INVALID_HANDLE_VALUE && GetLastError() == ERROR_FILE_NOT_FOUND) 222 hKey = SetupDiCreateDevRegKeyW(DeviceInfoSet, DeviceInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DRV, NULL, NULL); 223 if (hKey == INVALID_HANDLE_VALUE) 224 { 225 hKey = NULL; 226 rc = GetLastError(); 227 ERR("SetupDiCreateDevRegKeyW() failed with error 0x%lx\n", rc); 228 goto cleanup; 229 } 230 231 rc = RegSetValueExW(hKey, L"NetCfgInstanceId", 0, REG_SZ, (const BYTE*)UuidString, (wcslen(UuidString) + 1) * sizeof(WCHAR)); 232 if (rc != ERROR_SUCCESS) 233 { 234 ERR("RegSetValueExW() failed with error 0x%lx\n", rc); 235 goto cleanup; 236 } 237 238 rc = RegSetValueExW(hKey, L"Characteristics", 0, REG_DWORD, (const BYTE*)&Characteristics, sizeof(DWORD)); 239 if (rc != ERROR_SUCCESS) 240 { 241 ERR("RegSetValueExW() failed with error 0x%lx\n", rc); 242 goto cleanup; 243 } 244 245 if (BusType) 246 { 247 rc = RegSetValueExW(hKey, L"BusType", 0, REG_SZ, (const BYTE*)BusType, (wcslen(BusType) + 1) * sizeof(WCHAR)); 248 if (rc != ERROR_SUCCESS) 249 { 250 ERR("RegSetValueExW() failed with error 0x%lx\n", rc); 251 goto cleanup; 252 } 253 } 254 255 rc = RegCreateKeyExW(hKey, L"Linkage", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_SET_VALUE, NULL, &hLinkageKey, NULL); 256 if (rc != ERROR_SUCCESS) 257 { 258 ERR("RegCreateKeyExW() failed with error 0x%lx\n", rc); 259 goto cleanup; 260 } 261 262 rc = RegSetValueExW(hLinkageKey, L"Export", 0, REG_SZ, (const BYTE*)DeviceName, (wcslen(DeviceName) + 1) * sizeof(WCHAR)); 263 if (rc != ERROR_SUCCESS) 264 { 265 ERR("RegSetValueExW() failed with error 0x%lx\n", rc); 266 goto cleanup; 267 } 268 269 rc = RegSetValueExW(hLinkageKey, L"RootDevice", 0, REG_SZ, (const BYTE*)UuidString, (wcslen(UuidString) + 1) * sizeof(WCHAR)); 270 if (rc != ERROR_SUCCESS) 271 { 272 ERR("RegSetValueExW() failed with error 0x%lx\n", rc); 273 goto cleanup; 274 } 275 276 rc = RegSetValueExW(hLinkageKey, L"UpperBind", 0, REG_SZ, (const BYTE*)L"Tcpip", (wcslen(L"Tcpip") + 1) * sizeof(WCHAR)); 277 if (rc != ERROR_SUCCESS) 278 { 279 ERR("RegSetValueExW() failed with error 0x%lx\n", rc); 280 goto cleanup; 281 } 282 RegCloseKey(hKey); 283 hKey = NULL; 284 285 /* Write connection information in network subkey */ 286 rc = RegCreateKeyExW(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_CREATE_SUB_KEY, NULL, &hNetworkKey, NULL); 287 if (rc != ERROR_SUCCESS) 288 { 289 ERR("RegCreateKeyExW() failed with error 0x%lx\n", rc); 290 goto cleanup; 291 } 292 293 rc = RegCreateKeyExW(hNetworkKey, UuidString, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_CREATE_SUB_KEY, NULL, &hKey, NULL); 294 if (rc != ERROR_SUCCESS) 295 { 296 ERR("RegCreateKeyExW() failed with error 0x%lx\n", rc); 297 goto cleanup; 298 } 299 300 rc = RegCreateKeyExW(hKey, L"Connection", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_SET_VALUE, NULL, &hConnectionKey, NULL); 301 RegCloseKey(hKey); 302 hKey = NULL; 303 if (rc != ERROR_SUCCESS) 304 { 305 ERR("RegCreateKeyExW() failed with error 0x%lx\n", rc); 306 goto cleanup; 307 } 308 309 if (!LoadStringW(netcfgx_hInstance, IDS_NET_CONNECT, szBuffer, sizeof(szBuffer)/sizeof(WCHAR))) 310 { 311 wcscpy(szBuffer, L"Network Connection"); 312 } 313 314 rc = RegSetValueExW(hConnectionKey, L"Name", 0, REG_SZ, (const BYTE*)szBuffer, (wcslen(szBuffer) + 1) * sizeof(WCHAR)); 315 if (rc != ERROR_SUCCESS) 316 { 317 ERR("RegSetValueExW() failed with error 0x%lx\n", rc); 318 goto cleanup; 319 } 320 321 rc = RegSetValueExW(hConnectionKey, L"PnpInstanceId", 0, REG_SZ, (const BYTE*)InstanceId, (wcslen(InstanceId) + 1) * sizeof(WCHAR)); 322 if (rc != ERROR_SUCCESS) 323 { 324 ERR("RegSetValueExW() failed with error 0x%lx\n", rc); 325 goto cleanup; 326 } 327 328 dwShowIcon = 1; 329 rc = RegSetValueExW(hConnectionKey, L"ShowIcon", 0, REG_DWORD, (const BYTE*)&dwShowIcon, sizeof(dwShowIcon)); 330 if (rc != ERROR_SUCCESS) 331 { 332 ERR("RegSetValueExW() failed with error 0x%lx\n", rc); 333 goto cleanup; 334 } 335 336 /* Write linkage information in Tcpip service */ 337 rc = RegCreateKeyExW(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Linkage", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_QUERY_VALUE | KEY_SET_VALUE, NULL, &hKey, NULL); 338 if (rc != ERROR_SUCCESS) 339 { 340 ERR("RegCreateKeyExW() failed with error 0x%lx\n", rc); 341 goto cleanup; 342 } 343 rc = AppendStringToMultiSZ(hKey, L"Bind", DeviceName); 344 if (rc != ERROR_SUCCESS) 345 { 346 ERR("AppendStringToMultiSZ() failed with error 0x%lx\n", rc); 347 goto cleanup; 348 } 349 rc = AppendStringToMultiSZ(hKey, L"Export", ExportName); 350 if (rc != ERROR_SUCCESS) 351 { 352 ERR("AppendStringToMultiSZ() failed with error 0x%lx\n", rc); 353 goto cleanup; 354 } 355 rc = AppendStringToMultiSZ(hKey, L"Route", UuidString); 356 if (rc != ERROR_SUCCESS) 357 { 358 ERR("AppendStringToMultiSZ() failed with error 0x%lx\n", rc); 359 goto cleanup; 360 } 361 362 rc = ERROR_SUCCESS; 363 364 cleanup: 365 HeapFree(GetProcessHeap(), 0, InstanceId); 366 HeapFree(GetProcessHeap(), 0, DeviceName); 367 HeapFree(GetProcessHeap(), 0, ExportName); 368 if (hKey != NULL) 369 RegCloseKey(hKey); 370 if (hNetworkKey != NULL) 371 RegCloseKey(hNetworkKey); 372 if (hLinkageKey != NULL) 373 RegCloseKey(hLinkageKey); 374 if (hConnectionKey != NULL) 375 RegCloseKey(hConnectionKey); 376 return rc; 377 } 378 379 static 380 DWORD 381 InstallNetClient(VOID) 382 { 383 FIXME("Installation of network clients is not yet supported\n"); 384 return ERROR_GEN_FAILURE; 385 } 386 387 static 388 DWORD 389 InstallNetService(VOID) 390 { 391 FIXME("Installation of network services is not yet supported\n"); 392 return ERROR_GEN_FAILURE; 393 } 394 395 static 396 DWORD 397 InstallNetTransport(VOID) 398 { 399 FIXME("Installation of network protocols is not yet supported\n"); 400 return ERROR_GEN_FAILURE; 401 } 402 403 DWORD 404 WINAPI 405 NetClassInstaller( 406 IN DI_FUNCTION InstallFunction, 407 IN HDEVINFO DeviceInfoSet, 408 IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL) 409 { 410 SP_DRVINFO_DATA_W DriverInfoData; 411 SP_DRVINFO_DETAIL_DATA_W DriverInfoDetail; 412 WCHAR SectionName[LINE_LEN]; 413 HINF hInf = INVALID_HANDLE_VALUE; 414 INFCONTEXT InfContext; 415 UINT ErrorLine; 416 INT CharacteristicsInt; 417 DWORD Characteristics; 418 LPWSTR BusType = NULL; 419 RPC_STATUS RpcStatus; 420 UUID Uuid; 421 LPWSTR UuidRpcString = NULL; 422 LPWSTR UuidString = NULL; 423 LONG rc; 424 DWORD dwLength; 425 426 if (InstallFunction != DIF_INSTALLDEVICE) 427 return ERROR_DI_DO_DEFAULT; 428 429 TRACE("%lu %p %p\n", InstallFunction, DeviceInfoSet, DeviceInfoData); 430 431 /* Get driver info details */ 432 DriverInfoData.cbSize = sizeof(SP_DRVINFO_DATA_W); 433 if (!SetupDiGetSelectedDriverW(DeviceInfoSet, DeviceInfoData, &DriverInfoData)) 434 { 435 rc = GetLastError(); 436 ERR("SetupDiGetSelectedDriverW() failed with error 0x%lx\n", rc); 437 goto cleanup; 438 } 439 440 DriverInfoDetail.cbSize = sizeof(SP_DRVINFO_DETAIL_DATA_W); 441 if (!SetupDiGetDriverInfoDetailW(DeviceInfoSet, DeviceInfoData, &DriverInfoData, &DriverInfoDetail, sizeof(DriverInfoDetail), NULL) 442 && GetLastError() != ERROR_INSUFFICIENT_BUFFER) 443 { 444 rc = GetLastError(); 445 ERR("SetupDiGetDriverInfoDetailW() failed with error 0x%lx\n", rc); 446 goto cleanup; 447 } 448 449 hInf = SetupOpenInfFileW(DriverInfoDetail.InfFileName, NULL, INF_STYLE_WIN4, &ErrorLine); 450 if (hInf == INVALID_HANDLE_VALUE) 451 { 452 rc = GetLastError(); 453 ERR("SetupOpenInfFileW() failed with error 0x%lx\n", rc); 454 goto cleanup; 455 } 456 457 if (!SetupDiGetActualSectionToInstallW(hInf, DriverInfoDetail.SectionName, SectionName, LINE_LEN, NULL, NULL)) 458 { 459 rc = GetLastError(); 460 ERR("SetupDiGetActualSectionToInstallW() failed with error 0x%lx\n", rc); 461 goto cleanup; 462 } 463 464 /* Get Characteristics and BusType (optional) from .inf file */ 465 if (!SetupFindFirstLineW(hInf, SectionName, L"Characteristics", &InfContext)) 466 { 467 rc = GetLastError(); 468 ERR("Unable to find key %S in section %S of file %S (error 0x%lx)\n", 469 L"Characteristics", SectionName, DriverInfoDetail.InfFileName, rc); 470 goto cleanup; 471 } 472 473 if (!SetupGetIntField(&InfContext, 1, &CharacteristicsInt)) 474 { 475 rc = GetLastError(); 476 ERR("SetupGetIntField() failed with error 0x%lx\n", rc); 477 goto cleanup; 478 } 479 480 Characteristics = (DWORD)CharacteristicsInt; 481 if (IsEqualIID(&DeviceInfoData->ClassGuid, &GUID_DEVCLASS_NET)) 482 { 483 if (SetupFindFirstLineW(hInf, SectionName, L"BusType", &InfContext)) 484 { 485 if (!SetupGetStringFieldW(&InfContext, 1, NULL, 0, &dwLength)) 486 { 487 rc = GetLastError(); 488 ERR("SetupGetStringFieldW() failed with error 0x%lx\n", rc); 489 goto cleanup; 490 } 491 492 BusType = HeapAlloc(GetProcessHeap(), 0, dwLength * sizeof(WCHAR)); 493 if (!BusType) 494 { 495 ERR("HeapAlloc() failed\n"); 496 rc = ERROR_NOT_ENOUGH_MEMORY; 497 goto cleanup; 498 } 499 500 if (!SetupGetStringFieldW(&InfContext, 1, BusType, dwLength, NULL)) 501 { 502 rc = GetLastError(); 503 ERR("SetupGetStringFieldW() failed with error 0x%lx\n", rc); 504 goto cleanup; 505 } 506 } 507 } 508 509 /* Create a new UUID */ 510 RpcStatus = UuidCreate(&Uuid); 511 if (RpcStatus != RPC_S_OK && RpcStatus != RPC_S_UUID_LOCAL_ONLY) 512 { 513 ERR("UuidCreate() failed with RPC status 0x%lx\n", RpcStatus); 514 rc = ERROR_GEN_FAILURE; 515 goto cleanup; 516 } 517 518 RpcStatus = UuidToStringW(&Uuid, &UuidRpcString); 519 if (RpcStatus != RPC_S_OK) 520 { 521 ERR("UuidToStringW() failed with RPC status 0x%lx\n", RpcStatus); 522 rc = ERROR_GEN_FAILURE; 523 goto cleanup; 524 } 525 526 /* Add curly braces around Uuid */ 527 UuidString = HeapAlloc(GetProcessHeap(), 0, (2 + wcslen(UuidRpcString)) * sizeof(WCHAR) + sizeof(UNICODE_NULL)); 528 if (!UuidString) 529 { 530 ERR("HeapAlloc() failed\n"); 531 rc = ERROR_NOT_ENOUGH_MEMORY; 532 goto cleanup; 533 } 534 535 wcscpy(UuidString, L"{"); 536 wcscat(UuidString, UuidRpcString); 537 wcscat(UuidString, L"}"); 538 539 if (IsEqualIID(&DeviceInfoData->ClassGuid, &GUID_DEVCLASS_NET)) 540 rc = InstallNetDevice(DeviceInfoSet, DeviceInfoData, UuidString, Characteristics, BusType); 541 else if (IsEqualIID(&DeviceInfoData->ClassGuid, &GUID_DEVCLASS_NETCLIENT)) 542 rc = InstallNetClient(); 543 else if (IsEqualIID(&DeviceInfoData->ClassGuid, &GUID_DEVCLASS_NETSERVICE)) 544 rc = InstallNetService(); 545 else if (IsEqualIID(&DeviceInfoData->ClassGuid, &GUID_DEVCLASS_NETTRANS)) 546 rc = InstallNetTransport(); 547 else 548 { 549 ERR("Invalid class guid\n"); 550 rc = ERROR_GEN_FAILURE; 551 } 552 553 cleanup: 554 if (hInf != INVALID_HANDLE_VALUE) 555 SetupCloseInfFile(hInf); 556 if (UuidRpcString != NULL) 557 RpcStringFreeW(&UuidRpcString); 558 HeapFree(GetProcessHeap(), 0, BusType); 559 HeapFree(GetProcessHeap(), 0, UuidString); 560 561 if (rc == ERROR_SUCCESS) 562 rc = ERROR_DI_DO_DEFAULT; 563 TRACE("Returning 0x%lx\n", rc); 564 return rc; 565 } 566