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