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 *****************************************************************/
13 #define WIN32_NO_STATUS
19 #include <pseh/pseh2.h>
21 #define NTOS_MODE_USER
22 #include <ndk/ntndk.h>
24 #include <syssetup/syssetup.h>
34 #define PM_REGISTRATION_NOTIFY (WM_APP + 1)
35 /* Private Message used to communicate progress from the background
36 registration thread to the main thread.
37 wParam = 0 Registration in progress
38 = 1 Registration completed
39 lParam = Pointer to a REGISTRATIONNOTIFY structure */
41 typedef struct _REGISTRATIONNOTIFY
47 } REGISTRATIONNOTIFY
, *PREGISTRATIONNOTIFY
;
49 typedef struct _REGISTRATIONDATA
55 } REGISTRATIONDATA
, *PREGISTRATIONDATA
;
57 /* GLOBALS ******************************************************************/
62 /* FUNCTIONS ****************************************************************/
64 GetRosInstallCD(WCHAR
* szPath
, DWORD dwPathLength
);
68 RunVMWInstall(HWND hWnd
)
70 PROCESS_INFORMATION ProcInfo
;
73 STARTUPINFOW si
= {0};
74 WCHAR InstallName
[] = L
"vmwinst.exe";
76 si
.cb
= sizeof(STARTUPINFO
);
78 if(CreateProcessW(NULL
, InstallName
, NULL
, NULL
, TRUE
, NORMAL_PRIORITY_CLASS
,
79 NULL
, NULL
, &si
, &ProcInfo
))
81 EnableWindow(hWnd
, FALSE
);
84 while (PeekMessage(&msg
, NULL
, 0, 0, PM_REMOVE
))
86 if (msg
.message
== WM_QUIT
)
88 TranslateMessage(&msg
);
89 DispatchMessage(&msg
);
92 ret
= MsgWaitForMultipleObjects(1, &ProcInfo
.hProcess
, FALSE
, INFINITE
, QS_ALLEVENTS
| QS_ALLINPUT
);
93 if (ret
== WAIT_OBJECT_0
)
97 EnableWindow(hWnd
, TRUE
);
99 CloseHandle(ProcInfo
.hThread
);
100 CloseHandle(ProcInfo
.hProcess
);
108 CenterWindow(HWND hWnd
)
114 hWndParent
= GetParent(hWnd
);
115 if (hWndParent
== NULL
)
116 hWndParent
= GetDesktopWindow();
118 GetWindowRect(hWndParent
, &rcParent
);
119 GetWindowRect(hWnd
, &rcWindow
);
123 ((rcParent
.right
- rcParent
.left
) - (rcWindow
.right
- rcWindow
.left
)) / 2,
124 ((rcParent
.bottom
- rcParent
.top
) - (rcWindow
.bottom
- rcWindow
.top
)) / 2,
132 CreateTitleFont(VOID
)
134 NONCLIENTMETRICSW ncm
;
140 ncm
.cbSize
= sizeof(NONCLIENTMETRICSW
);
141 SystemParametersInfo(SPI_GETNONCLIENTMETRICS
, 0, &ncm
, 0);
143 LogFont
= ncm
.lfMessageFont
;
144 LogFont
.lfWeight
= FW_BOLD
;
145 wcscpy(LogFont
.lfFaceName
, L
"MS Shell Dlg");
149 LogFont
.lfHeight
= 0 - GetDeviceCaps(hdc
, LOGPIXELSY
) * FontSize
/ 72;
150 hFont
= CreateFontIndirectW(&LogFont
);
151 ReleaseDC(NULL
, hdc
);
157 static INT_PTR CALLBACK
158 GplDlgProc(HWND hwndDlg
,
163 HRSRC GplTextResource
;
173 GplTextResource
= FindResourceW(hDllInstance
, MAKEINTRESOURCE(IDR_GPL
), L
"RT_TEXT");
174 if (NULL
== GplTextResource
)
178 Size
= SizeofResource(hDllInstance
, GplTextResource
);
183 GplText
= HeapAlloc(GetProcessHeap(), 0, Size
+ 1);
188 GplTextMem
= LoadResource(hDllInstance
, GplTextResource
);
189 if (NULL
== GplTextMem
)
191 HeapFree(GetProcessHeap(), 0, GplText
);
194 GplTextLocked
= LockResource(GplTextMem
);
195 if (NULL
== GplTextLocked
)
197 HeapFree(GetProcessHeap(), 0, GplText
);
200 memcpy(GplText
, GplTextLocked
, Size
);
201 GplText
[Size
] = '\0';
202 SendMessageA(GetDlgItem(hwndDlg
, IDC_GPL_TEXT
), WM_SETTEXT
, 0, (LPARAM
) GplText
);
203 HeapFree(GetProcessHeap(), 0, GplText
);
204 SetFocus(GetDlgItem(hwndDlg
, IDOK
));
208 EndDialog(hwndDlg
, IDCANCEL
);
212 if (HIWORD(wParam
) == BN_CLICKED
&& IDOK
== LOWORD(wParam
))
214 EndDialog(hwndDlg
, IDOK
);
226 static INT_PTR CALLBACK
227 WelcomeDlgProc(HWND hwndDlg
,
236 PSETUPDATA SetupData
;
240 /* Get pointer to the global setup data */
241 SetupData
= (PSETUPDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
243 hwndControl
= GetParent(hwndDlg
);
245 /* Center the wizard window */
246 CenterWindow (hwndControl
);
248 /* Hide the system menu */
249 dwStyle
= GetWindowLongPtr(hwndControl
, GWL_STYLE
);
250 SetWindowLongPtr(hwndControl
, GWL_STYLE
, dwStyle
& ~WS_SYSMENU
);
252 /* Hide and disable the 'Cancel' button */
253 hwndControl
= GetDlgItem(GetParent(hwndDlg
), IDCANCEL
);
254 ShowWindow (hwndControl
, SW_HIDE
);
255 EnableWindow (hwndControl
, FALSE
);
258 SendDlgItemMessage(hwndDlg
,
261 (WPARAM
)SetupData
->hTitleFont
,
269 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
274 /* Enable the Next button */
275 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_NEXT
);
276 if (SetupData
.UnattendSetup
)
278 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, IDD_ACKPAGE
);
284 SetupData
.UnattendSetup
= FALSE
;
301 static INT_PTR CALLBACK
302 AckPageDlgProc(HWND hwndDlg
,
309 PWCHAR End
, CurrentProject
;
310 INT ProjectsSize
, ProjectsCount
;
320 Projects
= HeapAlloc(GetProcessHeap(), 0, ProjectsSize
* sizeof(WCHAR
));
321 if (NULL
== Projects
)
325 ProjectsCount
= LoadStringW(hDllInstance
, IDS_ACKPROJECTS
, Projects
, ProjectsSize
);
326 if (0 == ProjectsCount
)
328 HeapFree(GetProcessHeap(), 0, Projects
);
331 if (ProjectsCount
< ProjectsSize
- 1)
335 HeapFree(GetProcessHeap(), 0, Projects
);
339 CurrentProject
= Projects
;
340 while (L
'\0' != *CurrentProject
)
342 End
= wcschr(CurrentProject
, L
'\n');
347 (void)ListBox_AddString(GetDlgItem(hwndDlg
, IDC_PROJECTS
), CurrentProject
);
350 CurrentProject
= End
+ 1;
354 CurrentProject
+= wcslen(CurrentProject
);
357 HeapFree(GetProcessHeap(), 0, Projects
);
362 if (HIWORD(wParam
) == BN_CLICKED
&& IDC_VIEWGPL
== LOWORD(wParam
))
364 DialogBox(hDllInstance
, MAKEINTRESOURCE(IDD_GPL
), NULL
, GplDlgProc
);
370 lpnm
= (LPNMHDR
)lParam
;
375 /* Enable the Back and Next buttons */
376 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_BACK
| PSWIZB_NEXT
);
377 if (SetupData
.UnattendSetup
)
379 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, IDD_OWNERPAGE
);
385 SetupData
.UnattendSetup
= FALSE
;
403 WriteOwnerSettings(WCHAR
* OwnerName
,
404 WCHAR
* OwnerOrganization
)
411 res
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
412 L
"Software\\Microsoft\\Windows NT\\CurrentVersion",
417 if (res
!= ERROR_SUCCESS
)
422 res
= RegSetValueExW(hKey
,
427 (wcslen(OwnerName
) + 1) * sizeof(WCHAR
));
429 if (res
!= ERROR_SUCCESS
)
435 res
= RegSetValueExW(hKey
,
436 L
"RegisteredOrganization",
439 (LPBYTE
)OwnerOrganization
,
440 (wcslen(OwnerOrganization
) + 1) * sizeof(WCHAR
));
443 return (res
== ERROR_SUCCESS
);
446 static INT_PTR CALLBACK
447 OwnerPageDlgProc(HWND hwndDlg
,
453 WCHAR OwnerOrganization
[51];
455 WCHAR ErrorName
[256];
462 SendDlgItemMessage(hwndDlg
, IDC_OWNERNAME
, EM_LIMITTEXT
, 50, 0);
463 SendDlgItemMessage(hwndDlg
, IDC_OWNERORGANIZATION
, EM_LIMITTEXT
, 50, 0);
465 /* Set focus to owner name */
466 SetFocus(GetDlgItem(hwndDlg
, IDC_OWNERNAME
));
473 lpnm
= (LPNMHDR
)lParam
;
478 /* Enable the Back and Next buttons */
479 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_BACK
| PSWIZB_NEXT
);
480 if (SetupData
.UnattendSetup
)
482 SendMessage(GetDlgItem(hwndDlg
, IDC_OWNERNAME
), WM_SETTEXT
, 0, (LPARAM
)SetupData
.OwnerName
);
483 SendMessage(GetDlgItem(hwndDlg
, IDC_OWNERORGANIZATION
), WM_SETTEXT
, 0, (LPARAM
)SetupData
.OwnerOrganization
);
484 if (WriteOwnerSettings(SetupData
.OwnerName
, SetupData
.OwnerOrganization
))
486 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, IDD_COMPUTERPAGE
);
494 if (GetDlgItemTextW(hwndDlg
, IDC_OWNERNAME
, OwnerName
, 50) == 0)
496 if (0 == LoadStringW(hDllInstance
, IDS_REACTOS_SETUP
, Title
, sizeof(Title
) / sizeof(Title
[0])))
498 wcscpy(Title
, L
"ReactOS Setup");
500 if (0 == LoadStringW(hDllInstance
, IDS_WZD_NAME
, ErrorName
, sizeof(ErrorName
) / sizeof(ErrorName
[0])))
502 wcscpy(ErrorName
, L
"Setup cannot continue until you enter your name.");
504 MessageBoxW(hwndDlg
, ErrorName
, Title
, MB_ICONERROR
| MB_OK
);
506 SetFocus(GetDlgItem(hwndDlg
, IDC_OWNERNAME
));
507 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, -1);
512 OwnerOrganization
[0] = 0;
513 GetDlgItemTextW(hwndDlg
, IDC_OWNERORGANIZATION
, OwnerOrganization
, 50);
515 if (!WriteOwnerSettings(OwnerName
, OwnerOrganization
))
517 SetFocus(GetDlgItem(hwndDlg
, IDC_OWNERNAME
));
518 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, -1);
523 SetupData
.UnattendSetup
= FALSE
;
540 WriteComputerSettings(WCHAR
* ComputerName
, HWND hwndDlg
)
543 WCHAR ErrorComputerName
[256];
544 if (!SetComputerNameW(ComputerName
))
546 if (0 == LoadStringW(hDllInstance
, IDS_REACTOS_SETUP
, Title
, sizeof(Title
) / sizeof(Title
[0])))
548 wcscpy(Title
, L
"ReactOS Setup");
550 if (0 == LoadStringW(hDllInstance
, IDS_WZD_SETCOMPUTERNAME
, ErrorComputerName
,
551 sizeof(ErrorComputerName
) / sizeof(ErrorComputerName
[0])))
553 wcscpy(ErrorComputerName
, L
"Setup failed to set the computer name.");
555 MessageBoxW(hwndDlg
, ErrorComputerName
, Title
, MB_ICONERROR
| MB_OK
);
560 /* Try to also set DNS hostname */
561 SetComputerNameExW(ComputerNamePhysicalDnsHostname
, ComputerName
);
566 static INT_PTR CALLBACK
567 ComputerPageDlgProc(HWND hwndDlg
,
572 WCHAR ComputerName
[MAX_COMPUTERNAME_LENGTH
+ 1];
577 WCHAR EmptyComputerName
[256], NotMatchPassword
[256], WrongPassword
[256];
581 if (0 == LoadStringW(hDllInstance
, IDS_REACTOS_SETUP
, Title
, sizeof(Title
) / sizeof(Title
[0])))
583 wcscpy(Title
, L
"ReactOS Setup");
590 /* Retrieve current computer name */
591 Length
= MAX_COMPUTERNAME_LENGTH
+ 1;
592 GetComputerNameW(ComputerName
, &Length
);
594 /* Display current computer name */
595 SetDlgItemTextW(hwndDlg
, IDC_COMPUTERNAME
, ComputerName
);
597 /* Set text limits */
598 SendDlgItemMessage(hwndDlg
, IDC_COMPUTERNAME
, EM_LIMITTEXT
, 64, 0);
599 SendDlgItemMessage(hwndDlg
, IDC_ADMINPASSWORD1
, EM_LIMITTEXT
, 14, 0);
600 SendDlgItemMessage(hwndDlg
, IDC_ADMINPASSWORD2
, EM_LIMITTEXT
, 14, 0);
602 /* Set focus to computer name */
603 SetFocus(GetDlgItem(hwndDlg
, IDC_COMPUTERNAME
));
604 if (SetupData
.UnattendSetup
)
606 SendMessage(GetDlgItem(hwndDlg
, IDC_COMPUTERNAME
), WM_SETTEXT
, 0, (LPARAM
)SetupData
.ComputerName
);
607 SendMessage(GetDlgItem(hwndDlg
, IDC_ADMINPASSWORD1
), WM_SETTEXT
, 0, (LPARAM
)SetupData
.AdminPassword
);
608 SendMessage(GetDlgItem(hwndDlg
, IDC_ADMINPASSWORD2
), WM_SETTEXT
, 0, (LPARAM
)SetupData
.AdminPassword
);
617 lpnm
= (LPNMHDR
)lParam
;
622 /* Enable the Back and Next buttons */
623 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_BACK
| PSWIZB_NEXT
);
624 if (SetupData
.UnattendSetup
&& WriteComputerSettings(SetupData
.ComputerName
, hwndDlg
))
626 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, IDD_LOCALEPAGE
);
632 if (GetDlgItemTextW(hwndDlg
, IDC_COMPUTERNAME
, ComputerName
, 64) == 0)
634 if (0 == LoadStringW(hDllInstance
, IDS_WZD_COMPUTERNAME
, EmptyComputerName
,
635 sizeof(EmptyComputerName
) / sizeof(EmptyComputerName
[0])))
637 wcscpy(EmptyComputerName
, L
"Setup cannot continue until you enter the name of your computer.");
639 MessageBoxW(hwndDlg
, EmptyComputerName
, Title
, MB_ICONERROR
| MB_OK
);
640 SetFocus(GetDlgItem(hwndDlg
, IDC_COMPUTERNAME
));
641 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, -1);
645 /* No need to check computer name for invalid characters,
646 * SetComputerName() will do it for us */
648 if (!WriteComputerSettings(ComputerName
, hwndDlg
))
650 SetFocus(GetDlgItem(hwndDlg
, IDC_COMPUTERNAME
));
651 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, -1);
656 /* Check if admin passwords have been entered */
657 if ((GetDlgItemText(hwndDlg
, IDC_ADMINPASSWORD1
, Password1
, 15) == 0) ||
658 (GetDlgItemText(hwndDlg
, IDC_ADMINPASSWORD2
, Password2
, 15) == 0))
660 if (0 == LoadStringW(hDllInstance
, IDS_WZD_PASSWORDEMPTY
, EmptyPassword
,
661 sizeof(EmptyPassword
) / sizeof(EmptyPassword
[0])))
663 wcscpy(EmptyPassword
, L
"You must enter a password !");
665 MessageBoxW(hwndDlg
, EmptyPassword
, Title
, MB_ICONERROR
| MB_OK
);
666 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, -1);
670 GetDlgItemTextW(hwndDlg
, IDC_ADMINPASSWORD1
, Password1
, 15);
671 GetDlgItemTextW(hwndDlg
, IDC_ADMINPASSWORD2
, Password2
, 15);
673 /* Check if passwords match */
674 if (wcscmp(Password1
, Password2
))
676 if (0 == LoadStringW(hDllInstance
, IDS_WZD_PASSWORDMATCH
, NotMatchPassword
,
677 sizeof(NotMatchPassword
) / sizeof(NotMatchPassword
[0])))
679 wcscpy(NotMatchPassword
, L
"The passwords you entered do not match. Please enter the desired password again.");
681 MessageBoxW(hwndDlg
, NotMatchPassword
, Title
, MB_ICONERROR
| MB_OK
);
682 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, -1);
686 /* Check password for invalid characters */
687 Password
= (PWCHAR
)Password1
;
690 if (!isprint(*Password
))
692 if (0 == LoadStringW(hDllInstance
, IDS_WZD_PASSWORDCHAR
, WrongPassword
,
693 sizeof(WrongPassword
) / sizeof(WrongPassword
[0])))
695 wcscpy(WrongPassword
, L
"The password you entered contains invalid characters. Please enter a cleaned password.");
697 MessageBoxW(hwndDlg
, WrongPassword
, Title
, MB_ICONERROR
| MB_OK
);
698 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, -1);
705 /* FIXME: Set admin password */
709 SetupData
.UnattendSetup
= FALSE
;
727 SetKeyboardLayoutName(HWND hwnd
)
730 TCHAR szLayoutPath
[256];
731 TCHAR szLocaleName
[32];
735 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE
,
736 _T("SYSTEM\\CurrentControlSet\\Control\\NLS\\Locale"),
742 dwValueSize
= 16 * sizeof(TCHAR
);
743 if (RegQueryValueEx(hKey
,
754 _tcscpy(szLayoutPath
,
755 _T("SYSTEM\\CurrentControlSet\\Control\\Keyboard Layouts\\"));
756 _tcscat(szLayoutPath
,
759 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE
,
766 dwValueSize
= 32 * sizeof(TCHAR
);
767 if (RegQueryValueEx(hKey
,
784 RunControlPanelApplet(HWND hwnd
, WCHAR
*lpCommandLine
)
786 STARTUPINFOW StartupInfo
;
787 PROCESS_INFORMATION ProcessInformation
;
789 ZeroMemory(&StartupInfo
, sizeof(STARTUPINFOW
));
790 StartupInfo
.cb
= sizeof(STARTUPINFOW
);
792 if (!CreateProcessW(NULL
,
801 &ProcessInformation
))
803 MessageBoxW(hwnd
, L
"Error: failed to launch rundll32", NULL
, MB_ICONERROR
);
807 WaitForSingleObject(ProcessInformation
.hProcess
, INFINITE
);
808 CloseHandle(ProcessInformation
.hThread
);
809 CloseHandle(ProcessInformation
.hProcess
);
814 WriteUserLocale(VOID
)
820 lcid
= GetSystemDefaultLCID();
822 if (GetLocaleInfoW(MAKELCID(lcid
, SORT_DEFAULT
), LOCALE_ILANGUAGE
, Locale
, sizeof(Locale
) / sizeof(Locale
[0])) != 0)
824 if (RegCreateKeyExW(HKEY_CURRENT_USER
, L
"Control Panel\\International",
825 0, NULL
, REG_OPTION_NON_VOLATILE
,
826 KEY_WRITE
, NULL
, &hKey
, NULL
) == ERROR_SUCCESS
)
828 RegSetValueExW(hKey
, L
"Locale", 0, REG_SZ
, (LPBYTE
)Locale
, (wcslen(Locale
)+1) * sizeof(WCHAR
));
834 static INT_PTR CALLBACK
835 LocalePageDlgProc(HWND hwndDlg
,
840 PSETUPDATA SetupData
;
841 WCHAR szBuffer
[1024];
843 /* Retrieve pointer to the global setup data */
844 SetupData
= (PSETUPDATA
)GetWindowLongPtr (hwndDlg
, GWL_USERDATA
);
850 /* Save pointer to the global setup data */
851 SetupData
= (PSETUPDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
852 SetWindowLongPtr(hwndDlg
, GWL_USERDATA
, (DWORD_PTR
)SetupData
);
855 SetKeyboardLayoutName(GetDlgItem(hwndDlg
, IDC_LAYOUTTEXT
));
860 if (HIWORD(wParam
) == BN_CLICKED
)
862 switch (LOWORD(wParam
))
864 case IDC_CUSTOMLOCALE
:
866 wcscpy(szBuffer
, L
"rundll32.exe shell32.dll,Control_RunDLL intl.cpl,,5");
867 RunControlPanelApplet(hwndDlg
, szBuffer
);
868 /* FIXME: Update input locale name */
872 case IDC_CUSTOMLAYOUT
:
874 wcscpy(szBuffer
, L
"rundll32.exe shell32.dll,Control_RunDLL input.dll,@1");
875 RunControlPanelApplet(hwndDlg
, szBuffer
);
884 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
889 /* Enable the Back and Next buttons */
890 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_BACK
| PSWIZB_NEXT
);
891 if (SetupData
->UnattendSetup
)
893 WCHAR szPath
[MAX_PATH
];
894 if (GetRosInstallCD(szPath
, MAX_PATH
))
896 swprintf(szBuffer
, L
"rundll32.exe shell32.dll,Control_RunDLL intl.cpl,,/f:\"%S\\reactos\\unattend.inf\"", szPath
);
900 wcscpy(szBuffer
, L
"rundll32.exe shell32.dll,Control_RunDLL intl.cpl,,/f:\"unattend.inf\"");
903 RunControlPanelApplet(hwndDlg
, szBuffer
);
904 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, IDD_DATETIMEPAGE
);
913 SetupData
->UnattendSetup
= FALSE
;
930 static PTIMEZONE_ENTRY
931 GetLargerTimeZoneEntry(PSETUPDATA SetupData
, DWORD Index
)
933 PTIMEZONE_ENTRY Entry
;
935 Entry
= SetupData
->TimeZoneListHead
;
936 while (Entry
!= NULL
)
938 if (Entry
->Index
>= Index
)
949 CreateTimeZoneList(PSETUPDATA SetupData
)
951 WCHAR szKeyName
[256];
959 PTIMEZONE_ENTRY Entry
;
960 PTIMEZONE_ENTRY Current
;
962 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
963 L
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones",
972 dwNameSize
= 256 * sizeof(WCHAR
);
973 lError
= RegEnumKeyExW(hZonesKey
,
981 if (lError
!= ERROR_SUCCESS
&& lError
!= ERROR_MORE_DATA
)
984 if (RegOpenKeyExW(hZonesKey
,
991 Entry
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(TIMEZONE_ENTRY
));
994 RegCloseKey(hZoneKey
);
998 dwValueSize
= 64 * sizeof(TCHAR
);
999 if (RegQueryValueExW(hZoneKey
,
1003 (LPBYTE
)&Entry
->Description
,
1006 RegCloseKey(hZoneKey
);
1010 dwValueSize
= 32 * sizeof(TCHAR
);
1011 if (RegQueryValueExW(hZoneKey
,
1015 (LPBYTE
)&Entry
->StandardName
,
1018 RegCloseKey(hZoneKey
);
1022 dwValueSize
= 32 * sizeof(WCHAR
);
1023 if (RegQueryValueExW(hZoneKey
,
1027 (LPBYTE
)&Entry
->DaylightName
,
1030 RegCloseKey(hZoneKey
);
1034 dwValueSize
= sizeof(DWORD
);
1035 if (RegQueryValueExW(hZoneKey
,
1039 (LPBYTE
)&Entry
->Index
,
1042 RegCloseKey(hZoneKey
);
1046 dwValueSize
= sizeof(TZ_INFO
);
1047 if (RegQueryValueExW(hZoneKey
,
1051 (LPBYTE
)&Entry
->TimezoneInfo
,
1054 RegCloseKey(hZoneKey
);
1058 RegCloseKey(hZoneKey
);
1060 if (SetupData
->TimeZoneListHead
== NULL
&&
1061 SetupData
->TimeZoneListTail
== NULL
)
1065 SetupData
->TimeZoneListHead
= Entry
;
1066 SetupData
->TimeZoneListTail
= Entry
;
1070 Current
= GetLargerTimeZoneEntry(SetupData
, Entry
->Index
);
1071 if (Current
!= NULL
)
1073 if (Current
== SetupData
->TimeZoneListHead
)
1075 /* Prepend to head */
1077 Entry
->Next
= SetupData
->TimeZoneListHead
;
1078 SetupData
->TimeZoneListHead
->Prev
= Entry
;
1079 SetupData
->TimeZoneListHead
= Entry
;
1083 /* Insert before current */
1084 Entry
->Prev
= Current
->Prev
;
1085 Entry
->Next
= Current
;
1086 Current
->Prev
->Next
= Entry
;
1087 Current
->Prev
= Entry
;
1092 /* Append to tail */
1093 Entry
->Prev
= SetupData
->TimeZoneListTail
;
1095 SetupData
->TimeZoneListTail
->Next
= Entry
;
1096 SetupData
->TimeZoneListTail
= Entry
;
1103 RegCloseKey(hZonesKey
);
1108 DestroyTimeZoneList(PSETUPDATA SetupData
)
1110 PTIMEZONE_ENTRY Entry
;
1112 while (SetupData
->TimeZoneListHead
!= NULL
)
1114 Entry
= SetupData
->TimeZoneListHead
;
1116 SetupData
->TimeZoneListHead
= Entry
->Next
;
1117 if (SetupData
->TimeZoneListHead
!= NULL
)
1119 SetupData
->TimeZoneListHead
->Prev
= NULL
;
1122 HeapFree(GetProcessHeap(), 0, Entry
);
1125 SetupData
->TimeZoneListTail
= NULL
;
1129 GetTimeZoneListIndex(LPDWORD lpIndex
)
1131 WCHAR szLanguageIdString
[9];
1138 BOOL bFound
= FALSE
;
1139 unsigned long iLanguageID
;
1141 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
1142 L
"SYSTEM\\CurrentControlSet\\Control\\NLS\\Language",
1148 dwValueSize
= 9 * sizeof(TCHAR
);
1149 if (RegQueryValueExW(hKey
,
1153 (LPBYTE
)szLanguageIdString
,
1160 iLanguageID
= wcstoul(szLanguageIdString
, NULL
, 16);
1163 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
1164 L
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones",
1171 if (RegQueryValueExW(hKey
,
1182 Buffer
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, dwValueSize
);
1189 if (RegQueryValueExW(hKey
,
1196 HeapFree(GetProcessHeap(), 0, Buffer
);
1206 Length
= wcslen(Ptr
);
1207 if (wcstoul(Ptr
, NULL
, 16) == iLanguageID
)
1210 Ptr
= Ptr
+ Length
+ 1;
1216 *lpIndex
= wcstoul(Ptr
, &End
, 10);
1217 HeapFree(GetProcessHeap(), 0, Buffer
);
1221 Length
= wcslen(Ptr
);
1222 Ptr
= Ptr
+ Length
+ 1;
1225 HeapFree(GetProcessHeap(), 0, Buffer
);
1232 ShowTimeZoneList(HWND hwnd
, PSETUPDATA SetupData
, DWORD dwEntryIndex
)
1234 PTIMEZONE_ENTRY Entry
;
1238 GetTimeZoneListIndex(&dwEntryIndex
);
1240 Entry
= SetupData
->TimeZoneListHead
;
1241 while (Entry
!= NULL
)
1243 dwCount
= SendMessage(hwnd
,
1246 (LPARAM
)Entry
->Description
);
1248 if (dwEntryIndex
!= 0 && dwEntryIndex
== Entry
->Index
)
1251 Entry
= Entry
->Next
;
1262 SetLocalTimeZone(HWND hwnd
, PSETUPDATA SetupData
)
1264 TIME_ZONE_INFORMATION TimeZoneInformation
;
1265 PTIMEZONE_ENTRY Entry
;
1269 dwIndex
= SendMessage(hwnd
,
1275 Entry
= SetupData
->TimeZoneListHead
;
1282 Entry
= Entry
->Next
;
1285 wcscpy(TimeZoneInformation
.StandardName
,
1286 Entry
->StandardName
);
1287 wcscpy(TimeZoneInformation
.DaylightName
,
1288 Entry
->DaylightName
);
1290 TimeZoneInformation
.Bias
= Entry
->TimezoneInfo
.Bias
;
1291 TimeZoneInformation
.StandardBias
= Entry
->TimezoneInfo
.StandardBias
;
1292 TimeZoneInformation
.DaylightBias
= Entry
->TimezoneInfo
.DaylightBias
;
1294 memcpy(&TimeZoneInformation
.StandardDate
,
1295 &Entry
->TimezoneInfo
.StandardDate
,
1296 sizeof(SYSTEMTIME
));
1297 memcpy(&TimeZoneInformation
.DaylightDate
,
1298 &Entry
->TimezoneInfo
.DaylightDate
,
1299 sizeof(SYSTEMTIME
));
1301 /* Set time zone information */
1302 SetTimeZoneInformation(&TimeZoneInformation
);
1307 GetLocalSystemTime(HWND hwnd
, PSETUPDATA SetupData
)
1312 if (DateTime_GetSystemtime(GetDlgItem(hwnd
, IDC_DATEPICKER
), &Date
) != GDT_VALID
)
1317 if (DateTime_GetSystemtime(GetDlgItem(hwnd
, IDC_TIMEPICKER
), &Time
) != GDT_VALID
)
1322 SetupData
->SystemTime
.wYear
= Date
.wYear
;
1323 SetupData
->SystemTime
.wMonth
= Date
.wMonth
;
1324 SetupData
->SystemTime
.wDayOfWeek
= Date
.wDayOfWeek
;
1325 SetupData
->SystemTime
.wDay
= Date
.wDay
;
1326 SetupData
->SystemTime
.wHour
= Time
.wHour
;
1327 SetupData
->SystemTime
.wMinute
= Time
.wMinute
;
1328 SetupData
->SystemTime
.wSecond
= Time
.wSecond
;
1329 SetupData
->SystemTime
.wMilliseconds
= Time
.wMilliseconds
;
1336 SetAutoDaylightInfo(HWND hwnd
)
1341 if (SendMessage(hwnd
, BM_GETCHECK
, 0, 0) == BST_UNCHECKED
)
1343 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
1344 L
"SYSTEM\\CurrentControlSet\\Control\\TimeZoneInformation",
1350 RegSetValueExW(hKey
,
1351 L
"DisableAutoDaylightTimeSet",
1362 SetSystemLocalTime(HWND hwnd
, PSETUPDATA SetupData
)
1366 TOKEN_PRIVILEGES priv
, previouspriv
;
1370 * enable the SeSystemtimePrivilege privilege
1373 if(OpenProcessToken(GetCurrentProcess(),
1374 TOKEN_ADJUST_PRIVILEGES
| TOKEN_QUERY
,
1377 priv
.PrivilegeCount
= 1;
1378 priv
.Privileges
[0].Attributes
= SE_PRIVILEGE_ENABLED
;
1380 if(LookupPrivilegeValue(NULL
,
1382 &priv
.Privileges
[0].Luid
))
1384 if(AdjustTokenPrivileges(hToken
,
1387 sizeof(previouspriv
),
1390 GetLastError() == ERROR_SUCCESS
)
1393 * We successfully enabled it, we're permitted to change the system time
1394 * Call SetLocalTime twice to ensure correct results
1396 Ret
= SetLocalTime(&SetupData
->SystemTime
) &&
1397 SetLocalTime(&SetupData
->SystemTime
);
1400 * for the sake of security, restore the previous status again
1402 if(previouspriv
.PrivilegeCount
> 0)
1404 AdjustTokenPrivileges(hToken
,
1413 CloseHandle(hToken
);
1420 WriteDateTimeSettings(HWND hwndDlg
, PSETUPDATA SetupData
)
1423 WCHAR ErrorLocalTime
[256];
1424 GetLocalSystemTime(hwndDlg
, SetupData
);
1425 SetLocalTimeZone(GetDlgItem(hwndDlg
, IDC_TIMEZONELIST
),
1428 SetAutoDaylightInfo(GetDlgItem(hwndDlg
, IDC_AUTODAYLIGHT
));
1429 if(!SetSystemLocalTime(hwndDlg
, SetupData
))
1431 if (0 == LoadStringW(hDllInstance
, IDS_REACTOS_SETUP
, Title
, sizeof(Title
) / sizeof(Title
[0])))
1433 wcscpy(Title
, L
"ReactOS Setup");
1435 if (0 == LoadStringW(hDllInstance
, IDS_WZD_LOCALTIME
, ErrorLocalTime
,
1436 sizeof(ErrorLocalTime
) / sizeof(ErrorLocalTime
[0])))
1438 wcscpy(ErrorLocalTime
, L
"Setup failed to set the computer name.");
1440 MessageBoxW(hwndDlg
, ErrorLocalTime
, Title
, MB_ICONWARNING
| MB_OK
);
1447 static INT_PTR CALLBACK
1448 DateTimePageDlgProc(HWND hwndDlg
,
1453 PSETUPDATA SetupData
;
1455 WCHAR ErrorLocalTime
[256];
1457 /* Retrieve pointer to the global setup data */
1458 SetupData
= (PSETUPDATA
)GetWindowLongPtr (hwndDlg
, GWL_USERDATA
);
1464 /* Save pointer to the global setup data */
1465 SetupData
= (PSETUPDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
1466 SetWindowLongPtr(hwndDlg
, GWL_USERDATA
, (DWORD_PTR
)SetupData
);
1468 CreateTimeZoneList(SetupData
);
1470 if (SetupData
->UnattendSetup
)
1472 ShowTimeZoneList(GetDlgItem(hwndDlg
, IDC_TIMEZONELIST
),
1473 SetupData
, SetupData
->TimeZoneIndex
);
1475 if (!SetupData
->DisableAutoDaylightTimeSet
)
1477 SendDlgItemMessage(hwndDlg
, IDC_AUTODAYLIGHT
, BM_SETCHECK
, (WPARAM
)BST_CHECKED
, 0);
1482 ShowTimeZoneList(GetDlgItem(hwndDlg
, IDC_TIMEZONELIST
),
1483 SetupData
, 85 /* GMT time zone */);
1485 SendDlgItemMessage(hwndDlg
, IDC_AUTODAYLIGHT
, BM_SETCHECK
, (WPARAM
)BST_CHECKED
, 0);
1494 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
1499 /* Enable the Back and Next buttons */
1500 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_BACK
| PSWIZB_NEXT
);
1501 if (SetupData
->UnattendSetup
&& WriteDateTimeSettings(hwndDlg
, SetupData
))
1503 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, IDD_PROCESSPAGE
);
1510 GetLocalSystemTime(hwndDlg
, SetupData
);
1511 SetLocalTimeZone(GetDlgItem(hwndDlg
, IDC_TIMEZONELIST
),
1513 SetAutoDaylightInfo(GetDlgItem(hwndDlg
, IDC_AUTODAYLIGHT
));
1514 if(!SetSystemLocalTime(hwndDlg
, SetupData
))
1516 if (0 == LoadStringW(hDllInstance
, IDS_REACTOS_SETUP
, Title
, sizeof(Title
) / sizeof(Title
[0])))
1518 wcscpy(Title
, L
"ReactOS Setup");
1520 if (0 == LoadStringW(hDllInstance
, IDS_WZD_LOCALTIME
, ErrorLocalTime
,
1521 sizeof(ErrorLocalTime
) / sizeof(ErrorLocalTime
[0])))
1523 wcscpy(ErrorLocalTime
, L
"Setup failed to set the computer name.");
1525 MessageBoxW(hwndDlg
, ErrorLocalTime
, Title
, MB_ICONWARNING
| MB_OK
);
1531 SetupData
->UnattendSetup
= FALSE
;
1541 DestroyTimeZoneList(SetupData
);
1552 static UINT CALLBACK
1553 RegistrationNotificationProc(PVOID Context
,
1558 PREGISTRATIONDATA RegistrationData
;
1559 REGISTRATIONNOTIFY RegistrationNotify
;
1560 PSP_REGISTER_CONTROL_STATUSW StatusInfo
;
1562 WCHAR ErrorMessage
[128];
1564 RegistrationData
= (PREGISTRATIONDATA
) Context
;
1566 if (SPFILENOTIFY_STARTREGISTRATION
== Notification
||
1567 SPFILENOTIFY_ENDREGISTRATION
== Notification
)
1569 StatusInfo
= (PSP_REGISTER_CONTROL_STATUSW
) Param1
;
1570 RegistrationNotify
.CurrentItem
= wcsrchr(StatusInfo
->FileName
, L
'\\');
1571 if (NULL
== RegistrationNotify
.CurrentItem
)
1573 RegistrationNotify
.CurrentItem
= StatusInfo
->FileName
;
1577 RegistrationNotify
.CurrentItem
++;
1580 if (SPFILENOTIFY_STARTREGISTRATION
== Notification
)
1582 DPRINT("Received SPFILENOTIFY_STARTREGISTRATION notification for %S\n",
1583 StatusInfo
->FileName
);
1584 RegistrationNotify
.ErrorMessage
= NULL
;
1585 RegistrationNotify
.Progress
= RegistrationData
->Registered
;
1589 DPRINT("Received SPFILENOTIFY_ENDREGISTRATION notification for %S\n",
1590 StatusInfo
->FileName
);
1591 DPRINT("Win32Error %u FailureCode %u\n", StatusInfo
->Win32Error
,
1592 StatusInfo
->FailureCode
);
1593 if (SPREG_SUCCESS
!= StatusInfo
->FailureCode
)
1595 switch(StatusInfo
->FailureCode
)
1597 case SPREG_LOADLIBRARY
:
1598 MessageID
= IDS_LOADLIBRARY_FAILED
;
1600 case SPREG_GETPROCADDR
:
1601 MessageID
= IDS_GETPROCADDR_FAILED
;
1604 MessageID
= IDS_REGSVR_FAILED
;
1606 case SPREG_DLLINSTALL
:
1607 MessageID
= IDS_DLLINSTALL_FAILED
;
1610 MessageID
= IDS_TIMEOUT
;
1613 MessageID
= IDS_REASON_UNKNOWN
;
1616 if (0 == LoadStringW(hDllInstance
, MessageID
,
1618 sizeof(ErrorMessage
) /
1619 sizeof(ErrorMessage
[0])))
1621 ErrorMessage
[0] = L
'\0';
1623 if (SPREG_TIMEOUT
!= StatusInfo
->FailureCode
)
1625 FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM
, NULL
,
1626 StatusInfo
->Win32Error
, 0,
1627 ErrorMessage
+ wcslen(ErrorMessage
),
1628 sizeof(ErrorMessage
) / sizeof(ErrorMessage
[0]) -
1629 wcslen(ErrorMessage
), NULL
);
1631 RegistrationNotify
.ErrorMessage
= ErrorMessage
;
1635 RegistrationNotify
.ErrorMessage
= NULL
;
1637 if (RegistrationData
->Registered
< RegistrationData
->DllCount
)
1639 RegistrationData
->Registered
++;
1643 RegistrationNotify
.Progress
= RegistrationData
->Registered
;
1644 RegistrationNotify
.ActivityID
= IDS_REGISTERING_COMPONENTS
;
1645 SendMessage(RegistrationData
->hwndDlg
, PM_REGISTRATION_NOTIFY
,
1646 0, (LPARAM
) &RegistrationNotify
);
1652 DPRINT1("Received unexpected notification %u\n", Notification
);
1653 return SetupDefaultQueueCallback(RegistrationData
->DefaultContext
,
1654 Notification
, Param1
, Param2
);
1659 static DWORD CALLBACK
1660 RegistrationProc(LPVOID Parameter
)
1662 PREGISTRATIONDATA RegistrationData
;
1663 REGISTRATIONNOTIFY RegistrationNotify
;
1664 DWORD LastError
= NO_ERROR
;
1665 WCHAR UnknownError
[84];
1667 RegistrationData
= (PREGISTRATIONDATA
) Parameter
;
1668 RegistrationData
->Registered
= 0;
1669 RegistrationData
->DefaultContext
= SetupInitDefaultQueueCallback(RegistrationData
->hwndDlg
);
1673 if (!SetupInstallFromInfSectionW(GetParent(RegistrationData
->hwndDlg
),
1675 L
"RegistrationPhase2",
1677 SPINST_REGISTERCALLBACKAWARE
|
1682 RegistrationNotificationProc
,
1687 LastError
= GetLastError();
1690 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1692 DPRINT("Catching exception\n");
1693 LastError
= RtlNtStatusToDosError(_SEH2_GetExceptionCode());
1697 if (NO_ERROR
== LastError
)
1699 RegistrationNotify
.ErrorMessage
= NULL
;
1703 DPRINT1("SetupInstallFromInfSection failed with error %u\n",
1705 if (0 == FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER
|
1706 FORMAT_MESSAGE_FROM_SYSTEM
, NULL
, LastError
, 0,
1707 (LPWSTR
) &RegistrationNotify
.ErrorMessage
, 0,
1710 if (0 == LoadStringW(hDllInstance
, IDS_UNKNOWN_ERROR
,
1712 sizeof(UnknownError
) / sizeof(UnknownError
[0] -
1715 wcscpy(UnknownError
, L
"Unknown error");
1717 wcscat(UnknownError
, L
" ");
1718 _ultow(LastError
, UnknownError
+ wcslen(UnknownError
), 10);
1719 RegistrationNotify
.ErrorMessage
= UnknownError
;
1723 RegistrationNotify
.Progress
= RegistrationData
->DllCount
;
1724 RegistrationNotify
.ActivityID
= IDS_REGISTERING_COMPONENTS
;
1725 RegistrationNotify
.CurrentItem
= NULL
;
1726 SendMessage(RegistrationData
->hwndDlg
, PM_REGISTRATION_NOTIFY
,
1727 1, (LPARAM
) &RegistrationNotify
);
1728 if (NULL
!= RegistrationNotify
.ErrorMessage
&&
1729 UnknownError
!= RegistrationNotify
.ErrorMessage
)
1731 LocalFree((PVOID
) RegistrationNotify
.ErrorMessage
);
1734 SetupTermDefaultQueueCallback(RegistrationData
->DefaultContext
);
1735 HeapFree(GetProcessHeap(), 0, RegistrationData
);
1742 StartComponentRegistration(HWND hwndDlg
, PULONG MaxProgress
)
1744 HANDLE RegistrationThread
;
1747 WCHAR SectionName
[512];
1748 PREGISTRATIONDATA RegistrationData
;
1751 if (! SetupFindFirstLineW(hSysSetupInf
, L
"RegistrationPhase2",
1752 L
"RegisterDlls", &Context
))
1754 DPRINT1("No RegistrationPhase2 section found\n");
1757 if (! SetupGetStringFieldW(&Context
, 1, SectionName
,
1758 sizeof(SectionName
) / sizeof(SectionName
[0]),
1761 DPRINT1("Unable to retrieve section name\n");
1764 DllCount
= SetupGetLineCountW(hSysSetupInf
, SectionName
);
1765 DPRINT("SectionName %S DllCount %ld\n", SectionName
, DllCount
);
1768 SetLastError(STATUS_NOT_FOUND
);
1772 *MaxProgress
= (ULONG
) DllCount
;
1775 * Create a background thread to do the actual registrations, so the
1776 * main thread can just run its message loop.
1778 RegistrationThread
= NULL
;
1779 RegistrationData
= HeapAlloc(GetProcessHeap(), 0,
1780 sizeof(REGISTRATIONDATA
));
1781 if (NULL
!= RegistrationData
)
1783 RegistrationData
->hwndDlg
= hwndDlg
;
1784 RegistrationData
->DllCount
= DllCount
;
1785 RegistrationThread
= CreateThread(NULL
, 0, RegistrationProc
,
1786 (LPVOID
) RegistrationData
, 0, NULL
);
1787 if (NULL
!= RegistrationThread
)
1789 CloseHandle(RegistrationThread
);
1793 DPRINT1("CreateThread failed, error %u\n", GetLastError());
1799 DPRINT1("HeapAlloc() failed, error %u\n", GetLastError());
1807 static INT_PTR CALLBACK
1808 ProcessPageDlgProc(HWND hwndDlg
,
1813 PSETUPDATA SetupData
;
1814 PREGISTRATIONNOTIFY RegistrationNotify
;
1815 static UINT oldActivityID
= -1;
1818 /* Retrieve pointer to the global setup data */
1819 SetupData
= (PSETUPDATA
)GetWindowLongPtr (hwndDlg
, GWL_USERDATA
);
1825 /* Save pointer to the global setup data */
1826 SetupData
= (PSETUPDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
1827 SetWindowLongPtr(hwndDlg
, GWL_USERDATA
, (DWORD_PTR
)SetupData
);
1833 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
1834 ULONG MaxProgress
= 0;
1839 /* Disable the Back and Next buttons */
1840 PropSheet_SetWizButtons(GetParent(hwndDlg
), 0);
1842 StartComponentRegistration(hwndDlg
, &MaxProgress
);
1844 SendDlgItemMessage(hwndDlg
, IDC_PROCESSPROGRESS
, PBM_SETRANGE
,
1845 0, MAKELPARAM(0, MaxProgress
));
1846 SendDlgItemMessage(hwndDlg
, IDC_PROCESSPROGRESS
, PBM_SETPOS
,
1854 SetupData
->UnattendSetup
= FALSE
;
1863 case PM_REGISTRATION_NOTIFY
:
1866 RegistrationNotify
= (PREGISTRATIONNOTIFY
) lParam
;
1867 // update if necessary only
1868 if (oldActivityID
!= RegistrationNotify
->ActivityID
)
1870 if (0 != LoadStringW(hDllInstance
, RegistrationNotify
->ActivityID
,
1872 sizeof(Activity
) / sizeof(Activity
[0])))
1874 SendDlgItemMessageW(hwndDlg
, IDC_ACTIVITY
, WM_SETTEXT
,
1875 0, (LPARAM
) Activity
);
1877 oldActivityID
= RegistrationNotify
->ActivityID
;
1879 SendDlgItemMessageW(hwndDlg
, IDC_ITEM
, WM_SETTEXT
, 0,
1880 (LPARAM
)(NULL
== RegistrationNotify
->CurrentItem
?
1881 L
"" : RegistrationNotify
->CurrentItem
));
1882 SendDlgItemMessage(hwndDlg
, IDC_PROCESSPROGRESS
, PBM_SETPOS
,
1883 RegistrationNotify
->Progress
, 0);
1884 if (NULL
!= RegistrationNotify
->ErrorMessage
)
1886 if (0 == LoadStringW(hDllInstance
, IDS_REACTOS_SETUP
,
1887 Title
, sizeof(Title
) / sizeof(Title
[0])))
1889 wcscpy(Title
, L
"ReactOS Setup");
1891 MessageBoxW(hwndDlg
, RegistrationNotify
->ErrorMessage
,
1892 Title
, MB_ICONERROR
| MB_OK
);
1899 if(!SetupData
->UnattendSetup
&& !SetupData
->DisableVmwInst
)
1900 RunVMWInstall(GetParent(hwndDlg
));
1903 /* Enable the Back and Next buttons */
1904 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_NEXT
);
1905 PropSheet_PressButton(GetParent(hwndDlg
), PSBTN_NEXT
);
1919 SetupIsActive( DWORD dw
)
1922 if (RegOpenKeyExW( HKEY_LOCAL_MACHINE
, L
"SYSTEM\\Setup", 0, KEY_WRITE
, &hKey
) == ERROR_SUCCESS
) {
1923 RegSetValueExW( hKey
, L
"SystemSetupInProgress", 0, REG_DWORD
, (CONST BYTE
*)&dw
, sizeof(dw
) );
1924 RegCloseKey( hKey
);
1929 static INT_PTR CALLBACK
1930 FinishDlgProc(HWND hwndDlg
,
1940 PSETUPDATA SetupData
;
1942 /* Get pointer to the global setup data */
1943 SetupData
= (PSETUPDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
1945 /* Set title font */
1946 SendDlgItemMessage(hwndDlg
,
1949 (WPARAM
)SetupData
->hTitleFont
,
1951 if (SetupData
->UnattendSetup
)
1953 KillTimer(hwndDlg
, 1);
1972 hWndProgress
= GetDlgItem(hwndDlg
, IDC_RESTART_PROGRESS
);
1973 Position
= SendMessage(hWndProgress
, PBM_GETPOS
, 0, 0);
1974 if (Position
== 300)
1976 KillTimer(hwndDlg
, 1);
1977 PropSheet_PressButton(GetParent(hwndDlg
), PSBTN_FINISH
);
1981 SendMessage(hWndProgress
, PBM_SETPOS
, Position
+ 1, 0);
1988 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
1993 /* Enable the correct buttons on for the active page */
1994 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_FINISH
);
1996 SendDlgItemMessage(hwndDlg
, IDC_RESTART_PROGRESS
, PBM_SETRANGE
, 0,
1997 MAKELPARAM(0, 300));
1998 SendDlgItemMessage(hwndDlg
, IDC_RESTART_PROGRESS
, PBM_SETPOS
, 0, 0);
1999 SetTimer(hwndDlg
, 1, 50, NULL
);
2003 DestroyWindow(GetParent(hwndDlg
));
2019 ProcessUnattendInf(HINF hUnattendedInf
)
2021 INFCONTEXT InfContext
;
2023 WCHAR szValue
[MAX_PATH
];
2027 if (!SetupFindFirstLineW(hUnattendedInf
,
2029 L
"UnattendSetupEnabled",
2032 DPRINT1("Error: Cant find UnattendSetupEnabled Key! %d\n", GetLastError());
2036 if (!SetupGetStringFieldW(&InfContext
,
2039 sizeof(szValue
) / sizeof(WCHAR
),
2042 DPRINT1("Error: SetupGetStringField failed with %d\n", GetLastError());
2046 if (wcscmp(szValue
, L
"yes") != 0)
2048 DPRINT("Unattend setup was disabled by UnattendSetupEnabled key.\n");
2052 if (!SetupFindFirstLineW(hUnattendedInf
,
2057 DPRINT1("Error: SetupFindFirstLine failed %d\n", GetLastError());
2064 if (!SetupGetStringFieldW(&InfContext
,
2067 sizeof(szName
) / sizeof(WCHAR
),
2070 DPRINT1("Error: SetupGetStringField failed with %d\n", GetLastError());
2074 if (!SetupGetStringFieldW(&InfContext
,
2077 sizeof(szValue
) / sizeof(WCHAR
),
2080 DPRINT1("Error: SetupGetStringField failed with %d\n", GetLastError());
2083 DPRINT1("Name %S Value %S\n",szName
, szValue
);
2084 if (!wcscmp(szName
, L
"FullName"))
2086 if ((sizeof(SetupData
.OwnerName
) / sizeof(TCHAR
)) > LineLength
)
2088 wcscpy(SetupData
.OwnerName
, szValue
);
2091 else if (!wcscmp(szName
, L
"OrgName"))
2093 if ((sizeof(SetupData
.OwnerOrganization
) / sizeof(WCHAR
)) > LineLength
)
2095 wcscpy(SetupData
.OwnerOrganization
, szValue
);
2098 else if (!wcscmp(szName
, L
"ComputerName"))
2100 if ((sizeof(SetupData
.ComputerName
) / sizeof(WCHAR
)) > LineLength
)
2102 wcscpy(SetupData
.ComputerName
, szValue
);
2105 else if (!wcscmp(szName
, L
"AdminPassword"))
2107 if ((sizeof(SetupData
.AdminPassword
) / sizeof(WCHAR
)) > LineLength
)
2109 wcscpy(SetupData
.AdminPassword
, szValue
);
2112 else if (!wcscmp(szName
, L
"TimeZoneIndex"))
2114 SetupData
.TimeZoneIndex
= _wtoi(szValue
);
2116 else if (!wcscmp(szName
, L
"DisableAutoDaylightTimeSet"))
2118 SetupData
.DisableAutoDaylightTimeSet
= _wtoi(szValue
);
2120 else if (!wcscmp(szName
, L
"DisableVmwInst"))
2122 if(!wcscmp(szValue
, L
"yes"))
2123 SetupData
.DisableVmwInst
= 1;
2125 SetupData
.DisableVmwInst
= 0;
2129 while (SetupFindNextLine(&InfContext
, &InfContext
));
2131 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
2132 L
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunOnce",
2135 &hKey
) != ERROR_SUCCESS
)
2137 DPRINT1("Error: failed to open HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\RunOnce\n");
2142 if (SetupFindFirstLineW(hUnattendedInf
,
2151 if(SetupGetStringFieldW(&InfContext
,
2154 sizeof(szValue
) / sizeof(WCHAR
),
2157 WCHAR szPath
[MAX_PATH
];
2158 swprintf(szName
, L
"%d", i
);
2159 DPRINT("szName %S szValue %S\n", szName
, szValue
);
2161 if (ExpandEnvironmentStringsW(szValue
, szPath
, MAX_PATH
))
2163 DPRINT("value %S\n", szPath
);
2164 if (RegSetValueExW(hKey
,
2168 (const BYTE
*)szPath
,
2169 (wcslen(szPath
)+1) * sizeof(WCHAR
)) == ERROR_SUCCESS
)
2175 }while(SetupFindNextLine(&InfContext
, &InfContext
));
2183 * GetRosInstallCD should find the path to ros installation medium
2185 * If there are more than one CDDrive in it containing a ReactOS
2186 * installation cd, then it will pick the first one regardless if
2187 * it is really the installation cd
2189 * The best way to implement this is to set the key
2190 * HKLM\Software\Microsoft\Windows NT\CurrentVersion\SourcePath (REG_SZ)
2194 GetRosInstallCD(WCHAR
* szPath
, DWORD dwPathLength
)
2196 WCHAR szDrives
[512];
2197 WCHAR szDrive
[] = L
"D:\\";
2198 DWORD dwLength
, dwIndex
;
2200 dwLength
= GetLogicalDriveStringsW(sizeof(szDrives
) / sizeof(WCHAR
), szDrives
);
2202 if (dwLength
> (sizeof(szDrives
) / sizeof(WCHAR
)) || dwLength
== 0)
2204 /* buffer too small or failure */
2205 LogItem(SYSSETUP_SEVERITY_INFORMATION
, L
"GetLogicalDriveStringsW failed");
2210 for (dwIndex
= 0; dwIndex
< dwLength
; dwIndex
++)
2212 szDrive
[0] = pDrive
[dwIndex
];
2213 if (GetDriveTypeW(szDrive
) == DRIVE_CDROM
)
2215 WCHAR szBuffer
[MAX_PATH
];
2216 wcscpy(szBuffer
, szDrive
);
2217 wcscat(szBuffer
, L
"reactos\\ntoskrnl.exe");
2218 LogItem(SYSSETUP_SEVERITY_INFORMATION
, szBuffer
);
2219 if (FileExists(szBuffer
, NULL
))
2221 wcsncpy(szPath
, szDrive
, dwPathLength
);
2230 ProcessUnattendSetup()
2232 WCHAR szPath
[MAX_PATH
];
2233 HINF hUnattendedInf
;
2236 if (!GetRosInstallCD(szPath
, MAX_PATH
))
2238 /* no cd drive found */
2242 dwLength
= wcslen(szPath
);
2243 if (dwLength
+ 21 > MAX_PATH
)
2246 * allocate bigger buffer
2251 wcscat(szPath
, L
"reactos\\unattend.inf");
2253 hUnattendedInf
= SetupOpenInfFileW(szPath
,
2258 if (hUnattendedInf
!= INVALID_HANDLE_VALUE
)
2260 SetupData
.UnattendSetup
= ProcessUnattendInf(hUnattendedInf
);
2261 SetupCloseInfFile(hUnattendedInf
);
2269 PROPSHEETHEADER psh
;
2270 HPROPSHEETPAGE ahpsp
[8];
2271 PROPSHEETPAGE psp
= {0};
2276 /* Clear setup data */
2277 ZeroMemory(&SetupData
, sizeof(SETUPDATA
));
2279 ProcessUnattendSetup();
2282 /* Create the Welcome page */
2283 psp
.dwSize
= sizeof(PROPSHEETPAGE
);
2284 psp
.dwFlags
= PSP_DEFAULT
| PSP_HIDEHEADER
;
2285 psp
.hInstance
= hDllInstance
;
2286 psp
.lParam
= (LPARAM
)&SetupData
;
2287 psp
.pfnDlgProc
= WelcomeDlgProc
;
2288 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_WELCOMEPAGE
);
2289 ahpsp
[nPages
++] = CreatePropertySheetPage(&psp
);
2291 /* Create the Acknowledgements page */
2292 psp
.dwFlags
= PSP_DEFAULT
| PSP_USEHEADERTITLE
| PSP_USEHEADERSUBTITLE
;
2293 psp
.pszHeaderTitle
= MAKEINTRESOURCE(IDS_ACKTITLE
);
2294 psp
.pszHeaderSubTitle
= MAKEINTRESOURCE(IDS_ACKSUBTITLE
);
2295 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_ACKPAGE
);
2296 psp
.pfnDlgProc
= AckPageDlgProc
;
2297 ahpsp
[nPages
++] = CreatePropertySheetPage(&psp
);
2299 /* Create the Owner page */
2300 psp
.dwFlags
= PSP_DEFAULT
| PSP_USEHEADERTITLE
| PSP_USEHEADERSUBTITLE
;
2301 psp
.pszHeaderTitle
= MAKEINTRESOURCE(IDS_OWNERTITLE
);
2302 psp
.pszHeaderSubTitle
= MAKEINTRESOURCE(IDS_OWNERSUBTITLE
);
2303 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_OWNERPAGE
);
2304 psp
.pfnDlgProc
= OwnerPageDlgProc
;
2305 ahpsp
[nPages
++] = CreatePropertySheetPage(&psp
);
2307 /* Create the Computer page */
2308 psp
.dwFlags
= PSP_DEFAULT
| PSP_USEHEADERTITLE
| PSP_USEHEADERSUBTITLE
;
2309 psp
.pszHeaderTitle
= MAKEINTRESOURCE(IDS_COMPUTERTITLE
);
2310 psp
.pszHeaderSubTitle
= MAKEINTRESOURCE(IDS_COMPUTERSUBTITLE
);
2311 psp
.pfnDlgProc
= ComputerPageDlgProc
;
2312 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_COMPUTERPAGE
);
2313 ahpsp
[nPages
++] = CreatePropertySheetPage(&psp
);
2316 /* Create the Locale page */
2317 psp
.dwFlags
= PSP_DEFAULT
| PSP_USEHEADERTITLE
| PSP_USEHEADERSUBTITLE
;
2318 psp
.pszHeaderTitle
= MAKEINTRESOURCE(IDS_LOCALETITLE
);
2319 psp
.pszHeaderSubTitle
= MAKEINTRESOURCE(IDS_LOCALESUBTITLE
);
2320 psp
.pfnDlgProc
= LocalePageDlgProc
;
2321 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_LOCALEPAGE
);
2322 ahpsp
[nPages
++] = CreatePropertySheetPage(&psp
);
2325 /* Create the DateTime page */
2326 psp
.dwFlags
= PSP_DEFAULT
| PSP_USEHEADERTITLE
| PSP_USEHEADERSUBTITLE
;
2327 psp
.pszHeaderTitle
= MAKEINTRESOURCE(IDS_DATETIMETITLE
);
2328 psp
.pszHeaderSubTitle
= MAKEINTRESOURCE(IDS_DATETIMESUBTITLE
);
2329 psp
.pfnDlgProc
= DateTimePageDlgProc
;
2330 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_DATETIMEPAGE
);
2331 ahpsp
[nPages
++] = CreatePropertySheetPage(&psp
);
2334 /* Create the Process page */
2335 psp
.dwFlags
= PSP_DEFAULT
| PSP_USEHEADERTITLE
| PSP_USEHEADERSUBTITLE
;
2336 psp
.pszHeaderTitle
= MAKEINTRESOURCE(IDS_PROCESSTITLE
);
2337 psp
.pszHeaderSubTitle
= MAKEINTRESOURCE(IDS_PROCESSSUBTITLE
);
2338 psp
.pfnDlgProc
= ProcessPageDlgProc
;
2339 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_PROCESSPAGE
);
2340 ahpsp
[nPages
++] = CreatePropertySheetPage(&psp
);
2343 /* Create the Finish page */
2344 psp
.dwFlags
= PSP_DEFAULT
| PSP_HIDEHEADER
;
2345 psp
.pfnDlgProc
= FinishDlgProc
;
2346 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_FINISHPAGE
);
2347 ahpsp
[nPages
++] = CreatePropertySheetPage(&psp
);
2349 /* Create the property sheet */
2350 psh
.dwSize
= sizeof(PROPSHEETHEADER
);
2351 psh
.dwFlags
= PSH_WIZARD97
| PSH_WATERMARK
| PSH_HEADER
| PSH_MODELESS
;
2352 psh
.hInstance
= hDllInstance
;
2353 psh
.hwndParent
= NULL
;
2354 psh
.nPages
= nPages
;
2357 psh
.pszbmWatermark
= MAKEINTRESOURCE(IDB_WATERMARK
);
2358 psh
.pszbmHeader
= MAKEINTRESOURCE(IDB_HEADER
);
2360 /* Create title font */
2361 SetupData
.hTitleFont
= CreateTitleFont();
2363 /* Display the wizard */
2364 hWnd
= (HWND
)PropertySheet(&psh
);
2365 ShowWindow(hWnd
, SW_SHOW
);
2367 while (GetMessage(&msg
, NULL
, 0, 0))
2369 if(!IsDialogMessage(hWnd
, &msg
))
2371 TranslateMessage(&msg
);
2372 DispatchMessage(&msg
);
2376 DeleteObject(SetupData
.hTitleFont
);