Add some debug messages, and disable them (#define NDEBUG)
[reactos.git] / reactos / lib / netcfgx / netcfgx.c
1 /*
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
6 *
7 * PROGRAMMERS: Hervé Poussineau (hpoussin@reactos.org)
8 */
9
10 #define NDEBUG
11 #include <debug.h>
12
13 #include "netcfgx.h"
14
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
18 */
19 static 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(
32 hKey,
33 ValueName,
34 NULL,
35 &dwRegType,
36 NULL,
37 &dwRequired);
38 if (rc != ERROR_FILE_NOT_FOUND)
39 {
40 if (rc != ERROR_SUCCESS)
41 goto cleanup;
42 if (dwRegType != REG_MULTI_SZ)
43 {
44 rc = ERROR_GEN_FAILURE;
45 goto cleanup;
46 }
47
48 dwTmp = dwLength = dwRequired + wcslen(ValueToAppend) * sizeof(WCHAR) + sizeof(UNICODE_NULL);
49 Buffer = HeapAlloc(GetProcessHeap(), 0, dwLength);
50 if (!Buffer)
51 {
52 rc = ERROR_NOT_ENOUGH_MEMORY;
53 goto cleanup;
54 }
55 rc = RegQueryValueExW(
56 hKey,
57 ValueName,
58 NULL,
59 NULL,
60 (BYTE*)Buffer,
61 &dwTmp);
62 if (rc != ERROR_SUCCESS)
63 goto cleanup;
64 }
65 else
66 {
67 dwRequired = sizeof(WCHAR);
68 dwLength = wcslen(ValueToAppend) * sizeof(WCHAR) + 2 * sizeof(UNICODE_NULL);
69 Buffer = HeapAlloc(GetProcessHeap(), 0, dwLength);
70 if (!Buffer)
71 {
72 rc = ERROR_NOT_ENOUGH_MEMORY;
73 goto cleanup;
74 }
75 }
76
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;
81
82 rc = RegSetValueExW(
83 hKey,
84 ValueName,
85 0,
86 REG_MULTI_SZ,
87 (const BYTE*)Buffer,
88 dwLength);
89
90 cleanup:
91 HeapFree(GetProcessHeap(), 0, Buffer);
92 return rc;
93 }
94
95 DWORD WINAPI
96 NetClassInstaller(
97 IN DI_FUNCTION InstallFunction,
98 IN HDEVINFO DeviceInfoSet,
99 IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL)
100 {
101 RPC_STATUS RpcStatus;
102 UUID Uuid;
103 LPWSTR UuidRpcString = NULL;
104 LPWSTR UuidString = NULL;
105 LPWSTR DeviceName = NULL;
106 LPWSTR ExportName = NULL;
107 LONG rc;
108 HKEY hKey = INVALID_HANDLE_VALUE;
109 HKEY hLinkageKey = INVALID_HANDLE_VALUE;
110 HKEY hNetworkKey = INVALID_HANDLE_VALUE;
111 HKEY hConnectionKey = INVALID_HANDLE_VALUE;
112
113 if (InstallFunction != DIF_INSTALLDEVICE)
114 return ERROR_DI_DO_DEFAULT;
115
116 DPRINT("%lu %p %p\n", InstallFunction, DeviceInfoSet, DeviceInfoData);
117
118 /* Create a new UUID */
119 RpcStatus = UuidCreate(&Uuid);
120 if (RpcStatus != RPC_S_OK && RpcStatus != RPC_S_UUID_LOCAL_ONLY)
121 {
122 DPRINT("UuidCreate() failed with RPC status 0x%lx\n", RpcStatus);
123 rc = ERROR_GEN_FAILURE;
124 goto cleanup;
125 }
126 RpcStatus = UuidToStringW(&Uuid, &UuidRpcString);
127 if (RpcStatus != RPC_S_OK)
128 {
129 DPRINT("UuidToStringW() failed with RPC status 0x%lx\n", RpcStatus);
130 rc = ERROR_GEN_FAILURE;
131 goto cleanup;
132 }
133
134 /* Add curly braces around Uuid */
135 UuidString = HeapAlloc(GetProcessHeap(), 0, (2 + wcslen(UuidRpcString)) * sizeof(WCHAR) + sizeof(UNICODE_NULL));
136 if (!UuidString)
137 {
138 DPRINT("HeapAlloc() failed\n");
139 rc = ERROR_NOT_ENOUGH_MEMORY;
140 goto cleanup;
141 }
142 wcscpy(UuidString, L"{");
143 wcscat(UuidString, UuidRpcString);
144 wcscat(UuidString, L"}");
145
146 /* Create device name */
147 DeviceName = HeapAlloc(GetProcessHeap(), 0, (wcslen(L"\\Device\\") + wcslen(UuidString)) * sizeof(WCHAR) + sizeof(UNICODE_NULL));
148 if (!DeviceName)
149 {
150 DPRINT("HeapAlloc() failed\n");
151 rc = ERROR_NOT_ENOUGH_MEMORY;
152 goto cleanup;
153 }
154 wcscpy(DeviceName, L"\\Device\\");
155 wcscat(DeviceName, UuidString);
156
157 /* Create export name */
158 ExportName = HeapAlloc(GetProcessHeap(), 0, (wcslen(L"\\Device\\Tcpip_") + wcslen(UuidString)) * sizeof(WCHAR) + sizeof(UNICODE_NULL));
159 if (!ExportName)
160 {
161 DPRINT("HeapAlloc() failed\n");
162 rc = ERROR_NOT_ENOUGH_MEMORY;
163 goto cleanup;
164 }
165 wcscpy(ExportName, L"\\Device\\Tcpip_");
166 wcscat(ExportName, UuidString);
167
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)
171 {
172 DPRINT("RegCreateKeyExW() failed with error 0x%lx\n", rc);
173 goto cleanup;
174 }
175 rc = RegCreateKeyExW(hKey, UuidString, 0, NULL, REG_OPTION_NON_VOLATILE, 0, NULL, &hNetworkKey, NULL);
176 if (rc != ERROR_SUCCESS)
177 {
178 DPRINT("RegCreateKeyExW() failed with error 0x%lx\n", rc);
179 goto cleanup;
180 }
181 RegCloseKey(hKey);
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)
185 {
186 DPRINT("RegCreateKeyExW() failed with error 0x%lx\n", rc);
187 goto cleanup;
188 }
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)
193 {
194 DPRINT("RegSetValueExW() failed with error 0x%lx\n", rc);
195 goto cleanup;
196 }
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)
199 {
200 DPRINT("RegSetValueExW() failed with error 0x%lx\n", rc);
201 goto cleanup;
202 }
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)
205 {
206 DPRINT("RegSetValueExW() failed with error 0x%lx\n", rc);
207 goto cleanup;
208 }
209 RegCloseKey(hKey);
210 hKey = INVALID_HANDLE_VALUE;
211
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)
215 {
216 rc = GetLastError();
217 DPRINT("SetupDiCreateDevRegKeyW() failed with error 0x%lx\n", rc);
218 goto cleanup;
219 }
220 rc = RegSetValueExW(hKey, L"NetCfgInstanceId", 0, REG_SZ, (const BYTE*)UuidString, (wcslen(UuidString) + 1) * sizeof(WCHAR));
221 if (rc != ERROR_SUCCESS)
222 {
223 DPRINT("RegSetValueExW() failed with error 0x%lx\n", rc);
224 goto cleanup;
225 }
226 rc = RegCreateKeyExW(hKey, L"Linkage", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_SET_VALUE, NULL, &hLinkageKey, NULL);
227 if (rc != ERROR_SUCCESS)
228 {
229 DPRINT("RegCreateKeyExW() failed with error 0x%lx\n", rc);
230 goto cleanup;
231 }
232 rc = RegSetValueExW(hLinkageKey, L"Export", 0, REG_SZ, (const BYTE*)DeviceName, (wcslen(DeviceName) + 1) * sizeof(WCHAR));
233 if (rc != ERROR_SUCCESS)
234 {
235 DPRINT("RegSetValueExW() failed with error 0x%lx\n", rc);
236 goto cleanup;
237 }
238 rc = RegSetValueExW(hLinkageKey, L"RootDevice", 0, REG_SZ, (const BYTE*)UuidString, (wcslen(UuidString) + 1) * sizeof(WCHAR));
239 if (rc != ERROR_SUCCESS)
240 {
241 DPRINT("RegSetValueExW() failed with error 0x%lx\n", rc);
242 goto cleanup;
243 }
244 rc = RegSetValueExW(hLinkageKey, L"UpperBind", 0, REG_SZ, (const BYTE*)L"Tcpip", (wcslen(L"Tcpip") + 1) * sizeof(WCHAR));
245 if (rc != ERROR_SUCCESS)
246 {
247 DPRINT("RegSetValueExW() failed with error 0x%lx\n", rc);
248 goto cleanup;
249 }
250 RegCloseKey(hKey);
251 hKey = INVALID_HANDLE_VALUE;
252
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)
256 {
257 DPRINT("RegCreateKeyExW() failed with error 0x%lx\n", rc);
258 goto cleanup;
259 }
260 rc = RegCreateKeyExW(hNetworkKey, UuidString, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_SET_VALUE, NULL, &hKey, NULL);
261 if (rc != ERROR_SUCCESS)
262 {
263 DPRINT("RegCreateKeyExW() failed with error 0x%lx\n", rc);
264 goto cleanup;
265 }
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)
268 {
269 DPRINT("RegSetValueExW() failed with error 0x%lx\n", rc);
270 goto cleanup;
271 }
272 RegCloseKey(hKey);
273 hKey = INVALID_HANDLE_VALUE;
274
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)
278 {
279 DPRINT("RegCreateKeyExW() failed with error 0x%lx\n", rc);
280 goto cleanup;
281 }
282 rc = AppendStringToMultiSZ(hKey, L"Bind", DeviceName);
283 if (rc != ERROR_SUCCESS)
284 {
285 DPRINT("AppendStringToMultiSZ() failed with error 0x%lx\n", rc);
286 goto cleanup;
287 }
288 rc = AppendStringToMultiSZ(hKey, L"Export", ExportName);
289 if (rc != ERROR_SUCCESS)
290 {
291 DPRINT("AppendStringToMultiSZ() failed with error 0x%lx\n", rc);
292 goto cleanup;
293 }
294 rc = AppendStringToMultiSZ(hKey, L"Route", UuidString);
295 if (rc != ERROR_SUCCESS)
296 {
297 DPRINT("AppendStringToMultiSZ() failed with error 0x%lx\n", rc);
298 goto cleanup;
299 }
300
301 rc = ERROR_SUCCESS;
302
303 cleanup:
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)
310 RegCloseKey(hKey);
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);
317
318 if (rc == ERROR_SUCCESS)
319 rc = ERROR_DI_DO_DEFAULT;
320 DPRINT("Returning 0x%lx\n", rc);
321 return rc;
322 }