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 SP_DEVINSTALL_PARAMS_W DeviceInstallParams; 103 LPWSTR InstanceId = NULL; 104 LPWSTR ComponentId = NULL; 105 LPWSTR DeviceName = NULL; 106 LPWSTR ExportName = NULL; 107 LONG rc; 108 HKEY hKey = NULL; 109 HKEY hNetworkKey = NULL; 110 HKEY hLinkageKey = NULL; 111 HKEY hConnectionKey = NULL; 112 DWORD dwShowIcon, dwLength, dwValue; 113 WCHAR szBuffer[300]; 114 PWSTR ptr; 115 116 DeviceInstallParams.cbSize = sizeof(DeviceInstallParams); 117 if (!SetupDiGetDeviceInstallParamsW(DeviceInfoSet, 118 DeviceInfoData, 119 &DeviceInstallParams)) 120 { 121 rc = GetLastError(); 122 ERR("SetupDiGetDeviceInstallParamsW() failed (Error %lu)\n", rc); 123 goto cleanup; 124 } 125 126 /* Do not start the adapter in the call to SetupDiInstallDevice */ 127 DeviceInstallParams.Flags |= DI_DONOTCALLCONFIGMG; 128 129 if (!SetupDiSetDeviceInstallParamsW(DeviceInfoSet, 130 DeviceInfoData, 131 &DeviceInstallParams)) 132 { 133 rc = GetLastError(); 134 ERR("SetupDiSetDeviceInstallParamsW() failed (Error %lu)\n", rc); 135 goto cleanup; 136 } 137 138 /* Install the adapter */ 139 if (!SetupDiInstallDevice(DeviceInfoSet, DeviceInfoData)) 140 { 141 rc = GetLastError(); 142 ERR("SetupDiInstallDevice() failed (Error %lu)\n", rc); 143 goto cleanup; 144 } 145 146 /* Get Instance ID */ 147 if (SetupDiGetDeviceInstanceIdW(DeviceInfoSet, DeviceInfoData, NULL, 0, &dwLength)) 148 { 149 ERR("SetupDiGetDeviceInstanceIdW() returned TRUE. FALSE expected\n"); 150 rc = ERROR_GEN_FAILURE; 151 goto cleanup; 152 } 153 154 InstanceId = HeapAlloc(GetProcessHeap(), 0, dwLength * sizeof(WCHAR)); 155 if (!InstanceId) 156 { 157 ERR("HeapAlloc() failed\n"); 158 rc = ERROR_NOT_ENOUGH_MEMORY; 159 goto cleanup; 160 } 161 162 if (!SetupDiGetDeviceInstanceIdW(DeviceInfoSet, DeviceInfoData, InstanceId, dwLength, NULL)) 163 { 164 rc = GetLastError(); 165 ERR("SetupDiGetDeviceInstanceIdW() failed with error 0x%lx\n", rc); 166 goto cleanup; 167 } 168 169 ComponentId = HeapAlloc(GetProcessHeap(), 0, dwLength * sizeof(WCHAR)); 170 if (!ComponentId) 171 { 172 ERR("HeapAlloc() failed\n"); 173 rc = ERROR_NOT_ENOUGH_MEMORY; 174 goto cleanup; 175 } 176 177 wcscpy(ComponentId, InstanceId); 178 ptr = wcsrchr(ComponentId, L'\\'); 179 if (ptr != NULL) 180 *ptr = UNICODE_NULL; 181 182 /* Create device name */ 183 DeviceName = HeapAlloc(GetProcessHeap(), 0, (wcslen(L"\\Device\\") + wcslen(UuidString)) * sizeof(WCHAR) + sizeof(UNICODE_NULL)); 184 if (!DeviceName) 185 { 186 ERR("HeapAlloc() failed\n"); 187 rc = ERROR_NOT_ENOUGH_MEMORY; 188 goto cleanup; 189 } 190 wcscpy(DeviceName, L"\\Device\\"); 191 wcscat(DeviceName, UuidString); 192 193 /* Create export name */ 194 ExportName = HeapAlloc(GetProcessHeap(), 0, (wcslen(L"\\Device\\Tcpip_") + wcslen(UuidString)) * sizeof(WCHAR) + sizeof(UNICODE_NULL)); 195 if (!ExportName) 196 { 197 ERR("HeapAlloc() failed\n"); 198 rc = ERROR_NOT_ENOUGH_MEMORY; 199 goto cleanup; 200 } 201 wcscpy(ExportName, L"\\Device\\Tcpip_"); 202 wcscat(ExportName, UuidString); 203 204 /* Write Tcpip parameters in new service Key */ 205 rc = RegCreateKeyExW(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Services", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_CREATE_SUB_KEY, NULL, &hKey, NULL); 206 if (rc != ERROR_SUCCESS) 207 { 208 ERR("RegCreateKeyExW() failed with error 0x%lx\n", rc); 209 goto cleanup; 210 } 211 212 rc = RegCreateKeyExW(hKey, UuidString, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_CREATE_SUB_KEY, NULL, &hNetworkKey, NULL); 213 if (rc != ERROR_SUCCESS) 214 { 215 ERR("RegCreateKeyExW() failed with error 0x%lx\n", rc); 216 goto cleanup; 217 } 218 RegCloseKey(hKey); 219 hKey = NULL; 220 221 rc = RegCreateKeyExW(hNetworkKey, L"Parameters\\Tcpip", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_SET_VALUE, NULL, &hKey, NULL); 222 if (rc != ERROR_SUCCESS) 223 { 224 ERR("RegCreateKeyExW() failed with error 0x%lx\n", rc); 225 goto cleanup; 226 } 227 RegCloseKey(hNetworkKey); 228 hNetworkKey = NULL; 229 230 rc = RegSetValueExW(hKey, L"DefaultGateway", 0, REG_SZ, (const BYTE*)L"0.0.0.0", (wcslen(L"0.0.0.0") + 1) * sizeof(WCHAR)); 231 if (rc != ERROR_SUCCESS) 232 { 233 ERR("RegSetValueExW() failed with error 0x%lx\n", rc); 234 goto cleanup; 235 } 236 237 rc = RegSetValueExW(hKey, L"IPAddress", 0, REG_SZ, (const BYTE*)L"0.0.0.0", (wcslen(L"0.0.0.0") + 1) * sizeof(WCHAR)); 238 if (rc != ERROR_SUCCESS) 239 { 240 ERR("RegSetValueExW() failed with error 0x%lx\n", rc); 241 goto cleanup; 242 } 243 244 rc = RegSetValueExW(hKey, L"SubnetMask", 0, REG_SZ, (const BYTE*)L"0.0.0.0", (wcslen(L"0.0.0.0") + 1) * sizeof(WCHAR)); 245 if (rc != ERROR_SUCCESS) 246 { 247 ERR("RegSetValueExW() failed with error 0x%lx\n", rc); 248 goto cleanup; 249 } 250 251 dwValue = 1; 252 rc = RegSetValueExW(hKey, L"EnableDHCP", 0, REG_DWORD, (const BYTE*)&dwValue, sizeof(DWORD)); 253 if (rc != ERROR_SUCCESS) 254 { 255 ERR("RegSetValueExW() failed with error 0x%lx\n", rc); 256 goto cleanup; 257 } 258 RegCloseKey(hKey); 259 hKey = NULL; 260 261 /* Write 'Linkage' key in hardware key */ 262 #if _WIN32_WINNT >= 0x502 263 hKey = SetupDiOpenDevRegKey(DeviceInfoSet, DeviceInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DRV, KEY_READ | KEY_WRITE); 264 #else 265 hKey = SetupDiOpenDevRegKey(DeviceInfoSet, DeviceInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DRV, KEY_ALL_ACCESS); 266 #endif 267 if (hKey == INVALID_HANDLE_VALUE && GetLastError() == ERROR_FILE_NOT_FOUND) 268 hKey = SetupDiCreateDevRegKeyW(DeviceInfoSet, DeviceInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DRV, NULL, NULL); 269 if (hKey == INVALID_HANDLE_VALUE) 270 { 271 hKey = NULL; 272 rc = GetLastError(); 273 ERR("SetupDiCreateDevRegKeyW() failed with error 0x%lx\n", rc); 274 goto cleanup; 275 } 276 277 rc = RegSetValueExW(hKey, L"NetCfgInstanceId", 0, REG_SZ, (const BYTE*)UuidString, (wcslen(UuidString) + 1) * sizeof(WCHAR)); 278 if (rc != ERROR_SUCCESS) 279 { 280 ERR("RegSetValueExW() failed with error 0x%lx\n", rc); 281 goto cleanup; 282 } 283 284 rc = RegSetValueExW(hKey, L"Characteristics", 0, REG_DWORD, (const BYTE*)&Characteristics, sizeof(DWORD)); 285 if (rc != ERROR_SUCCESS) 286 { 287 ERR("RegSetValueExW() failed with error 0x%lx\n", rc); 288 goto cleanup; 289 } 290 291 rc = RegSetValueExW(hKey, L"ComponentId", 0, REG_SZ, (const BYTE*)ComponentId, (wcslen(ComponentId) + 1) * sizeof(WCHAR)); 292 if (rc != ERROR_SUCCESS) 293 { 294 ERR("RegSetValueExW() failed with error 0x%lx\n", rc); 295 goto cleanup; 296 } 297 298 if (BusType) 299 { 300 rc = RegSetValueExW(hKey, L"BusType", 0, REG_SZ, (const BYTE*)BusType, (wcslen(BusType) + 1) * sizeof(WCHAR)); 301 if (rc != ERROR_SUCCESS) 302 { 303 ERR("RegSetValueExW() failed with error 0x%lx\n", rc); 304 goto cleanup; 305 } 306 } 307 308 rc = RegCreateKeyExW(hKey, L"Linkage", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_SET_VALUE, NULL, &hLinkageKey, NULL); 309 if (rc != ERROR_SUCCESS) 310 { 311 ERR("RegCreateKeyExW() failed with error 0x%lx\n", rc); 312 goto cleanup; 313 } 314 315 rc = RegSetValueExW(hLinkageKey, L"Export", 0, REG_SZ, (const BYTE*)DeviceName, (wcslen(DeviceName) + 1) * sizeof(WCHAR)); 316 if (rc != ERROR_SUCCESS) 317 { 318 ERR("RegSetValueExW() failed with error 0x%lx\n", rc); 319 goto cleanup; 320 } 321 322 rc = RegSetValueExW(hLinkageKey, L"RootDevice", 0, REG_SZ, (const BYTE*)UuidString, (wcslen(UuidString) + 1) * sizeof(WCHAR)); 323 if (rc != ERROR_SUCCESS) 324 { 325 ERR("RegSetValueExW() failed with error 0x%lx\n", rc); 326 goto cleanup; 327 } 328 329 rc = RegSetValueExW(hLinkageKey, L"UpperBind", 0, REG_SZ, (const BYTE*)L"Tcpip", (wcslen(L"Tcpip") + 1) * sizeof(WCHAR)); 330 if (rc != ERROR_SUCCESS) 331 { 332 ERR("RegSetValueExW() failed with error 0x%lx\n", rc); 333 goto cleanup; 334 } 335 RegCloseKey(hKey); 336 hKey = NULL; 337 338 /* Write connection information in network subkey */ 339 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); 340 if (rc != ERROR_SUCCESS) 341 { 342 ERR("RegCreateKeyExW() failed with error 0x%lx\n", rc); 343 goto cleanup; 344 } 345 346 rc = RegCreateKeyExW(hNetworkKey, UuidString, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_CREATE_SUB_KEY, NULL, &hKey, NULL); 347 if (rc != ERROR_SUCCESS) 348 { 349 ERR("RegCreateKeyExW() failed with error 0x%lx\n", rc); 350 goto cleanup; 351 } 352 353 rc = RegCreateKeyExW(hKey, L"Connection", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_SET_VALUE, NULL, &hConnectionKey, NULL); 354 RegCloseKey(hKey); 355 hKey = NULL; 356 if (rc != ERROR_SUCCESS) 357 { 358 ERR("RegCreateKeyExW() failed with error 0x%lx\n", rc); 359 goto cleanup; 360 } 361 362 if (!LoadStringW(netcfgx_hInstance, IDS_NET_CONNECT, szBuffer, sizeof(szBuffer)/sizeof(WCHAR))) 363 { 364 wcscpy(szBuffer, L"Network Connection"); 365 } 366 367 rc = RegSetValueExW(hConnectionKey, L"Name", 0, REG_SZ, (const BYTE*)szBuffer, (wcslen(szBuffer) + 1) * sizeof(WCHAR)); 368 if (rc != ERROR_SUCCESS) 369 { 370 ERR("RegSetValueExW() failed with error 0x%lx\n", rc); 371 goto cleanup; 372 } 373 374 rc = RegSetValueExW(hConnectionKey, L"PnpInstanceID", 0, REG_SZ, (const BYTE*)InstanceId, (wcslen(InstanceId) + 1) * sizeof(WCHAR)); 375 if (rc != ERROR_SUCCESS) 376 { 377 ERR("RegSetValueExW() failed with error 0x%lx\n", rc); 378 goto cleanup; 379 } 380 381 dwShowIcon = 1; 382 rc = RegSetValueExW(hConnectionKey, L"ShowIcon", 0, REG_DWORD, (const BYTE*)&dwShowIcon, sizeof(dwShowIcon)); 383 if (rc != ERROR_SUCCESS) 384 { 385 ERR("RegSetValueExW() failed with error 0x%lx\n", rc); 386 goto cleanup; 387 } 388 389 /* Write linkage information in Tcpip service */ 390 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); 391 if (rc != ERROR_SUCCESS) 392 { 393 ERR("RegCreateKeyExW() failed with error 0x%lx\n", rc); 394 goto cleanup; 395 } 396 rc = AppendStringToMultiSZ(hKey, L"Bind", DeviceName); 397 if (rc != ERROR_SUCCESS) 398 { 399 ERR("AppendStringToMultiSZ() failed with error 0x%lx\n", rc); 400 goto cleanup; 401 } 402 rc = AppendStringToMultiSZ(hKey, L"Export", ExportName); 403 if (rc != ERROR_SUCCESS) 404 { 405 ERR("AppendStringToMultiSZ() failed with error 0x%lx\n", rc); 406 goto cleanup; 407 } 408 rc = AppendStringToMultiSZ(hKey, L"Route", UuidString); 409 if (rc != ERROR_SUCCESS) 410 { 411 ERR("AppendStringToMultiSZ() failed with error 0x%lx\n", rc); 412 goto cleanup; 413 } 414 415 /* Start the device */ 416 if (!SetupDiRestartDevices(DeviceInfoSet, DeviceInfoData)) 417 { 418 rc = GetLastError(); 419 ERR("SetupDiRestartDevices() failed with error 0x%lx\n", rc); 420 goto cleanup; 421 } 422 423 rc = ERROR_SUCCESS; 424 425 cleanup: 426 HeapFree(GetProcessHeap(), 0, InstanceId); 427 HeapFree(GetProcessHeap(), 0, ComponentId); 428 HeapFree(GetProcessHeap(), 0, DeviceName); 429 HeapFree(GetProcessHeap(), 0, ExportName); 430 if (hKey != NULL) 431 RegCloseKey(hKey); 432 if (hNetworkKey != NULL) 433 RegCloseKey(hNetworkKey); 434 if (hLinkageKey != NULL) 435 RegCloseKey(hLinkageKey); 436 if (hConnectionKey != NULL) 437 RegCloseKey(hConnectionKey); 438 439 return rc; 440 } 441 442 static 443 DWORD 444 InstallNetClient(VOID) 445 { 446 FIXME("Installation of network clients is not yet supported\n"); 447 return ERROR_GEN_FAILURE; 448 } 449 450 static 451 DWORD 452 InstallNetService(VOID) 453 { 454 FIXME("Installation of network services is not yet supported\n"); 455 return ERROR_GEN_FAILURE; 456 } 457 458 static 459 DWORD 460 InstallNetTransport(VOID) 461 { 462 FIXME("Installation of network protocols is not yet supported\n"); 463 return ERROR_GEN_FAILURE; 464 } 465 466 DWORD 467 WINAPI 468 NetClassInstaller( 469 IN DI_FUNCTION InstallFunction, 470 IN HDEVINFO DeviceInfoSet, 471 IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL) 472 { 473 SP_DRVINFO_DATA_W DriverInfoData; 474 SP_DRVINFO_DETAIL_DATA_W DriverInfoDetail; 475 WCHAR SectionName[LINE_LEN]; 476 HINF hInf = INVALID_HANDLE_VALUE; 477 INFCONTEXT InfContext; 478 UINT ErrorLine; 479 INT CharacteristicsInt; 480 DWORD Characteristics; 481 LPWSTR BusType = NULL; 482 RPC_STATUS RpcStatus; 483 UUID Uuid; 484 LPWSTR UuidRpcString = NULL; 485 LPWSTR UuidString = NULL; 486 LONG rc; 487 DWORD dwLength; 488 489 if (InstallFunction != DIF_INSTALLDEVICE) 490 return ERROR_DI_DO_DEFAULT; 491 492 TRACE("%lu %p %p\n", InstallFunction, DeviceInfoSet, DeviceInfoData); 493 494 /* Get driver info details */ 495 DriverInfoData.cbSize = sizeof(SP_DRVINFO_DATA_W); 496 if (!SetupDiGetSelectedDriverW(DeviceInfoSet, DeviceInfoData, &DriverInfoData)) 497 { 498 rc = GetLastError(); 499 ERR("SetupDiGetSelectedDriverW() failed with error 0x%lx\n", rc); 500 goto cleanup; 501 } 502 503 DriverInfoDetail.cbSize = sizeof(SP_DRVINFO_DETAIL_DATA_W); 504 if (!SetupDiGetDriverInfoDetailW(DeviceInfoSet, DeviceInfoData, &DriverInfoData, &DriverInfoDetail, sizeof(DriverInfoDetail), NULL) 505 && GetLastError() != ERROR_INSUFFICIENT_BUFFER) 506 { 507 rc = GetLastError(); 508 ERR("SetupDiGetDriverInfoDetailW() failed with error 0x%lx\n", rc); 509 goto cleanup; 510 } 511 512 hInf = SetupOpenInfFileW(DriverInfoDetail.InfFileName, NULL, INF_STYLE_WIN4, &ErrorLine); 513 if (hInf == INVALID_HANDLE_VALUE) 514 { 515 rc = GetLastError(); 516 ERR("SetupOpenInfFileW() failed with error 0x%lx\n", rc); 517 goto cleanup; 518 } 519 520 if (!SetupDiGetActualSectionToInstallW(hInf, DriverInfoDetail.SectionName, SectionName, LINE_LEN, NULL, NULL)) 521 { 522 rc = GetLastError(); 523 ERR("SetupDiGetActualSectionToInstallW() failed with error 0x%lx\n", rc); 524 goto cleanup; 525 } 526 527 /* Get Characteristics and BusType (optional) from .inf file */ 528 if (!SetupFindFirstLineW(hInf, SectionName, L"Characteristics", &InfContext)) 529 { 530 rc = GetLastError(); 531 ERR("Unable to find key %S in section %S of file %S (error 0x%lx)\n", 532 L"Characteristics", SectionName, DriverInfoDetail.InfFileName, rc); 533 goto cleanup; 534 } 535 536 if (!SetupGetIntField(&InfContext, 1, &CharacteristicsInt)) 537 { 538 rc = GetLastError(); 539 ERR("SetupGetIntField() failed with error 0x%lx\n", rc); 540 goto cleanup; 541 } 542 543 Characteristics = (DWORD)CharacteristicsInt; 544 if (IsEqualIID(&DeviceInfoData->ClassGuid, &GUID_DEVCLASS_NET)) 545 { 546 if (SetupFindFirstLineW(hInf, SectionName, L"BusType", &InfContext)) 547 { 548 if (!SetupGetStringFieldW(&InfContext, 1, NULL, 0, &dwLength)) 549 { 550 rc = GetLastError(); 551 ERR("SetupGetStringFieldW() failed with error 0x%lx\n", rc); 552 goto cleanup; 553 } 554 555 BusType = HeapAlloc(GetProcessHeap(), 0, dwLength * sizeof(WCHAR)); 556 if (!BusType) 557 { 558 ERR("HeapAlloc() failed\n"); 559 rc = ERROR_NOT_ENOUGH_MEMORY; 560 goto cleanup; 561 } 562 563 if (!SetupGetStringFieldW(&InfContext, 1, BusType, dwLength, NULL)) 564 { 565 rc = GetLastError(); 566 ERR("SetupGetStringFieldW() failed with error 0x%lx\n", rc); 567 goto cleanup; 568 } 569 } 570 } 571 572 /* Create a new UUID */ 573 RpcStatus = UuidCreate(&Uuid); 574 if (RpcStatus != RPC_S_OK && RpcStatus != RPC_S_UUID_LOCAL_ONLY) 575 { 576 ERR("UuidCreate() failed with RPC status 0x%lx\n", RpcStatus); 577 rc = ERROR_GEN_FAILURE; 578 goto cleanup; 579 } 580 581 RpcStatus = UuidToStringW(&Uuid, &UuidRpcString); 582 if (RpcStatus != RPC_S_OK) 583 { 584 ERR("UuidToStringW() failed with RPC status 0x%lx\n", RpcStatus); 585 rc = ERROR_GEN_FAILURE; 586 goto cleanup; 587 } 588 589 /* Add curly braces around Uuid */ 590 UuidString = HeapAlloc(GetProcessHeap(), 0, (2 + wcslen(UuidRpcString)) * sizeof(WCHAR) + sizeof(UNICODE_NULL)); 591 if (!UuidString) 592 { 593 ERR("HeapAlloc() failed\n"); 594 rc = ERROR_NOT_ENOUGH_MEMORY; 595 goto cleanup; 596 } 597 598 wcscpy(UuidString, L"{"); 599 wcscat(UuidString, UuidRpcString); 600 wcscat(UuidString, L"}"); 601 602 if (IsEqualIID(&DeviceInfoData->ClassGuid, &GUID_DEVCLASS_NET)) 603 rc = InstallNetDevice(DeviceInfoSet, DeviceInfoData, UuidString, Characteristics, BusType); 604 else if (IsEqualIID(&DeviceInfoData->ClassGuid, &GUID_DEVCLASS_NETCLIENT)) 605 rc = InstallNetClient(); 606 else if (IsEqualIID(&DeviceInfoData->ClassGuid, &GUID_DEVCLASS_NETSERVICE)) 607 rc = InstallNetService(); 608 else if (IsEqualIID(&DeviceInfoData->ClassGuid, &GUID_DEVCLASS_NETTRANS)) 609 rc = InstallNetTransport(); 610 else 611 { 612 ERR("Invalid class guid\n"); 613 rc = ERROR_GEN_FAILURE; 614 } 615 616 cleanup: 617 if (hInf != INVALID_HANDLE_VALUE) 618 SetupCloseInfFile(hInf); 619 if (UuidRpcString != NULL) 620 RpcStringFreeW(&UuidRpcString); 621 HeapFree(GetProcessHeap(), 0, BusType); 622 HeapFree(GetProcessHeap(), 0, UuidString); 623 624 TRACE("Returning 0x%lx\n", rc); 625 return rc; 626 } 627