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>
11 /* INCLUDES *****************************************************************/
25 #define PM_REGISTRATION_NOTIFY (WM_APP + 1)
26 /* Private Message used to communicate progress from the background
27 registration thread to the main thread.
28 wParam = 0 Registration in progress
29 = 1 Registration completed
30 lParam = Pointer to a REGISTRATIONNOTIFY structure */
32 typedef struct _REGISTRATIONNOTIFY
38 } REGISTRATIONNOTIFY
, *PREGISTRATIONNOTIFY
;
40 typedef struct _REGISTRATIONDATA
46 } REGISTRATIONDATA
, *PREGISTRATIONDATA
;
49 /* FUNCTIONS ****************************************************************/
51 extern void WINAPI
Control_RunDLLW(HWND hWnd
, HINSTANCE hInst
, LPCWSTR cmd
, DWORD nCmdShow
);
54 GetRosInstallCD(WCHAR
*pwszPath
, DWORD cchPathMax
);
58 RunVMWInstall(HWND hWnd
)
60 PROCESS_INFORMATION ProcInfo
;
64 WCHAR InstallName
[] = L
"vmwinst.exe";
66 ZeroMemory(&si
, sizeof(si
));
69 if(CreateProcessW(NULL
, InstallName
, NULL
, NULL
, TRUE
, NORMAL_PRIORITY_CLASS
,
70 NULL
, NULL
, &si
, &ProcInfo
))
72 EnableWindow(hWnd
, FALSE
);
75 while (PeekMessage(&msg
, NULL
, 0, 0, PM_REMOVE
))
77 if (msg
.message
== WM_QUIT
)
79 TranslateMessage(&msg
);
80 DispatchMessage(&msg
);
83 ret
= MsgWaitForMultipleObjects(1, &ProcInfo
.hProcess
, FALSE
, INFINITE
, QS_ALLEVENTS
| QS_ALLINPUT
);
84 if (ret
== WAIT_OBJECT_0
)
88 EnableWindow(hWnd
, TRUE
);
90 CloseHandle(ProcInfo
.hThread
);
91 CloseHandle(ProcInfo
.hProcess
);
99 CenterWindow(HWND hWnd
)
105 hWndParent
= GetParent(hWnd
);
106 if (hWndParent
== NULL
)
107 hWndParent
= GetDesktopWindow();
109 GetWindowRect(hWndParent
, &rcParent
);
110 GetWindowRect(hWnd
, &rcWindow
);
114 ((rcParent
.right
- rcParent
.left
) - (rcWindow
.right
- rcWindow
.left
)) / 2,
115 ((rcParent
.bottom
- rcParent
.top
) - (rcWindow
.bottom
- rcWindow
.top
)) / 2,
123 CreateTitleFont(VOID
)
125 NONCLIENTMETRICSW ncm
;
131 ncm
.cbSize
= sizeof(NONCLIENTMETRICSW
);
132 SystemParametersInfo(SPI_GETNONCLIENTMETRICS
, 0, &ncm
, 0);
134 LogFont
= ncm
.lfMessageFont
;
135 LogFont
.lfWeight
= FW_BOLD
;
136 wcscpy(LogFont
.lfFaceName
, L
"MS Shell Dlg");
140 LogFont
.lfHeight
= 0 - GetDeviceCaps(hdc
, LOGPIXELSY
) * FontSize
/ 72;
141 hFont
= CreateFontIndirectW(&LogFont
);
142 ReleaseDC(NULL
, hdc
);
148 static INT_PTR CALLBACK
149 GplDlgProc(HWND hwndDlg
,
154 HRSRC GplTextResource
;
164 GplTextResource
= FindResourceW(hDllInstance
, MAKEINTRESOURCE(IDR_GPL
), L
"RT_TEXT");
165 if (NULL
== GplTextResource
)
169 Size
= SizeofResource(hDllInstance
, GplTextResource
);
174 GplText
= HeapAlloc(GetProcessHeap(), 0, Size
+ 1);
179 GplTextMem
= LoadResource(hDllInstance
, GplTextResource
);
180 if (NULL
== GplTextMem
)
182 HeapFree(GetProcessHeap(), 0, GplText
);
185 GplTextLocked
= LockResource(GplTextMem
);
186 if (NULL
== GplTextLocked
)
188 HeapFree(GetProcessHeap(), 0, GplText
);
191 memcpy(GplText
, GplTextLocked
, Size
);
192 GplText
[Size
] = '\0';
193 SendMessageA(GetDlgItem(hwndDlg
, IDC_GPL_TEXT
), WM_SETTEXT
, 0, (LPARAM
) GplText
);
194 HeapFree(GetProcessHeap(), 0, GplText
);
195 SetFocus(GetDlgItem(hwndDlg
, IDOK
));
199 EndDialog(hwndDlg
, IDCANCEL
);
203 if (HIWORD(wParam
) == BN_CLICKED
&& IDOK
== LOWORD(wParam
))
205 EndDialog(hwndDlg
, IDOK
);
217 static INT_PTR CALLBACK
218 WelcomeDlgProc(HWND hwndDlg
,
223 PSETUPDATA pSetupData
;
225 pSetupData
= (PSETUPDATA
)GetWindowLongPtr(hwndDlg
, DWLP_USER
);
234 /* Get pointer to the global setup data */
235 pSetupData
= (PSETUPDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
236 SetWindowLongPtr(hwndDlg
, DWLP_USER
, (LONG_PTR
)pSetupData
);
238 hwndControl
= GetParent(hwndDlg
);
240 /* Center the wizard window */
241 CenterWindow (hwndControl
);
243 /* Hide the system menu */
244 dwStyle
= GetWindowLongPtr(hwndControl
, GWL_STYLE
);
245 SetWindowLongPtr(hwndControl
, GWL_STYLE
, dwStyle
& ~WS_SYSMENU
);
247 /* Hide and disable the 'Cancel' button */
248 hwndControl
= GetDlgItem(GetParent(hwndDlg
), IDCANCEL
);
249 ShowWindow (hwndControl
, SW_HIDE
);
250 EnableWindow (hwndControl
, FALSE
);
253 SendDlgItemMessage(hwndDlg
,
256 (WPARAM
)pSetupData
->hTitleFont
,
264 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
269 LogItem(L
"BEGIN", L
"WelcomePage");
270 /* Enable the Next button */
271 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_NEXT
);
272 if (pSetupData
->UnattendSetup
)
274 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, IDD_ACKPAGE
);
280 LogItem(L
"END", L
"WelcomePage");
284 pSetupData
->UnattendSetup
= FALSE
;
301 static INT_PTR CALLBACK
302 AckPageDlgProc(HWND hwndDlg
,
309 PWCHAR End
, CurrentProject
;
310 INT ProjectsSize
, ProjectsCount
;
311 PSETUPDATA pSetupData
;
313 pSetupData
= (PSETUPDATA
)GetWindowLongPtr(hwndDlg
, DWLP_USER
);
319 pSetupData
= (PSETUPDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
320 SetWindowLongPtr(hwndDlg
, DWLP_USER
, (LONG_PTR
)pSetupData
);
326 Projects
= HeapAlloc(GetProcessHeap(), 0, ProjectsSize
* sizeof(WCHAR
));
327 if (NULL
== Projects
)
331 ProjectsCount
= LoadStringW(hDllInstance
, IDS_ACKPROJECTS
, Projects
, ProjectsSize
);
332 if (0 == ProjectsCount
)
334 HeapFree(GetProcessHeap(), 0, Projects
);
337 if (ProjectsCount
< ProjectsSize
- 1)
341 HeapFree(GetProcessHeap(), 0, Projects
);
345 CurrentProject
= Projects
;
346 while (L
'\0' != *CurrentProject
)
348 End
= wcschr(CurrentProject
, L
'\n');
353 (void)ListBox_AddString(GetDlgItem(hwndDlg
, IDC_PROJECTS
), CurrentProject
);
356 CurrentProject
= End
+ 1;
360 CurrentProject
+= wcslen(CurrentProject
);
363 HeapFree(GetProcessHeap(), 0, Projects
);
368 if (HIWORD(wParam
) == BN_CLICKED
&& IDC_VIEWGPL
== LOWORD(wParam
))
370 DialogBox(hDllInstance
, MAKEINTRESOURCE(IDD_GPL
), NULL
, GplDlgProc
);
371 SetForegroundWindow(GetParent(hwndDlg
));
377 lpnm
= (LPNMHDR
)lParam
;
382 /* Enable the Back and Next buttons */
383 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_BACK
| PSWIZB_NEXT
);
384 if (pSetupData
->UnattendSetup
)
386 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, IDD_LOCALEPAGE
);
392 pSetupData
->UnattendSetup
= FALSE
;
410 WriteOwnerSettings(WCHAR
* OwnerName
,
411 WCHAR
* OwnerOrganization
)
418 res
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
419 L
"Software\\Microsoft\\Windows NT\\CurrentVersion",
424 if (res
!= ERROR_SUCCESS
)
429 res
= RegSetValueExW(hKey
,
434 (wcslen(OwnerName
) + 1) * sizeof(WCHAR
));
436 if (res
!= ERROR_SUCCESS
)
442 res
= RegSetValueExW(hKey
,
443 L
"RegisteredOrganization",
446 (LPBYTE
)OwnerOrganization
,
447 (wcslen(OwnerOrganization
) + 1) * sizeof(WCHAR
));
450 return (res
== ERROR_SUCCESS
);
453 static INT_PTR CALLBACK
454 OwnerPageDlgProc(HWND hwndDlg
,
460 WCHAR OwnerOrganization
[51];
462 WCHAR ErrorName
[256];
464 PSETUPDATA pSetupData
;
466 pSetupData
= (PSETUPDATA
)GetWindowLongPtr(hwndDlg
, DWLP_USER
);
472 pSetupData
= (PSETUPDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
473 SetWindowLongPtr(hwndDlg
, DWLP_USER
, (LONG_PTR
)pSetupData
);
475 /* set a localized ('Owner') placeholder string as default */
476 if (LoadStringW(hDllInstance
, IDS_MACHINE_OWNER_NAME
, OwnerName
, _countof(OwnerName
)))
478 SendDlgItemMessage(hwndDlg
, IDC_OWNERNAME
, WM_SETTEXT
, 0, (LPARAM
)OwnerName
);
481 SendDlgItemMessage(hwndDlg
, IDC_OWNERNAME
, EM_LIMITTEXT
, 50, 0);
482 SendDlgItemMessage(hwndDlg
, IDC_OWNERORGANIZATION
, EM_LIMITTEXT
, 50, 0);
484 /* Set focus to owner name */
485 SetFocus(GetDlgItem(hwndDlg
, IDC_OWNERNAME
));
487 /* Select the default text to quickly overwrite it by typing */
488 SendDlgItemMessage(hwndDlg
, IDC_OWNERNAME
, EM_SETSEL
, 0, -1);
495 lpnm
= (LPNMHDR
)lParam
;
500 /* Enable the Back and Next buttons */
501 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_BACK
| PSWIZB_NEXT
);
502 if (pSetupData
->UnattendSetup
)
504 SendMessage(GetDlgItem(hwndDlg
, IDC_OWNERNAME
), WM_SETTEXT
, 0, (LPARAM
)pSetupData
->OwnerName
);
505 SendMessage(GetDlgItem(hwndDlg
, IDC_OWNERORGANIZATION
), WM_SETTEXT
, 0, (LPARAM
)pSetupData
->OwnerOrganization
);
506 if (WriteOwnerSettings(pSetupData
->OwnerName
, pSetupData
->OwnerOrganization
))
508 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, IDD_COMPUTERPAGE
);
516 if (GetDlgItemTextW(hwndDlg
, IDC_OWNERNAME
, OwnerName
, 50) == 0)
518 if (0 == LoadStringW(hDllInstance
, IDS_REACTOS_SETUP
, Title
, sizeof(Title
) / sizeof(Title
[0])))
520 wcscpy(Title
, L
"ReactOS Setup");
522 if (0 == LoadStringW(hDllInstance
, IDS_WZD_NAME
, ErrorName
, sizeof(ErrorName
) / sizeof(ErrorName
[0])))
524 wcscpy(ErrorName
, L
"Setup cannot continue until you enter your name.");
526 MessageBoxW(hwndDlg
, ErrorName
, Title
, MB_ICONERROR
| MB_OK
);
528 SetFocus(GetDlgItem(hwndDlg
, IDC_OWNERNAME
));
529 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, -1);
534 OwnerOrganization
[0] = 0;
535 GetDlgItemTextW(hwndDlg
, IDC_OWNERORGANIZATION
, OwnerOrganization
, 50);
537 if (!WriteOwnerSettings(OwnerName
, OwnerOrganization
))
539 SetFocus(GetDlgItem(hwndDlg
, IDC_OWNERNAME
));
540 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, -1);
545 pSetupData
->UnattendSetup
= FALSE
;
563 WriteComputerSettings(WCHAR
* ComputerName
, HWND hwndDlg
)
566 WCHAR ErrorComputerName
[256];
568 if (!SetComputerNameW(ComputerName
))
572 if (0 == LoadStringW(hDllInstance
, IDS_REACTOS_SETUP
, Title
, sizeof(Title
) / sizeof(Title
[0])))
574 wcscpy(Title
, L
"ReactOS Setup");
576 if (0 == LoadStringW(hDllInstance
, IDS_WZD_SETCOMPUTERNAME
, ErrorComputerName
,
577 sizeof(ErrorComputerName
) / sizeof(ErrorComputerName
[0])))
579 wcscpy(ErrorComputerName
, L
"Setup failed to set the computer name.");
581 MessageBoxW(hwndDlg
, ErrorComputerName
, Title
, MB_ICONERROR
| MB_OK
);
587 /* Try to also set DNS hostname */
588 SetComputerNameExW(ComputerNamePhysicalDnsHostname
, ComputerName
);
590 /* Set the accounts domain name */
591 SetAccountsDomainSid(NULL
, ComputerName
);
599 WriteDefaultLogonData(LPWSTR Domain
)
601 WCHAR szAdministratorName
[256];
605 if (LoadStringW(hDllInstance
,
606 IDS_ADMINISTRATOR_NAME
,
608 sizeof(szAdministratorName
) / sizeof(WCHAR
)) == 0)
610 wcscpy(szAdministratorName
, L
"Administrator");
613 lError
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
614 L
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon",
618 if (lError
!= ERROR_SUCCESS
)
621 lError
= RegSetValueEx(hKey
,
626 (wcslen(Domain
)+ 1) * sizeof(WCHAR
));
627 if (lError
!= ERROR_SUCCESS
)
629 DPRINT1("RegSetValueEx(\"DefaultDomain\") failed!\n");
632 lError
= RegSetValueEx(hKey
,
636 (LPBYTE
)szAdministratorName
,
637 (wcslen(szAdministratorName
)+ 1) * sizeof(WCHAR
));
638 if (lError
!= ERROR_SUCCESS
)
640 DPRINT1("RegSetValueEx(\"DefaultUserName\") failed!\n");
649 /* lpBuffer will be filled with a 15-char string (plus the null terminator) */
651 GenerateComputerName(LPWSTR lpBuffer
)
653 static const WCHAR Chars
[] = L
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
654 static const unsigned cChars
= sizeof(Chars
) / sizeof(WCHAR
) - 1;
657 wcscpy(lpBuffer
, L
"REACTOS-");
659 srand(GetTickCount());
661 /* fill in 7 characters */
662 for (i
= 8; i
< 15; i
++)
663 lpBuffer
[i
] = Chars
[rand() % cChars
];
665 lpBuffer
[15] = UNICODE_NULL
; /* NULL-terminate */
668 static INT_PTR CALLBACK
669 ComputerPageDlgProc(HWND hwndDlg
,
674 WCHAR ComputerName
[MAX_COMPUTERNAME_LENGTH
+ 1];
675 WCHAR Password1
[128];
676 WCHAR Password2
[128];
679 WCHAR EmptyComputerName
[256], NotMatchPassword
[256], WrongPassword
[256];
681 PSETUPDATA pSetupData
;
683 pSetupData
= (PSETUPDATA
)GetWindowLongPtr(hwndDlg
, DWLP_USER
);
685 if (0 == LoadStringW(hDllInstance
, IDS_REACTOS_SETUP
, Title
, sizeof(Title
) / sizeof(Title
[0])))
687 wcscpy(Title
, L
"ReactOS Setup");
693 pSetupData
= (PSETUPDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
694 SetWindowLongPtr(hwndDlg
, DWLP_USER
, (LONG_PTR
)pSetupData
);
696 /* Generate a new pseudo-random computer name */
697 GenerateComputerName(ComputerName
);
699 /* Display current computer name */
700 SetDlgItemTextW(hwndDlg
, IDC_COMPUTERNAME
, ComputerName
);
702 /* Set text limits */
703 SendDlgItemMessage(hwndDlg
, IDC_COMPUTERNAME
, EM_LIMITTEXT
, MAX_COMPUTERNAME_LENGTH
, 0);
704 SendDlgItemMessage(hwndDlg
, IDC_ADMINPASSWORD1
, EM_LIMITTEXT
, 127, 0);
705 SendDlgItemMessage(hwndDlg
, IDC_ADMINPASSWORD2
, EM_LIMITTEXT
, 127, 0);
707 /* Set focus to computer name */
708 SetFocus(GetDlgItem(hwndDlg
, IDC_COMPUTERNAME
));
709 if (pSetupData
->UnattendSetup
)
711 SendMessage(GetDlgItem(hwndDlg
, IDC_COMPUTERNAME
), WM_SETTEXT
, 0, (LPARAM
)pSetupData
->ComputerName
);
712 SendMessage(GetDlgItem(hwndDlg
, IDC_ADMINPASSWORD1
), WM_SETTEXT
, 0, (LPARAM
)pSetupData
->AdminPassword
);
713 SendMessage(GetDlgItem(hwndDlg
, IDC_ADMINPASSWORD2
), WM_SETTEXT
, 0, (LPARAM
)pSetupData
->AdminPassword
);
714 WriteComputerSettings(pSetupData
->ComputerName
, NULL
);
715 SetAdministratorPassword(pSetupData
->AdminPassword
);
718 /* Store the administrator account name as the default user name */
719 WriteDefaultLogonData(pSetupData
->ComputerName
);
725 lpnm
= (LPNMHDR
)lParam
;
730 /* Enable the Back and Next buttons */
731 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_BACK
| PSWIZB_NEXT
);
732 if (pSetupData
->UnattendSetup
&& WriteComputerSettings(pSetupData
->ComputerName
, hwndDlg
))
734 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, IDD_DATETIMEPAGE
);
740 if (0 == GetDlgItemTextW(hwndDlg
, IDC_COMPUTERNAME
, ComputerName
, MAX_COMPUTERNAME_LENGTH
+ 1))
742 if (0 == LoadStringW(hDllInstance
, IDS_WZD_COMPUTERNAME
, EmptyComputerName
,
743 sizeof(EmptyComputerName
) / sizeof(EmptyComputerName
[0])))
745 wcscpy(EmptyComputerName
, L
"Setup cannot continue until you enter the name of your computer.");
747 MessageBoxW(hwndDlg
, EmptyComputerName
, Title
, MB_ICONERROR
| MB_OK
);
748 SetFocus(GetDlgItem(hwndDlg
, IDC_COMPUTERNAME
));
749 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, -1);
753 /* No need to check computer name for invalid characters,
754 * SetComputerName() will do it for us */
756 if (!WriteComputerSettings(ComputerName
, hwndDlg
))
758 SetFocus(GetDlgItem(hwndDlg
, IDC_COMPUTERNAME
));
759 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, -1);
764 /* Check if admin passwords have been entered */
765 if ((GetDlgItemText(hwndDlg
, IDC_ADMINPASSWORD1
, Password1
, 128) == 0) ||
766 (GetDlgItemText(hwndDlg
, IDC_ADMINPASSWORD2
, Password2
, 128) == 0))
768 if (0 == LoadStringW(hDllInstance
, IDS_WZD_PASSWORDEMPTY
, EmptyPassword
,
769 sizeof(EmptyPassword
) / sizeof(EmptyPassword
[0])))
771 wcscpy(EmptyPassword
, L
"You must enter a password !");
773 MessageBoxW(hwndDlg
, EmptyPassword
, Title
, MB_ICONERROR
| MB_OK
);
774 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, -1);
778 GetDlgItemTextW(hwndDlg
, IDC_ADMINPASSWORD1
, Password1
, 128);
779 GetDlgItemTextW(hwndDlg
, IDC_ADMINPASSWORD2
, Password2
, 128);
781 /* Check if passwords match */
782 if (wcscmp(Password1
, Password2
))
784 if (0 == LoadStringW(hDllInstance
, IDS_WZD_PASSWORDMATCH
, NotMatchPassword
,
785 sizeof(NotMatchPassword
) / sizeof(NotMatchPassword
[0])))
787 wcscpy(NotMatchPassword
, L
"The passwords you entered do not match. Please enter the desired password again.");
789 MessageBoxW(hwndDlg
, NotMatchPassword
, Title
, MB_ICONERROR
| MB_OK
);
790 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, -1);
794 /* Check password for invalid characters */
795 Password
= (PWCHAR
)Password1
;
798 if (!isprint(*Password
))
800 if (0 == LoadStringW(hDllInstance
, IDS_WZD_PASSWORDCHAR
, WrongPassword
,
801 sizeof(WrongPassword
) / sizeof(WrongPassword
[0])))
803 wcscpy(WrongPassword
, L
"The password you entered contains invalid characters. Please enter a cleaned password.");
805 MessageBoxW(hwndDlg
, WrongPassword
, Title
, MB_ICONERROR
| MB_OK
);
806 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, -1);
812 /* Set admin password */
813 SetAdministratorPassword(Password1
);
817 pSetupData
->UnattendSetup
= FALSE
;
835 SetKeyboardLayoutName(HWND hwnd
)
838 TCHAR szLayoutPath
[256];
839 TCHAR szLocaleName
[32];
843 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE
,
844 _T("SYSTEM\\CurrentControlSet\\Control\\NLS\\Locale"),
850 dwValueSize
= 16 * sizeof(TCHAR
);
851 if (RegQueryValueEx(hKey
,
862 _tcscpy(szLayoutPath
,
863 _T("SYSTEM\\CurrentControlSet\\Control\\Keyboard Layouts\\"));
864 _tcscat(szLayoutPath
,
867 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE
,
874 dwValueSize
= 32 * sizeof(TCHAR
);
875 if (RegQueryValueEx(hKey
,
892 RunControlPanelApplet(HWND hwnd
, PCWSTR pwszCPLParameters
)
895 if (pwszCPLParameters
)
897 STARTUPINFOW StartupInfo
;
898 PROCESS_INFORMATION ProcessInformation
;
899 WCHAR CmdLine
[MAX_PATH
] = L
"rundll32.exe shell32.dll,Control_RunDLL ";
901 ZeroMemory(&StartupInfo
, sizeof(StartupInfo
));
902 StartupInfo
.cb
= sizeof(StartupInfo
);
904 ASSERT(_countof(CmdLine
) > wcslen(CmdLine
) + wcslen(pwszCPLParameters
));
905 wcscat(CmdLine
, pwszCPLParameters
);
907 if (!CreateProcessW(NULL
,
916 &ProcessInformation
))
918 MessageBoxW(hwnd
, L
"Error: Failed to launch the Control Panel Applet.", NULL
, MB_ICONERROR
);
922 while((MsgWaitForMultipleObjects(1, &ProcessInformation
.hProcess
, FALSE
, INFINITE
, QS_ALLINPUT
|QS_ALLPOSTMESSAGE
)) != WAIT_OBJECT_0
)
924 while(PeekMessageW(&msg
, NULL
, 0, 0, PM_REMOVE
))
926 TranslateMessage(&msg
);
927 DispatchMessageW(&msg
);
930 CloseHandle(ProcessInformation
.hThread
);
931 CloseHandle(ProcessInformation
.hProcess
);
936 MessageBoxW(hwnd
, L
"Error: Failed to launch the Control Panel Applet.", NULL
, MB_ICONERROR
);
942 WriteUserLocale(VOID
)
948 lcid
= GetSystemDefaultLCID();
950 if (GetLocaleInfoW(MAKELCID(lcid
, SORT_DEFAULT
), LOCALE_ILANGUAGE
, Locale
, sizeof(Locale
) / sizeof(Locale
[0])) != 0)
952 if (RegCreateKeyExW(HKEY_CURRENT_USER
, L
"Control Panel\\International",
953 0, NULL
, REG_OPTION_NON_VOLATILE
,
954 KEY_WRITE
, NULL
, &hKey
, NULL
) == ERROR_SUCCESS
)
956 RegSetValueExW(hKey
, L
"Locale", 0, REG_SZ
, (LPBYTE
)Locale
, (wcslen(Locale
) + 1) * sizeof(WCHAR
));
962 static INT_PTR CALLBACK
963 LocalePageDlgProc(HWND hwndDlg
,
968 PSETUPDATA SetupData
;
970 /* Retrieve pointer to the global setup data */
971 SetupData
= (PSETUPDATA
)GetWindowLongPtr (hwndDlg
, GWL_USERDATA
);
977 /* Save pointer to the global setup data */
978 SetupData
= (PSETUPDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
979 SetWindowLongPtr(hwndDlg
, GWL_USERDATA
, (DWORD_PTR
)SetupData
);
982 SetKeyboardLayoutName(GetDlgItem(hwndDlg
, IDC_LAYOUTTEXT
));
987 if (HIWORD(wParam
) == BN_CLICKED
)
989 switch (LOWORD(wParam
))
991 case IDC_CUSTOMLOCALE
:
992 RunControlPanelApplet(hwndDlg
, L
"intl.cpl,,5");
993 /* FIXME: Update input locale name */
996 case IDC_CUSTOMLAYOUT
:
997 RunControlPanelApplet(hwndDlg
, L
"input.dll,@1");
1005 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
1010 /* Enable the Back and Next buttons */
1011 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_BACK
| PSWIZB_NEXT
);
1012 if (SetupData
->UnattendSetup
)
1014 WCHAR wszPath
[MAX_PATH
];
1015 if (GetRosInstallCD(wszPath
, _countof(wszPath
)))
1017 WCHAR wszParams
[1024];
1018 swprintf(wszParams
, L
"intl.cpl,,/f:\"%sreactos\\unattend.inf\"", wszPath
);
1019 RunControlPanelApplet(hwndDlg
, wszParams
);
1023 RunControlPanelApplet(hwndDlg
, L
"intl.cpl,,/f:\"unattend.inf\"");
1026 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, IDD_OWNERPAGE
);
1035 SetupData
->UnattendSetup
= FALSE
;
1052 static PTIMEZONE_ENTRY
1053 GetLargerTimeZoneEntry(PSETUPDATA SetupData
, DWORD Index
)
1055 PTIMEZONE_ENTRY Entry
;
1057 Entry
= SetupData
->TimeZoneListHead
;
1058 while (Entry
!= NULL
)
1060 if (Entry
->Index
>= Index
)
1063 Entry
= Entry
->Next
;
1071 CreateTimeZoneList(PSETUPDATA SetupData
)
1073 WCHAR szKeyName
[256];
1081 PTIMEZONE_ENTRY Entry
;
1082 PTIMEZONE_ENTRY Current
;
1084 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
1085 L
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones",
1094 dwNameSize
= 256 * sizeof(WCHAR
);
1095 lError
= RegEnumKeyExW(hZonesKey
,
1103 if (lError
!= ERROR_SUCCESS
&& lError
!= ERROR_MORE_DATA
)
1106 if (RegOpenKeyExW(hZonesKey
,
1113 Entry
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(TIMEZONE_ENTRY
));
1116 RegCloseKey(hZoneKey
);
1120 dwValueSize
= 64 * sizeof(WCHAR
);
1121 if (RegQueryValueExW(hZoneKey
,
1125 (LPBYTE
)&Entry
->Description
,
1128 RegCloseKey(hZoneKey
);
1132 dwValueSize
= 32 * sizeof(WCHAR
);
1133 if (RegQueryValueExW(hZoneKey
,
1137 (LPBYTE
)&Entry
->StandardName
,
1140 RegCloseKey(hZoneKey
);
1144 dwValueSize
= 32 * sizeof(WCHAR
);
1145 if (RegQueryValueExW(hZoneKey
,
1149 (LPBYTE
)&Entry
->DaylightName
,
1152 RegCloseKey(hZoneKey
);
1156 dwValueSize
= sizeof(DWORD
);
1157 if (RegQueryValueExW(hZoneKey
,
1161 (LPBYTE
)&Entry
->Index
,
1164 RegCloseKey(hZoneKey
);
1168 dwValueSize
= sizeof(TZ_INFO
);
1169 if (RegQueryValueExW(hZoneKey
,
1173 (LPBYTE
)&Entry
->TimezoneInfo
,
1176 RegCloseKey(hZoneKey
);
1180 RegCloseKey(hZoneKey
);
1182 if (SetupData
->TimeZoneListHead
== NULL
&&
1183 SetupData
->TimeZoneListTail
== NULL
)
1187 SetupData
->TimeZoneListHead
= Entry
;
1188 SetupData
->TimeZoneListTail
= Entry
;
1192 Current
= GetLargerTimeZoneEntry(SetupData
, Entry
->Index
);
1193 if (Current
!= NULL
)
1195 if (Current
== SetupData
->TimeZoneListHead
)
1197 /* Prepend to head */
1199 Entry
->Next
= SetupData
->TimeZoneListHead
;
1200 SetupData
->TimeZoneListHead
->Prev
= Entry
;
1201 SetupData
->TimeZoneListHead
= Entry
;
1205 /* Insert before current */
1206 Entry
->Prev
= Current
->Prev
;
1207 Entry
->Next
= Current
;
1208 Current
->Prev
->Next
= Entry
;
1209 Current
->Prev
= Entry
;
1214 /* Append to tail */
1215 Entry
->Prev
= SetupData
->TimeZoneListTail
;
1217 SetupData
->TimeZoneListTail
->Next
= Entry
;
1218 SetupData
->TimeZoneListTail
= Entry
;
1225 RegCloseKey(hZonesKey
);
1230 DestroyTimeZoneList(PSETUPDATA SetupData
)
1232 PTIMEZONE_ENTRY Entry
;
1234 while (SetupData
->TimeZoneListHead
!= NULL
)
1236 Entry
= SetupData
->TimeZoneListHead
;
1238 SetupData
->TimeZoneListHead
= Entry
->Next
;
1239 if (SetupData
->TimeZoneListHead
!= NULL
)
1241 SetupData
->TimeZoneListHead
->Prev
= NULL
;
1244 HeapFree(GetProcessHeap(), 0, Entry
);
1247 SetupData
->TimeZoneListTail
= NULL
;
1251 GetTimeZoneListIndex(LPDWORD lpIndex
)
1253 WCHAR szLanguageIdString
[9];
1260 BOOL bFound
= FALSE
;
1261 unsigned long iLanguageID
;
1265 *lpIndex
= 85; /* fallback to GMT time zone */
1267 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
1268 L
"SYSTEM\\CurrentControlSet\\Control\\NLS\\Language",
1274 dwValueSize
= 9 * sizeof(WCHAR
);
1275 if (RegQueryValueExW(hKey
,
1279 (LPBYTE
)szLanguageIdString
,
1286 iLanguageID
= wcstoul(szLanguageIdString
, NULL
, 16);
1291 iLanguageID
= *lpIndex
;
1294 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
1295 L
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones",
1302 if (RegQueryValueExW(hKey
,
1313 Buffer
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, dwValueSize
);
1320 if (RegQueryValueExW(hKey
,
1327 HeapFree(GetProcessHeap(), 0, Buffer
);
1337 Length
= wcslen(Ptr
);
1338 if (wcstoul(Ptr
, NULL
, 16) == iLanguageID
)
1341 Ptr
= Ptr
+ Length
+ 1;
1347 *lpIndex
= wcstoul(Ptr
, &End
, 10);
1348 HeapFree(GetProcessHeap(), 0, Buffer
);
1352 Length
= wcslen(Ptr
);
1353 Ptr
= Ptr
+ Length
+ 1;
1356 HeapFree(GetProcessHeap(), 0, Buffer
);
1363 ShowTimeZoneList(HWND hwnd
, PSETUPDATA SetupData
, DWORD dwEntryIndex
)
1365 PTIMEZONE_ENTRY Entry
;
1369 GetTimeZoneListIndex(&dwEntryIndex
);
1371 Entry
= SetupData
->TimeZoneListHead
;
1372 while (Entry
!= NULL
)
1374 dwCount
= SendMessage(hwnd
,
1377 (LPARAM
)Entry
->Description
);
1379 if (dwEntryIndex
!= 0 && dwEntryIndex
== Entry
->Index
)
1382 Entry
= Entry
->Next
;
1393 SetLocalTimeZone(HWND hwnd
, PSETUPDATA SetupData
)
1395 TIME_ZONE_INFORMATION TimeZoneInformation
;
1396 PTIMEZONE_ENTRY Entry
;
1400 dwIndex
= SendMessage(hwnd
,
1406 Entry
= SetupData
->TimeZoneListHead
;
1413 Entry
= Entry
->Next
;
1416 wcscpy(TimeZoneInformation
.StandardName
,
1417 Entry
->StandardName
);
1418 wcscpy(TimeZoneInformation
.DaylightName
,
1419 Entry
->DaylightName
);
1421 TimeZoneInformation
.Bias
= Entry
->TimezoneInfo
.Bias
;
1422 TimeZoneInformation
.StandardBias
= Entry
->TimezoneInfo
.StandardBias
;
1423 TimeZoneInformation
.DaylightBias
= Entry
->TimezoneInfo
.DaylightBias
;
1425 memcpy(&TimeZoneInformation
.StandardDate
,
1426 &Entry
->TimezoneInfo
.StandardDate
,
1427 sizeof(SYSTEMTIME
));
1428 memcpy(&TimeZoneInformation
.DaylightDate
,
1429 &Entry
->TimezoneInfo
.DaylightDate
,
1430 sizeof(SYSTEMTIME
));
1432 /* Set time zone information */
1433 SetTimeZoneInformation(&TimeZoneInformation
);
1438 GetLocalSystemTime(HWND hwnd
, PSETUPDATA SetupData
)
1443 if (DateTime_GetSystemtime(GetDlgItem(hwnd
, IDC_DATEPICKER
), &Date
) != GDT_VALID
)
1448 if (DateTime_GetSystemtime(GetDlgItem(hwnd
, IDC_TIMEPICKER
), &Time
) != GDT_VALID
)
1453 SetupData
->SystemTime
.wYear
= Date
.wYear
;
1454 SetupData
->SystemTime
.wMonth
= Date
.wMonth
;
1455 SetupData
->SystemTime
.wDayOfWeek
= Date
.wDayOfWeek
;
1456 SetupData
->SystemTime
.wDay
= Date
.wDay
;
1457 SetupData
->SystemTime
.wHour
= Time
.wHour
;
1458 SetupData
->SystemTime
.wMinute
= Time
.wMinute
;
1459 SetupData
->SystemTime
.wSecond
= Time
.wSecond
;
1460 SetupData
->SystemTime
.wMilliseconds
= Time
.wMilliseconds
;
1467 SetAutoDaylightInfo(HWND hwnd
)
1472 if (SendMessage(hwnd
, BM_GETCHECK
, 0, 0) == BST_UNCHECKED
)
1474 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
1475 L
"SYSTEM\\CurrentControlSet\\Control\\TimeZoneInformation",
1481 RegSetValueExW(hKey
,
1482 L
"DisableAutoDaylightTimeSet",
1493 SetSystemLocalTime(HWND hwnd
, PSETUPDATA SetupData
)
1498 * Call SetLocalTime twice to ensure correct results
1500 Ret
= SetLocalTime(&SetupData
->SystemTime
) &&
1501 SetLocalTime(&SetupData
->SystemTime
);
1507 WriteDateTimeSettings(HWND hwndDlg
, PSETUPDATA SetupData
)
1510 WCHAR ErrorLocalTime
[256];
1511 GetLocalSystemTime(hwndDlg
, SetupData
);
1512 SetLocalTimeZone(GetDlgItem(hwndDlg
, IDC_TIMEZONELIST
),
1515 SetAutoDaylightInfo(GetDlgItem(hwndDlg
, IDC_AUTODAYLIGHT
));
1516 if(!SetSystemLocalTime(hwndDlg
, SetupData
))
1518 if (0 == LoadStringW(hDllInstance
, IDS_REACTOS_SETUP
, Title
, sizeof(Title
) / sizeof(Title
[0])))
1520 wcscpy(Title
, L
"ReactOS Setup");
1522 if (0 == LoadStringW(hDllInstance
, IDS_WZD_LOCALTIME
, ErrorLocalTime
,
1523 sizeof(ErrorLocalTime
) / sizeof(ErrorLocalTime
[0])))
1525 wcscpy(ErrorLocalTime
, L
"Setup was unable to set the local time.");
1527 MessageBoxW(hwndDlg
, ErrorLocalTime
, Title
, MB_ICONWARNING
| MB_OK
);
1534 static INT_PTR CALLBACK
1535 DateTimePageDlgProc(HWND hwndDlg
,
1540 PSETUPDATA SetupData
;
1542 /* Retrieve pointer to the global setup data */
1543 SetupData
= (PSETUPDATA
)GetWindowLongPtr (hwndDlg
, GWL_USERDATA
);
1549 /* Save pointer to the global setup data */
1550 SetupData
= (PSETUPDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
1551 SetWindowLongPtr(hwndDlg
, GWL_USERDATA
, (DWORD_PTR
)SetupData
);
1553 CreateTimeZoneList(SetupData
);
1555 if (SetupData
->UnattendSetup
)
1557 ShowTimeZoneList(GetDlgItem(hwndDlg
, IDC_TIMEZONELIST
),
1558 SetupData
, SetupData
->TimeZoneIndex
);
1560 if (!SetupData
->DisableAutoDaylightTimeSet
)
1562 SendDlgItemMessage(hwndDlg
, IDC_AUTODAYLIGHT
, BM_SETCHECK
, (WPARAM
)BST_CHECKED
, 0);
1567 ShowTimeZoneList(GetDlgItem(hwndDlg
, IDC_TIMEZONELIST
),
1570 SendDlgItemMessage(hwndDlg
, IDC_AUTODAYLIGHT
, BM_SETCHECK
, (WPARAM
)BST_CHECKED
, 0);
1579 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
1584 /* Enable the Back and Next buttons */
1585 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_BACK
| PSWIZB_NEXT
);
1586 if (SetupData
->UnattendSetup
&& WriteDateTimeSettings(hwndDlg
, SetupData
))
1588 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, IDD_PROCESSPAGE
);
1595 WriteDateTimeSettings(hwndDlg
, SetupData
);
1600 SetupData
->UnattendSetup
= FALSE
;
1610 DestroyTimeZoneList(SetupData
);
1621 static UINT CALLBACK
1622 RegistrationNotificationProc(PVOID Context
,
1627 PREGISTRATIONDATA RegistrationData
;
1628 REGISTRATIONNOTIFY RegistrationNotify
;
1629 PSP_REGISTER_CONTROL_STATUSW StatusInfo
;
1631 WCHAR ErrorMessage
[128];
1633 RegistrationData
= (PREGISTRATIONDATA
) Context
;
1635 if (SPFILENOTIFY_STARTREGISTRATION
== Notification
||
1636 SPFILENOTIFY_ENDREGISTRATION
== Notification
)
1638 StatusInfo
= (PSP_REGISTER_CONTROL_STATUSW
) Param1
;
1639 RegistrationNotify
.CurrentItem
= wcsrchr(StatusInfo
->FileName
, L
'\\');
1640 if (NULL
== RegistrationNotify
.CurrentItem
)
1642 RegistrationNotify
.CurrentItem
= StatusInfo
->FileName
;
1646 RegistrationNotify
.CurrentItem
++;
1649 if (SPFILENOTIFY_STARTREGISTRATION
== Notification
)
1651 DPRINT("Received SPFILENOTIFY_STARTREGISTRATION notification for %S\n",
1652 StatusInfo
->FileName
);
1653 RegistrationNotify
.ErrorMessage
= NULL
;
1654 RegistrationNotify
.Progress
= RegistrationData
->Registered
;
1658 DPRINT("Received SPFILENOTIFY_ENDREGISTRATION notification for %S\n",
1659 StatusInfo
->FileName
);
1660 DPRINT("Win32Error %u FailureCode %u\n", StatusInfo
->Win32Error
,
1661 StatusInfo
->FailureCode
);
1662 if (SPREG_SUCCESS
!= StatusInfo
->FailureCode
)
1664 switch(StatusInfo
->FailureCode
)
1666 case SPREG_LOADLIBRARY
:
1667 MessageID
= IDS_LOADLIBRARY_FAILED
;
1669 case SPREG_GETPROCADDR
:
1670 MessageID
= IDS_GETPROCADDR_FAILED
;
1673 MessageID
= IDS_REGSVR_FAILED
;
1675 case SPREG_DLLINSTALL
:
1676 MessageID
= IDS_DLLINSTALL_FAILED
;
1679 MessageID
= IDS_TIMEOUT
;
1682 MessageID
= IDS_REASON_UNKNOWN
;
1685 if (0 == LoadStringW(hDllInstance
, MessageID
,
1687 sizeof(ErrorMessage
) /
1688 sizeof(ErrorMessage
[0])))
1690 ErrorMessage
[0] = L
'\0';
1692 if (SPREG_TIMEOUT
!= StatusInfo
->FailureCode
)
1694 FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM
, NULL
,
1695 StatusInfo
->Win32Error
, 0,
1696 ErrorMessage
+ wcslen(ErrorMessage
),
1697 sizeof(ErrorMessage
) / sizeof(ErrorMessage
[0]) -
1698 wcslen(ErrorMessage
), NULL
);
1700 RegistrationNotify
.ErrorMessage
= ErrorMessage
;
1704 RegistrationNotify
.ErrorMessage
= NULL
;
1706 if (RegistrationData
->Registered
< RegistrationData
->DllCount
)
1708 RegistrationData
->Registered
++;
1712 RegistrationNotify
.Progress
= RegistrationData
->Registered
;
1713 RegistrationNotify
.ActivityID
= IDS_REGISTERING_COMPONENTS
;
1714 SendMessage(RegistrationData
->hwndDlg
, PM_REGISTRATION_NOTIFY
,
1715 0, (LPARAM
) &RegistrationNotify
);
1721 DPRINT1("Received unexpected notification %u\n", Notification
);
1722 return SetupDefaultQueueCallback(RegistrationData
->DefaultContext
,
1723 Notification
, Param1
, Param2
);
1728 static DWORD CALLBACK
1729 RegistrationProc(LPVOID Parameter
)
1731 PREGISTRATIONDATA RegistrationData
;
1732 REGISTRATIONNOTIFY RegistrationNotify
;
1733 DWORD LastError
= NO_ERROR
;
1734 WCHAR UnknownError
[84];
1736 RegistrationData
= (PREGISTRATIONDATA
) Parameter
;
1737 RegistrationData
->Registered
= 0;
1738 RegistrationData
->DefaultContext
= SetupInitDefaultQueueCallback(RegistrationData
->hwndDlg
);
1742 if (!SetupInstallFromInfSectionW(GetParent(RegistrationData
->hwndDlg
),
1744 L
"RegistrationPhase2",
1746 SPINST_REGISTERCALLBACKAWARE
|
1751 RegistrationNotificationProc
,
1756 LastError
= GetLastError();
1759 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1761 DPRINT("Catching exception\n");
1762 LastError
= RtlNtStatusToDosError(_SEH2_GetExceptionCode());
1766 if (NO_ERROR
== LastError
)
1768 RegistrationNotify
.ErrorMessage
= NULL
;
1772 DPRINT1("SetupInstallFromInfSection failed with error %u\n",
1774 if (0 == FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER
|
1775 FORMAT_MESSAGE_FROM_SYSTEM
, NULL
, LastError
, 0,
1776 (LPWSTR
) &RegistrationNotify
.ErrorMessage
, 0,
1779 if (0 == LoadStringW(hDllInstance
, IDS_UNKNOWN_ERROR
,
1781 sizeof(UnknownError
) / sizeof(UnknownError
[0]) -
1784 wcscpy(UnknownError
, L
"Unknown error");
1786 wcscat(UnknownError
, L
" ");
1787 _ultow(LastError
, UnknownError
+ wcslen(UnknownError
), 10);
1788 RegistrationNotify
.ErrorMessage
= UnknownError
;
1792 RegistrationNotify
.Progress
= RegistrationData
->DllCount
;
1793 RegistrationNotify
.ActivityID
= IDS_REGISTERING_COMPONENTS
;
1794 RegistrationNotify
.CurrentItem
= NULL
;
1795 SendMessage(RegistrationData
->hwndDlg
, PM_REGISTRATION_NOTIFY
,
1796 1, (LPARAM
) &RegistrationNotify
);
1797 if (NULL
!= RegistrationNotify
.ErrorMessage
&&
1798 UnknownError
!= RegistrationNotify
.ErrorMessage
)
1800 LocalFree((PVOID
) RegistrationNotify
.ErrorMessage
);
1803 SetupTermDefaultQueueCallback(RegistrationData
->DefaultContext
);
1804 HeapFree(GetProcessHeap(), 0, RegistrationData
);
1806 RegisterTypeLibraries(hSysSetupInf
, L
"TypeLibraries");
1808 // FIXME: Move this call to a separate cleanup page!
1809 RtlCreateBootStatusDataFile();
1816 StartComponentRegistration(HWND hwndDlg
, PULONG MaxProgress
)
1818 HANDLE RegistrationThread
;
1821 WCHAR SectionName
[512];
1822 PREGISTRATIONDATA RegistrationData
;
1825 if (! SetupFindFirstLineW(hSysSetupInf
, L
"RegistrationPhase2",
1826 L
"RegisterDlls", &Context
))
1828 DPRINT1("No RegistrationPhase2 section found\n");
1831 if (! SetupGetStringFieldW(&Context
, 1, SectionName
,
1832 sizeof(SectionName
) / sizeof(SectionName
[0]),
1835 DPRINT1("Unable to retrieve section name\n");
1838 DllCount
= SetupGetLineCountW(hSysSetupInf
, SectionName
);
1839 DPRINT("SectionName %S DllCount %ld\n", SectionName
, DllCount
);
1842 SetLastError(STATUS_NOT_FOUND
);
1846 *MaxProgress
= (ULONG
) DllCount
;
1849 * Create a background thread to do the actual registrations, so the
1850 * main thread can just run its message loop.
1852 RegistrationThread
= NULL
;
1853 RegistrationData
= HeapAlloc(GetProcessHeap(), 0,
1854 sizeof(REGISTRATIONDATA
));
1855 if (RegistrationData
!= NULL
)
1857 RegistrationData
->hwndDlg
= hwndDlg
;
1858 RegistrationData
->DllCount
= DllCount
;
1859 RegistrationThread
= CreateThread(NULL
, 0, RegistrationProc
,
1860 RegistrationData
, 0, NULL
);
1861 if (RegistrationThread
!= NULL
)
1863 CloseHandle(RegistrationThread
);
1867 DPRINT1("CreateThread failed, error %u\n", GetLastError());
1868 HeapFree(GetProcessHeap(), 0, RegistrationData
);
1874 DPRINT1("HeapAlloc() failed, error %u\n", GetLastError());
1882 static INT_PTR CALLBACK
1883 ProcessPageDlgProc(HWND hwndDlg
,
1888 PSETUPDATA SetupData
;
1889 PREGISTRATIONNOTIFY RegistrationNotify
;
1890 static UINT oldActivityID
= -1;
1893 /* Retrieve pointer to the global setup data */
1894 SetupData
= (PSETUPDATA
)GetWindowLongPtr (hwndDlg
, GWL_USERDATA
);
1900 /* Save pointer to the global setup data */
1901 SetupData
= (PSETUPDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
1902 SetWindowLongPtr(hwndDlg
, GWL_USERDATA
, (DWORD_PTR
)SetupData
);
1908 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
1909 ULONG MaxProgress
= 0;
1914 /* Disable the Back and Next buttons */
1915 PropSheet_SetWizButtons(GetParent(hwndDlg
), 0);
1917 StartComponentRegistration(hwndDlg
, &MaxProgress
);
1919 SendDlgItemMessage(hwndDlg
, IDC_PROCESSPROGRESS
, PBM_SETRANGE
,
1920 0, MAKELPARAM(0, MaxProgress
));
1921 SendDlgItemMessage(hwndDlg
, IDC_PROCESSPROGRESS
, PBM_SETPOS
,
1929 SetupData
->UnattendSetup
= FALSE
;
1938 case PM_REGISTRATION_NOTIFY
:
1941 RegistrationNotify
= (PREGISTRATIONNOTIFY
) lParam
;
1942 // update if necessary only
1943 if (oldActivityID
!= RegistrationNotify
->ActivityID
)
1945 if (0 != LoadStringW(hDllInstance
, RegistrationNotify
->ActivityID
,
1947 sizeof(Activity
) / sizeof(Activity
[0])))
1949 SendDlgItemMessageW(hwndDlg
, IDC_ACTIVITY
, WM_SETTEXT
,
1950 0, (LPARAM
) Activity
);
1952 oldActivityID
= RegistrationNotify
->ActivityID
;
1954 SendDlgItemMessageW(hwndDlg
, IDC_ITEM
, WM_SETTEXT
, 0,
1955 (LPARAM
)(NULL
== RegistrationNotify
->CurrentItem
?
1956 L
"" : RegistrationNotify
->CurrentItem
));
1957 SendDlgItemMessage(hwndDlg
, IDC_PROCESSPROGRESS
, PBM_SETPOS
,
1958 RegistrationNotify
->Progress
, 0);
1959 if (NULL
!= RegistrationNotify
->ErrorMessage
)
1961 if (0 == LoadStringW(hDllInstance
, IDS_REACTOS_SETUP
,
1962 Title
, sizeof(Title
) / sizeof(Title
[0])))
1964 wcscpy(Title
, L
"ReactOS Setup");
1966 MessageBoxW(hwndDlg
, RegistrationNotify
->ErrorMessage
,
1967 Title
, MB_ICONERROR
| MB_OK
);
1974 if(!SetupData
->UnattendSetup
&& !SetupData
->DisableVmwInst
)
1975 RunVMWInstall(GetParent(hwndDlg
));
1978 /* Enable the Back and Next buttons */
1979 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_NEXT
);
1980 PropSheet_PressButton(GetParent(hwndDlg
), PSBTN_NEXT
);
1994 SetInstallationCompleted(VOID
)
1997 DWORD InProgress
= 0;
2000 if (RegOpenKeyExW( HKEY_LOCAL_MACHINE
,
2004 &hKey
) == ERROR_SUCCESS
)
2006 RegSetValueExW( hKey
, L
"SystemSetupInProgress", 0, REG_DWORD
, (LPBYTE
)&InProgress
, sizeof(InProgress
) );
2007 RegCloseKey( hKey
);
2010 if (RegOpenKeyExW( HKEY_LOCAL_MACHINE
,
2011 L
"Software\\Microsoft\\Windows NT\\CurrentVersion",
2014 &hKey
) == ERROR_SUCCESS
)
2016 InstallDate
= (DWORD
)time(NULL
);
2017 RegSetValueExW( hKey
, L
"InstallDate", 0, REG_DWORD
, (LPBYTE
)&InstallDate
, sizeof(InstallDate
) );
2018 RegCloseKey( hKey
);
2022 static INT_PTR CALLBACK
2023 FinishDlgProc(HWND hwndDlg
,
2033 /* Get pointer to the global setup data */
2034 PSETUPDATA SetupData
= (PSETUPDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
2036 if (!SetupData
->UnattendSetup
|| !SetupData
->DisableGeckoInst
)
2038 /* Run the Wine Gecko prompt */
2039 Control_RunDLLW(hwndDlg
, 0, L
"appwiz.cpl install_gecko", SW_SHOW
);
2042 /* Set title font */
2043 SendDlgItemMessage(hwndDlg
,
2046 (WPARAM
)SetupData
->hTitleFont
,
2048 if (SetupData
->UnattendSetup
)
2050 KillTimer(hwndDlg
, 1);
2051 SetInstallationCompleted();
2059 SetInstallationCompleted();
2069 hWndProgress
= GetDlgItem(hwndDlg
, IDC_RESTART_PROGRESS
);
2070 Position
= SendMessage(hWndProgress
, PBM_GETPOS
, 0, 0);
2071 if (Position
== 300)
2073 KillTimer(hwndDlg
, 1);
2074 PropSheet_PressButton(GetParent(hwndDlg
), PSBTN_FINISH
);
2078 SendMessage(hWndProgress
, PBM_SETPOS
, Position
+ 1, 0);
2085 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
2090 /* Enable the correct buttons on for the active page */
2091 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_FINISH
);
2093 SendDlgItemMessage(hwndDlg
, IDC_RESTART_PROGRESS
, PBM_SETRANGE
, 0,
2094 MAKELPARAM(0, 300));
2095 SendDlgItemMessage(hwndDlg
, IDC_RESTART_PROGRESS
, PBM_SETPOS
, 0, 0);
2096 SetTimer(hwndDlg
, 1, 50, NULL
);
2100 DestroyWindow(GetParent(hwndDlg
));
2119 PSETUPDATA pSetupData
)
2121 INFCONTEXT InfContext
;
2123 WCHAR szValue
[MAX_PATH
];
2127 if (!SetupFindFirstLineW(pSetupData
->hUnattendedInf
,
2129 L
"UnattendSetupEnabled",
2132 DPRINT1("Error: Cant find UnattendSetupEnabled Key! %d\n", GetLastError());
2136 if (!SetupGetStringFieldW(&InfContext
,
2139 sizeof(szValue
) / sizeof(WCHAR
),
2142 DPRINT1("Error: SetupGetStringField failed with %d\n", GetLastError());
2146 if (wcscmp(szValue
, L
"yes") != 0)
2148 DPRINT("Unattend setup was disabled by UnattendSetupEnabled key.\n");
2152 pSetupData
->UnattendSetup
= TRUE
;
2154 if (!SetupFindFirstLineW(pSetupData
->hUnattendedInf
,
2159 DPRINT1("Error: SetupFindFirstLine failed %d\n", GetLastError());
2165 if (!SetupGetStringFieldW(&InfContext
,
2168 sizeof(szName
) / sizeof(WCHAR
),
2171 DPRINT1("Error: SetupGetStringField failed with %d\n", GetLastError());
2175 if (!SetupGetStringFieldW(&InfContext
,
2178 sizeof(szValue
) / sizeof(WCHAR
),
2181 DPRINT1("Error: SetupGetStringField failed with %d\n", GetLastError());
2184 DPRINT1("Name %S Value %S\n", szName
, szValue
);
2185 if (!wcscmp(szName
, L
"FullName"))
2187 if ((sizeof(pSetupData
->OwnerName
) / sizeof(TCHAR
)) > LineLength
)
2189 wcscpy(pSetupData
->OwnerName
, szValue
);
2192 else if (!wcscmp(szName
, L
"OrgName"))
2194 if ((sizeof(pSetupData
->OwnerOrganization
) / sizeof(WCHAR
)) > LineLength
)
2196 wcscpy(pSetupData
->OwnerOrganization
, szValue
);
2199 else if (!wcscmp(szName
, L
"ComputerName"))
2201 if ((sizeof(pSetupData
->ComputerName
) / sizeof(WCHAR
)) > LineLength
)
2203 wcscpy(pSetupData
->ComputerName
, szValue
);
2206 else if (!wcscmp(szName
, L
"AdminPassword"))
2208 if ((sizeof(pSetupData
->AdminPassword
) / sizeof(WCHAR
)) > LineLength
)
2210 wcscpy(pSetupData
->AdminPassword
, szValue
);
2213 else if (!wcscmp(szName
, L
"TimeZoneIndex"))
2215 pSetupData
->TimeZoneIndex
= _wtoi(szValue
);
2217 else if (!wcscmp(szName
, L
"DisableAutoDaylightTimeSet"))
2219 pSetupData
->DisableAutoDaylightTimeSet
= _wtoi(szValue
);
2221 else if (!wcscmp(szName
, L
"DisableVmwInst"))
2223 if(!wcscmp(szValue
, L
"yes"))
2224 pSetupData
->DisableVmwInst
= 1;
2226 pSetupData
->DisableVmwInst
= 0;
2228 else if (!wcscmp(szName
, L
"DisableGeckoInst"))
2230 if(!wcscmp(szValue
, L
"yes"))
2231 pSetupData
->DisableGeckoInst
= 1;
2233 pSetupData
->DisableGeckoInst
= 0;
2237 while (SetupFindNextLine(&InfContext
, &InfContext
));
2239 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
2240 L
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunOnce",
2243 &hKey
) != ERROR_SUCCESS
)
2245 DPRINT1("Error: failed to open HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\RunOnce\n");
2249 if (SetupFindFirstLineW(pSetupData
->hUnattendedInf
,
2258 if(SetupGetStringFieldW(&InfContext
,
2261 sizeof(szValue
) / sizeof(WCHAR
),
2264 WCHAR szPath
[MAX_PATH
];
2265 swprintf(szName
, L
"%d", i
);
2266 DPRINT("szName %S szValue %S\n", szName
, szValue
);
2268 if (ExpandEnvironmentStringsW(szValue
, szPath
, MAX_PATH
))
2270 DPRINT("value %S\n", szPath
);
2271 if (RegSetValueExW(hKey
,
2275 (const BYTE
*)szPath
,
2276 (wcslen(szPath
) + 1) * sizeof(WCHAR
)) == ERROR_SUCCESS
)
2282 } while(SetupFindNextLine(&InfContext
, &InfContext
));
2289 * GetRosInstallCD should find the path to ros installation medium
2291 * If there are more than one CDDrive in it containing a ReactOS
2292 * installation cd, then it will pick the first one regardless if
2293 * it is really the installation cd
2295 * The best way to implement this is to set the key
2296 * HKLM\Software\Microsoft\Windows NT\CurrentVersion\SourcePath (REG_SZ)
2300 GetRosInstallCD(WCHAR
*pwszPath
, DWORD cchPathMax
)
2302 WCHAR wszDrives
[512];
2306 cchDrives
= GetLogicalDriveStringsW(_countof(wszDrives
) - 1, wszDrives
);
2307 if (cchDrives
== 0 || cchDrives
>= _countof(wszDrives
))
2309 /* buffer too small or failure */
2310 LogItem(NULL
, L
"GetLogicalDriveStringsW failed");
2314 for (pwszDrive
= wszDrives
; pwszDrive
[0]; pwszDrive
+= wcslen(pwszDrive
) + 1)
2316 if (GetDriveTypeW(pwszDrive
) == DRIVE_CDROM
)
2318 WCHAR wszBuf
[MAX_PATH
];
2319 wsprintf(wszBuf
, L
"%sreactos\\system32\\ntoskrnl.exe", pwszDrive
);
2320 LogItem(NULL
, wszBuf
);
2321 if (GetFileAttributesW(wszBuf
) != INVALID_FILE_ATTRIBUTES
)
2323 /* the file exists, so this is the right drive */
2324 wcsncpy(pwszPath
, pwszDrive
, cchPathMax
);
2325 OutputDebugStringW(L
"GetRosInstallCD: ");OutputDebugStringW(pwszPath
);OutputDebugStringW(L
"\n");
2335 ProcessUnattendSetup(
2336 PSETUPDATA pSetupData
)
2338 WCHAR szPath
[MAX_PATH
];
2341 if (!GetRosInstallCD(szPath
, MAX_PATH
))
2343 /* no cd drive found */
2347 dwLength
= wcslen(szPath
);
2348 if (dwLength
+ 21 > MAX_PATH
)
2351 * allocate bigger buffer
2356 wcscat(szPath
, L
"reactos\\unattend.inf");
2358 pSetupData
->hUnattendedInf
= SetupOpenInfFileW(szPath
,
2362 if (pSetupData
->hUnattendedInf
!= INVALID_HANDLE_VALUE
)
2364 ProcessUnattendInf(pSetupData
);
2372 PROPSHEETHEADER psh
;
2373 HPROPSHEETPAGE ahpsp
[8];
2374 PROPSHEETPAGE psp
= {0};
2378 PSETUPDATA pSetupData
= NULL
;
2380 LogItem(L
"BEGIN_SECTION", L
"InstallWizard");
2382 /* Allocate setup data */
2383 pSetupData
= HeapAlloc(GetProcessHeap(),
2386 if (pSetupData
== NULL
)
2388 LogItem(NULL
, L
"SetupData allocation failed!");
2390 L
"Setup failed to allocate global data!",
2392 MB_ICONERROR
| MB_OK
);
2396 pSetupData
->hUnattendedInf
= INVALID_HANDLE_VALUE
;
2397 ProcessUnattendSetup(pSetupData
);
2399 /* Create the Welcome page */
2400 psp
.dwSize
= sizeof(PROPSHEETPAGE
);
2401 psp
.dwFlags
= PSP_DEFAULT
| PSP_HIDEHEADER
;
2402 psp
.hInstance
= hDllInstance
;
2403 psp
.lParam
= (LPARAM
)pSetupData
;
2404 psp
.pfnDlgProc
= WelcomeDlgProc
;
2405 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_WELCOMEPAGE
);
2406 ahpsp
[nPages
++] = CreatePropertySheetPage(&psp
);
2408 /* Create the Acknowledgements page */
2409 psp
.dwFlags
= PSP_DEFAULT
| PSP_USEHEADERTITLE
| PSP_USEHEADERSUBTITLE
;
2410 psp
.pszHeaderTitle
= MAKEINTRESOURCE(IDS_ACKTITLE
);
2411 psp
.pszHeaderSubTitle
= MAKEINTRESOURCE(IDS_ACKSUBTITLE
);
2412 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_ACKPAGE
);
2413 psp
.pfnDlgProc
= AckPageDlgProc
;
2414 ahpsp
[nPages
++] = CreatePropertySheetPage(&psp
);
2416 /* Create the Locale page */
2417 psp
.dwFlags
= PSP_DEFAULT
| PSP_USEHEADERTITLE
| PSP_USEHEADERSUBTITLE
;
2418 psp
.pszHeaderTitle
= MAKEINTRESOURCE(IDS_LOCALETITLE
);
2419 psp
.pszHeaderSubTitle
= MAKEINTRESOURCE(IDS_LOCALESUBTITLE
);
2420 psp
.pfnDlgProc
= LocalePageDlgProc
;
2421 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_LOCALEPAGE
);
2422 ahpsp
[nPages
++] = CreatePropertySheetPage(&psp
);
2425 /* Create the Owner page */
2426 psp
.dwFlags
= PSP_DEFAULT
| PSP_USEHEADERTITLE
| PSP_USEHEADERSUBTITLE
;
2427 psp
.pszHeaderTitle
= MAKEINTRESOURCE(IDS_OWNERTITLE
);
2428 psp
.pszHeaderSubTitle
= MAKEINTRESOURCE(IDS_OWNERSUBTITLE
);
2429 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_OWNERPAGE
);
2430 psp
.pfnDlgProc
= OwnerPageDlgProc
;
2431 ahpsp
[nPages
++] = CreatePropertySheetPage(&psp
);
2433 /* Create the Computer page */
2434 psp
.dwFlags
= PSP_DEFAULT
| PSP_USEHEADERTITLE
| PSP_USEHEADERSUBTITLE
;
2435 psp
.pszHeaderTitle
= MAKEINTRESOURCE(IDS_COMPUTERTITLE
);
2436 psp
.pszHeaderSubTitle
= MAKEINTRESOURCE(IDS_COMPUTERSUBTITLE
);
2437 psp
.pfnDlgProc
= ComputerPageDlgProc
;
2438 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_COMPUTERPAGE
);
2439 ahpsp
[nPages
++] = CreatePropertySheetPage(&psp
);
2442 /* Create the DateTime page */
2443 psp
.dwFlags
= PSP_DEFAULT
| PSP_USEHEADERTITLE
| PSP_USEHEADERSUBTITLE
;
2444 psp
.pszHeaderTitle
= MAKEINTRESOURCE(IDS_DATETIMETITLE
);
2445 psp
.pszHeaderSubTitle
= MAKEINTRESOURCE(IDS_DATETIMESUBTITLE
);
2446 psp
.pfnDlgProc
= DateTimePageDlgProc
;
2447 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_DATETIMEPAGE
);
2448 ahpsp
[nPages
++] = CreatePropertySheetPage(&psp
);
2451 /* Create the Process page */
2452 psp
.dwFlags
= PSP_DEFAULT
| PSP_USEHEADERTITLE
| PSP_USEHEADERSUBTITLE
;
2453 psp
.pszHeaderTitle
= MAKEINTRESOURCE(IDS_PROCESSTITLE
);
2454 psp
.pszHeaderSubTitle
= MAKEINTRESOURCE(IDS_PROCESSSUBTITLE
);
2455 psp
.pfnDlgProc
= ProcessPageDlgProc
;
2456 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_PROCESSPAGE
);
2457 ahpsp
[nPages
++] = CreatePropertySheetPage(&psp
);
2460 /* Create the Finish page */
2461 psp
.dwFlags
= PSP_DEFAULT
| PSP_HIDEHEADER
;
2462 psp
.pfnDlgProc
= FinishDlgProc
;
2463 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_FINISHPAGE
);
2464 ahpsp
[nPages
++] = CreatePropertySheetPage(&psp
);
2466 /* Create the property sheet */
2467 psh
.dwSize
= sizeof(PROPSHEETHEADER
);
2468 psh
.dwFlags
= PSH_WIZARD97
| PSH_WATERMARK
| PSH_HEADER
| PSH_MODELESS
;
2469 psh
.hInstance
= hDllInstance
;
2470 psh
.hwndParent
= NULL
;
2471 psh
.nPages
= nPages
;
2474 psh
.pszbmWatermark
= MAKEINTRESOURCE(IDB_WATERMARK
);
2475 psh
.pszbmHeader
= MAKEINTRESOURCE(IDB_HEADER
);
2477 /* Create title font */
2478 pSetupData
->hTitleFont
= CreateTitleFont();
2480 /* Display the wizard */
2481 hWnd
= (HWND
)PropertySheet(&psh
);
2482 ShowWindow(hWnd
, SW_SHOW
);
2484 while (GetMessage(&msg
, NULL
, 0, 0))
2486 if (!IsDialogMessage(hWnd
, &msg
))
2488 TranslateMessage(&msg
);
2489 DispatchMessage(&msg
);
2493 if (pSetupData
->hUnattendedInf
!= INVALID_HANDLE_VALUE
)
2494 SetupCloseInfFile(pSetupData
->hUnattendedInf
);
2496 DeleteObject(pSetupData
->hTitleFont
);
2497 HeapFree(GetProcessHeap(), 0, pSetupData
);
2499 LogItem(L
"END_SECTION", L
"InstallWizard");