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