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 *****************************************************************/
19 #define PM_REGISTRATION_NOTIFY (WM_APP + 1)
20 /* Private Message used to communicate progress from the background
21 registration thread to the main thread.
22 wParam = 0 Registration in progress
23 = 1 Registration completed
24 lParam = Pointer to a REGISTRATIONNOTIFY structure */
26 typedef struct _REGISTRATIONNOTIFY
32 } REGISTRATIONNOTIFY
, *PREGISTRATIONNOTIFY
;
34 typedef struct _REGISTRATIONDATA
40 } REGISTRATIONDATA
, *PREGISTRATIONDATA
;
42 /* GLOBALS ******************************************************************/
47 /* FUNCTIONS ****************************************************************/
49 extern void WINAPI
Control_RunDLLW(HWND hWnd
, HINSTANCE hInst
, LPCWSTR cmd
, DWORD nCmdShow
);
52 GetRosInstallCD(WCHAR
*pwszPath
, DWORD cchPathMax
);
56 RunVMWInstall(HWND hWnd
)
58 PROCESS_INFORMATION ProcInfo
;
62 WCHAR InstallName
[] = L
"vmwinst.exe";
64 ZeroMemory(&si
, sizeof(si
));
67 if(CreateProcessW(NULL
, InstallName
, NULL
, NULL
, TRUE
, NORMAL_PRIORITY_CLASS
,
68 NULL
, NULL
, &si
, &ProcInfo
))
70 EnableWindow(hWnd
, FALSE
);
73 while (PeekMessage(&msg
, NULL
, 0, 0, PM_REMOVE
))
75 if (msg
.message
== WM_QUIT
)
77 TranslateMessage(&msg
);
78 DispatchMessage(&msg
);
81 ret
= MsgWaitForMultipleObjects(1, &ProcInfo
.hProcess
, FALSE
, INFINITE
, QS_ALLEVENTS
| QS_ALLINPUT
);
82 if (ret
== WAIT_OBJECT_0
)
86 EnableWindow(hWnd
, TRUE
);
88 CloseHandle(ProcInfo
.hThread
);
89 CloseHandle(ProcInfo
.hProcess
);
97 CenterWindow(HWND hWnd
)
103 hWndParent
= GetParent(hWnd
);
104 if (hWndParent
== NULL
)
105 hWndParent
= GetDesktopWindow();
107 GetWindowRect(hWndParent
, &rcParent
);
108 GetWindowRect(hWnd
, &rcWindow
);
112 ((rcParent
.right
- rcParent
.left
) - (rcWindow
.right
- rcWindow
.left
)) / 2,
113 ((rcParent
.bottom
- rcParent
.top
) - (rcWindow
.bottom
- rcWindow
.top
)) / 2,
121 CreateTitleFont(VOID
)
123 NONCLIENTMETRICSW ncm
;
129 ncm
.cbSize
= sizeof(NONCLIENTMETRICSW
);
130 SystemParametersInfo(SPI_GETNONCLIENTMETRICS
, 0, &ncm
, 0);
132 LogFont
= ncm
.lfMessageFont
;
133 LogFont
.lfWeight
= FW_BOLD
;
134 wcscpy(LogFont
.lfFaceName
, L
"MS Shell Dlg");
138 LogFont
.lfHeight
= 0 - GetDeviceCaps(hdc
, LOGPIXELSY
) * FontSize
/ 72;
139 hFont
= CreateFontIndirectW(&LogFont
);
140 ReleaseDC(NULL
, hdc
);
146 static INT_PTR CALLBACK
147 GplDlgProc(HWND hwndDlg
,
152 HRSRC GplTextResource
;
162 GplTextResource
= FindResourceW(hDllInstance
, MAKEINTRESOURCE(IDR_GPL
), L
"RT_TEXT");
163 if (NULL
== GplTextResource
)
167 Size
= SizeofResource(hDllInstance
, GplTextResource
);
172 GplText
= HeapAlloc(GetProcessHeap(), 0, Size
+ 1);
177 GplTextMem
= LoadResource(hDllInstance
, GplTextResource
);
178 if (NULL
== GplTextMem
)
180 HeapFree(GetProcessHeap(), 0, GplText
);
183 GplTextLocked
= LockResource(GplTextMem
);
184 if (NULL
== GplTextLocked
)
186 HeapFree(GetProcessHeap(), 0, GplText
);
189 memcpy(GplText
, GplTextLocked
, Size
);
190 GplText
[Size
] = '\0';
191 SendMessageA(GetDlgItem(hwndDlg
, IDC_GPL_TEXT
), WM_SETTEXT
, 0, (LPARAM
) GplText
);
192 HeapFree(GetProcessHeap(), 0, GplText
);
193 SetFocus(GetDlgItem(hwndDlg
, IDOK
));
197 EndDialog(hwndDlg
, IDCANCEL
);
201 if (HIWORD(wParam
) == BN_CLICKED
&& IDOK
== LOWORD(wParam
))
203 EndDialog(hwndDlg
, IDOK
);
215 static INT_PTR CALLBACK
216 WelcomeDlgProc(HWND hwndDlg
,
225 PSETUPDATA SetupData
;
229 /* Get pointer to the global setup data */
230 SetupData
= (PSETUPDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
232 hwndControl
= GetParent(hwndDlg
);
234 /* Center the wizard window */
235 CenterWindow (hwndControl
);
237 /* Hide the system menu */
238 dwStyle
= GetWindowLongPtr(hwndControl
, GWL_STYLE
);
239 SetWindowLongPtr(hwndControl
, GWL_STYLE
, dwStyle
& ~WS_SYSMENU
);
241 /* Hide and disable the 'Cancel' button */
242 hwndControl
= GetDlgItem(GetParent(hwndDlg
), IDCANCEL
);
243 ShowWindow (hwndControl
, SW_HIDE
);
244 EnableWindow (hwndControl
, FALSE
);
247 SendDlgItemMessage(hwndDlg
,
250 (WPARAM
)SetupData
->hTitleFont
,
258 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
263 /* Enable the Next button */
264 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_NEXT
);
265 if (SetupData
.UnattendSetup
)
267 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, IDD_ACKPAGE
);
273 SetupData
.UnattendSetup
= FALSE
;
290 static INT_PTR CALLBACK
291 AckPageDlgProc(HWND hwndDlg
,
298 PWCHAR End
, CurrentProject
;
299 INT ProjectsSize
, ProjectsCount
;
309 Projects
= HeapAlloc(GetProcessHeap(), 0, ProjectsSize
* sizeof(WCHAR
));
310 if (NULL
== Projects
)
314 ProjectsCount
= LoadStringW(hDllInstance
, IDS_ACKPROJECTS
, Projects
, ProjectsSize
);
315 if (0 == ProjectsCount
)
317 HeapFree(GetProcessHeap(), 0, Projects
);
320 if (ProjectsCount
< ProjectsSize
- 1)
324 HeapFree(GetProcessHeap(), 0, Projects
);
328 CurrentProject
= Projects
;
329 while (L
'\0' != *CurrentProject
)
331 End
= wcschr(CurrentProject
, L
'\n');
336 (void)ListBox_AddString(GetDlgItem(hwndDlg
, IDC_PROJECTS
), CurrentProject
);
339 CurrentProject
= End
+ 1;
343 CurrentProject
+= wcslen(CurrentProject
);
346 HeapFree(GetProcessHeap(), 0, Projects
);
351 if (HIWORD(wParam
) == BN_CLICKED
&& IDC_VIEWGPL
== LOWORD(wParam
))
353 DialogBox(hDllInstance
, MAKEINTRESOURCE(IDD_GPL
), NULL
, GplDlgProc
);
354 SetForegroundWindow(GetParent(hwndDlg
));
360 lpnm
= (LPNMHDR
)lParam
;
365 /* Enable the Back and Next buttons */
366 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_BACK
| PSWIZB_NEXT
);
367 if (SetupData
.UnattendSetup
)
369 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, IDD_LOCALEPAGE
);
375 SetupData
.UnattendSetup
= FALSE
;
393 WriteOwnerSettings(WCHAR
* OwnerName
,
394 WCHAR
* OwnerOrganization
)
401 res
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
402 L
"Software\\Microsoft\\Windows NT\\CurrentVersion",
407 if (res
!= ERROR_SUCCESS
)
412 res
= RegSetValueExW(hKey
,
417 (wcslen(OwnerName
) + 1) * sizeof(WCHAR
));
419 if (res
!= ERROR_SUCCESS
)
425 res
= RegSetValueExW(hKey
,
426 L
"RegisteredOrganization",
429 (LPBYTE
)OwnerOrganization
,
430 (wcslen(OwnerOrganization
) + 1) * sizeof(WCHAR
));
433 return (res
== ERROR_SUCCESS
);
436 static INT_PTR CALLBACK
437 OwnerPageDlgProc(HWND hwndDlg
,
443 WCHAR OwnerOrganization
[51];
445 WCHAR ErrorName
[256];
452 SendDlgItemMessage(hwndDlg
, IDC_OWNERNAME
, EM_LIMITTEXT
, 50, 0);
453 SendDlgItemMessage(hwndDlg
, IDC_OWNERORGANIZATION
, EM_LIMITTEXT
, 50, 0);
455 /* Set focus to owner name */
456 SetFocus(GetDlgItem(hwndDlg
, IDC_OWNERNAME
));
463 lpnm
= (LPNMHDR
)lParam
;
468 /* Enable the Back and Next buttons */
469 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_BACK
| PSWIZB_NEXT
);
470 if (SetupData
.UnattendSetup
)
472 SendMessage(GetDlgItem(hwndDlg
, IDC_OWNERNAME
), WM_SETTEXT
, 0, (LPARAM
)SetupData
.OwnerName
);
473 SendMessage(GetDlgItem(hwndDlg
, IDC_OWNERORGANIZATION
), WM_SETTEXT
, 0, (LPARAM
)SetupData
.OwnerOrganization
);
474 if (WriteOwnerSettings(SetupData
.OwnerName
, SetupData
.OwnerOrganization
))
476 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, IDD_COMPUTERPAGE
);
484 if (GetDlgItemTextW(hwndDlg
, IDC_OWNERNAME
, OwnerName
, 50) == 0)
486 if (0 == LoadStringW(hDllInstance
, IDS_REACTOS_SETUP
, Title
, sizeof(Title
) / sizeof(Title
[0])))
488 wcscpy(Title
, L
"ReactOS Setup");
490 if (0 == LoadStringW(hDllInstance
, IDS_WZD_NAME
, ErrorName
, sizeof(ErrorName
) / sizeof(ErrorName
[0])))
492 wcscpy(ErrorName
, L
"Setup cannot continue until you enter your name.");
494 MessageBoxW(hwndDlg
, ErrorName
, Title
, MB_ICONERROR
| MB_OK
);
496 SetFocus(GetDlgItem(hwndDlg
, IDC_OWNERNAME
));
497 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, -1);
502 OwnerOrganization
[0] = 0;
503 GetDlgItemTextW(hwndDlg
, IDC_OWNERORGANIZATION
, OwnerOrganization
, 50);
505 if (!WriteOwnerSettings(OwnerName
, OwnerOrganization
))
507 SetFocus(GetDlgItem(hwndDlg
, IDC_OWNERNAME
));
508 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, -1);
513 SetupData
.UnattendSetup
= FALSE
;
531 WriteComputerSettings(WCHAR
* ComputerName
, HWND hwndDlg
)
534 WCHAR ErrorComputerName
[256];
536 if (!SetComputerNameW(ComputerName
))
540 if (0 == LoadStringW(hDllInstance
, IDS_REACTOS_SETUP
, Title
, sizeof(Title
) / sizeof(Title
[0])))
542 wcscpy(Title
, L
"ReactOS Setup");
544 if (0 == LoadStringW(hDllInstance
, IDS_WZD_SETCOMPUTERNAME
, ErrorComputerName
,
545 sizeof(ErrorComputerName
) / sizeof(ErrorComputerName
[0])))
547 wcscpy(ErrorComputerName
, L
"Setup failed to set the computer name.");
549 MessageBoxW(hwndDlg
, ErrorComputerName
, Title
, MB_ICONERROR
| MB_OK
);
555 /* Try to also set DNS hostname */
556 SetComputerNameExW(ComputerNamePhysicalDnsHostname
, ComputerName
);
558 /* Set the account domain name */
559 SetAccountDomain(ComputerName
, NULL
);
564 /* lpBuffer will be filled with a 15-char string (plus the null terminator) */
566 GenerateComputerName(LPWSTR lpBuffer
)
568 static const WCHAR Chars
[] = L
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
569 static const unsigned cChars
= sizeof(Chars
) / sizeof(WCHAR
) - 1;
572 wcscpy(lpBuffer
, L
"REACTOS-");
574 srand(GetTickCount());
576 /* fill in 7 characters */
577 for (i
= 8; i
< 15; i
++)
578 lpBuffer
[i
] = Chars
[rand() % cChars
];
580 lpBuffer
[15] = UNICODE_NULL
; /* NULL-terminate */
583 static INT_PTR CALLBACK
584 ComputerPageDlgProc(HWND hwndDlg
,
589 WCHAR ComputerName
[MAX_COMPUTERNAME_LENGTH
+ 1];
594 WCHAR EmptyComputerName
[256], NotMatchPassword
[256], WrongPassword
[256];
597 if (0 == LoadStringW(hDllInstance
, IDS_REACTOS_SETUP
, Title
, sizeof(Title
) / sizeof(Title
[0])))
599 wcscpy(Title
, L
"ReactOS Setup");
606 /* Generate a new pseudo-random computer name */
607 GenerateComputerName(ComputerName
);
609 /* Display current computer name */
610 SetDlgItemTextW(hwndDlg
, IDC_COMPUTERNAME
, ComputerName
);
612 /* Set text limits */
613 SendDlgItemMessage(hwndDlg
, IDC_COMPUTERNAME
, EM_LIMITTEXT
, MAX_COMPUTERNAME_LENGTH
, 0);
614 SendDlgItemMessage(hwndDlg
, IDC_ADMINPASSWORD1
, EM_LIMITTEXT
, 14, 0);
615 SendDlgItemMessage(hwndDlg
, IDC_ADMINPASSWORD2
, EM_LIMITTEXT
, 14, 0);
617 /* Set focus to computer name */
618 SetFocus(GetDlgItem(hwndDlg
, IDC_COMPUTERNAME
));
619 if (SetupData
.UnattendSetup
)
621 SendMessage(GetDlgItem(hwndDlg
, IDC_COMPUTERNAME
), WM_SETTEXT
, 0, (LPARAM
)SetupData
.ComputerName
);
622 SendMessage(GetDlgItem(hwndDlg
, IDC_ADMINPASSWORD1
), WM_SETTEXT
, 0, (LPARAM
)SetupData
.AdminPassword
);
623 SendMessage(GetDlgItem(hwndDlg
, IDC_ADMINPASSWORD2
), WM_SETTEXT
, 0, (LPARAM
)SetupData
.AdminPassword
);
624 WriteComputerSettings(SetupData
.ComputerName
, NULL
);
625 SetAdministratorPassword(SetupData
.AdminPassword
);
634 lpnm
= (LPNMHDR
)lParam
;
639 /* Enable the Back and Next buttons */
640 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_BACK
| PSWIZB_NEXT
);
641 if (SetupData
.UnattendSetup
&& WriteComputerSettings(SetupData
.ComputerName
, hwndDlg
))
643 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, IDD_DATETIMEPAGE
);
649 if (0 == GetDlgItemTextW(hwndDlg
, IDC_COMPUTERNAME
, ComputerName
, MAX_COMPUTERNAME_LENGTH
+ 1))
651 if (0 == LoadStringW(hDllInstance
, IDS_WZD_COMPUTERNAME
, EmptyComputerName
,
652 sizeof(EmptyComputerName
) / sizeof(EmptyComputerName
[0])))
654 wcscpy(EmptyComputerName
, L
"Setup cannot continue until you enter the name of your computer.");
656 MessageBoxW(hwndDlg
, EmptyComputerName
, Title
, MB_ICONERROR
| MB_OK
);
657 SetFocus(GetDlgItem(hwndDlg
, IDC_COMPUTERNAME
));
658 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, -1);
662 /* No need to check computer name for invalid characters,
663 * SetComputerName() will do it for us */
665 if (!WriteComputerSettings(ComputerName
, hwndDlg
))
667 SetFocus(GetDlgItem(hwndDlg
, IDC_COMPUTERNAME
));
668 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, -1);
673 /* Check if admin passwords have been entered */
674 if ((GetDlgItemText(hwndDlg
, IDC_ADMINPASSWORD1
, Password1
, 15) == 0) ||
675 (GetDlgItemText(hwndDlg
, IDC_ADMINPASSWORD2
, Password2
, 15) == 0))
677 if (0 == LoadStringW(hDllInstance
, IDS_WZD_PASSWORDEMPTY
, EmptyPassword
,
678 sizeof(EmptyPassword
) / sizeof(EmptyPassword
[0])))
680 wcscpy(EmptyPassword
, L
"You must enter a password !");
682 MessageBoxW(hwndDlg
, EmptyPassword
, Title
, MB_ICONERROR
| MB_OK
);
683 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, -1);
687 GetDlgItemTextW(hwndDlg
, IDC_ADMINPASSWORD1
, Password1
, 15);
688 GetDlgItemTextW(hwndDlg
, IDC_ADMINPASSWORD2
, Password2
, 15);
690 /* Check if passwords match */
691 if (wcscmp(Password1
, Password2
))
693 if (0 == LoadStringW(hDllInstance
, IDS_WZD_PASSWORDMATCH
, NotMatchPassword
,
694 sizeof(NotMatchPassword
) / sizeof(NotMatchPassword
[0])))
696 wcscpy(NotMatchPassword
, L
"The passwords you entered do not match. Please enter the desired password again.");
698 MessageBoxW(hwndDlg
, NotMatchPassword
, Title
, MB_ICONERROR
| MB_OK
);
699 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, -1);
703 /* Check password for invalid characters */
704 Password
= (PWCHAR
)Password1
;
707 if (!isprint(*Password
))
709 if (0 == LoadStringW(hDllInstance
, IDS_WZD_PASSWORDCHAR
, WrongPassword
,
710 sizeof(WrongPassword
) / sizeof(WrongPassword
[0])))
712 wcscpy(WrongPassword
, L
"The password you entered contains invalid characters. Please enter a cleaned password.");
714 MessageBoxW(hwndDlg
, WrongPassword
, Title
, MB_ICONERROR
| MB_OK
);
715 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, -1);
721 /* Set admin password */
722 SetAdministratorPassword(Password1
);
726 SetupData
.UnattendSetup
= FALSE
;
744 SetKeyboardLayoutName(HWND hwnd
)
747 TCHAR szLayoutPath
[256];
748 TCHAR szLocaleName
[32];
752 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE
,
753 _T("SYSTEM\\CurrentControlSet\\Control\\NLS\\Locale"),
759 dwValueSize
= 16 * sizeof(TCHAR
);
760 if (RegQueryValueEx(hKey
,
771 _tcscpy(szLayoutPath
,
772 _T("SYSTEM\\CurrentControlSet\\Control\\Keyboard Layouts\\"));
773 _tcscat(szLayoutPath
,
776 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE
,
783 dwValueSize
= 32 * sizeof(TCHAR
);
784 if (RegQueryValueEx(hKey
,
801 RunControlPanelApplet(HWND hwnd
, PCWSTR pwszCPLParameters
)
803 if (pwszCPLParameters
)
805 STARTUPINFOW StartupInfo
;
806 PROCESS_INFORMATION ProcessInformation
;
807 WCHAR CmdLine
[MAX_PATH
] = L
"rundll32.exe shell32.dll,Control_RunDLL ";
809 ZeroMemory(&StartupInfo
, sizeof(StartupInfo
));
810 StartupInfo
.cb
= sizeof(StartupInfo
);
812 ASSERT(_countof(CmdLine
) > wcslen(CmdLine
) + wcslen(pwszCPLParameters
));
813 wcscat(CmdLine
, pwszCPLParameters
);
815 if (!CreateProcessW(NULL
,
824 &ProcessInformation
))
826 MessageBoxW(hwnd
, L
"Error: Failed to launch the Control Panel Applet.", NULL
, MB_ICONERROR
);
830 WaitForSingleObject(ProcessInformation
.hProcess
, INFINITE
);
831 CloseHandle(ProcessInformation
.hThread
);
832 CloseHandle(ProcessInformation
.hProcess
);
837 MessageBoxW(hwnd
, L
"Error: Failed to launch the Control Panel Applet.", NULL
, MB_ICONERROR
);
843 WriteUserLocale(VOID
)
849 lcid
= GetSystemDefaultLCID();
851 if (GetLocaleInfoW(MAKELCID(lcid
, SORT_DEFAULT
), LOCALE_ILANGUAGE
, Locale
, sizeof(Locale
) / sizeof(Locale
[0])) != 0)
853 if (RegCreateKeyExW(HKEY_CURRENT_USER
, L
"Control Panel\\International",
854 0, NULL
, REG_OPTION_NON_VOLATILE
,
855 KEY_WRITE
, NULL
, &hKey
, NULL
) == ERROR_SUCCESS
)
857 RegSetValueExW(hKey
, L
"Locale", 0, REG_SZ
, (LPBYTE
)Locale
, (wcslen(Locale
) + 1) * sizeof(WCHAR
));
863 static INT_PTR CALLBACK
864 LocalePageDlgProc(HWND hwndDlg
,
869 PSETUPDATA SetupData
;
871 /* Retrieve pointer to the global setup data */
872 SetupData
= (PSETUPDATA
)GetWindowLongPtr (hwndDlg
, GWL_USERDATA
);
878 /* Save pointer to the global setup data */
879 SetupData
= (PSETUPDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
880 SetWindowLongPtr(hwndDlg
, GWL_USERDATA
, (DWORD_PTR
)SetupData
);
883 SetKeyboardLayoutName(GetDlgItem(hwndDlg
, IDC_LAYOUTTEXT
));
888 if (HIWORD(wParam
) == BN_CLICKED
)
890 switch (LOWORD(wParam
))
892 case IDC_CUSTOMLOCALE
:
893 RunControlPanelApplet(hwndDlg
, L
"intl.cpl,,5");
894 /* FIXME: Update input locale name */
897 case IDC_CUSTOMLAYOUT
:
898 RunControlPanelApplet(hwndDlg
, L
"input.dll,@1");
906 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
911 /* Enable the Back and Next buttons */
912 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_BACK
| PSWIZB_NEXT
);
913 if (SetupData
->UnattendSetup
)
915 WCHAR wszPath
[MAX_PATH
];
916 if (GetRosInstallCD(wszPath
, _countof(wszPath
)))
918 WCHAR wszParams
[1024];
919 swprintf(wszParams
, L
"intl.cpl,,/f:\"%sreactos\\unattend.inf\"", wszPath
);
920 RunControlPanelApplet(hwndDlg
, wszParams
);
924 RunControlPanelApplet(hwndDlg
, L
"intl.cpl,,/f:\"unattend.inf\"");
927 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, IDD_OWNERPAGE
);
936 SetupData
->UnattendSetup
= FALSE
;
953 static PTIMEZONE_ENTRY
954 GetLargerTimeZoneEntry(PSETUPDATA SetupData
, DWORD Index
)
956 PTIMEZONE_ENTRY Entry
;
958 Entry
= SetupData
->TimeZoneListHead
;
959 while (Entry
!= NULL
)
961 if (Entry
->Index
>= Index
)
972 CreateTimeZoneList(PSETUPDATA SetupData
)
974 WCHAR szKeyName
[256];
982 PTIMEZONE_ENTRY Entry
;
983 PTIMEZONE_ENTRY Current
;
985 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
986 L
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones",
995 dwNameSize
= 256 * sizeof(WCHAR
);
996 lError
= RegEnumKeyExW(hZonesKey
,
1004 if (lError
!= ERROR_SUCCESS
&& lError
!= ERROR_MORE_DATA
)
1007 if (RegOpenKeyExW(hZonesKey
,
1014 Entry
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(TIMEZONE_ENTRY
));
1017 RegCloseKey(hZoneKey
);
1021 dwValueSize
= 64 * sizeof(WCHAR
);
1022 if (RegQueryValueExW(hZoneKey
,
1026 (LPBYTE
)&Entry
->Description
,
1029 RegCloseKey(hZoneKey
);
1033 dwValueSize
= 32 * sizeof(WCHAR
);
1034 if (RegQueryValueExW(hZoneKey
,
1038 (LPBYTE
)&Entry
->StandardName
,
1041 RegCloseKey(hZoneKey
);
1045 dwValueSize
= 32 * sizeof(WCHAR
);
1046 if (RegQueryValueExW(hZoneKey
,
1050 (LPBYTE
)&Entry
->DaylightName
,
1053 RegCloseKey(hZoneKey
);
1057 dwValueSize
= sizeof(DWORD
);
1058 if (RegQueryValueExW(hZoneKey
,
1062 (LPBYTE
)&Entry
->Index
,
1065 RegCloseKey(hZoneKey
);
1069 dwValueSize
= sizeof(TZ_INFO
);
1070 if (RegQueryValueExW(hZoneKey
,
1074 (LPBYTE
)&Entry
->TimezoneInfo
,
1077 RegCloseKey(hZoneKey
);
1081 RegCloseKey(hZoneKey
);
1083 if (SetupData
->TimeZoneListHead
== NULL
&&
1084 SetupData
->TimeZoneListTail
== NULL
)
1088 SetupData
->TimeZoneListHead
= Entry
;
1089 SetupData
->TimeZoneListTail
= Entry
;
1093 Current
= GetLargerTimeZoneEntry(SetupData
, Entry
->Index
);
1094 if (Current
!= NULL
)
1096 if (Current
== SetupData
->TimeZoneListHead
)
1098 /* Prepend to head */
1100 Entry
->Next
= SetupData
->TimeZoneListHead
;
1101 SetupData
->TimeZoneListHead
->Prev
= Entry
;
1102 SetupData
->TimeZoneListHead
= Entry
;
1106 /* Insert before current */
1107 Entry
->Prev
= Current
->Prev
;
1108 Entry
->Next
= Current
;
1109 Current
->Prev
->Next
= Entry
;
1110 Current
->Prev
= Entry
;
1115 /* Append to tail */
1116 Entry
->Prev
= SetupData
->TimeZoneListTail
;
1118 SetupData
->TimeZoneListTail
->Next
= Entry
;
1119 SetupData
->TimeZoneListTail
= Entry
;
1126 RegCloseKey(hZonesKey
);
1131 DestroyTimeZoneList(PSETUPDATA SetupData
)
1133 PTIMEZONE_ENTRY Entry
;
1135 while (SetupData
->TimeZoneListHead
!= NULL
)
1137 Entry
= SetupData
->TimeZoneListHead
;
1139 SetupData
->TimeZoneListHead
= Entry
->Next
;
1140 if (SetupData
->TimeZoneListHead
!= NULL
)
1142 SetupData
->TimeZoneListHead
->Prev
= NULL
;
1145 HeapFree(GetProcessHeap(), 0, Entry
);
1148 SetupData
->TimeZoneListTail
= NULL
;
1152 GetTimeZoneListIndex(LPDWORD lpIndex
)
1154 WCHAR szLanguageIdString
[9];
1161 BOOL bFound
= FALSE
;
1162 unsigned long iLanguageID
;
1164 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
1165 L
"SYSTEM\\CurrentControlSet\\Control\\NLS\\Language",
1171 dwValueSize
= 9 * sizeof(WCHAR
);
1172 if (RegQueryValueExW(hKey
,
1176 (LPBYTE
)szLanguageIdString
,
1183 iLanguageID
= wcstoul(szLanguageIdString
, NULL
, 16);
1186 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
1187 L
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones",
1194 if (RegQueryValueExW(hKey
,
1205 Buffer
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, dwValueSize
);
1212 if (RegQueryValueExW(hKey
,
1219 HeapFree(GetProcessHeap(), 0, Buffer
);
1229 Length
= wcslen(Ptr
);
1230 if (wcstoul(Ptr
, NULL
, 16) == iLanguageID
)
1233 Ptr
= Ptr
+ Length
+ 1;
1239 *lpIndex
= wcstoul(Ptr
, &End
, 10);
1240 HeapFree(GetProcessHeap(), 0, Buffer
);
1244 Length
= wcslen(Ptr
);
1245 Ptr
= Ptr
+ Length
+ 1;
1248 HeapFree(GetProcessHeap(), 0, Buffer
);
1255 ShowTimeZoneList(HWND hwnd
, PSETUPDATA SetupData
, DWORD dwEntryIndex
)
1257 PTIMEZONE_ENTRY Entry
;
1261 GetTimeZoneListIndex(&dwEntryIndex
);
1263 Entry
= SetupData
->TimeZoneListHead
;
1264 while (Entry
!= NULL
)
1266 dwCount
= SendMessage(hwnd
,
1269 (LPARAM
)Entry
->Description
);
1271 if (dwEntryIndex
!= 0 && dwEntryIndex
== Entry
->Index
)
1274 Entry
= Entry
->Next
;
1285 SetLocalTimeZone(HWND hwnd
, PSETUPDATA SetupData
)
1287 TIME_ZONE_INFORMATION TimeZoneInformation
;
1288 PTIMEZONE_ENTRY Entry
;
1292 dwIndex
= SendMessage(hwnd
,
1298 Entry
= SetupData
->TimeZoneListHead
;
1305 Entry
= Entry
->Next
;
1308 wcscpy(TimeZoneInformation
.StandardName
,
1309 Entry
->StandardName
);
1310 wcscpy(TimeZoneInformation
.DaylightName
,
1311 Entry
->DaylightName
);
1313 TimeZoneInformation
.Bias
= Entry
->TimezoneInfo
.Bias
;
1314 TimeZoneInformation
.StandardBias
= Entry
->TimezoneInfo
.StandardBias
;
1315 TimeZoneInformation
.DaylightBias
= Entry
->TimezoneInfo
.DaylightBias
;
1317 memcpy(&TimeZoneInformation
.StandardDate
,
1318 &Entry
->TimezoneInfo
.StandardDate
,
1319 sizeof(SYSTEMTIME
));
1320 memcpy(&TimeZoneInformation
.DaylightDate
,
1321 &Entry
->TimezoneInfo
.DaylightDate
,
1322 sizeof(SYSTEMTIME
));
1324 /* Set time zone information */
1325 SetTimeZoneInformation(&TimeZoneInformation
);
1330 GetLocalSystemTime(HWND hwnd
, PSETUPDATA SetupData
)
1335 if (DateTime_GetSystemtime(GetDlgItem(hwnd
, IDC_DATEPICKER
), &Date
) != GDT_VALID
)
1340 if (DateTime_GetSystemtime(GetDlgItem(hwnd
, IDC_TIMEPICKER
), &Time
) != GDT_VALID
)
1345 SetupData
->SystemTime
.wYear
= Date
.wYear
;
1346 SetupData
->SystemTime
.wMonth
= Date
.wMonth
;
1347 SetupData
->SystemTime
.wDayOfWeek
= Date
.wDayOfWeek
;
1348 SetupData
->SystemTime
.wDay
= Date
.wDay
;
1349 SetupData
->SystemTime
.wHour
= Time
.wHour
;
1350 SetupData
->SystemTime
.wMinute
= Time
.wMinute
;
1351 SetupData
->SystemTime
.wSecond
= Time
.wSecond
;
1352 SetupData
->SystemTime
.wMilliseconds
= Time
.wMilliseconds
;
1359 SetAutoDaylightInfo(HWND hwnd
)
1364 if (SendMessage(hwnd
, BM_GETCHECK
, 0, 0) == BST_UNCHECKED
)
1366 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
1367 L
"SYSTEM\\CurrentControlSet\\Control\\TimeZoneInformation",
1373 RegSetValueExW(hKey
,
1374 L
"DisableAutoDaylightTimeSet",
1385 SetSystemLocalTime(HWND hwnd
, PSETUPDATA SetupData
)
1390 * Call SetLocalTime twice to ensure correct results
1392 Ret
= SetLocalTime(&SetupData
->SystemTime
) &&
1393 SetLocalTime(&SetupData
->SystemTime
);
1399 WriteDateTimeSettings(HWND hwndDlg
, PSETUPDATA SetupData
)
1402 WCHAR ErrorLocalTime
[256];
1403 GetLocalSystemTime(hwndDlg
, SetupData
);
1404 SetLocalTimeZone(GetDlgItem(hwndDlg
, IDC_TIMEZONELIST
),
1407 SetAutoDaylightInfo(GetDlgItem(hwndDlg
, IDC_AUTODAYLIGHT
));
1408 if(!SetSystemLocalTime(hwndDlg
, SetupData
))
1410 if (0 == LoadStringW(hDllInstance
, IDS_REACTOS_SETUP
, Title
, sizeof(Title
) / sizeof(Title
[0])))
1412 wcscpy(Title
, L
"ReactOS Setup");
1414 if (0 == LoadStringW(hDllInstance
, IDS_WZD_LOCALTIME
, ErrorLocalTime
,
1415 sizeof(ErrorLocalTime
) / sizeof(ErrorLocalTime
[0])))
1417 wcscpy(ErrorLocalTime
, L
"Setup was unable to set the local time.");
1419 MessageBoxW(hwndDlg
, ErrorLocalTime
, Title
, MB_ICONWARNING
| MB_OK
);
1426 static INT_PTR CALLBACK
1427 DateTimePageDlgProc(HWND hwndDlg
,
1432 PSETUPDATA SetupData
;
1434 /* Retrieve pointer to the global setup data */
1435 SetupData
= (PSETUPDATA
)GetWindowLongPtr (hwndDlg
, GWL_USERDATA
);
1441 /* Save pointer to the global setup data */
1442 SetupData
= (PSETUPDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
1443 SetWindowLongPtr(hwndDlg
, GWL_USERDATA
, (DWORD_PTR
)SetupData
);
1445 CreateTimeZoneList(SetupData
);
1447 if (SetupData
->UnattendSetup
)
1449 ShowTimeZoneList(GetDlgItem(hwndDlg
, IDC_TIMEZONELIST
),
1450 SetupData
, SetupData
->TimeZoneIndex
);
1452 if (!SetupData
->DisableAutoDaylightTimeSet
)
1454 SendDlgItemMessage(hwndDlg
, IDC_AUTODAYLIGHT
, BM_SETCHECK
, (WPARAM
)BST_CHECKED
, 0);
1459 ShowTimeZoneList(GetDlgItem(hwndDlg
, IDC_TIMEZONELIST
),
1460 SetupData
, 85 /* GMT time zone */);
1462 SendDlgItemMessage(hwndDlg
, IDC_AUTODAYLIGHT
, BM_SETCHECK
, (WPARAM
)BST_CHECKED
, 0);
1471 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
1476 /* Enable the Back and Next buttons */
1477 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_BACK
| PSWIZB_NEXT
);
1478 if (SetupData
->UnattendSetup
&& WriteDateTimeSettings(hwndDlg
, SetupData
))
1480 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, IDD_PROCESSPAGE
);
1487 WriteDateTimeSettings(hwndDlg
, SetupData
);
1492 SetupData
->UnattendSetup
= FALSE
;
1502 DestroyTimeZoneList(SetupData
);
1513 static UINT CALLBACK
1514 RegistrationNotificationProc(PVOID Context
,
1519 PREGISTRATIONDATA RegistrationData
;
1520 REGISTRATIONNOTIFY RegistrationNotify
;
1521 PSP_REGISTER_CONTROL_STATUSW StatusInfo
;
1523 WCHAR ErrorMessage
[128];
1525 RegistrationData
= (PREGISTRATIONDATA
) Context
;
1527 if (SPFILENOTIFY_STARTREGISTRATION
== Notification
||
1528 SPFILENOTIFY_ENDREGISTRATION
== Notification
)
1530 StatusInfo
= (PSP_REGISTER_CONTROL_STATUSW
) Param1
;
1531 RegistrationNotify
.CurrentItem
= wcsrchr(StatusInfo
->FileName
, L
'\\');
1532 if (NULL
== RegistrationNotify
.CurrentItem
)
1534 RegistrationNotify
.CurrentItem
= StatusInfo
->FileName
;
1538 RegistrationNotify
.CurrentItem
++;
1541 if (SPFILENOTIFY_STARTREGISTRATION
== Notification
)
1543 DPRINT("Received SPFILENOTIFY_STARTREGISTRATION notification for %S\n",
1544 StatusInfo
->FileName
);
1545 RegistrationNotify
.ErrorMessage
= NULL
;
1546 RegistrationNotify
.Progress
= RegistrationData
->Registered
;
1550 DPRINT("Received SPFILENOTIFY_ENDREGISTRATION notification for %S\n",
1551 StatusInfo
->FileName
);
1552 DPRINT("Win32Error %u FailureCode %u\n", StatusInfo
->Win32Error
,
1553 StatusInfo
->FailureCode
);
1554 if (SPREG_SUCCESS
!= StatusInfo
->FailureCode
)
1556 switch(StatusInfo
->FailureCode
)
1558 case SPREG_LOADLIBRARY
:
1559 MessageID
= IDS_LOADLIBRARY_FAILED
;
1561 case SPREG_GETPROCADDR
:
1562 MessageID
= IDS_GETPROCADDR_FAILED
;
1565 MessageID
= IDS_REGSVR_FAILED
;
1567 case SPREG_DLLINSTALL
:
1568 MessageID
= IDS_DLLINSTALL_FAILED
;
1571 MessageID
= IDS_TIMEOUT
;
1574 MessageID
= IDS_REASON_UNKNOWN
;
1577 if (0 == LoadStringW(hDllInstance
, MessageID
,
1579 sizeof(ErrorMessage
) /
1580 sizeof(ErrorMessage
[0])))
1582 ErrorMessage
[0] = L
'\0';
1584 if (SPREG_TIMEOUT
!= StatusInfo
->FailureCode
)
1586 FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM
, NULL
,
1587 StatusInfo
->Win32Error
, 0,
1588 ErrorMessage
+ wcslen(ErrorMessage
),
1589 sizeof(ErrorMessage
) / sizeof(ErrorMessage
[0]) -
1590 wcslen(ErrorMessage
), NULL
);
1592 RegistrationNotify
.ErrorMessage
= ErrorMessage
;
1596 RegistrationNotify
.ErrorMessage
= NULL
;
1598 if (RegistrationData
->Registered
< RegistrationData
->DllCount
)
1600 RegistrationData
->Registered
++;
1604 RegistrationNotify
.Progress
= RegistrationData
->Registered
;
1605 RegistrationNotify
.ActivityID
= IDS_REGISTERING_COMPONENTS
;
1606 SendMessage(RegistrationData
->hwndDlg
, PM_REGISTRATION_NOTIFY
,
1607 0, (LPARAM
) &RegistrationNotify
);
1613 DPRINT1("Received unexpected notification %u\n", Notification
);
1614 return SetupDefaultQueueCallback(RegistrationData
->DefaultContext
,
1615 Notification
, Param1
, Param2
);
1620 static DWORD CALLBACK
1621 RegistrationProc(LPVOID Parameter
)
1623 PREGISTRATIONDATA RegistrationData
;
1624 REGISTRATIONNOTIFY RegistrationNotify
;
1625 DWORD LastError
= NO_ERROR
;
1626 WCHAR UnknownError
[84];
1628 RegistrationData
= (PREGISTRATIONDATA
) Parameter
;
1629 RegistrationData
->Registered
= 0;
1630 RegistrationData
->DefaultContext
= SetupInitDefaultQueueCallback(RegistrationData
->hwndDlg
);
1634 if (!SetupInstallFromInfSectionW(GetParent(RegistrationData
->hwndDlg
),
1636 L
"RegistrationPhase2",
1638 SPINST_REGISTERCALLBACKAWARE
|
1643 RegistrationNotificationProc
,
1648 LastError
= GetLastError();
1651 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1653 DPRINT("Catching exception\n");
1654 LastError
= RtlNtStatusToDosError(_SEH2_GetExceptionCode());
1658 if (NO_ERROR
== LastError
)
1660 RegistrationNotify
.ErrorMessage
= NULL
;
1664 DPRINT1("SetupInstallFromInfSection failed with error %u\n",
1666 if (0 == FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER
|
1667 FORMAT_MESSAGE_FROM_SYSTEM
, NULL
, LastError
, 0,
1668 (LPWSTR
) &RegistrationNotify
.ErrorMessage
, 0,
1671 if (0 == LoadStringW(hDllInstance
, IDS_UNKNOWN_ERROR
,
1673 sizeof(UnknownError
) / sizeof(UnknownError
[0]) -
1676 wcscpy(UnknownError
, L
"Unknown error");
1678 wcscat(UnknownError
, L
" ");
1679 _ultow(LastError
, UnknownError
+ wcslen(UnknownError
), 10);
1680 RegistrationNotify
.ErrorMessage
= UnknownError
;
1684 RegistrationNotify
.Progress
= RegistrationData
->DllCount
;
1685 RegistrationNotify
.ActivityID
= IDS_REGISTERING_COMPONENTS
;
1686 RegistrationNotify
.CurrentItem
= NULL
;
1687 SendMessage(RegistrationData
->hwndDlg
, PM_REGISTRATION_NOTIFY
,
1688 1, (LPARAM
) &RegistrationNotify
);
1689 if (NULL
!= RegistrationNotify
.ErrorMessage
&&
1690 UnknownError
!= RegistrationNotify
.ErrorMessage
)
1692 LocalFree((PVOID
) RegistrationNotify
.ErrorMessage
);
1695 SetupTermDefaultQueueCallback(RegistrationData
->DefaultContext
);
1696 HeapFree(GetProcessHeap(), 0, RegistrationData
);
1698 RegisterTypeLibraries(hSysSetupInf
, L
"TypeLibraries");
1700 // FIXME: Move this call to a separate cleanup page!
1701 RtlCreateBootStatusDataFile();
1708 StartComponentRegistration(HWND hwndDlg
, PULONG MaxProgress
)
1710 HANDLE RegistrationThread
;
1713 WCHAR SectionName
[512];
1714 PREGISTRATIONDATA RegistrationData
;
1717 if (! SetupFindFirstLineW(hSysSetupInf
, L
"RegistrationPhase2",
1718 L
"RegisterDlls", &Context
))
1720 DPRINT1("No RegistrationPhase2 section found\n");
1723 if (! SetupGetStringFieldW(&Context
, 1, SectionName
,
1724 sizeof(SectionName
) / sizeof(SectionName
[0]),
1727 DPRINT1("Unable to retrieve section name\n");
1730 DllCount
= SetupGetLineCountW(hSysSetupInf
, SectionName
);
1731 DPRINT("SectionName %S DllCount %ld\n", SectionName
, DllCount
);
1734 SetLastError(STATUS_NOT_FOUND
);
1738 *MaxProgress
= (ULONG
) DllCount
;
1741 * Create a background thread to do the actual registrations, so the
1742 * main thread can just run its message loop.
1744 RegistrationThread
= NULL
;
1745 RegistrationData
= HeapAlloc(GetProcessHeap(), 0,
1746 sizeof(REGISTRATIONDATA
));
1747 if (RegistrationData
!= NULL
)
1749 RegistrationData
->hwndDlg
= hwndDlg
;
1750 RegistrationData
->DllCount
= DllCount
;
1751 RegistrationThread
= CreateThread(NULL
, 0, RegistrationProc
,
1752 (LPVOID
) RegistrationData
, 0, NULL
);
1753 if (RegistrationThread
!= NULL
)
1755 CloseHandle(RegistrationThread
);
1759 DPRINT1("CreateThread failed, error %u\n", GetLastError());
1760 HeapFree(GetProcessHeap(), 0, RegistrationData
);
1766 DPRINT1("HeapAlloc() failed, error %u\n", GetLastError());
1774 static INT_PTR CALLBACK
1775 ProcessPageDlgProc(HWND hwndDlg
,
1780 PSETUPDATA SetupData
;
1781 PREGISTRATIONNOTIFY RegistrationNotify
;
1782 static UINT oldActivityID
= -1;
1785 /* Retrieve pointer to the global setup data */
1786 SetupData
= (PSETUPDATA
)GetWindowLongPtr (hwndDlg
, GWL_USERDATA
);
1792 /* Save pointer to the global setup data */
1793 SetupData
= (PSETUPDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
1794 SetWindowLongPtr(hwndDlg
, GWL_USERDATA
, (DWORD_PTR
)SetupData
);
1800 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
1801 ULONG MaxProgress
= 0;
1806 /* Disable the Back and Next buttons */
1807 PropSheet_SetWizButtons(GetParent(hwndDlg
), 0);
1809 StartComponentRegistration(hwndDlg
, &MaxProgress
);
1811 SendDlgItemMessage(hwndDlg
, IDC_PROCESSPROGRESS
, PBM_SETRANGE
,
1812 0, MAKELPARAM(0, MaxProgress
));
1813 SendDlgItemMessage(hwndDlg
, IDC_PROCESSPROGRESS
, PBM_SETPOS
,
1821 SetupData
->UnattendSetup
= FALSE
;
1830 case PM_REGISTRATION_NOTIFY
:
1833 RegistrationNotify
= (PREGISTRATIONNOTIFY
) lParam
;
1834 // update if necessary only
1835 if (oldActivityID
!= RegistrationNotify
->ActivityID
)
1837 if (0 != LoadStringW(hDllInstance
, RegistrationNotify
->ActivityID
,
1839 sizeof(Activity
) / sizeof(Activity
[0])))
1841 SendDlgItemMessageW(hwndDlg
, IDC_ACTIVITY
, WM_SETTEXT
,
1842 0, (LPARAM
) Activity
);
1844 oldActivityID
= RegistrationNotify
->ActivityID
;
1846 SendDlgItemMessageW(hwndDlg
, IDC_ITEM
, WM_SETTEXT
, 0,
1847 (LPARAM
)(NULL
== RegistrationNotify
->CurrentItem
?
1848 L
"" : RegistrationNotify
->CurrentItem
));
1849 SendDlgItemMessage(hwndDlg
, IDC_PROCESSPROGRESS
, PBM_SETPOS
,
1850 RegistrationNotify
->Progress
, 0);
1851 if (NULL
!= RegistrationNotify
->ErrorMessage
)
1853 if (0 == LoadStringW(hDllInstance
, IDS_REACTOS_SETUP
,
1854 Title
, sizeof(Title
) / sizeof(Title
[0])))
1856 wcscpy(Title
, L
"ReactOS Setup");
1858 MessageBoxW(hwndDlg
, RegistrationNotify
->ErrorMessage
,
1859 Title
, MB_ICONERROR
| MB_OK
);
1866 if(!SetupData
->UnattendSetup
&& !SetupData
->DisableVmwInst
)
1867 RunVMWInstall(GetParent(hwndDlg
));
1870 /* Enable the Back and Next buttons */
1871 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_NEXT
);
1872 PropSheet_PressButton(GetParent(hwndDlg
), PSBTN_NEXT
);
1886 SetInstallationCompleted(VOID
)
1889 DWORD InProgress
= 0;
1892 if (RegOpenKeyExW( HKEY_LOCAL_MACHINE
,
1896 &hKey
) == ERROR_SUCCESS
)
1898 RegSetValueExW( hKey
, L
"SystemSetupInProgress", 0, REG_DWORD
, (LPBYTE
)&InProgress
, sizeof(InProgress
) );
1899 RegCloseKey( hKey
);
1902 if (RegOpenKeyExW( HKEY_LOCAL_MACHINE
,
1903 L
"Software\\Microsoft\\Windows NT\\CurrentVersion",
1906 &hKey
) == ERROR_SUCCESS
)
1908 InstallDate
= (DWORD
)time(NULL
);
1909 RegSetValueExW( hKey
, L
"InstallDate", 0, REG_DWORD
, (LPBYTE
)&InstallDate
, sizeof(InstallDate
) );
1910 RegCloseKey( hKey
);
1914 static INT_PTR CALLBACK
1915 FinishDlgProc(HWND hwndDlg
,
1925 /* Get pointer to the global setup data */
1926 PSETUPDATA SetupData
= (PSETUPDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
1928 /* Run the Wine Gecko prompt */
1929 Control_RunDLLW(GetDesktopWindow(), 0, L
"appwiz.cpl install_gecko", SW_SHOW
);
1931 /* Set title font */
1932 SendDlgItemMessage(hwndDlg
,
1935 (WPARAM
)SetupData
->hTitleFont
,
1937 if (SetupData
->UnattendSetup
)
1939 KillTimer(hwndDlg
, 1);
1940 SetInstallationCompleted();
1948 SetInstallationCompleted();
1958 hWndProgress
= GetDlgItem(hwndDlg
, IDC_RESTART_PROGRESS
);
1959 Position
= SendMessage(hWndProgress
, PBM_GETPOS
, 0, 0);
1960 if (Position
== 300)
1962 KillTimer(hwndDlg
, 1);
1963 PropSheet_PressButton(GetParent(hwndDlg
), PSBTN_FINISH
);
1967 SendMessage(hWndProgress
, PBM_SETPOS
, Position
+ 1, 0);
1974 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
1979 /* Enable the correct buttons on for the active page */
1980 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_FINISH
);
1982 SendDlgItemMessage(hwndDlg
, IDC_RESTART_PROGRESS
, PBM_SETRANGE
, 0,
1983 MAKELPARAM(0, 300));
1984 SendDlgItemMessage(hwndDlg
, IDC_RESTART_PROGRESS
, PBM_SETPOS
, 0, 0);
1985 SetTimer(hwndDlg
, 1, 50, NULL
);
1989 DestroyWindow(GetParent(hwndDlg
));
2007 ProcessUnattendInf(HINF hUnattendedInf
)
2009 INFCONTEXT InfContext
;
2011 WCHAR szValue
[MAX_PATH
];
2015 if (!SetupFindFirstLineW(hUnattendedInf
,
2017 L
"UnattendSetupEnabled",
2020 DPRINT1("Error: Cant find UnattendSetupEnabled Key! %d\n", GetLastError());
2024 if (!SetupGetStringFieldW(&InfContext
,
2027 sizeof(szValue
) / sizeof(WCHAR
),
2030 DPRINT1("Error: SetupGetStringField failed with %d\n", GetLastError());
2034 if (wcscmp(szValue
, L
"yes") != 0)
2036 DPRINT("Unattend setup was disabled by UnattendSetupEnabled key.\n");
2040 if (!SetupFindFirstLineW(hUnattendedInf
,
2045 DPRINT1("Error: SetupFindFirstLine failed %d\n", GetLastError());
2052 if (!SetupGetStringFieldW(&InfContext
,
2055 sizeof(szName
) / sizeof(WCHAR
),
2058 DPRINT1("Error: SetupGetStringField failed with %d\n", GetLastError());
2062 if (!SetupGetStringFieldW(&InfContext
,
2065 sizeof(szValue
) / sizeof(WCHAR
),
2068 DPRINT1("Error: SetupGetStringField failed with %d\n", GetLastError());
2071 DPRINT1("Name %S Value %S\n", szName
, szValue
);
2072 if (!wcscmp(szName
, L
"FullName"))
2074 if ((sizeof(SetupData
.OwnerName
) / sizeof(TCHAR
)) > LineLength
)
2076 wcscpy(SetupData
.OwnerName
, szValue
);
2079 else if (!wcscmp(szName
, L
"OrgName"))
2081 if ((sizeof(SetupData
.OwnerOrganization
) / sizeof(WCHAR
)) > LineLength
)
2083 wcscpy(SetupData
.OwnerOrganization
, szValue
);
2086 else if (!wcscmp(szName
, L
"ComputerName"))
2088 if ((sizeof(SetupData
.ComputerName
) / sizeof(WCHAR
)) > LineLength
)
2090 wcscpy(SetupData
.ComputerName
, szValue
);
2093 else if (!wcscmp(szName
, L
"AdminPassword"))
2095 if ((sizeof(SetupData
.AdminPassword
) / sizeof(WCHAR
)) > LineLength
)
2097 wcscpy(SetupData
.AdminPassword
, szValue
);
2100 else if (!wcscmp(szName
, L
"TimeZoneIndex"))
2102 SetupData
.TimeZoneIndex
= _wtoi(szValue
);
2104 else if (!wcscmp(szName
, L
"DisableAutoDaylightTimeSet"))
2106 SetupData
.DisableAutoDaylightTimeSet
= _wtoi(szValue
);
2108 else if (!wcscmp(szName
, L
"DisableVmwInst"))
2110 if(!wcscmp(szValue
, L
"yes"))
2111 SetupData
.DisableVmwInst
= 1;
2113 SetupData
.DisableVmwInst
= 0;
2117 while (SetupFindNextLine(&InfContext
, &InfContext
));
2119 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
2120 L
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunOnce",
2123 &hKey
) != ERROR_SUCCESS
)
2125 DPRINT1("Error: failed to open HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\RunOnce\n");
2130 if (SetupFindFirstLineW(hUnattendedInf
,
2139 if(SetupGetStringFieldW(&InfContext
,
2142 sizeof(szValue
) / sizeof(WCHAR
),
2145 WCHAR szPath
[MAX_PATH
];
2146 swprintf(szName
, L
"%d", i
);
2147 DPRINT("szName %S szValue %S\n", szName
, szValue
);
2149 if (ExpandEnvironmentStringsW(szValue
, szPath
, MAX_PATH
))
2151 DPRINT("value %S\n", szPath
);
2152 if (RegSetValueExW(hKey
,
2156 (const BYTE
*)szPath
,
2157 (wcslen(szPath
) + 1) * sizeof(WCHAR
)) == ERROR_SUCCESS
)
2163 } while(SetupFindNextLine(&InfContext
, &InfContext
));
2171 * GetRosInstallCD should find the path to ros installation medium
2173 * If there are more than one CDDrive in it containing a ReactOS
2174 * installation cd, then it will pick the first one regardless if
2175 * it is really the installation cd
2177 * The best way to implement this is to set the key
2178 * HKLM\Software\Microsoft\Windows NT\CurrentVersion\SourcePath (REG_SZ)
2182 GetRosInstallCD(WCHAR
*pwszPath
, DWORD cchPathMax
)
2184 WCHAR wszDrives
[512];
2188 cchDrives
= GetLogicalDriveStringsW(_countof(wszDrives
) - 1, wszDrives
);
2189 if (cchDrives
== 0 || cchDrives
>= _countof(wszDrives
))
2191 /* buffer too small or failure */
2192 LogItem(SYSSETUP_SEVERITY_INFORMATION
, L
"GetLogicalDriveStringsW failed");
2196 for (pwszDrive
= wszDrives
; pwszDrive
[0]; pwszDrive
+= wcslen(pwszDrive
) + 1)
2198 if (GetDriveTypeW(pwszDrive
) == DRIVE_CDROM
)
2200 WCHAR wszBuf
[MAX_PATH
];
2201 wsprintf(wszBuf
, L
"%sreactos\\system32\\ntoskrnl.exe", pwszDrive
);
2202 LogItem(SYSSETUP_SEVERITY_INFORMATION
, wszBuf
);
2203 if (GetFileAttributesW(wszBuf
) != INVALID_FILE_ATTRIBUTES
)
2205 /* the file exists, so this is the right drive */
2206 wcsncpy(pwszPath
, pwszDrive
, cchPathMax
);
2207 OutputDebugStringW(L
"GetRosInstallCD: ");OutputDebugStringW(pwszPath
);OutputDebugStringW(L
"\n");
2217 ProcessUnattendSetup(VOID
)
2219 WCHAR szPath
[MAX_PATH
];
2220 HINF hUnattendedInf
;
2223 if (!GetRosInstallCD(szPath
, MAX_PATH
))
2225 /* no cd drive found */
2229 dwLength
= wcslen(szPath
);
2230 if (dwLength
+ 21 > MAX_PATH
)
2233 * allocate bigger buffer
2238 wcscat(szPath
, L
"reactos\\unattend.inf");
2240 hUnattendedInf
= SetupOpenInfFileW(szPath
,
2245 if (hUnattendedInf
!= INVALID_HANDLE_VALUE
)
2247 SetupData
.UnattendSetup
= ProcessUnattendInf(hUnattendedInf
);
2248 SetupCloseInfFile(hUnattendedInf
);
2256 PROPSHEETHEADER psh
;
2257 HPROPSHEETPAGE ahpsp
[8];
2258 PROPSHEETPAGE psp
= {0};
2263 /* Clear setup data */
2264 ZeroMemory(&SetupData
, sizeof(SETUPDATA
));
2266 ProcessUnattendSetup();
2268 /* Create the Welcome page */
2269 psp
.dwSize
= sizeof(PROPSHEETPAGE
);
2270 psp
.dwFlags
= PSP_DEFAULT
| PSP_HIDEHEADER
;
2271 psp
.hInstance
= hDllInstance
;
2272 psp
.lParam
= (LPARAM
)&SetupData
;
2273 psp
.pfnDlgProc
= WelcomeDlgProc
;
2274 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_WELCOMEPAGE
);
2275 ahpsp
[nPages
++] = CreatePropertySheetPage(&psp
);
2277 /* Create the Acknowledgements page */
2278 psp
.dwFlags
= PSP_DEFAULT
| PSP_USEHEADERTITLE
| PSP_USEHEADERSUBTITLE
;
2279 psp
.pszHeaderTitle
= MAKEINTRESOURCE(IDS_ACKTITLE
);
2280 psp
.pszHeaderSubTitle
= MAKEINTRESOURCE(IDS_ACKSUBTITLE
);
2281 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_ACKPAGE
);
2282 psp
.pfnDlgProc
= AckPageDlgProc
;
2283 ahpsp
[nPages
++] = CreatePropertySheetPage(&psp
);
2285 /* Create the Locale page */
2286 psp
.dwFlags
= PSP_DEFAULT
| PSP_USEHEADERTITLE
| PSP_USEHEADERSUBTITLE
;
2287 psp
.pszHeaderTitle
= MAKEINTRESOURCE(IDS_LOCALETITLE
);
2288 psp
.pszHeaderSubTitle
= MAKEINTRESOURCE(IDS_LOCALESUBTITLE
);
2289 psp
.pfnDlgProc
= LocalePageDlgProc
;
2290 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_LOCALEPAGE
);
2291 ahpsp
[nPages
++] = CreatePropertySheetPage(&psp
);
2294 /* Create the Owner page */
2295 psp
.dwFlags
= PSP_DEFAULT
| PSP_USEHEADERTITLE
| PSP_USEHEADERSUBTITLE
;
2296 psp
.pszHeaderTitle
= MAKEINTRESOURCE(IDS_OWNERTITLE
);
2297 psp
.pszHeaderSubTitle
= MAKEINTRESOURCE(IDS_OWNERSUBTITLE
);
2298 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_OWNERPAGE
);
2299 psp
.pfnDlgProc
= OwnerPageDlgProc
;
2300 ahpsp
[nPages
++] = CreatePropertySheetPage(&psp
);
2302 /* Create the Computer page */
2303 psp
.dwFlags
= PSP_DEFAULT
| PSP_USEHEADERTITLE
| PSP_USEHEADERSUBTITLE
;
2304 psp
.pszHeaderTitle
= MAKEINTRESOURCE(IDS_COMPUTERTITLE
);
2305 psp
.pszHeaderSubTitle
= MAKEINTRESOURCE(IDS_COMPUTERSUBTITLE
);
2306 psp
.pfnDlgProc
= ComputerPageDlgProc
;
2307 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_COMPUTERPAGE
);
2308 ahpsp
[nPages
++] = CreatePropertySheetPage(&psp
);
2311 /* Create the DateTime page */
2312 psp
.dwFlags
= PSP_DEFAULT
| PSP_USEHEADERTITLE
| PSP_USEHEADERSUBTITLE
;
2313 psp
.pszHeaderTitle
= MAKEINTRESOURCE(IDS_DATETIMETITLE
);
2314 psp
.pszHeaderSubTitle
= MAKEINTRESOURCE(IDS_DATETIMESUBTITLE
);
2315 psp
.pfnDlgProc
= DateTimePageDlgProc
;
2316 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_DATETIMEPAGE
);
2317 ahpsp
[nPages
++] = CreatePropertySheetPage(&psp
);
2320 /* Create the Process page */
2321 psp
.dwFlags
= PSP_DEFAULT
| PSP_USEHEADERTITLE
| PSP_USEHEADERSUBTITLE
;
2322 psp
.pszHeaderTitle
= MAKEINTRESOURCE(IDS_PROCESSTITLE
);
2323 psp
.pszHeaderSubTitle
= MAKEINTRESOURCE(IDS_PROCESSSUBTITLE
);
2324 psp
.pfnDlgProc
= ProcessPageDlgProc
;
2325 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_PROCESSPAGE
);
2326 ahpsp
[nPages
++] = CreatePropertySheetPage(&psp
);
2329 /* Create the Finish page */
2330 psp
.dwFlags
= PSP_DEFAULT
| PSP_HIDEHEADER
;
2331 psp
.pfnDlgProc
= FinishDlgProc
;
2332 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_FINISHPAGE
);
2333 ahpsp
[nPages
++] = CreatePropertySheetPage(&psp
);
2335 /* Create the property sheet */
2336 psh
.dwSize
= sizeof(PROPSHEETHEADER
);
2337 psh
.dwFlags
= PSH_WIZARD97
| PSH_WATERMARK
| PSH_HEADER
| PSH_MODELESS
;
2338 psh
.hInstance
= hDllInstance
;
2339 psh
.hwndParent
= NULL
;
2340 psh
.nPages
= nPages
;
2343 psh
.pszbmWatermark
= MAKEINTRESOURCE(IDB_WATERMARK
);
2344 psh
.pszbmHeader
= MAKEINTRESOURCE(IDB_HEADER
);
2346 /* Create title font */
2347 SetupData
.hTitleFont
= CreateTitleFont();
2349 /* Display the wizard */
2350 hWnd
= (HWND
)PropertySheet(&psh
);
2351 ShowWindow(hWnd
, SW_SHOW
);
2353 while (GetMessage(&msg
, NULL
, 0, 0))
2355 if(!IsDialogMessage(hWnd
, &msg
))
2357 TranslateMessage(&msg
);
2358 DispatchMessage(&msg
);
2362 DeleteObject(SetupData
.hTitleFont
);