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 LOGFONTW LogFont
= {0};
129 LogFont
.lfWeight
= FW_HEAVY
;
130 wcscpy(LogFont
.lfFaceName
, L
"MS Shell Dlg");
133 LogFont
.lfHeight
= -MulDiv(12, GetDeviceCaps(hdc
, LOGPIXELSY
), 72);
135 hFont
= CreateFontIndirectW(&LogFont
);
137 ReleaseDC(NULL
, hdc
);
146 LOGFONTW tmpFont
= {0};
150 /* Grabs the Drawing Context */
153 tmpFont
.lfHeight
= -MulDiv(8, GetDeviceCaps(hDc
, LOGPIXELSY
), 72);
154 tmpFont
.lfWeight
= FW_HEAVY
;
155 wcscpy(tmpFont
.lfFaceName
, L
"MS Shell Dlg");
157 hBoldFont
= CreateFontIndirectW(&tmpFont
);
159 ReleaseDC(NULL
, hDc
);
164 static INT_PTR CALLBACK
165 GplDlgProc(HWND hwndDlg
,
170 HRSRC GplTextResource
;
180 GplTextResource
= FindResourceW(hDllInstance
, MAKEINTRESOURCE(IDR_GPL
), L
"RT_TEXT");
181 if (NULL
== GplTextResource
)
185 Size
= SizeofResource(hDllInstance
, GplTextResource
);
190 GplText
= HeapAlloc(GetProcessHeap(), 0, Size
+ 1);
195 GplTextMem
= LoadResource(hDllInstance
, GplTextResource
);
196 if (NULL
== GplTextMem
)
198 HeapFree(GetProcessHeap(), 0, GplText
);
201 GplTextLocked
= LockResource(GplTextMem
);
202 if (NULL
== GplTextLocked
)
204 HeapFree(GetProcessHeap(), 0, GplText
);
207 memcpy(GplText
, GplTextLocked
, Size
);
208 GplText
[Size
] = '\0';
209 SendMessageA(GetDlgItem(hwndDlg
, IDC_GPL_TEXT
), WM_SETTEXT
, 0, (LPARAM
) GplText
);
210 HeapFree(GetProcessHeap(), 0, GplText
);
211 SetFocus(GetDlgItem(hwndDlg
, IDOK
));
215 EndDialog(hwndDlg
, IDCANCEL
);
219 if (HIWORD(wParam
) == BN_CLICKED
&& IDOK
== LOWORD(wParam
))
221 EndDialog(hwndDlg
, IDOK
);
233 static INT_PTR CALLBACK
234 WelcomeDlgProc(HWND hwndDlg
,
239 PSETUPDATA pSetupData
;
241 pSetupData
= (PSETUPDATA
)GetWindowLongPtr(hwndDlg
, DWLP_USER
);
250 /* Get pointer to the global setup data */
251 pSetupData
= (PSETUPDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
252 SetWindowLongPtr(hwndDlg
, DWLP_USER
, (LONG_PTR
)pSetupData
);
254 hwndControl
= GetParent(hwndDlg
);
256 /* Center the wizard window */
257 CenterWindow (hwndControl
);
259 /* Hide the system menu */
260 dwStyle
= GetWindowLongPtr(hwndControl
, GWL_STYLE
);
261 SetWindowLongPtr(hwndControl
, GWL_STYLE
, dwStyle
& ~WS_SYSMENU
);
263 /* Hide and disable the 'Cancel' button */
264 hwndControl
= GetDlgItem(GetParent(hwndDlg
), IDCANCEL
);
265 ShowWindow (hwndControl
, SW_HIDE
);
266 EnableWindow (hwndControl
, FALSE
);
269 SendDlgItemMessage(hwndDlg
,
272 (WPARAM
)pSetupData
->hTitleFont
,
280 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
285 LogItem(L
"BEGIN", L
"WelcomePage");
286 /* Enable the Next button */
287 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_NEXT
);
288 if (pSetupData
->UnattendSetup
)
290 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, IDD_ACKPAGE
);
296 LogItem(L
"END", L
"WelcomePage");
300 pSetupData
->UnattendSetup
= FALSE
;
317 static INT_PTR CALLBACK
318 AckPageDlgProc(HWND hwndDlg
,
325 PWCHAR End
, CurrentProject
;
326 INT ProjectsSize
, ProjectsCount
;
327 PSETUPDATA pSetupData
;
329 pSetupData
= (PSETUPDATA
)GetWindowLongPtr(hwndDlg
, DWLP_USER
);
335 pSetupData
= (PSETUPDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
336 SetWindowLongPtr(hwndDlg
, DWLP_USER
, (LONG_PTR
)pSetupData
);
342 Projects
= HeapAlloc(GetProcessHeap(), 0, ProjectsSize
* sizeof(WCHAR
));
343 if (NULL
== Projects
)
347 ProjectsCount
= LoadStringW(hDllInstance
, IDS_ACKPROJECTS
, Projects
, ProjectsSize
);
348 if (0 == ProjectsCount
)
350 HeapFree(GetProcessHeap(), 0, Projects
);
353 if (ProjectsCount
< ProjectsSize
- 1)
357 HeapFree(GetProcessHeap(), 0, Projects
);
361 CurrentProject
= Projects
;
362 while (L
'\0' != *CurrentProject
)
364 End
= wcschr(CurrentProject
, L
'\n');
369 (void)ListBox_AddString(GetDlgItem(hwndDlg
, IDC_PROJECTS
), CurrentProject
);
372 CurrentProject
= End
+ 1;
376 CurrentProject
+= wcslen(CurrentProject
);
379 HeapFree(GetProcessHeap(), 0, Projects
);
384 if (HIWORD(wParam
) == BN_CLICKED
&& IDC_VIEWGPL
== LOWORD(wParam
))
386 DialogBox(hDllInstance
, MAKEINTRESOURCE(IDD_GPL
), NULL
, GplDlgProc
);
387 SetForegroundWindow(GetParent(hwndDlg
));
393 lpnm
= (LPNMHDR
)lParam
;
398 /* Enable the Back and Next buttons */
399 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_BACK
| PSWIZB_NEXT
);
400 if (pSetupData
->UnattendSetup
)
402 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, IDD_LOCALEPAGE
);
408 pSetupData
->UnattendSetup
= FALSE
;
426 WriteOwnerSettings(WCHAR
* OwnerName
,
427 WCHAR
* OwnerOrganization
)
434 res
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
435 L
"Software\\Microsoft\\Windows NT\\CurrentVersion",
440 if (res
!= ERROR_SUCCESS
)
445 res
= RegSetValueExW(hKey
,
450 (wcslen(OwnerName
) + 1) * sizeof(WCHAR
));
452 if (res
!= ERROR_SUCCESS
)
458 res
= RegSetValueExW(hKey
,
459 L
"RegisteredOrganization",
462 (LPBYTE
)OwnerOrganization
,
463 (wcslen(OwnerOrganization
) + 1) * sizeof(WCHAR
));
466 return (res
== ERROR_SUCCESS
);
469 static INT_PTR CALLBACK
470 OwnerPageDlgProc(HWND hwndDlg
,
476 WCHAR OwnerOrganization
[51];
478 WCHAR ErrorName
[256];
480 PSETUPDATA pSetupData
;
482 pSetupData
= (PSETUPDATA
)GetWindowLongPtr(hwndDlg
, DWLP_USER
);
488 pSetupData
= (PSETUPDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
489 SetWindowLongPtr(hwndDlg
, DWLP_USER
, (LONG_PTR
)pSetupData
);
491 /* set a localized ('Owner') placeholder string as default */
492 if (LoadStringW(hDllInstance
, IDS_MACHINE_OWNER_NAME
, OwnerName
, _countof(OwnerName
)))
494 SendDlgItemMessage(hwndDlg
, IDC_OWNERNAME
, WM_SETTEXT
, 0, (LPARAM
)OwnerName
);
497 SendDlgItemMessage(hwndDlg
, IDC_OWNERNAME
, EM_LIMITTEXT
, 50, 0);
498 SendDlgItemMessage(hwndDlg
, IDC_OWNERORGANIZATION
, EM_LIMITTEXT
, 50, 0);
500 /* Set focus to owner name */
501 SetFocus(GetDlgItem(hwndDlg
, IDC_OWNERNAME
));
503 /* Select the default text to quickly overwrite it by typing */
504 SendDlgItemMessage(hwndDlg
, IDC_OWNERNAME
, EM_SETSEL
, 0, -1);
511 lpnm
= (LPNMHDR
)lParam
;
516 /* Enable the Back and Next buttons */
517 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_BACK
| PSWIZB_NEXT
);
518 if (pSetupData
->UnattendSetup
)
520 SendMessage(GetDlgItem(hwndDlg
, IDC_OWNERNAME
), WM_SETTEXT
, 0, (LPARAM
)pSetupData
->OwnerName
);
521 SendMessage(GetDlgItem(hwndDlg
, IDC_OWNERORGANIZATION
), WM_SETTEXT
, 0, (LPARAM
)pSetupData
->OwnerOrganization
);
522 if (WriteOwnerSettings(pSetupData
->OwnerName
, pSetupData
->OwnerOrganization
))
524 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, IDD_COMPUTERPAGE
);
532 if (GetDlgItemTextW(hwndDlg
, IDC_OWNERNAME
, OwnerName
, 50) == 0)
534 if (0 == LoadStringW(hDllInstance
, IDS_REACTOS_SETUP
, Title
, sizeof(Title
) / sizeof(Title
[0])))
536 wcscpy(Title
, L
"ReactOS Setup");
538 if (0 == LoadStringW(hDllInstance
, IDS_WZD_NAME
, ErrorName
, sizeof(ErrorName
) / sizeof(ErrorName
[0])))
540 wcscpy(ErrorName
, L
"Setup cannot continue until you enter your name.");
542 MessageBoxW(hwndDlg
, ErrorName
, Title
, MB_ICONERROR
| MB_OK
);
544 SetFocus(GetDlgItem(hwndDlg
, IDC_OWNERNAME
));
545 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, -1);
550 OwnerOrganization
[0] = 0;
551 GetDlgItemTextW(hwndDlg
, IDC_OWNERORGANIZATION
, OwnerOrganization
, 50);
553 if (!WriteOwnerSettings(OwnerName
, OwnerOrganization
))
555 SetFocus(GetDlgItem(hwndDlg
, IDC_OWNERNAME
));
556 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, -1);
561 pSetupData
->UnattendSetup
= FALSE
;
579 WriteComputerSettings(WCHAR
* ComputerName
, HWND hwndDlg
)
582 WCHAR ErrorComputerName
[256];
584 if (!SetComputerNameW(ComputerName
))
588 if (0 == LoadStringW(hDllInstance
, IDS_REACTOS_SETUP
, Title
, sizeof(Title
) / sizeof(Title
[0])))
590 wcscpy(Title
, L
"ReactOS Setup");
592 if (0 == LoadStringW(hDllInstance
, IDS_WZD_SETCOMPUTERNAME
, ErrorComputerName
,
593 sizeof(ErrorComputerName
) / sizeof(ErrorComputerName
[0])))
595 wcscpy(ErrorComputerName
, L
"Setup failed to set the computer name.");
597 MessageBoxW(hwndDlg
, ErrorComputerName
, Title
, MB_ICONERROR
| MB_OK
);
603 /* Try to also set DNS hostname */
604 SetComputerNameExW(ComputerNamePhysicalDnsHostname
, ComputerName
);
606 /* Set the accounts domain name */
607 SetAccountsDomainSid(NULL
, ComputerName
);
615 WriteDefaultLogonData(LPWSTR Domain
)
617 WCHAR szAdministratorName
[256];
621 if (LoadStringW(hDllInstance
,
622 IDS_ADMINISTRATOR_NAME
,
624 sizeof(szAdministratorName
) / sizeof(WCHAR
)) == 0)
626 wcscpy(szAdministratorName
, L
"Administrator");
629 lError
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
630 L
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon",
634 if (lError
!= ERROR_SUCCESS
)
637 lError
= RegSetValueEx(hKey
,
642 (wcslen(Domain
)+ 1) * sizeof(WCHAR
));
643 if (lError
!= ERROR_SUCCESS
)
645 DPRINT1("RegSetValueEx(\"DefaultDomain\") failed!\n");
648 lError
= RegSetValueEx(hKey
,
652 (LPBYTE
)szAdministratorName
,
653 (wcslen(szAdministratorName
)+ 1) * sizeof(WCHAR
));
654 if (lError
!= ERROR_SUCCESS
)
656 DPRINT1("RegSetValueEx(\"DefaultUserName\") failed!\n");
665 /* lpBuffer will be filled with a 15-char string (plus the null terminator) */
667 GenerateComputerName(LPWSTR lpBuffer
)
669 static const WCHAR Chars
[] = L
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
670 static const unsigned cChars
= sizeof(Chars
) / sizeof(WCHAR
) - 1;
673 wcscpy(lpBuffer
, L
"REACTOS-");
675 srand(GetTickCount());
677 /* fill in 7 characters */
678 for (i
= 8; i
< 15; i
++)
679 lpBuffer
[i
] = Chars
[rand() % cChars
];
681 lpBuffer
[15] = UNICODE_NULL
; /* NULL-terminate */
684 static INT_PTR CALLBACK
685 ComputerPageDlgProc(HWND hwndDlg
,
690 WCHAR ComputerName
[MAX_COMPUTERNAME_LENGTH
+ 1];
691 WCHAR Password1
[128];
692 WCHAR Password2
[128];
695 WCHAR EmptyComputerName
[256], NotMatchPassword
[256], WrongPassword
[256];
697 PSETUPDATA pSetupData
;
699 pSetupData
= (PSETUPDATA
)GetWindowLongPtr(hwndDlg
, DWLP_USER
);
701 if (0 == LoadStringW(hDllInstance
, IDS_REACTOS_SETUP
, Title
, sizeof(Title
) / sizeof(Title
[0])))
703 wcscpy(Title
, L
"ReactOS Setup");
709 pSetupData
= (PSETUPDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
710 SetWindowLongPtr(hwndDlg
, DWLP_USER
, (LONG_PTR
)pSetupData
);
712 /* Generate a new pseudo-random computer name */
713 GenerateComputerName(ComputerName
);
715 /* Display current computer name */
716 SetDlgItemTextW(hwndDlg
, IDC_COMPUTERNAME
, ComputerName
);
718 /* Set text limits */
719 SendDlgItemMessage(hwndDlg
, IDC_COMPUTERNAME
, EM_LIMITTEXT
, MAX_COMPUTERNAME_LENGTH
, 0);
720 SendDlgItemMessage(hwndDlg
, IDC_ADMINPASSWORD1
, EM_LIMITTEXT
, 127, 0);
721 SendDlgItemMessage(hwndDlg
, IDC_ADMINPASSWORD2
, EM_LIMITTEXT
, 127, 0);
723 /* Set focus to computer name */
724 SetFocus(GetDlgItem(hwndDlg
, IDC_COMPUTERNAME
));
725 if (pSetupData
->UnattendSetup
)
727 SendMessage(GetDlgItem(hwndDlg
, IDC_COMPUTERNAME
), WM_SETTEXT
, 0, (LPARAM
)pSetupData
->ComputerName
);
728 SendMessage(GetDlgItem(hwndDlg
, IDC_ADMINPASSWORD1
), WM_SETTEXT
, 0, (LPARAM
)pSetupData
->AdminPassword
);
729 SendMessage(GetDlgItem(hwndDlg
, IDC_ADMINPASSWORD2
), WM_SETTEXT
, 0, (LPARAM
)pSetupData
->AdminPassword
);
730 WriteComputerSettings(pSetupData
->ComputerName
, NULL
);
731 SetAdministratorPassword(pSetupData
->AdminPassword
);
734 /* Store the administrator account name as the default user name */
735 WriteDefaultLogonData(pSetupData
->ComputerName
);
741 lpnm
= (LPNMHDR
)lParam
;
746 /* Enable the Back and Next buttons */
747 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_BACK
| PSWIZB_NEXT
);
748 if (pSetupData
->UnattendSetup
&& WriteComputerSettings(pSetupData
->ComputerName
, hwndDlg
))
750 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, IDD_DATETIMEPAGE
);
756 if (0 == GetDlgItemTextW(hwndDlg
, IDC_COMPUTERNAME
, ComputerName
, MAX_COMPUTERNAME_LENGTH
+ 1))
758 if (0 == LoadStringW(hDllInstance
, IDS_WZD_COMPUTERNAME
, EmptyComputerName
,
759 sizeof(EmptyComputerName
) / sizeof(EmptyComputerName
[0])))
761 wcscpy(EmptyComputerName
, L
"Setup cannot continue until you enter the name of your computer.");
763 MessageBoxW(hwndDlg
, EmptyComputerName
, Title
, MB_ICONERROR
| MB_OK
);
764 SetFocus(GetDlgItem(hwndDlg
, IDC_COMPUTERNAME
));
765 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, -1);
769 /* No need to check computer name for invalid characters,
770 * SetComputerName() will do it for us */
772 if (!WriteComputerSettings(ComputerName
, hwndDlg
))
774 SetFocus(GetDlgItem(hwndDlg
, IDC_COMPUTERNAME
));
775 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, -1);
780 /* Check if admin passwords have been entered */
781 if ((GetDlgItemText(hwndDlg
, IDC_ADMINPASSWORD1
, Password1
, 128) == 0) ||
782 (GetDlgItemText(hwndDlg
, IDC_ADMINPASSWORD2
, Password2
, 128) == 0))
784 if (0 == LoadStringW(hDllInstance
, IDS_WZD_PASSWORDEMPTY
, EmptyPassword
,
785 sizeof(EmptyPassword
) / sizeof(EmptyPassword
[0])))
787 wcscpy(EmptyPassword
, L
"You must enter a password !");
789 MessageBoxW(hwndDlg
, EmptyPassword
, Title
, MB_ICONERROR
| MB_OK
);
790 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, -1);
794 GetDlgItemTextW(hwndDlg
, IDC_ADMINPASSWORD1
, Password1
, 128);
795 GetDlgItemTextW(hwndDlg
, IDC_ADMINPASSWORD2
, Password2
, 128);
797 /* Check if passwords match */
798 if (wcscmp(Password1
, Password2
))
800 if (0 == LoadStringW(hDllInstance
, IDS_WZD_PASSWORDMATCH
, NotMatchPassword
,
801 sizeof(NotMatchPassword
) / sizeof(NotMatchPassword
[0])))
803 wcscpy(NotMatchPassword
, L
"The passwords you entered do not match. Please enter the desired password again.");
805 MessageBoxW(hwndDlg
, NotMatchPassword
, Title
, MB_ICONERROR
| MB_OK
);
806 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, -1);
810 /* Check password for invalid characters */
811 Password
= (PWCHAR
)Password1
;
814 if (!isprint(*Password
))
816 if (0 == LoadStringW(hDllInstance
, IDS_WZD_PASSWORDCHAR
, WrongPassword
,
817 sizeof(WrongPassword
) / sizeof(WrongPassword
[0])))
819 wcscpy(WrongPassword
, L
"The password you entered contains invalid characters. Please enter a cleaned password.");
821 MessageBoxW(hwndDlg
, WrongPassword
, Title
, MB_ICONERROR
| MB_OK
);
822 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, -1);
828 /* Set admin password */
829 SetAdministratorPassword(Password1
);
833 pSetupData
->UnattendSetup
= FALSE
;
851 SetKeyboardLayoutName(HWND hwnd
)
854 TCHAR szLayoutPath
[256];
855 TCHAR szLocaleName
[32];
859 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE
,
860 _T("SYSTEM\\CurrentControlSet\\Control\\NLS\\Locale"),
866 dwValueSize
= 16 * sizeof(TCHAR
);
867 if (RegQueryValueEx(hKey
,
878 _tcscpy(szLayoutPath
,
879 _T("SYSTEM\\CurrentControlSet\\Control\\Keyboard Layouts\\"));
880 _tcscat(szLayoutPath
,
883 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE
,
890 dwValueSize
= 32 * sizeof(TCHAR
);
891 if (RegQueryValueEx(hKey
,
908 RunControlPanelApplet(HWND hwnd
, PCWSTR pwszCPLParameters
)
911 if (pwszCPLParameters
)
913 STARTUPINFOW StartupInfo
;
914 PROCESS_INFORMATION ProcessInformation
;
915 WCHAR CmdLine
[MAX_PATH
] = L
"rundll32.exe shell32.dll,Control_RunDLL ";
917 ZeroMemory(&StartupInfo
, sizeof(StartupInfo
));
918 StartupInfo
.cb
= sizeof(StartupInfo
);
920 ASSERT(_countof(CmdLine
) > wcslen(CmdLine
) + wcslen(pwszCPLParameters
));
921 wcscat(CmdLine
, pwszCPLParameters
);
923 if (!CreateProcessW(NULL
,
932 &ProcessInformation
))
934 MessageBoxW(hwnd
, L
"Error: Failed to launch the Control Panel Applet.", NULL
, MB_ICONERROR
);
938 while((MsgWaitForMultipleObjects(1, &ProcessInformation
.hProcess
, FALSE
, INFINITE
, QS_ALLINPUT
|QS_ALLPOSTMESSAGE
)) != WAIT_OBJECT_0
)
940 while(PeekMessageW(&msg
, NULL
, 0, 0, PM_REMOVE
))
942 TranslateMessage(&msg
);
943 DispatchMessageW(&msg
);
946 CloseHandle(ProcessInformation
.hThread
);
947 CloseHandle(ProcessInformation
.hProcess
);
952 MessageBoxW(hwnd
, L
"Error: Failed to launch the Control Panel Applet.", NULL
, MB_ICONERROR
);
958 WriteUserLocale(VOID
)
964 lcid
= GetSystemDefaultLCID();
966 if (GetLocaleInfoW(MAKELCID(lcid
, SORT_DEFAULT
), LOCALE_ILANGUAGE
, Locale
, sizeof(Locale
) / sizeof(Locale
[0])) != 0)
968 if (RegCreateKeyExW(HKEY_CURRENT_USER
, L
"Control Panel\\International",
969 0, NULL
, REG_OPTION_NON_VOLATILE
,
970 KEY_WRITE
, NULL
, &hKey
, NULL
) == ERROR_SUCCESS
)
972 RegSetValueExW(hKey
, L
"Locale", 0, REG_SZ
, (LPBYTE
)Locale
, (wcslen(Locale
) + 1) * sizeof(WCHAR
));
978 static INT_PTR CALLBACK
979 LocalePageDlgProc(HWND hwndDlg
,
984 PSETUPDATA SetupData
;
986 /* Retrieve pointer to the global setup data */
987 SetupData
= (PSETUPDATA
)GetWindowLongPtr (hwndDlg
, GWL_USERDATA
);
993 /* Save pointer to the global setup data */
994 SetupData
= (PSETUPDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
995 SetWindowLongPtr(hwndDlg
, GWL_USERDATA
, (DWORD_PTR
)SetupData
);
998 SetKeyboardLayoutName(GetDlgItem(hwndDlg
, IDC_LAYOUTTEXT
));
1003 if (HIWORD(wParam
) == BN_CLICKED
)
1005 switch (LOWORD(wParam
))
1007 case IDC_CUSTOMLOCALE
:
1008 RunControlPanelApplet(hwndDlg
, L
"intl.cpl,,5");
1009 /* FIXME: Update input locale name */
1012 case IDC_CUSTOMLAYOUT
:
1013 RunControlPanelApplet(hwndDlg
, L
"input.dll,@1");
1021 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
1026 /* Enable the Back and Next buttons */
1027 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_BACK
| PSWIZB_NEXT
);
1028 if (SetupData
->UnattendSetup
)
1030 WCHAR wszPath
[MAX_PATH
];
1031 if (GetRosInstallCD(wszPath
, _countof(wszPath
)))
1033 WCHAR wszParams
[1024];
1034 swprintf(wszParams
, L
"intl.cpl,,/f:\"%sreactos\\unattend.inf\"", wszPath
);
1035 RunControlPanelApplet(hwndDlg
, wszParams
);
1039 RunControlPanelApplet(hwndDlg
, L
"intl.cpl,,/f:\"unattend.inf\"");
1042 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, IDD_OWNERPAGE
);
1051 SetupData
->UnattendSetup
= FALSE
;
1068 static PTIMEZONE_ENTRY
1069 GetLargerTimeZoneEntry(PSETUPDATA SetupData
, DWORD Index
)
1071 PTIMEZONE_ENTRY Entry
;
1073 Entry
= SetupData
->TimeZoneListHead
;
1074 while (Entry
!= NULL
)
1076 if (Entry
->Index
>= Index
)
1079 Entry
= Entry
->Next
;
1087 CreateTimeZoneList(PSETUPDATA SetupData
)
1089 WCHAR szKeyName
[256];
1097 PTIMEZONE_ENTRY Entry
;
1098 PTIMEZONE_ENTRY Current
;
1100 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
1101 L
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones",
1110 dwNameSize
= 256 * sizeof(WCHAR
);
1111 lError
= RegEnumKeyExW(hZonesKey
,
1119 if (lError
!= ERROR_SUCCESS
&& lError
!= ERROR_MORE_DATA
)
1122 if (RegOpenKeyExW(hZonesKey
,
1129 Entry
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(TIMEZONE_ENTRY
));
1132 RegCloseKey(hZoneKey
);
1136 dwValueSize
= 64 * sizeof(WCHAR
);
1137 if (RegQueryValueExW(hZoneKey
,
1141 (LPBYTE
)&Entry
->Description
,
1144 RegCloseKey(hZoneKey
);
1148 dwValueSize
= 32 * sizeof(WCHAR
);
1149 if (RegQueryValueExW(hZoneKey
,
1153 (LPBYTE
)&Entry
->StandardName
,
1156 RegCloseKey(hZoneKey
);
1160 dwValueSize
= 32 * sizeof(WCHAR
);
1161 if (RegQueryValueExW(hZoneKey
,
1165 (LPBYTE
)&Entry
->DaylightName
,
1168 RegCloseKey(hZoneKey
);
1172 dwValueSize
= sizeof(DWORD
);
1173 if (RegQueryValueExW(hZoneKey
,
1177 (LPBYTE
)&Entry
->Index
,
1180 RegCloseKey(hZoneKey
);
1184 dwValueSize
= sizeof(TZ_INFO
);
1185 if (RegQueryValueExW(hZoneKey
,
1189 (LPBYTE
)&Entry
->TimezoneInfo
,
1192 RegCloseKey(hZoneKey
);
1196 RegCloseKey(hZoneKey
);
1198 if (SetupData
->TimeZoneListHead
== NULL
&&
1199 SetupData
->TimeZoneListTail
== NULL
)
1203 SetupData
->TimeZoneListHead
= Entry
;
1204 SetupData
->TimeZoneListTail
= Entry
;
1208 Current
= GetLargerTimeZoneEntry(SetupData
, Entry
->Index
);
1209 if (Current
!= NULL
)
1211 if (Current
== SetupData
->TimeZoneListHead
)
1213 /* Prepend to head */
1215 Entry
->Next
= SetupData
->TimeZoneListHead
;
1216 SetupData
->TimeZoneListHead
->Prev
= Entry
;
1217 SetupData
->TimeZoneListHead
= Entry
;
1221 /* Insert before current */
1222 Entry
->Prev
= Current
->Prev
;
1223 Entry
->Next
= Current
;
1224 Current
->Prev
->Next
= Entry
;
1225 Current
->Prev
= Entry
;
1230 /* Append to tail */
1231 Entry
->Prev
= SetupData
->TimeZoneListTail
;
1233 SetupData
->TimeZoneListTail
->Next
= Entry
;
1234 SetupData
->TimeZoneListTail
= Entry
;
1241 RegCloseKey(hZonesKey
);
1246 DestroyTimeZoneList(PSETUPDATA SetupData
)
1248 PTIMEZONE_ENTRY Entry
;
1250 while (SetupData
->TimeZoneListHead
!= NULL
)
1252 Entry
= SetupData
->TimeZoneListHead
;
1254 SetupData
->TimeZoneListHead
= Entry
->Next
;
1255 if (SetupData
->TimeZoneListHead
!= NULL
)
1257 SetupData
->TimeZoneListHead
->Prev
= NULL
;
1260 HeapFree(GetProcessHeap(), 0, Entry
);
1263 SetupData
->TimeZoneListTail
= NULL
;
1267 GetTimeZoneListIndex(LPDWORD lpIndex
)
1269 WCHAR szLanguageIdString
[9];
1276 BOOL bFound
= FALSE
;
1277 unsigned long iLanguageID
;
1281 *lpIndex
= 85; /* fallback to GMT time zone */
1283 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
1284 L
"SYSTEM\\CurrentControlSet\\Control\\NLS\\Language",
1290 dwValueSize
= 9 * sizeof(WCHAR
);
1291 if (RegQueryValueExW(hKey
,
1295 (LPBYTE
)szLanguageIdString
,
1302 iLanguageID
= wcstoul(szLanguageIdString
, NULL
, 16);
1307 iLanguageID
= *lpIndex
;
1310 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
1311 L
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones",
1318 if (RegQueryValueExW(hKey
,
1329 Buffer
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, dwValueSize
);
1336 if (RegQueryValueExW(hKey
,
1343 HeapFree(GetProcessHeap(), 0, Buffer
);
1353 Length
= wcslen(Ptr
);
1354 if (wcstoul(Ptr
, NULL
, 16) == iLanguageID
)
1357 Ptr
= Ptr
+ Length
+ 1;
1363 *lpIndex
= wcstoul(Ptr
, &End
, 10);
1364 HeapFree(GetProcessHeap(), 0, Buffer
);
1368 Length
= wcslen(Ptr
);
1369 Ptr
= Ptr
+ Length
+ 1;
1372 HeapFree(GetProcessHeap(), 0, Buffer
);
1379 ShowTimeZoneList(HWND hwnd
, PSETUPDATA SetupData
, DWORD dwEntryIndex
)
1381 PTIMEZONE_ENTRY Entry
;
1385 GetTimeZoneListIndex(&dwEntryIndex
);
1387 Entry
= SetupData
->TimeZoneListHead
;
1388 while (Entry
!= NULL
)
1390 dwCount
= SendMessage(hwnd
,
1393 (LPARAM
)Entry
->Description
);
1395 if (dwEntryIndex
!= 0 && dwEntryIndex
== Entry
->Index
)
1398 Entry
= Entry
->Next
;
1409 SetLocalTimeZone(HWND hwnd
, PSETUPDATA SetupData
)
1411 TIME_ZONE_INFORMATION TimeZoneInformation
;
1412 PTIMEZONE_ENTRY Entry
;
1416 dwIndex
= SendMessage(hwnd
,
1422 Entry
= SetupData
->TimeZoneListHead
;
1429 Entry
= Entry
->Next
;
1432 wcscpy(TimeZoneInformation
.StandardName
,
1433 Entry
->StandardName
);
1434 wcscpy(TimeZoneInformation
.DaylightName
,
1435 Entry
->DaylightName
);
1437 TimeZoneInformation
.Bias
= Entry
->TimezoneInfo
.Bias
;
1438 TimeZoneInformation
.StandardBias
= Entry
->TimezoneInfo
.StandardBias
;
1439 TimeZoneInformation
.DaylightBias
= Entry
->TimezoneInfo
.DaylightBias
;
1441 memcpy(&TimeZoneInformation
.StandardDate
,
1442 &Entry
->TimezoneInfo
.StandardDate
,
1443 sizeof(SYSTEMTIME
));
1444 memcpy(&TimeZoneInformation
.DaylightDate
,
1445 &Entry
->TimezoneInfo
.DaylightDate
,
1446 sizeof(SYSTEMTIME
));
1448 /* Set time zone information */
1449 SetTimeZoneInformation(&TimeZoneInformation
);
1454 GetLocalSystemTime(HWND hwnd
, PSETUPDATA SetupData
)
1459 if (DateTime_GetSystemtime(GetDlgItem(hwnd
, IDC_DATEPICKER
), &Date
) != GDT_VALID
)
1464 if (DateTime_GetSystemtime(GetDlgItem(hwnd
, IDC_TIMEPICKER
), &Time
) != GDT_VALID
)
1469 SetupData
->SystemTime
.wYear
= Date
.wYear
;
1470 SetupData
->SystemTime
.wMonth
= Date
.wMonth
;
1471 SetupData
->SystemTime
.wDayOfWeek
= Date
.wDayOfWeek
;
1472 SetupData
->SystemTime
.wDay
= Date
.wDay
;
1473 SetupData
->SystemTime
.wHour
= Time
.wHour
;
1474 SetupData
->SystemTime
.wMinute
= Time
.wMinute
;
1475 SetupData
->SystemTime
.wSecond
= Time
.wSecond
;
1476 SetupData
->SystemTime
.wMilliseconds
= Time
.wMilliseconds
;
1483 SetAutoDaylightInfo(HWND hwnd
)
1488 if (SendMessage(hwnd
, BM_GETCHECK
, 0, 0) == BST_UNCHECKED
)
1490 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
1491 L
"SYSTEM\\CurrentControlSet\\Control\\TimeZoneInformation",
1497 RegSetValueExW(hKey
,
1498 L
"DisableAutoDaylightTimeSet",
1509 SetSystemLocalTime(HWND hwnd
, PSETUPDATA SetupData
)
1514 * Call SetLocalTime twice to ensure correct results
1516 Ret
= SetLocalTime(&SetupData
->SystemTime
) &&
1517 SetLocalTime(&SetupData
->SystemTime
);
1523 WriteDateTimeSettings(HWND hwndDlg
, PSETUPDATA SetupData
)
1526 WCHAR ErrorLocalTime
[256];
1527 GetLocalSystemTime(hwndDlg
, SetupData
);
1528 SetLocalTimeZone(GetDlgItem(hwndDlg
, IDC_TIMEZONELIST
),
1531 SetAutoDaylightInfo(GetDlgItem(hwndDlg
, IDC_AUTODAYLIGHT
));
1532 if(!SetSystemLocalTime(hwndDlg
, SetupData
))
1534 if (0 == LoadStringW(hDllInstance
, IDS_REACTOS_SETUP
, Title
, sizeof(Title
) / sizeof(Title
[0])))
1536 wcscpy(Title
, L
"ReactOS Setup");
1538 if (0 == LoadStringW(hDllInstance
, IDS_WZD_LOCALTIME
, ErrorLocalTime
,
1539 sizeof(ErrorLocalTime
) / sizeof(ErrorLocalTime
[0])))
1541 wcscpy(ErrorLocalTime
, L
"Setup was unable to set the local time.");
1543 MessageBoxW(hwndDlg
, ErrorLocalTime
, Title
, MB_ICONWARNING
| MB_OK
);
1550 static INT_PTR CALLBACK
1551 DateTimePageDlgProc(HWND hwndDlg
,
1556 PSETUPDATA SetupData
;
1558 /* Retrieve pointer to the global setup data */
1559 SetupData
= (PSETUPDATA
)GetWindowLongPtr (hwndDlg
, GWL_USERDATA
);
1565 /* Save pointer to the global setup data */
1566 SetupData
= (PSETUPDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
1567 SetWindowLongPtr(hwndDlg
, GWL_USERDATA
, (DWORD_PTR
)SetupData
);
1569 CreateTimeZoneList(SetupData
);
1571 if (SetupData
->UnattendSetup
)
1573 ShowTimeZoneList(GetDlgItem(hwndDlg
, IDC_TIMEZONELIST
),
1574 SetupData
, SetupData
->TimeZoneIndex
);
1576 if (!SetupData
->DisableAutoDaylightTimeSet
)
1578 SendDlgItemMessage(hwndDlg
, IDC_AUTODAYLIGHT
, BM_SETCHECK
, (WPARAM
)BST_CHECKED
, 0);
1583 ShowTimeZoneList(GetDlgItem(hwndDlg
, IDC_TIMEZONELIST
),
1586 SendDlgItemMessage(hwndDlg
, IDC_AUTODAYLIGHT
, BM_SETCHECK
, (WPARAM
)BST_CHECKED
, 0);
1595 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
1600 /* Enable the Back and Next buttons */
1601 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_BACK
| PSWIZB_NEXT
);
1602 if (SetupData
->UnattendSetup
&& WriteDateTimeSettings(hwndDlg
, SetupData
))
1604 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, SetupData
->uFirstNetworkWizardPage
);
1611 WriteDateTimeSettings(hwndDlg
, SetupData
);
1616 SetupData
->UnattendSetup
= FALSE
;
1626 DestroyTimeZoneList(SetupData
);
1637 static UINT CALLBACK
1638 RegistrationNotificationProc(PVOID Context
,
1643 PREGISTRATIONDATA RegistrationData
;
1644 REGISTRATIONNOTIFY RegistrationNotify
;
1645 PSP_REGISTER_CONTROL_STATUSW StatusInfo
;
1647 WCHAR ErrorMessage
[128];
1649 RegistrationData
= (PREGISTRATIONDATA
) Context
;
1651 if (SPFILENOTIFY_STARTREGISTRATION
== Notification
||
1652 SPFILENOTIFY_ENDREGISTRATION
== Notification
)
1654 StatusInfo
= (PSP_REGISTER_CONTROL_STATUSW
) Param1
;
1655 RegistrationNotify
.CurrentItem
= wcsrchr(StatusInfo
->FileName
, L
'\\');
1656 if (NULL
== RegistrationNotify
.CurrentItem
)
1658 RegistrationNotify
.CurrentItem
= StatusInfo
->FileName
;
1662 RegistrationNotify
.CurrentItem
++;
1665 if (SPFILENOTIFY_STARTREGISTRATION
== Notification
)
1667 DPRINT("Received SPFILENOTIFY_STARTREGISTRATION notification for %S\n",
1668 StatusInfo
->FileName
);
1669 RegistrationNotify
.ErrorMessage
= NULL
;
1670 RegistrationNotify
.Progress
= RegistrationData
->Registered
;
1674 DPRINT("Received SPFILENOTIFY_ENDREGISTRATION notification for %S\n",
1675 StatusInfo
->FileName
);
1676 DPRINT("Win32Error %u FailureCode %u\n", StatusInfo
->Win32Error
,
1677 StatusInfo
->FailureCode
);
1678 if (SPREG_SUCCESS
!= StatusInfo
->FailureCode
)
1680 switch(StatusInfo
->FailureCode
)
1682 case SPREG_LOADLIBRARY
:
1683 MessageID
= IDS_LOADLIBRARY_FAILED
;
1685 case SPREG_GETPROCADDR
:
1686 MessageID
= IDS_GETPROCADDR_FAILED
;
1689 MessageID
= IDS_REGSVR_FAILED
;
1691 case SPREG_DLLINSTALL
:
1692 MessageID
= IDS_DLLINSTALL_FAILED
;
1695 MessageID
= IDS_TIMEOUT
;
1698 MessageID
= IDS_REASON_UNKNOWN
;
1701 if (0 == LoadStringW(hDllInstance
, MessageID
,
1703 sizeof(ErrorMessage
) /
1704 sizeof(ErrorMessage
[0])))
1706 ErrorMessage
[0] = L
'\0';
1708 if (SPREG_TIMEOUT
!= StatusInfo
->FailureCode
)
1710 FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM
, NULL
,
1711 StatusInfo
->Win32Error
, 0,
1712 ErrorMessage
+ wcslen(ErrorMessage
),
1713 sizeof(ErrorMessage
) / sizeof(ErrorMessage
[0]) -
1714 wcslen(ErrorMessage
), NULL
);
1716 RegistrationNotify
.ErrorMessage
= ErrorMessage
;
1720 RegistrationNotify
.ErrorMessage
= NULL
;
1722 if (RegistrationData
->Registered
< RegistrationData
->DllCount
)
1724 RegistrationData
->Registered
++;
1728 RegistrationNotify
.Progress
= RegistrationData
->Registered
;
1729 RegistrationNotify
.ActivityID
= IDS_REGISTERING_COMPONENTS
;
1730 SendMessage(RegistrationData
->hwndDlg
, PM_REGISTRATION_NOTIFY
,
1731 0, (LPARAM
) &RegistrationNotify
);
1737 DPRINT1("Received unexpected notification %u\n", Notification
);
1738 return SetupDefaultQueueCallback(RegistrationData
->DefaultContext
,
1739 Notification
, Param1
, Param2
);
1744 static DWORD CALLBACK
1745 RegistrationProc(LPVOID Parameter
)
1747 PREGISTRATIONDATA RegistrationData
;
1748 REGISTRATIONNOTIFY RegistrationNotify
;
1749 DWORD LastError
= NO_ERROR
;
1750 WCHAR UnknownError
[84];
1752 RegistrationData
= (PREGISTRATIONDATA
) Parameter
;
1753 RegistrationData
->Registered
= 0;
1754 RegistrationData
->DefaultContext
= SetupInitDefaultQueueCallback(RegistrationData
->hwndDlg
);
1758 if (!SetupInstallFromInfSectionW(GetParent(RegistrationData
->hwndDlg
),
1760 L
"RegistrationPhase2",
1762 SPINST_REGISTERCALLBACKAWARE
|
1767 RegistrationNotificationProc
,
1772 LastError
= GetLastError();
1775 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1777 DPRINT("Catching exception\n");
1778 LastError
= RtlNtStatusToDosError(_SEH2_GetExceptionCode());
1782 if (NO_ERROR
== LastError
)
1784 RegistrationNotify
.ErrorMessage
= NULL
;
1788 DPRINT1("SetupInstallFromInfSection failed with error %u\n",
1790 if (0 == FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER
|
1791 FORMAT_MESSAGE_FROM_SYSTEM
, NULL
, LastError
, 0,
1792 (LPWSTR
) &RegistrationNotify
.ErrorMessage
, 0,
1795 if (0 == LoadStringW(hDllInstance
, IDS_UNKNOWN_ERROR
,
1797 sizeof(UnknownError
) / sizeof(UnknownError
[0]) -
1800 wcscpy(UnknownError
, L
"Unknown error");
1802 wcscat(UnknownError
, L
" ");
1803 _ultow(LastError
, UnknownError
+ wcslen(UnknownError
), 10);
1804 RegistrationNotify
.ErrorMessage
= UnknownError
;
1808 RegistrationNotify
.Progress
= RegistrationData
->DllCount
;
1809 RegistrationNotify
.ActivityID
= IDS_REGISTERING_COMPONENTS
;
1810 RegistrationNotify
.CurrentItem
= NULL
;
1811 SendMessage(RegistrationData
->hwndDlg
, PM_REGISTRATION_NOTIFY
,
1812 1, (LPARAM
) &RegistrationNotify
);
1813 if (NULL
!= RegistrationNotify
.ErrorMessage
&&
1814 UnknownError
!= RegistrationNotify
.ErrorMessage
)
1816 LocalFree((PVOID
) RegistrationNotify
.ErrorMessage
);
1819 SetupTermDefaultQueueCallback(RegistrationData
->DefaultContext
);
1820 HeapFree(GetProcessHeap(), 0, RegistrationData
);
1822 RegisterTypeLibraries(hSysSetupInf
, L
"TypeLibraries");
1824 // FIXME: Move this call to a separate cleanup page!
1825 RtlCreateBootStatusDataFile();
1832 StartComponentRegistration(HWND hwndDlg
, PULONG MaxProgress
)
1834 HANDLE RegistrationThread
;
1837 WCHAR SectionName
[512];
1838 PREGISTRATIONDATA RegistrationData
;
1841 if (! SetupFindFirstLineW(hSysSetupInf
, L
"RegistrationPhase2",
1842 L
"RegisterDlls", &Context
))
1844 DPRINT1("No RegistrationPhase2 section found\n");
1847 if (! SetupGetStringFieldW(&Context
, 1, SectionName
,
1848 sizeof(SectionName
) / sizeof(SectionName
[0]),
1851 DPRINT1("Unable to retrieve section name\n");
1854 DllCount
= SetupGetLineCountW(hSysSetupInf
, SectionName
);
1855 DPRINT("SectionName %S DllCount %ld\n", SectionName
, DllCount
);
1858 SetLastError(STATUS_NOT_FOUND
);
1862 *MaxProgress
= (ULONG
) DllCount
;
1865 * Create a background thread to do the actual registrations, so the
1866 * main thread can just run its message loop.
1868 RegistrationThread
= NULL
;
1869 RegistrationData
= HeapAlloc(GetProcessHeap(), 0,
1870 sizeof(REGISTRATIONDATA
));
1871 if (RegistrationData
!= NULL
)
1873 RegistrationData
->hwndDlg
= hwndDlg
;
1874 RegistrationData
->DllCount
= DllCount
;
1875 RegistrationThread
= CreateThread(NULL
, 0, RegistrationProc
,
1876 RegistrationData
, 0, NULL
);
1877 if (RegistrationThread
!= NULL
)
1879 CloseHandle(RegistrationThread
);
1883 DPRINT1("CreateThread failed, error %u\n", GetLastError());
1884 HeapFree(GetProcessHeap(), 0, RegistrationData
);
1890 DPRINT1("HeapAlloc() failed, error %u\n", GetLastError());
1898 static INT_PTR CALLBACK
1899 ProcessPageDlgProc(HWND hwndDlg
,
1904 PSETUPDATA SetupData
;
1905 PREGISTRATIONNOTIFY RegistrationNotify
;
1906 static UINT oldActivityID
= -1;
1909 /* Retrieve pointer to the global setup data */
1910 SetupData
= (PSETUPDATA
)GetWindowLongPtr (hwndDlg
, GWL_USERDATA
);
1916 /* Save pointer to the global setup data */
1917 SetupData
= (PSETUPDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
1918 SetWindowLongPtr(hwndDlg
, GWL_USERDATA
, (DWORD_PTR
)SetupData
);
1924 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
1925 ULONG MaxProgress
= 0;
1930 /* Disable the Back and Next buttons */
1931 PropSheet_SetWizButtons(GetParent(hwndDlg
), 0);
1933 StartComponentRegistration(hwndDlg
, &MaxProgress
);
1935 SendDlgItemMessage(hwndDlg
, IDC_PROCESSPROGRESS
, PBM_SETRANGE
,
1936 0, MAKELPARAM(0, MaxProgress
));
1937 SendDlgItemMessage(hwndDlg
, IDC_PROCESSPROGRESS
, PBM_SETPOS
,
1945 SetupData
->UnattendSetup
= FALSE
;
1954 case PM_REGISTRATION_NOTIFY
:
1957 RegistrationNotify
= (PREGISTRATIONNOTIFY
) lParam
;
1958 // update if necessary only
1959 if (oldActivityID
!= RegistrationNotify
->ActivityID
)
1961 if (0 != LoadStringW(hDllInstance
, RegistrationNotify
->ActivityID
,
1963 sizeof(Activity
) / sizeof(Activity
[0])))
1965 SendDlgItemMessageW(hwndDlg
, IDC_ACTIVITY
, WM_SETTEXT
,
1966 0, (LPARAM
) Activity
);
1968 oldActivityID
= RegistrationNotify
->ActivityID
;
1970 SendDlgItemMessageW(hwndDlg
, IDC_ITEM
, WM_SETTEXT
, 0,
1971 (LPARAM
)(NULL
== RegistrationNotify
->CurrentItem
?
1972 L
"" : RegistrationNotify
->CurrentItem
));
1973 SendDlgItemMessage(hwndDlg
, IDC_PROCESSPROGRESS
, PBM_SETPOS
,
1974 RegistrationNotify
->Progress
, 0);
1975 if (NULL
!= RegistrationNotify
->ErrorMessage
)
1977 if (0 == LoadStringW(hDllInstance
, IDS_REACTOS_SETUP
,
1978 Title
, sizeof(Title
) / sizeof(Title
[0])))
1980 wcscpy(Title
, L
"ReactOS Setup");
1982 MessageBoxW(hwndDlg
, RegistrationNotify
->ErrorMessage
,
1983 Title
, MB_ICONERROR
| MB_OK
);
1990 if(!SetupData
->UnattendSetup
&& !SetupData
->DisableVmwInst
)
1991 RunVMWInstall(GetParent(hwndDlg
));
1994 /* Enable the Back and Next buttons */
1995 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_NEXT
);
1996 PropSheet_PressButton(GetParent(hwndDlg
), PSBTN_NEXT
);
2010 SetInstallationCompleted(VOID
)
2013 DWORD InProgress
= 0;
2016 if (RegOpenKeyExW( HKEY_LOCAL_MACHINE
,
2020 &hKey
) == ERROR_SUCCESS
)
2022 RegSetValueExW( hKey
, L
"SystemSetupInProgress", 0, REG_DWORD
, (LPBYTE
)&InProgress
, sizeof(InProgress
) );
2023 RegCloseKey( hKey
);
2026 if (RegOpenKeyExW( HKEY_LOCAL_MACHINE
,
2027 L
"Software\\Microsoft\\Windows NT\\CurrentVersion",
2030 &hKey
) == ERROR_SUCCESS
)
2032 InstallDate
= (DWORD
)time(NULL
);
2033 RegSetValueExW( hKey
, L
"InstallDate", 0, REG_DWORD
, (LPBYTE
)&InstallDate
, sizeof(InstallDate
) );
2034 RegCloseKey( hKey
);
2038 static INT_PTR CALLBACK
2039 FinishDlgProc(HWND hwndDlg
,
2049 /* Get pointer to the global setup data */
2050 PSETUPDATA SetupData
= (PSETUPDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
2052 if (!SetupData
->UnattendSetup
|| !SetupData
->DisableGeckoInst
)
2054 /* Run the Wine Gecko prompt */
2055 Control_RunDLLW(hwndDlg
, 0, L
"appwiz.cpl install_gecko", SW_SHOW
);
2058 /* Set title font */
2059 SendDlgItemMessage(hwndDlg
,
2062 (WPARAM
)SetupData
->hTitleFont
,
2064 if (SetupData
->UnattendSetup
)
2066 KillTimer(hwndDlg
, 1);
2067 SetInstallationCompleted();
2075 SetInstallationCompleted();
2085 hWndProgress
= GetDlgItem(hwndDlg
, IDC_RESTART_PROGRESS
);
2086 Position
= SendMessage(hWndProgress
, PBM_GETPOS
, 0, 0);
2087 if (Position
== 300)
2089 KillTimer(hwndDlg
, 1);
2090 PropSheet_PressButton(GetParent(hwndDlg
), PSBTN_FINISH
);
2094 SendMessage(hWndProgress
, PBM_SETPOS
, Position
+ 1, 0);
2101 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
2106 /* Enable the correct buttons on for the active page */
2107 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_FINISH
);
2109 SendDlgItemMessage(hwndDlg
, IDC_RESTART_PROGRESS
, PBM_SETRANGE
, 0,
2110 MAKELPARAM(0, 300));
2111 SendDlgItemMessage(hwndDlg
, IDC_RESTART_PROGRESS
, PBM_SETPOS
, 0, 0);
2112 SetTimer(hwndDlg
, 1, 50, NULL
);
2116 DestroyWindow(GetParent(hwndDlg
));
2135 PSETUPDATA pSetupData
)
2137 INFCONTEXT InfContext
;
2139 WCHAR szValue
[MAX_PATH
];
2143 if (!SetupFindFirstLineW(pSetupData
->hUnattendedInf
,
2145 L
"UnattendSetupEnabled",
2148 DPRINT1("Error: Cant find UnattendSetupEnabled Key! %d\n", GetLastError());
2152 if (!SetupGetStringFieldW(&InfContext
,
2155 sizeof(szValue
) / sizeof(WCHAR
),
2158 DPRINT1("Error: SetupGetStringField failed with %d\n", GetLastError());
2162 if (wcscmp(szValue
, L
"yes") != 0)
2164 DPRINT("Unattend setup was disabled by UnattendSetupEnabled key.\n");
2168 pSetupData
->UnattendSetup
= TRUE
;
2170 if (!SetupFindFirstLineW(pSetupData
->hUnattendedInf
,
2175 DPRINT1("Error: SetupFindFirstLine failed %d\n", GetLastError());
2181 if (!SetupGetStringFieldW(&InfContext
,
2184 sizeof(szName
) / sizeof(WCHAR
),
2187 DPRINT1("Error: SetupGetStringField failed with %d\n", GetLastError());
2191 if (!SetupGetStringFieldW(&InfContext
,
2194 sizeof(szValue
) / sizeof(WCHAR
),
2197 DPRINT1("Error: SetupGetStringField failed with %d\n", GetLastError());
2200 DPRINT1("Name %S Value %S\n", szName
, szValue
);
2201 if (!wcscmp(szName
, L
"FullName"))
2203 if ((sizeof(pSetupData
->OwnerName
) / sizeof(TCHAR
)) > LineLength
)
2205 wcscpy(pSetupData
->OwnerName
, szValue
);
2208 else if (!wcscmp(szName
, L
"OrgName"))
2210 if ((sizeof(pSetupData
->OwnerOrganization
) / sizeof(WCHAR
)) > LineLength
)
2212 wcscpy(pSetupData
->OwnerOrganization
, szValue
);
2215 else if (!wcscmp(szName
, L
"ComputerName"))
2217 if ((sizeof(pSetupData
->ComputerName
) / sizeof(WCHAR
)) > LineLength
)
2219 wcscpy(pSetupData
->ComputerName
, szValue
);
2222 else if (!wcscmp(szName
, L
"AdminPassword"))
2224 if ((sizeof(pSetupData
->AdminPassword
) / sizeof(WCHAR
)) > LineLength
)
2226 wcscpy(pSetupData
->AdminPassword
, szValue
);
2229 else if (!wcscmp(szName
, L
"TimeZoneIndex"))
2231 pSetupData
->TimeZoneIndex
= _wtoi(szValue
);
2233 else if (!wcscmp(szName
, L
"DisableAutoDaylightTimeSet"))
2235 pSetupData
->DisableAutoDaylightTimeSet
= _wtoi(szValue
);
2237 else if (!wcscmp(szName
, L
"DisableVmwInst"))
2239 if(!wcscmp(szValue
, L
"yes"))
2240 pSetupData
->DisableVmwInst
= 1;
2242 pSetupData
->DisableVmwInst
= 0;
2244 else if (!wcscmp(szName
, L
"DisableGeckoInst"))
2246 if(!wcscmp(szValue
, L
"yes"))
2247 pSetupData
->DisableGeckoInst
= 1;
2249 pSetupData
->DisableGeckoInst
= 0;
2253 while (SetupFindNextLine(&InfContext
, &InfContext
));
2255 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
2256 L
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunOnce",
2259 &hKey
) != ERROR_SUCCESS
)
2261 DPRINT1("Error: failed to open HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\RunOnce\n");
2265 if (SetupFindFirstLineW(pSetupData
->hUnattendedInf
,
2274 if(SetupGetStringFieldW(&InfContext
,
2277 sizeof(szValue
) / sizeof(WCHAR
),
2280 WCHAR szPath
[MAX_PATH
];
2281 swprintf(szName
, L
"%d", i
);
2282 DPRINT("szName %S szValue %S\n", szName
, szValue
);
2284 if (ExpandEnvironmentStringsW(szValue
, szPath
, MAX_PATH
))
2286 DPRINT("value %S\n", szPath
);
2287 if (RegSetValueExW(hKey
,
2291 (const BYTE
*)szPath
,
2292 (wcslen(szPath
) + 1) * sizeof(WCHAR
)) == ERROR_SUCCESS
)
2298 } while(SetupFindNextLine(&InfContext
, &InfContext
));
2305 * GetRosInstallCD should find the path to ros installation medium
2307 * If there are more than one CDDrive in it containing a ReactOS
2308 * installation cd, then it will pick the first one regardless if
2309 * it is really the installation cd
2311 * The best way to implement this is to set the key
2312 * HKLM\Software\Microsoft\Windows NT\CurrentVersion\SourcePath (REG_SZ)
2316 GetRosInstallCD(WCHAR
*pwszPath
, DWORD cchPathMax
)
2318 WCHAR wszDrives
[512];
2322 cchDrives
= GetLogicalDriveStringsW(_countof(wszDrives
) - 1, wszDrives
);
2323 if (cchDrives
== 0 || cchDrives
>= _countof(wszDrives
))
2325 /* buffer too small or failure */
2326 LogItem(NULL
, L
"GetLogicalDriveStringsW failed");
2330 for (pwszDrive
= wszDrives
; pwszDrive
[0]; pwszDrive
+= wcslen(pwszDrive
) + 1)
2332 if (GetDriveTypeW(pwszDrive
) == DRIVE_CDROM
)
2334 WCHAR wszBuf
[MAX_PATH
];
2335 wsprintf(wszBuf
, L
"%sreactos\\system32\\ntoskrnl.exe", pwszDrive
);
2336 LogItem(NULL
, wszBuf
);
2337 if (GetFileAttributesW(wszBuf
) != INVALID_FILE_ATTRIBUTES
)
2339 /* the file exists, so this is the right drive */
2340 wcsncpy(pwszPath
, pwszDrive
, cchPathMax
);
2341 OutputDebugStringW(L
"GetRosInstallCD: ");OutputDebugStringW(pwszPath
);OutputDebugStringW(L
"\n");
2351 ProcessUnattendSetup(
2352 PSETUPDATA pSetupData
)
2354 WCHAR szPath
[MAX_PATH
];
2357 if (!GetRosInstallCD(szPath
, MAX_PATH
))
2359 /* no cd drive found */
2363 dwLength
= wcslen(szPath
);
2364 if (dwLength
+ 21 > MAX_PATH
)
2367 * allocate bigger buffer
2372 wcscat(szPath
, L
"reactos\\unattend.inf");
2374 pSetupData
->hUnattendedInf
= SetupOpenInfFileW(szPath
,
2378 if (pSetupData
->hUnattendedInf
!= INVALID_HANDLE_VALUE
)
2380 ProcessUnattendInf(pSetupData
);
2384 typedef DWORD(WINAPI
*PFNREQUESTWIZARDPAGES
)(PDWORD
, HPROPSHEETPAGE
*, PSETUPDATA
);
2389 PROPSHEETHEADER psh
;
2390 HPROPSHEETPAGE
*phpage
= NULL
;
2391 PROPSHEETPAGE psp
= {0};
2395 PSETUPDATA pSetupData
= NULL
;
2396 HMODULE hNetShell
= NULL
;
2397 PFNREQUESTWIZARDPAGES pfn
= NULL
;
2398 DWORD dwPageCount
= 8, dwNetworkPageCount
= 0;
2400 LogItem(L
"BEGIN_SECTION", L
"InstallWizard");
2402 /* Allocate setup data */
2403 pSetupData
= HeapAlloc(GetProcessHeap(),
2406 if (pSetupData
== NULL
)
2408 LogItem(NULL
, L
"SetupData allocation failed!");
2410 L
"Setup failed to allocate global data!",
2412 MB_ICONERROR
| MB_OK
);
2416 hNetShell
= LoadLibraryW(L
"netshell.dll");
2417 if (hNetShell
!= NULL
)
2419 DPRINT("Netshell.dll loaded!\n");
2421 pfn
= (PFNREQUESTWIZARDPAGES
)GetProcAddress(hNetShell
,
2422 "NetSetupRequestWizardPages");
2425 pfn(&dwNetworkPageCount
, NULL
, NULL
);
2426 dwPageCount
+= dwNetworkPageCount
;
2430 DPRINT("PageCount: %lu\n", dwPageCount
);
2432 phpage
= HeapAlloc(GetProcessHeap(),
2434 dwPageCount
* sizeof(HPROPSHEETPAGE
));
2437 LogItem(NULL
, L
"Page array allocation failed!");
2439 L
"Setup failed to allocate page array!",
2441 MB_ICONERROR
| MB_OK
);
2445 pSetupData
->hUnattendedInf
= INVALID_HANDLE_VALUE
;
2446 ProcessUnattendSetup(pSetupData
);
2448 /* Create the Welcome page */
2449 psp
.dwSize
= sizeof(PROPSHEETPAGE
);
2450 psp
.dwFlags
= PSP_DEFAULT
| PSP_HIDEHEADER
;
2451 psp
.hInstance
= hDllInstance
;
2452 psp
.lParam
= (LPARAM
)pSetupData
;
2453 psp
.pfnDlgProc
= WelcomeDlgProc
;
2454 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_WELCOMEPAGE
);
2455 phpage
[nPages
++] = CreatePropertySheetPage(&psp
);
2457 /* Create the Acknowledgements page */
2458 psp
.dwFlags
= PSP_DEFAULT
| PSP_USEHEADERTITLE
| PSP_USEHEADERSUBTITLE
;
2459 psp
.pszHeaderTitle
= MAKEINTRESOURCE(IDS_ACKTITLE
);
2460 psp
.pszHeaderSubTitle
= MAKEINTRESOURCE(IDS_ACKSUBTITLE
);
2461 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_ACKPAGE
);
2462 psp
.pfnDlgProc
= AckPageDlgProc
;
2463 phpage
[nPages
++] = CreatePropertySheetPage(&psp
);
2465 /* Create the Locale page */
2466 psp
.dwFlags
= PSP_DEFAULT
| PSP_USEHEADERTITLE
| PSP_USEHEADERSUBTITLE
;
2467 psp
.pszHeaderTitle
= MAKEINTRESOURCE(IDS_LOCALETITLE
);
2468 psp
.pszHeaderSubTitle
= MAKEINTRESOURCE(IDS_LOCALESUBTITLE
);
2469 psp
.pfnDlgProc
= LocalePageDlgProc
;
2470 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_LOCALEPAGE
);
2471 phpage
[nPages
++] = CreatePropertySheetPage(&psp
);
2474 /* Create the Owner page */
2475 psp
.dwFlags
= PSP_DEFAULT
| PSP_USEHEADERTITLE
| PSP_USEHEADERSUBTITLE
;
2476 psp
.pszHeaderTitle
= MAKEINTRESOURCE(IDS_OWNERTITLE
);
2477 psp
.pszHeaderSubTitle
= MAKEINTRESOURCE(IDS_OWNERSUBTITLE
);
2478 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_OWNERPAGE
);
2479 psp
.pfnDlgProc
= OwnerPageDlgProc
;
2480 phpage
[nPages
++] = CreatePropertySheetPage(&psp
);
2482 /* Create the Computer page */
2483 psp
.dwFlags
= PSP_DEFAULT
| PSP_USEHEADERTITLE
| PSP_USEHEADERSUBTITLE
;
2484 psp
.pszHeaderTitle
= MAKEINTRESOURCE(IDS_COMPUTERTITLE
);
2485 psp
.pszHeaderSubTitle
= MAKEINTRESOURCE(IDS_COMPUTERSUBTITLE
);
2486 psp
.pfnDlgProc
= ComputerPageDlgProc
;
2487 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_COMPUTERPAGE
);
2488 phpage
[nPages
++] = CreatePropertySheetPage(&psp
);
2491 /* Create the DateTime page */
2492 psp
.dwFlags
= PSP_DEFAULT
| PSP_USEHEADERTITLE
| PSP_USEHEADERSUBTITLE
;
2493 psp
.pszHeaderTitle
= MAKEINTRESOURCE(IDS_DATETIMETITLE
);
2494 psp
.pszHeaderSubTitle
= MAKEINTRESOURCE(IDS_DATETIMESUBTITLE
);
2495 psp
.pfnDlgProc
= DateTimePageDlgProc
;
2496 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_DATETIMEPAGE
);
2497 phpage
[nPages
++] = CreatePropertySheetPage(&psp
);
2500 pSetupData
->uFirstNetworkWizardPage
= IDD_PROCESSPAGE
;
2501 pSetupData
->uPostNetworkWizardPage
= IDD_PROCESSPAGE
;
2505 pfn(&dwNetworkPageCount
, &phpage
[nPages
], pSetupData
);
2506 nPages
+= dwNetworkPageCount
;
2509 /* Create the Process page */
2510 psp
.dwFlags
= PSP_DEFAULT
| PSP_USEHEADERTITLE
| PSP_USEHEADERSUBTITLE
;
2511 psp
.pszHeaderTitle
= MAKEINTRESOURCE(IDS_PROCESSTITLE
);
2512 psp
.pszHeaderSubTitle
= MAKEINTRESOURCE(IDS_PROCESSSUBTITLE
);
2513 psp
.pfnDlgProc
= ProcessPageDlgProc
;
2514 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_PROCESSPAGE
);
2515 phpage
[nPages
++] = CreatePropertySheetPage(&psp
);
2518 /* Create the Finish page */
2519 psp
.dwFlags
= PSP_DEFAULT
| PSP_HIDEHEADER
;
2520 psp
.pfnDlgProc
= FinishDlgProc
;
2521 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_FINISHPAGE
);
2522 phpage
[nPages
++] = CreatePropertySheetPage(&psp
);
2524 /* Create the property sheet */
2525 psh
.dwSize
= sizeof(PROPSHEETHEADER
);
2526 psh
.dwFlags
= PSH_WIZARD97
| PSH_WATERMARK
| PSH_HEADER
| PSH_MODELESS
;
2527 psh
.hInstance
= hDllInstance
;
2528 psh
.hwndParent
= NULL
;
2529 psh
.nPages
= nPages
;
2531 psh
.phpage
= phpage
;
2532 psh
.pszbmWatermark
= MAKEINTRESOURCE(IDB_WATERMARK
);
2533 psh
.pszbmHeader
= MAKEINTRESOURCE(IDB_HEADER
);
2535 /* Create title font */
2536 pSetupData
->hTitleFont
= CreateTitleFont();
2537 pSetupData
->hBoldFont
= CreateBoldFont();
2539 /* Display the wizard */
2540 hWnd
= (HWND
)PropertySheet(&psh
);
2541 ShowWindow(hWnd
, SW_SHOW
);
2543 while (GetMessage(&msg
, NULL
, 0, 0))
2545 if (!IsDialogMessage(hWnd
, &msg
))
2547 TranslateMessage(&msg
);
2548 DispatchMessage(&msg
);
2552 if (pSetupData
->hUnattendedInf
!= INVALID_HANDLE_VALUE
)
2553 SetupCloseInfFile(pSetupData
->hUnattendedInf
);
2557 HeapFree(GetProcessHeap(), 0, phpage
);
2559 if (hNetShell
!= NULL
)
2560 FreeLibrary(hNetShell
);
2562 if (pSetupData
!= NULL
)
2564 DeleteObject(pSetupData
->hBoldFont
);
2565 DeleteObject(pSetupData
->hTitleFont
);
2566 HeapFree(GetProcessHeap(), 0, pSetupData
);
2569 LogItem(L
"END_SECTION", L
"InstallWizard");