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>
10 /* INCLUDES *****************************************************************/
24 #define PM_REGISTRATION_NOTIFY (WM_APP + 1)
25 /* Private Message used to communicate progress from the background
26 registration thread to the main thread.
27 wParam = 0 Registration in progress
28 = 1 Registration completed
29 lParam = Pointer to a REGISTRATIONNOTIFY structure */
31 typedef struct _REGISTRATIONNOTIFY
37 } REGISTRATIONNOTIFY
, *PREGISTRATIONNOTIFY
;
39 typedef struct _REGISTRATIONDATA
45 } REGISTRATIONDATA
, *PREGISTRATIONDATA
;
47 /* GLOBALS ******************************************************************/
52 /* FUNCTIONS ****************************************************************/
54 extern void WINAPI
Control_RunDLLW(HWND hWnd
, HINSTANCE hInst
, LPCWSTR cmd
, DWORD nCmdShow
);
57 GetRosInstallCD(WCHAR
*pwszPath
, DWORD cchPathMax
);
61 RunVMWInstall(HWND hWnd
)
63 PROCESS_INFORMATION ProcInfo
;
67 WCHAR InstallName
[] = L
"vmwinst.exe";
69 ZeroMemory(&si
, sizeof(si
));
72 if(CreateProcessW(NULL
, InstallName
, NULL
, NULL
, TRUE
, NORMAL_PRIORITY_CLASS
,
73 NULL
, NULL
, &si
, &ProcInfo
))
75 EnableWindow(hWnd
, FALSE
);
78 while (PeekMessage(&msg
, NULL
, 0, 0, PM_REMOVE
))
80 if (msg
.message
== WM_QUIT
)
82 TranslateMessage(&msg
);
83 DispatchMessage(&msg
);
86 ret
= MsgWaitForMultipleObjects(1, &ProcInfo
.hProcess
, FALSE
, INFINITE
, QS_ALLEVENTS
| QS_ALLINPUT
);
87 if (ret
== WAIT_OBJECT_0
)
91 EnableWindow(hWnd
, TRUE
);
93 CloseHandle(ProcInfo
.hThread
);
94 CloseHandle(ProcInfo
.hProcess
);
102 CenterWindow(HWND hWnd
)
108 hWndParent
= GetParent(hWnd
);
109 if (hWndParent
== NULL
)
110 hWndParent
= GetDesktopWindow();
112 GetWindowRect(hWndParent
, &rcParent
);
113 GetWindowRect(hWnd
, &rcWindow
);
117 ((rcParent
.right
- rcParent
.left
) - (rcWindow
.right
- rcWindow
.left
)) / 2,
118 ((rcParent
.bottom
- rcParent
.top
) - (rcWindow
.bottom
- rcWindow
.top
)) / 2,
126 CreateTitleFont(VOID
)
128 NONCLIENTMETRICSW ncm
;
134 ncm
.cbSize
= sizeof(NONCLIENTMETRICSW
);
135 SystemParametersInfo(SPI_GETNONCLIENTMETRICS
, 0, &ncm
, 0);
137 LogFont
= ncm
.lfMessageFont
;
138 LogFont
.lfWeight
= FW_BOLD
;
139 wcscpy(LogFont
.lfFaceName
, L
"MS Shell Dlg");
143 LogFont
.lfHeight
= 0 - GetDeviceCaps(hdc
, LOGPIXELSY
) * FontSize
/ 72;
144 hFont
= CreateFontIndirectW(&LogFont
);
145 ReleaseDC(NULL
, hdc
);
151 static INT_PTR CALLBACK
152 GplDlgProc(HWND hwndDlg
,
157 HRSRC GplTextResource
;
167 GplTextResource
= FindResourceW(hDllInstance
, MAKEINTRESOURCE(IDR_GPL
), L
"RT_TEXT");
168 if (NULL
== GplTextResource
)
172 Size
= SizeofResource(hDllInstance
, GplTextResource
);
177 GplText
= HeapAlloc(GetProcessHeap(), 0, Size
+ 1);
182 GplTextMem
= LoadResource(hDllInstance
, GplTextResource
);
183 if (NULL
== GplTextMem
)
185 HeapFree(GetProcessHeap(), 0, GplText
);
188 GplTextLocked
= LockResource(GplTextMem
);
189 if (NULL
== GplTextLocked
)
191 HeapFree(GetProcessHeap(), 0, GplText
);
194 memcpy(GplText
, GplTextLocked
, Size
);
195 GplText
[Size
] = '\0';
196 SendMessageA(GetDlgItem(hwndDlg
, IDC_GPL_TEXT
), WM_SETTEXT
, 0, (LPARAM
) GplText
);
197 HeapFree(GetProcessHeap(), 0, GplText
);
198 SetFocus(GetDlgItem(hwndDlg
, IDOK
));
202 EndDialog(hwndDlg
, IDCANCEL
);
206 if (HIWORD(wParam
) == BN_CLICKED
&& IDOK
== LOWORD(wParam
))
208 EndDialog(hwndDlg
, IDOK
);
220 static INT_PTR CALLBACK
221 WelcomeDlgProc(HWND hwndDlg
,
230 PSETUPDATA SetupData
;
234 /* Get pointer to the global setup data */
235 SetupData
= (PSETUPDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
237 hwndControl
= GetParent(hwndDlg
);
239 /* Center the wizard window */
240 CenterWindow (hwndControl
);
242 /* Hide the system menu */
243 dwStyle
= GetWindowLongPtr(hwndControl
, GWL_STYLE
);
244 SetWindowLongPtr(hwndControl
, GWL_STYLE
, dwStyle
& ~WS_SYSMENU
);
246 /* Hide and disable the 'Cancel' button */
247 hwndControl
= GetDlgItem(GetParent(hwndDlg
), IDCANCEL
);
248 ShowWindow (hwndControl
, SW_HIDE
);
249 EnableWindow (hwndControl
, FALSE
);
252 SendDlgItemMessage(hwndDlg
,
255 (WPARAM
)SetupData
->hTitleFont
,
263 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
268 /* Enable the Next button */
269 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_NEXT
);
270 if (SetupData
.UnattendSetup
)
272 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, IDD_ACKPAGE
);
278 SetupData
.UnattendSetup
= FALSE
;
295 static INT_PTR CALLBACK
296 AckPageDlgProc(HWND hwndDlg
,
303 PWCHAR End
, CurrentProject
;
304 INT ProjectsSize
, ProjectsCount
;
314 Projects
= HeapAlloc(GetProcessHeap(), 0, ProjectsSize
* sizeof(WCHAR
));
315 if (NULL
== Projects
)
319 ProjectsCount
= LoadStringW(hDllInstance
, IDS_ACKPROJECTS
, Projects
, ProjectsSize
);
320 if (0 == ProjectsCount
)
322 HeapFree(GetProcessHeap(), 0, Projects
);
325 if (ProjectsCount
< ProjectsSize
- 1)
329 HeapFree(GetProcessHeap(), 0, Projects
);
333 CurrentProject
= Projects
;
334 while (L
'\0' != *CurrentProject
)
336 End
= wcschr(CurrentProject
, L
'\n');
341 (void)ListBox_AddString(GetDlgItem(hwndDlg
, IDC_PROJECTS
), CurrentProject
);
344 CurrentProject
= End
+ 1;
348 CurrentProject
+= wcslen(CurrentProject
);
351 HeapFree(GetProcessHeap(), 0, Projects
);
356 if (HIWORD(wParam
) == BN_CLICKED
&& IDC_VIEWGPL
== LOWORD(wParam
))
358 DialogBox(hDllInstance
, MAKEINTRESOURCE(IDD_GPL
), NULL
, GplDlgProc
);
359 SetForegroundWindow(GetParent(hwndDlg
));
365 lpnm
= (LPNMHDR
)lParam
;
370 /* Enable the Back and Next buttons */
371 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_BACK
| PSWIZB_NEXT
);
372 if (SetupData
.UnattendSetup
)
374 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, IDD_LOCALEPAGE
);
380 SetupData
.UnattendSetup
= FALSE
;
398 WriteOwnerSettings(WCHAR
* OwnerName
,
399 WCHAR
* OwnerOrganization
)
406 res
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
407 L
"Software\\Microsoft\\Windows NT\\CurrentVersion",
412 if (res
!= ERROR_SUCCESS
)
417 res
= RegSetValueExW(hKey
,
422 (wcslen(OwnerName
) + 1) * sizeof(WCHAR
));
424 if (res
!= ERROR_SUCCESS
)
430 res
= RegSetValueExW(hKey
,
431 L
"RegisteredOrganization",
434 (LPBYTE
)OwnerOrganization
,
435 (wcslen(OwnerOrganization
) + 1) * sizeof(WCHAR
));
438 return (res
== ERROR_SUCCESS
);
441 static INT_PTR CALLBACK
442 OwnerPageDlgProc(HWND hwndDlg
,
448 WCHAR OwnerOrganization
[51];
450 WCHAR ErrorName
[256];
457 SendDlgItemMessage(hwndDlg
, IDC_OWNERNAME
, EM_LIMITTEXT
, 50, 0);
458 SendDlgItemMessage(hwndDlg
, IDC_OWNERORGANIZATION
, EM_LIMITTEXT
, 50, 0);
460 /* Set focus to owner name */
461 SetFocus(GetDlgItem(hwndDlg
, IDC_OWNERNAME
));
468 lpnm
= (LPNMHDR
)lParam
;
473 /* Enable the Back and Next buttons */
474 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_BACK
| PSWIZB_NEXT
);
475 if (SetupData
.UnattendSetup
)
477 SendMessage(GetDlgItem(hwndDlg
, IDC_OWNERNAME
), WM_SETTEXT
, 0, (LPARAM
)SetupData
.OwnerName
);
478 SendMessage(GetDlgItem(hwndDlg
, IDC_OWNERORGANIZATION
), WM_SETTEXT
, 0, (LPARAM
)SetupData
.OwnerOrganization
);
479 if (WriteOwnerSettings(SetupData
.OwnerName
, SetupData
.OwnerOrganization
))
481 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, IDD_COMPUTERPAGE
);
489 if (GetDlgItemTextW(hwndDlg
, IDC_OWNERNAME
, OwnerName
, 50) == 0)
491 if (0 == LoadStringW(hDllInstance
, IDS_REACTOS_SETUP
, Title
, sizeof(Title
) / sizeof(Title
[0])))
493 wcscpy(Title
, L
"ReactOS Setup");
495 if (0 == LoadStringW(hDllInstance
, IDS_WZD_NAME
, ErrorName
, sizeof(ErrorName
) / sizeof(ErrorName
[0])))
497 wcscpy(ErrorName
, L
"Setup cannot continue until you enter your name.");
499 MessageBoxW(hwndDlg
, ErrorName
, Title
, MB_ICONERROR
| MB_OK
);
501 SetFocus(GetDlgItem(hwndDlg
, IDC_OWNERNAME
));
502 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, -1);
507 OwnerOrganization
[0] = 0;
508 GetDlgItemTextW(hwndDlg
, IDC_OWNERORGANIZATION
, OwnerOrganization
, 50);
510 if (!WriteOwnerSettings(OwnerName
, OwnerOrganization
))
512 SetFocus(GetDlgItem(hwndDlg
, IDC_OWNERNAME
));
513 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, -1);
518 SetupData
.UnattendSetup
= FALSE
;
536 WriteComputerSettings(WCHAR
* ComputerName
, HWND hwndDlg
)
539 WCHAR ErrorComputerName
[256];
541 if (!SetComputerNameW(ComputerName
))
545 if (0 == LoadStringW(hDllInstance
, IDS_REACTOS_SETUP
, Title
, sizeof(Title
) / sizeof(Title
[0])))
547 wcscpy(Title
, L
"ReactOS Setup");
549 if (0 == LoadStringW(hDllInstance
, IDS_WZD_SETCOMPUTERNAME
, ErrorComputerName
,
550 sizeof(ErrorComputerName
) / sizeof(ErrorComputerName
[0])))
552 wcscpy(ErrorComputerName
, L
"Setup failed to set the computer name.");
554 MessageBoxW(hwndDlg
, ErrorComputerName
, Title
, MB_ICONERROR
| MB_OK
);
560 /* Try to also set DNS hostname */
561 SetComputerNameExW(ComputerNamePhysicalDnsHostname
, ComputerName
);
563 /* Set the account domain name */
564 SetAccountDomain(ComputerName
, NULL
);
572 WriteDefaultLogonData(LPWSTR Domain
)
574 WCHAR szAdministratorName
[256];
578 if (LoadStringW(hDllInstance
,
579 IDS_ADMINISTRATOR_NAME
,
581 sizeof(szAdministratorName
) / sizeof(WCHAR
)) == 0)
583 wcscpy(szAdministratorName
, L
"Administrator");
586 lError
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
587 L
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon",
591 if (lError
!= ERROR_SUCCESS
)
594 lError
= RegSetValueEx(hKey
,
599 (wcslen(Domain
)+ 1) * sizeof(WCHAR
));
600 if (lError
!= ERROR_SUCCESS
)
602 DPRINT1("RegSetValueEx(\"DefaultDomain\") failed!\n");
605 lError
= RegSetValueEx(hKey
,
609 (LPBYTE
)szAdministratorName
,
610 (wcslen(szAdministratorName
)+ 1) * sizeof(WCHAR
));
611 if (lError
!= ERROR_SUCCESS
)
613 DPRINT1("RegSetValueEx(\"DefaultUserName\") failed!\n");
622 /* lpBuffer will be filled with a 15-char string (plus the null terminator) */
624 GenerateComputerName(LPWSTR lpBuffer
)
626 static const WCHAR Chars
[] = L
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
627 static const unsigned cChars
= sizeof(Chars
) / sizeof(WCHAR
) - 1;
630 wcscpy(lpBuffer
, L
"REACTOS-");
632 srand(GetTickCount());
634 /* fill in 7 characters */
635 for (i
= 8; i
< 15; i
++)
636 lpBuffer
[i
] = Chars
[rand() % cChars
];
638 lpBuffer
[15] = UNICODE_NULL
; /* NULL-terminate */
641 static INT_PTR CALLBACK
642 ComputerPageDlgProc(HWND hwndDlg
,
647 WCHAR ComputerName
[MAX_COMPUTERNAME_LENGTH
+ 1];
648 WCHAR Password1
[128];
649 WCHAR Password2
[128];
652 WCHAR EmptyComputerName
[256], NotMatchPassword
[256], WrongPassword
[256];
655 if (0 == LoadStringW(hDllInstance
, IDS_REACTOS_SETUP
, Title
, sizeof(Title
) / sizeof(Title
[0])))
657 wcscpy(Title
, L
"ReactOS Setup");
663 /* Generate a new pseudo-random computer name */
664 GenerateComputerName(ComputerName
);
666 /* Display current computer name */
667 SetDlgItemTextW(hwndDlg
, IDC_COMPUTERNAME
, ComputerName
);
669 /* Set text limits */
670 SendDlgItemMessage(hwndDlg
, IDC_COMPUTERNAME
, EM_LIMITTEXT
, MAX_COMPUTERNAME_LENGTH
, 0);
671 SendDlgItemMessage(hwndDlg
, IDC_ADMINPASSWORD1
, EM_LIMITTEXT
, 127, 0);
672 SendDlgItemMessage(hwndDlg
, IDC_ADMINPASSWORD2
, EM_LIMITTEXT
, 127, 0);
674 /* Set focus to computer name */
675 SetFocus(GetDlgItem(hwndDlg
, IDC_COMPUTERNAME
));
676 if (SetupData
.UnattendSetup
)
678 SendMessage(GetDlgItem(hwndDlg
, IDC_COMPUTERNAME
), WM_SETTEXT
, 0, (LPARAM
)SetupData
.ComputerName
);
679 SendMessage(GetDlgItem(hwndDlg
, IDC_ADMINPASSWORD1
), WM_SETTEXT
, 0, (LPARAM
)SetupData
.AdminPassword
);
680 SendMessage(GetDlgItem(hwndDlg
, IDC_ADMINPASSWORD2
), WM_SETTEXT
, 0, (LPARAM
)SetupData
.AdminPassword
);
681 WriteComputerSettings(SetupData
.ComputerName
, NULL
);
682 SetAdministratorPassword(SetupData
.AdminPassword
);
685 /* Store the administrator account name as the default user name */
686 WriteDefaultLogonData(SetupData
.ComputerName
);
692 lpnm
= (LPNMHDR
)lParam
;
697 /* Enable the Back and Next buttons */
698 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_BACK
| PSWIZB_NEXT
);
699 if (SetupData
.UnattendSetup
&& WriteComputerSettings(SetupData
.ComputerName
, hwndDlg
))
701 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, IDD_DATETIMEPAGE
);
707 if (0 == GetDlgItemTextW(hwndDlg
, IDC_COMPUTERNAME
, ComputerName
, MAX_COMPUTERNAME_LENGTH
+ 1))
709 if (0 == LoadStringW(hDllInstance
, IDS_WZD_COMPUTERNAME
, EmptyComputerName
,
710 sizeof(EmptyComputerName
) / sizeof(EmptyComputerName
[0])))
712 wcscpy(EmptyComputerName
, L
"Setup cannot continue until you enter the name of your computer.");
714 MessageBoxW(hwndDlg
, EmptyComputerName
, Title
, MB_ICONERROR
| MB_OK
);
715 SetFocus(GetDlgItem(hwndDlg
, IDC_COMPUTERNAME
));
716 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, -1);
720 /* No need to check computer name for invalid characters,
721 * SetComputerName() will do it for us */
723 if (!WriteComputerSettings(ComputerName
, hwndDlg
))
725 SetFocus(GetDlgItem(hwndDlg
, IDC_COMPUTERNAME
));
726 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, -1);
731 /* Check if admin passwords have been entered */
732 if ((GetDlgItemText(hwndDlg
, IDC_ADMINPASSWORD1
, Password1
, 128) == 0) ||
733 (GetDlgItemText(hwndDlg
, IDC_ADMINPASSWORD2
, Password2
, 128) == 0))
735 if (0 == LoadStringW(hDllInstance
, IDS_WZD_PASSWORDEMPTY
, EmptyPassword
,
736 sizeof(EmptyPassword
) / sizeof(EmptyPassword
[0])))
738 wcscpy(EmptyPassword
, L
"You must enter a password !");
740 MessageBoxW(hwndDlg
, EmptyPassword
, Title
, MB_ICONERROR
| MB_OK
);
741 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, -1);
745 GetDlgItemTextW(hwndDlg
, IDC_ADMINPASSWORD1
, Password1
, 128);
746 GetDlgItemTextW(hwndDlg
, IDC_ADMINPASSWORD2
, Password2
, 128);
748 /* Check if passwords match */
749 if (wcscmp(Password1
, Password2
))
751 if (0 == LoadStringW(hDllInstance
, IDS_WZD_PASSWORDMATCH
, NotMatchPassword
,
752 sizeof(NotMatchPassword
) / sizeof(NotMatchPassword
[0])))
754 wcscpy(NotMatchPassword
, L
"The passwords you entered do not match. Please enter the desired password again.");
756 MessageBoxW(hwndDlg
, NotMatchPassword
, Title
, MB_ICONERROR
| MB_OK
);
757 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, -1);
761 /* Check password for invalid characters */
762 Password
= (PWCHAR
)Password1
;
765 if (!isprint(*Password
))
767 if (0 == LoadStringW(hDllInstance
, IDS_WZD_PASSWORDCHAR
, WrongPassword
,
768 sizeof(WrongPassword
) / sizeof(WrongPassword
[0])))
770 wcscpy(WrongPassword
, L
"The password you entered contains invalid characters. Please enter a cleaned password.");
772 MessageBoxW(hwndDlg
, WrongPassword
, Title
, MB_ICONERROR
| MB_OK
);
773 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, -1);
779 /* Set admin password */
780 SetAdministratorPassword(Password1
);
784 SetupData
.UnattendSetup
= FALSE
;
802 SetKeyboardLayoutName(HWND hwnd
)
805 TCHAR szLayoutPath
[256];
806 TCHAR szLocaleName
[32];
810 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE
,
811 _T("SYSTEM\\CurrentControlSet\\Control\\NLS\\Locale"),
817 dwValueSize
= 16 * sizeof(TCHAR
);
818 if (RegQueryValueEx(hKey
,
829 _tcscpy(szLayoutPath
,
830 _T("SYSTEM\\CurrentControlSet\\Control\\Keyboard Layouts\\"));
831 _tcscat(szLayoutPath
,
834 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE
,
841 dwValueSize
= 32 * sizeof(TCHAR
);
842 if (RegQueryValueEx(hKey
,
859 RunControlPanelApplet(HWND hwnd
, PCWSTR pwszCPLParameters
)
862 if (pwszCPLParameters
)
864 STARTUPINFOW StartupInfo
;
865 PROCESS_INFORMATION ProcessInformation
;
866 WCHAR CmdLine
[MAX_PATH
] = L
"rundll32.exe shell32.dll,Control_RunDLL ";
868 ZeroMemory(&StartupInfo
, sizeof(StartupInfo
));
869 StartupInfo
.cb
= sizeof(StartupInfo
);
871 ASSERT(_countof(CmdLine
) > wcslen(CmdLine
) + wcslen(pwszCPLParameters
));
872 wcscat(CmdLine
, pwszCPLParameters
);
874 if (!CreateProcessW(NULL
,
883 &ProcessInformation
))
885 MessageBoxW(hwnd
, L
"Error: Failed to launch the Control Panel Applet.", NULL
, MB_ICONERROR
);
889 while((MsgWaitForMultipleObjects(1, ProcessInformation
.hProcess
, FALSE
, INFINITE
, QS_ALLINPUT
|QS_ALLPOSTMESSAGE
)) != WAIT_OBJECT_0
)
891 while(PeekMessage(&msg
, NULL
, 0, 0, PM_REMOVE
))
893 TranslateMessage(&msg
);
894 DispatchMessage(&msg
);
897 CloseHandle(ProcessInformation
.hThread
);
898 CloseHandle(ProcessInformation
.hProcess
);
903 MessageBoxW(hwnd
, L
"Error: Failed to launch the Control Panel Applet.", NULL
, MB_ICONERROR
);
909 WriteUserLocale(VOID
)
915 lcid
= GetSystemDefaultLCID();
917 if (GetLocaleInfoW(MAKELCID(lcid
, SORT_DEFAULT
), LOCALE_ILANGUAGE
, Locale
, sizeof(Locale
) / sizeof(Locale
[0])) != 0)
919 if (RegCreateKeyExW(HKEY_CURRENT_USER
, L
"Control Panel\\International",
920 0, NULL
, REG_OPTION_NON_VOLATILE
,
921 KEY_WRITE
, NULL
, &hKey
, NULL
) == ERROR_SUCCESS
)
923 RegSetValueExW(hKey
, L
"Locale", 0, REG_SZ
, (LPBYTE
)Locale
, (wcslen(Locale
) + 1) * sizeof(WCHAR
));
929 static INT_PTR CALLBACK
930 LocalePageDlgProc(HWND hwndDlg
,
935 PSETUPDATA SetupData
;
937 /* Retrieve pointer to the global setup data */
938 SetupData
= (PSETUPDATA
)GetWindowLongPtr (hwndDlg
, GWL_USERDATA
);
944 /* Save pointer to the global setup data */
945 SetupData
= (PSETUPDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
946 SetWindowLongPtr(hwndDlg
, GWL_USERDATA
, (DWORD_PTR
)SetupData
);
949 SetKeyboardLayoutName(GetDlgItem(hwndDlg
, IDC_LAYOUTTEXT
));
954 if (HIWORD(wParam
) == BN_CLICKED
)
956 switch (LOWORD(wParam
))
958 case IDC_CUSTOMLOCALE
:
959 RunControlPanelApplet(hwndDlg
, L
"intl.cpl,,5");
960 /* FIXME: Update input locale name */
963 case IDC_CUSTOMLAYOUT
:
964 RunControlPanelApplet(hwndDlg
, L
"input.dll,@1");
972 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
977 /* Enable the Back and Next buttons */
978 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_BACK
| PSWIZB_NEXT
);
979 if (SetupData
->UnattendSetup
)
981 WCHAR wszPath
[MAX_PATH
];
982 if (GetRosInstallCD(wszPath
, _countof(wszPath
)))
984 WCHAR wszParams
[1024];
985 swprintf(wszParams
, L
"intl.cpl,,/f:\"%sreactos\\unattend.inf\"", wszPath
);
986 RunControlPanelApplet(hwndDlg
, wszParams
);
990 RunControlPanelApplet(hwndDlg
, L
"intl.cpl,,/f:\"unattend.inf\"");
993 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, IDD_OWNERPAGE
);
1002 SetupData
->UnattendSetup
= FALSE
;
1019 static PTIMEZONE_ENTRY
1020 GetLargerTimeZoneEntry(PSETUPDATA SetupData
, DWORD Index
)
1022 PTIMEZONE_ENTRY Entry
;
1024 Entry
= SetupData
->TimeZoneListHead
;
1025 while (Entry
!= NULL
)
1027 if (Entry
->Index
>= Index
)
1030 Entry
= Entry
->Next
;
1038 CreateTimeZoneList(PSETUPDATA SetupData
)
1040 WCHAR szKeyName
[256];
1048 PTIMEZONE_ENTRY Entry
;
1049 PTIMEZONE_ENTRY Current
;
1051 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
1052 L
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones",
1061 dwNameSize
= 256 * sizeof(WCHAR
);
1062 lError
= RegEnumKeyExW(hZonesKey
,
1070 if (lError
!= ERROR_SUCCESS
&& lError
!= ERROR_MORE_DATA
)
1073 if (RegOpenKeyExW(hZonesKey
,
1080 Entry
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(TIMEZONE_ENTRY
));
1083 RegCloseKey(hZoneKey
);
1087 dwValueSize
= 64 * sizeof(WCHAR
);
1088 if (RegQueryValueExW(hZoneKey
,
1092 (LPBYTE
)&Entry
->Description
,
1095 RegCloseKey(hZoneKey
);
1099 dwValueSize
= 32 * sizeof(WCHAR
);
1100 if (RegQueryValueExW(hZoneKey
,
1104 (LPBYTE
)&Entry
->StandardName
,
1107 RegCloseKey(hZoneKey
);
1111 dwValueSize
= 32 * sizeof(WCHAR
);
1112 if (RegQueryValueExW(hZoneKey
,
1116 (LPBYTE
)&Entry
->DaylightName
,
1119 RegCloseKey(hZoneKey
);
1123 dwValueSize
= sizeof(DWORD
);
1124 if (RegQueryValueExW(hZoneKey
,
1128 (LPBYTE
)&Entry
->Index
,
1131 RegCloseKey(hZoneKey
);
1135 dwValueSize
= sizeof(TZ_INFO
);
1136 if (RegQueryValueExW(hZoneKey
,
1140 (LPBYTE
)&Entry
->TimezoneInfo
,
1143 RegCloseKey(hZoneKey
);
1147 RegCloseKey(hZoneKey
);
1149 if (SetupData
->TimeZoneListHead
== NULL
&&
1150 SetupData
->TimeZoneListTail
== NULL
)
1154 SetupData
->TimeZoneListHead
= Entry
;
1155 SetupData
->TimeZoneListTail
= Entry
;
1159 Current
= GetLargerTimeZoneEntry(SetupData
, Entry
->Index
);
1160 if (Current
!= NULL
)
1162 if (Current
== SetupData
->TimeZoneListHead
)
1164 /* Prepend to head */
1166 Entry
->Next
= SetupData
->TimeZoneListHead
;
1167 SetupData
->TimeZoneListHead
->Prev
= Entry
;
1168 SetupData
->TimeZoneListHead
= Entry
;
1172 /* Insert before current */
1173 Entry
->Prev
= Current
->Prev
;
1174 Entry
->Next
= Current
;
1175 Current
->Prev
->Next
= Entry
;
1176 Current
->Prev
= Entry
;
1181 /* Append to tail */
1182 Entry
->Prev
= SetupData
->TimeZoneListTail
;
1184 SetupData
->TimeZoneListTail
->Next
= Entry
;
1185 SetupData
->TimeZoneListTail
= Entry
;
1192 RegCloseKey(hZonesKey
);
1197 DestroyTimeZoneList(PSETUPDATA SetupData
)
1199 PTIMEZONE_ENTRY Entry
;
1201 while (SetupData
->TimeZoneListHead
!= NULL
)
1203 Entry
= SetupData
->TimeZoneListHead
;
1205 SetupData
->TimeZoneListHead
= Entry
->Next
;
1206 if (SetupData
->TimeZoneListHead
!= NULL
)
1208 SetupData
->TimeZoneListHead
->Prev
= NULL
;
1211 HeapFree(GetProcessHeap(), 0, Entry
);
1214 SetupData
->TimeZoneListTail
= NULL
;
1218 GetTimeZoneListIndex(LPDWORD lpIndex
)
1220 WCHAR szLanguageIdString
[9];
1227 BOOL bFound
= FALSE
;
1228 unsigned long iLanguageID
;
1232 *lpIndex
= 85; /* fallback to GMT time zone */
1234 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
1235 L
"SYSTEM\\CurrentControlSet\\Control\\NLS\\Language",
1241 dwValueSize
= 9 * sizeof(WCHAR
);
1242 if (RegQueryValueExW(hKey
,
1246 (LPBYTE
)szLanguageIdString
,
1253 iLanguageID
= wcstoul(szLanguageIdString
, NULL
, 16);
1258 iLanguageID
= *lpIndex
;
1261 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
1262 L
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones",
1269 if (RegQueryValueExW(hKey
,
1280 Buffer
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, dwValueSize
);
1287 if (RegQueryValueExW(hKey
,
1294 HeapFree(GetProcessHeap(), 0, Buffer
);
1304 Length
= wcslen(Ptr
);
1305 if (wcstoul(Ptr
, NULL
, 16) == iLanguageID
)
1308 Ptr
= Ptr
+ Length
+ 1;
1314 *lpIndex
= wcstoul(Ptr
, &End
, 10);
1315 HeapFree(GetProcessHeap(), 0, Buffer
);
1319 Length
= wcslen(Ptr
);
1320 Ptr
= Ptr
+ Length
+ 1;
1323 HeapFree(GetProcessHeap(), 0, Buffer
);
1330 ShowTimeZoneList(HWND hwnd
, PSETUPDATA SetupData
, DWORD dwEntryIndex
)
1332 PTIMEZONE_ENTRY Entry
;
1336 GetTimeZoneListIndex(&dwEntryIndex
);
1338 Entry
= SetupData
->TimeZoneListHead
;
1339 while (Entry
!= NULL
)
1341 dwCount
= SendMessage(hwnd
,
1344 (LPARAM
)Entry
->Description
);
1346 if (dwEntryIndex
!= 0 && dwEntryIndex
== Entry
->Index
)
1349 Entry
= Entry
->Next
;
1360 SetLocalTimeZone(HWND hwnd
, PSETUPDATA SetupData
)
1362 TIME_ZONE_INFORMATION TimeZoneInformation
;
1363 PTIMEZONE_ENTRY Entry
;
1367 dwIndex
= SendMessage(hwnd
,
1373 Entry
= SetupData
->TimeZoneListHead
;
1380 Entry
= Entry
->Next
;
1383 wcscpy(TimeZoneInformation
.StandardName
,
1384 Entry
->StandardName
);
1385 wcscpy(TimeZoneInformation
.DaylightName
,
1386 Entry
->DaylightName
);
1388 TimeZoneInformation
.Bias
= Entry
->TimezoneInfo
.Bias
;
1389 TimeZoneInformation
.StandardBias
= Entry
->TimezoneInfo
.StandardBias
;
1390 TimeZoneInformation
.DaylightBias
= Entry
->TimezoneInfo
.DaylightBias
;
1392 memcpy(&TimeZoneInformation
.StandardDate
,
1393 &Entry
->TimezoneInfo
.StandardDate
,
1394 sizeof(SYSTEMTIME
));
1395 memcpy(&TimeZoneInformation
.DaylightDate
,
1396 &Entry
->TimezoneInfo
.DaylightDate
,
1397 sizeof(SYSTEMTIME
));
1399 /* Set time zone information */
1400 SetTimeZoneInformation(&TimeZoneInformation
);
1405 GetLocalSystemTime(HWND hwnd
, PSETUPDATA SetupData
)
1410 if (DateTime_GetSystemtime(GetDlgItem(hwnd
, IDC_DATEPICKER
), &Date
) != GDT_VALID
)
1415 if (DateTime_GetSystemtime(GetDlgItem(hwnd
, IDC_TIMEPICKER
), &Time
) != GDT_VALID
)
1420 SetupData
->SystemTime
.wYear
= Date
.wYear
;
1421 SetupData
->SystemTime
.wMonth
= Date
.wMonth
;
1422 SetupData
->SystemTime
.wDayOfWeek
= Date
.wDayOfWeek
;
1423 SetupData
->SystemTime
.wDay
= Date
.wDay
;
1424 SetupData
->SystemTime
.wHour
= Time
.wHour
;
1425 SetupData
->SystemTime
.wMinute
= Time
.wMinute
;
1426 SetupData
->SystemTime
.wSecond
= Time
.wSecond
;
1427 SetupData
->SystemTime
.wMilliseconds
= Time
.wMilliseconds
;
1434 SetAutoDaylightInfo(HWND hwnd
)
1439 if (SendMessage(hwnd
, BM_GETCHECK
, 0, 0) == BST_UNCHECKED
)
1441 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
1442 L
"SYSTEM\\CurrentControlSet\\Control\\TimeZoneInformation",
1448 RegSetValueExW(hKey
,
1449 L
"DisableAutoDaylightTimeSet",
1460 SetSystemLocalTime(HWND hwnd
, PSETUPDATA SetupData
)
1465 * Call SetLocalTime twice to ensure correct results
1467 Ret
= SetLocalTime(&SetupData
->SystemTime
) &&
1468 SetLocalTime(&SetupData
->SystemTime
);
1474 WriteDateTimeSettings(HWND hwndDlg
, PSETUPDATA SetupData
)
1477 WCHAR ErrorLocalTime
[256];
1478 GetLocalSystemTime(hwndDlg
, SetupData
);
1479 SetLocalTimeZone(GetDlgItem(hwndDlg
, IDC_TIMEZONELIST
),
1482 SetAutoDaylightInfo(GetDlgItem(hwndDlg
, IDC_AUTODAYLIGHT
));
1483 if(!SetSystemLocalTime(hwndDlg
, SetupData
))
1485 if (0 == LoadStringW(hDllInstance
, IDS_REACTOS_SETUP
, Title
, sizeof(Title
) / sizeof(Title
[0])))
1487 wcscpy(Title
, L
"ReactOS Setup");
1489 if (0 == LoadStringW(hDllInstance
, IDS_WZD_LOCALTIME
, ErrorLocalTime
,
1490 sizeof(ErrorLocalTime
) / sizeof(ErrorLocalTime
[0])))
1492 wcscpy(ErrorLocalTime
, L
"Setup was unable to set the local time.");
1494 MessageBoxW(hwndDlg
, ErrorLocalTime
, Title
, MB_ICONWARNING
| MB_OK
);
1501 static INT_PTR CALLBACK
1502 DateTimePageDlgProc(HWND hwndDlg
,
1507 PSETUPDATA SetupData
;
1509 /* Retrieve pointer to the global setup data */
1510 SetupData
= (PSETUPDATA
)GetWindowLongPtr (hwndDlg
, GWL_USERDATA
);
1516 /* Save pointer to the global setup data */
1517 SetupData
= (PSETUPDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
1518 SetWindowLongPtr(hwndDlg
, GWL_USERDATA
, (DWORD_PTR
)SetupData
);
1520 CreateTimeZoneList(SetupData
);
1522 if (SetupData
->UnattendSetup
)
1524 ShowTimeZoneList(GetDlgItem(hwndDlg
, IDC_TIMEZONELIST
),
1525 SetupData
, SetupData
->TimeZoneIndex
);
1527 if (!SetupData
->DisableAutoDaylightTimeSet
)
1529 SendDlgItemMessage(hwndDlg
, IDC_AUTODAYLIGHT
, BM_SETCHECK
, (WPARAM
)BST_CHECKED
, 0);
1534 ShowTimeZoneList(GetDlgItem(hwndDlg
, IDC_TIMEZONELIST
),
1537 SendDlgItemMessage(hwndDlg
, IDC_AUTODAYLIGHT
, BM_SETCHECK
, (WPARAM
)BST_CHECKED
, 0);
1546 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
1551 /* Enable the Back and Next buttons */
1552 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_BACK
| PSWIZB_NEXT
);
1553 if (SetupData
->UnattendSetup
&& WriteDateTimeSettings(hwndDlg
, SetupData
))
1555 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, IDD_PROCESSPAGE
);
1562 WriteDateTimeSettings(hwndDlg
, SetupData
);
1567 SetupData
->UnattendSetup
= FALSE
;
1577 DestroyTimeZoneList(SetupData
);
1588 static UINT CALLBACK
1589 RegistrationNotificationProc(PVOID Context
,
1594 PREGISTRATIONDATA RegistrationData
;
1595 REGISTRATIONNOTIFY RegistrationNotify
;
1596 PSP_REGISTER_CONTROL_STATUSW StatusInfo
;
1598 WCHAR ErrorMessage
[128];
1600 RegistrationData
= (PREGISTRATIONDATA
) Context
;
1602 if (SPFILENOTIFY_STARTREGISTRATION
== Notification
||
1603 SPFILENOTIFY_ENDREGISTRATION
== Notification
)
1605 StatusInfo
= (PSP_REGISTER_CONTROL_STATUSW
) Param1
;
1606 RegistrationNotify
.CurrentItem
= wcsrchr(StatusInfo
->FileName
, L
'\\');
1607 if (NULL
== RegistrationNotify
.CurrentItem
)
1609 RegistrationNotify
.CurrentItem
= StatusInfo
->FileName
;
1613 RegistrationNotify
.CurrentItem
++;
1616 if (SPFILENOTIFY_STARTREGISTRATION
== Notification
)
1618 DPRINT("Received SPFILENOTIFY_STARTREGISTRATION notification for %S\n",
1619 StatusInfo
->FileName
);
1620 RegistrationNotify
.ErrorMessage
= NULL
;
1621 RegistrationNotify
.Progress
= RegistrationData
->Registered
;
1625 DPRINT("Received SPFILENOTIFY_ENDREGISTRATION notification for %S\n",
1626 StatusInfo
->FileName
);
1627 DPRINT("Win32Error %u FailureCode %u\n", StatusInfo
->Win32Error
,
1628 StatusInfo
->FailureCode
);
1629 if (SPREG_SUCCESS
!= StatusInfo
->FailureCode
)
1631 switch(StatusInfo
->FailureCode
)
1633 case SPREG_LOADLIBRARY
:
1634 MessageID
= IDS_LOADLIBRARY_FAILED
;
1636 case SPREG_GETPROCADDR
:
1637 MessageID
= IDS_GETPROCADDR_FAILED
;
1640 MessageID
= IDS_REGSVR_FAILED
;
1642 case SPREG_DLLINSTALL
:
1643 MessageID
= IDS_DLLINSTALL_FAILED
;
1646 MessageID
= IDS_TIMEOUT
;
1649 MessageID
= IDS_REASON_UNKNOWN
;
1652 if (0 == LoadStringW(hDllInstance
, MessageID
,
1654 sizeof(ErrorMessage
) /
1655 sizeof(ErrorMessage
[0])))
1657 ErrorMessage
[0] = L
'\0';
1659 if (SPREG_TIMEOUT
!= StatusInfo
->FailureCode
)
1661 FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM
, NULL
,
1662 StatusInfo
->Win32Error
, 0,
1663 ErrorMessage
+ wcslen(ErrorMessage
),
1664 sizeof(ErrorMessage
) / sizeof(ErrorMessage
[0]) -
1665 wcslen(ErrorMessage
), NULL
);
1667 RegistrationNotify
.ErrorMessage
= ErrorMessage
;
1671 RegistrationNotify
.ErrorMessage
= NULL
;
1673 if (RegistrationData
->Registered
< RegistrationData
->DllCount
)
1675 RegistrationData
->Registered
++;
1679 RegistrationNotify
.Progress
= RegistrationData
->Registered
;
1680 RegistrationNotify
.ActivityID
= IDS_REGISTERING_COMPONENTS
;
1681 SendMessage(RegistrationData
->hwndDlg
, PM_REGISTRATION_NOTIFY
,
1682 0, (LPARAM
) &RegistrationNotify
);
1688 DPRINT1("Received unexpected notification %u\n", Notification
);
1689 return SetupDefaultQueueCallback(RegistrationData
->DefaultContext
,
1690 Notification
, Param1
, Param2
);
1695 static DWORD CALLBACK
1696 RegistrationProc(LPVOID Parameter
)
1698 PREGISTRATIONDATA RegistrationData
;
1699 REGISTRATIONNOTIFY RegistrationNotify
;
1700 DWORD LastError
= NO_ERROR
;
1701 WCHAR UnknownError
[84];
1703 RegistrationData
= (PREGISTRATIONDATA
) Parameter
;
1704 RegistrationData
->Registered
= 0;
1705 RegistrationData
->DefaultContext
= SetupInitDefaultQueueCallback(RegistrationData
->hwndDlg
);
1709 if (!SetupInstallFromInfSectionW(GetParent(RegistrationData
->hwndDlg
),
1711 L
"RegistrationPhase2",
1713 SPINST_REGISTERCALLBACKAWARE
|
1718 RegistrationNotificationProc
,
1723 LastError
= GetLastError();
1726 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1728 DPRINT("Catching exception\n");
1729 LastError
= RtlNtStatusToDosError(_SEH2_GetExceptionCode());
1733 if (NO_ERROR
== LastError
)
1735 RegistrationNotify
.ErrorMessage
= NULL
;
1739 DPRINT1("SetupInstallFromInfSection failed with error %u\n",
1741 if (0 == FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER
|
1742 FORMAT_MESSAGE_FROM_SYSTEM
, NULL
, LastError
, 0,
1743 (LPWSTR
) &RegistrationNotify
.ErrorMessage
, 0,
1746 if (0 == LoadStringW(hDllInstance
, IDS_UNKNOWN_ERROR
,
1748 sizeof(UnknownError
) / sizeof(UnknownError
[0]) -
1751 wcscpy(UnknownError
, L
"Unknown error");
1753 wcscat(UnknownError
, L
" ");
1754 _ultow(LastError
, UnknownError
+ wcslen(UnknownError
), 10);
1755 RegistrationNotify
.ErrorMessage
= UnknownError
;
1759 RegistrationNotify
.Progress
= RegistrationData
->DllCount
;
1760 RegistrationNotify
.ActivityID
= IDS_REGISTERING_COMPONENTS
;
1761 RegistrationNotify
.CurrentItem
= NULL
;
1762 SendMessage(RegistrationData
->hwndDlg
, PM_REGISTRATION_NOTIFY
,
1763 1, (LPARAM
) &RegistrationNotify
);
1764 if (NULL
!= RegistrationNotify
.ErrorMessage
&&
1765 UnknownError
!= RegistrationNotify
.ErrorMessage
)
1767 LocalFree((PVOID
) RegistrationNotify
.ErrorMessage
);
1770 SetupTermDefaultQueueCallback(RegistrationData
->DefaultContext
);
1771 HeapFree(GetProcessHeap(), 0, RegistrationData
);
1773 RegisterTypeLibraries(hSysSetupInf
, L
"TypeLibraries");
1775 // FIXME: Move this call to a separate cleanup page!
1776 RtlCreateBootStatusDataFile();
1783 StartComponentRegistration(HWND hwndDlg
, PULONG MaxProgress
)
1785 HANDLE RegistrationThread
;
1788 WCHAR SectionName
[512];
1789 PREGISTRATIONDATA RegistrationData
;
1792 if (! SetupFindFirstLineW(hSysSetupInf
, L
"RegistrationPhase2",
1793 L
"RegisterDlls", &Context
))
1795 DPRINT1("No RegistrationPhase2 section found\n");
1798 if (! SetupGetStringFieldW(&Context
, 1, SectionName
,
1799 sizeof(SectionName
) / sizeof(SectionName
[0]),
1802 DPRINT1("Unable to retrieve section name\n");
1805 DllCount
= SetupGetLineCountW(hSysSetupInf
, SectionName
);
1806 DPRINT("SectionName %S DllCount %ld\n", SectionName
, DllCount
);
1809 SetLastError(STATUS_NOT_FOUND
);
1813 *MaxProgress
= (ULONG
) DllCount
;
1816 * Create a background thread to do the actual registrations, so the
1817 * main thread can just run its message loop.
1819 RegistrationThread
= NULL
;
1820 RegistrationData
= HeapAlloc(GetProcessHeap(), 0,
1821 sizeof(REGISTRATIONDATA
));
1822 if (RegistrationData
!= NULL
)
1824 RegistrationData
->hwndDlg
= hwndDlg
;
1825 RegistrationData
->DllCount
= DllCount
;
1826 RegistrationThread
= CreateThread(NULL
, 0, RegistrationProc
,
1827 RegistrationData
, 0, NULL
);
1828 if (RegistrationThread
!= NULL
)
1830 CloseHandle(RegistrationThread
);
1834 DPRINT1("CreateThread failed, error %u\n", GetLastError());
1835 HeapFree(GetProcessHeap(), 0, RegistrationData
);
1841 DPRINT1("HeapAlloc() failed, error %u\n", GetLastError());
1849 static INT_PTR CALLBACK
1850 ProcessPageDlgProc(HWND hwndDlg
,
1855 PSETUPDATA SetupData
;
1856 PREGISTRATIONNOTIFY RegistrationNotify
;
1857 static UINT oldActivityID
= -1;
1860 /* Retrieve pointer to the global setup data */
1861 SetupData
= (PSETUPDATA
)GetWindowLongPtr (hwndDlg
, GWL_USERDATA
);
1867 /* Save pointer to the global setup data */
1868 SetupData
= (PSETUPDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
1869 SetWindowLongPtr(hwndDlg
, GWL_USERDATA
, (DWORD_PTR
)SetupData
);
1875 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
1876 ULONG MaxProgress
= 0;
1881 /* Disable the Back and Next buttons */
1882 PropSheet_SetWizButtons(GetParent(hwndDlg
), 0);
1884 StartComponentRegistration(hwndDlg
, &MaxProgress
);
1886 SendDlgItemMessage(hwndDlg
, IDC_PROCESSPROGRESS
, PBM_SETRANGE
,
1887 0, MAKELPARAM(0, MaxProgress
));
1888 SendDlgItemMessage(hwndDlg
, IDC_PROCESSPROGRESS
, PBM_SETPOS
,
1896 SetupData
->UnattendSetup
= FALSE
;
1905 case PM_REGISTRATION_NOTIFY
:
1908 RegistrationNotify
= (PREGISTRATIONNOTIFY
) lParam
;
1909 // update if necessary only
1910 if (oldActivityID
!= RegistrationNotify
->ActivityID
)
1912 if (0 != LoadStringW(hDllInstance
, RegistrationNotify
->ActivityID
,
1914 sizeof(Activity
) / sizeof(Activity
[0])))
1916 SendDlgItemMessageW(hwndDlg
, IDC_ACTIVITY
, WM_SETTEXT
,
1917 0, (LPARAM
) Activity
);
1919 oldActivityID
= RegistrationNotify
->ActivityID
;
1921 SendDlgItemMessageW(hwndDlg
, IDC_ITEM
, WM_SETTEXT
, 0,
1922 (LPARAM
)(NULL
== RegistrationNotify
->CurrentItem
?
1923 L
"" : RegistrationNotify
->CurrentItem
));
1924 SendDlgItemMessage(hwndDlg
, IDC_PROCESSPROGRESS
, PBM_SETPOS
,
1925 RegistrationNotify
->Progress
, 0);
1926 if (NULL
!= RegistrationNotify
->ErrorMessage
)
1928 if (0 == LoadStringW(hDllInstance
, IDS_REACTOS_SETUP
,
1929 Title
, sizeof(Title
) / sizeof(Title
[0])))
1931 wcscpy(Title
, L
"ReactOS Setup");
1933 MessageBoxW(hwndDlg
, RegistrationNotify
->ErrorMessage
,
1934 Title
, MB_ICONERROR
| MB_OK
);
1941 if(!SetupData
->UnattendSetup
&& !SetupData
->DisableVmwInst
)
1942 RunVMWInstall(GetParent(hwndDlg
));
1945 /* Enable the Back and Next buttons */
1946 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_NEXT
);
1947 PropSheet_PressButton(GetParent(hwndDlg
), PSBTN_NEXT
);
1961 SetInstallationCompleted(VOID
)
1964 DWORD InProgress
= 0;
1967 if (RegOpenKeyExW( HKEY_LOCAL_MACHINE
,
1971 &hKey
) == ERROR_SUCCESS
)
1973 RegSetValueExW( hKey
, L
"SystemSetupInProgress", 0, REG_DWORD
, (LPBYTE
)&InProgress
, sizeof(InProgress
) );
1974 RegCloseKey( hKey
);
1977 if (RegOpenKeyExW( HKEY_LOCAL_MACHINE
,
1978 L
"Software\\Microsoft\\Windows NT\\CurrentVersion",
1981 &hKey
) == ERROR_SUCCESS
)
1983 InstallDate
= (DWORD
)time(NULL
);
1984 RegSetValueExW( hKey
, L
"InstallDate", 0, REG_DWORD
, (LPBYTE
)&InstallDate
, sizeof(InstallDate
) );
1985 RegCloseKey( hKey
);
1989 static INT_PTR CALLBACK
1990 FinishDlgProc(HWND hwndDlg
,
2000 /* Get pointer to the global setup data */
2001 PSETUPDATA SetupData
= (PSETUPDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
2003 if (!SetupData
->UnattendSetup
|| !SetupData
->DisableGeckoInst
)
2005 /* Run the Wine Gecko prompt */
2006 Control_RunDLLW(hwndDlg
, 0, L
"appwiz.cpl install_gecko", SW_SHOW
);
2009 /* Set title font */
2010 SendDlgItemMessage(hwndDlg
,
2013 (WPARAM
)SetupData
->hTitleFont
,
2015 if (SetupData
->UnattendSetup
)
2017 KillTimer(hwndDlg
, 1);
2018 SetInstallationCompleted();
2026 SetInstallationCompleted();
2036 hWndProgress
= GetDlgItem(hwndDlg
, IDC_RESTART_PROGRESS
);
2037 Position
= SendMessage(hWndProgress
, PBM_GETPOS
, 0, 0);
2038 if (Position
== 300)
2040 KillTimer(hwndDlg
, 1);
2041 PropSheet_PressButton(GetParent(hwndDlg
), PSBTN_FINISH
);
2045 SendMessage(hWndProgress
, PBM_SETPOS
, Position
+ 1, 0);
2052 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
2057 /* Enable the correct buttons on for the active page */
2058 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_FINISH
);
2060 SendDlgItemMessage(hwndDlg
, IDC_RESTART_PROGRESS
, PBM_SETRANGE
, 0,
2061 MAKELPARAM(0, 300));
2062 SendDlgItemMessage(hwndDlg
, IDC_RESTART_PROGRESS
, PBM_SETPOS
, 0, 0);
2063 SetTimer(hwndDlg
, 1, 50, NULL
);
2067 DestroyWindow(GetParent(hwndDlg
));
2085 ProcessUnattendInf(HINF hUnattendedInf
)
2087 INFCONTEXT InfContext
;
2089 WCHAR szValue
[MAX_PATH
];
2093 if (!SetupFindFirstLineW(hUnattendedInf
,
2095 L
"UnattendSetupEnabled",
2098 DPRINT1("Error: Cant find UnattendSetupEnabled Key! %d\n", GetLastError());
2102 if (!SetupGetStringFieldW(&InfContext
,
2105 sizeof(szValue
) / sizeof(WCHAR
),
2108 DPRINT1("Error: SetupGetStringField failed with %d\n", GetLastError());
2112 if (wcscmp(szValue
, L
"yes") != 0)
2114 DPRINT("Unattend setup was disabled by UnattendSetupEnabled key.\n");
2118 if (!SetupFindFirstLineW(hUnattendedInf
,
2123 DPRINT1("Error: SetupFindFirstLine failed %d\n", GetLastError());
2130 if (!SetupGetStringFieldW(&InfContext
,
2133 sizeof(szName
) / sizeof(WCHAR
),
2136 DPRINT1("Error: SetupGetStringField failed with %d\n", GetLastError());
2140 if (!SetupGetStringFieldW(&InfContext
,
2143 sizeof(szValue
) / sizeof(WCHAR
),
2146 DPRINT1("Error: SetupGetStringField failed with %d\n", GetLastError());
2149 DPRINT1("Name %S Value %S\n", szName
, szValue
);
2150 if (!wcscmp(szName
, L
"FullName"))
2152 if ((sizeof(SetupData
.OwnerName
) / sizeof(TCHAR
)) > LineLength
)
2154 wcscpy(SetupData
.OwnerName
, szValue
);
2157 else if (!wcscmp(szName
, L
"OrgName"))
2159 if ((sizeof(SetupData
.OwnerOrganization
) / sizeof(WCHAR
)) > LineLength
)
2161 wcscpy(SetupData
.OwnerOrganization
, szValue
);
2164 else if (!wcscmp(szName
, L
"ComputerName"))
2166 if ((sizeof(SetupData
.ComputerName
) / sizeof(WCHAR
)) > LineLength
)
2168 wcscpy(SetupData
.ComputerName
, szValue
);
2171 else if (!wcscmp(szName
, L
"AdminPassword"))
2173 if ((sizeof(SetupData
.AdminPassword
) / sizeof(WCHAR
)) > LineLength
)
2175 wcscpy(SetupData
.AdminPassword
, szValue
);
2178 else if (!wcscmp(szName
, L
"TimeZoneIndex"))
2180 SetupData
.TimeZoneIndex
= _wtoi(szValue
);
2182 else if (!wcscmp(szName
, L
"DisableAutoDaylightTimeSet"))
2184 SetupData
.DisableAutoDaylightTimeSet
= _wtoi(szValue
);
2186 else if (!wcscmp(szName
, L
"DisableVmwInst"))
2188 if(!wcscmp(szValue
, L
"yes"))
2189 SetupData
.DisableVmwInst
= 1;
2191 SetupData
.DisableVmwInst
= 0;
2193 else if (!wcscmp(szName
, L
"DisableGeckoInst"))
2195 if(!wcscmp(szValue
, L
"yes"))
2196 SetupData
.DisableGeckoInst
= 1;
2198 SetupData
.DisableGeckoInst
= 0;
2202 while (SetupFindNextLine(&InfContext
, &InfContext
));
2203 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
2204 L
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunOnce",
2207 &hKey
) != ERROR_SUCCESS
)
2209 DPRINT1("Error: failed to open HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\RunOnce\n");
2214 if (SetupFindFirstLineW(hUnattendedInf
,
2223 if(SetupGetStringFieldW(&InfContext
,
2226 sizeof(szValue
) / sizeof(WCHAR
),
2229 WCHAR szPath
[MAX_PATH
];
2230 swprintf(szName
, L
"%d", i
);
2231 DPRINT("szName %S szValue %S\n", szName
, szValue
);
2233 if (ExpandEnvironmentStringsW(szValue
, szPath
, MAX_PATH
))
2235 DPRINT("value %S\n", szPath
);
2236 if (RegSetValueExW(hKey
,
2240 (const BYTE
*)szPath
,
2241 (wcslen(szPath
) + 1) * sizeof(WCHAR
)) == ERROR_SUCCESS
)
2247 } while(SetupFindNextLine(&InfContext
, &InfContext
));
2255 * GetRosInstallCD should find the path to ros installation medium
2257 * If there are more than one CDDrive in it containing a ReactOS
2258 * installation cd, then it will pick the first one regardless if
2259 * it is really the installation cd
2261 * The best way to implement this is to set the key
2262 * HKLM\Software\Microsoft\Windows NT\CurrentVersion\SourcePath (REG_SZ)
2266 GetRosInstallCD(WCHAR
*pwszPath
, DWORD cchPathMax
)
2268 WCHAR wszDrives
[512];
2272 cchDrives
= GetLogicalDriveStringsW(_countof(wszDrives
) - 1, wszDrives
);
2273 if (cchDrives
== 0 || cchDrives
>= _countof(wszDrives
))
2275 /* buffer too small or failure */
2276 LogItem(SYSSETUP_SEVERITY_INFORMATION
, L
"GetLogicalDriveStringsW failed");
2280 for (pwszDrive
= wszDrives
; pwszDrive
[0]; pwszDrive
+= wcslen(pwszDrive
) + 1)
2282 if (GetDriveTypeW(pwszDrive
) == DRIVE_CDROM
)
2284 WCHAR wszBuf
[MAX_PATH
];
2285 wsprintf(wszBuf
, L
"%sreactos\\system32\\ntoskrnl.exe", pwszDrive
);
2286 LogItem(SYSSETUP_SEVERITY_INFORMATION
, wszBuf
);
2287 if (GetFileAttributesW(wszBuf
) != INVALID_FILE_ATTRIBUTES
)
2289 /* the file exists, so this is the right drive */
2290 wcsncpy(pwszPath
, pwszDrive
, cchPathMax
);
2291 OutputDebugStringW(L
"GetRosInstallCD: ");OutputDebugStringW(pwszPath
);OutputDebugStringW(L
"\n");
2301 ProcessUnattendSetup(VOID
)
2303 WCHAR szPath
[MAX_PATH
];
2304 HINF hUnattendedInf
;
2307 if (!GetRosInstallCD(szPath
, MAX_PATH
))
2309 /* no cd drive found */
2313 dwLength
= wcslen(szPath
);
2314 if (dwLength
+ 21 > MAX_PATH
)
2317 * allocate bigger buffer
2322 wcscat(szPath
, L
"reactos\\unattend.inf");
2324 hUnattendedInf
= SetupOpenInfFileW(szPath
,
2329 if (hUnattendedInf
!= INVALID_HANDLE_VALUE
)
2331 SetupData
.UnattendSetup
= ProcessUnattendInf(hUnattendedInf
);
2332 SetupCloseInfFile(hUnattendedInf
);
2340 PROPSHEETHEADER psh
;
2341 HPROPSHEETPAGE ahpsp
[8];
2342 PROPSHEETPAGE psp
= {0};
2347 /* Clear setup data */
2348 ZeroMemory(&SetupData
, sizeof(SETUPDATA
));
2350 ProcessUnattendSetup();
2352 /* Create the Welcome page */
2353 psp
.dwSize
= sizeof(PROPSHEETPAGE
);
2354 psp
.dwFlags
= PSP_DEFAULT
| PSP_HIDEHEADER
;
2355 psp
.hInstance
= hDllInstance
;
2356 psp
.lParam
= (LPARAM
)&SetupData
;
2357 psp
.pfnDlgProc
= WelcomeDlgProc
;
2358 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_WELCOMEPAGE
);
2359 ahpsp
[nPages
++] = CreatePropertySheetPage(&psp
);
2361 /* Create the Acknowledgements page */
2362 psp
.dwFlags
= PSP_DEFAULT
| PSP_USEHEADERTITLE
| PSP_USEHEADERSUBTITLE
;
2363 psp
.pszHeaderTitle
= MAKEINTRESOURCE(IDS_ACKTITLE
);
2364 psp
.pszHeaderSubTitle
= MAKEINTRESOURCE(IDS_ACKSUBTITLE
);
2365 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_ACKPAGE
);
2366 psp
.pfnDlgProc
= AckPageDlgProc
;
2367 ahpsp
[nPages
++] = CreatePropertySheetPage(&psp
);
2369 /* Create the Locale page */
2370 psp
.dwFlags
= PSP_DEFAULT
| PSP_USEHEADERTITLE
| PSP_USEHEADERSUBTITLE
;
2371 psp
.pszHeaderTitle
= MAKEINTRESOURCE(IDS_LOCALETITLE
);
2372 psp
.pszHeaderSubTitle
= MAKEINTRESOURCE(IDS_LOCALESUBTITLE
);
2373 psp
.pfnDlgProc
= LocalePageDlgProc
;
2374 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_LOCALEPAGE
);
2375 ahpsp
[nPages
++] = CreatePropertySheetPage(&psp
);
2378 /* Create the Owner page */
2379 psp
.dwFlags
= PSP_DEFAULT
| PSP_USEHEADERTITLE
| PSP_USEHEADERSUBTITLE
;
2380 psp
.pszHeaderTitle
= MAKEINTRESOURCE(IDS_OWNERTITLE
);
2381 psp
.pszHeaderSubTitle
= MAKEINTRESOURCE(IDS_OWNERSUBTITLE
);
2382 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_OWNERPAGE
);
2383 psp
.pfnDlgProc
= OwnerPageDlgProc
;
2384 ahpsp
[nPages
++] = CreatePropertySheetPage(&psp
);
2386 /* Create the Computer page */
2387 psp
.dwFlags
= PSP_DEFAULT
| PSP_USEHEADERTITLE
| PSP_USEHEADERSUBTITLE
;
2388 psp
.pszHeaderTitle
= MAKEINTRESOURCE(IDS_COMPUTERTITLE
);
2389 psp
.pszHeaderSubTitle
= MAKEINTRESOURCE(IDS_COMPUTERSUBTITLE
);
2390 psp
.pfnDlgProc
= ComputerPageDlgProc
;
2391 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_COMPUTERPAGE
);
2392 ahpsp
[nPages
++] = CreatePropertySheetPage(&psp
);
2395 /* Create the DateTime page */
2396 psp
.dwFlags
= PSP_DEFAULT
| PSP_USEHEADERTITLE
| PSP_USEHEADERSUBTITLE
;
2397 psp
.pszHeaderTitle
= MAKEINTRESOURCE(IDS_DATETIMETITLE
);
2398 psp
.pszHeaderSubTitle
= MAKEINTRESOURCE(IDS_DATETIMESUBTITLE
);
2399 psp
.pfnDlgProc
= DateTimePageDlgProc
;
2400 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_DATETIMEPAGE
);
2401 ahpsp
[nPages
++] = CreatePropertySheetPage(&psp
);
2404 /* Create the Process page */
2405 psp
.dwFlags
= PSP_DEFAULT
| PSP_USEHEADERTITLE
| PSP_USEHEADERSUBTITLE
;
2406 psp
.pszHeaderTitle
= MAKEINTRESOURCE(IDS_PROCESSTITLE
);
2407 psp
.pszHeaderSubTitle
= MAKEINTRESOURCE(IDS_PROCESSSUBTITLE
);
2408 psp
.pfnDlgProc
= ProcessPageDlgProc
;
2409 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_PROCESSPAGE
);
2410 ahpsp
[nPages
++] = CreatePropertySheetPage(&psp
);
2413 /* Create the Finish page */
2414 psp
.dwFlags
= PSP_DEFAULT
| PSP_HIDEHEADER
;
2415 psp
.pfnDlgProc
= FinishDlgProc
;
2416 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_FINISHPAGE
);
2417 ahpsp
[nPages
++] = CreatePropertySheetPage(&psp
);
2419 /* Create the property sheet */
2420 psh
.dwSize
= sizeof(PROPSHEETHEADER
);
2421 psh
.dwFlags
= PSH_WIZARD97
| PSH_WATERMARK
| PSH_HEADER
| PSH_MODELESS
;
2422 psh
.hInstance
= hDllInstance
;
2423 psh
.hwndParent
= NULL
;
2424 psh
.nPages
= nPages
;
2427 psh
.pszbmWatermark
= MAKEINTRESOURCE(IDB_WATERMARK
);
2428 psh
.pszbmHeader
= MAKEINTRESOURCE(IDB_HEADER
);
2430 /* Create title font */
2431 SetupData
.hTitleFont
= CreateTitleFont();
2433 /* Display the wizard */
2434 hWnd
= (HWND
)PropertySheet(&psh
);
2435 ShowWindow(hWnd
, SW_SHOW
);
2437 while (GetMessage(&msg
, NULL
, 0, 0))
2439 if (!IsDialogMessage(hWnd
, &msg
))
2441 TranslateMessage(&msg
);
2442 DispatchMessage(&msg
);
2446 DeleteObject(SetupData
.hTitleFont
);