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 CenterWindow(HWND hWnd
)
64 hWndParent
= GetParent(hWnd
);
65 if (hWndParent
== NULL
)
66 hWndParent
= GetDesktopWindow();
68 GetWindowRect(hWndParent
, &rcParent
);
69 GetWindowRect(hWnd
, &rcWindow
);
73 ((rcParent
.right
- rcParent
.left
) - (rcWindow
.right
- rcWindow
.left
)) / 2,
74 ((rcParent
.bottom
- rcParent
.top
) - (rcWindow
.bottom
- rcWindow
.top
)) / 2,
84 LOGFONTW LogFont
= {0};
88 LogFont
.lfWeight
= FW_HEAVY
;
89 wcscpy(LogFont
.lfFaceName
, L
"MS Shell Dlg");
92 LogFont
.lfHeight
= -MulDiv(12, GetDeviceCaps(hdc
, LOGPIXELSY
), 72);
94 hFont
= CreateFontIndirectW(&LogFont
);
105 LOGFONTW tmpFont
= {0};
109 /* Grabs the Drawing Context */
112 tmpFont
.lfHeight
= -MulDiv(8, GetDeviceCaps(hDc
, LOGPIXELSY
), 72);
113 tmpFont
.lfWeight
= FW_HEAVY
;
114 wcscpy(tmpFont
.lfFaceName
, L
"MS Shell Dlg");
116 hBoldFont
= CreateFontIndirectW(&tmpFont
);
118 ReleaseDC(NULL
, hDc
);
123 static INT_PTR CALLBACK
124 GplDlgProc(HWND hwndDlg
,
129 HRSRC GplTextResource
;
139 GplTextResource
= FindResourceW(hDllInstance
, MAKEINTRESOURCE(IDR_GPL
), L
"RT_TEXT");
140 if (NULL
== GplTextResource
)
144 Size
= SizeofResource(hDllInstance
, GplTextResource
);
149 GplText
= HeapAlloc(GetProcessHeap(), 0, Size
+ 1);
154 GplTextMem
= LoadResource(hDllInstance
, GplTextResource
);
155 if (NULL
== GplTextMem
)
157 HeapFree(GetProcessHeap(), 0, GplText
);
160 GplTextLocked
= LockResource(GplTextMem
);
161 if (NULL
== GplTextLocked
)
163 HeapFree(GetProcessHeap(), 0, GplText
);
166 memcpy(GplText
, GplTextLocked
, Size
);
167 GplText
[Size
] = '\0';
168 SendMessageA(GetDlgItem(hwndDlg
, IDC_GPL_TEXT
), WM_SETTEXT
, 0, (LPARAM
) GplText
);
169 HeapFree(GetProcessHeap(), 0, GplText
);
170 SetFocus(GetDlgItem(hwndDlg
, IDOK
));
174 EndDialog(hwndDlg
, IDCANCEL
);
178 if (HIWORD(wParam
) == BN_CLICKED
&& IDOK
== LOWORD(wParam
))
180 EndDialog(hwndDlg
, IDOK
);
192 static INT_PTR CALLBACK
193 WelcomeDlgProc(HWND hwndDlg
,
198 PSETUPDATA pSetupData
;
200 pSetupData
= (PSETUPDATA
)GetWindowLongPtr(hwndDlg
, DWLP_USER
);
209 /* Get pointer to the global setup data */
210 pSetupData
= (PSETUPDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
211 SetWindowLongPtr(hwndDlg
, DWLP_USER
, (LONG_PTR
)pSetupData
);
213 hwndControl
= GetParent(hwndDlg
);
215 /* Center the wizard window */
216 CenterWindow (hwndControl
);
218 /* Hide the system menu */
219 dwStyle
= GetWindowLongPtr(hwndControl
, GWL_STYLE
);
220 SetWindowLongPtr(hwndControl
, GWL_STYLE
, dwStyle
& ~WS_SYSMENU
);
222 /* Hide and disable the 'Cancel' button */
223 hwndControl
= GetDlgItem(GetParent(hwndDlg
), IDCANCEL
);
224 ShowWindow (hwndControl
, SW_HIDE
);
225 EnableWindow (hwndControl
, FALSE
);
228 SendDlgItemMessage(hwndDlg
,
231 (WPARAM
)pSetupData
->hTitleFont
,
239 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
244 LogItem(L
"BEGIN", L
"WelcomePage");
245 /* Enable the Next button */
246 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_NEXT
);
247 if (pSetupData
->UnattendSetup
)
249 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, IDD_ACKPAGE
);
255 LogItem(L
"END", L
"WelcomePage");
259 pSetupData
->UnattendSetup
= FALSE
;
276 static INT_PTR CALLBACK
277 AckPageDlgProc(HWND hwndDlg
,
284 PWCHAR End
, CurrentProject
;
285 INT ProjectsSize
, ProjectsCount
;
286 PSETUPDATA pSetupData
;
288 pSetupData
= (PSETUPDATA
)GetWindowLongPtr(hwndDlg
, DWLP_USER
);
294 pSetupData
= (PSETUPDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
295 SetWindowLongPtr(hwndDlg
, DWLP_USER
, (LONG_PTR
)pSetupData
);
301 Projects
= HeapAlloc(GetProcessHeap(), 0, ProjectsSize
* sizeof(WCHAR
));
302 if (NULL
== Projects
)
306 ProjectsCount
= LoadStringW(hDllInstance
, IDS_ACKPROJECTS
, Projects
, ProjectsSize
);
307 if (0 == ProjectsCount
)
309 HeapFree(GetProcessHeap(), 0, Projects
);
312 if (ProjectsCount
< ProjectsSize
- 1)
316 HeapFree(GetProcessHeap(), 0, Projects
);
320 CurrentProject
= Projects
;
321 while (L
'\0' != *CurrentProject
)
323 End
= wcschr(CurrentProject
, L
'\n');
328 (void)ListBox_AddString(GetDlgItem(hwndDlg
, IDC_PROJECTS
), CurrentProject
);
331 CurrentProject
= End
+ 1;
335 CurrentProject
+= wcslen(CurrentProject
);
338 HeapFree(GetProcessHeap(), 0, Projects
);
343 if (HIWORD(wParam
) == BN_CLICKED
&& IDC_VIEWGPL
== LOWORD(wParam
))
345 DialogBox(hDllInstance
, MAKEINTRESOURCE(IDD_GPL
), NULL
, GplDlgProc
);
346 SetForegroundWindow(GetParent(hwndDlg
));
352 lpnm
= (LPNMHDR
)lParam
;
357 /* Enable the Back and Next buttons */
358 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_BACK
| PSWIZB_NEXT
);
359 if (pSetupData
->UnattendSetup
)
361 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, IDD_LOCALEPAGE
);
367 pSetupData
->UnattendSetup
= FALSE
;
385 WriteOwnerSettings(WCHAR
* OwnerName
,
386 WCHAR
* OwnerOrganization
)
393 res
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
394 L
"Software\\Microsoft\\Windows NT\\CurrentVersion",
399 if (res
!= ERROR_SUCCESS
)
404 res
= RegSetValueExW(hKey
,
409 (wcslen(OwnerName
) + 1) * sizeof(WCHAR
));
411 if (res
!= ERROR_SUCCESS
)
417 res
= RegSetValueExW(hKey
,
418 L
"RegisteredOrganization",
421 (LPBYTE
)OwnerOrganization
,
422 (wcslen(OwnerOrganization
) + 1) * sizeof(WCHAR
));
425 return (res
== ERROR_SUCCESS
);
428 static INT_PTR CALLBACK
429 OwnerPageDlgProc(HWND hwndDlg
,
435 WCHAR OwnerOrganization
[51];
437 WCHAR ErrorName
[256];
439 PSETUPDATA pSetupData
;
441 pSetupData
= (PSETUPDATA
)GetWindowLongPtr(hwndDlg
, DWLP_USER
);
447 pSetupData
= (PSETUPDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
448 SetWindowLongPtr(hwndDlg
, DWLP_USER
, (LONG_PTR
)pSetupData
);
450 /* set a localized ('Owner') placeholder string as default */
451 if (LoadStringW(hDllInstance
, IDS_MACHINE_OWNER_NAME
, OwnerName
, _countof(OwnerName
)))
453 SendDlgItemMessage(hwndDlg
, IDC_OWNERNAME
, WM_SETTEXT
, 0, (LPARAM
)OwnerName
);
456 SendDlgItemMessage(hwndDlg
, IDC_OWNERNAME
, EM_LIMITTEXT
, 50, 0);
457 SendDlgItemMessage(hwndDlg
, IDC_OWNERORGANIZATION
, EM_LIMITTEXT
, 50, 0);
459 /* Set focus to owner name */
460 SetFocus(GetDlgItem(hwndDlg
, IDC_OWNERNAME
));
462 /* Select the default text to quickly overwrite it by typing */
463 SendDlgItemMessage(hwndDlg
, IDC_OWNERNAME
, EM_SETSEL
, 0, -1);
470 lpnm
= (LPNMHDR
)lParam
;
475 /* Enable the Back and Next buttons */
476 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_BACK
| PSWIZB_NEXT
);
477 if (pSetupData
->UnattendSetup
)
479 SendMessage(GetDlgItem(hwndDlg
, IDC_OWNERNAME
), WM_SETTEXT
, 0, (LPARAM
)pSetupData
->OwnerName
);
480 SendMessage(GetDlgItem(hwndDlg
, IDC_OWNERORGANIZATION
), WM_SETTEXT
, 0, (LPARAM
)pSetupData
->OwnerOrganization
);
481 if (WriteOwnerSettings(pSetupData
->OwnerName
, pSetupData
->OwnerOrganization
))
483 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, IDD_COMPUTERPAGE
);
491 if (GetDlgItemTextW(hwndDlg
, IDC_OWNERNAME
, OwnerName
, 50) == 0)
493 if (0 == LoadStringW(hDllInstance
, IDS_REACTOS_SETUP
, Title
, sizeof(Title
) / sizeof(Title
[0])))
495 wcscpy(Title
, L
"ReactOS Setup");
497 if (0 == LoadStringW(hDllInstance
, IDS_WZD_NAME
, ErrorName
, sizeof(ErrorName
) / sizeof(ErrorName
[0])))
499 wcscpy(ErrorName
, L
"Setup cannot continue until you enter your name.");
501 MessageBoxW(hwndDlg
, ErrorName
, Title
, MB_ICONERROR
| MB_OK
);
503 SetFocus(GetDlgItem(hwndDlg
, IDC_OWNERNAME
));
504 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, -1);
509 OwnerOrganization
[0] = 0;
510 GetDlgItemTextW(hwndDlg
, IDC_OWNERORGANIZATION
, OwnerOrganization
, 50);
512 if (!WriteOwnerSettings(OwnerName
, OwnerOrganization
))
514 SetFocus(GetDlgItem(hwndDlg
, IDC_OWNERNAME
));
515 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, -1);
520 pSetupData
->UnattendSetup
= FALSE
;
538 WriteComputerSettings(WCHAR
* ComputerName
, HWND hwndDlg
)
541 WCHAR ErrorComputerName
[256];
543 if (!SetComputerNameW(ComputerName
))
547 if (0 == LoadStringW(hDllInstance
, IDS_REACTOS_SETUP
, Title
, sizeof(Title
) / sizeof(Title
[0])))
549 wcscpy(Title
, L
"ReactOS Setup");
551 if (0 == LoadStringW(hDllInstance
, IDS_WZD_SETCOMPUTERNAME
, ErrorComputerName
,
552 sizeof(ErrorComputerName
) / sizeof(ErrorComputerName
[0])))
554 wcscpy(ErrorComputerName
, L
"Setup failed to set the computer name.");
556 MessageBoxW(hwndDlg
, ErrorComputerName
, Title
, MB_ICONERROR
| MB_OK
);
562 /* Try to also set DNS hostname */
563 SetComputerNameExW(ComputerNamePhysicalDnsHostname
, ComputerName
);
565 /* Set the accounts domain name */
566 SetAccountsDomainSid(NULL
, ComputerName
);
574 WriteDefaultLogonData(LPWSTR Domain
)
576 WCHAR szAdministratorName
[256];
580 if (LoadStringW(hDllInstance
,
581 IDS_ADMINISTRATOR_NAME
,
583 sizeof(szAdministratorName
) / sizeof(WCHAR
)) == 0)
585 wcscpy(szAdministratorName
, L
"Administrator");
588 lError
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
589 L
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon",
593 if (lError
!= ERROR_SUCCESS
)
596 lError
= RegSetValueEx(hKey
,
601 (wcslen(Domain
)+ 1) * sizeof(WCHAR
));
602 if (lError
!= ERROR_SUCCESS
)
604 DPRINT1("RegSetValueEx(\"DefaultDomain\") failed!\n");
607 lError
= RegSetValueEx(hKey
,
611 (LPBYTE
)szAdministratorName
,
612 (wcslen(szAdministratorName
)+ 1) * sizeof(WCHAR
));
613 if (lError
!= ERROR_SUCCESS
)
615 DPRINT1("RegSetValueEx(\"DefaultUserName\") failed!\n");
624 /* lpBuffer will be filled with a 15-char string (plus the null terminator) */
626 GenerateComputerName(LPWSTR lpBuffer
)
628 static const WCHAR Chars
[] = L
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
629 static const unsigned cChars
= sizeof(Chars
) / sizeof(WCHAR
) - 1;
632 wcscpy(lpBuffer
, L
"REACTOS-");
634 srand(GetTickCount());
636 /* fill in 7 characters */
637 for (i
= 8; i
< 15; i
++)
638 lpBuffer
[i
] = Chars
[rand() % cChars
];
640 lpBuffer
[15] = UNICODE_NULL
; /* NULL-terminate */
643 static INT_PTR CALLBACK
644 ComputerPageDlgProc(HWND hwndDlg
,
649 WCHAR ComputerName
[MAX_COMPUTERNAME_LENGTH
+ 1];
650 WCHAR Password1
[128];
651 WCHAR Password2
[128];
654 WCHAR EmptyComputerName
[256], NotMatchPassword
[256], WrongPassword
[256];
656 PSETUPDATA pSetupData
;
658 pSetupData
= (PSETUPDATA
)GetWindowLongPtr(hwndDlg
, DWLP_USER
);
660 if (0 == LoadStringW(hDllInstance
, IDS_REACTOS_SETUP
, Title
, sizeof(Title
) / sizeof(Title
[0])))
662 wcscpy(Title
, L
"ReactOS Setup");
668 pSetupData
= (PSETUPDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
669 SetWindowLongPtr(hwndDlg
, DWLP_USER
, (LONG_PTR
)pSetupData
);
671 /* Generate a new pseudo-random computer name */
672 GenerateComputerName(ComputerName
);
674 /* Display current computer name */
675 SetDlgItemTextW(hwndDlg
, IDC_COMPUTERNAME
, ComputerName
);
677 /* Set text limits */
678 SendDlgItemMessage(hwndDlg
, IDC_COMPUTERNAME
, EM_LIMITTEXT
, MAX_COMPUTERNAME_LENGTH
, 0);
679 SendDlgItemMessage(hwndDlg
, IDC_ADMINPASSWORD1
, EM_LIMITTEXT
, 127, 0);
680 SendDlgItemMessage(hwndDlg
, IDC_ADMINPASSWORD2
, EM_LIMITTEXT
, 127, 0);
682 /* Set focus to computer name */
683 SetFocus(GetDlgItem(hwndDlg
, IDC_COMPUTERNAME
));
684 if (pSetupData
->UnattendSetup
)
686 SendMessage(GetDlgItem(hwndDlg
, IDC_COMPUTERNAME
), WM_SETTEXT
, 0, (LPARAM
)pSetupData
->ComputerName
);
687 SendMessage(GetDlgItem(hwndDlg
, IDC_ADMINPASSWORD1
), WM_SETTEXT
, 0, (LPARAM
)pSetupData
->AdminPassword
);
688 SendMessage(GetDlgItem(hwndDlg
, IDC_ADMINPASSWORD2
), WM_SETTEXT
, 0, (LPARAM
)pSetupData
->AdminPassword
);
689 WriteComputerSettings(pSetupData
->ComputerName
, NULL
);
690 SetAdministratorPassword(pSetupData
->AdminPassword
);
693 /* Store the administrator account name as the default user name */
694 WriteDefaultLogonData(pSetupData
->ComputerName
);
700 lpnm
= (LPNMHDR
)lParam
;
705 /* Enable the Back and Next buttons */
706 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_BACK
| PSWIZB_NEXT
);
707 if (pSetupData
->UnattendSetup
&& WriteComputerSettings(pSetupData
->ComputerName
, hwndDlg
))
709 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, IDD_THEMEPAGE
);
715 if (0 == GetDlgItemTextW(hwndDlg
, IDC_COMPUTERNAME
, ComputerName
, MAX_COMPUTERNAME_LENGTH
+ 1))
717 if (0 == LoadStringW(hDllInstance
, IDS_WZD_COMPUTERNAME
, EmptyComputerName
,
718 sizeof(EmptyComputerName
) / sizeof(EmptyComputerName
[0])))
720 wcscpy(EmptyComputerName
, L
"Setup cannot continue until you enter the name of your computer.");
722 MessageBoxW(hwndDlg
, EmptyComputerName
, Title
, MB_ICONERROR
| MB_OK
);
723 SetFocus(GetDlgItem(hwndDlg
, IDC_COMPUTERNAME
));
724 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, -1);
728 /* No need to check computer name for invalid characters,
729 * SetComputerName() will do it for us */
731 if (!WriteComputerSettings(ComputerName
, hwndDlg
))
733 SetFocus(GetDlgItem(hwndDlg
, IDC_COMPUTERNAME
));
734 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, -1);
739 /* Check if admin passwords have been entered */
740 if ((GetDlgItemText(hwndDlg
, IDC_ADMINPASSWORD1
, Password1
, 128) == 0) ||
741 (GetDlgItemText(hwndDlg
, IDC_ADMINPASSWORD2
, Password2
, 128) == 0))
743 if (0 == LoadStringW(hDllInstance
, IDS_WZD_PASSWORDEMPTY
, EmptyPassword
,
744 sizeof(EmptyPassword
) / sizeof(EmptyPassword
[0])))
746 wcscpy(EmptyPassword
, L
"You must enter a password !");
748 MessageBoxW(hwndDlg
, EmptyPassword
, Title
, MB_ICONERROR
| MB_OK
);
749 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, -1);
753 GetDlgItemTextW(hwndDlg
, IDC_ADMINPASSWORD1
, Password1
, 128);
754 GetDlgItemTextW(hwndDlg
, IDC_ADMINPASSWORD2
, Password2
, 128);
756 /* Check if passwords match */
757 if (wcscmp(Password1
, Password2
))
759 if (0 == LoadStringW(hDllInstance
, IDS_WZD_PASSWORDMATCH
, NotMatchPassword
,
760 sizeof(NotMatchPassword
) / sizeof(NotMatchPassword
[0])))
762 wcscpy(NotMatchPassword
, L
"The passwords you entered do not match. Please enter the desired password again.");
764 MessageBoxW(hwndDlg
, NotMatchPassword
, Title
, MB_ICONERROR
| MB_OK
);
765 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, -1);
769 /* Check password for invalid characters */
770 Password
= (PWCHAR
)Password1
;
773 if (!isprint(*Password
))
775 if (0 == LoadStringW(hDllInstance
, IDS_WZD_PASSWORDCHAR
, WrongPassword
,
776 sizeof(WrongPassword
) / sizeof(WrongPassword
[0])))
778 wcscpy(WrongPassword
, L
"The password you entered contains invalid characters. Please enter a cleaned password.");
780 MessageBoxW(hwndDlg
, WrongPassword
, Title
, MB_ICONERROR
| MB_OK
);
781 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, -1);
787 /* Set admin password */
788 SetAdministratorPassword(Password1
);
792 pSetupData
->UnattendSetup
= FALSE
;
810 SetKeyboardLayoutName(HWND hwnd
)
813 TCHAR szLayoutPath
[256];
814 TCHAR szLocaleName
[32];
818 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE
,
819 _T("SYSTEM\\CurrentControlSet\\Control\\NLS\\Locale"),
825 dwValueSize
= 16 * sizeof(TCHAR
);
826 if (RegQueryValueEx(hKey
,
837 _tcscpy(szLayoutPath
,
838 _T("SYSTEM\\CurrentControlSet\\Control\\Keyboard Layouts\\"));
839 _tcscat(szLayoutPath
,
842 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE
,
849 dwValueSize
= 32 * sizeof(TCHAR
);
850 if (RegQueryValueEx(hKey
,
867 RunControlPanelApplet(HWND hwnd
, PCWSTR pwszCPLParameters
)
870 if (pwszCPLParameters
)
872 STARTUPINFOW StartupInfo
;
873 PROCESS_INFORMATION ProcessInformation
;
874 WCHAR CmdLine
[MAX_PATH
] = L
"rundll32.exe shell32.dll,Control_RunDLL ";
876 ZeroMemory(&StartupInfo
, sizeof(StartupInfo
));
877 StartupInfo
.cb
= sizeof(StartupInfo
);
879 ASSERT(_countof(CmdLine
) > wcslen(CmdLine
) + wcslen(pwszCPLParameters
));
880 wcscat(CmdLine
, pwszCPLParameters
);
882 if (!CreateProcessW(NULL
,
891 &ProcessInformation
))
893 MessageBoxW(hwnd
, L
"Error: Failed to launch the Control Panel Applet.", NULL
, MB_ICONERROR
);
897 while((MsgWaitForMultipleObjects(1, &ProcessInformation
.hProcess
, FALSE
, INFINITE
, QS_ALLINPUT
|QS_ALLPOSTMESSAGE
)) != WAIT_OBJECT_0
)
899 while(PeekMessageW(&msg
, NULL
, 0, 0, PM_REMOVE
))
901 TranslateMessage(&msg
);
902 DispatchMessageW(&msg
);
905 CloseHandle(ProcessInformation
.hThread
);
906 CloseHandle(ProcessInformation
.hProcess
);
911 MessageBoxW(hwnd
, L
"Error: Failed to launch the Control Panel Applet.", NULL
, MB_ICONERROR
);
917 WriteUserLocale(VOID
)
923 lcid
= GetSystemDefaultLCID();
925 if (GetLocaleInfoW(MAKELCID(lcid
, SORT_DEFAULT
), LOCALE_ILANGUAGE
, Locale
, sizeof(Locale
) / sizeof(Locale
[0])) != 0)
927 if (RegCreateKeyExW(HKEY_CURRENT_USER
, L
"Control Panel\\International",
928 0, NULL
, REG_OPTION_NON_VOLATILE
,
929 KEY_WRITE
, NULL
, &hKey
, NULL
) == ERROR_SUCCESS
)
931 RegSetValueExW(hKey
, L
"Locale", 0, REG_SZ
, (LPBYTE
)Locale
, (wcslen(Locale
) + 1) * sizeof(WCHAR
));
937 static INT_PTR CALLBACK
938 LocalePageDlgProc(HWND hwndDlg
,
943 PSETUPDATA SetupData
;
945 /* Retrieve pointer to the global setup data */
946 SetupData
= (PSETUPDATA
)GetWindowLongPtr (hwndDlg
, GWL_USERDATA
);
952 /* Save pointer to the global setup data */
953 SetupData
= (PSETUPDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
954 SetWindowLongPtr(hwndDlg
, GWL_USERDATA
, (DWORD_PTR
)SetupData
);
957 SetKeyboardLayoutName(GetDlgItem(hwndDlg
, IDC_LAYOUTTEXT
));
962 if (HIWORD(wParam
) == BN_CLICKED
)
964 switch (LOWORD(wParam
))
966 case IDC_CUSTOMLOCALE
:
967 RunControlPanelApplet(hwndDlg
, L
"intl.cpl,,5");
968 /* FIXME: Update input locale name */
971 case IDC_CUSTOMLAYOUT
:
972 RunControlPanelApplet(hwndDlg
, L
"input.dll,@1");
980 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
985 /* Enable the Back and Next buttons */
986 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_BACK
| PSWIZB_NEXT
);
987 if (SetupData
->UnattendSetup
)
989 WCHAR wszPath
[MAX_PATH
];
990 if (GetRosInstallCD(wszPath
, _countof(wszPath
)))
992 WCHAR wszParams
[1024];
993 swprintf(wszParams
, L
"intl.cpl,,/f:\"%sreactos\\unattend.inf\"", wszPath
);
994 RunControlPanelApplet(hwndDlg
, wszParams
);
998 RunControlPanelApplet(hwndDlg
, L
"intl.cpl,,/f:\"unattend.inf\"");
1001 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, IDD_OWNERPAGE
);
1010 SetupData
->UnattendSetup
= FALSE
;
1027 static PTIMEZONE_ENTRY
1028 GetLargerTimeZoneEntry(PSETUPDATA SetupData
, DWORD Index
)
1030 PTIMEZONE_ENTRY Entry
;
1032 Entry
= SetupData
->TimeZoneListHead
;
1033 while (Entry
!= NULL
)
1035 if (Entry
->Index
>= Index
)
1038 Entry
= Entry
->Next
;
1046 CreateTimeZoneList(PSETUPDATA SetupData
)
1048 WCHAR szKeyName
[256];
1056 PTIMEZONE_ENTRY Entry
;
1057 PTIMEZONE_ENTRY Current
;
1059 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
1060 L
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones",
1069 dwNameSize
= 256 * sizeof(WCHAR
);
1070 lError
= RegEnumKeyExW(hZonesKey
,
1078 if (lError
!= ERROR_SUCCESS
&& lError
!= ERROR_MORE_DATA
)
1081 if (RegOpenKeyExW(hZonesKey
,
1088 Entry
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(TIMEZONE_ENTRY
));
1091 RegCloseKey(hZoneKey
);
1095 dwValueSize
= 64 * sizeof(WCHAR
);
1096 if (RegQueryValueExW(hZoneKey
,
1100 (LPBYTE
)&Entry
->Description
,
1103 RegCloseKey(hZoneKey
);
1107 dwValueSize
= 32 * sizeof(WCHAR
);
1108 if (RegQueryValueExW(hZoneKey
,
1112 (LPBYTE
)&Entry
->StandardName
,
1115 RegCloseKey(hZoneKey
);
1119 dwValueSize
= 32 * sizeof(WCHAR
);
1120 if (RegQueryValueExW(hZoneKey
,
1124 (LPBYTE
)&Entry
->DaylightName
,
1127 RegCloseKey(hZoneKey
);
1131 dwValueSize
= sizeof(DWORD
);
1132 if (RegQueryValueExW(hZoneKey
,
1136 (LPBYTE
)&Entry
->Index
,
1139 RegCloseKey(hZoneKey
);
1143 dwValueSize
= sizeof(TZ_INFO
);
1144 if (RegQueryValueExW(hZoneKey
,
1148 (LPBYTE
)&Entry
->TimezoneInfo
,
1151 RegCloseKey(hZoneKey
);
1155 RegCloseKey(hZoneKey
);
1157 if (SetupData
->TimeZoneListHead
== NULL
&&
1158 SetupData
->TimeZoneListTail
== NULL
)
1162 SetupData
->TimeZoneListHead
= Entry
;
1163 SetupData
->TimeZoneListTail
= Entry
;
1167 Current
= GetLargerTimeZoneEntry(SetupData
, Entry
->Index
);
1168 if (Current
!= NULL
)
1170 if (Current
== SetupData
->TimeZoneListHead
)
1172 /* Prepend to head */
1174 Entry
->Next
= SetupData
->TimeZoneListHead
;
1175 SetupData
->TimeZoneListHead
->Prev
= Entry
;
1176 SetupData
->TimeZoneListHead
= Entry
;
1180 /* Insert before current */
1181 Entry
->Prev
= Current
->Prev
;
1182 Entry
->Next
= Current
;
1183 Current
->Prev
->Next
= Entry
;
1184 Current
->Prev
= Entry
;
1189 /* Append to tail */
1190 Entry
->Prev
= SetupData
->TimeZoneListTail
;
1192 SetupData
->TimeZoneListTail
->Next
= Entry
;
1193 SetupData
->TimeZoneListTail
= Entry
;
1200 RegCloseKey(hZonesKey
);
1205 DestroyTimeZoneList(PSETUPDATA SetupData
)
1207 PTIMEZONE_ENTRY Entry
;
1209 while (SetupData
->TimeZoneListHead
!= NULL
)
1211 Entry
= SetupData
->TimeZoneListHead
;
1213 SetupData
->TimeZoneListHead
= Entry
->Next
;
1214 if (SetupData
->TimeZoneListHead
!= NULL
)
1216 SetupData
->TimeZoneListHead
->Prev
= NULL
;
1219 HeapFree(GetProcessHeap(), 0, Entry
);
1222 SetupData
->TimeZoneListTail
= NULL
;
1226 GetTimeZoneListIndex(LPDWORD lpIndex
)
1228 WCHAR szLanguageIdString
[9];
1235 BOOL bFound
= FALSE
;
1236 unsigned long iLanguageID
;
1240 *lpIndex
= 85; /* fallback to GMT time zone */
1242 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
1243 L
"SYSTEM\\CurrentControlSet\\Control\\NLS\\Language",
1249 dwValueSize
= 9 * sizeof(WCHAR
);
1250 if (RegQueryValueExW(hKey
,
1254 (LPBYTE
)szLanguageIdString
,
1261 iLanguageID
= wcstoul(szLanguageIdString
, NULL
, 16);
1266 iLanguageID
= *lpIndex
;
1269 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
1270 L
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones",
1277 if (RegQueryValueExW(hKey
,
1288 Buffer
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, dwValueSize
);
1295 if (RegQueryValueExW(hKey
,
1302 HeapFree(GetProcessHeap(), 0, Buffer
);
1312 Length
= wcslen(Ptr
);
1313 if (wcstoul(Ptr
, NULL
, 16) == iLanguageID
)
1316 Ptr
= Ptr
+ Length
+ 1;
1322 *lpIndex
= wcstoul(Ptr
, &End
, 10);
1323 HeapFree(GetProcessHeap(), 0, Buffer
);
1327 Length
= wcslen(Ptr
);
1328 Ptr
= Ptr
+ Length
+ 1;
1331 HeapFree(GetProcessHeap(), 0, Buffer
);
1338 ShowTimeZoneList(HWND hwnd
, PSETUPDATA SetupData
, DWORD dwEntryIndex
)
1340 PTIMEZONE_ENTRY Entry
;
1344 GetTimeZoneListIndex(&dwEntryIndex
);
1346 Entry
= SetupData
->TimeZoneListHead
;
1347 while (Entry
!= NULL
)
1349 dwCount
= SendMessage(hwnd
,
1352 (LPARAM
)Entry
->Description
);
1354 if (dwEntryIndex
!= 0 && dwEntryIndex
== Entry
->Index
)
1357 Entry
= Entry
->Next
;
1368 SetLocalTimeZone(HWND hwnd
, PSETUPDATA SetupData
)
1370 TIME_ZONE_INFORMATION TimeZoneInformation
;
1371 PTIMEZONE_ENTRY Entry
;
1375 dwIndex
= SendMessage(hwnd
,
1381 Entry
= SetupData
->TimeZoneListHead
;
1388 Entry
= Entry
->Next
;
1391 wcscpy(TimeZoneInformation
.StandardName
,
1392 Entry
->StandardName
);
1393 wcscpy(TimeZoneInformation
.DaylightName
,
1394 Entry
->DaylightName
);
1396 TimeZoneInformation
.Bias
= Entry
->TimezoneInfo
.Bias
;
1397 TimeZoneInformation
.StandardBias
= Entry
->TimezoneInfo
.StandardBias
;
1398 TimeZoneInformation
.DaylightBias
= Entry
->TimezoneInfo
.DaylightBias
;
1400 memcpy(&TimeZoneInformation
.StandardDate
,
1401 &Entry
->TimezoneInfo
.StandardDate
,
1402 sizeof(SYSTEMTIME
));
1403 memcpy(&TimeZoneInformation
.DaylightDate
,
1404 &Entry
->TimezoneInfo
.DaylightDate
,
1405 sizeof(SYSTEMTIME
));
1407 /* Set time zone information */
1408 SetTimeZoneInformation(&TimeZoneInformation
);
1413 GetLocalSystemTime(HWND hwnd
, PSETUPDATA SetupData
)
1418 if (DateTime_GetSystemtime(GetDlgItem(hwnd
, IDC_DATEPICKER
), &Date
) != GDT_VALID
)
1423 if (DateTime_GetSystemtime(GetDlgItem(hwnd
, IDC_TIMEPICKER
), &Time
) != GDT_VALID
)
1428 SetupData
->SystemTime
.wYear
= Date
.wYear
;
1429 SetupData
->SystemTime
.wMonth
= Date
.wMonth
;
1430 SetupData
->SystemTime
.wDayOfWeek
= Date
.wDayOfWeek
;
1431 SetupData
->SystemTime
.wDay
= Date
.wDay
;
1432 SetupData
->SystemTime
.wHour
= Time
.wHour
;
1433 SetupData
->SystemTime
.wMinute
= Time
.wMinute
;
1434 SetupData
->SystemTime
.wSecond
= Time
.wSecond
;
1435 SetupData
->SystemTime
.wMilliseconds
= Time
.wMilliseconds
;
1442 SetAutoDaylightInfo(HWND hwnd
)
1447 if (SendMessage(hwnd
, BM_GETCHECK
, 0, 0) == BST_UNCHECKED
)
1449 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
1450 L
"SYSTEM\\CurrentControlSet\\Control\\TimeZoneInformation",
1456 RegSetValueExW(hKey
,
1457 L
"DisableAutoDaylightTimeSet",
1468 SetSystemLocalTime(HWND hwnd
, PSETUPDATA SetupData
)
1473 * Call SetLocalTime twice to ensure correct results
1475 Ret
= SetLocalTime(&SetupData
->SystemTime
) &&
1476 SetLocalTime(&SetupData
->SystemTime
);
1483 UpdateLocalSystemTime(HWND hwnd
)
1485 SYSTEMTIME LocalTime
;
1487 GetLocalTime(&LocalTime
);
1488 DateTime_SetSystemtime(GetDlgItem(hwnd
, IDC_DATEPICKER
), GDT_VALID
, &LocalTime
);
1489 DateTime_SetSystemtime(GetDlgItem(hwnd
, IDC_TIMEPICKER
), GDT_VALID
, &LocalTime
);
1494 WriteDateTimeSettings(HWND hwndDlg
, PSETUPDATA SetupData
)
1497 WCHAR ErrorLocalTime
[256];
1499 GetLocalSystemTime(hwndDlg
, SetupData
);
1500 SetLocalTimeZone(GetDlgItem(hwndDlg
, IDC_TIMEZONELIST
),
1503 SetAutoDaylightInfo(GetDlgItem(hwndDlg
, IDC_AUTODAYLIGHT
));
1504 if(!SetSystemLocalTime(hwndDlg
, SetupData
))
1506 if (0 == LoadStringW(hDllInstance
, IDS_REACTOS_SETUP
, Title
, sizeof(Title
) / sizeof(Title
[0])))
1508 wcscpy(Title
, L
"ReactOS Setup");
1510 if (0 == LoadStringW(hDllInstance
, IDS_WZD_LOCALTIME
, ErrorLocalTime
,
1511 sizeof(ErrorLocalTime
) / sizeof(ErrorLocalTime
[0])))
1513 wcscpy(ErrorLocalTime
, L
"Setup was unable to set the local time.");
1515 MessageBoxW(hwndDlg
, ErrorLocalTime
, Title
, MB_ICONWARNING
| MB_OK
);
1523 static INT_PTR CALLBACK
1524 DateTimePageDlgProc(HWND hwndDlg
,
1529 PSETUPDATA SetupData
;
1531 /* Retrieve pointer to the global setup data */
1532 SetupData
= (PSETUPDATA
)GetWindowLongPtr (hwndDlg
, GWL_USERDATA
);
1537 /* Save pointer to the global setup data */
1538 SetupData
= (PSETUPDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
1539 SetWindowLongPtr(hwndDlg
, GWL_USERDATA
, (DWORD_PTR
)SetupData
);
1541 CreateTimeZoneList(SetupData
);
1543 if (SetupData
->UnattendSetup
)
1545 ShowTimeZoneList(GetDlgItem(hwndDlg
, IDC_TIMEZONELIST
),
1546 SetupData
, SetupData
->TimeZoneIndex
);
1548 if (!SetupData
->DisableAutoDaylightTimeSet
)
1550 SendDlgItemMessage(hwndDlg
, IDC_AUTODAYLIGHT
, BM_SETCHECK
, (WPARAM
)BST_CHECKED
, 0);
1555 ShowTimeZoneList(GetDlgItem(hwndDlg
, IDC_TIMEZONELIST
),
1558 SendDlgItemMessage(hwndDlg
, IDC_AUTODAYLIGHT
, BM_SETCHECK
, (WPARAM
)BST_CHECKED
, 0);
1563 UpdateLocalSystemTime(hwndDlg
);
1567 switch (((LPNMHDR
)lParam
)->code
)
1570 /* Enable the Back and Next buttons */
1571 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_BACK
| PSWIZB_NEXT
);
1572 if (SetupData
->UnattendSetup
&& WriteDateTimeSettings(hwndDlg
, SetupData
))
1574 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, SetupData
->uFirstNetworkWizardPage
);
1577 SetTimer(hwndDlg
, 1, 1000, NULL
);
1580 case PSN_KILLACTIVE
:
1581 case DTN_DATETIMECHANGE
:
1582 KillTimer(hwndDlg
, 1);
1586 WriteDateTimeSettings(hwndDlg
, SetupData
);
1590 SetupData
->UnattendSetup
= FALSE
;
1599 DestroyTimeZoneList(SetupData
);
1610 static INT_PTR CALLBACK
1611 ThemePageDlgProc(HWND hwndDlg
,
1616 PSETUPDATA SetupData
;
1618 /* Retrieve pointer to the global setup data */
1619 SetupData
= (PSETUPDATA
)GetWindowLongPtr (hwndDlg
, GWL_USERDATA
);
1625 BUTTON_IMAGELIST imldata
= {0, {0,10,0,10}, BUTTON_IMAGELIST_ALIGN_TOP
};
1627 /* Save pointer to the global setup data */
1628 SetupData
= (PSETUPDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
1629 SetWindowLongPtr(hwndDlg
, GWL_USERDATA
, (DWORD_PTR
)SetupData
);
1631 imldata
.himl
= ImageList_LoadImage(hDllInstance
, MAKEINTRESOURCE(IDB_CLASSIC
), 0, 0, CLR_NONE
, IMAGE_BITMAP
, LR_CREATEDIBSECTION
);
1632 SendDlgItemMessage(hwndDlg
, IDC_CLASSICSTYLE
, BCM_SETIMAGELIST
, 0, (LPARAM
)&imldata
);
1634 imldata
.himl
= ImageList_LoadImage(hDllInstance
, MAKEINTRESOURCE(IDB_LAUTUS
), 0, 0, CLR_NONE
, IMAGE_BITMAP
, LR_CREATEDIBSECTION
);
1635 SendDlgItemMessage(hwndDlg
, IDC_THEMEDSTYLE
, BCM_SETIMAGELIST
, 0, (LPARAM
)&imldata
);
1637 SendDlgItemMessage(hwndDlg
, IDC_CLASSICSTYLE
, BM_SETCHECK
, BST_CHECKED
, 0);
1641 if (HIWORD(wParam
) == BN_CLICKED
)
1643 switch (LOWORD(wParam
))
1645 case IDC_THEMEDSTYLE
:
1647 WCHAR wszParams
[1024];
1648 WCHAR wszTheme
[MAX_PATH
];
1649 WCHAR
* format
= L
"desk.cpl desk,@Appearance /Action:ActivateMSTheme /file:\"%s\"";
1651 SHGetFolderPathAndSubDirW(0, CSIDL_RESOURCES
, NULL
, SHGFP_TYPE_DEFAULT
, L
"themes\\lautus\\lautus.msstyles", wszTheme
);
1652 swprintf(wszParams
, format
, wszTheme
);
1653 RunControlPanelApplet(hwndDlg
, wszParams
);
1656 case IDC_CLASSICSTYLE
:
1657 RunControlPanelApplet(hwndDlg
, L
"desk.cpl desk,@Appearance /Action:ActivateMSTheme");
1662 switch (((LPNMHDR
)lParam
)->code
)
1665 /* Enable the Back and Next buttons */
1666 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_BACK
| PSWIZB_NEXT
);
1667 if (SetupData
->UnattendSetup
)
1669 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, SetupData
->uFirstNetworkWizardPage
);
1678 SetupData
->UnattendSetup
= FALSE
;
1693 static UINT CALLBACK
1694 RegistrationNotificationProc(PVOID Context
,
1699 PREGISTRATIONDATA RegistrationData
;
1700 REGISTRATIONNOTIFY RegistrationNotify
;
1701 PSP_REGISTER_CONTROL_STATUSW StatusInfo
;
1703 WCHAR ErrorMessage
[128];
1705 RegistrationData
= (PREGISTRATIONDATA
) Context
;
1707 if (SPFILENOTIFY_STARTREGISTRATION
== Notification
||
1708 SPFILENOTIFY_ENDREGISTRATION
== Notification
)
1710 StatusInfo
= (PSP_REGISTER_CONTROL_STATUSW
) Param1
;
1711 RegistrationNotify
.CurrentItem
= wcsrchr(StatusInfo
->FileName
, L
'\\');
1712 if (NULL
== RegistrationNotify
.CurrentItem
)
1714 RegistrationNotify
.CurrentItem
= StatusInfo
->FileName
;
1718 RegistrationNotify
.CurrentItem
++;
1721 if (SPFILENOTIFY_STARTREGISTRATION
== Notification
)
1723 DPRINT("Received SPFILENOTIFY_STARTREGISTRATION notification for %S\n",
1724 StatusInfo
->FileName
);
1725 RegistrationNotify
.ErrorMessage
= NULL
;
1726 RegistrationNotify
.Progress
= RegistrationData
->Registered
;
1730 DPRINT("Received SPFILENOTIFY_ENDREGISTRATION notification for %S\n",
1731 StatusInfo
->FileName
);
1732 DPRINT("Win32Error %u FailureCode %u\n", StatusInfo
->Win32Error
,
1733 StatusInfo
->FailureCode
);
1734 if (SPREG_SUCCESS
!= StatusInfo
->FailureCode
)
1736 switch(StatusInfo
->FailureCode
)
1738 case SPREG_LOADLIBRARY
:
1739 MessageID
= IDS_LOADLIBRARY_FAILED
;
1741 case SPREG_GETPROCADDR
:
1742 MessageID
= IDS_GETPROCADDR_FAILED
;
1745 MessageID
= IDS_REGSVR_FAILED
;
1747 case SPREG_DLLINSTALL
:
1748 MessageID
= IDS_DLLINSTALL_FAILED
;
1751 MessageID
= IDS_TIMEOUT
;
1754 MessageID
= IDS_REASON_UNKNOWN
;
1757 if (0 == LoadStringW(hDllInstance
, MessageID
,
1759 sizeof(ErrorMessage
) /
1760 sizeof(ErrorMessage
[0])))
1762 ErrorMessage
[0] = L
'\0';
1764 if (SPREG_TIMEOUT
!= StatusInfo
->FailureCode
)
1766 FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM
, NULL
,
1767 StatusInfo
->Win32Error
, 0,
1768 ErrorMessage
+ wcslen(ErrorMessage
),
1769 sizeof(ErrorMessage
) / sizeof(ErrorMessage
[0]) -
1770 wcslen(ErrorMessage
), NULL
);
1772 RegistrationNotify
.ErrorMessage
= ErrorMessage
;
1776 RegistrationNotify
.ErrorMessage
= NULL
;
1778 if (RegistrationData
->Registered
< RegistrationData
->DllCount
)
1780 RegistrationData
->Registered
++;
1784 RegistrationNotify
.Progress
= RegistrationData
->Registered
;
1785 RegistrationNotify
.ActivityID
= IDS_REGISTERING_COMPONENTS
;
1786 SendMessage(RegistrationData
->hwndDlg
, PM_REGISTRATION_NOTIFY
,
1787 0, (LPARAM
) &RegistrationNotify
);
1793 DPRINT1("Received unexpected notification %u\n", Notification
);
1794 return SetupDefaultQueueCallback(RegistrationData
->DefaultContext
,
1795 Notification
, Param1
, Param2
);
1800 static DWORD CALLBACK
1801 RegistrationProc(LPVOID Parameter
)
1803 PREGISTRATIONDATA RegistrationData
;
1804 REGISTRATIONNOTIFY RegistrationNotify
;
1805 DWORD LastError
= NO_ERROR
;
1806 WCHAR UnknownError
[84];
1808 RegistrationData
= (PREGISTRATIONDATA
) Parameter
;
1809 RegistrationData
->Registered
= 0;
1810 RegistrationData
->DefaultContext
= SetupInitDefaultQueueCallback(RegistrationData
->hwndDlg
);
1814 if (!SetupInstallFromInfSectionW(GetParent(RegistrationData
->hwndDlg
),
1816 L
"RegistrationPhase2",
1818 SPINST_REGISTERCALLBACKAWARE
|
1823 RegistrationNotificationProc
,
1828 LastError
= GetLastError();
1831 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1833 DPRINT("Catching exception\n");
1834 LastError
= RtlNtStatusToDosError(_SEH2_GetExceptionCode());
1838 if (NO_ERROR
== LastError
)
1840 RegistrationNotify
.ErrorMessage
= NULL
;
1844 DPRINT1("SetupInstallFromInfSection failed with error %u\n",
1846 if (0 == FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER
|
1847 FORMAT_MESSAGE_FROM_SYSTEM
, NULL
, LastError
, 0,
1848 (LPWSTR
) &RegistrationNotify
.ErrorMessage
, 0,
1851 if (0 == LoadStringW(hDllInstance
, IDS_UNKNOWN_ERROR
,
1853 sizeof(UnknownError
) / sizeof(UnknownError
[0]) -
1856 wcscpy(UnknownError
, L
"Unknown error");
1858 wcscat(UnknownError
, L
" ");
1859 _ultow(LastError
, UnknownError
+ wcslen(UnknownError
), 10);
1860 RegistrationNotify
.ErrorMessage
= UnknownError
;
1864 RegistrationNotify
.Progress
= RegistrationData
->DllCount
;
1865 RegistrationNotify
.ActivityID
= IDS_REGISTERING_COMPONENTS
;
1866 RegistrationNotify
.CurrentItem
= NULL
;
1867 SendMessage(RegistrationData
->hwndDlg
, PM_REGISTRATION_NOTIFY
,
1868 1, (LPARAM
) &RegistrationNotify
);
1869 if (NULL
!= RegistrationNotify
.ErrorMessage
&&
1870 UnknownError
!= RegistrationNotify
.ErrorMessage
)
1872 LocalFree((PVOID
) RegistrationNotify
.ErrorMessage
);
1875 SetupTermDefaultQueueCallback(RegistrationData
->DefaultContext
);
1876 HeapFree(GetProcessHeap(), 0, RegistrationData
);
1878 RegisterTypeLibraries(hSysSetupInf
, L
"TypeLibraries");
1880 // FIXME: Move this call to a separate cleanup page!
1881 RtlCreateBootStatusDataFile();
1888 StartComponentRegistration(HWND hwndDlg
, PULONG MaxProgress
)
1890 HANDLE RegistrationThread
;
1893 WCHAR SectionName
[512];
1894 PREGISTRATIONDATA RegistrationData
;
1897 if (! SetupFindFirstLineW(hSysSetupInf
, L
"RegistrationPhase2",
1898 L
"RegisterDlls", &Context
))
1900 DPRINT1("No RegistrationPhase2 section found\n");
1903 if (! SetupGetStringFieldW(&Context
, 1, SectionName
,
1904 sizeof(SectionName
) / sizeof(SectionName
[0]),
1907 DPRINT1("Unable to retrieve section name\n");
1910 DllCount
= SetupGetLineCountW(hSysSetupInf
, SectionName
);
1911 DPRINT("SectionName %S DllCount %ld\n", SectionName
, DllCount
);
1914 SetLastError(STATUS_NOT_FOUND
);
1918 *MaxProgress
= (ULONG
) DllCount
;
1921 * Create a background thread to do the actual registrations, so the
1922 * main thread can just run its message loop.
1924 RegistrationThread
= NULL
;
1925 RegistrationData
= HeapAlloc(GetProcessHeap(), 0,
1926 sizeof(REGISTRATIONDATA
));
1927 if (RegistrationData
!= NULL
)
1929 RegistrationData
->hwndDlg
= hwndDlg
;
1930 RegistrationData
->DllCount
= DllCount
;
1931 RegistrationThread
= CreateThread(NULL
, 0, RegistrationProc
,
1932 RegistrationData
, 0, NULL
);
1933 if (RegistrationThread
!= NULL
)
1935 CloseHandle(RegistrationThread
);
1939 DPRINT1("CreateThread failed, error %u\n", GetLastError());
1940 HeapFree(GetProcessHeap(), 0, RegistrationData
);
1946 DPRINT1("HeapAlloc() failed, error %u\n", GetLastError());
1954 static INT_PTR CALLBACK
1955 ProcessPageDlgProc(HWND hwndDlg
,
1960 PSETUPDATA SetupData
;
1961 PREGISTRATIONNOTIFY RegistrationNotify
;
1962 static UINT oldActivityID
= -1;
1965 /* Retrieve pointer to the global setup data */
1966 SetupData
= (PSETUPDATA
)GetWindowLongPtr (hwndDlg
, GWL_USERDATA
);
1972 /* Save pointer to the global setup data */
1973 SetupData
= (PSETUPDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
1974 SetWindowLongPtr(hwndDlg
, GWL_USERDATA
, (DWORD_PTR
)SetupData
);
1980 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
1981 ULONG MaxProgress
= 0;
1986 /* Disable the Back and Next buttons */
1987 PropSheet_SetWizButtons(GetParent(hwndDlg
), 0);
1989 StartComponentRegistration(hwndDlg
, &MaxProgress
);
1991 SendDlgItemMessage(hwndDlg
, IDC_PROCESSPROGRESS
, PBM_SETRANGE
,
1992 0, MAKELPARAM(0, MaxProgress
));
1993 SendDlgItemMessage(hwndDlg
, IDC_PROCESSPROGRESS
, PBM_SETPOS
,
2001 SetupData
->UnattendSetup
= FALSE
;
2010 case PM_REGISTRATION_NOTIFY
:
2013 RegistrationNotify
= (PREGISTRATIONNOTIFY
) lParam
;
2014 // update if necessary only
2015 if (oldActivityID
!= RegistrationNotify
->ActivityID
)
2017 if (0 != LoadStringW(hDllInstance
, RegistrationNotify
->ActivityID
,
2019 sizeof(Activity
) / sizeof(Activity
[0])))
2021 SendDlgItemMessageW(hwndDlg
, IDC_ACTIVITY
, WM_SETTEXT
,
2022 0, (LPARAM
) Activity
);
2024 oldActivityID
= RegistrationNotify
->ActivityID
;
2026 SendDlgItemMessageW(hwndDlg
, IDC_ITEM
, WM_SETTEXT
, 0,
2027 (LPARAM
)(NULL
== RegistrationNotify
->CurrentItem
?
2028 L
"" : RegistrationNotify
->CurrentItem
));
2029 SendDlgItemMessage(hwndDlg
, IDC_PROCESSPROGRESS
, PBM_SETPOS
,
2030 RegistrationNotify
->Progress
, 0);
2031 if (NULL
!= RegistrationNotify
->ErrorMessage
)
2033 if (0 == LoadStringW(hDllInstance
, IDS_REACTOS_SETUP
,
2034 Title
, sizeof(Title
) / sizeof(Title
[0])))
2036 wcscpy(Title
, L
"ReactOS Setup");
2038 MessageBoxW(hwndDlg
, RegistrationNotify
->ErrorMessage
,
2039 Title
, MB_ICONERROR
| MB_OK
);
2045 /* Enable the Back and Next buttons */
2046 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_NEXT
);
2047 PropSheet_PressButton(GetParent(hwndDlg
), PSBTN_NEXT
);
2061 SetInstallationCompleted(VOID
)
2064 DWORD InProgress
= 0;
2067 if (RegOpenKeyExW( HKEY_LOCAL_MACHINE
,
2071 &hKey
) == ERROR_SUCCESS
)
2073 RegSetValueExW( hKey
, L
"SystemSetupInProgress", 0, REG_DWORD
, (LPBYTE
)&InProgress
, sizeof(InProgress
) );
2074 RegCloseKey( hKey
);
2077 if (RegOpenKeyExW( HKEY_LOCAL_MACHINE
,
2078 L
"Software\\Microsoft\\Windows NT\\CurrentVersion",
2081 &hKey
) == ERROR_SUCCESS
)
2083 InstallDate
= (DWORD
)time(NULL
);
2084 RegSetValueExW( hKey
, L
"InstallDate", 0, REG_DWORD
, (LPBYTE
)&InstallDate
, sizeof(InstallDate
) );
2085 RegCloseKey( hKey
);
2089 static INT_PTR CALLBACK
2090 FinishDlgProc(HWND hwndDlg
,
2100 /* Get pointer to the global setup data */
2101 PSETUPDATA SetupData
= (PSETUPDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
2103 if (!SetupData
->UnattendSetup
|| !SetupData
->DisableGeckoInst
)
2105 /* Run the Wine Gecko prompt */
2106 Control_RunDLLW(hwndDlg
, 0, L
"appwiz.cpl install_gecko", SW_SHOW
);
2109 /* Set title font */
2110 SendDlgItemMessage(hwndDlg
,
2113 (WPARAM
)SetupData
->hTitleFont
,
2115 if (SetupData
->UnattendSetup
)
2117 KillTimer(hwndDlg
, 1);
2118 SetInstallationCompleted();
2126 SetInstallationCompleted();
2136 hWndProgress
= GetDlgItem(hwndDlg
, IDC_RESTART_PROGRESS
);
2137 Position
= SendMessage(hWndProgress
, PBM_GETPOS
, 0, 0);
2138 if (Position
== 300)
2140 KillTimer(hwndDlg
, 1);
2141 PropSheet_PressButton(GetParent(hwndDlg
), PSBTN_FINISH
);
2145 SendMessage(hWndProgress
, PBM_SETPOS
, Position
+ 1, 0);
2152 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
2157 /* Enable the correct buttons on for the active page */
2158 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_FINISH
);
2160 SendDlgItemMessage(hwndDlg
, IDC_RESTART_PROGRESS
, PBM_SETRANGE
, 0,
2161 MAKELPARAM(0, 300));
2162 SendDlgItemMessage(hwndDlg
, IDC_RESTART_PROGRESS
, PBM_SETPOS
, 0, 0);
2163 SetTimer(hwndDlg
, 1, 50, NULL
);
2167 DestroyWindow(GetParent(hwndDlg
));
2186 PSETUPDATA pSetupData
)
2188 INFCONTEXT InfContext
;
2190 WCHAR szValue
[MAX_PATH
];
2194 if (!SetupFindFirstLineW(pSetupData
->hUnattendedInf
,
2196 L
"UnattendSetupEnabled",
2199 DPRINT1("Error: Cant find UnattendSetupEnabled Key! %d\n", GetLastError());
2203 if (!SetupGetStringFieldW(&InfContext
,
2206 sizeof(szValue
) / sizeof(WCHAR
),
2209 DPRINT1("Error: SetupGetStringField failed with %d\n", GetLastError());
2213 if (wcscmp(szValue
, L
"yes") != 0)
2215 DPRINT("Unattend setup was disabled by UnattendSetupEnabled key.\n");
2219 pSetupData
->UnattendSetup
= TRUE
;
2221 if (!SetupFindFirstLineW(pSetupData
->hUnattendedInf
,
2226 DPRINT1("Error: SetupFindFirstLine failed %d\n", GetLastError());
2232 if (!SetupGetStringFieldW(&InfContext
,
2235 sizeof(szName
) / sizeof(WCHAR
),
2238 DPRINT1("Error: SetupGetStringField failed with %d\n", GetLastError());
2242 if (!SetupGetStringFieldW(&InfContext
,
2245 sizeof(szValue
) / sizeof(WCHAR
),
2248 DPRINT1("Error: SetupGetStringField failed with %d\n", GetLastError());
2251 DPRINT1("Name %S Value %S\n", szName
, szValue
);
2252 if (!wcscmp(szName
, L
"FullName"))
2254 if ((sizeof(pSetupData
->OwnerName
) / sizeof(TCHAR
)) > LineLength
)
2256 wcscpy(pSetupData
->OwnerName
, szValue
);
2259 else if (!wcscmp(szName
, L
"OrgName"))
2261 if ((sizeof(pSetupData
->OwnerOrganization
) / sizeof(WCHAR
)) > LineLength
)
2263 wcscpy(pSetupData
->OwnerOrganization
, szValue
);
2266 else if (!wcscmp(szName
, L
"ComputerName"))
2268 if ((sizeof(pSetupData
->ComputerName
) / sizeof(WCHAR
)) > LineLength
)
2270 wcscpy(pSetupData
->ComputerName
, szValue
);
2273 else if (!wcscmp(szName
, L
"AdminPassword"))
2275 if ((sizeof(pSetupData
->AdminPassword
) / sizeof(WCHAR
)) > LineLength
)
2277 wcscpy(pSetupData
->AdminPassword
, szValue
);
2280 else if (!wcscmp(szName
, L
"TimeZoneIndex"))
2282 pSetupData
->TimeZoneIndex
= _wtoi(szValue
);
2284 else if (!wcscmp(szName
, L
"DisableAutoDaylightTimeSet"))
2286 pSetupData
->DisableAutoDaylightTimeSet
= _wtoi(szValue
);
2288 else if (!wcscmp(szName
, L
"DisableGeckoInst"))
2290 if(!wcscmp(szValue
, L
"yes"))
2291 pSetupData
->DisableGeckoInst
= 1;
2293 pSetupData
->DisableGeckoInst
= 0;
2297 while (SetupFindNextLine(&InfContext
, &InfContext
));
2299 if (SetupFindFirstLineW(pSetupData
->hUnattendedInf
,
2304 DEVMODEW dm
= { { 0 } };
2305 dm
.dmSize
= sizeof(dm
);
2306 if (EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &dm
))
2311 if (!SetupGetStringFieldW(&InfContext
,
2314 sizeof(szName
) / sizeof(WCHAR
),
2317 DPRINT1("Error: SetupGetStringField failed with %d\n", GetLastError());
2321 if (!SetupGetStringFieldW(&InfContext
,
2324 sizeof(szValue
) / sizeof(WCHAR
),
2327 DPRINT1("Error: SetupGetStringField failed with %d\n", GetLastError());
2330 iValue
= _wtoi(szValue
);
2331 DPRINT1("Name %S Value %i\n", szName
, iValue
);
2336 if (!wcscmp(szName
, L
"BitsPerPel"))
2338 dm
.dmFields
|= DM_BITSPERPEL
;
2339 dm
.dmBitsPerPel
= iValue
;
2341 else if (!wcscmp(szName
, L
"XResolution"))
2343 dm
.dmFields
|= DM_PELSWIDTH
;
2344 dm
.dmPelsWidth
= iValue
;
2346 else if (!wcscmp(szName
, L
"YResolution"))
2348 dm
.dmFields
|= DM_PELSHEIGHT
;
2349 dm
.dmPelsHeight
= iValue
;
2351 else if (!wcscmp(szName
, L
"VRefresh"))
2353 dm
.dmFields
|= DM_DISPLAYFREQUENCY
;
2354 dm
.dmDisplayFrequency
= iValue
;
2357 while (SetupFindNextLine(&InfContext
, &InfContext
));
2359 ChangeDisplaySettingsW(&dm
, CDS_UPDATEREGISTRY
);
2363 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
2364 L
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunOnce",
2367 &hKey
) != ERROR_SUCCESS
)
2369 DPRINT1("Error: failed to open HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\RunOnce\n");
2373 if (SetupFindFirstLineW(pSetupData
->hUnattendedInf
,
2382 if(SetupGetStringFieldW(&InfContext
,
2385 sizeof(szValue
) / sizeof(WCHAR
),
2388 WCHAR szPath
[MAX_PATH
];
2389 swprintf(szName
, L
"%d", i
);
2390 DPRINT("szName %S szValue %S\n", szName
, szValue
);
2392 if (ExpandEnvironmentStringsW(szValue
, szPath
, MAX_PATH
))
2394 DPRINT("value %S\n", szPath
);
2395 if (RegSetValueExW(hKey
,
2399 (const BYTE
*)szPath
,
2400 (wcslen(szPath
) + 1) * sizeof(WCHAR
)) == ERROR_SUCCESS
)
2406 } while(SetupFindNextLine(&InfContext
, &InfContext
));
2413 * GetRosInstallCD should find the path to ros installation medium
2415 * If there are more than one CDDrive in it containing a ReactOS
2416 * installation cd, then it will pick the first one regardless if
2417 * it is really the installation cd
2419 * The best way to implement this is to set the key
2420 * HKLM\Software\Microsoft\Windows NT\CurrentVersion\SourcePath (REG_SZ)
2424 GetRosInstallCD(WCHAR
*pwszPath
, DWORD cchPathMax
)
2426 WCHAR wszDrives
[512];
2430 cchDrives
= GetLogicalDriveStringsW(_countof(wszDrives
) - 1, wszDrives
);
2431 if (cchDrives
== 0 || cchDrives
>= _countof(wszDrives
))
2433 /* buffer too small or failure */
2434 LogItem(NULL
, L
"GetLogicalDriveStringsW failed");
2438 for (pwszDrive
= wszDrives
; pwszDrive
[0]; pwszDrive
+= wcslen(pwszDrive
) + 1)
2440 if (GetDriveTypeW(pwszDrive
) == DRIVE_CDROM
)
2442 WCHAR wszBuf
[MAX_PATH
];
2443 wsprintf(wszBuf
, L
"%sreactos\\system32\\ntoskrnl.exe", pwszDrive
);
2444 LogItem(NULL
, wszBuf
);
2445 if (GetFileAttributesW(wszBuf
) != INVALID_FILE_ATTRIBUTES
)
2447 /* the file exists, so this is the right drive */
2448 wcsncpy(pwszPath
, pwszDrive
, cchPathMax
);
2449 OutputDebugStringW(L
"GetRosInstallCD: ");OutputDebugStringW(pwszPath
);OutputDebugStringW(L
"\n");
2459 ProcessUnattendSetup(
2460 PSETUPDATA pSetupData
)
2462 WCHAR szPath
[MAX_PATH
];
2465 if (!GetRosInstallCD(szPath
, MAX_PATH
))
2467 /* no cd drive found */
2471 dwLength
= wcslen(szPath
);
2472 if (dwLength
+ 21 > MAX_PATH
)
2475 * allocate bigger buffer
2480 wcscat(szPath
, L
"reactos\\unattend.inf");
2482 pSetupData
->hUnattendedInf
= SetupOpenInfFileW(szPath
,
2486 if (pSetupData
->hUnattendedInf
!= INVALID_HANDLE_VALUE
)
2488 ProcessUnattendInf(pSetupData
);
2492 typedef DWORD(WINAPI
*PFNREQUESTWIZARDPAGES
)(PDWORD
, HPROPSHEETPAGE
*, PSETUPDATA
);
2497 PROPSHEETHEADER psh
;
2498 HPROPSHEETPAGE
*phpage
= NULL
;
2499 PROPSHEETPAGE psp
= {0};
2503 PSETUPDATA pSetupData
= NULL
;
2504 HMODULE hNetShell
= NULL
;
2505 PFNREQUESTWIZARDPAGES pfn
= NULL
;
2506 DWORD dwPageCount
= 8, dwNetworkPageCount
= 0;
2508 LogItem(L
"BEGIN_SECTION", L
"InstallWizard");
2510 /* Allocate setup data */
2511 pSetupData
= HeapAlloc(GetProcessHeap(),
2514 if (pSetupData
== NULL
)
2516 LogItem(NULL
, L
"SetupData allocation failed!");
2518 L
"Setup failed to allocate global data!",
2520 MB_ICONERROR
| MB_OK
);
2524 hNetShell
= LoadLibraryW(L
"netshell.dll");
2525 if (hNetShell
!= NULL
)
2527 DPRINT("Netshell.dll loaded!\n");
2529 pfn
= (PFNREQUESTWIZARDPAGES
)GetProcAddress(hNetShell
,
2530 "NetSetupRequestWizardPages");
2533 pfn(&dwNetworkPageCount
, NULL
, NULL
);
2534 dwPageCount
+= dwNetworkPageCount
;
2538 DPRINT("PageCount: %lu\n", dwPageCount
);
2540 phpage
= HeapAlloc(GetProcessHeap(),
2542 dwPageCount
* sizeof(HPROPSHEETPAGE
));
2545 LogItem(NULL
, L
"Page array allocation failed!");
2547 L
"Setup failed to allocate page array!",
2549 MB_ICONERROR
| MB_OK
);
2553 pSetupData
->hUnattendedInf
= INVALID_HANDLE_VALUE
;
2554 ProcessUnattendSetup(pSetupData
);
2556 /* Create the Welcome page */
2557 psp
.dwSize
= sizeof(PROPSHEETPAGE
);
2558 psp
.dwFlags
= PSP_DEFAULT
| PSP_HIDEHEADER
;
2559 psp
.hInstance
= hDllInstance
;
2560 psp
.lParam
= (LPARAM
)pSetupData
;
2561 psp
.pfnDlgProc
= WelcomeDlgProc
;
2562 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_WELCOMEPAGE
);
2563 phpage
[nPages
++] = CreatePropertySheetPage(&psp
);
2565 /* Create the Acknowledgements page */
2566 psp
.dwFlags
= PSP_DEFAULT
| PSP_USEHEADERTITLE
| PSP_USEHEADERSUBTITLE
;
2567 psp
.pszHeaderTitle
= MAKEINTRESOURCE(IDS_ACKTITLE
);
2568 psp
.pszHeaderSubTitle
= MAKEINTRESOURCE(IDS_ACKSUBTITLE
);
2569 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_ACKPAGE
);
2570 psp
.pfnDlgProc
= AckPageDlgProc
;
2571 phpage
[nPages
++] = CreatePropertySheetPage(&psp
);
2573 /* Create the Locale page */
2574 psp
.dwFlags
= PSP_DEFAULT
| PSP_USEHEADERTITLE
| PSP_USEHEADERSUBTITLE
;
2575 psp
.pszHeaderTitle
= MAKEINTRESOURCE(IDS_LOCALETITLE
);
2576 psp
.pszHeaderSubTitle
= MAKEINTRESOURCE(IDS_LOCALESUBTITLE
);
2577 psp
.pfnDlgProc
= LocalePageDlgProc
;
2578 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_LOCALEPAGE
);
2579 phpage
[nPages
++] = CreatePropertySheetPage(&psp
);
2582 /* Create the Owner page */
2583 psp
.dwFlags
= PSP_DEFAULT
| PSP_USEHEADERTITLE
| PSP_USEHEADERSUBTITLE
;
2584 psp
.pszHeaderTitle
= MAKEINTRESOURCE(IDS_OWNERTITLE
);
2585 psp
.pszHeaderSubTitle
= MAKEINTRESOURCE(IDS_OWNERSUBTITLE
);
2586 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_OWNERPAGE
);
2587 psp
.pfnDlgProc
= OwnerPageDlgProc
;
2588 phpage
[nPages
++] = CreatePropertySheetPage(&psp
);
2590 /* Create the Computer page */
2591 psp
.dwFlags
= PSP_DEFAULT
| PSP_USEHEADERTITLE
| PSP_USEHEADERSUBTITLE
;
2592 psp
.pszHeaderTitle
= MAKEINTRESOURCE(IDS_COMPUTERTITLE
);
2593 psp
.pszHeaderSubTitle
= MAKEINTRESOURCE(IDS_COMPUTERSUBTITLE
);
2594 psp
.pfnDlgProc
= ComputerPageDlgProc
;
2595 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_COMPUTERPAGE
);
2596 phpage
[nPages
++] = CreatePropertySheetPage(&psp
);
2599 /* Create the DateTime page */
2600 psp
.dwFlags
= PSP_DEFAULT
| PSP_USEHEADERTITLE
| PSP_USEHEADERSUBTITLE
;
2601 psp
.pszHeaderTitle
= MAKEINTRESOURCE(IDS_DATETIMETITLE
);
2602 psp
.pszHeaderSubTitle
= MAKEINTRESOURCE(IDS_DATETIMESUBTITLE
);
2603 psp
.pfnDlgProc
= DateTimePageDlgProc
;
2604 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_DATETIMEPAGE
);
2605 phpage
[nPages
++] = CreatePropertySheetPage(&psp
);
2607 /* Create the theme selection page */
2608 psp
.dwFlags
= PSP_DEFAULT
| PSP_USEHEADERTITLE
| PSP_USEHEADERSUBTITLE
;
2609 psp
.pszHeaderTitle
= MAKEINTRESOURCE(IDS_THEMESELECTIONTITLE
);
2610 psp
.pszHeaderSubTitle
= MAKEINTRESOURCE(IDS_THEMESELECTIONSUBTITLE
);
2611 psp
.pfnDlgProc
= ThemePageDlgProc
;
2612 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_THEMEPAGE
);
2613 phpage
[nPages
++] = CreatePropertySheetPage(&psp
);
2615 pSetupData
->uFirstNetworkWizardPage
= IDD_PROCESSPAGE
;
2616 pSetupData
->uPostNetworkWizardPage
= IDD_PROCESSPAGE
;
2620 pfn(&dwNetworkPageCount
, &phpage
[nPages
], pSetupData
);
2621 nPages
+= dwNetworkPageCount
;
2624 /* Create the Process page */
2625 psp
.dwFlags
= PSP_DEFAULT
| PSP_USEHEADERTITLE
| PSP_USEHEADERSUBTITLE
;
2626 psp
.pszHeaderTitle
= MAKEINTRESOURCE(IDS_PROCESSTITLE
);
2627 psp
.pszHeaderSubTitle
= MAKEINTRESOURCE(IDS_PROCESSSUBTITLE
);
2628 psp
.pfnDlgProc
= ProcessPageDlgProc
;
2629 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_PROCESSPAGE
);
2630 phpage
[nPages
++] = CreatePropertySheetPage(&psp
);
2633 /* Create the Finish page */
2634 psp
.dwFlags
= PSP_DEFAULT
| PSP_HIDEHEADER
;
2635 psp
.pfnDlgProc
= FinishDlgProc
;
2636 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_FINISHPAGE
);
2637 phpage
[nPages
++] = CreatePropertySheetPage(&psp
);
2639 /* Create the property sheet */
2640 psh
.dwSize
= sizeof(PROPSHEETHEADER
);
2641 psh
.dwFlags
= PSH_WIZARD97
| PSH_WATERMARK
| PSH_HEADER
| PSH_MODELESS
;
2642 psh
.hInstance
= hDllInstance
;
2643 psh
.hwndParent
= NULL
;
2644 psh
.nPages
= nPages
;
2646 psh
.phpage
= phpage
;
2647 psh
.pszbmWatermark
= MAKEINTRESOURCE(IDB_WATERMARK
);
2648 psh
.pszbmHeader
= MAKEINTRESOURCE(IDB_HEADER
);
2650 /* Create title font */
2651 pSetupData
->hTitleFont
= CreateTitleFont();
2652 pSetupData
->hBoldFont
= CreateBoldFont();
2654 /* Display the wizard */
2655 hWnd
= (HWND
)PropertySheet(&psh
);
2656 ShowWindow(hWnd
, SW_SHOW
);
2658 while (GetMessage(&msg
, NULL
, 0, 0))
2660 if (!IsDialogMessage(hWnd
, &msg
))
2662 TranslateMessage(&msg
);
2663 DispatchMessage(&msg
);
2667 if (pSetupData
->hUnattendedInf
!= INVALID_HANDLE_VALUE
)
2668 SetupCloseInfFile(pSetupData
->hUnattendedInf
);
2672 HeapFree(GetProcessHeap(), 0, phpage
);
2674 if (hNetShell
!= NULL
)
2675 FreeLibrary(hNetShell
);
2677 if (pSetupData
!= NULL
)
2679 DeleteObject(pSetupData
->hBoldFont
);
2680 DeleteObject(pSetupData
->hTitleFont
);
2681 HeapFree(GetProcessHeap(), 0, pSetupData
);
2684 LogItem(L
"END_SECTION", L
"InstallWizard");