1 /* 2 * COPYRIGHT: See COPYING in the top level directory 3 * PROJECT: System setup 4 * FILE: dll/win32/syssetup/wizard.c 5 * PURPOSE: GUI controls 6 * PROGRAMMERS: Eric Kohl 7 * Pierre Schweitzer <heis_spiter@hotmail.com> 8 * Ismael Ferreras Morezuelas <swyterzone+ros@gmail.com> 9 * Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com> 10 */ 11 12 /* INCLUDES *****************************************************************/ 13 14 #include "precomp.h" 15 16 #include <stdlib.h> 17 #include <time.h> 18 #include <winnls.h> 19 #include <windowsx.h> 20 #include <wincon.h> 21 #include <shlobj.h> 22 #include <tzlib.h> 23 #include <strsafe.h> 24 25 #define NDEBUG 26 #include <debug.h> 27 28 #define PM_REGISTRATION_NOTIFY (WM_APP + 1) 29 /* Private Message used to communicate progress from the background 30 registration thread to the main thread. 31 wParam = 0 Registration in progress 32 = 1 Registration completed 33 lParam = Pointer to a REGISTRATIONNOTIFY structure */ 34 35 typedef struct _REGISTRATIONNOTIFY 36 { 37 ULONG Progress; 38 UINT ActivityID; 39 LPCWSTR CurrentItem; 40 LPCWSTR ErrorMessage; 41 } REGISTRATIONNOTIFY, *PREGISTRATIONNOTIFY; 42 43 typedef struct _REGISTRATIONDATA 44 { 45 HWND hwndDlg; 46 ULONG DllCount; 47 ULONG Registered; 48 PVOID DefaultContext; 49 } REGISTRATIONDATA, *PREGISTRATIONDATA; 50 51 typedef struct _TIMEZONE_ENTRY 52 { 53 struct _TIMEZONE_ENTRY *Prev; 54 struct _TIMEZONE_ENTRY *Next; 55 WCHAR Description[128]; /* 'Display' */ 56 WCHAR StandardName[32]; /* 'Std' */ 57 WCHAR DaylightName[32]; /* 'Dlt' */ 58 REG_TZI_FORMAT TimezoneInfo; /* 'TZI' */ 59 ULONG Index; 60 } TIMEZONE_ENTRY, *PTIMEZONE_ENTRY; 61 62 63 /* FUNCTIONS ****************************************************************/ 64 65 extern void WINAPI Control_RunDLLW(HWND hWnd, HINSTANCE hInst, LPCWSTR cmd, DWORD nCmdShow); 66 67 68 static VOID 69 CenterWindow(HWND hWnd) 70 { 71 HWND hWndParent; 72 RECT rcParent; 73 RECT rcWindow; 74 75 hWndParent = GetParent(hWnd); 76 if (hWndParent == NULL) 77 hWndParent = GetDesktopWindow(); 78 79 GetWindowRect(hWndParent, &rcParent); 80 GetWindowRect(hWnd, &rcWindow); 81 82 SetWindowPos(hWnd, 83 HWND_TOP, 84 ((rcParent.right - rcParent.left) - (rcWindow.right - rcWindow.left)) / 2, 85 ((rcParent.bottom - rcParent.top) - (rcWindow.bottom - rcWindow.top)) / 2, 86 0, 87 0, 88 SWP_NOSIZE); 89 } 90 91 92 static HFONT 93 CreateTitleFont(VOID) 94 { 95 LOGFONTW LogFont = {0}; 96 HDC hdc; 97 HFONT hFont; 98 99 LogFont.lfWeight = FW_BOLD; 100 wcscpy(LogFont.lfFaceName, L"MS Shell Dlg"); 101 102 hdc = GetDC(NULL); 103 LogFont.lfHeight = -MulDiv(12, GetDeviceCaps(hdc, LOGPIXELSY), 72); 104 105 hFont = CreateFontIndirectW(&LogFont); 106 107 ReleaseDC(NULL, hdc); 108 109 return hFont; 110 } 111 112 113 static HFONT 114 CreateBoldFont(VOID) 115 { 116 LOGFONTW tmpFont = {0}; 117 HFONT hBoldFont; 118 HDC hDc; 119 120 /* Grabs the Drawing Context */ 121 hDc = GetDC(NULL); 122 123 tmpFont.lfHeight = -MulDiv(8, GetDeviceCaps(hDc, LOGPIXELSY), 72); 124 tmpFont.lfWeight = FW_BOLD; 125 wcscpy(tmpFont.lfFaceName, L"MS Shell Dlg"); 126 127 hBoldFont = CreateFontIndirectW(&tmpFont); 128 129 ReleaseDC(NULL, hDc); 130 131 return hBoldFont; 132 } 133 134 static INT_PTR CALLBACK 135 GplDlgProc(HWND hwndDlg, 136 UINT uMsg, 137 WPARAM wParam, 138 LPARAM lParam) 139 { 140 HRSRC GplTextResource; 141 HGLOBAL GplTextMem; 142 PVOID GplTextLocked; 143 PCHAR GplText; 144 DWORD Size; 145 146 147 switch (uMsg) 148 { 149 case WM_INITDIALOG: 150 GplTextResource = FindResourceW(hDllInstance, MAKEINTRESOURCE(IDR_GPL), L"RT_TEXT"); 151 if (NULL == GplTextResource) 152 { 153 break; 154 } 155 Size = SizeofResource(hDllInstance, GplTextResource); 156 if (0 == Size) 157 { 158 break; 159 } 160 GplText = HeapAlloc(GetProcessHeap(), 0, Size + 1); 161 if (NULL == GplText) 162 { 163 break; 164 } 165 GplTextMem = LoadResource(hDllInstance, GplTextResource); 166 if (NULL == GplTextMem) 167 { 168 HeapFree(GetProcessHeap(), 0, GplText); 169 break; 170 } 171 GplTextLocked = LockResource(GplTextMem); 172 if (NULL == GplTextLocked) 173 { 174 HeapFree(GetProcessHeap(), 0, GplText); 175 break; 176 } 177 memcpy(GplText, GplTextLocked, Size); 178 GplText[Size] = '\0'; 179 SendMessageA(GetDlgItem(hwndDlg, IDC_GPL_TEXT), WM_SETTEXT, 0, (LPARAM) GplText); 180 HeapFree(GetProcessHeap(), 0, GplText); 181 SetFocus(GetDlgItem(hwndDlg, IDOK)); 182 return FALSE; 183 184 case WM_CLOSE: 185 EndDialog(hwndDlg, IDCANCEL); 186 break; 187 188 case WM_COMMAND: 189 if (HIWORD(wParam) == BN_CLICKED && IDOK == LOWORD(wParam)) 190 { 191 EndDialog(hwndDlg, IDOK); 192 } 193 break; 194 195 default: 196 break; 197 } 198 199 return FALSE; 200 } 201 202 203 static INT_PTR CALLBACK 204 WelcomeDlgProc(HWND hwndDlg, 205 UINT uMsg, 206 WPARAM wParam, 207 LPARAM lParam) 208 { 209 PSETUPDATA pSetupData; 210 211 pSetupData = (PSETUPDATA)GetWindowLongPtr(hwndDlg, DWLP_USER); 212 213 switch (uMsg) 214 { 215 case WM_INITDIALOG: 216 { 217 HWND hwndControl; 218 DWORD dwStyle; 219 220 /* Get pointer to the global setup data */ 221 pSetupData = (PSETUPDATA)((LPPROPSHEETPAGE)lParam)->lParam; 222 SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pSetupData); 223 224 hwndControl = GetParent(hwndDlg); 225 226 /* Center the wizard window */ 227 CenterWindow (hwndControl); 228 229 /* Hide the system menu */ 230 dwStyle = GetWindowLongPtr(hwndControl, GWL_STYLE); 231 SetWindowLongPtr(hwndControl, GWL_STYLE, dwStyle & ~WS_SYSMENU); 232 233 /* Hide and disable the 'Cancel' button */ 234 hwndControl = GetDlgItem(GetParent(hwndDlg), IDCANCEL); 235 ShowWindow (hwndControl, SW_HIDE); 236 EnableWindow (hwndControl, FALSE); 237 238 /* Set title font */ 239 SendDlgItemMessage(hwndDlg, 240 IDC_WELCOMETITLE, 241 WM_SETFONT, 242 (WPARAM)pSetupData->hTitleFont, 243 (LPARAM)TRUE); 244 } 245 break; 246 247 248 case WM_NOTIFY: 249 { 250 LPNMHDR lpnm = (LPNMHDR)lParam; 251 252 switch (lpnm->code) 253 { 254 case PSN_SETACTIVE: 255 LogItem(L"BEGIN", L"WelcomePage"); 256 /* Enable the Next button */ 257 PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT); 258 if (pSetupData->UnattendSetup) 259 { 260 SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_ACKPAGE); 261 return TRUE; 262 } 263 break; 264 265 case PSN_WIZNEXT: 266 LogItem(L"END", L"WelcomePage"); 267 break; 268 269 case PSN_WIZBACK: 270 pSetupData->UnattendSetup = FALSE; 271 break; 272 273 default: 274 break; 275 } 276 } 277 break; 278 279 default: 280 break; 281 } 282 283 return FALSE; 284 } 285 286 287 static INT_PTR CALLBACK 288 AckPageDlgProc(HWND hwndDlg, 289 UINT uMsg, 290 WPARAM wParam, 291 LPARAM lParam) 292 { 293 LPNMHDR lpnm; 294 PWCHAR Projects; 295 PWCHAR End, CurrentProject; 296 INT ProjectsSize, ProjectsCount; 297 PSETUPDATA pSetupData; 298 299 pSetupData = (PSETUPDATA)GetWindowLongPtr(hwndDlg, DWLP_USER); 300 301 switch (uMsg) 302 { 303 case WM_INITDIALOG: 304 { 305 pSetupData = (PSETUPDATA)((LPPROPSHEETPAGE)lParam)->lParam; 306 SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pSetupData); 307 308 Projects = NULL; 309 ProjectsSize = 256; 310 while (TRUE) 311 { 312 Projects = HeapAlloc(GetProcessHeap(), 0, ProjectsSize * sizeof(WCHAR)); 313 if (NULL == Projects) 314 { 315 return FALSE; 316 } 317 ProjectsCount = LoadStringW(hDllInstance, IDS_ACKPROJECTS, Projects, ProjectsSize); 318 if (0 == ProjectsCount) 319 { 320 HeapFree(GetProcessHeap(), 0, Projects); 321 return FALSE; 322 } 323 if (ProjectsCount < ProjectsSize - 1) 324 { 325 break; 326 } 327 HeapFree(GetProcessHeap(), 0, Projects); 328 ProjectsSize *= 2; 329 } 330 331 CurrentProject = Projects; 332 while (*CurrentProject != L'\0') 333 { 334 End = wcschr(CurrentProject, L'\n'); 335 if (NULL != End) 336 { 337 *End = L'\0'; 338 } 339 (void)ListBox_AddString(GetDlgItem(hwndDlg, IDC_PROJECTS), CurrentProject); 340 if (NULL != End) 341 { 342 CurrentProject = End + 1; 343 } 344 else 345 { 346 CurrentProject += wcslen(CurrentProject); 347 } 348 } 349 HeapFree(GetProcessHeap(), 0, Projects); 350 } 351 break; 352 353 case WM_COMMAND: 354 if (HIWORD(wParam) == BN_CLICKED && IDC_VIEWGPL == LOWORD(wParam)) 355 { 356 DialogBox(hDllInstance, MAKEINTRESOURCE(IDD_GPL), NULL, GplDlgProc); 357 SetForegroundWindow(GetParent(hwndDlg)); 358 } 359 break; 360 361 case WM_NOTIFY: 362 { 363 lpnm = (LPNMHDR)lParam; 364 365 switch (lpnm->code) 366 { 367 case PSN_SETACTIVE: 368 /* Enable the Back and Next buttons */ 369 PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK | PSWIZB_NEXT); 370 if (pSetupData->UnattendSetup) 371 { 372 SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_PRODUCT); 373 return TRUE; 374 } 375 break; 376 377 case PSN_WIZBACK: 378 pSetupData->UnattendSetup = FALSE; 379 break; 380 381 default: 382 break; 383 } 384 } 385 break; 386 387 default: 388 break; 389 } 390 391 return FALSE; 392 } 393 394 static const WCHAR s_szProductOptions[] = L"SYSTEM\\CurrentControlSet\\Control\\ProductOptions"; 395 static const WCHAR s_szRosVersion[] = L"SYSTEM\\CurrentControlSet\\Control\\ReactOS\\Settings\\Version"; 396 static const WCHAR s_szControlWindows[] = L"SYSTEM\\CurrentControlSet\\Control\\Windows"; 397 static const WCHAR s_szWinlogon[] = L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon"; 398 399 typedef struct _PRODUCT_OPTION_DATA 400 { 401 LPCWSTR ProductSuite; 402 LPCWSTR ProductType; 403 DWORD ReportAsWorkstation; 404 DWORD CSDVersion; 405 DWORD LogonType; 406 } PRODUCT_OPTION_DATA; 407 408 static const PRODUCT_OPTION_DATA s_ProductOptionData[] = 409 { 410 { L"Terminal Server\0", L"ServerNT", 0, 0x200, 0 }, 411 { L"\0", L"WinNT", 1, 0x300, 1 } 412 }; 413 414 static BOOL 415 DoWriteProductOption(PRODUCT_OPTION nOption) 416 { 417 HKEY hKey; 418 LONG error; 419 LPCWSTR pszData; 420 DWORD dwValue, cbData; 421 const PRODUCT_OPTION_DATA *pData = &s_ProductOptionData[nOption]; 422 ASSERT(0 <= nOption && nOption < _countof(s_ProductOptionData)); 423 424 /* open ProductOptions key */ 425 error = RegOpenKeyExW(HKEY_LOCAL_MACHINE, s_szProductOptions, 0, KEY_WRITE, &hKey); 426 if (error) 427 { 428 DPRINT1("RegOpenKeyExW failed\n"); 429 goto Error; 430 } 431 432 /* write ProductSuite */ 433 pszData = pData->ProductSuite; 434 cbData = (lstrlenW(pszData) + 2) * sizeof(WCHAR); 435 error = RegSetValueExW(hKey, L"ProductSuite", 0, REG_MULTI_SZ, (const BYTE *)pszData, cbData); 436 if (error) 437 { 438 DPRINT1("RegSetValueExW failed\n"); 439 goto Error; 440 } 441 442 /* write ProductType */ 443 pszData = pData->ProductType; 444 cbData = (lstrlenW(pszData) + 1) * sizeof(WCHAR); 445 error = RegSetValueExW(hKey, L"ProductType", 0, REG_SZ, (const BYTE *)pszData, cbData); 446 if (error) 447 { 448 DPRINT1("RegSetValueExW failed\n"); 449 goto Error; 450 } 451 452 RegCloseKey(hKey); 453 454 /* open ReactOS version key */ 455 error = RegOpenKeyExW(HKEY_LOCAL_MACHINE, s_szRosVersion, 0, KEY_WRITE, &hKey); 456 if (error) 457 { 458 DPRINT1("RegOpenKeyExW failed\n"); 459 goto Error; 460 } 461 462 /* write ReportAsWorkstation */ 463 dwValue = pData->ReportAsWorkstation; 464 cbData = sizeof(dwValue); 465 error = RegSetValueExW(hKey, L"ReportAsWorkstation", 0, REG_DWORD, (const BYTE *)&dwValue, cbData); 466 if (error) 467 { 468 DPRINT1("RegSetValueExW failed\n"); 469 goto Error; 470 } 471 472 RegCloseKey(hKey); 473 474 /* open Control Windows key */ 475 error = RegOpenKeyExW(HKEY_LOCAL_MACHINE, s_szControlWindows, 0, KEY_WRITE, &hKey); 476 if (error) 477 { 478 DPRINT1("RegOpenKeyExW failed\n"); 479 goto Error; 480 } 481 482 /* write Control Windows CSDVersion */ 483 dwValue = pData->CSDVersion; 484 cbData = sizeof(dwValue); 485 error = RegSetValueExW(hKey, L"CSDVersion", 0, REG_DWORD, (const BYTE *)&dwValue, cbData); 486 if (error) 487 { 488 DPRINT1("RegSetValueExW failed\n"); 489 goto Error; 490 } 491 492 RegCloseKey(hKey); 493 494 /* open Winlogon key */ 495 error = RegOpenKeyExW(HKEY_LOCAL_MACHINE, s_szWinlogon, 0, KEY_WRITE, &hKey); 496 if (error) 497 { 498 DPRINT1("RegOpenKeyExW failed\n"); 499 goto Error; 500 } 501 502 /* write LogonType */ 503 dwValue = pData->LogonType; 504 cbData = sizeof(dwValue); 505 error = RegSetValueExW(hKey, L"LogonType", 0, REG_DWORD, (const BYTE *)&dwValue, cbData); 506 if (error) 507 { 508 DPRINT1("RegSetValueExW failed\n"); 509 goto Error; 510 } 511 512 Error: 513 if (hKey) 514 RegCloseKey(hKey); 515 516 return error == ERROR_SUCCESS; 517 } 518 519 static void 520 OnChooseOption(HWND hwndDlg, PRODUCT_OPTION nOption) 521 { 522 WCHAR szText[256]; 523 ASSERT(0 <= nOption && nOption < _countof(s_ProductOptionData)); 524 525 switch (nOption) 526 { 527 case PRODUCT_OPTION_SERVER: 528 LoadStringW(hDllInstance, IDS_PRODUCTSERVERINFO, szText, _countof(szText)); 529 break; 530 531 case PRODUCT_OPTION_WORKSTATION: 532 LoadStringW(hDllInstance, IDS_PRODUCTWORKSTATIONINFO, szText, _countof(szText)); 533 break; 534 535 default: 536 return; 537 } 538 539 SetDlgItemTextW(hwndDlg, IDC_PRODUCT_DESCRIPTION, szText); 540 } 541 542 static INT_PTR CALLBACK 543 ProductPageDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) 544 { 545 LPNMHDR lpnm; 546 PSETUPDATA pSetupData; 547 INT iItem; 548 WCHAR szText[64], szDefault[64]; 549 HICON hIcon; 550 551 pSetupData = (PSETUPDATA)GetWindowLongPtr(hwndDlg, DWLP_USER); 552 553 switch (uMsg) 554 { 555 case WM_INITDIALOG: 556 { 557 pSetupData = (PSETUPDATA)((LPPROPSHEETPAGE)lParam)->lParam; 558 SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pSetupData); 559 560 LoadStringW(hDllInstance, IDS_DEFAULT, szDefault, _countof(szDefault)); 561 562 LoadStringW(hDllInstance, IDS_PRODUCTSERVERNAME, szText, _countof(szText)); 563 if (PRODUCT_OPTION_DEFAULT == PRODUCT_OPTION_SERVER) 564 { 565 StringCchCatW(szText, _countof(szText), L" "); 566 StringCchCatW(szText, _countof(szText), szDefault); 567 } 568 SendDlgItemMessageW(hwndDlg, IDC_PRODUCT_OPTIONS, CB_ADDSTRING, 0, (LPARAM)szText); 569 570 LoadStringW(hDllInstance, IDS_PRODUCTWORKSTATIONNAME, szText, _countof(szText)); 571 if (PRODUCT_OPTION_DEFAULT == PRODUCT_OPTION_WORKSTATION) 572 { 573 StringCchCatW(szText, _countof(szText), L" "); 574 StringCchCatW(szText, _countof(szText), szDefault); 575 } 576 SendDlgItemMessageW(hwndDlg, IDC_PRODUCT_OPTIONS, CB_ADDSTRING, 0, (LPARAM)szText); 577 578 SendDlgItemMessageW(hwndDlg, IDC_PRODUCT_OPTIONS, CB_SETCURSEL, PRODUCT_OPTION_DEFAULT, 0); 579 OnChooseOption(hwndDlg, PRODUCT_OPTION_DEFAULT); 580 581 hIcon = LoadIcon(NULL, IDI_WINLOGO); 582 SendDlgItemMessageW(hwndDlg, IDC_PRODUCT_ICON, STM_SETICON, (WPARAM)hIcon, 0); 583 return TRUE; 584 } 585 586 case WM_COMMAND: 587 if (HIWORD(wParam) == CBN_SELCHANGE && IDC_PRODUCT_OPTIONS == LOWORD(wParam)) 588 { 589 iItem = SendDlgItemMessageW(hwndDlg, IDC_PRODUCT_OPTIONS, CB_GETCURSEL, 0, 0); 590 OnChooseOption(hwndDlg, (PRODUCT_OPTION)iItem); 591 } 592 break; 593 594 case WM_NOTIFY: 595 { 596 lpnm = (LPNMHDR)lParam; 597 598 switch (lpnm->code) 599 { 600 case PSN_SETACTIVE: 601 /* Enable the Back and Next buttons */ 602 PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK | PSWIZB_NEXT); 603 if (pSetupData->UnattendSetup) 604 { 605 OnChooseOption(hwndDlg, pSetupData->ProductOption); 606 DoWriteProductOption(pSetupData->ProductOption); 607 SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_LOCALEPAGE); 608 return TRUE; 609 } 610 break; 611 612 case PSN_WIZNEXT: 613 iItem = SendDlgItemMessageW(hwndDlg, IDC_PRODUCT_OPTIONS, CB_GETCURSEL, 0, 0); 614 pSetupData->ProductOption = (PRODUCT_OPTION)iItem; 615 DoWriteProductOption(pSetupData->ProductOption); 616 break; 617 618 case PSN_WIZBACK: 619 pSetupData->UnattendSetup = FALSE; 620 break; 621 622 default: 623 break; 624 } 625 } 626 break; 627 628 default: 629 break; 630 } 631 632 return FALSE; 633 } 634 635 static 636 BOOL 637 WriteOwnerSettings(WCHAR * OwnerName, 638 WCHAR * OwnerOrganization) 639 { 640 HKEY hKey; 641 LONG res; 642 643 res = RegOpenKeyExW(HKEY_LOCAL_MACHINE, 644 L"Software\\Microsoft\\Windows NT\\CurrentVersion", 645 0, 646 KEY_ALL_ACCESS, 647 &hKey); 648 649 if (res != ERROR_SUCCESS) 650 { 651 return FALSE; 652 } 653 654 res = RegSetValueExW(hKey, 655 L"RegisteredOwner", 656 0, 657 REG_SZ, 658 (LPBYTE)OwnerName, 659 (wcslen(OwnerName) + 1) * sizeof(WCHAR)); 660 661 if (res != ERROR_SUCCESS) 662 { 663 RegCloseKey(hKey); 664 return FALSE; 665 } 666 667 res = RegSetValueExW(hKey, 668 L"RegisteredOrganization", 669 0, 670 REG_SZ, 671 (LPBYTE)OwnerOrganization, 672 (wcslen(OwnerOrganization) + 1) * sizeof(WCHAR)); 673 674 RegCloseKey(hKey); 675 return (res == ERROR_SUCCESS); 676 } 677 678 static INT_PTR CALLBACK 679 OwnerPageDlgProc(HWND hwndDlg, 680 UINT uMsg, 681 WPARAM wParam, 682 LPARAM lParam) 683 { 684 WCHAR OwnerName[51]; 685 WCHAR OwnerOrganization[51]; 686 WCHAR Title[64]; 687 WCHAR ErrorName[256]; 688 LPNMHDR lpnm; 689 PSETUPDATA pSetupData; 690 691 pSetupData = (PSETUPDATA)GetWindowLongPtr(hwndDlg, DWLP_USER); 692 693 switch (uMsg) 694 { 695 case WM_INITDIALOG: 696 { 697 pSetupData = (PSETUPDATA)((LPPROPSHEETPAGE)lParam)->lParam; 698 SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pSetupData); 699 700 /* set a localized ('Owner') placeholder string as default */ 701 if (LoadStringW(hDllInstance, IDS_MACHINE_OWNER_NAME, OwnerName, _countof(OwnerName))) 702 { 703 SendDlgItemMessage(hwndDlg, IDC_OWNERNAME, WM_SETTEXT, 0, (LPARAM)OwnerName); 704 } 705 706 SendDlgItemMessage(hwndDlg, IDC_OWNERNAME, EM_LIMITTEXT, 50, 0); 707 SendDlgItemMessage(hwndDlg, IDC_OWNERORGANIZATION, EM_LIMITTEXT, 50, 0); 708 709 /* Set focus to owner name */ 710 SetFocus(GetDlgItem(hwndDlg, IDC_OWNERNAME)); 711 712 /* Select the default text to quickly overwrite it by typing */ 713 SendDlgItemMessage(hwndDlg, IDC_OWNERNAME, EM_SETSEL, 0, -1); 714 } 715 break; 716 717 718 case WM_NOTIFY: 719 { 720 lpnm = (LPNMHDR)lParam; 721 722 switch (lpnm->code) 723 { 724 case PSN_SETACTIVE: 725 /* Enable the Back and Next buttons */ 726 PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK | PSWIZB_NEXT); 727 if (pSetupData->UnattendSetup) 728 { 729 SendMessage(GetDlgItem(hwndDlg, IDC_OWNERNAME), WM_SETTEXT, 0, (LPARAM)pSetupData->OwnerName); 730 SendMessage(GetDlgItem(hwndDlg, IDC_OWNERORGANIZATION), WM_SETTEXT, 0, (LPARAM)pSetupData->OwnerOrganization); 731 if (WriteOwnerSettings(pSetupData->OwnerName, pSetupData->OwnerOrganization)) 732 { 733 SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_COMPUTERPAGE); 734 return TRUE; 735 } 736 } 737 break; 738 739 case PSN_WIZNEXT: 740 OwnerName[0] = 0; 741 if (GetDlgItemTextW(hwndDlg, IDC_OWNERNAME, OwnerName, 50) == 0) 742 { 743 if (0 == LoadStringW(hDllInstance, IDS_REACTOS_SETUP, Title, ARRAYSIZE(Title))) 744 { 745 wcscpy(Title, L"ReactOS Setup"); 746 } 747 if (0 == LoadStringW(hDllInstance, IDS_WZD_NAME, ErrorName, ARRAYSIZE(ErrorName))) 748 { 749 wcscpy(ErrorName, L"Setup cannot continue until you enter your name."); 750 } 751 MessageBoxW(hwndDlg, ErrorName, Title, MB_ICONERROR | MB_OK); 752 753 SetFocus(GetDlgItem(hwndDlg, IDC_OWNERNAME)); 754 SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1); 755 756 return TRUE; 757 } 758 759 OwnerOrganization[0] = 0; 760 GetDlgItemTextW(hwndDlg, IDC_OWNERORGANIZATION, OwnerOrganization, 50); 761 762 if (!WriteOwnerSettings(OwnerName, OwnerOrganization)) 763 { 764 SetFocus(GetDlgItem(hwndDlg, IDC_OWNERNAME)); 765 SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1); 766 return TRUE; 767 } 768 769 case PSN_WIZBACK: 770 pSetupData->UnattendSetup = FALSE; 771 break; 772 773 default: 774 break; 775 } 776 } 777 break; 778 779 default: 780 break; 781 } 782 783 return FALSE; 784 } 785 786 static 787 BOOL 788 WriteComputerSettings(WCHAR * ComputerName, HWND hwndDlg) 789 { 790 WCHAR Title[64]; 791 WCHAR ErrorComputerName[256]; 792 LONG lError; 793 HKEY hKey = NULL; 794 795 if (!SetComputerNameW(ComputerName)) 796 { 797 if (hwndDlg != NULL) 798 { 799 if (0 == LoadStringW(hDllInstance, IDS_REACTOS_SETUP, Title, ARRAYSIZE(Title))) 800 { 801 wcscpy(Title, L"ReactOS Setup"); 802 } 803 if (0 == LoadStringW(hDllInstance, IDS_WZD_SETCOMPUTERNAME, ErrorComputerName, 804 ARRAYSIZE(ErrorComputerName))) 805 { 806 wcscpy(ErrorComputerName, L"Setup failed to set the computer name."); 807 } 808 MessageBoxW(hwndDlg, ErrorComputerName, Title, MB_ICONERROR | MB_OK); 809 } 810 811 return FALSE; 812 } 813 814 /* Set the physical DNS domain */ 815 SetComputerNameExW(ComputerNamePhysicalDnsDomain, L""); 816 817 /* Set the physical DNS hostname */ 818 SetComputerNameExW(ComputerNamePhysicalDnsHostname, ComputerName); 819 820 /* Set the accounts domain name */ 821 SetAccountsDomainSid(NULL, ComputerName); 822 823 /* Now we need to set the Hostname */ 824 lError = RegOpenKeyExW(HKEY_LOCAL_MACHINE, 825 L"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters", 826 0, 827 KEY_SET_VALUE, 828 &hKey); 829 if (lError != ERROR_SUCCESS) 830 { 831 DPRINT1("RegOpenKeyExW for Tcpip\\Parameters failed (%08lX)\n", lError); 832 return TRUE; 833 } 834 835 lError = RegSetValueEx(hKey, 836 L"Hostname", 837 0, 838 REG_SZ, 839 (LPBYTE)ComputerName, 840 (wcslen(ComputerName) + 1) * sizeof(WCHAR)); 841 if (lError != ERROR_SUCCESS) 842 { 843 DPRINT1("RegSetValueEx(\"Hostname\") failed (%08lX)\n", lError); 844 } 845 846 RegCloseKey(hKey); 847 848 return TRUE; 849 } 850 851 852 static 853 BOOL 854 WriteDefaultLogonData(LPWSTR Domain) 855 { 856 WCHAR szAdministratorName[256]; 857 HKEY hKey = NULL; 858 LONG lError; 859 860 if (LoadStringW(hDllInstance, 861 IDS_ADMINISTRATOR_NAME, 862 szAdministratorName, 863 ARRAYSIZE(szAdministratorName)) == 0) 864 { 865 wcscpy(szAdministratorName, L"Administrator"); 866 } 867 868 lError = RegOpenKeyExW(HKEY_LOCAL_MACHINE, 869 L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", 870 0, 871 KEY_SET_VALUE, 872 &hKey); 873 if (lError != ERROR_SUCCESS) 874 return FALSE; 875 876 lError = RegSetValueEx(hKey, 877 L"DefaultDomainName", 878 0, 879 REG_SZ, 880 (LPBYTE)Domain, 881 (wcslen(Domain)+ 1) * sizeof(WCHAR)); 882 if (lError != ERROR_SUCCESS) 883 { 884 DPRINT1("RegSetValueEx(\"DefaultDomainName\") failed!\n"); 885 } 886 887 lError = RegSetValueEx(hKey, 888 L"DefaultUserName", 889 0, 890 REG_SZ, 891 (LPBYTE)szAdministratorName, 892 (wcslen(szAdministratorName)+ 1) * sizeof(WCHAR)); 893 if (lError != ERROR_SUCCESS) 894 { 895 DPRINT1("RegSetValueEx(\"DefaultUserName\") failed!\n"); 896 } 897 898 RegCloseKey(hKey); 899 900 return TRUE; 901 } 902 903 904 /* lpBuffer will be filled with a 15-char string (plus the null terminator) */ 905 static void 906 GenerateComputerName(LPWSTR lpBuffer) 907 { 908 static const WCHAR Chars[] = L"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; 909 static const unsigned cChars = sizeof(Chars) / sizeof(WCHAR) - 1; 910 unsigned i; 911 912 wcscpy(lpBuffer, L"REACTOS-"); 913 914 srand(GetTickCount()); 915 916 /* fill in 7 characters */ 917 for (i = 8; i < 15; i++) 918 lpBuffer[i] = Chars[rand() % cChars]; 919 920 lpBuffer[15] = UNICODE_NULL; /* NULL-terminate */ 921 } 922 923 static INT_PTR CALLBACK 924 ComputerPageDlgProc(HWND hwndDlg, 925 UINT uMsg, 926 WPARAM wParam, 927 LPARAM lParam) 928 { 929 WCHAR ComputerName[MAX_COMPUTERNAME_LENGTH + 1]; 930 WCHAR Password1[128]; 931 WCHAR Password2[128]; 932 PWCHAR Password; 933 WCHAR Title[64]; 934 WCHAR EmptyComputerName[256], NotMatchPassword[256], WrongPassword[256]; 935 LPNMHDR lpnm; 936 PSETUPDATA pSetupData; 937 938 pSetupData = (PSETUPDATA)GetWindowLongPtr(hwndDlg, DWLP_USER); 939 940 if (0 == LoadStringW(hDllInstance, IDS_REACTOS_SETUP, Title, ARRAYSIZE(Title))) 941 { 942 wcscpy(Title, L"ReactOS Setup"); 943 } 944 945 switch (uMsg) 946 { 947 case WM_INITDIALOG: 948 pSetupData = (PSETUPDATA)((LPPROPSHEETPAGE)lParam)->lParam; 949 SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pSetupData); 950 951 /* Generate a new pseudo-random computer name */ 952 GenerateComputerName(ComputerName); 953 954 /* Display current computer name */ 955 SetDlgItemTextW(hwndDlg, IDC_COMPUTERNAME, ComputerName); 956 957 /* Set text limits */ 958 SendDlgItemMessage(hwndDlg, IDC_COMPUTERNAME, EM_LIMITTEXT, MAX_COMPUTERNAME_LENGTH, 0); 959 SendDlgItemMessage(hwndDlg, IDC_ADMINPASSWORD1, EM_LIMITTEXT, 127, 0); 960 SendDlgItemMessage(hwndDlg, IDC_ADMINPASSWORD2, EM_LIMITTEXT, 127, 0); 961 962 /* Set focus to computer name */ 963 SetFocus(GetDlgItem(hwndDlg, IDC_COMPUTERNAME)); 964 if (pSetupData->UnattendSetup) 965 { 966 SendMessage(GetDlgItem(hwndDlg, IDC_COMPUTERNAME), WM_SETTEXT, 0, (LPARAM)pSetupData->ComputerName); 967 SendMessage(GetDlgItem(hwndDlg, IDC_ADMINPASSWORD1), WM_SETTEXT, 0, (LPARAM)pSetupData->AdminPassword); 968 SendMessage(GetDlgItem(hwndDlg, IDC_ADMINPASSWORD2), WM_SETTEXT, 0, (LPARAM)pSetupData->AdminPassword); 969 WriteComputerSettings(pSetupData->ComputerName, NULL); 970 SetAdministratorPassword(pSetupData->AdminPassword); 971 } 972 973 /* Store the administrator account name as the default user name */ 974 WriteDefaultLogonData(pSetupData->ComputerName); 975 break; 976 977 978 case WM_NOTIFY: 979 { 980 lpnm = (LPNMHDR)lParam; 981 982 switch (lpnm->code) 983 { 984 case PSN_SETACTIVE: 985 /* Enable the Back and Next buttons */ 986 PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK | PSWIZB_NEXT); 987 if (pSetupData->UnattendSetup && WriteComputerSettings(pSetupData->ComputerName, hwndDlg)) 988 { 989 SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_THEMEPAGE); 990 return TRUE; 991 } 992 break; 993 994 case PSN_WIZNEXT: 995 if (0 == GetDlgItemTextW(hwndDlg, IDC_COMPUTERNAME, ComputerName, MAX_COMPUTERNAME_LENGTH + 1)) 996 { 997 if (0 == LoadStringW(hDllInstance, IDS_WZD_COMPUTERNAME, EmptyComputerName, 998 ARRAYSIZE(EmptyComputerName))) 999 { 1000 wcscpy(EmptyComputerName, L"Setup cannot continue until you enter the name of your computer."); 1001 } 1002 MessageBoxW(hwndDlg, EmptyComputerName, Title, MB_ICONERROR | MB_OK); 1003 SetFocus(GetDlgItem(hwndDlg, IDC_COMPUTERNAME)); 1004 SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1); 1005 return TRUE; 1006 } 1007 1008 /* No need to check computer name for invalid characters, 1009 * SetComputerName() will do it for us */ 1010 1011 if (!WriteComputerSettings(ComputerName, hwndDlg)) 1012 { 1013 SetFocus(GetDlgItem(hwndDlg, IDC_COMPUTERNAME)); 1014 SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1); 1015 return TRUE; 1016 } 1017 1018 #ifdef PASSWORDS_MANDATORY 1019 /* Check if admin passwords have been entered */ 1020 if ((GetDlgItemText(hwndDlg, IDC_ADMINPASSWORD1, Password1, 128) == 0) || 1021 (GetDlgItemText(hwndDlg, IDC_ADMINPASSWORD2, Password2, 128) == 0)) 1022 { 1023 if (0 == LoadStringW(hDllInstance, IDS_WZD_PASSWORDEMPTY, EmptyPassword, 1024 ARRAYSIZE(EmptyPassword))) 1025 { 1026 wcscpy(EmptyPassword, L"You must enter a password !"); 1027 } 1028 MessageBoxW(hwndDlg, EmptyPassword, Title, MB_ICONERROR | MB_OK); 1029 SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1); 1030 return TRUE; 1031 } 1032 #else 1033 GetDlgItemTextW(hwndDlg, IDC_ADMINPASSWORD1, Password1, 128); 1034 GetDlgItemTextW(hwndDlg, IDC_ADMINPASSWORD2, Password2, 128); 1035 #endif 1036 /* Check if passwords match */ 1037 if (wcscmp(Password1, Password2)) 1038 { 1039 if (0 == LoadStringW(hDllInstance, IDS_WZD_PASSWORDMATCH, NotMatchPassword, 1040 ARRAYSIZE(NotMatchPassword))) 1041 { 1042 wcscpy(NotMatchPassword, L"The passwords you entered do not match. Please enter the desired password again."); 1043 } 1044 MessageBoxW(hwndDlg, NotMatchPassword, Title, MB_ICONERROR | MB_OK); 1045 SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1); 1046 return TRUE; 1047 } 1048 1049 /* Check password for invalid characters */ 1050 Password = (PWCHAR)Password1; 1051 while (*Password) 1052 { 1053 if (!isprint(*Password)) 1054 { 1055 if (0 == LoadStringW(hDllInstance, IDS_WZD_PASSWORDCHAR, WrongPassword, 1056 ARRAYSIZE(WrongPassword))) 1057 { 1058 wcscpy(WrongPassword, L"The password you entered contains invalid characters. Please enter a cleaned password."); 1059 } 1060 MessageBoxW(hwndDlg, WrongPassword, Title, MB_ICONERROR | MB_OK); 1061 SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1); 1062 return TRUE; 1063 } 1064 Password++; 1065 } 1066 1067 /* Set admin password */ 1068 SetAdministratorPassword(Password1); 1069 break; 1070 1071 case PSN_WIZBACK: 1072 pSetupData->UnattendSetup = FALSE; 1073 break; 1074 1075 default: 1076 break; 1077 } 1078 } 1079 break; 1080 1081 default: 1082 break; 1083 } 1084 1085 return FALSE; 1086 } 1087 1088 1089 static VOID 1090 SetKeyboardLayoutName(HWND hwnd) 1091 { 1092 #if 0 1093 TCHAR szLayoutPath[256]; 1094 TCHAR szLocaleName[32]; 1095 DWORD dwLocaleSize; 1096 HKEY hKey; 1097 1098 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, 1099 _T("SYSTEM\\CurrentControlSet\\Control\\NLS\\Locale"), 1100 0, 1101 KEY_ALL_ACCESS, 1102 &hKey)) 1103 return; 1104 1105 dwValueSize = 16 * sizeof(TCHAR); 1106 if (RegQueryValueEx(hKey, 1107 NULL, 1108 NULL, 1109 NULL, 1110 szLocaleName, 1111 &dwLocaleSize)) 1112 { 1113 RegCloseKey(hKey); 1114 return; 1115 } 1116 1117 _tcscpy(szLayoutPath, 1118 _T("SYSTEM\\CurrentControlSet\\Control\\Keyboard Layouts\\")); 1119 _tcscat(szLayoutPath, 1120 szLocaleName); 1121 1122 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, 1123 szLayoutPath, 1124 0, 1125 KEY_ALL_ACCESS, 1126 &hKey)) 1127 return; 1128 1129 dwValueSize = 32 * sizeof(TCHAR); 1130 if (RegQueryValueEx(hKey, 1131 _T("Layout Text"), 1132 NULL, 1133 NULL, 1134 szLocaleName, 1135 &dwLocaleSize)) 1136 { 1137 RegCloseKey(hKey); 1138 return; 1139 } 1140 1141 RegCloseKey(hKey); 1142 #endif 1143 } 1144 1145 1146 static BOOL 1147 RunControlPanelApplet(HWND hwnd, PCWSTR pwszCPLParameters) 1148 { 1149 MSG msg; 1150 STARTUPINFOW StartupInfo; 1151 PROCESS_INFORMATION ProcessInformation; 1152 WCHAR CmdLine[MAX_PATH] = L"rundll32.exe shell32.dll,Control_RunDLL "; 1153 1154 if (!pwszCPLParameters) 1155 { 1156 MessageBoxW(hwnd, L"Error: Failed to launch the Control Panel Applet.", NULL, MB_ICONERROR); 1157 return FALSE; 1158 } 1159 1160 ZeroMemory(&StartupInfo, sizeof(StartupInfo)); 1161 StartupInfo.cb = sizeof(StartupInfo); 1162 ZeroMemory(&ProcessInformation, sizeof(ProcessInformation)); 1163 1164 ASSERT(_countof(CmdLine) > wcslen(CmdLine) + wcslen(pwszCPLParameters)); 1165 wcscat(CmdLine, pwszCPLParameters); 1166 1167 if (!CreateProcessW(NULL, 1168 CmdLine, 1169 NULL, 1170 NULL, 1171 FALSE, 1172 0, 1173 NULL, 1174 NULL, 1175 &StartupInfo, 1176 &ProcessInformation)) 1177 { 1178 MessageBoxW(hwnd, L"Error: Failed to launch the Control Panel Applet.", NULL, MB_ICONERROR); 1179 return FALSE; 1180 } 1181 1182 while ((MsgWaitForMultipleObjects(1, &ProcessInformation.hProcess, FALSE, INFINITE, QS_ALLINPUT|QS_ALLPOSTMESSAGE )) != WAIT_OBJECT_0) 1183 { 1184 while (PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE)) 1185 { 1186 TranslateMessage(&msg); 1187 DispatchMessageW(&msg); 1188 } 1189 } 1190 CloseHandle(ProcessInformation.hThread); 1191 CloseHandle(ProcessInformation.hProcess); 1192 return TRUE; 1193 } 1194 1195 static VOID 1196 WriteUserLocale(VOID) 1197 { 1198 HKEY hKey; 1199 LCID lcid; 1200 WCHAR Locale[12]; 1201 1202 lcid = GetSystemDefaultLCID(); 1203 1204 if (GetLocaleInfoW(MAKELCID(lcid, SORT_DEFAULT), LOCALE_ILANGUAGE, Locale, ARRAYSIZE(Locale)) != 0) 1205 { 1206 if (RegCreateKeyExW(HKEY_CURRENT_USER, L"Control Panel\\International", 1207 0, NULL, REG_OPTION_NON_VOLATILE, 1208 KEY_WRITE, NULL, &hKey, NULL) == ERROR_SUCCESS) 1209 { 1210 RegSetValueExW(hKey, L"Locale", 0, REG_SZ, (LPBYTE)Locale, (wcslen(Locale) + 1) * sizeof(WCHAR)); 1211 RegCloseKey(hKey); 1212 } 1213 } 1214 } 1215 1216 static INT_PTR CALLBACK 1217 LocalePageDlgProc(HWND hwndDlg, 1218 UINT uMsg, 1219 WPARAM wParam, 1220 LPARAM lParam) 1221 { 1222 PSETUPDATA SetupData; 1223 1224 /* Retrieve pointer to the global setup data */ 1225 SetupData = (PSETUPDATA)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); 1226 1227 switch (uMsg) 1228 { 1229 case WM_INITDIALOG: 1230 { 1231 /* Save pointer to the global setup data */ 1232 SetupData = (PSETUPDATA)((LPPROPSHEETPAGE)lParam)->lParam; 1233 SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (DWORD_PTR)SetupData); 1234 WriteUserLocale(); 1235 1236 SetKeyboardLayoutName(GetDlgItem(hwndDlg, IDC_LAYOUTTEXT)); 1237 } 1238 break; 1239 1240 case WM_COMMAND: 1241 if (HIWORD(wParam) == BN_CLICKED) 1242 { 1243 switch (LOWORD(wParam)) 1244 { 1245 case IDC_CUSTOMLOCALE: 1246 RunControlPanelApplet(hwndDlg, L"intl.cpl,,5"); 1247 /* FIXME: Update input locale name */ 1248 break; 1249 1250 case IDC_CUSTOMLAYOUT: 1251 RunControlPanelApplet(hwndDlg, L"input.dll,@1"); 1252 break; 1253 } 1254 } 1255 break; 1256 1257 case WM_NOTIFY: 1258 { 1259 LPNMHDR lpnm = (LPNMHDR)lParam; 1260 1261 switch (lpnm->code) 1262 { 1263 case PSN_SETACTIVE: 1264 /* Enable the Back and Next buttons */ 1265 PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK | PSWIZB_NEXT); 1266 if (SetupData->UnattendSetup) 1267 { 1268 // if (!*SetupData->SourcePath) 1269 { 1270 RunControlPanelApplet(hwndDlg, L"intl.cpl,,/f:\"$winnt$.inf\""); // Should be in System32 1271 } 1272 1273 SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_OWNERPAGE); 1274 return TRUE; 1275 } 1276 break; 1277 1278 case PSN_WIZNEXT: 1279 break; 1280 1281 case PSN_WIZBACK: 1282 SetupData->UnattendSetup = FALSE; 1283 break; 1284 1285 default: 1286 break; 1287 } 1288 } 1289 break; 1290 1291 default: 1292 break; 1293 } 1294 1295 return FALSE; 1296 } 1297 1298 1299 static PTIMEZONE_ENTRY 1300 GetLargerTimeZoneEntry(PSETUPDATA SetupData, DWORD Index) 1301 { 1302 PTIMEZONE_ENTRY Entry; 1303 1304 Entry = SetupData->TimeZoneListHead; 1305 while (Entry != NULL) 1306 { 1307 if (Entry->Index >= Index) 1308 return Entry; 1309 1310 Entry = Entry->Next; 1311 } 1312 1313 return NULL; 1314 } 1315 1316 static LONG 1317 RetrieveTimeZone( 1318 IN HKEY hZoneKey, 1319 IN PVOID Context) 1320 { 1321 LONG lError; 1322 PSETUPDATA SetupData = (PSETUPDATA)Context; 1323 PTIMEZONE_ENTRY Entry; 1324 PTIMEZONE_ENTRY Current; 1325 ULONG DescriptionSize; 1326 ULONG StandardNameSize; 1327 ULONG DaylightNameSize; 1328 1329 Entry = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(TIMEZONE_ENTRY)); 1330 if (Entry == NULL) 1331 { 1332 return ERROR_NOT_ENOUGH_MEMORY; 1333 } 1334 1335 DescriptionSize = sizeof(Entry->Description); 1336 StandardNameSize = sizeof(Entry->StandardName); 1337 DaylightNameSize = sizeof(Entry->DaylightName); 1338 1339 lError = QueryTimeZoneData(hZoneKey, 1340 &Entry->Index, 1341 &Entry->TimezoneInfo, 1342 Entry->Description, 1343 &DescriptionSize, 1344 Entry->StandardName, 1345 &StandardNameSize, 1346 Entry->DaylightName, 1347 &DaylightNameSize); 1348 if (lError != ERROR_SUCCESS) 1349 { 1350 HeapFree(GetProcessHeap(), 0, Entry); 1351 return lError; 1352 } 1353 1354 if (SetupData->TimeZoneListHead == NULL && 1355 SetupData->TimeZoneListTail == NULL) 1356 { 1357 Entry->Prev = NULL; 1358 Entry->Next = NULL; 1359 SetupData->TimeZoneListHead = Entry; 1360 SetupData->TimeZoneListTail = Entry; 1361 } 1362 else 1363 { 1364 Current = GetLargerTimeZoneEntry(SetupData, Entry->Index); 1365 if (Current != NULL) 1366 { 1367 if (Current == SetupData->TimeZoneListHead) 1368 { 1369 /* Prepend to head */ 1370 Entry->Prev = NULL; 1371 Entry->Next = SetupData->TimeZoneListHead; 1372 SetupData->TimeZoneListHead->Prev = Entry; 1373 SetupData->TimeZoneListHead = Entry; 1374 } 1375 else 1376 { 1377 /* Insert before current */ 1378 Entry->Prev = Current->Prev; 1379 Entry->Next = Current; 1380 Current->Prev->Next = Entry; 1381 Current->Prev = Entry; 1382 } 1383 } 1384 else 1385 { 1386 /* Append to tail */ 1387 Entry->Prev = SetupData->TimeZoneListTail; 1388 Entry->Next = NULL; 1389 SetupData->TimeZoneListTail->Next = Entry; 1390 SetupData->TimeZoneListTail = Entry; 1391 } 1392 } 1393 1394 return ERROR_SUCCESS; 1395 } 1396 1397 static VOID 1398 CreateTimeZoneList(PSETUPDATA SetupData) 1399 { 1400 EnumerateTimeZoneList(RetrieveTimeZone, SetupData); 1401 } 1402 1403 static VOID 1404 DestroyTimeZoneList(PSETUPDATA SetupData) 1405 { 1406 PTIMEZONE_ENTRY Entry; 1407 1408 while (SetupData->TimeZoneListHead != NULL) 1409 { 1410 Entry = SetupData->TimeZoneListHead; 1411 1412 SetupData->TimeZoneListHead = Entry->Next; 1413 if (SetupData->TimeZoneListHead != NULL) 1414 { 1415 SetupData->TimeZoneListHead->Prev = NULL; 1416 } 1417 1418 HeapFree(GetProcessHeap(), 0, Entry); 1419 } 1420 1421 SetupData->TimeZoneListTail = NULL; 1422 } 1423 1424 1425 static VOID 1426 ShowTimeZoneList(HWND hwnd, PSETUPDATA SetupData, DWORD dwEntryIndex) 1427 { 1428 PTIMEZONE_ENTRY Entry; 1429 DWORD dwIndex = 0; 1430 DWORD dwCount; 1431 1432 GetTimeZoneListIndex(&dwEntryIndex); 1433 1434 Entry = SetupData->TimeZoneListHead; 1435 while (Entry != NULL) 1436 { 1437 dwCount = SendMessage(hwnd, 1438 CB_ADDSTRING, 1439 0, 1440 (LPARAM)Entry->Description); 1441 1442 if (dwEntryIndex != 0 && dwEntryIndex == Entry->Index) 1443 dwIndex = dwCount; 1444 1445 Entry = Entry->Next; 1446 } 1447 1448 SendMessage(hwnd, 1449 CB_SETCURSEL, 1450 (WPARAM)dwIndex, 1451 0); 1452 } 1453 1454 1455 static VOID 1456 SetLocalTimeZone(HWND hwnd, PSETUPDATA SetupData) 1457 { 1458 TIME_ZONE_INFORMATION TimeZoneInformation; 1459 PTIMEZONE_ENTRY Entry; 1460 DWORD dwIndex; 1461 DWORD i; 1462 1463 dwIndex = SendMessage(hwnd, 1464 CB_GETCURSEL, 1465 0, 1466 0); 1467 1468 i = 0; 1469 Entry = SetupData->TimeZoneListHead; 1470 while (i < dwIndex) 1471 { 1472 if (Entry == NULL) 1473 return; 1474 1475 i++; 1476 Entry = Entry->Next; 1477 } 1478 1479 wcscpy(TimeZoneInformation.StandardName, 1480 Entry->StandardName); 1481 wcscpy(TimeZoneInformation.DaylightName, 1482 Entry->DaylightName); 1483 1484 TimeZoneInformation.Bias = Entry->TimezoneInfo.Bias; 1485 TimeZoneInformation.StandardBias = Entry->TimezoneInfo.StandardBias; 1486 TimeZoneInformation.DaylightBias = Entry->TimezoneInfo.DaylightBias; 1487 1488 memcpy(&TimeZoneInformation.StandardDate, 1489 &Entry->TimezoneInfo.StandardDate, 1490 sizeof(SYSTEMTIME)); 1491 memcpy(&TimeZoneInformation.DaylightDate, 1492 &Entry->TimezoneInfo.DaylightDate, 1493 sizeof(SYSTEMTIME)); 1494 1495 /* Set time zone information */ 1496 SetTimeZoneInformation(&TimeZoneInformation); 1497 } 1498 1499 1500 static BOOL 1501 GetLocalSystemTime(HWND hwnd, PSETUPDATA SetupData) 1502 { 1503 SYSTEMTIME Date; 1504 SYSTEMTIME Time; 1505 1506 if (DateTime_GetSystemtime(GetDlgItem(hwnd, IDC_DATEPICKER), &Date) != GDT_VALID) 1507 { 1508 return FALSE; 1509 } 1510 1511 if (DateTime_GetSystemtime(GetDlgItem(hwnd, IDC_TIMEPICKER), &Time) != GDT_VALID) 1512 { 1513 return FALSE; 1514 } 1515 1516 SetupData->SystemTime.wYear = Date.wYear; 1517 SetupData->SystemTime.wMonth = Date.wMonth; 1518 SetupData->SystemTime.wDayOfWeek = Date.wDayOfWeek; 1519 SetupData->SystemTime.wDay = Date.wDay; 1520 SetupData->SystemTime.wHour = Time.wHour; 1521 SetupData->SystemTime.wMinute = Time.wMinute; 1522 SetupData->SystemTime.wSecond = Time.wSecond; 1523 SetupData->SystemTime.wMilliseconds = Time.wMilliseconds; 1524 1525 return TRUE; 1526 } 1527 1528 1529 static BOOL 1530 SetSystemLocalTime(HWND hwnd, PSETUPDATA SetupData) 1531 { 1532 BOOL Ret = FALSE; 1533 1534 /* 1535 * Call SetLocalTime twice to ensure correct results 1536 */ 1537 Ret = SetLocalTime(&SetupData->SystemTime) && 1538 SetLocalTime(&SetupData->SystemTime); 1539 1540 return Ret; 1541 } 1542 1543 1544 static VOID 1545 UpdateLocalSystemTime(HWND hwnd) 1546 { 1547 SYSTEMTIME LocalTime; 1548 1549 GetLocalTime(&LocalTime); 1550 DateTime_SetSystemtime(GetDlgItem(hwnd, IDC_DATEPICKER), GDT_VALID, &LocalTime); 1551 DateTime_SetSystemtime(GetDlgItem(hwnd, IDC_TIMEPICKER), GDT_VALID, &LocalTime); 1552 } 1553 1554 1555 static BOOL 1556 WriteDateTimeSettings(HWND hwndDlg, PSETUPDATA SetupData) 1557 { 1558 WCHAR Title[64]; 1559 WCHAR ErrorLocalTime[256]; 1560 1561 GetLocalSystemTime(hwndDlg, SetupData); 1562 SetLocalTimeZone(GetDlgItem(hwndDlg, IDC_TIMEZONELIST), 1563 SetupData); 1564 1565 SetAutoDaylight(SendDlgItemMessage(hwndDlg, IDC_AUTODAYLIGHT, 1566 BM_GETCHECK, 0, 0) != BST_UNCHECKED); 1567 if (!SetSystemLocalTime(hwndDlg, SetupData)) 1568 { 1569 if (0 == LoadStringW(hDllInstance, IDS_REACTOS_SETUP, Title, ARRAYSIZE(Title))) 1570 { 1571 wcscpy(Title, L"ReactOS Setup"); 1572 } 1573 if (0 == LoadStringW(hDllInstance, IDS_WZD_LOCALTIME, ErrorLocalTime, 1574 ARRAYSIZE(ErrorLocalTime))) 1575 { 1576 wcscpy(ErrorLocalTime, L"Setup was unable to set the local time."); 1577 } 1578 MessageBoxW(hwndDlg, ErrorLocalTime, Title, MB_ICONWARNING | MB_OK); 1579 return FALSE; 1580 } 1581 1582 return TRUE; 1583 } 1584 1585 1586 static INT_PTR CALLBACK 1587 DateTimePageDlgProc(HWND hwndDlg, 1588 UINT uMsg, 1589 WPARAM wParam, 1590 LPARAM lParam) 1591 { 1592 PSETUPDATA SetupData; 1593 1594 /* Retrieve pointer to the global setup data */ 1595 SetupData = (PSETUPDATA)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); 1596 1597 switch (uMsg) 1598 { 1599 case WM_INITDIALOG: 1600 { 1601 /* Save pointer to the global setup data */ 1602 SetupData = (PSETUPDATA)((LPPROPSHEETPAGE)lParam)->lParam; 1603 SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (DWORD_PTR)SetupData); 1604 1605 CreateTimeZoneList(SetupData); 1606 1607 if (SetupData->UnattendSetup) 1608 { 1609 ShowTimeZoneList(GetDlgItem(hwndDlg, IDC_TIMEZONELIST), 1610 SetupData, SetupData->TimeZoneIndex); 1611 1612 if (!SetupData->DisableAutoDaylightTimeSet) 1613 { 1614 SendDlgItemMessage(hwndDlg, IDC_AUTODAYLIGHT, BM_SETCHECK, (WPARAM)BST_CHECKED, 0); 1615 } 1616 } 1617 else 1618 { 1619 ShowTimeZoneList(GetDlgItem(hwndDlg, IDC_TIMEZONELIST), 1620 SetupData, -1); 1621 1622 SendDlgItemMessage(hwndDlg, IDC_AUTODAYLIGHT, BM_SETCHECK, (WPARAM)BST_CHECKED, 0); 1623 } 1624 break; 1625 } 1626 1627 case WM_TIMER: 1628 UpdateLocalSystemTime(hwndDlg); 1629 break; 1630 1631 case WM_NOTIFY: 1632 switch (((LPNMHDR)lParam)->code) 1633 { 1634 case PSN_SETACTIVE: 1635 /* Enable the Back and Next buttons */ 1636 PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK | PSWIZB_NEXT); 1637 if (SetupData->UnattendSetup && WriteDateTimeSettings(hwndDlg, SetupData)) 1638 { 1639 SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, SetupData->uFirstNetworkWizardPage); 1640 return TRUE; 1641 } 1642 SetTimer(hwndDlg, 1, 1000, NULL); 1643 break; 1644 1645 case PSN_KILLACTIVE: 1646 case DTN_DATETIMECHANGE: 1647 KillTimer(hwndDlg, 1); 1648 break; 1649 1650 case PSN_WIZNEXT: 1651 WriteDateTimeSettings(hwndDlg, SetupData); 1652 break; 1653 1654 case PSN_WIZBACK: 1655 SetupData->UnattendSetup = FALSE; 1656 break; 1657 1658 default: 1659 break; 1660 } 1661 break; 1662 1663 case WM_DESTROY: 1664 DestroyTimeZoneList(SetupData); 1665 break; 1666 1667 default: 1668 break; 1669 } 1670 1671 return FALSE; 1672 } 1673 1674 static struct ThemeInfo 1675 { 1676 LPCWSTR PreviewBitmap; 1677 UINT DisplayName; 1678 LPCWSTR ThemeFile; 1679 1680 } Themes[] = { 1681 { MAKEINTRESOURCE(IDB_CLASSIC), IDS_CLASSIC, NULL }, 1682 { MAKEINTRESOURCE(IDB_LAUTUS), IDS_LAUTUS, L"themes\\lautus\\lautus.msstyles" }, 1683 { MAKEINTRESOURCE(IDB_LUNAR), IDS_LUNAR, L"themes\\lunar\\lunar.msstyles" }, 1684 { MAKEINTRESOURCE(IDB_MIZU), IDS_MIZU, L"themes\\mizu\\mizu.msstyles"}, 1685 }; 1686 1687 static INT_PTR CALLBACK 1688 ThemePageDlgProc(HWND hwndDlg, 1689 UINT uMsg, 1690 WPARAM wParam, 1691 LPARAM lParam) 1692 { 1693 PSETUPDATA SetupData; 1694 LPNMLISTVIEW pnmv; 1695 1696 /* Retrieve pointer to the global setup data */ 1697 SetupData = (PSETUPDATA)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); 1698 1699 switch (uMsg) 1700 { 1701 case WM_INITDIALOG: 1702 { 1703 HWND hListView; 1704 HIMAGELIST himl; 1705 DWORD n; 1706 LVITEM lvi = {0}; 1707 1708 /* Save pointer to the global setup data */ 1709 SetupData = (PSETUPDATA)((LPPROPSHEETPAGE)lParam)->lParam; 1710 SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (DWORD_PTR)SetupData); 1711 1712 hListView = GetDlgItem(hwndDlg, IDC_THEMEPICKER); 1713 1714 /* Common */ 1715 himl = ImageList_Create(180, 163, ILC_COLOR32 | ILC_MASK, ARRAYSIZE(Themes), 1); 1716 lvi.mask = LVIF_TEXT | LVIF_IMAGE |LVIF_STATE; 1717 1718 for (n = 0; n < ARRAYSIZE(Themes); ++n) 1719 { 1720 WCHAR DisplayName[100] = {0}; 1721 /* Load the bitmap */ 1722 HANDLE image = LoadImageW(hDllInstance, Themes[n].PreviewBitmap, IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION); 1723 ImageList_AddMasked(himl, image, RGB(255,0,255)); 1724 1725 /* Load the string */ 1726 LoadStringW(hDllInstance, Themes[n].DisplayName, DisplayName, ARRAYSIZE(DisplayName)); 1727 DisplayName[ARRAYSIZE(DisplayName)-1] = UNICODE_NULL; 1728 1729 /* Add the listview item */ 1730 lvi.iItem = n; 1731 lvi.iImage = n; 1732 lvi.pszText = DisplayName; 1733 ListView_InsertItem(hListView, &lvi); 1734 } 1735 1736 /* Register the imagelist */ 1737 ListView_SetImageList(hListView, himl, LVSIL_NORMAL); 1738 /* Transparant background */ 1739 ListView_SetBkColor(hListView, CLR_NONE); 1740 ListView_SetTextBkColor(hListView, CLR_NONE); 1741 /* Reduce the size between the items */ 1742 ListView_SetIconSpacing(hListView, 190, 173); 1743 break; 1744 } 1745 case WM_NOTIFY: 1746 switch (((LPNMHDR)lParam)->code) 1747 { 1748 //case LVN_ITEMCHANGING: 1749 case LVN_ITEMCHANGED: 1750 pnmv = (LPNMLISTVIEW)lParam; 1751 if ((pnmv->uChanged & LVIF_STATE) && (pnmv->uNewState & LVIS_SELECTED)) 1752 { 1753 int iTheme = pnmv->iItem; 1754 DPRINT1("Selected theme: %u\n", Themes[iTheme].DisplayName); 1755 1756 if (Themes[iTheme].ThemeFile) 1757 { 1758 WCHAR wszParams[1024]; 1759 WCHAR wszTheme[MAX_PATH]; 1760 WCHAR* format = L"desk.cpl desk,@Appearance /Action:ActivateMSTheme /file:\"%s\""; 1761 1762 SHGetFolderPathAndSubDirW(0, CSIDL_RESOURCES, NULL, SHGFP_TYPE_DEFAULT, Themes[iTheme].ThemeFile, wszTheme); 1763 swprintf(wszParams, format, wszTheme); 1764 RunControlPanelApplet(hwndDlg, wszParams); 1765 } 1766 else 1767 { 1768 RunControlPanelApplet(hwndDlg, L"desk.cpl desk,@Appearance /Action:ActivateMSTheme"); 1769 } 1770 } 1771 break; 1772 case PSN_SETACTIVE: 1773 /* Enable the Back and Next buttons */ 1774 PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK | PSWIZB_NEXT); 1775 if (SetupData->UnattendSetup) 1776 { 1777 SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, SetupData->uFirstNetworkWizardPage); 1778 return TRUE; 1779 } 1780 break; 1781 1782 case PSN_WIZNEXT: 1783 break; 1784 1785 case PSN_WIZBACK: 1786 SetupData->UnattendSetup = FALSE; 1787 break; 1788 1789 default: 1790 break; 1791 } 1792 break; 1793 1794 default: 1795 break; 1796 } 1797 1798 return FALSE; 1799 } 1800 1801 static UINT CALLBACK 1802 RegistrationNotificationProc(PVOID Context, 1803 UINT Notification, 1804 UINT_PTR Param1, 1805 UINT_PTR Param2) 1806 { 1807 PREGISTRATIONDATA RegistrationData; 1808 REGISTRATIONNOTIFY RegistrationNotify; 1809 PSP_REGISTER_CONTROL_STATUSW StatusInfo; 1810 UINT MessageID; 1811 WCHAR ErrorMessage[128]; 1812 1813 RegistrationData = (PREGISTRATIONDATA) Context; 1814 1815 if (SPFILENOTIFY_STARTREGISTRATION == Notification || 1816 SPFILENOTIFY_ENDREGISTRATION == Notification) 1817 { 1818 StatusInfo = (PSP_REGISTER_CONTROL_STATUSW) Param1; 1819 RegistrationNotify.CurrentItem = wcsrchr(StatusInfo->FileName, L'\\'); 1820 if (NULL == RegistrationNotify.CurrentItem) 1821 { 1822 RegistrationNotify.CurrentItem = StatusInfo->FileName; 1823 } 1824 else 1825 { 1826 RegistrationNotify.CurrentItem++; 1827 } 1828 1829 if (SPFILENOTIFY_STARTREGISTRATION == Notification) 1830 { 1831 DPRINT("Received SPFILENOTIFY_STARTREGISTRATION notification for %S\n", 1832 StatusInfo->FileName); 1833 RegistrationNotify.ErrorMessage = NULL; 1834 RegistrationNotify.Progress = RegistrationData->Registered; 1835 } 1836 else 1837 { 1838 DPRINT("Received SPFILENOTIFY_ENDREGISTRATION notification for %S\n", 1839 StatusInfo->FileName); 1840 DPRINT("Win32Error %u FailureCode %u\n", StatusInfo->Win32Error, 1841 StatusInfo->FailureCode); 1842 if (SPREG_SUCCESS != StatusInfo->FailureCode) 1843 { 1844 switch(StatusInfo->FailureCode) 1845 { 1846 case SPREG_LOADLIBRARY: 1847 MessageID = IDS_LOADLIBRARY_FAILED; 1848 break; 1849 case SPREG_GETPROCADDR: 1850 MessageID = IDS_GETPROCADDR_FAILED; 1851 break; 1852 case SPREG_REGSVR: 1853 MessageID = IDS_REGSVR_FAILED; 1854 break; 1855 case SPREG_DLLINSTALL: 1856 MessageID = IDS_DLLINSTALL_FAILED; 1857 break; 1858 case SPREG_TIMEOUT: 1859 MessageID = IDS_TIMEOUT; 1860 break; 1861 default: 1862 MessageID = IDS_REASON_UNKNOWN; 1863 break; 1864 } 1865 if (0 == LoadStringW(hDllInstance, MessageID, 1866 ErrorMessage, 1867 ARRAYSIZE(ErrorMessage))) 1868 { 1869 ErrorMessage[0] = L'\0'; 1870 } 1871 if (SPREG_TIMEOUT != StatusInfo->FailureCode) 1872 { 1873 FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM, NULL, 1874 StatusInfo->Win32Error, 0, 1875 ErrorMessage + wcslen(ErrorMessage), 1876 ARRAYSIZE(ErrorMessage) - wcslen(ErrorMessage), 1877 NULL); 1878 } 1879 RegistrationNotify.ErrorMessage = ErrorMessage; 1880 } 1881 else 1882 { 1883 RegistrationNotify.ErrorMessage = NULL; 1884 } 1885 if (RegistrationData->Registered < RegistrationData->DllCount) 1886 { 1887 RegistrationData->Registered++; 1888 } 1889 } 1890 1891 RegistrationNotify.Progress = RegistrationData->Registered; 1892 RegistrationNotify.ActivityID = IDS_REGISTERING_COMPONENTS; 1893 SendMessage(RegistrationData->hwndDlg, PM_REGISTRATION_NOTIFY, 1894 0, (LPARAM) &RegistrationNotify); 1895 1896 return FILEOP_DOIT; 1897 } 1898 else 1899 { 1900 DPRINT1("Received unexpected notification %u\n", Notification); 1901 return SetupDefaultQueueCallback(RegistrationData->DefaultContext, 1902 Notification, Param1, Param2); 1903 } 1904 } 1905 1906 1907 static DWORD CALLBACK 1908 RegistrationProc(LPVOID Parameter) 1909 { 1910 PREGISTRATIONDATA RegistrationData; 1911 REGISTRATIONNOTIFY RegistrationNotify; 1912 DWORD LastError = NO_ERROR; 1913 WCHAR UnknownError[84]; 1914 1915 RegistrationData = (PREGISTRATIONDATA) Parameter; 1916 RegistrationData->Registered = 0; 1917 RegistrationData->DefaultContext = SetupInitDefaultQueueCallback(RegistrationData->hwndDlg); 1918 1919 _SEH2_TRY 1920 { 1921 if (!SetupInstallFromInfSectionW(GetParent(RegistrationData->hwndDlg), 1922 hSysSetupInf, 1923 L"RegistrationPhase2", 1924 SPINST_REGISTRY | 1925 SPINST_REGISTERCALLBACKAWARE | 1926 SPINST_REGSVR, 1927 0, 1928 NULL, 1929 0, 1930 RegistrationNotificationProc, 1931 RegistrationData, 1932 NULL, 1933 NULL)) 1934 { 1935 LastError = GetLastError(); 1936 } 1937 } 1938 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 1939 { 1940 DPRINT("Catching exception\n"); 1941 LastError = RtlNtStatusToDosError(_SEH2_GetExceptionCode()); 1942 } 1943 _SEH2_END; 1944 1945 if (NO_ERROR == LastError) 1946 { 1947 RegistrationNotify.ErrorMessage = NULL; 1948 } 1949 else 1950 { 1951 DPRINT1("SetupInstallFromInfSection failed with error %u\n", 1952 LastError); 1953 if (0 == FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | 1954 FORMAT_MESSAGE_FROM_SYSTEM, NULL, LastError, 0, 1955 (LPWSTR) &RegistrationNotify.ErrorMessage, 0, 1956 NULL)) 1957 { 1958 if (0 == LoadStringW(hDllInstance, IDS_UNKNOWN_ERROR, 1959 UnknownError, 1960 ARRAYSIZE(UnknownError) - 20)) 1961 { 1962 wcscpy(UnknownError, L"Unknown error"); 1963 } 1964 wcscat(UnknownError, L" "); 1965 _ultow(LastError, UnknownError + wcslen(UnknownError), 10); 1966 RegistrationNotify.ErrorMessage = UnknownError; 1967 } 1968 } 1969 1970 RegistrationNotify.Progress = RegistrationData->DllCount; 1971 RegistrationNotify.ActivityID = IDS_REGISTERING_COMPONENTS; 1972 RegistrationNotify.CurrentItem = NULL; 1973 SendMessage(RegistrationData->hwndDlg, PM_REGISTRATION_NOTIFY, 1974 1, (LPARAM) &RegistrationNotify); 1975 if (NULL != RegistrationNotify.ErrorMessage && 1976 UnknownError != RegistrationNotify.ErrorMessage) 1977 { 1978 LocalFree((PVOID) RegistrationNotify.ErrorMessage); 1979 } 1980 1981 SetupTermDefaultQueueCallback(RegistrationData->DefaultContext); 1982 HeapFree(GetProcessHeap(), 0, RegistrationData); 1983 1984 RegisterTypeLibraries(hSysSetupInf, L"TypeLibraries"); 1985 1986 // FIXME: Move this call to a separate cleanup page! 1987 RtlCreateBootStatusDataFile(); 1988 1989 return 0; 1990 } 1991 1992 1993 static BOOL 1994 StartComponentRegistration(HWND hwndDlg, PULONG MaxProgress) 1995 { 1996 HANDLE RegistrationThread; 1997 LONG DllCount; 1998 INFCONTEXT Context; 1999 WCHAR SectionName[512]; 2000 PREGISTRATIONDATA RegistrationData; 2001 2002 DllCount = -1; 2003 if (!SetupFindFirstLineW(hSysSetupInf, L"RegistrationPhase2", 2004 L"RegisterDlls", &Context)) 2005 { 2006 DPRINT1("No RegistrationPhase2 section found\n"); 2007 return FALSE; 2008 } 2009 if (!SetupGetStringFieldW(&Context, 1, SectionName, 2010 ARRAYSIZE(SectionName), 2011 NULL)) 2012 { 2013 DPRINT1("Unable to retrieve section name\n"); 2014 return FALSE; 2015 } 2016 DllCount = SetupGetLineCountW(hSysSetupInf, SectionName); 2017 DPRINT("SectionName %S DllCount %ld\n", SectionName, DllCount); 2018 if (DllCount < 0) 2019 { 2020 SetLastError(STATUS_NOT_FOUND); 2021 return FALSE; 2022 } 2023 2024 *MaxProgress = (ULONG) DllCount; 2025 2026 /* 2027 * Create a background thread to do the actual registrations, so the 2028 * main thread can just run its message loop. 2029 */ 2030 RegistrationThread = NULL; 2031 RegistrationData = HeapAlloc(GetProcessHeap(), 0, 2032 sizeof(REGISTRATIONDATA)); 2033 if (RegistrationData != NULL) 2034 { 2035 RegistrationData->hwndDlg = hwndDlg; 2036 RegistrationData->DllCount = DllCount; 2037 RegistrationThread = CreateThread(NULL, 0, RegistrationProc, 2038 RegistrationData, 0, NULL); 2039 if (RegistrationThread != NULL) 2040 { 2041 CloseHandle(RegistrationThread); 2042 } 2043 else 2044 { 2045 DPRINT1("CreateThread failed, error %u\n", GetLastError()); 2046 HeapFree(GetProcessHeap(), 0, RegistrationData); 2047 return FALSE; 2048 } 2049 } 2050 else 2051 { 2052 DPRINT1("HeapAlloc() failed, error %u\n", GetLastError()); 2053 return FALSE; 2054 } 2055 2056 return TRUE; 2057 } 2058 2059 2060 static INT_PTR CALLBACK 2061 ProcessPageDlgProc(HWND hwndDlg, 2062 UINT uMsg, 2063 WPARAM wParam, 2064 LPARAM lParam) 2065 { 2066 PSETUPDATA SetupData; 2067 PREGISTRATIONNOTIFY RegistrationNotify; 2068 static UINT oldActivityID = -1; 2069 WCHAR Title[64]; 2070 2071 /* Retrieve pointer to the global setup data */ 2072 SetupData = (PSETUPDATA)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); 2073 2074 switch (uMsg) 2075 { 2076 case WM_INITDIALOG: 2077 { 2078 /* Save pointer to the global setup data */ 2079 SetupData = (PSETUPDATA)((LPPROPSHEETPAGE)lParam)->lParam; 2080 SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (DWORD_PTR)SetupData); 2081 } 2082 break; 2083 2084 case WM_NOTIFY: 2085 { 2086 LPNMHDR lpnm = (LPNMHDR)lParam; 2087 ULONG MaxProgress = 0; 2088 2089 switch (lpnm->code) 2090 { 2091 case PSN_SETACTIVE: 2092 /* Disable the Back and Next buttons */ 2093 PropSheet_SetWizButtons(GetParent(hwndDlg), 0); 2094 2095 StartComponentRegistration(hwndDlg, &MaxProgress); 2096 2097 SendDlgItemMessage(hwndDlg, IDC_PROCESSPROGRESS, PBM_SETRANGE, 2098 0, MAKELPARAM(0, MaxProgress)); 2099 SendDlgItemMessage(hwndDlg, IDC_PROCESSPROGRESS, PBM_SETPOS, 2100 0, 0); 2101 break; 2102 2103 case PSN_WIZNEXT: 2104 break; 2105 2106 case PSN_WIZBACK: 2107 SetupData->UnattendSetup = FALSE; 2108 break; 2109 2110 default: 2111 break; 2112 } 2113 } 2114 break; 2115 2116 case PM_REGISTRATION_NOTIFY: 2117 { 2118 WCHAR Activity[64]; 2119 RegistrationNotify = (PREGISTRATIONNOTIFY) lParam; 2120 // update if necessary only 2121 if (oldActivityID != RegistrationNotify->ActivityID) 2122 { 2123 if (0 != LoadStringW(hDllInstance, RegistrationNotify->ActivityID, 2124 Activity, 2125 ARRAYSIZE(Activity))) 2126 { 2127 SendDlgItemMessageW(hwndDlg, IDC_ACTIVITY, WM_SETTEXT, 2128 0, (LPARAM) Activity); 2129 } 2130 oldActivityID = RegistrationNotify->ActivityID; 2131 } 2132 SendDlgItemMessageW(hwndDlg, IDC_ITEM, WM_SETTEXT, 0, 2133 (LPARAM)(NULL == RegistrationNotify->CurrentItem ? 2134 L"" : RegistrationNotify->CurrentItem)); 2135 SendDlgItemMessage(hwndDlg, IDC_PROCESSPROGRESS, PBM_SETPOS, 2136 RegistrationNotify->Progress, 0); 2137 if (NULL != RegistrationNotify->ErrorMessage) 2138 { 2139 if (0 == LoadStringW(hDllInstance, IDS_REACTOS_SETUP, 2140 Title, ARRAYSIZE(Title))) 2141 { 2142 wcscpy(Title, L"ReactOS Setup"); 2143 } 2144 MessageBoxW(hwndDlg, RegistrationNotify->ErrorMessage, 2145 Title, MB_ICONERROR | MB_OK); 2146 2147 } 2148 2149 if (wParam) 2150 { 2151 /* Enable the Back and Next buttons */ 2152 PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT); 2153 PropSheet_PressButton(GetParent(hwndDlg), PSBTN_NEXT); 2154 } 2155 } 2156 return TRUE; 2157 2158 default: 2159 break; 2160 } 2161 2162 return FALSE; 2163 } 2164 2165 2166 static VOID 2167 SetInstallationCompleted(VOID) 2168 { 2169 HKEY hKey = 0; 2170 DWORD InProgress = 0; 2171 DWORD InstallDate; 2172 2173 if (RegOpenKeyExW( HKEY_LOCAL_MACHINE, 2174 L"SYSTEM\\Setup", 2175 0, 2176 KEY_WRITE, 2177 &hKey ) == ERROR_SUCCESS) 2178 { 2179 RegSetValueExW( hKey, L"SystemSetupInProgress", 0, REG_DWORD, (LPBYTE)&InProgress, sizeof(InProgress) ); 2180 RegCloseKey( hKey ); 2181 } 2182 2183 if (RegOpenKeyExW( HKEY_LOCAL_MACHINE, 2184 L"Software\\Microsoft\\Windows NT\\CurrentVersion", 2185 0, 2186 KEY_WRITE, 2187 &hKey ) == ERROR_SUCCESS) 2188 { 2189 InstallDate = (DWORD)time(NULL); 2190 RegSetValueExW( hKey, L"InstallDate", 0, REG_DWORD, (LPBYTE)&InstallDate, sizeof(InstallDate) ); 2191 RegCloseKey( hKey ); 2192 } 2193 } 2194 2195 static INT_PTR CALLBACK 2196 FinishDlgProc(HWND hwndDlg, 2197 UINT uMsg, 2198 WPARAM wParam, 2199 LPARAM lParam) 2200 { 2201 2202 switch (uMsg) 2203 { 2204 case WM_INITDIALOG: 2205 { 2206 /* Get pointer to the global setup data */ 2207 PSETUPDATA SetupData = (PSETUPDATA)((LPPROPSHEETPAGE)lParam)->lParam; 2208 2209 if (!SetupData->UnattendSetup || !SetupData->DisableGeckoInst) 2210 { 2211 /* Run the Wine Gecko prompt */ 2212 Control_RunDLLW(hwndDlg, 0, L"appwiz.cpl install_gecko", SW_SHOW); 2213 } 2214 2215 /* Set title font */ 2216 SendDlgItemMessage(hwndDlg, 2217 IDC_FINISHTITLE, 2218 WM_SETFONT, 2219 (WPARAM)SetupData->hTitleFont, 2220 (LPARAM)TRUE); 2221 if (SetupData->UnattendSetup) 2222 { 2223 KillTimer(hwndDlg, 1); 2224 SetInstallationCompleted(); 2225 PostQuitMessage(0); 2226 } 2227 } 2228 break; 2229 2230 case WM_DESTROY: 2231 { 2232 SetInstallationCompleted(); 2233 PostQuitMessage(0); 2234 return TRUE; 2235 } 2236 2237 case WM_TIMER: 2238 { 2239 INT Position; 2240 HWND hWndProgress; 2241 2242 hWndProgress = GetDlgItem(hwndDlg, IDC_RESTART_PROGRESS); 2243 Position = SendMessage(hWndProgress, PBM_GETPOS, 0, 0); 2244 if (Position == 300) 2245 { 2246 KillTimer(hwndDlg, 1); 2247 PropSheet_PressButton(GetParent(hwndDlg), PSBTN_FINISH); 2248 } 2249 else 2250 { 2251 SendMessage(hWndProgress, PBM_SETPOS, Position + 1, 0); 2252 } 2253 } 2254 return TRUE; 2255 2256 case WM_NOTIFY: 2257 { 2258 LPNMHDR lpnm = (LPNMHDR)lParam; 2259 2260 switch (lpnm->code) 2261 { 2262 case PSN_SETACTIVE: 2263 /* Enable the correct buttons on for the active page */ 2264 PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_FINISH); 2265 2266 SendDlgItemMessage(hwndDlg, IDC_RESTART_PROGRESS, PBM_SETRANGE, 0, 2267 MAKELPARAM(0, 300)); 2268 SendDlgItemMessage(hwndDlg, IDC_RESTART_PROGRESS, PBM_SETPOS, 0, 0); 2269 SetTimer(hwndDlg, 1, 50, NULL); 2270 break; 2271 2272 case PSN_WIZFINISH: 2273 DestroyWindow(GetParent(hwndDlg)); 2274 break; 2275 2276 default: 2277 break; 2278 } 2279 } 2280 break; 2281 2282 default: 2283 break; 2284 } 2285 2286 return FALSE; 2287 } 2288 2289 2290 /* 2291 * GetInstallSourceWin32 retrieves the path to the ReactOS installation medium 2292 * in Win32 format, for later use by syssetup and storage in the registry. 2293 */ 2294 static BOOL 2295 GetInstallSourceWin32( 2296 OUT PWSTR pwszPath, 2297 IN DWORD cchPathMax, 2298 IN PCWSTR pwszNTPath) 2299 { 2300 WCHAR wszDrives[512]; 2301 WCHAR wszNTPath[512]; // MAX_PATH ? 2302 DWORD cchDrives; 2303 PWCHAR pwszDrive; 2304 2305 *pwszPath = UNICODE_NULL; 2306 2307 cchDrives = GetLogicalDriveStringsW(_countof(wszDrives) - 1, wszDrives); 2308 if (cchDrives == 0 || cchDrives >= _countof(wszDrives)) 2309 { 2310 /* Buffer too small or failure */ 2311 LogItem(NULL, L"GetLogicalDriveStringsW failed"); 2312 return FALSE; 2313 } 2314 2315 for (pwszDrive = wszDrives; *pwszDrive; pwszDrive += wcslen(pwszDrive) + 1) 2316 { 2317 WCHAR wszBuf[MAX_PATH]; 2318 2319 /* Retrieve the NT path corresponding to the current Win32 DOS path */ 2320 pwszDrive[2] = UNICODE_NULL; // Temporarily remove the backslash 2321 QueryDosDeviceW(pwszDrive, wszNTPath, _countof(wszNTPath)); 2322 pwszDrive[2] = L'\\'; // Restore the backslash 2323 2324 wcscat(wszNTPath, L"\\"); // Concat a backslash 2325 2326 /* Logging */ 2327 wsprintf(wszBuf, L"Testing '%s' --> '%s' %s a CD", 2328 pwszDrive, wszNTPath, 2329 (GetDriveTypeW(pwszDrive) == DRIVE_CDROM) ? L"is" : L"is not"); 2330 LogItem(NULL, wszBuf); 2331 2332 /* Check whether the NT path corresponds to the NT installation source path */ 2333 if (!_wcsicmp(wszNTPath, pwszNTPath)) 2334 { 2335 /* Found it! */ 2336 wcscpy(pwszPath, pwszDrive); // cchPathMax 2337 2338 /* Logging */ 2339 wsprintf(wszBuf, L"GetInstallSourceWin32: %s", pwszPath); 2340 LogItem(NULL, wszBuf); 2341 wcscat(wszBuf, L"\n"); 2342 OutputDebugStringW(wszBuf); 2343 2344 return TRUE; 2345 } 2346 } 2347 2348 return FALSE; 2349 } 2350 2351 VOID 2352 ProcessUnattendSection( 2353 IN OUT PSETUPDATA pSetupData) 2354 { 2355 INFCONTEXT InfContext; 2356 WCHAR szName[256]; 2357 WCHAR szValue[MAX_PATH]; 2358 DWORD LineLength; 2359 HKEY hKey; 2360 2361 if (!SetupFindFirstLineW(pSetupData->hSetupInf, 2362 L"Unattend", 2363 L"UnattendSetupEnabled", 2364 &InfContext)) 2365 { 2366 DPRINT1("Error: Cannot find UnattendSetupEnabled Key! %d\n", GetLastError()); 2367 return; 2368 } 2369 2370 if (!SetupGetStringFieldW(&InfContext, 2371 1, 2372 szValue, 2373 ARRAYSIZE(szValue), 2374 &LineLength)) 2375 { 2376 DPRINT1("Error: SetupGetStringField failed with %d\n", GetLastError()); 2377 return; 2378 } 2379 2380 if (_wcsicmp(szValue, L"yes") != 0) 2381 { 2382 DPRINT("Unattend setup was disabled by UnattendSetupEnabled key.\n"); 2383 return; 2384 } 2385 2386 pSetupData->UnattendSetup = TRUE; 2387 2388 if (!SetupFindFirstLineW(pSetupData->hSetupInf, 2389 L"Unattend", 2390 NULL, 2391 &InfContext)) 2392 { 2393 DPRINT1("Error: SetupFindFirstLine failed %d\n", GetLastError()); 2394 return; 2395 } 2396 2397 do 2398 { 2399 if (!SetupGetStringFieldW(&InfContext, 2400 0, 2401 szName, 2402 ARRAYSIZE(szName), 2403 &LineLength)) 2404 { 2405 DPRINT1("Error: SetupGetStringField failed with %d\n", GetLastError()); 2406 return; 2407 } 2408 2409 if (!SetupGetStringFieldW(&InfContext, 2410 1, 2411 szValue, 2412 ARRAYSIZE(szValue), 2413 &LineLength)) 2414 { 2415 DPRINT1("Error: SetupGetStringField failed with %d\n", GetLastError()); 2416 return; 2417 } 2418 DPRINT1("Name %S Value %S\n", szName, szValue); 2419 if (!_wcsicmp(szName, L"FullName")) 2420 { 2421 if (ARRAYSIZE(pSetupData->OwnerName) > LineLength) 2422 { 2423 wcscpy(pSetupData->OwnerName, szValue); 2424 } 2425 } 2426 else if (!_wcsicmp(szName, L"OrgName")) 2427 { 2428 if (ARRAYSIZE(pSetupData->OwnerOrganization) > LineLength) 2429 { 2430 wcscpy(pSetupData->OwnerOrganization, szValue); 2431 } 2432 } 2433 else if (!_wcsicmp(szName, L"ComputerName")) 2434 { 2435 if (ARRAYSIZE(pSetupData->ComputerName) > LineLength) 2436 { 2437 wcscpy(pSetupData->ComputerName, szValue); 2438 } 2439 } 2440 else if (!_wcsicmp(szName, L"AdminPassword")) 2441 { 2442 if (ARRAYSIZE(pSetupData->AdminPassword) > LineLength) 2443 { 2444 wcscpy(pSetupData->AdminPassword, szValue); 2445 } 2446 } 2447 else if (!_wcsicmp(szName, L"TimeZoneIndex")) 2448 { 2449 pSetupData->TimeZoneIndex = _wtoi(szValue); 2450 } 2451 else if (!_wcsicmp(szName, L"DisableAutoDaylightTimeSet")) 2452 { 2453 pSetupData->DisableAutoDaylightTimeSet = _wtoi(szValue); 2454 } 2455 else if (!_wcsicmp(szName, L"DisableGeckoInst")) 2456 { 2457 if (!_wcsicmp(szValue, L"yes")) 2458 pSetupData->DisableGeckoInst = TRUE; 2459 else 2460 pSetupData->DisableGeckoInst = FALSE; 2461 } 2462 else if (!_wcsicmp(szName, L"ProductOption")) 2463 { 2464 pSetupData->ProductOption = (PRODUCT_OPTION)_wtoi(szValue); 2465 } 2466 } while (SetupFindNextLine(&InfContext, &InfContext)); 2467 2468 if (SetupFindFirstLineW(pSetupData->hSetupInf, 2469 L"Display", 2470 NULL, 2471 &InfContext)) 2472 { 2473 DEVMODEW dm = { { 0 } }; 2474 dm.dmSize = sizeof(dm); 2475 if (EnumDisplaySettingsW(NULL, ENUM_CURRENT_SETTINGS, &dm)) 2476 { 2477 do 2478 { 2479 int iValue; 2480 if (!SetupGetStringFieldW(&InfContext, 2481 0, 2482 szName, 2483 ARRAYSIZE(szName), 2484 &LineLength)) 2485 { 2486 DPRINT1("Error: SetupGetStringField failed with %d\n", GetLastError()); 2487 return; 2488 } 2489 2490 if (!SetupGetStringFieldW(&InfContext, 2491 1, 2492 szValue, 2493 ARRAYSIZE(szValue), 2494 &LineLength)) 2495 { 2496 DPRINT1("Error: SetupGetStringField failed with %d\n", GetLastError()); 2497 return; 2498 } 2499 iValue = _wtoi(szValue); 2500 DPRINT1("Name %S Value %i\n", szName, iValue); 2501 2502 if (!iValue) 2503 continue; 2504 2505 if (!_wcsicmp(szName, L"BitsPerPel")) 2506 { 2507 dm.dmFields |= DM_BITSPERPEL; 2508 dm.dmBitsPerPel = iValue; 2509 } 2510 else if (!_wcsicmp(szName, L"XResolution")) 2511 { 2512 dm.dmFields |= DM_PELSWIDTH; 2513 dm.dmPelsWidth = iValue; 2514 } 2515 else if (!_wcsicmp(szName, L"YResolution")) 2516 { 2517 dm.dmFields |= DM_PELSHEIGHT; 2518 dm.dmPelsHeight = iValue; 2519 } 2520 else if (!_wcsicmp(szName, L"VRefresh")) 2521 { 2522 dm.dmFields |= DM_DISPLAYFREQUENCY; 2523 dm.dmDisplayFrequency = iValue; 2524 } 2525 } while (SetupFindNextLine(&InfContext, &InfContext)); 2526 2527 ChangeDisplaySettingsW(&dm, CDS_UPDATEREGISTRY); 2528 } 2529 } 2530 2531 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, 2532 L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunOnce", 2533 0, 2534 KEY_SET_VALUE, 2535 &hKey) != ERROR_SUCCESS) 2536 { 2537 DPRINT1("Error: failed to open HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\RunOnce\n"); 2538 return; 2539 } 2540 2541 if (SetupFindFirstLineW(pSetupData->hSetupInf, 2542 L"GuiRunOnce", 2543 NULL, 2544 &InfContext)) 2545 { 2546 int i = 0; 2547 do 2548 { 2549 if (SetupGetStringFieldW(&InfContext, 2550 0, 2551 szValue, 2552 ARRAYSIZE(szValue), 2553 NULL)) 2554 { 2555 WCHAR szPath[MAX_PATH]; 2556 swprintf(szName, L"%d", i); 2557 DPRINT("szName %S szValue %S\n", szName, szValue); 2558 2559 if (ExpandEnvironmentStringsW(szValue, szPath, MAX_PATH)) 2560 { 2561 DPRINT("value %S\n", szPath); 2562 if (RegSetValueExW(hKey, 2563 szName, 2564 0, 2565 REG_SZ, 2566 (const BYTE*)szPath, 2567 (wcslen(szPath) + 1) * sizeof(WCHAR)) == ERROR_SUCCESS) 2568 { 2569 i++; 2570 } 2571 } 2572 } 2573 } while (SetupFindNextLine(&InfContext, &InfContext)); 2574 } 2575 2576 RegCloseKey(hKey); 2577 } 2578 2579 VOID 2580 ProcessSetupInf( 2581 IN OUT PSETUPDATA pSetupData) 2582 { 2583 WCHAR szPath[MAX_PATH]; 2584 WCHAR szValue[MAX_PATH]; 2585 INFCONTEXT InfContext; 2586 DWORD LineLength; 2587 HKEY hKey; 2588 LONG res; 2589 2590 pSetupData->hSetupInf = INVALID_HANDLE_VALUE; 2591 2592 /* Retrieve the path of the setup INF */ 2593 GetSystemDirectoryW(szPath, _countof(szPath)); 2594 wcscat(szPath, L"\\$winnt$.inf"); 2595 2596 /* Open the setup INF */ 2597 pSetupData->hSetupInf = SetupOpenInfFileW(szPath, 2598 NULL, 2599 INF_STYLE_OLDNT, 2600 NULL); 2601 if (pSetupData->hSetupInf == INVALID_HANDLE_VALUE) 2602 { 2603 DPRINT1("Error: Cannot open the setup information file %S with error %d\n", szPath, GetLastError()); 2604 return; 2605 } 2606 2607 2608 /* Retrieve the NT source path from which the 1st-stage installer was run */ 2609 if (!SetupFindFirstLineW(pSetupData->hSetupInf, 2610 L"data", 2611 L"sourcepath", 2612 &InfContext)) 2613 { 2614 DPRINT1("Error: Cannot find sourcepath Key! %d\n", GetLastError()); 2615 return; 2616 } 2617 2618 if (!SetupGetStringFieldW(&InfContext, 2619 1, 2620 szValue, 2621 ARRAYSIZE(szValue), 2622 &LineLength)) 2623 { 2624 DPRINT1("Error: SetupGetStringField failed with %d\n", GetLastError()); 2625 return; 2626 } 2627 2628 *pSetupData->SourcePath = UNICODE_NULL; 2629 2630 /* Close the setup INF as we are going to modify it manually */ 2631 if (pSetupData->hSetupInf != INVALID_HANDLE_VALUE) 2632 SetupCloseInfFile(pSetupData->hSetupInf); 2633 2634 2635 /* Find the installation source path in Win32 format */ 2636 if (!GetInstallSourceWin32(pSetupData->SourcePath, 2637 _countof(pSetupData->SourcePath), 2638 szValue)) 2639 { 2640 *pSetupData->SourcePath = UNICODE_NULL; 2641 } 2642 2643 /* Save the path in Win32 format in the setup INF */ 2644 swprintf(szValue, L"\"%s\"", pSetupData->SourcePath); 2645 WritePrivateProfileStringW(L"data", L"dospath", szValue, szPath); 2646 2647 /* 2648 * Save it also in the registry, in the following keys: 2649 * - HKLM\Software\Microsoft\Windows\CurrentVersion\Setup , 2650 * values "SourcePath" and "ServicePackSourcePath" (REG_SZ); 2651 * - HKLM\Software\Microsoft\Windows NT\CurrentVersion , 2652 * value "SourcePath" (REG_SZ); set to the full path (e.g. D:\I386). 2653 */ 2654 #if 0 2655 res = RegOpenKeyExW(HKEY_LOCAL_MACHINE, 2656 L"Software\\Microsoft\\Windows NT\\CurrentVersion", 2657 0, 2658 KEY_ALL_ACCESS, 2659 &hKey); 2660 2661 if (res != ERROR_SUCCESS) 2662 { 2663 return FALSE; 2664 } 2665 #endif 2666 2667 res = RegCreateKeyExW(HKEY_LOCAL_MACHINE, 2668 L"Software\\Microsoft\\Windows\\CurrentVersion\\Setup", 2669 0, NULL, 2670 REG_OPTION_NON_VOLATILE, 2671 KEY_ALL_ACCESS, // KEY_WRITE 2672 NULL, 2673 &hKey, 2674 NULL); 2675 if (res == ERROR_SUCCESS) 2676 { 2677 res = RegSetValueExW(hKey, 2678 L"SourcePath", 2679 0, 2680 REG_SZ, 2681 (LPBYTE)pSetupData->SourcePath, 2682 (wcslen(pSetupData->SourcePath) + 1) * sizeof(WCHAR)); 2683 2684 res = RegSetValueExW(hKey, 2685 L"ServicePackSourcePath", 2686 0, 2687 REG_SZ, 2688 (LPBYTE)pSetupData->SourcePath, 2689 (wcslen(pSetupData->SourcePath) + 1) * sizeof(WCHAR)); 2690 2691 RegCloseKey(hKey); 2692 } 2693 2694 2695 /* Now, re-open the setup INF (this must succeed) */ 2696 pSetupData->hSetupInf = SetupOpenInfFileW(szPath, 2697 NULL, 2698 INF_STYLE_OLDNT, 2699 NULL); 2700 if (pSetupData->hSetupInf == INVALID_HANDLE_VALUE) 2701 { 2702 DPRINT1("Error: Cannot open the setup information file %S with error %d\n", szPath, GetLastError()); 2703 return; 2704 } 2705 2706 /* Process the unattended section of the setup file */ 2707 ProcessUnattendSection(pSetupData); 2708 } 2709 2710 typedef DWORD(WINAPI *PFNREQUESTWIZARDPAGES)(PDWORD, HPROPSHEETPAGE *, PSETUPDATA); 2711 2712 VOID 2713 InstallWizard(VOID) 2714 { 2715 PROPSHEETHEADER psh = {0}; 2716 HPROPSHEETPAGE *phpage = NULL; 2717 PROPSHEETPAGE psp = {0}; 2718 UINT nPages = 0; 2719 HWND hWnd; 2720 MSG msg; 2721 PSETUPDATA pSetupData = NULL; 2722 HMODULE hNetShell = NULL; 2723 PFNREQUESTWIZARDPAGES pfn = NULL; 2724 DWORD dwPageCount = 10, dwNetworkPageCount = 0; 2725 2726 LogItem(L"BEGIN_SECTION", L"InstallWizard"); 2727 2728 /* Allocate setup data */ 2729 pSetupData = HeapAlloc(GetProcessHeap(), 2730 HEAP_ZERO_MEMORY, 2731 sizeof(SETUPDATA)); 2732 if (pSetupData == NULL) 2733 { 2734 LogItem(NULL, L"SetupData allocation failed!"); 2735 MessageBoxW(NULL, 2736 L"Setup failed to allocate global data!", 2737 L"ReactOS Setup", 2738 MB_ICONERROR | MB_OK); 2739 goto done; 2740 } 2741 pSetupData->ProductOption = PRODUCT_OPTION_DEFAULT; 2742 2743 hNetShell = LoadLibraryW(L"netshell.dll"); 2744 if (hNetShell != NULL) 2745 { 2746 DPRINT("Netshell.dll loaded!\n"); 2747 2748 pfn = (PFNREQUESTWIZARDPAGES)GetProcAddress(hNetShell, 2749 "NetSetupRequestWizardPages"); 2750 if (pfn != NULL) 2751 { 2752 pfn(&dwNetworkPageCount, NULL, NULL); 2753 dwPageCount += dwNetworkPageCount; 2754 } 2755 } 2756 2757 DPRINT("PageCount: %lu\n", dwPageCount); 2758 2759 phpage = HeapAlloc(GetProcessHeap(), 2760 HEAP_ZERO_MEMORY, 2761 dwPageCount * sizeof(HPROPSHEETPAGE)); 2762 if (phpage == NULL) 2763 { 2764 LogItem(NULL, L"Page array allocation failed!"); 2765 MessageBoxW(NULL, 2766 L"Setup failed to allocate page array!", 2767 L"ReactOS Setup", 2768 MB_ICONERROR | MB_OK); 2769 goto done; 2770 } 2771 2772 /* Process the $winnt$.inf setup file */ 2773 ProcessSetupInf(pSetupData); 2774 2775 /* Create the Welcome page */ 2776 psp.dwSize = sizeof(PROPSHEETPAGE); 2777 psp.dwFlags = PSP_DEFAULT | PSP_HIDEHEADER; 2778 psp.hInstance = hDllInstance; 2779 psp.lParam = (LPARAM)pSetupData; 2780 psp.pfnDlgProc = WelcomeDlgProc; 2781 psp.pszTemplate = MAKEINTRESOURCE(IDD_WELCOMEPAGE); 2782 phpage[nPages++] = CreatePropertySheetPage(&psp); 2783 2784 /* Create the Acknowledgements page */ 2785 psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE; 2786 psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_ACKTITLE); 2787 psp.pszHeaderSubTitle = MAKEINTRESOURCE(IDS_ACKSUBTITLE); 2788 psp.pszTemplate = MAKEINTRESOURCE(IDD_ACKPAGE); 2789 psp.pfnDlgProc = AckPageDlgProc; 2790 phpage[nPages++] = CreatePropertySheetPage(&psp); 2791 2792 /* Create the Product page */ 2793 psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE; 2794 psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_PRODUCTTITLE); 2795 psp.pszHeaderSubTitle = MAKEINTRESOURCE(IDS_PRODUCTSUBTITLE); 2796 psp.pszTemplate = MAKEINTRESOURCE(IDD_PRODUCT); 2797 psp.pfnDlgProc = ProductPageDlgProc; 2798 phpage[nPages++] = CreatePropertySheetPage(&psp); 2799 2800 /* Create the Locale page */ 2801 psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE; 2802 psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_LOCALETITLE); 2803 psp.pszHeaderSubTitle = MAKEINTRESOURCE(IDS_LOCALESUBTITLE); 2804 psp.pfnDlgProc = LocalePageDlgProc; 2805 psp.pszTemplate = MAKEINTRESOURCE(IDD_LOCALEPAGE); 2806 phpage[nPages++] = CreatePropertySheetPage(&psp); 2807 2808 /* Create the Owner page */ 2809 psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE; 2810 psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_OWNERTITLE); 2811 psp.pszHeaderSubTitle = MAKEINTRESOURCE(IDS_OWNERSUBTITLE); 2812 psp.pszTemplate = MAKEINTRESOURCE(IDD_OWNERPAGE); 2813 psp.pfnDlgProc = OwnerPageDlgProc; 2814 phpage[nPages++] = CreatePropertySheetPage(&psp); 2815 2816 /* Create the Computer page */ 2817 psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE; 2818 psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_COMPUTERTITLE); 2819 psp.pszHeaderSubTitle = MAKEINTRESOURCE(IDS_COMPUTERSUBTITLE); 2820 psp.pfnDlgProc = ComputerPageDlgProc; 2821 psp.pszTemplate = MAKEINTRESOURCE(IDD_COMPUTERPAGE); 2822 phpage[nPages++] = CreatePropertySheetPage(&psp); 2823 2824 /* Create the DateTime page */ 2825 psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE; 2826 psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_DATETIMETITLE); 2827 psp.pszHeaderSubTitle = MAKEINTRESOURCE(IDS_DATETIMESUBTITLE); 2828 psp.pfnDlgProc = DateTimePageDlgProc; 2829 psp.pszTemplate = MAKEINTRESOURCE(IDD_DATETIMEPAGE); 2830 phpage[nPages++] = CreatePropertySheetPage(&psp); 2831 2832 /* Create the theme selection page */ 2833 psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE; 2834 psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_THEMESELECTIONTITLE); 2835 psp.pszHeaderSubTitle = MAKEINTRESOURCE(IDS_THEMESELECTIONSUBTITLE); 2836 psp.pfnDlgProc = ThemePageDlgProc; 2837 psp.pszTemplate = MAKEINTRESOURCE(IDD_THEMEPAGE); 2838 phpage[nPages++] = CreatePropertySheetPage(&psp); 2839 2840 pSetupData->uFirstNetworkWizardPage = IDD_PROCESSPAGE; 2841 pSetupData->uPostNetworkWizardPage = IDD_PROCESSPAGE; 2842 2843 if (pfn) 2844 { 2845 pfn(&dwNetworkPageCount, &phpage[nPages], pSetupData); 2846 nPages += dwNetworkPageCount; 2847 } 2848 2849 /* Create the Process page */ 2850 psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE; 2851 psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_PROCESSTITLE); 2852 psp.pszHeaderSubTitle = MAKEINTRESOURCE(IDS_PROCESSSUBTITLE); 2853 psp.pfnDlgProc = ProcessPageDlgProc; 2854 psp.pszTemplate = MAKEINTRESOURCE(IDD_PROCESSPAGE); 2855 phpage[nPages++] = CreatePropertySheetPage(&psp); 2856 2857 /* Create the Finish page */ 2858 psp.dwFlags = PSP_DEFAULT | PSP_HIDEHEADER; 2859 psp.pfnDlgProc = FinishDlgProc; 2860 psp.pszTemplate = MAKEINTRESOURCE(IDD_FINISHPAGE); 2861 phpage[nPages++] = CreatePropertySheetPage(&psp); 2862 2863 ASSERT(nPages == dwPageCount); 2864 2865 /* Create the property sheet */ 2866 psh.dwSize = sizeof(PROPSHEETHEADER); 2867 psh.dwFlags = PSH_WIZARD97 | PSH_WATERMARK | PSH_HEADER | PSH_MODELESS; 2868 psh.hInstance = hDllInstance; 2869 psh.hwndParent = NULL; 2870 psh.nPages = nPages; 2871 psh.nStartPage = 0; 2872 psh.phpage = phpage; 2873 psh.pszbmWatermark = MAKEINTRESOURCE(IDB_WATERMARK); 2874 psh.pszbmHeader = MAKEINTRESOURCE(IDB_HEADER); 2875 2876 /* Create title font */ 2877 pSetupData->hTitleFont = CreateTitleFont(); 2878 pSetupData->hBoldFont = CreateBoldFont(); 2879 2880 /* Display the wizard */ 2881 hWnd = (HWND)PropertySheet(&psh); 2882 ShowWindow(hWnd, SW_SHOW); 2883 2884 while (GetMessage(&msg, NULL, 0, 0)) 2885 { 2886 if (!IsDialogMessage(hWnd, &msg)) 2887 { 2888 TranslateMessage(&msg); 2889 DispatchMessage(&msg); 2890 } 2891 } 2892 2893 DeleteObject(pSetupData->hBoldFont); 2894 DeleteObject(pSetupData->hTitleFont); 2895 2896 if (pSetupData->hSetupInf != INVALID_HANDLE_VALUE) 2897 SetupCloseInfFile(pSetupData->hSetupInf); 2898 2899 done: 2900 if (phpage != NULL) 2901 HeapFree(GetProcessHeap(), 0, phpage); 2902 2903 if (hNetShell != NULL) 2904 FreeLibrary(hNetShell); 2905 2906 if (pSetupData != NULL) 2907 HeapFree(GetProcessHeap(), 0, pSetupData); 2908 2909 LogItem(L"END_SECTION", L"InstallWizard"); 2910 } 2911 2912 /* EOF */ 2913