2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Configuration of networkd devices
4 * FILE: lib/netcfgx/netcfgx.c
5 * PURPOSE: Network devices installer
7 * PROGRAMMERS: Hervé Poussineau (hpoussin@reactos.org)
15 /* Append a REG_SZ to an existing REG_MULTI_SZ string in the registry.
16 * If the value doesn't exist, create it.
17 * Returns ERROR_SUCCESS if success. Othewise, returns an error code
20 AppendStringToMultiSZ(
23 IN PCWSTR ValueToAppend
)
27 DWORD dwRequired
, dwLength
;
31 rc
= RegQueryValueExW(
38 if (rc
!= ERROR_FILE_NOT_FOUND
)
40 if (rc
!= ERROR_SUCCESS
)
42 if (dwRegType
!= REG_MULTI_SZ
)
44 rc
= ERROR_GEN_FAILURE
;
48 dwTmp
= dwLength
= dwRequired
+ wcslen(ValueToAppend
) * sizeof(WCHAR
) + sizeof(UNICODE_NULL
);
49 Buffer
= HeapAlloc(GetProcessHeap(), 0, dwLength
);
52 rc
= ERROR_NOT_ENOUGH_MEMORY
;
55 rc
= RegQueryValueExW(
62 if (rc
!= ERROR_SUCCESS
)
67 dwRequired
= sizeof(WCHAR
);
68 dwLength
= wcslen(ValueToAppend
) * sizeof(WCHAR
) + 2 * sizeof(UNICODE_NULL
);
69 Buffer
= HeapAlloc(GetProcessHeap(), 0, dwLength
);
72 rc
= ERROR_NOT_ENOUGH_MEMORY
;
77 /* Append the value */
78 wcscpy(&Buffer
[dwRequired
/ sizeof(WCHAR
) - 1], ValueToAppend
);
79 /* Terminate the REG_MULTI_SZ string */
80 Buffer
[dwLength
/ sizeof(WCHAR
) - 1] = UNICODE_NULL
;
91 HeapFree(GetProcessHeap(), 0, Buffer
);
97 IN DI_FUNCTION InstallFunction
,
98 IN HDEVINFO DeviceInfoSet
,
99 IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL
)
101 RPC_STATUS RpcStatus
;
103 LPWSTR UuidRpcString
= NULL
;
104 LPWSTR UuidString
= NULL
;
105 LPWSTR DeviceName
= NULL
;
106 LPWSTR ExportName
= NULL
;
108 HKEY hKey
= INVALID_HANDLE_VALUE
;
109 HKEY hLinkageKey
= INVALID_HANDLE_VALUE
;
110 HKEY hNetworkKey
= INVALID_HANDLE_VALUE
;
111 HKEY hConnectionKey
= INVALID_HANDLE_VALUE
;
113 if (InstallFunction
!= DIF_INSTALLDEVICE
)
114 return ERROR_DI_DO_DEFAULT
;
116 DPRINT("%lu %p %p\n", InstallFunction
, DeviceInfoSet
, DeviceInfoData
);
118 /* Create a new UUID */
119 RpcStatus
= UuidCreate(&Uuid
);
120 if (RpcStatus
!= RPC_S_OK
&& RpcStatus
!= RPC_S_UUID_LOCAL_ONLY
)
122 DPRINT("UuidCreate() failed with RPC status 0x%lx\n", RpcStatus
);
123 rc
= ERROR_GEN_FAILURE
;
126 RpcStatus
= UuidToStringW(&Uuid
, &UuidRpcString
);
127 if (RpcStatus
!= RPC_S_OK
)
129 DPRINT("UuidToStringW() failed with RPC status 0x%lx\n", RpcStatus
);
130 rc
= ERROR_GEN_FAILURE
;
134 /* Add curly braces around Uuid */
135 UuidString
= HeapAlloc(GetProcessHeap(), 0, (2 + wcslen(UuidRpcString
)) * sizeof(WCHAR
) + sizeof(UNICODE_NULL
));
138 DPRINT("HeapAlloc() failed\n");
139 rc
= ERROR_NOT_ENOUGH_MEMORY
;
142 wcscpy(UuidString
, L
"{");
143 wcscat(UuidString
, UuidRpcString
);
144 wcscat(UuidString
, L
"}");
146 /* Create device name */
147 DeviceName
= HeapAlloc(GetProcessHeap(), 0, (wcslen(L
"\\Device\\") + wcslen(UuidString
)) * sizeof(WCHAR
) + sizeof(UNICODE_NULL
));
150 DPRINT("HeapAlloc() failed\n");
151 rc
= ERROR_NOT_ENOUGH_MEMORY
;
154 wcscpy(DeviceName
, L
"\\Device\\");
155 wcscat(DeviceName
, UuidString
);
157 /* Create export name */
158 ExportName
= HeapAlloc(GetProcessHeap(), 0, (wcslen(L
"\\Device\\Tcpip_") + wcslen(UuidString
)) * sizeof(WCHAR
) + sizeof(UNICODE_NULL
));
161 DPRINT("HeapAlloc() failed\n");
162 rc
= ERROR_NOT_ENOUGH_MEMORY
;
165 wcscpy(ExportName
, L
"\\Device\\Tcpip_");
166 wcscat(ExportName
, UuidString
);
168 /* Write Tcpip parameters in new service Key */
169 rc
= RegCreateKeyExW(HKEY_LOCAL_MACHINE
, L
"SYSTEM\\CurrentControlSet\\Services", 0, NULL
, REG_OPTION_NON_VOLATILE
, 0, NULL
, &hKey
, NULL
);
170 if (rc
!= ERROR_SUCCESS
)
172 DPRINT("RegCreateKeyExW() failed with error 0x%lx\n", rc
);
175 rc
= RegCreateKeyExW(hKey
, UuidString
, 0, NULL
, REG_OPTION_NON_VOLATILE
, 0, NULL
, &hNetworkKey
, NULL
);
176 if (rc
!= ERROR_SUCCESS
)
178 DPRINT("RegCreateKeyExW() failed with error 0x%lx\n", rc
);
182 hKey
= INVALID_HANDLE_VALUE
;
183 rc
= RegCreateKeyExW(hNetworkKey
, L
"Parameters\\Tcpip", 0, NULL
, REG_OPTION_NON_VOLATILE
, KEY_SET_VALUE
, NULL
, &hKey
, NULL
);
184 if (rc
!= ERROR_SUCCESS
)
186 DPRINT("RegCreateKeyExW() failed with error 0x%lx\n", rc
);
189 RegCloseKey(hNetworkKey
);
190 hNetworkKey
= INVALID_HANDLE_VALUE
;
191 rc
= RegSetValueExW(hKey
, L
"DefaultGateway", 0, REG_SZ
, (const BYTE
*)L
"0.0.0.0", (wcslen(L
"0.0.0.0") + 1) * sizeof(WCHAR
));
192 if (rc
!= ERROR_SUCCESS
)
194 DPRINT("RegSetValueExW() failed with error 0x%lx\n", rc
);
197 rc
= RegSetValueExW(hKey
, L
"IPAddress", 0, REG_SZ
, (const BYTE
*)L
"0.0.0.0", (wcslen(L
"0.0.0.0") + 1) * sizeof(WCHAR
));
198 if (rc
!= ERROR_SUCCESS
)
200 DPRINT("RegSetValueExW() failed with error 0x%lx\n", rc
);
203 rc
= RegSetValueExW(hKey
, L
"SubnetMask", 0, REG_SZ
, (const BYTE
*)L
"0.0.0.0", (wcslen(L
"0.0.0.0") + 1) * sizeof(WCHAR
));
204 if (rc
!= ERROR_SUCCESS
)
206 DPRINT("RegSetValueExW() failed with error 0x%lx\n", rc
);
210 hKey
= INVALID_HANDLE_VALUE
;
212 /* Write 'Linkage' key in hardware key */
213 hKey
= SetupDiCreateDevRegKeyW(DeviceInfoSet
, DeviceInfoData
, DICS_FLAG_GLOBAL
, 0, DIREG_DRV
, NULL
, NULL
);
214 if (hKey
== INVALID_HANDLE_VALUE
)
217 DPRINT("SetupDiCreateDevRegKeyW() failed with error 0x%lx\n", rc
);
220 rc
= RegSetValueExW(hKey
, L
"NetCfgInstanceId", 0, REG_SZ
, (const BYTE
*)UuidString
, (wcslen(UuidString
) + 1) * sizeof(WCHAR
));
221 if (rc
!= ERROR_SUCCESS
)
223 DPRINT("RegSetValueExW() failed with error 0x%lx\n", rc
);
226 rc
= RegCreateKeyExW(hKey
, L
"Linkage", 0, NULL
, REG_OPTION_NON_VOLATILE
, KEY_SET_VALUE
, NULL
, &hLinkageKey
, NULL
);
227 if (rc
!= ERROR_SUCCESS
)
229 DPRINT("RegCreateKeyExW() failed with error 0x%lx\n", rc
);
232 rc
= RegSetValueExW(hLinkageKey
, L
"Export", 0, REG_SZ
, (const BYTE
*)DeviceName
, (wcslen(DeviceName
) + 1) * sizeof(WCHAR
));
233 if (rc
!= ERROR_SUCCESS
)
235 DPRINT("RegSetValueExW() failed with error 0x%lx\n", rc
);
238 rc
= RegSetValueExW(hLinkageKey
, L
"RootDevice", 0, REG_SZ
, (const BYTE
*)UuidString
, (wcslen(UuidString
) + 1) * sizeof(WCHAR
));
239 if (rc
!= ERROR_SUCCESS
)
241 DPRINT("RegSetValueExW() failed with error 0x%lx\n", rc
);
244 rc
= RegSetValueExW(hLinkageKey
, L
"UpperBind", 0, REG_SZ
, (const BYTE
*)L
"Tcpip", (wcslen(L
"Tcpip") + 1) * sizeof(WCHAR
));
245 if (rc
!= ERROR_SUCCESS
)
247 DPRINT("RegSetValueExW() failed with error 0x%lx\n", rc
);
251 hKey
= INVALID_HANDLE_VALUE
;
253 /* Write connection information in network subkey */
254 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
);
255 if (rc
!= ERROR_SUCCESS
)
257 DPRINT("RegCreateKeyExW() failed with error 0x%lx\n", rc
);
260 rc
= RegCreateKeyExW(hNetworkKey
, UuidString
, 0, NULL
, REG_OPTION_NON_VOLATILE
, KEY_SET_VALUE
, NULL
, &hKey
, NULL
);
261 if (rc
!= ERROR_SUCCESS
)
263 DPRINT("RegCreateKeyExW() failed with error 0x%lx\n", rc
);
266 rc
= RegSetValueExW(hKey
, L
"Name", 0, REG_SZ
, (const BYTE
*)L
"Network connection", (wcslen(L
"Network connection") + 1) * sizeof(WCHAR
));
267 if (rc
!= ERROR_SUCCESS
)
269 DPRINT("RegSetValueExW() failed with error 0x%lx\n", rc
);
273 hKey
= INVALID_HANDLE_VALUE
;
275 /* Write linkage information in Tcpip service */
276 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
);
277 if (rc
!= ERROR_SUCCESS
)
279 DPRINT("RegCreateKeyExW() failed with error 0x%lx\n", rc
);
282 rc
= AppendStringToMultiSZ(hKey
, L
"Bind", DeviceName
);
283 if (rc
!= ERROR_SUCCESS
)
285 DPRINT("AppendStringToMultiSZ() failed with error 0x%lx\n", rc
);
288 rc
= AppendStringToMultiSZ(hKey
, L
"Export", ExportName
);
289 if (rc
!= ERROR_SUCCESS
)
291 DPRINT("AppendStringToMultiSZ() failed with error 0x%lx\n", rc
);
294 rc
= AppendStringToMultiSZ(hKey
, L
"Route", UuidString
);
295 if (rc
!= ERROR_SUCCESS
)
297 DPRINT("AppendStringToMultiSZ() failed with error 0x%lx\n", rc
);
304 if (UuidRpcString
!= NULL
)
305 RpcStringFreeW(&UuidRpcString
);
306 HeapFree(GetProcessHeap(), 0, UuidString
);
307 HeapFree(GetProcessHeap(), 0, DeviceName
);
308 HeapFree(GetProcessHeap(), 0, ExportName
);
309 if (hKey
!= INVALID_HANDLE_VALUE
)
311 if (hLinkageKey
!= INVALID_HANDLE_VALUE
)
312 RegCloseKey(hLinkageKey
);
313 if (hNetworkKey
!= INVALID_HANDLE_VALUE
)
314 RegCloseKey(hNetworkKey
);
315 if (hConnectionKey
!= INVALID_HANDLE_VALUE
)
316 RegCloseKey(hConnectionKey
);
318 if (rc
== ERROR_SUCCESS
)
319 rc
= ERROR_DI_DO_DEFAULT
;
320 DPRINT("Returning 0x%lx\n", rc
);