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 #include <strsafe.h> 12 13 14 /* Append a REG_SZ to an existing REG_MULTI_SZ string in the registry. 15 * If the value doesn't exist, create it. 16 * Returns ERROR_SUCCESS if success. Otherwise, returns an error code 17 */ 18 static 19 LONG 20 AppendStringToMultiSZ( 21 IN HKEY hKey, 22 IN PCWSTR ValueName, 23 IN PCWSTR ValueToAppend) 24 { 25 PWSTR Buffer = NULL; 26 DWORD dwRegType; 27 DWORD dwRequired, dwLength; 28 DWORD dwTmp; 29 LONG rc; 30 31 rc = RegQueryValueExW(hKey, 32 ValueName, 33 NULL, 34 &dwRegType, 35 NULL, 36 &dwRequired); 37 if (rc != ERROR_FILE_NOT_FOUND) 38 { 39 if (rc != ERROR_SUCCESS) 40 goto cleanup; 41 if (dwRegType != REG_MULTI_SZ) 42 { 43 rc = ERROR_GEN_FAILURE; 44 goto cleanup; 45 } 46 47 dwTmp = dwLength = dwRequired + wcslen(ValueToAppend) * sizeof(WCHAR) + sizeof(UNICODE_NULL); 48 Buffer = HeapAlloc(GetProcessHeap(), 0, dwLength); 49 if (!Buffer) 50 { 51 rc = ERROR_NOT_ENOUGH_MEMORY; 52 goto cleanup; 53 } 54 55 rc = RegQueryValueExW(hKey, 56 ValueName, 57 NULL, 58 NULL, 59 (BYTE*)Buffer, 60 &dwTmp); 61 if (rc != ERROR_SUCCESS) 62 goto cleanup; 63 } 64 else 65 { 66 dwRequired = sizeof(WCHAR); 67 dwLength = wcslen(ValueToAppend) * sizeof(WCHAR) + 2 * sizeof(UNICODE_NULL); 68 Buffer = HeapAlloc(GetProcessHeap(), 0, dwLength); 69 if (!Buffer) 70 { 71 rc = ERROR_NOT_ENOUGH_MEMORY; 72 goto cleanup; 73 } 74 } 75 76 /* Append the value */ 77 wcscpy(&Buffer[dwRequired / sizeof(WCHAR) - 1], ValueToAppend); 78 /* Terminate the REG_MULTI_SZ string */ 79 Buffer[dwLength / sizeof(WCHAR) - 1] = UNICODE_NULL; 80 81 rc = RegSetValueExW(hKey, 82 ValueName, 83 0, 84 REG_MULTI_SZ, 85 (const BYTE*)Buffer, 86 dwLength); 87 88 cleanup: 89 HeapFree(GetProcessHeap(), 0, Buffer); 90 return rc; 91 } 92 93 static 94 DWORD 95 GetUniqueConnectionName( 96 _In_ HKEY hNetworkKey, 97 _Out_ PWSTR *ppszNameBuffer) 98 { 99 int Length = 0; 100 PWSTR pszDefaultName = NULL; 101 PWSTR pszNameBuffer = NULL; 102 DWORD dwSubKeys = 0; 103 DWORD dwError; 104 105 TRACE("GetNewConnectionName()\n"); 106 107 Length = LoadStringW(netcfgx_hInstance, IDS_NET_CONNECT, (LPWSTR)&pszDefaultName, 0); 108 if (Length == 0) 109 { 110 pszDefaultName = L"Network Connection"; 111 Length = wcslen(pszDefaultName); 112 } 113 114 TRACE("Length %d\n", Length); 115 116 dwError = RegQueryInfoKeyW(hNetworkKey, 117 NULL, NULL, NULL, &dwSubKeys, 118 NULL, NULL, NULL, NULL, NULL, NULL, NULL); 119 if (dwError != ERROR_SUCCESS) 120 { 121 ERR("RegQueryInfoKeyW: Error %lu\n", dwError); 122 return dwError; 123 } 124 125 TRACE("Adapter Count: %lu\n", dwSubKeys); 126 127 pszNameBuffer = HeapAlloc(GetProcessHeap(), 128 HEAP_ZERO_MEMORY, 129 (Length + ((dwSubKeys != 0) ? 6 : 1)) * sizeof(WCHAR)); 130 if (pszNameBuffer == NULL) 131 { 132 return ERROR_OUTOFMEMORY; 133 } 134 135 if (dwSubKeys != 0) 136 StringCchPrintfW(pszNameBuffer, Length + 6, L"%.*s %lu", Length, pszDefaultName, dwSubKeys + 1); 137 else 138 StringCchPrintfW(pszNameBuffer, Length + 1, L"%.*s", Length, pszDefaultName); 139 140 TRACE("Adapter Name: %S\n", pszNameBuffer); 141 142 *ppszNameBuffer = pszNameBuffer; 143 144 return ERROR_SUCCESS; 145 } 146 147 static 148 DWORD 149 InstallNetDevice( 150 IN HDEVINFO DeviceInfoSet, 151 IN PSP_DEVINFO_DATA DeviceInfoData, 152 LPCWSTR UuidString, 153 DWORD Characteristics, 154 LPCWSTR BusType) 155 { 156 SP_DEVINSTALL_PARAMS_W DeviceInstallParams; 157 LPWSTR InstanceId = NULL; 158 LPWSTR ComponentId = NULL; 159 LPWSTR DeviceName = NULL; 160 LPWSTR ExportName = NULL; 161 LONG rc; 162 HKEY hKey = NULL; 163 HKEY hNetworkKey = NULL; 164 HKEY hLinkageKey = NULL; 165 HKEY hConnectionKey = NULL; 166 DWORD dwShowIcon, dwLength, dwValue; 167 PWSTR pszNameBuffer = NULL; 168 PWSTR ptr; 169 170 DeviceInstallParams.cbSize = sizeof(DeviceInstallParams); 171 if (!SetupDiGetDeviceInstallParamsW(DeviceInfoSet, 172 DeviceInfoData, 173 &DeviceInstallParams)) 174 { 175 rc = GetLastError(); 176 ERR("SetupDiGetDeviceInstallParamsW() failed (Error %lu)\n", rc); 177 goto cleanup; 178 } 179 180 /* Do not start the adapter in the call to SetupDiInstallDevice */ 181 DeviceInstallParams.Flags |= DI_DONOTCALLCONFIGMG; 182 183 if (!SetupDiSetDeviceInstallParamsW(DeviceInfoSet, 184 DeviceInfoData, 185 &DeviceInstallParams)) 186 { 187 rc = GetLastError(); 188 ERR("SetupDiSetDeviceInstallParamsW() failed (Error %lu)\n", rc); 189 goto cleanup; 190 } 191 192 /* Install the adapter */ 193 if (!SetupDiInstallDevice(DeviceInfoSet, DeviceInfoData)) 194 { 195 rc = GetLastError(); 196 ERR("SetupDiInstallDevice() failed (Error %lu)\n", rc); 197 goto cleanup; 198 } 199 200 /* Get Instance ID */ 201 if (SetupDiGetDeviceInstanceIdW(DeviceInfoSet, DeviceInfoData, NULL, 0, &dwLength)) 202 { 203 ERR("SetupDiGetDeviceInstanceIdW() returned TRUE. FALSE expected\n"); 204 rc = ERROR_GEN_FAILURE; 205 goto cleanup; 206 } 207 208 InstanceId = HeapAlloc(GetProcessHeap(), 0, dwLength * sizeof(WCHAR)); 209 if (!InstanceId) 210 { 211 ERR("HeapAlloc() failed\n"); 212 rc = ERROR_NOT_ENOUGH_MEMORY; 213 goto cleanup; 214 } 215 216 if (!SetupDiGetDeviceInstanceIdW(DeviceInfoSet, DeviceInfoData, InstanceId, dwLength, NULL)) 217 { 218 rc = GetLastError(); 219 ERR("SetupDiGetDeviceInstanceIdW() failed with error 0x%lx\n", rc); 220 goto cleanup; 221 } 222 223 ComponentId = HeapAlloc(GetProcessHeap(), 0, dwLength * sizeof(WCHAR)); 224 if (!ComponentId) 225 { 226 ERR("HeapAlloc() failed\n"); 227 rc = ERROR_NOT_ENOUGH_MEMORY; 228 goto cleanup; 229 } 230 231 wcscpy(ComponentId, InstanceId); 232 ptr = wcsrchr(ComponentId, L'\\'); 233 if (ptr != NULL) 234 *ptr = UNICODE_NULL; 235 236 /* Create device name */ 237 DeviceName = HeapAlloc(GetProcessHeap(), 0, (wcslen(L"\\Device\\") + wcslen(UuidString)) * sizeof(WCHAR) + sizeof(UNICODE_NULL)); 238 if (!DeviceName) 239 { 240 ERR("HeapAlloc() failed\n"); 241 rc = ERROR_NOT_ENOUGH_MEMORY; 242 goto cleanup; 243 } 244 wcscpy(DeviceName, L"\\Device\\"); 245 wcscat(DeviceName, UuidString); 246 247 /* Create export name */ 248 ExportName = HeapAlloc(GetProcessHeap(), 0, (wcslen(L"\\Device\\Tcpip_") + wcslen(UuidString)) * sizeof(WCHAR) + sizeof(UNICODE_NULL)); 249 if (!ExportName) 250 { 251 ERR("HeapAlloc() failed\n"); 252 rc = ERROR_NOT_ENOUGH_MEMORY; 253 goto cleanup; 254 } 255 wcscpy(ExportName, L"\\Device\\Tcpip_"); 256 wcscat(ExportName, UuidString); 257 258 /* Write Tcpip parameters in new service Key */ 259 rc = RegCreateKeyExW(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Services", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_CREATE_SUB_KEY, NULL, &hKey, NULL); 260 if (rc != ERROR_SUCCESS) 261 { 262 ERR("RegCreateKeyExW() failed with error 0x%lx\n", rc); 263 goto cleanup; 264 } 265 266 rc = RegCreateKeyExW(hKey, UuidString, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_CREATE_SUB_KEY, NULL, &hNetworkKey, NULL); 267 if (rc != ERROR_SUCCESS) 268 { 269 ERR("RegCreateKeyExW() failed with error 0x%lx\n", rc); 270 goto cleanup; 271 } 272 RegCloseKey(hKey); 273 hKey = NULL; 274 275 rc = RegCreateKeyExW(hNetworkKey, L"Parameters\\Tcpip", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_SET_VALUE, NULL, &hKey, NULL); 276 if (rc != ERROR_SUCCESS) 277 { 278 ERR("RegCreateKeyExW() failed with error 0x%lx\n", rc); 279 goto cleanup; 280 } 281 RegCloseKey(hNetworkKey); 282 hNetworkKey = NULL; 283 284 rc = RegSetValueExW(hKey, L"DefaultGateway", 0, REG_SZ, (const BYTE*)L"0.0.0.0", (wcslen(L"0.0.0.0") + 1) * sizeof(WCHAR)); 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"IPAddress", 0, REG_SZ, (const BYTE*)L"0.0.0.0", (wcslen(L"0.0.0.0") + 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 rc = RegSetValueExW(hKey, L"SubnetMask", 0, REG_SZ, (const BYTE*)L"0.0.0.0", (wcslen(L"0.0.0.0") + 1) * sizeof(WCHAR)); 299 if (rc != ERROR_SUCCESS) 300 { 301 ERR("RegSetValueExW() failed with error 0x%lx\n", rc); 302 goto cleanup; 303 } 304 305 dwValue = 1; 306 rc = RegSetValueExW(hKey, L"EnableDHCP", 0, REG_DWORD, (const BYTE*)&dwValue, sizeof(DWORD)); 307 if (rc != ERROR_SUCCESS) 308 { 309 ERR("RegSetValueExW() failed with error 0x%lx\n", rc); 310 goto cleanup; 311 } 312 RegCloseKey(hKey); 313 hKey = NULL; 314 315 /* Write 'Linkage' key in hardware key */ 316 #if _WIN32_WINNT >= 0x502 317 hKey = SetupDiOpenDevRegKey(DeviceInfoSet, DeviceInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DRV, KEY_READ | KEY_WRITE); 318 #else 319 hKey = SetupDiOpenDevRegKey(DeviceInfoSet, DeviceInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DRV, KEY_ALL_ACCESS); 320 #endif 321 if (hKey == INVALID_HANDLE_VALUE && GetLastError() == ERROR_FILE_NOT_FOUND) 322 hKey = SetupDiCreateDevRegKeyW(DeviceInfoSet, DeviceInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DRV, NULL, NULL); 323 if (hKey == INVALID_HANDLE_VALUE) 324 { 325 hKey = NULL; 326 rc = GetLastError(); 327 ERR("SetupDiCreateDevRegKeyW() failed with error 0x%lx\n", rc); 328 goto cleanup; 329 } 330 331 rc = RegSetValueExW(hKey, L"NetCfgInstanceId", 0, REG_SZ, (const BYTE*)UuidString, (wcslen(UuidString) + 1) * sizeof(WCHAR)); 332 if (rc != ERROR_SUCCESS) 333 { 334 ERR("RegSetValueExW() failed with error 0x%lx\n", rc); 335 goto cleanup; 336 } 337 338 rc = RegSetValueExW(hKey, L"Characteristics", 0, REG_DWORD, (const BYTE*)&Characteristics, sizeof(DWORD)); 339 if (rc != ERROR_SUCCESS) 340 { 341 ERR("RegSetValueExW() failed with error 0x%lx\n", rc); 342 goto cleanup; 343 } 344 345 rc = RegSetValueExW(hKey, L"ComponentId", 0, REG_SZ, (const BYTE*)ComponentId, (wcslen(ComponentId) + 1) * sizeof(WCHAR)); 346 if (rc != ERROR_SUCCESS) 347 { 348 ERR("RegSetValueExW() failed with error 0x%lx\n", rc); 349 goto cleanup; 350 } 351 352 if (BusType) 353 { 354 rc = RegSetValueExW(hKey, L"BusType", 0, REG_SZ, (const BYTE*)BusType, (wcslen(BusType) + 1) * sizeof(WCHAR)); 355 if (rc != ERROR_SUCCESS) 356 { 357 ERR("RegSetValueExW() failed with error 0x%lx\n", rc); 358 goto cleanup; 359 } 360 } 361 362 rc = RegCreateKeyExW(hKey, L"Linkage", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_SET_VALUE, NULL, &hLinkageKey, NULL); 363 if (rc != ERROR_SUCCESS) 364 { 365 ERR("RegCreateKeyExW() failed with error 0x%lx\n", rc); 366 goto cleanup; 367 } 368 369 rc = RegSetValueExW(hLinkageKey, L"Export", 0, REG_SZ, (const BYTE*)DeviceName, (wcslen(DeviceName) + 1) * sizeof(WCHAR)); 370 if (rc != ERROR_SUCCESS) 371 { 372 ERR("RegSetValueExW() failed with error 0x%lx\n", rc); 373 goto cleanup; 374 } 375 376 rc = RegSetValueExW(hLinkageKey, L"RootDevice", 0, REG_SZ, (const BYTE*)UuidString, (wcslen(UuidString) + 1) * sizeof(WCHAR)); 377 if (rc != ERROR_SUCCESS) 378 { 379 ERR("RegSetValueExW() failed with error 0x%lx\n", rc); 380 goto cleanup; 381 } 382 383 rc = RegSetValueExW(hLinkageKey, L"UpperBind", 0, REG_SZ, (const BYTE*)L"Tcpip", (wcslen(L"Tcpip") + 1) * sizeof(WCHAR)); 384 if (rc != ERROR_SUCCESS) 385 { 386 ERR("RegSetValueExW() failed with error 0x%lx\n", rc); 387 goto cleanup; 388 } 389 RegCloseKey(hKey); 390 hKey = NULL; 391 392 /* Write connection information in network subkey */ 393 rc = RegCreateKeyExW(HKEY_LOCAL_MACHINE, 394 L"SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}", 395 0, 396 NULL, 397 REG_OPTION_NON_VOLATILE, 398 KEY_CREATE_SUB_KEY | KEY_QUERY_VALUE, 399 NULL, 400 &hNetworkKey, 401 NULL); 402 if (rc != ERROR_SUCCESS) 403 { 404 ERR("RegCreateKeyExW() failed with error 0x%lx\n", rc); 405 goto cleanup; 406 } 407 408 rc = GetUniqueConnectionName(hNetworkKey, &pszNameBuffer); 409 if (rc != ERROR_SUCCESS) 410 { 411 ERR("GetUniqueConnectionName() failed with error 0x%lx\n", rc); 412 goto cleanup; 413 } 414 415 rc = RegCreateKeyExW(hNetworkKey, UuidString, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_CREATE_SUB_KEY, NULL, &hKey, NULL); 416 if (rc != ERROR_SUCCESS) 417 { 418 ERR("RegCreateKeyExW() failed with error 0x%lx\n", rc); 419 goto cleanup; 420 } 421 422 rc = RegCreateKeyExW(hKey, L"Connection", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_SET_VALUE, NULL, &hConnectionKey, NULL); 423 RegCloseKey(hKey); 424 hKey = NULL; 425 if (rc != ERROR_SUCCESS) 426 { 427 ERR("RegCreateKeyExW() failed with error 0x%lx\n", rc); 428 goto cleanup; 429 } 430 431 rc = RegSetValueExW(hConnectionKey, L"Name", 0, REG_SZ, (const BYTE*)pszNameBuffer, (wcslen(pszNameBuffer) + 1) * sizeof(WCHAR)); 432 if (rc != ERROR_SUCCESS) 433 { 434 ERR("RegSetValueExW() failed with error 0x%lx\n", rc); 435 goto cleanup; 436 } 437 438 rc = RegSetValueExW(hConnectionKey, L"PnpInstanceID", 0, REG_SZ, (const BYTE*)InstanceId, (wcslen(InstanceId) + 1) * sizeof(WCHAR)); 439 if (rc != ERROR_SUCCESS) 440 { 441 ERR("RegSetValueExW() failed with error 0x%lx\n", rc); 442 goto cleanup; 443 } 444 445 dwShowIcon = 1; 446 rc = RegSetValueExW(hConnectionKey, L"ShowIcon", 0, REG_DWORD, (const BYTE*)&dwShowIcon, sizeof(dwShowIcon)); 447 if (rc != ERROR_SUCCESS) 448 { 449 ERR("RegSetValueExW() failed with error 0x%lx\n", rc); 450 goto cleanup; 451 } 452 453 /* Write linkage information in Tcpip service */ 454 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); 455 if (rc != ERROR_SUCCESS) 456 { 457 ERR("RegCreateKeyExW() failed with error 0x%lx\n", rc); 458 goto cleanup; 459 } 460 rc = AppendStringToMultiSZ(hKey, L"Bind", DeviceName); 461 if (rc != ERROR_SUCCESS) 462 { 463 ERR("AppendStringToMultiSZ() failed with error 0x%lx\n", rc); 464 goto cleanup; 465 } 466 rc = AppendStringToMultiSZ(hKey, L"Export", ExportName); 467 if (rc != ERROR_SUCCESS) 468 { 469 ERR("AppendStringToMultiSZ() failed with error 0x%lx\n", rc); 470 goto cleanup; 471 } 472 rc = AppendStringToMultiSZ(hKey, L"Route", UuidString); 473 if (rc != ERROR_SUCCESS) 474 { 475 ERR("AppendStringToMultiSZ() failed with error 0x%lx\n", rc); 476 goto cleanup; 477 } 478 479 /* Start the device */ 480 if (!SetupDiRestartDevices(DeviceInfoSet, DeviceInfoData)) 481 { 482 rc = GetLastError(); 483 ERR("SetupDiRestartDevices() failed with error 0x%lx\n", rc); 484 goto cleanup; 485 } 486 487 rc = ERROR_SUCCESS; 488 489 cleanup: 490 HeapFree(GetProcessHeap(), 0, pszNameBuffer); 491 HeapFree(GetProcessHeap(), 0, InstanceId); 492 HeapFree(GetProcessHeap(), 0, ComponentId); 493 HeapFree(GetProcessHeap(), 0, DeviceName); 494 HeapFree(GetProcessHeap(), 0, ExportName); 495 if (hKey != NULL) 496 RegCloseKey(hKey); 497 if (hNetworkKey != NULL) 498 RegCloseKey(hNetworkKey); 499 if (hLinkageKey != NULL) 500 RegCloseKey(hLinkageKey); 501 if (hConnectionKey != NULL) 502 RegCloseKey(hConnectionKey); 503 504 return rc; 505 } 506 507 static 508 DWORD 509 InstallNetClient(VOID) 510 { 511 FIXME("Installation of network clients is not yet supported\n"); 512 return ERROR_GEN_FAILURE; 513 } 514 515 static 516 DWORD 517 InstallNetService(VOID) 518 { 519 FIXME("Installation of network services is not yet supported\n"); 520 return ERROR_GEN_FAILURE; 521 } 522 523 static 524 DWORD 525 InstallNetTransport(VOID) 526 { 527 FIXME("Installation of network protocols is not yet supported\n"); 528 return ERROR_GEN_FAILURE; 529 } 530 531 DWORD 532 WINAPI 533 NetClassInstaller( 534 IN DI_FUNCTION InstallFunction, 535 IN HDEVINFO DeviceInfoSet, 536 IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL) 537 { 538 SP_DRVINFO_DATA_W DriverInfoData; 539 SP_DRVINFO_DETAIL_DATA_W DriverInfoDetail; 540 WCHAR SectionName[LINE_LEN]; 541 HINF hInf = INVALID_HANDLE_VALUE; 542 INFCONTEXT InfContext; 543 UINT ErrorLine; 544 INT CharacteristicsInt; 545 DWORD Characteristics; 546 LPWSTR BusType = NULL; 547 RPC_STATUS RpcStatus; 548 UUID Uuid; 549 LPWSTR UuidRpcString = NULL; 550 LPWSTR UuidString = NULL; 551 LONG rc; 552 DWORD dwLength; 553 554 if (InstallFunction != DIF_INSTALLDEVICE) 555 return ERROR_DI_DO_DEFAULT; 556 557 TRACE("%lu %p %p\n", InstallFunction, DeviceInfoSet, DeviceInfoData); 558 559 /* Get driver info details */ 560 DriverInfoData.cbSize = sizeof(SP_DRVINFO_DATA_W); 561 if (!SetupDiGetSelectedDriverW(DeviceInfoSet, DeviceInfoData, &DriverInfoData)) 562 { 563 rc = GetLastError(); 564 ERR("SetupDiGetSelectedDriverW() failed with error 0x%lx\n", rc); 565 goto cleanup; 566 } 567 568 DriverInfoDetail.cbSize = sizeof(SP_DRVINFO_DETAIL_DATA_W); 569 if (!SetupDiGetDriverInfoDetailW(DeviceInfoSet, DeviceInfoData, &DriverInfoData, &DriverInfoDetail, sizeof(DriverInfoDetail), NULL) 570 && GetLastError() != ERROR_INSUFFICIENT_BUFFER) 571 { 572 rc = GetLastError(); 573 ERR("SetupDiGetDriverInfoDetailW() failed with error 0x%lx\n", rc); 574 goto cleanup; 575 } 576 577 hInf = SetupOpenInfFileW(DriverInfoDetail.InfFileName, NULL, INF_STYLE_WIN4, &ErrorLine); 578 if (hInf == INVALID_HANDLE_VALUE) 579 { 580 rc = GetLastError(); 581 ERR("SetupOpenInfFileW() failed with error 0x%lx\n", rc); 582 goto cleanup; 583 } 584 585 if (!SetupDiGetActualSectionToInstallW(hInf, DriverInfoDetail.SectionName, SectionName, LINE_LEN, NULL, NULL)) 586 { 587 rc = GetLastError(); 588 ERR("SetupDiGetActualSectionToInstallW() failed with error 0x%lx\n", rc); 589 goto cleanup; 590 } 591 592 /* Get Characteristics and BusType (optional) from .inf file */ 593 if (!SetupFindFirstLineW(hInf, SectionName, L"Characteristics", &InfContext)) 594 { 595 rc = GetLastError(); 596 ERR("Unable to find key %S in section %S of file %S (error 0x%lx)\n", 597 L"Characteristics", SectionName, DriverInfoDetail.InfFileName, rc); 598 goto cleanup; 599 } 600 601 if (!SetupGetIntField(&InfContext, 1, &CharacteristicsInt)) 602 { 603 rc = GetLastError(); 604 ERR("SetupGetIntField() failed with error 0x%lx\n", rc); 605 goto cleanup; 606 } 607 608 Characteristics = (DWORD)CharacteristicsInt; 609 if (IsEqualIID(&DeviceInfoData->ClassGuid, &GUID_DEVCLASS_NET)) 610 { 611 if (SetupFindFirstLineW(hInf, SectionName, L"BusType", &InfContext)) 612 { 613 if (!SetupGetStringFieldW(&InfContext, 1, NULL, 0, &dwLength)) 614 { 615 rc = GetLastError(); 616 ERR("SetupGetStringFieldW() failed with error 0x%lx\n", rc); 617 goto cleanup; 618 } 619 620 BusType = HeapAlloc(GetProcessHeap(), 0, dwLength * sizeof(WCHAR)); 621 if (!BusType) 622 { 623 ERR("HeapAlloc() failed\n"); 624 rc = ERROR_NOT_ENOUGH_MEMORY; 625 goto cleanup; 626 } 627 628 if (!SetupGetStringFieldW(&InfContext, 1, BusType, dwLength, NULL)) 629 { 630 rc = GetLastError(); 631 ERR("SetupGetStringFieldW() failed with error 0x%lx\n", rc); 632 goto cleanup; 633 } 634 } 635 } 636 637 /* Create a new UUID */ 638 RpcStatus = UuidCreate(&Uuid); 639 if (RpcStatus != RPC_S_OK && RpcStatus != RPC_S_UUID_LOCAL_ONLY) 640 { 641 ERR("UuidCreate() failed with RPC status 0x%lx\n", RpcStatus); 642 rc = ERROR_GEN_FAILURE; 643 goto cleanup; 644 } 645 646 RpcStatus = UuidToStringW(&Uuid, &UuidRpcString); 647 if (RpcStatus != RPC_S_OK) 648 { 649 ERR("UuidToStringW() failed with RPC status 0x%lx\n", RpcStatus); 650 rc = ERROR_GEN_FAILURE; 651 goto cleanup; 652 } 653 654 /* Add curly braces around Uuid */ 655 UuidString = HeapAlloc(GetProcessHeap(), 0, (2 + wcslen(UuidRpcString)) * sizeof(WCHAR) + sizeof(UNICODE_NULL)); 656 if (!UuidString) 657 { 658 ERR("HeapAlloc() failed\n"); 659 rc = ERROR_NOT_ENOUGH_MEMORY; 660 goto cleanup; 661 } 662 663 wcscpy(UuidString, L"{"); 664 wcscat(UuidString, UuidRpcString); 665 wcscat(UuidString, L"}"); 666 667 if (IsEqualIID(&DeviceInfoData->ClassGuid, &GUID_DEVCLASS_NET)) 668 rc = InstallNetDevice(DeviceInfoSet, DeviceInfoData, UuidString, Characteristics, BusType); 669 else if (IsEqualIID(&DeviceInfoData->ClassGuid, &GUID_DEVCLASS_NETCLIENT)) 670 rc = InstallNetClient(); 671 else if (IsEqualIID(&DeviceInfoData->ClassGuid, &GUID_DEVCLASS_NETSERVICE)) 672 rc = InstallNetService(); 673 else if (IsEqualIID(&DeviceInfoData->ClassGuid, &GUID_DEVCLASS_NETTRANS)) 674 rc = InstallNetTransport(); 675 else 676 { 677 ERR("Invalid class guid\n"); 678 rc = ERROR_GEN_FAILURE; 679 } 680 681 cleanup: 682 if (hInf != INVALID_HANDLE_VALUE) 683 SetupCloseInfFile(hInf); 684 if (UuidRpcString != NULL) 685 RpcStringFreeW(&UuidRpcString); 686 HeapFree(GetProcessHeap(), 0, BusType); 687 HeapFree(GetProcessHeap(), 0, UuidString); 688 689 TRACE("Returning 0x%lx\n", rc); 690 return rc; 691 } 692