1 /*
2 * PROJECT: ReactOS Shell
3 * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later)
4 * PURPOSE: ReactOS Networking Configuration
5 * COPYRIGHT: Copyright 2016 Eric Kohl
6 */
7
8 #include "precomp.h"
9
10 #include <syssetup/syssetup.h>
11
12
13 #define NETWORK_SETUP_MAGIC 0x50515253
14
15 typedef struct _NETWORKSETUPDATA
16 {
17 DWORD dwMagic;
18 BOOL bTypicalNetworkSetup;
19
20
21 PSETUPDATA pSetupData;
22 } NETWORKSETUPDATA, *PNETWORKSETUPDATA;
23
24
25 extern "C"
26 {
27
28 static
29 VOID
SetBoldText(HWND hwndDlg,INT control,PSETUPDATA pSetupData)30 SetBoldText(
31 HWND hwndDlg,
32 INT control,
33 PSETUPDATA pSetupData)
34 {
35 SendDlgItemMessageW(hwndDlg, control, WM_SETFONT, (WPARAM)pSetupData->hBoldFont, MAKELPARAM(TRUE, 0));
36 }
37
38
39 static
40 HRESULT
InstallTypicalNetworkSettings(VOID)41 InstallTypicalNetworkSettings(VOID)
42 {
43 INetCfg *pNetCfg = NULL;
44 INetCfgLock *pNetCfgLock = NULL;
45 INetCfgComponent *pTcpipComponent = NULL;
46 INetCfgComponent *pNicComponent = NULL;
47 IEnumNetCfgComponent *pEnumNicComponents = NULL;
48 WCHAR *pszNicName;
49 BOOL fWriteLocked = FALSE, fInitialized = FALSE;
50 HRESULT hr;
51
52 TRACE("InstallTypicalNetworkSettings()\n");
53
54 hr = CoInitialize(NULL);
55 if (hr != S_OK)
56 {
57 ERR("CoInitialize failed\n");
58 goto exit;
59 }
60
61 hr = CoCreateInstance(CLSID_CNetCfg,
62 NULL,
63 CLSCTX_INPROC_SERVER,
64 IID_INetCfg,
65 (PVOID*)&pNetCfg);
66 if (hr != S_OK)
67 {
68 ERR("CoCreateInstance failed\n");
69 goto exit;
70 }
71
72 /* Acquire the write-lock */
73 hr = pNetCfg->QueryInterface(IID_INetCfgLock,
74 (PVOID*)&pNetCfgLock);
75 if (hr != S_OK)
76 {
77 ERR("QueryInterface failed\n");
78 goto exit;
79 }
80
81 hr = pNetCfgLock->AcquireWriteLock(5000,
82 L"SysSetup",
83 NULL);
84 if (hr != S_OK)
85 {
86 ERR("AcquireWriteLock failed\n");
87 goto exit;
88 }
89
90 fWriteLocked = TRUE;
91
92 /* Initialize the network configuration */
93 hr = pNetCfg->Initialize(NULL);
94 if (hr != S_OK)
95 {
96 ERR("Initialize failed\n");
97 goto exit;
98 }
99
100 fInitialized = TRUE;
101
102 /* Find the TCP/IP driver */
103 hr = pNetCfg->FindComponent(L"ms_tcpip",
104 &pTcpipComponent);
105 if (hr == S_OK)
106 {
107 FIXME("Found the TCP/IP driver!\n");
108 }
109 else
110 {
111 ERR("Initialize failed\n");
112 goto exit;
113 }
114
115 hr = pNetCfg->EnumComponents(&GUID_DEVCLASS_NET,
116 &pEnumNicComponents);
117 if (hr != S_OK)
118 {
119 ERR("EnumComponents failed\n");
120 goto exit;
121 }
122
123 for (;;)
124 {
125 hr = pEnumNicComponents->Next(1,
126 &pNicComponent,
127 NULL);
128 if (hr != S_OK)
129 {
130 TRACE("EnumNicComponents done!\n");
131 break;
132 }
133
134 hr = pNicComponent->GetDisplayName(&pszNicName);
135 if (hr == S_OK)
136 {
137 FIXME("NIC name: %S\n", pszNicName);
138 CoTaskMemFree(pszNicName);
139 }
140
141 // FIXME Bind Tcpip to the NIC
142
143 pNicComponent->Release();
144 pNicComponent = NULL;
145 }
146
147 TRACE("Done!\n");
148 exit:
149 if (pNicComponent != NULL)
150 pNicComponent->Release();
151
152 if (pEnumNicComponents != NULL)
153 pEnumNicComponents->Release();
154
155 if (pTcpipComponent != NULL)
156 pTcpipComponent->Release();
157
158 if (fInitialized)
159 pNetCfg->Uninitialize();
160
161 if (fWriteLocked)
162 pNetCfgLock->ReleaseWriteLock();
163
164 if (pNetCfgLock != NULL)
165 pNetCfgLock->Release();
166
167 if (pNetCfg != NULL)
168 pNetCfg->Release();
169
170 CoUninitialize();
171
172 TRACE("InstallTypicalNetworkSettings() done!\n");
173
174 return hr;
175 }
176
177
178 static
179 INT_PTR
180 CALLBACK
NetworkSettingsPageDlgProc(HWND hwndDlg,UINT uMsg,WPARAM wParam,LPARAM lParam)181 NetworkSettingsPageDlgProc(
182 HWND hwndDlg,
183 UINT uMsg,
184 WPARAM wParam,
185 LPARAM lParam)
186 {
187 PNETWORKSETUPDATA pNetworkSetupData;
188 PSETUPDATA pSetupData;
189 LPNMHDR lpnm;
190
191 /* Retrieve pointer to the global setup data */
192 pNetworkSetupData = (PNETWORKSETUPDATA)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
193 if ((pNetworkSetupData != NULL) &&
194 (pNetworkSetupData->dwMagic == NETWORK_SETUP_MAGIC))
195 pSetupData = pNetworkSetupData->pSetupData;
196
197 switch (uMsg)
198 {
199 case WM_INITDIALOG:
200 /* Save pointer to the global setup data */
201 pNetworkSetupData = (PNETWORKSETUPDATA)((LPPROPSHEETPAGE)lParam)->lParam;
202 SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (DWORD_PTR)pNetworkSetupData);
203 pSetupData = pNetworkSetupData->pSetupData;
204
205 /* Set the fonts of both the options to bold */
206 SetBoldText(hwndDlg, IDC_NETWORK_TYPICAL, pSetupData);
207 SetBoldText(hwndDlg, IDC_NETWORK_CUSTOM, pSetupData);
208
209 /* Set the typical settings option as the default */
210 SendDlgItemMessage(hwndDlg, IDC_NETWORK_TYPICAL, BM_SETCHECK, (WPARAM)BST_CHECKED, 0);
211
212 if (pSetupData->UnattendSetup)
213 {
214 //...
215 }
216 break;
217
218 case WM_DESTROY:
219 /* ATTENTION: Free pNetworkSetupData only in one of the page functions!!! */
220 //...
221 break;
222
223 case WM_NOTIFY:
224 lpnm = (LPNMHDR)lParam;
225
226 switch (lpnm->code)
227 {
228 case PSN_SETACTIVE:
229 /* Enable the Back and Next buttons */
230 PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK | PSWIZB_NEXT);
231 if (pSetupData->UnattendSetup)
232 {
233 SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_NETWORKCOMPONENTPAGE);
234 return TRUE;
235 }
236 break;
237
238 case PSN_WIZNEXT:
239 pNetworkSetupData->bTypicalNetworkSetup = FALSE;
240
241 /* If the Typical Settings button is chosen, then skip to the Domain Page */
242 if (IsDlgButtonChecked(hwndDlg, IDC_NETWORK_TYPICAL) == BST_CHECKED)
243 {
244 pNetworkSetupData->bTypicalNetworkSetup = TRUE;
245
246 InstallTypicalNetworkSettings();
247
248 SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_NETWORKDOMAINPAGE);
249 return TRUE;
250 }
251 break;
252
253 case PSN_WIZBACK:
254 pSetupData->UnattendSetup = FALSE;
255 break;
256 }
257 break;
258
259 default:
260 break;
261 }
262
263 return FALSE;
264 }
265
266 static
267 INT_PTR
268 CALLBACK
NetworkComponentPageDlgProc(HWND hwndDlg,UINT uMsg,WPARAM wParam,LPARAM lParam)269 NetworkComponentPageDlgProc(
270 HWND hwndDlg,
271 UINT uMsg,
272 WPARAM wParam,
273 LPARAM lParam)
274 {
275 PNETWORKSETUPDATA pNetworkSetupData;
276 PSETUPDATA pSetupData;
277 LPNMHDR lpnm;
278
279 /* Retrieve pointer to the global setup data */
280 pNetworkSetupData = (PNETWORKSETUPDATA)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
281 if ((pNetworkSetupData != NULL) &&
282 (pNetworkSetupData->dwMagic == NETWORK_SETUP_MAGIC))
283 pSetupData = pNetworkSetupData->pSetupData;
284
285 switch (uMsg)
286 {
287 case WM_INITDIALOG:
288 /* Save pointer to the global setup data */
289 pNetworkSetupData = (PNETWORKSETUPDATA)((LPPROPSHEETPAGE)lParam)->lParam;
290 SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (DWORD_PTR)pNetworkSetupData);
291 pSetupData = pNetworkSetupData->pSetupData;
292
293 SetBoldText(hwndDlg, IDC_NETWORK_DEVICE, pSetupData);
294
295 if (pSetupData->UnattendSetup)
296 {
297 //...
298 }
299 break;
300
301 case WM_DESTROY:
302 /* ATTENTION: Free pNetworkSetupData only in one of the page functions!!! */
303 //...
304 break;
305
306 case WM_NOTIFY:
307 lpnm = (LPNMHDR)lParam;
308
309 switch (lpnm->code)
310 {
311 case PSN_SETACTIVE:
312 /* Enable the Back and Next buttons */
313 PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK | PSWIZB_NEXT);
314 if (pSetupData->UnattendSetup)
315 {
316 SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_NETWORKDOMAINPAGE);
317 return TRUE;
318 }
319 break;
320
321 case PSN_WIZBACK:
322 pSetupData->UnattendSetup = FALSE;
323 break;
324 }
325 break;
326
327 default:
328 break;
329 }
330
331 return FALSE;
332 }
333
334 static
335 INT_PTR
336 CALLBACK
NetworkDomainPageDlgProc(HWND hwndDlg,UINT uMsg,WPARAM wParam,LPARAM lParam)337 NetworkDomainPageDlgProc(
338 HWND hwndDlg,
339 UINT uMsg,
340 WPARAM wParam,
341 LPARAM lParam)
342 {
343 PNETWORKSETUPDATA pNetworkSetupData;
344 PSETUPDATA pSetupData;
345 WCHAR DomainName[51];
346 WCHAR Title[64];
347 WCHAR ErrorName[256];
348 LPNMHDR lpnm;
349
350 /* Retrieve pointer to the global setup data */
351 pNetworkSetupData = (PNETWORKSETUPDATA)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
352 if ((pNetworkSetupData != NULL) &&
353 (pNetworkSetupData->dwMagic == NETWORK_SETUP_MAGIC))
354 pSetupData = pNetworkSetupData->pSetupData;
355
356 switch (uMsg)
357 {
358 case WM_INITDIALOG:
359 /* Save pointer to the global setup data */
360 pNetworkSetupData = (PNETWORKSETUPDATA)((LPPROPSHEETPAGE)lParam)->lParam;
361 SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (DWORD_PTR)pNetworkSetupData);
362 pSetupData = pNetworkSetupData->pSetupData;
363
364 /* Set the workgroup option as the default */
365 SendDlgItemMessage(hwndDlg, IDC_SELECT_WORKGROUP, BM_SETCHECK, (WPARAM)BST_CHECKED, 0);
366
367 wcscpy(DomainName, L"WORKGROUP");
368
369 /* Display current computer name */
370 SetDlgItemTextW(hwndDlg, IDC_DOMAIN_NAME, DomainName);
371
372 /* Set focus to owner name */
373 SetFocus(GetDlgItem(hwndDlg, IDC_DOMAIN_NAME));
374
375 if (pSetupData->UnattendSetup)
376 {
377 //...
378 }
379 break;
380
381 case WM_DESTROY:
382 //...
383 /* ATTENTION: Free pNetworkSetupData only in one of the page functions!!! */
384 if (pNetworkSetupData != NULL)
385 {
386 if ((!IsBadReadPtr(pNetworkSetupData, sizeof(NETWORKSETUPDATA))) &&
387 (pNetworkSetupData->dwMagic == NETWORK_SETUP_MAGIC))
388 HeapFree(GetProcessHeap(), 0, pNetworkSetupData);
389
390 SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (DWORD_PTR)NULL);
391 }
392 break;
393
394 case WM_NOTIFY:
395 lpnm = (LPNMHDR)lParam;
396
397 switch (lpnm->code)
398 {
399 case PSN_SETACTIVE:
400 /* Enable the Back and Next buttons */
401 PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK | PSWIZB_NEXT);
402 if (pSetupData->UnattendSetup)
403 {
404 SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, pSetupData->uPostNetworkWizardPage);
405 return TRUE;
406 }
407 break;
408
409 case PSN_WIZNEXT:
410 DomainName[0] = 0;
411 if (GetDlgItemTextW(hwndDlg, IDC_DOMAIN_NAME, DomainName, 50) == 0)
412 {
413 if (0 == LoadStringW(netshell_hInstance, IDS_REACTOS_SETUP, Title, sizeof(Title) / sizeof(Title[0])))
414 {
415 wcscpy(Title, L"ReactOS Setup");
416 }
417 if (0 == LoadStringW(netshell_hInstance, IDS_WZD_DOMAIN_NAME, ErrorName, sizeof(ErrorName) / sizeof(ErrorName[0])))
418 {
419 wcscpy(ErrorName, L"Setup cannot continue until you\nenter the name of your domain/workgroup.");
420 }
421 MessageBoxW(hwndDlg, ErrorName, Title, MB_ICONERROR | MB_OK);
422
423 SetFocus(GetDlgItem(hwndDlg, IDC_DOMAIN_NAME));
424 SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1);
425
426 //TODO: Implement setting the Domain/Workgroup
427
428 return TRUE;
429 }
430 break;
431
432 case PSN_WIZBACK:
433 pSetupData->UnattendSetup = FALSE;
434
435 /* If the Typical setup chosen, then skip back to the Settings Page */
436 if (pNetworkSetupData->bTypicalNetworkSetup == TRUE)
437 {
438 SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_NETWORKSETTINGSPAGE);
439 return TRUE;
440 }
441 break;
442 }
443 break;
444
445 default:
446 break;
447 }
448
449 return FALSE;
450 }
451
452
453 DWORD
454 WINAPI
NetSetupRequestWizardPages(PDWORD pPageCount,HPROPSHEETPAGE * pPages,PSETUPDATA pSetupData)455 NetSetupRequestWizardPages(
456 PDWORD pPageCount,
457 HPROPSHEETPAGE *pPages,
458 PSETUPDATA pSetupData)
459 {
460 PNETWORKSETUPDATA pNetworkSetupData;
461 PROPSHEETPAGE psp = {0};
462 DWORD dwPageCount = 3;
463 INT nPage = 0;
464
465 if (pPageCount == NULL)
466 return ERROR_INVALID_PARAMETER;
467
468 if (pPages == NULL)
469 {
470 *pPageCount = dwPageCount;
471 return ERROR_SUCCESS;
472 }
473
474 if (*pPageCount < dwPageCount)
475 return ERROR_BUFFER_OVERFLOW;
476
477 pSetupData->uFirstNetworkWizardPage = IDD_NETWORKSETTINGSPAGE;
478
479 pNetworkSetupData = (PNETWORKSETUPDATA)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(NETWORKSETUPDATA));
480 if (pNetworkSetupData == NULL)
481 return ERROR_OUTOFMEMORY;
482
483 pNetworkSetupData->dwMagic = NETWORK_SETUP_MAGIC;
484 pNetworkSetupData->pSetupData = pSetupData;
485
486
487 /* Create the Network Settings page */
488 psp.dwSize = sizeof(PROPSHEETPAGE);
489 psp.hInstance = netshell_hInstance;
490 psp.lParam = (LPARAM)pNetworkSetupData;
491
492 psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
493 psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_NETWORKSETTINGSTITLE);
494 psp.pszHeaderSubTitle = MAKEINTRESOURCE(IDS_NETWORKSETTINGSSUBTITLE);
495 psp.pfnDlgProc = NetworkSettingsPageDlgProc;
496 psp.pszTemplate = MAKEINTRESOURCE(IDD_NETWORKSETTINGSPAGE);
497 pPages[nPage++] = CreatePropertySheetPage(&psp);
498
499 /* Create the Network Components page */
500 psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
501 psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_NETWORKCOMPONENTTITLE);
502 psp.pszHeaderSubTitle = MAKEINTRESOURCE(IDS_NETWORKCOMPONENTSUBTITLE);
503 psp.pfnDlgProc = NetworkComponentPageDlgProc;
504 psp.pszTemplate = MAKEINTRESOURCE(IDD_NETWORKCOMPONENTPAGE);
505 pPages[nPage++] = CreatePropertySheetPage(&psp);
506
507 /* Create the Domain/Workgroup page */
508 psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
509 psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_NETWORKDOMAINTITLE);
510 psp.pszHeaderSubTitle = MAKEINTRESOURCE(IDS_NETWORKDOMAINSUBTITLE);
511 psp.pfnDlgProc = NetworkDomainPageDlgProc;
512 psp.pszTemplate = MAKEINTRESOURCE(IDD_NETWORKDOMAINPAGE);
513 pPages[nPage++] = CreatePropertySheetPage(&psp);
514
515 *pPageCount = dwPageCount;
516
517 return ERROR_SUCCESS;
518 }
519
520 } // extern "C"
521