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 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 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 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 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 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 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