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
7 * PROGRAMMERS: Hervé Poussineau (hpoussin@reactos.org)
14 #define NTOS_MODE_USER
15 #include <ndk/iofuncs.h>
16 #include <ndk/rtlfuncs.h>
21 HINSTANCE netcfgx_hInstance
;
22 const GUID CLSID_TcpipConfigNotifyObject
= {0xA907657F, 0x6FDF, 0x11D0, {0x8E, 0xFB, 0x00, 0xC0, 0x4F, 0xD9, 0x12, 0xB2}};
24 static INTERFACE_TABLE InterfaceTable
[] =
31 &CLSID_TcpipConfigNotifyObject
,
32 TcpipConfigNotify_Constructor
42 DllMain(HINSTANCE hinstDLL
, DWORD fdwReason
, LPVOID fImpLoad
)
46 case DLL_PROCESS_ATTACH
:
47 netcfgx_hInstance
= hinstDLL
;
48 DisableThreadLibraryCalls(netcfgx_hInstance
);
65 DllRegisterServer(void)
69 WCHAR szName
[MAX_PATH
] = L
"CLSID\\";
71 if (FAILED(StringFromCLSID(&CLSID_CNetCfg
, &pStr
)))
72 return SELFREG_E_CLASS
;
74 wcscpy(&szName
[6], pStr
);
77 if (RegCreateKeyExW(HKEY_CLASSES_ROOT
, szName
, 0, NULL
, 0, KEY_WRITE
, NULL
, &hKey
, NULL
) != ERROR_SUCCESS
)
78 return SELFREG_E_CLASS
;
80 if (RegCreateKeyExW(hKey
, L
"InProcServer32", 0, NULL
, 0, KEY_WRITE
, NULL
, &hSubKey
, NULL
) == ERROR_SUCCESS
)
82 if (!GetModuleFileNameW(netcfgx_hInstance
, szName
, sizeof(szName
)/sizeof(WCHAR
)))
86 return SELFREG_E_CLASS
;
88 szName
[(sizeof(szName
)/sizeof(WCHAR
))-1] = L
'\0';
89 RegSetValueW(hSubKey
, NULL
, REG_SZ
, szName
, (wcslen(szName
)+1) * sizeof(WCHAR
));
90 RegSetValueExW(hSubKey
, L
"ThreadingModel", 0, REG_SZ
, (LPBYTE
)L
"Both", 10);
99 DllUnregisterServer(void)
102 // implement unregistering services
114 HRESULT hres
= E_OUTOFMEMORY
;
115 IClassFactory
* pcf
= NULL
;
122 for (i
= 0; InterfaceTable
[i
].riid
; i
++)
124 if (IsEqualIID(InterfaceTable
[i
].riid
, rclsid
))
126 pcf
= IClassFactory_fnConstructor(InterfaceTable
[i
].lpfnCI
, NULL
, NULL
);
133 return CLASS_E_CLASSNOTAVAILABLE
;
136 hres
= IClassFactory_QueryInterface(pcf
, riid
, ppv
);
137 IClassFactory_Release(pcf
);
143 /* Append a REG_SZ to an existing REG_MULTI_SZ string in the registry.
144 * If the value doesn't exist, create it.
145 * Returns ERROR_SUCCESS if success. Othewise, returns an error code
149 AppendStringToMultiSZ(
152 IN PCWSTR ValueToAppend
)
156 DWORD dwRequired
, dwLength
;
160 rc
= RegQueryValueExW(hKey
,
166 if (rc
!= ERROR_FILE_NOT_FOUND
)
168 if (rc
!= ERROR_SUCCESS
)
170 if (dwRegType
!= REG_MULTI_SZ
)
172 rc
= ERROR_GEN_FAILURE
;
176 dwTmp
= dwLength
= dwRequired
+ wcslen(ValueToAppend
) * sizeof(WCHAR
) + sizeof(UNICODE_NULL
);
177 Buffer
= HeapAlloc(GetProcessHeap(), 0, dwLength
);
180 rc
= ERROR_NOT_ENOUGH_MEMORY
;
184 rc
= RegQueryValueExW(hKey
,
190 if (rc
!= ERROR_SUCCESS
)
195 dwRequired
= sizeof(WCHAR
);
196 dwLength
= wcslen(ValueToAppend
) * sizeof(WCHAR
) + 2 * sizeof(UNICODE_NULL
);
197 Buffer
= HeapAlloc(GetProcessHeap(), 0, dwLength
);
200 rc
= ERROR_NOT_ENOUGH_MEMORY
;
205 /* Append the value */
206 wcscpy(&Buffer
[dwRequired
/ sizeof(WCHAR
) - 1], ValueToAppend
);
207 /* Terminate the REG_MULTI_SZ string */
208 Buffer
[dwLength
/ sizeof(WCHAR
) - 1] = UNICODE_NULL
;
210 rc
= RegSetValueExW(hKey
,
218 HeapFree(GetProcessHeap(), 0, Buffer
);
222 /* Install a section of a .inf file
223 * Returns TRUE if success, FALSE if failure. Error code can
224 * be retrieved with GetLastError()
231 IN LPCWSTR InfSection OPTIONAL
,
232 IN LPCWSTR InfService OPTIONAL
)
234 WCHAR Buffer
[MAX_PATH
];
235 HINF hInf
= INVALID_HANDLE_VALUE
;
237 PVOID Context
= NULL
;
240 /* Get Windows directory */
241 BufferSize
= MAX_PATH
- 5 - wcslen(InfFile
);
242 if (GetWindowsDirectoryW(Buffer
, BufferSize
) > BufferSize
)
244 /* Function failed */
245 SetLastError(ERROR_GEN_FAILURE
);
248 /* We have enough space to add some information in the buffer */
249 if (Buffer
[wcslen(Buffer
) - 1] != '\\')
250 wcscat(Buffer
, L
"\\");
251 wcscat(Buffer
, L
"Inf\\");
252 wcscat(Buffer
, InfFile
);
254 /* Install specified section */
255 hInf
= SetupOpenInfFileW(Buffer
, NULL
, INF_STYLE_WIN4
, NULL
);
256 if (hInf
== INVALID_HANDLE_VALUE
)
259 Context
= SetupInitDefaultQueueCallback(hWnd
);
264 if (ret
&& InfSection
)
266 ret
= SetupInstallFromInfSectionW(
268 InfSection
, SPINST_ALL
,
269 NULL
, NULL
, SP_COPY_NEWER
,
270 SetupDefaultQueueCallbackW
, Context
,
273 if (ret
&& InfService
)
275 ret
= SetupInstallServicesFromInfSectionW(
276 hInf
, InfService
, 0);
281 SetupTermDefaultQueueCallback(Context
);
282 if (hInf
!= INVALID_HANDLE_VALUE
)
283 SetupCloseInfFile(hInf
);
287 /* Add default services for network cards */
290 InstallAdditionalServices(
294 UNICODE_STRING TcpipServicePath
= RTL_CONSTANT_STRING(L
"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\Tcpip");
296 /* Install TCP/IP protocol */
297 ret
= InstallInfSection(hWnd
,
299 L
"MS_TCPIP.PrimaryInstall",
300 L
"MS_TCPIP.PrimaryInstall.Services");
301 if (!ret
&& GetLastError() != ERROR_FILE_NOT_FOUND
)
303 DPRINT("InstallInfSection() failed with error 0x%lx\n", GetLastError());
304 return GetLastError();
308 /* Start the TCP/IP driver */
309 ret
= NtLoadDriver(&TcpipServicePath
);
312 /* This isn't really fatal but we want to warn anyway */
313 DPRINT1("NtLoadDriver(TCPIP) failed with NTSTATUS 0x%lx\n", (NTSTATUS
)ret
);
318 /* You can add here more clients (SMB...) and services (DHCP server...) */
320 return ERROR_SUCCESS
;
326 IN HDEVINFO DeviceInfoSet
,
327 IN PSP_DEVINFO_DATA DeviceInfoData
,
329 DWORD Characteristics
,
332 LPWSTR InstanceId
= NULL
;
333 LPWSTR DeviceName
= NULL
;
334 LPWSTR ExportName
= NULL
;
337 HKEY hNetworkKey
= NULL
;
338 HKEY hLinkageKey
= NULL
;
339 HKEY hConnectionKey
= NULL
;
340 DWORD dwShowIcon
, dwLength
, dwValue
;
343 /* Get Instance ID */
344 if (SetupDiGetDeviceInstanceIdW(DeviceInfoSet
, DeviceInfoData
, NULL
, 0, &dwLength
))
346 DPRINT("SetupDiGetDeviceInstanceIdW() returned TRUE. FALSE expected\n");
347 rc
= ERROR_GEN_FAILURE
;
351 InstanceId
= HeapAlloc(GetProcessHeap(), 0, dwLength
* sizeof(WCHAR
));
354 DPRINT("HeapAlloc() failed\n");
355 rc
= ERROR_NOT_ENOUGH_MEMORY
;
359 if (!SetupDiGetDeviceInstanceIdW(DeviceInfoSet
, DeviceInfoData
, InstanceId
, dwLength
, NULL
))
362 DPRINT("SetupDiGetDeviceInstanceIdW() failed with error 0x%lx\n", rc
);
366 /* Create device name */
367 DeviceName
= HeapAlloc(GetProcessHeap(), 0, (wcslen(L
"\\Device\\") + wcslen(UuidString
)) * sizeof(WCHAR
) + sizeof(UNICODE_NULL
));
370 DPRINT("HeapAlloc() failed\n");
371 rc
= ERROR_NOT_ENOUGH_MEMORY
;
374 wcscpy(DeviceName
, L
"\\Device\\");
375 wcscat(DeviceName
, UuidString
);
377 /* Create export name */
378 ExportName
= HeapAlloc(GetProcessHeap(), 0, (wcslen(L
"\\Device\\Tcpip_") + wcslen(UuidString
)) * sizeof(WCHAR
) + sizeof(UNICODE_NULL
));
381 DPRINT("HeapAlloc() failed\n");
382 rc
= ERROR_NOT_ENOUGH_MEMORY
;
385 wcscpy(ExportName
, L
"\\Device\\Tcpip_");
386 wcscat(ExportName
, UuidString
);
388 /* Write Tcpip parameters in new service Key */
389 rc
= RegCreateKeyExW(HKEY_LOCAL_MACHINE
, L
"SYSTEM\\CurrentControlSet\\Services", 0, NULL
, REG_OPTION_NON_VOLATILE
, 0, NULL
, &hKey
, NULL
);
390 if (rc
!= ERROR_SUCCESS
)
392 DPRINT("RegCreateKeyExW() failed with error 0x%lx\n", rc
);
396 rc
= RegCreateKeyExW(hKey
, UuidString
, 0, NULL
, REG_OPTION_NON_VOLATILE
, 0, NULL
, &hNetworkKey
, NULL
);
397 if (rc
!= ERROR_SUCCESS
)
399 DPRINT("RegCreateKeyExW() failed with error 0x%lx\n", rc
);
405 rc
= RegCreateKeyExW(hNetworkKey
, L
"Parameters\\Tcpip", 0, NULL
, REG_OPTION_NON_VOLATILE
, KEY_SET_VALUE
, NULL
, &hKey
, NULL
);
406 if (rc
!= ERROR_SUCCESS
)
408 DPRINT("RegCreateKeyExW() failed with error 0x%lx\n", rc
);
411 RegCloseKey(hNetworkKey
);
414 rc
= RegSetValueExW(hKey
, L
"DefaultGateway", 0, REG_SZ
, (const BYTE
*)L
"0.0.0.0", (wcslen(L
"0.0.0.0") + 1) * sizeof(WCHAR
));
415 if (rc
!= ERROR_SUCCESS
)
417 DPRINT("RegSetValueExW() failed with error 0x%lx\n", rc
);
421 rc
= RegSetValueExW(hKey
, L
"IPAddress", 0, REG_SZ
, (const BYTE
*)L
"0.0.0.0", (wcslen(L
"0.0.0.0") + 1) * sizeof(WCHAR
));
422 if (rc
!= ERROR_SUCCESS
)
424 DPRINT("RegSetValueExW() failed with error 0x%lx\n", rc
);
428 rc
= RegSetValueExW(hKey
, L
"SubnetMask", 0, REG_SZ
, (const BYTE
*)L
"0.0.0.0", (wcslen(L
"0.0.0.0") + 1) * sizeof(WCHAR
));
429 if (rc
!= ERROR_SUCCESS
)
431 DPRINT("RegSetValueExW() failed with error 0x%lx\n", rc
);
436 rc
= RegSetValueExW(hKey
, L
"EnableDHCP", 0, REG_DWORD
, (const BYTE
*)&dwValue
, sizeof(DWORD
));
437 if (rc
!= ERROR_SUCCESS
)
439 DPRINT("RegSetValueExW() failed with error 0x%lx\n", rc
);
445 /* Write 'Linkage' key in hardware key */
446 #if _WIN32_WINNT >= 0x502
447 hKey
= SetupDiOpenDevRegKey(DeviceInfoSet
, DeviceInfoData
, DICS_FLAG_GLOBAL
, 0, DIREG_DRV
, KEY_READ
| KEY_WRITE
);
449 hKey
= SetupDiOpenDevRegKey(DeviceInfoSet
, DeviceInfoData
, DICS_FLAG_GLOBAL
, 0, DIREG_DRV
, KEY_ALL_ACCESS
);
451 if (hKey
== INVALID_HANDLE_VALUE
&& GetLastError() == ERROR_FILE_NOT_FOUND
)
452 hKey
= SetupDiCreateDevRegKeyW(DeviceInfoSet
, DeviceInfoData
, DICS_FLAG_GLOBAL
, 0, DIREG_DRV
, NULL
, NULL
);
453 if (hKey
== INVALID_HANDLE_VALUE
)
457 DPRINT("SetupDiCreateDevRegKeyW() failed with error 0x%lx\n", rc
);
461 rc
= RegSetValueExW(hKey
, L
"NetCfgInstanceId", 0, REG_SZ
, (const BYTE
*)UuidString
, (wcslen(UuidString
) + 1) * sizeof(WCHAR
));
462 if (rc
!= ERROR_SUCCESS
)
464 DPRINT("RegSetValueExW() failed with error 0x%lx\n", rc
);
468 rc
= RegSetValueExW(hKey
, L
"Characteristics", 0, REG_DWORD
, (const BYTE
*)&Characteristics
, sizeof(DWORD
));
469 if (rc
!= ERROR_SUCCESS
)
471 DPRINT("RegSetValueExW() failed with error 0x%lx\n", rc
);
477 rc
= RegSetValueExW(hKey
, L
"BusType", 0, REG_SZ
, (const BYTE
*)BusType
, (wcslen(BusType
) + 1) * sizeof(WCHAR
));
478 if (rc
!= ERROR_SUCCESS
)
480 DPRINT("RegSetValueExW() failed with error 0x%lx\n", rc
);
485 rc
= RegCreateKeyExW(hKey
, L
"Linkage", 0, NULL
, REG_OPTION_NON_VOLATILE
, KEY_SET_VALUE
, NULL
, &hLinkageKey
, NULL
);
486 if (rc
!= ERROR_SUCCESS
)
488 DPRINT("RegCreateKeyExW() failed with error 0x%lx\n", rc
);
492 rc
= RegSetValueExW(hLinkageKey
, L
"Export", 0, REG_SZ
, (const BYTE
*)DeviceName
, (wcslen(DeviceName
) + 1) * sizeof(WCHAR
));
493 if (rc
!= ERROR_SUCCESS
)
495 DPRINT("RegSetValueExW() failed with error 0x%lx\n", rc
);
499 rc
= RegSetValueExW(hLinkageKey
, L
"RootDevice", 0, REG_SZ
, (const BYTE
*)UuidString
, (wcslen(UuidString
) + 1) * sizeof(WCHAR
));
500 if (rc
!= ERROR_SUCCESS
)
502 DPRINT("RegSetValueExW() failed with error 0x%lx\n", rc
);
506 rc
= RegSetValueExW(hLinkageKey
, L
"UpperBind", 0, REG_SZ
, (const BYTE
*)L
"Tcpip", (wcslen(L
"Tcpip") + 1) * sizeof(WCHAR
));
507 if (rc
!= ERROR_SUCCESS
)
509 DPRINT("RegSetValueExW() failed with error 0x%lx\n", rc
);
515 /* Write connection information in network subkey */
516 rc
= RegCreateKeyExW(HKEY_LOCAL_MACHINE
, L
"SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}", 0, NULL
, REG_OPTION_NON_VOLATILE
, 0, NULL
, &hNetworkKey
, NULL
);
517 if (rc
!= ERROR_SUCCESS
)
519 DPRINT("RegCreateKeyExW() failed with error 0x%lx\n", rc
);
523 rc
= RegCreateKeyExW(hNetworkKey
, UuidString
, 0, NULL
, REG_OPTION_NON_VOLATILE
, KEY_CREATE_SUB_KEY
, NULL
, &hKey
, NULL
);
524 if (rc
!= ERROR_SUCCESS
)
526 DPRINT("RegCreateKeyExW() failed with error 0x%lx\n", rc
);
530 rc
= RegCreateKeyExW(hKey
, L
"Connection", 0, NULL
, REG_OPTION_NON_VOLATILE
, KEY_SET_VALUE
, NULL
, &hConnectionKey
, NULL
);
533 if (rc
!= ERROR_SUCCESS
)
535 DPRINT("RegCreateKeyExW() failed with error 0x%lx\n", rc
);
539 if (!LoadStringW(netcfgx_hInstance
, IDS_NET_CONNECT
, szBuffer
, sizeof(szBuffer
)/sizeof(WCHAR
)))
541 wcscpy(szBuffer
,L
"Network connection");
544 rc
= RegSetValueExW(hConnectionKey
, L
"Name", 0, REG_SZ
, (const BYTE
*)szBuffer
, (wcslen(szBuffer
) + 1) * sizeof(WCHAR
));
545 if (rc
!= ERROR_SUCCESS
)
547 DPRINT("RegSetValueExW() failed with error 0x%lx\n", rc
);
551 rc
= RegSetValueExW(hConnectionKey
, L
"PnpInstanceId", 0, REG_SZ
, (const BYTE
*)InstanceId
, (wcslen(InstanceId
) + 1) * sizeof(WCHAR
));
552 if (rc
!= ERROR_SUCCESS
)
554 DPRINT("RegSetValueExW() failed with error 0x%lx\n", rc
);
559 rc
= RegSetValueExW(hConnectionKey
, L
"ShowIcon", 0, REG_DWORD
, (const BYTE
*)&dwShowIcon
, sizeof(dwShowIcon
));
560 if (rc
!= ERROR_SUCCESS
)
562 DPRINT("RegSetValueExW() failed with error 0x%lx\n", rc
);
566 /* Write linkage information in Tcpip service */
567 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
);
568 if (rc
!= ERROR_SUCCESS
)
570 DPRINT("RegCreateKeyExW() failed with error 0x%lx\n", rc
);
573 rc
= AppendStringToMultiSZ(hKey
, L
"Bind", DeviceName
);
574 if (rc
!= ERROR_SUCCESS
)
576 DPRINT("AppendStringToMultiSZ() failed with error 0x%lx\n", rc
);
579 rc
= AppendStringToMultiSZ(hKey
, L
"Export", ExportName
);
580 if (rc
!= ERROR_SUCCESS
)
582 DPRINT("AppendStringToMultiSZ() failed with error 0x%lx\n", rc
);
585 rc
= AppendStringToMultiSZ(hKey
, L
"Route", UuidString
);
586 if (rc
!= ERROR_SUCCESS
)
588 DPRINT("AppendStringToMultiSZ() failed with error 0x%lx\n", rc
);
592 /* Install additionnal services */
593 rc
= InstallAdditionalServices(NULL
);
594 if (rc
!= ERROR_SUCCESS
)
596 DPRINT("InstallAdditionalServices() failed with error 0x%lx\n", rc
);
603 HeapFree(GetProcessHeap(), 0, InstanceId
);
604 HeapFree(GetProcessHeap(), 0, DeviceName
);
605 HeapFree(GetProcessHeap(), 0, ExportName
);
608 if (hNetworkKey
!= NULL
)
609 RegCloseKey(hNetworkKey
);
610 if (hLinkageKey
!= NULL
)
611 RegCloseKey(hLinkageKey
);
612 if (hConnectionKey
!= NULL
)
613 RegCloseKey(hConnectionKey
);
619 InstallNetClient(VOID
)
621 DPRINT1("Installation of network clients is not yet supported\n");
622 return ERROR_GEN_FAILURE
;
627 InstallNetService(VOID
)
629 DPRINT1("Installation of network services is not yet supported\n");
630 return ERROR_GEN_FAILURE
;
635 InstallNetTransport(VOID
)
637 DPRINT1("Installation of network protocols is not yet supported\n");
638 return ERROR_GEN_FAILURE
;
644 IN DI_FUNCTION InstallFunction
,
645 IN HDEVINFO DeviceInfoSet
,
646 IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL
)
648 SP_DRVINFO_DATA_W DriverInfoData
;
649 SP_DRVINFO_DETAIL_DATA_W DriverInfoDetail
;
650 WCHAR SectionName
[LINE_LEN
];
651 HINF hInf
= INVALID_HANDLE_VALUE
;
652 INFCONTEXT InfContext
;
654 INT CharacteristicsInt
;
655 DWORD Characteristics
;
656 LPWSTR BusType
= NULL
;
657 RPC_STATUS RpcStatus
;
659 LPWSTR UuidRpcString
= NULL
;
660 LPWSTR UuidString
= NULL
;
664 if (InstallFunction
!= DIF_INSTALLDEVICE
)
665 return ERROR_DI_DO_DEFAULT
;
667 DPRINT("%lu %p %p\n", InstallFunction
, DeviceInfoSet
, DeviceInfoData
);
669 /* Get driver info details */
670 DriverInfoData
.cbSize
= sizeof(SP_DRVINFO_DATA_W
);
671 if (!SetupDiGetSelectedDriverW(DeviceInfoSet
, DeviceInfoData
, &DriverInfoData
))
674 DPRINT("SetupDiGetSelectedDriverW() failed with error 0x%lx\n", rc
);
678 DriverInfoDetail
.cbSize
= sizeof(SP_DRVINFO_DETAIL_DATA_W
);
679 if (!SetupDiGetDriverInfoDetailW(DeviceInfoSet
, DeviceInfoData
, &DriverInfoData
, &DriverInfoDetail
, sizeof(DriverInfoDetail
), NULL
)
680 && GetLastError() != ERROR_INSUFFICIENT_BUFFER
)
683 DPRINT("SetupDiGetDriverInfoDetailW() failed with error 0x%lx\n", rc
);
687 hInf
= SetupOpenInfFileW(DriverInfoDetail
.InfFileName
, NULL
, INF_STYLE_WIN4
, &ErrorLine
);
688 if (hInf
== INVALID_HANDLE_VALUE
)
691 DPRINT("SetupOpenInfFileW() failed with error 0x%lx\n", rc
);
695 if (!SetupDiGetActualSectionToInstallW(hInf
, DriverInfoDetail
.SectionName
, SectionName
, LINE_LEN
, NULL
, NULL
))
698 DPRINT("SetupDiGetActualSectionToInstallW() failed with error 0x%lx\n", rc
);
702 /* Get Characteristics and BusType (optional) from .inf file */
703 if (!SetupFindFirstLineW(hInf
, SectionName
, L
"Characteristics", &InfContext
))
706 DPRINT("Unable to find key %S in section %S of file %S (error 0x%lx)\n",
707 L
"Characteristics", SectionName
, DriverInfoDetail
.InfFileName
, rc
);
711 if (!SetupGetIntField(&InfContext
, 1, &CharacteristicsInt
))
714 DPRINT("SetupGetIntField() failed with error 0x%lx\n", rc
);
718 Characteristics
= (DWORD
)CharacteristicsInt
;
719 if (IsEqualIID(&DeviceInfoData
->ClassGuid
, &GUID_DEVCLASS_NET
))
721 if (SetupFindFirstLineW(hInf
, SectionName
, L
"BusType", &InfContext
))
723 if (!SetupGetStringFieldW(&InfContext
, 1, NULL
, 0, &dwLength
))
726 DPRINT("SetupGetStringFieldW() failed with error 0x%lx\n", rc
);
730 BusType
= HeapAlloc(GetProcessHeap(), 0, dwLength
* sizeof(WCHAR
));
733 DPRINT("HeapAlloc() failed\n");
734 rc
= ERROR_NOT_ENOUGH_MEMORY
;
738 if (!SetupGetStringFieldW(&InfContext
, 1, BusType
, dwLength
, NULL
))
741 DPRINT("SetupGetStringFieldW() failed with error 0x%lx\n", rc
);
747 /* Create a new UUID */
748 RpcStatus
= UuidCreate(&Uuid
);
749 if (RpcStatus
!= RPC_S_OK
&& RpcStatus
!= RPC_S_UUID_LOCAL_ONLY
)
751 DPRINT("UuidCreate() failed with RPC status 0x%lx\n", RpcStatus
);
752 rc
= ERROR_GEN_FAILURE
;
756 RpcStatus
= UuidToStringW(&Uuid
, &UuidRpcString
);
757 if (RpcStatus
!= RPC_S_OK
)
759 DPRINT("UuidToStringW() failed with RPC status 0x%lx\n", RpcStatus
);
760 rc
= ERROR_GEN_FAILURE
;
764 /* Add curly braces around Uuid */
765 UuidString
= HeapAlloc(GetProcessHeap(), 0, (2 + wcslen(UuidRpcString
)) * sizeof(WCHAR
) + sizeof(UNICODE_NULL
));
768 DPRINT("HeapAlloc() failed\n");
769 rc
= ERROR_NOT_ENOUGH_MEMORY
;
773 wcscpy(UuidString
, L
"{");
774 wcscat(UuidString
, UuidRpcString
);
775 wcscat(UuidString
, L
"}");
777 if (IsEqualIID(&DeviceInfoData
->ClassGuid
, &GUID_DEVCLASS_NET
))
778 rc
= InstallNetDevice(DeviceInfoSet
, DeviceInfoData
, UuidString
, Characteristics
, BusType
);
779 else if (IsEqualIID(&DeviceInfoData
->ClassGuid
, &GUID_DEVCLASS_NETCLIENT
))
780 rc
= InstallNetClient();
781 else if (IsEqualIID(&DeviceInfoData
->ClassGuid
, &GUID_DEVCLASS_NETSERVICE
))
782 rc
= InstallNetService();
783 else if (IsEqualIID(&DeviceInfoData
->ClassGuid
, &GUID_DEVCLASS_NETTRANS
))
784 rc
= InstallNetTransport();
787 DPRINT("Invalid class guid\n");
788 rc
= ERROR_GEN_FAILURE
;
792 if (hInf
!= INVALID_HANDLE_VALUE
)
793 SetupCloseInfFile(hInf
);
794 if (UuidRpcString
!= NULL
)
795 RpcStringFreeW(&UuidRpcString
);
796 HeapFree(GetProcessHeap(), 0, BusType
);
797 HeapFree(GetProcessHeap(), 0, UuidString
);
799 if (rc
== ERROR_SUCCESS
)
800 rc
= ERROR_DI_DO_DEFAULT
;
801 DPRINT("Returning 0x%lx\n", rc
);