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 GetRosInstallCD(WCHAR
* szPath
, DWORD dwPathLength
);
53 RunVMWInstall(HWND hWnd
)
55 PROCESS_INFORMATION ProcInfo
;
58 STARTUPINFOW si
= {0};
59 WCHAR InstallName
[] = L
"vmwinst.exe";
61 si
.cb
= sizeof(STARTUPINFO
);
63 if(CreateProcessW(NULL
, InstallName
, NULL
, NULL
, TRUE
, NORMAL_PRIORITY_CLASS
,
64 NULL
, NULL
, &si
, &ProcInfo
))
66 EnableWindow(hWnd
, FALSE
);
69 while (PeekMessage(&msg
, NULL
, 0, 0, PM_REMOVE
))
71 if (msg
.message
== WM_QUIT
)
73 TranslateMessage(&msg
);
74 DispatchMessage(&msg
);
77 ret
= MsgWaitForMultipleObjects(1, &ProcInfo
.hProcess
, FALSE
, INFINITE
, QS_ALLEVENTS
| QS_ALLINPUT
);
78 if (ret
== WAIT_OBJECT_0
)
82 EnableWindow(hWnd
, TRUE
);
84 CloseHandle(ProcInfo
.hThread
);
85 CloseHandle(ProcInfo
.hProcess
);
93 CenterWindow(HWND hWnd
)
99 hWndParent
= GetParent(hWnd
);
100 if (hWndParent
== NULL
)
101 hWndParent
= GetDesktopWindow();
103 GetWindowRect(hWndParent
, &rcParent
);
104 GetWindowRect(hWnd
, &rcWindow
);
108 ((rcParent
.right
- rcParent
.left
) - (rcWindow
.right
- rcWindow
.left
)) / 2,
109 ((rcParent
.bottom
- rcParent
.top
) - (rcWindow
.bottom
- rcWindow
.top
)) / 2,
117 CreateTitleFont(VOID
)
119 NONCLIENTMETRICSW ncm
;
125 ncm
.cbSize
= sizeof(NONCLIENTMETRICSW
);
126 SystemParametersInfo(SPI_GETNONCLIENTMETRICS
, 0, &ncm
, 0);
128 LogFont
= ncm
.lfMessageFont
;
129 LogFont
.lfWeight
= FW_BOLD
;
130 wcscpy(LogFont
.lfFaceName
, L
"MS Shell Dlg");
134 LogFont
.lfHeight
= 0 - GetDeviceCaps(hdc
, LOGPIXELSY
) * FontSize
/ 72;
135 hFont
= CreateFontIndirectW(&LogFont
);
136 ReleaseDC(NULL
, hdc
);
142 static INT_PTR CALLBACK
143 GplDlgProc(HWND hwndDlg
,
148 HRSRC GplTextResource
;
158 GplTextResource
= FindResourceW(hDllInstance
, MAKEINTRESOURCE(IDR_GPL
), L
"RT_TEXT");
159 if (NULL
== GplTextResource
)
163 Size
= SizeofResource(hDllInstance
, GplTextResource
);
168 GplText
= HeapAlloc(GetProcessHeap(), 0, Size
+ 1);
173 GplTextMem
= LoadResource(hDllInstance
, GplTextResource
);
174 if (NULL
== GplTextMem
)
176 HeapFree(GetProcessHeap(), 0, GplText
);
179 GplTextLocked
= LockResource(GplTextMem
);
180 if (NULL
== GplTextLocked
)
182 HeapFree(GetProcessHeap(), 0, GplText
);
185 memcpy(GplText
, GplTextLocked
, Size
);
186 GplText
[Size
] = '\0';
187 SendMessageA(GetDlgItem(hwndDlg
, IDC_GPL_TEXT
), WM_SETTEXT
, 0, (LPARAM
) GplText
);
188 HeapFree(GetProcessHeap(), 0, GplText
);
189 SetFocus(GetDlgItem(hwndDlg
, IDOK
));
193 EndDialog(hwndDlg
, IDCANCEL
);
197 if (HIWORD(wParam
) == BN_CLICKED
&& IDOK
== LOWORD(wParam
))
199 EndDialog(hwndDlg
, IDOK
);
211 static INT_PTR CALLBACK
212 WelcomeDlgProc(HWND hwndDlg
,
221 PSETUPDATA SetupData
;
225 /* Get pointer to the global setup data */
226 SetupData
= (PSETUPDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
228 hwndControl
= GetParent(hwndDlg
);
230 /* Center the wizard window */
231 CenterWindow (hwndControl
);
233 /* Hide the system menu */
234 dwStyle
= GetWindowLongPtr(hwndControl
, GWL_STYLE
);
235 SetWindowLongPtr(hwndControl
, GWL_STYLE
, dwStyle
& ~WS_SYSMENU
);
237 /* Hide and disable the 'Cancel' button */
238 hwndControl
= GetDlgItem(GetParent(hwndDlg
), IDCANCEL
);
239 ShowWindow (hwndControl
, SW_HIDE
);
240 EnableWindow (hwndControl
, FALSE
);
243 SendDlgItemMessage(hwndDlg
,
246 (WPARAM
)SetupData
->hTitleFont
,
254 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
259 /* Enable the Next button */
260 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_NEXT
);
261 if (SetupData
.UnattendSetup
)
263 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, IDD_ACKPAGE
);
269 SetupData
.UnattendSetup
= FALSE
;
286 static INT_PTR CALLBACK
287 AckPageDlgProc(HWND hwndDlg
,
294 PWCHAR End
, CurrentProject
;
295 INT ProjectsSize
, ProjectsCount
;
305 Projects
= HeapAlloc(GetProcessHeap(), 0, ProjectsSize
* sizeof(WCHAR
));
306 if (NULL
== Projects
)
310 ProjectsCount
= LoadStringW(hDllInstance
, IDS_ACKPROJECTS
, Projects
, ProjectsSize
);
311 if (0 == ProjectsCount
)
313 HeapFree(GetProcessHeap(), 0, Projects
);
316 if (ProjectsCount
< ProjectsSize
- 1)
320 HeapFree(GetProcessHeap(), 0, Projects
);
324 CurrentProject
= Projects
;
325 while (L
'\0' != *CurrentProject
)
327 End
= wcschr(CurrentProject
, L
'\n');
332 (void)ListBox_AddString(GetDlgItem(hwndDlg
, IDC_PROJECTS
), CurrentProject
);
335 CurrentProject
= End
+ 1;
339 CurrentProject
+= wcslen(CurrentProject
);
342 HeapFree(GetProcessHeap(), 0, Projects
);
347 if (HIWORD(wParam
) == BN_CLICKED
&& IDC_VIEWGPL
== LOWORD(wParam
))
349 DialogBox(hDllInstance
, MAKEINTRESOURCE(IDD_GPL
), NULL
, GplDlgProc
);
355 lpnm
= (LPNMHDR
)lParam
;
360 /* Enable the Back and Next buttons */
361 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_BACK
| PSWIZB_NEXT
);
362 if (SetupData
.UnattendSetup
)
364 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, IDD_OWNERPAGE
);
370 SetupData
.UnattendSetup
= FALSE
;
388 WriteOwnerSettings(WCHAR
* OwnerName
,
389 WCHAR
* OwnerOrganization
)
396 res
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
397 L
"Software\\Microsoft\\Windows NT\\CurrentVersion",
402 if (res
!= ERROR_SUCCESS
)
407 res
= RegSetValueExW(hKey
,
412 (wcslen(OwnerName
) + 1) * sizeof(WCHAR
));
414 if (res
!= ERROR_SUCCESS
)
420 res
= RegSetValueExW(hKey
,
421 L
"RegisteredOrganization",
424 (LPBYTE
)OwnerOrganization
,
425 (wcslen(OwnerOrganization
) + 1) * sizeof(WCHAR
));
428 return (res
== ERROR_SUCCESS
);
431 static INT_PTR CALLBACK
432 OwnerPageDlgProc(HWND hwndDlg
,
438 WCHAR OwnerOrganization
[51];
440 WCHAR ErrorName
[256];
447 SendDlgItemMessage(hwndDlg
, IDC_OWNERNAME
, EM_LIMITTEXT
, 50, 0);
448 SendDlgItemMessage(hwndDlg
, IDC_OWNERORGANIZATION
, EM_LIMITTEXT
, 50, 0);
450 /* Set focus to owner name */
451 SetFocus(GetDlgItem(hwndDlg
, IDC_OWNERNAME
));
458 lpnm
= (LPNMHDR
)lParam
;
463 /* Enable the Back and Next buttons */
464 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_BACK
| PSWIZB_NEXT
);
465 if (SetupData
.UnattendSetup
)
467 SendMessage(GetDlgItem(hwndDlg
, IDC_OWNERNAME
), WM_SETTEXT
, 0, (LPARAM
)SetupData
.OwnerName
);
468 SendMessage(GetDlgItem(hwndDlg
, IDC_OWNERORGANIZATION
), WM_SETTEXT
, 0, (LPARAM
)SetupData
.OwnerOrganization
);
469 if (WriteOwnerSettings(SetupData
.OwnerName
, SetupData
.OwnerOrganization
))
471 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, IDD_COMPUTERPAGE
);
479 if (GetDlgItemTextW(hwndDlg
, IDC_OWNERNAME
, OwnerName
, 50) == 0)
481 if (0 == LoadStringW(hDllInstance
, IDS_REACTOS_SETUP
, Title
, sizeof(Title
) / sizeof(Title
[0])))
483 wcscpy(Title
, L
"ReactOS Setup");
485 if (0 == LoadStringW(hDllInstance
, IDS_WZD_NAME
, ErrorName
, sizeof(ErrorName
) / sizeof(ErrorName
[0])))
487 wcscpy(ErrorName
, L
"Setup cannot continue until you enter your name.");
489 MessageBoxW(hwndDlg
, ErrorName
, Title
, MB_ICONERROR
| MB_OK
);
491 SetFocus(GetDlgItem(hwndDlg
, IDC_OWNERNAME
));
492 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, -1);
497 OwnerOrganization
[0] = 0;
498 GetDlgItemTextW(hwndDlg
, IDC_OWNERORGANIZATION
, OwnerOrganization
, 50);
500 if (!WriteOwnerSettings(OwnerName
, OwnerOrganization
))
502 SetFocus(GetDlgItem(hwndDlg
, IDC_OWNERNAME
));
503 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, -1);
508 SetupData
.UnattendSetup
= FALSE
;
526 SetAccountDomain(LPWSTR DomainName
)
528 POLICY_ACCOUNT_DOMAIN_INFO Info
;
529 LSA_OBJECT_ATTRIBUTES ObjectAttributes
;
530 LSA_HANDLE PolicyHandle
;
533 memset(&ObjectAttributes
, 0, sizeof(LSA_OBJECT_ATTRIBUTES
));
534 ObjectAttributes
.Length
= sizeof(LSA_OBJECT_ATTRIBUTES
);
536 Status
= LsaOpenPolicy(NULL
,
540 if (Status
!= STATUS_SUCCESS
)
542 DPRINT("LsaOpenPolicy failed (Status: 0x%08lx)\n", Status
);
546 Info
.DomainName
.Buffer
= DomainName
;
547 Info
.DomainName
.Length
= wcslen(DomainName
) * sizeof(WCHAR
);
548 Info
.DomainName
.MaximumLength
= Info
.DomainName
.Length
+ sizeof(WCHAR
);
549 Info
.DomainSid
= NULL
;
551 Status
= LsaSetInformationPolicy(PolicyHandle
,
552 PolicyAccountDomainInformation
,
554 if (Status
!= STATUS_SUCCESS
)
556 DPRINT("LsaSetInformationPolicy failed (Status: 0x%08lx)\n", Status
);
559 LsaClose(PolicyHandle
);
566 WriteComputerSettings(WCHAR
* ComputerName
, HWND hwndDlg
)
569 WCHAR ErrorComputerName
[256];
570 if (!SetComputerNameW(ComputerName
))
572 if (0 == LoadStringW(hDllInstance
, IDS_REACTOS_SETUP
, Title
, sizeof(Title
) / sizeof(Title
[0])))
574 wcscpy(Title
, L
"ReactOS Setup");
576 if (0 == LoadStringW(hDllInstance
, IDS_WZD_SETCOMPUTERNAME
, ErrorComputerName
,
577 sizeof(ErrorComputerName
) / sizeof(ErrorComputerName
[0])))
579 wcscpy(ErrorComputerName
, L
"Setup failed to set the computer name.");
581 MessageBoxW(hwndDlg
, ErrorComputerName
, Title
, MB_ICONERROR
| MB_OK
);
586 /* Try to also set DNS hostname */
587 SetComputerNameExW(ComputerNamePhysicalDnsHostname
, ComputerName
);
589 /* Set the account domain name */
590 SetAccountDomain(ComputerName
);
595 /* lpBuffer will be filled with a 15-char string (plus the null terminator) */
597 GenerateComputerName(LPWSTR lpBuffer
)
599 static const WCHAR Chars
[] = L
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
600 static const unsigned cChars
= sizeof(Chars
) / sizeof(WCHAR
) - 1;
603 wcscpy(lpBuffer
, L
"REACTOS-");
605 srand(GetTickCount());
607 /* fill in 7 characters */
608 for (i
= 8; i
< 15; i
++)
609 lpBuffer
[i
] = Chars
[rand() % cChars
];
611 lpBuffer
[15] = UNICODE_NULL
; /* NULL-terminate */
614 static INT_PTR CALLBACK
615 ComputerPageDlgProc(HWND hwndDlg
,
620 WCHAR ComputerName
[MAX_COMPUTERNAME_LENGTH
+ 1];
625 WCHAR EmptyComputerName
[256], NotMatchPassword
[256], WrongPassword
[256];
628 if (0 == LoadStringW(hDllInstance
, IDS_REACTOS_SETUP
, Title
, sizeof(Title
) / sizeof(Title
[0])))
630 wcscpy(Title
, L
"ReactOS Setup");
637 /* Generate a new pseudo-random computer name */
638 GenerateComputerName(ComputerName
);
640 /* Display current computer name */
641 SetDlgItemTextW(hwndDlg
, IDC_COMPUTERNAME
, ComputerName
);
643 /* Set text limits */
644 SendDlgItemMessage(hwndDlg
, IDC_COMPUTERNAME
, EM_LIMITTEXT
, MAX_COMPUTERNAME_LENGTH
, 0);
645 SendDlgItemMessage(hwndDlg
, IDC_ADMINPASSWORD1
, EM_LIMITTEXT
, 14, 0);
646 SendDlgItemMessage(hwndDlg
, IDC_ADMINPASSWORD2
, EM_LIMITTEXT
, 14, 0);
648 /* Set focus to computer name */
649 SetFocus(GetDlgItem(hwndDlg
, IDC_COMPUTERNAME
));
650 if (SetupData
.UnattendSetup
)
652 SendMessage(GetDlgItem(hwndDlg
, IDC_COMPUTERNAME
), WM_SETTEXT
, 0, (LPARAM
)SetupData
.ComputerName
);
653 SendMessage(GetDlgItem(hwndDlg
, IDC_ADMINPASSWORD1
), WM_SETTEXT
, 0, (LPARAM
)SetupData
.AdminPassword
);
654 SendMessage(GetDlgItem(hwndDlg
, IDC_ADMINPASSWORD2
), WM_SETTEXT
, 0, (LPARAM
)SetupData
.AdminPassword
);
663 lpnm
= (LPNMHDR
)lParam
;
668 /* Enable the Back and Next buttons */
669 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_BACK
| PSWIZB_NEXT
);
670 if (SetupData
.UnattendSetup
&& WriteComputerSettings(SetupData
.ComputerName
, hwndDlg
))
672 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, IDD_LOCALEPAGE
);
678 if (0 == GetDlgItemTextW(hwndDlg
, IDC_COMPUTERNAME
, ComputerName
, MAX_COMPUTERNAME_LENGTH
+ 1))
680 if (0 == LoadStringW(hDllInstance
, IDS_WZD_COMPUTERNAME
, EmptyComputerName
,
681 sizeof(EmptyComputerName
) / sizeof(EmptyComputerName
[0])))
683 wcscpy(EmptyComputerName
, L
"Setup cannot continue until you enter the name of your computer.");
685 MessageBoxW(hwndDlg
, EmptyComputerName
, Title
, MB_ICONERROR
| MB_OK
);
686 SetFocus(GetDlgItem(hwndDlg
, IDC_COMPUTERNAME
));
687 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, -1);
691 /* No need to check computer name for invalid characters,
692 * SetComputerName() will do it for us */
694 if (!WriteComputerSettings(ComputerName
, hwndDlg
))
696 SetFocus(GetDlgItem(hwndDlg
, IDC_COMPUTERNAME
));
697 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, -1);
702 /* Check if admin passwords have been entered */
703 if ((GetDlgItemText(hwndDlg
, IDC_ADMINPASSWORD1
, Password1
, 15) == 0) ||
704 (GetDlgItemText(hwndDlg
, IDC_ADMINPASSWORD2
, Password2
, 15) == 0))
706 if (0 == LoadStringW(hDllInstance
, IDS_WZD_PASSWORDEMPTY
, EmptyPassword
,
707 sizeof(EmptyPassword
) / sizeof(EmptyPassword
[0])))
709 wcscpy(EmptyPassword
, L
"You must enter a password !");
711 MessageBoxW(hwndDlg
, EmptyPassword
, Title
, MB_ICONERROR
| MB_OK
);
712 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, -1);
716 GetDlgItemTextW(hwndDlg
, IDC_ADMINPASSWORD1
, Password1
, 15);
717 GetDlgItemTextW(hwndDlg
, IDC_ADMINPASSWORD2
, Password2
, 15);
719 /* Check if passwords match */
720 if (wcscmp(Password1
, Password2
))
722 if (0 == LoadStringW(hDllInstance
, IDS_WZD_PASSWORDMATCH
, NotMatchPassword
,
723 sizeof(NotMatchPassword
) / sizeof(NotMatchPassword
[0])))
725 wcscpy(NotMatchPassword
, L
"The passwords you entered do not match. Please enter the desired password again.");
727 MessageBoxW(hwndDlg
, NotMatchPassword
, Title
, MB_ICONERROR
| MB_OK
);
728 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, -1);
732 /* Check password for invalid characters */
733 Password
= (PWCHAR
)Password1
;
736 if (!isprint(*Password
))
738 if (0 == LoadStringW(hDllInstance
, IDS_WZD_PASSWORDCHAR
, WrongPassword
,
739 sizeof(WrongPassword
) / sizeof(WrongPassword
[0])))
741 wcscpy(WrongPassword
, L
"The password you entered contains invalid characters. Please enter a cleaned password.");
743 MessageBoxW(hwndDlg
, WrongPassword
, Title
, MB_ICONERROR
| MB_OK
);
744 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, -1);
750 /* FIXME: Set admin password */
754 SetupData
.UnattendSetup
= FALSE
;
772 SetKeyboardLayoutName(HWND hwnd
)
775 TCHAR szLayoutPath
[256];
776 TCHAR szLocaleName
[32];
780 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE
,
781 _T("SYSTEM\\CurrentControlSet\\Control\\NLS\\Locale"),
787 dwValueSize
= 16 * sizeof(TCHAR
);
788 if (RegQueryValueEx(hKey
,
799 _tcscpy(szLayoutPath
,
800 _T("SYSTEM\\CurrentControlSet\\Control\\Keyboard Layouts\\"));
801 _tcscat(szLayoutPath
,
804 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE
,
811 dwValueSize
= 32 * sizeof(TCHAR
);
812 if (RegQueryValueEx(hKey
,
829 RunControlPanelApplet(HWND hwnd
, WCHAR
*lpCommandLine
)
831 STARTUPINFOW StartupInfo
;
832 PROCESS_INFORMATION ProcessInformation
;
834 ZeroMemory(&StartupInfo
, sizeof(STARTUPINFOW
));
835 StartupInfo
.cb
= sizeof(STARTUPINFOW
);
837 if (!CreateProcessW(NULL
,
846 &ProcessInformation
))
848 MessageBoxW(hwnd
, L
"Error: failed to launch rundll32", NULL
, MB_ICONERROR
);
852 WaitForSingleObject(ProcessInformation
.hProcess
, INFINITE
);
853 CloseHandle(ProcessInformation
.hThread
);
854 CloseHandle(ProcessInformation
.hProcess
);
859 WriteUserLocale(VOID
)
865 lcid
= GetSystemDefaultLCID();
867 if (GetLocaleInfoW(MAKELCID(lcid
, SORT_DEFAULT
), LOCALE_ILANGUAGE
, Locale
, sizeof(Locale
) / sizeof(Locale
[0])) != 0)
869 if (RegCreateKeyExW(HKEY_CURRENT_USER
, L
"Control Panel\\International",
870 0, NULL
, REG_OPTION_NON_VOLATILE
,
871 KEY_WRITE
, NULL
, &hKey
, NULL
) == ERROR_SUCCESS
)
873 RegSetValueExW(hKey
, L
"Locale", 0, REG_SZ
, (LPBYTE
)Locale
, (wcslen(Locale
) + 1) * sizeof(WCHAR
));
879 static INT_PTR CALLBACK
880 LocalePageDlgProc(HWND hwndDlg
,
885 PSETUPDATA SetupData
;
886 WCHAR szBuffer
[1024];
888 /* Retrieve pointer to the global setup data */
889 SetupData
= (PSETUPDATA
)GetWindowLongPtr (hwndDlg
, GWL_USERDATA
);
895 /* Save pointer to the global setup data */
896 SetupData
= (PSETUPDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
897 SetWindowLongPtr(hwndDlg
, GWL_USERDATA
, (DWORD_PTR
)SetupData
);
900 SetKeyboardLayoutName(GetDlgItem(hwndDlg
, IDC_LAYOUTTEXT
));
905 if (HIWORD(wParam
) == BN_CLICKED
)
907 switch (LOWORD(wParam
))
909 case IDC_CUSTOMLOCALE
:
911 wcscpy(szBuffer
, L
"rundll32.exe shell32.dll,Control_RunDLL intl.cpl,,5");
912 RunControlPanelApplet(hwndDlg
, szBuffer
);
913 /* FIXME: Update input locale name */
917 case IDC_CUSTOMLAYOUT
:
919 wcscpy(szBuffer
, L
"rundll32.exe shell32.dll,Control_RunDLL input.dll,@1");
920 RunControlPanelApplet(hwndDlg
, szBuffer
);
929 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
934 /* Enable the Back and Next buttons */
935 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_BACK
| PSWIZB_NEXT
);
936 if (SetupData
->UnattendSetup
)
938 WCHAR szPath
[MAX_PATH
];
939 if (GetRosInstallCD(szPath
, MAX_PATH
))
941 swprintf(szBuffer
, L
"rundll32.exe shell32.dll,Control_RunDLL intl.cpl,,/f:\"%S\\reactos\\unattend.inf\"", szPath
);
945 wcscpy(szBuffer
, L
"rundll32.exe shell32.dll,Control_RunDLL intl.cpl,,/f:\"unattend.inf\"");
948 RunControlPanelApplet(hwndDlg
, szBuffer
);
949 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, IDD_DATETIMEPAGE
);
958 SetupData
->UnattendSetup
= FALSE
;
975 static PTIMEZONE_ENTRY
976 GetLargerTimeZoneEntry(PSETUPDATA SetupData
, DWORD Index
)
978 PTIMEZONE_ENTRY Entry
;
980 Entry
= SetupData
->TimeZoneListHead
;
981 while (Entry
!= NULL
)
983 if (Entry
->Index
>= Index
)
994 CreateTimeZoneList(PSETUPDATA SetupData
)
996 WCHAR szKeyName
[256];
1004 PTIMEZONE_ENTRY Entry
;
1005 PTIMEZONE_ENTRY Current
;
1007 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
1008 L
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones",
1017 dwNameSize
= 256 * sizeof(WCHAR
);
1018 lError
= RegEnumKeyExW(hZonesKey
,
1026 if (lError
!= ERROR_SUCCESS
&& lError
!= ERROR_MORE_DATA
)
1029 if (RegOpenKeyExW(hZonesKey
,
1036 Entry
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(TIMEZONE_ENTRY
));
1039 RegCloseKey(hZoneKey
);
1043 dwValueSize
= 64 * sizeof(WCHAR
);
1044 if (RegQueryValueExW(hZoneKey
,
1048 (LPBYTE
)&Entry
->Description
,
1051 RegCloseKey(hZoneKey
);
1055 dwValueSize
= 32 * sizeof(WCHAR
);
1056 if (RegQueryValueExW(hZoneKey
,
1060 (LPBYTE
)&Entry
->StandardName
,
1063 RegCloseKey(hZoneKey
);
1067 dwValueSize
= 32 * sizeof(WCHAR
);
1068 if (RegQueryValueExW(hZoneKey
,
1072 (LPBYTE
)&Entry
->DaylightName
,
1075 RegCloseKey(hZoneKey
);
1079 dwValueSize
= sizeof(DWORD
);
1080 if (RegQueryValueExW(hZoneKey
,
1084 (LPBYTE
)&Entry
->Index
,
1087 RegCloseKey(hZoneKey
);
1091 dwValueSize
= sizeof(TZ_INFO
);
1092 if (RegQueryValueExW(hZoneKey
,
1096 (LPBYTE
)&Entry
->TimezoneInfo
,
1099 RegCloseKey(hZoneKey
);
1103 RegCloseKey(hZoneKey
);
1105 if (SetupData
->TimeZoneListHead
== NULL
&&
1106 SetupData
->TimeZoneListTail
== NULL
)
1110 SetupData
->TimeZoneListHead
= Entry
;
1111 SetupData
->TimeZoneListTail
= Entry
;
1115 Current
= GetLargerTimeZoneEntry(SetupData
, Entry
->Index
);
1116 if (Current
!= NULL
)
1118 if (Current
== SetupData
->TimeZoneListHead
)
1120 /* Prepend to head */
1122 Entry
->Next
= SetupData
->TimeZoneListHead
;
1123 SetupData
->TimeZoneListHead
->Prev
= Entry
;
1124 SetupData
->TimeZoneListHead
= Entry
;
1128 /* Insert before current */
1129 Entry
->Prev
= Current
->Prev
;
1130 Entry
->Next
= Current
;
1131 Current
->Prev
->Next
= Entry
;
1132 Current
->Prev
= Entry
;
1137 /* Append to tail */
1138 Entry
->Prev
= SetupData
->TimeZoneListTail
;
1140 SetupData
->TimeZoneListTail
->Next
= Entry
;
1141 SetupData
->TimeZoneListTail
= Entry
;
1148 RegCloseKey(hZonesKey
);
1153 DestroyTimeZoneList(PSETUPDATA SetupData
)
1155 PTIMEZONE_ENTRY Entry
;
1157 while (SetupData
->TimeZoneListHead
!= NULL
)
1159 Entry
= SetupData
->TimeZoneListHead
;
1161 SetupData
->TimeZoneListHead
= Entry
->Next
;
1162 if (SetupData
->TimeZoneListHead
!= NULL
)
1164 SetupData
->TimeZoneListHead
->Prev
= NULL
;
1167 HeapFree(GetProcessHeap(), 0, Entry
);
1170 SetupData
->TimeZoneListTail
= NULL
;
1174 GetTimeZoneListIndex(LPDWORD lpIndex
)
1176 WCHAR szLanguageIdString
[9];
1183 BOOL bFound
= FALSE
;
1184 unsigned long iLanguageID
;
1186 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
1187 L
"SYSTEM\\CurrentControlSet\\Control\\NLS\\Language",
1193 dwValueSize
= 9 * sizeof(WCHAR
);
1194 if (RegQueryValueExW(hKey
,
1198 (LPBYTE
)szLanguageIdString
,
1205 iLanguageID
= wcstoul(szLanguageIdString
, NULL
, 16);
1208 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
1209 L
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones",
1216 if (RegQueryValueExW(hKey
,
1227 Buffer
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, dwValueSize
);
1234 if (RegQueryValueExW(hKey
,
1241 HeapFree(GetProcessHeap(), 0, Buffer
);
1251 Length
= wcslen(Ptr
);
1252 if (wcstoul(Ptr
, NULL
, 16) == iLanguageID
)
1255 Ptr
= Ptr
+ Length
+ 1;
1261 *lpIndex
= wcstoul(Ptr
, &End
, 10);
1262 HeapFree(GetProcessHeap(), 0, Buffer
);
1266 Length
= wcslen(Ptr
);
1267 Ptr
= Ptr
+ Length
+ 1;
1270 HeapFree(GetProcessHeap(), 0, Buffer
);
1277 ShowTimeZoneList(HWND hwnd
, PSETUPDATA SetupData
, DWORD dwEntryIndex
)
1279 PTIMEZONE_ENTRY Entry
;
1283 GetTimeZoneListIndex(&dwEntryIndex
);
1285 Entry
= SetupData
->TimeZoneListHead
;
1286 while (Entry
!= NULL
)
1288 dwCount
= SendMessage(hwnd
,
1291 (LPARAM
)Entry
->Description
);
1293 if (dwEntryIndex
!= 0 && dwEntryIndex
== Entry
->Index
)
1296 Entry
= Entry
->Next
;
1307 SetLocalTimeZone(HWND hwnd
, PSETUPDATA SetupData
)
1309 TIME_ZONE_INFORMATION TimeZoneInformation
;
1310 PTIMEZONE_ENTRY Entry
;
1314 dwIndex
= SendMessage(hwnd
,
1320 Entry
= SetupData
->TimeZoneListHead
;
1327 Entry
= Entry
->Next
;
1330 wcscpy(TimeZoneInformation
.StandardName
,
1331 Entry
->StandardName
);
1332 wcscpy(TimeZoneInformation
.DaylightName
,
1333 Entry
->DaylightName
);
1335 TimeZoneInformation
.Bias
= Entry
->TimezoneInfo
.Bias
;
1336 TimeZoneInformation
.StandardBias
= Entry
->TimezoneInfo
.StandardBias
;
1337 TimeZoneInformation
.DaylightBias
= Entry
->TimezoneInfo
.DaylightBias
;
1339 memcpy(&TimeZoneInformation
.StandardDate
,
1340 &Entry
->TimezoneInfo
.StandardDate
,
1341 sizeof(SYSTEMTIME
));
1342 memcpy(&TimeZoneInformation
.DaylightDate
,
1343 &Entry
->TimezoneInfo
.DaylightDate
,
1344 sizeof(SYSTEMTIME
));
1346 /* Set time zone information */
1347 SetTimeZoneInformation(&TimeZoneInformation
);
1352 GetLocalSystemTime(HWND hwnd
, PSETUPDATA SetupData
)
1357 if (DateTime_GetSystemtime(GetDlgItem(hwnd
, IDC_DATEPICKER
), &Date
) != GDT_VALID
)
1362 if (DateTime_GetSystemtime(GetDlgItem(hwnd
, IDC_TIMEPICKER
), &Time
) != GDT_VALID
)
1367 SetupData
->SystemTime
.wYear
= Date
.wYear
;
1368 SetupData
->SystemTime
.wMonth
= Date
.wMonth
;
1369 SetupData
->SystemTime
.wDayOfWeek
= Date
.wDayOfWeek
;
1370 SetupData
->SystemTime
.wDay
= Date
.wDay
;
1371 SetupData
->SystemTime
.wHour
= Time
.wHour
;
1372 SetupData
->SystemTime
.wMinute
= Time
.wMinute
;
1373 SetupData
->SystemTime
.wSecond
= Time
.wSecond
;
1374 SetupData
->SystemTime
.wMilliseconds
= Time
.wMilliseconds
;
1381 SetAutoDaylightInfo(HWND hwnd
)
1386 if (SendMessage(hwnd
, BM_GETCHECK
, 0, 0) == BST_UNCHECKED
)
1388 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
1389 L
"SYSTEM\\CurrentControlSet\\Control\\TimeZoneInformation",
1395 RegSetValueExW(hKey
,
1396 L
"DisableAutoDaylightTimeSet",
1407 SetSystemLocalTime(HWND hwnd
, PSETUPDATA SetupData
)
1411 TOKEN_PRIVILEGES priv
, previouspriv
;
1415 * enable the SeSystemtimePrivilege privilege
1418 if(OpenProcessToken(GetCurrentProcess(),
1419 TOKEN_ADJUST_PRIVILEGES
| TOKEN_QUERY
,
1422 priv
.PrivilegeCount
= 1;
1423 priv
.Privileges
[0].Attributes
= SE_PRIVILEGE_ENABLED
;
1425 if(LookupPrivilegeValue(NULL
,
1427 &priv
.Privileges
[0].Luid
))
1429 if(AdjustTokenPrivileges(hToken
,
1432 sizeof(previouspriv
),
1435 GetLastError() == ERROR_SUCCESS
)
1438 * We successfully enabled it, we're permitted to change the system time
1439 * Call SetLocalTime twice to ensure correct results
1441 Ret
= SetLocalTime(&SetupData
->SystemTime
) &&
1442 SetLocalTime(&SetupData
->SystemTime
);
1445 * for the sake of security, restore the previous status again
1447 if(previouspriv
.PrivilegeCount
> 0)
1449 AdjustTokenPrivileges(hToken
,
1458 CloseHandle(hToken
);
1465 WriteDateTimeSettings(HWND hwndDlg
, PSETUPDATA SetupData
)
1468 WCHAR ErrorLocalTime
[256];
1469 GetLocalSystemTime(hwndDlg
, SetupData
);
1470 SetLocalTimeZone(GetDlgItem(hwndDlg
, IDC_TIMEZONELIST
),
1473 SetAutoDaylightInfo(GetDlgItem(hwndDlg
, IDC_AUTODAYLIGHT
));
1474 if(!SetSystemLocalTime(hwndDlg
, SetupData
))
1476 if (0 == LoadStringW(hDllInstance
, IDS_REACTOS_SETUP
, Title
, sizeof(Title
) / sizeof(Title
[0])))
1478 wcscpy(Title
, L
"ReactOS Setup");
1480 if (0 == LoadStringW(hDllInstance
, IDS_WZD_LOCALTIME
, ErrorLocalTime
,
1481 sizeof(ErrorLocalTime
) / sizeof(ErrorLocalTime
[0])))
1483 wcscpy(ErrorLocalTime
, L
"Setup was unable to set the local time.");
1485 MessageBoxW(hwndDlg
, ErrorLocalTime
, Title
, MB_ICONWARNING
| MB_OK
);
1492 static INT_PTR CALLBACK
1493 DateTimePageDlgProc(HWND hwndDlg
,
1498 PSETUPDATA SetupData
;
1500 /* Retrieve pointer to the global setup data */
1501 SetupData
= (PSETUPDATA
)GetWindowLongPtr (hwndDlg
, GWL_USERDATA
);
1507 /* Save pointer to the global setup data */
1508 SetupData
= (PSETUPDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
1509 SetWindowLongPtr(hwndDlg
, GWL_USERDATA
, (DWORD_PTR
)SetupData
);
1511 CreateTimeZoneList(SetupData
);
1513 if (SetupData
->UnattendSetup
)
1515 ShowTimeZoneList(GetDlgItem(hwndDlg
, IDC_TIMEZONELIST
),
1516 SetupData
, SetupData
->TimeZoneIndex
);
1518 if (!SetupData
->DisableAutoDaylightTimeSet
)
1520 SendDlgItemMessage(hwndDlg
, IDC_AUTODAYLIGHT
, BM_SETCHECK
, (WPARAM
)BST_CHECKED
, 0);
1525 ShowTimeZoneList(GetDlgItem(hwndDlg
, IDC_TIMEZONELIST
),
1526 SetupData
, 85 /* GMT time zone */);
1528 SendDlgItemMessage(hwndDlg
, IDC_AUTODAYLIGHT
, BM_SETCHECK
, (WPARAM
)BST_CHECKED
, 0);
1537 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
1542 /* Enable the Back and Next buttons */
1543 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_BACK
| PSWIZB_NEXT
);
1544 if (SetupData
->UnattendSetup
&& WriteDateTimeSettings(hwndDlg
, SetupData
))
1546 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, IDD_PROCESSPAGE
);
1553 WriteDateTimeSettings(hwndDlg
, SetupData
);
1558 SetupData
->UnattendSetup
= FALSE
;
1568 DestroyTimeZoneList(SetupData
);
1579 static UINT CALLBACK
1580 RegistrationNotificationProc(PVOID Context
,
1585 PREGISTRATIONDATA RegistrationData
;
1586 REGISTRATIONNOTIFY RegistrationNotify
;
1587 PSP_REGISTER_CONTROL_STATUSW StatusInfo
;
1589 WCHAR ErrorMessage
[128];
1591 RegistrationData
= (PREGISTRATIONDATA
) Context
;
1593 if (SPFILENOTIFY_STARTREGISTRATION
== Notification
||
1594 SPFILENOTIFY_ENDREGISTRATION
== Notification
)
1596 StatusInfo
= (PSP_REGISTER_CONTROL_STATUSW
) Param1
;
1597 RegistrationNotify
.CurrentItem
= wcsrchr(StatusInfo
->FileName
, L
'\\');
1598 if (NULL
== RegistrationNotify
.CurrentItem
)
1600 RegistrationNotify
.CurrentItem
= StatusInfo
->FileName
;
1604 RegistrationNotify
.CurrentItem
++;
1607 if (SPFILENOTIFY_STARTREGISTRATION
== Notification
)
1609 DPRINT("Received SPFILENOTIFY_STARTREGISTRATION notification for %S\n",
1610 StatusInfo
->FileName
);
1611 RegistrationNotify
.ErrorMessage
= NULL
;
1612 RegistrationNotify
.Progress
= RegistrationData
->Registered
;
1616 DPRINT("Received SPFILENOTIFY_ENDREGISTRATION notification for %S\n",
1617 StatusInfo
->FileName
);
1618 DPRINT("Win32Error %u FailureCode %u\n", StatusInfo
->Win32Error
,
1619 StatusInfo
->FailureCode
);
1620 if (SPREG_SUCCESS
!= StatusInfo
->FailureCode
)
1622 switch(StatusInfo
->FailureCode
)
1624 case SPREG_LOADLIBRARY
:
1625 MessageID
= IDS_LOADLIBRARY_FAILED
;
1627 case SPREG_GETPROCADDR
:
1628 MessageID
= IDS_GETPROCADDR_FAILED
;
1631 MessageID
= IDS_REGSVR_FAILED
;
1633 case SPREG_DLLINSTALL
:
1634 MessageID
= IDS_DLLINSTALL_FAILED
;
1637 MessageID
= IDS_TIMEOUT
;
1640 MessageID
= IDS_REASON_UNKNOWN
;
1643 if (0 == LoadStringW(hDllInstance
, MessageID
,
1645 sizeof(ErrorMessage
) /
1646 sizeof(ErrorMessage
[0])))
1648 ErrorMessage
[0] = L
'\0';
1650 if (SPREG_TIMEOUT
!= StatusInfo
->FailureCode
)
1652 FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM
, NULL
,
1653 StatusInfo
->Win32Error
, 0,
1654 ErrorMessage
+ wcslen(ErrorMessage
),
1655 sizeof(ErrorMessage
) / sizeof(ErrorMessage
[0]) -
1656 wcslen(ErrorMessage
), NULL
);
1658 RegistrationNotify
.ErrorMessage
= ErrorMessage
;
1662 RegistrationNotify
.ErrorMessage
= NULL
;
1664 if (RegistrationData
->Registered
< RegistrationData
->DllCount
)
1666 RegistrationData
->Registered
++;
1670 RegistrationNotify
.Progress
= RegistrationData
->Registered
;
1671 RegistrationNotify
.ActivityID
= IDS_REGISTERING_COMPONENTS
;
1672 SendMessage(RegistrationData
->hwndDlg
, PM_REGISTRATION_NOTIFY
,
1673 0, (LPARAM
) &RegistrationNotify
);
1679 DPRINT1("Received unexpected notification %u\n", Notification
);
1680 return SetupDefaultQueueCallback(RegistrationData
->DefaultContext
,
1681 Notification
, Param1
, Param2
);
1686 static DWORD CALLBACK
1687 RegistrationProc(LPVOID Parameter
)
1689 PREGISTRATIONDATA RegistrationData
;
1690 REGISTRATIONNOTIFY RegistrationNotify
;
1691 DWORD LastError
= NO_ERROR
;
1692 WCHAR UnknownError
[84];
1694 RegistrationData
= (PREGISTRATIONDATA
) Parameter
;
1695 RegistrationData
->Registered
= 0;
1696 RegistrationData
->DefaultContext
= SetupInitDefaultQueueCallback(RegistrationData
->hwndDlg
);
1700 if (!SetupInstallFromInfSectionW(GetParent(RegistrationData
->hwndDlg
),
1702 L
"RegistrationPhase2",
1704 SPINST_REGISTERCALLBACKAWARE
|
1709 RegistrationNotificationProc
,
1714 LastError
= GetLastError();
1717 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1719 DPRINT("Catching exception\n");
1720 LastError
= RtlNtStatusToDosError(_SEH2_GetExceptionCode());
1724 if (NO_ERROR
== LastError
)
1726 RegistrationNotify
.ErrorMessage
= NULL
;
1730 DPRINT1("SetupInstallFromInfSection failed with error %u\n",
1732 if (0 == FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER
|
1733 FORMAT_MESSAGE_FROM_SYSTEM
, NULL
, LastError
, 0,
1734 (LPWSTR
) &RegistrationNotify
.ErrorMessage
, 0,
1737 if (0 == LoadStringW(hDllInstance
, IDS_UNKNOWN_ERROR
,
1739 sizeof(UnknownError
) / sizeof(UnknownError
[0]) -
1742 wcscpy(UnknownError
, L
"Unknown error");
1744 wcscat(UnknownError
, L
" ");
1745 _ultow(LastError
, UnknownError
+ wcslen(UnknownError
), 10);
1746 RegistrationNotify
.ErrorMessage
= UnknownError
;
1750 RegistrationNotify
.Progress
= RegistrationData
->DllCount
;
1751 RegistrationNotify
.ActivityID
= IDS_REGISTERING_COMPONENTS
;
1752 RegistrationNotify
.CurrentItem
= NULL
;
1753 SendMessage(RegistrationData
->hwndDlg
, PM_REGISTRATION_NOTIFY
,
1754 1, (LPARAM
) &RegistrationNotify
);
1755 if (NULL
!= RegistrationNotify
.ErrorMessage
&&
1756 UnknownError
!= RegistrationNotify
.ErrorMessage
)
1758 LocalFree((PVOID
) RegistrationNotify
.ErrorMessage
);
1761 SetupTermDefaultQueueCallback(RegistrationData
->DefaultContext
);
1762 HeapFree(GetProcessHeap(), 0, RegistrationData
);
1769 StartComponentRegistration(HWND hwndDlg
, PULONG MaxProgress
)
1771 HANDLE RegistrationThread
;
1774 WCHAR SectionName
[512];
1775 PREGISTRATIONDATA RegistrationData
;
1778 if (! SetupFindFirstLineW(hSysSetupInf
, L
"RegistrationPhase2",
1779 L
"RegisterDlls", &Context
))
1781 DPRINT1("No RegistrationPhase2 section found\n");
1784 if (! SetupGetStringFieldW(&Context
, 1, SectionName
,
1785 sizeof(SectionName
) / sizeof(SectionName
[0]),
1788 DPRINT1("Unable to retrieve section name\n");
1791 DllCount
= SetupGetLineCountW(hSysSetupInf
, SectionName
);
1792 DPRINT("SectionName %S DllCount %ld\n", SectionName
, DllCount
);
1795 SetLastError(STATUS_NOT_FOUND
);
1799 *MaxProgress
= (ULONG
) DllCount
;
1802 * Create a background thread to do the actual registrations, so the
1803 * main thread can just run its message loop.
1805 RegistrationThread
= NULL
;
1806 RegistrationData
= HeapAlloc(GetProcessHeap(), 0,
1807 sizeof(REGISTRATIONDATA
));
1808 if (RegistrationData
!= NULL
)
1810 RegistrationData
->hwndDlg
= hwndDlg
;
1811 RegistrationData
->DllCount
= DllCount
;
1812 RegistrationThread
= CreateThread(NULL
, 0, RegistrationProc
,
1813 (LPVOID
) RegistrationData
, 0, NULL
);
1814 if (RegistrationThread
!= NULL
)
1816 CloseHandle(RegistrationThread
);
1820 DPRINT1("CreateThread failed, error %u\n", GetLastError());
1821 HeapFree(GetProcessHeap(), 0, RegistrationData
);
1827 DPRINT1("HeapAlloc() failed, error %u\n", GetLastError());
1835 static INT_PTR CALLBACK
1836 ProcessPageDlgProc(HWND hwndDlg
,
1841 PSETUPDATA SetupData
;
1842 PREGISTRATIONNOTIFY RegistrationNotify
;
1843 static UINT oldActivityID
= -1;
1846 /* Retrieve pointer to the global setup data */
1847 SetupData
= (PSETUPDATA
)GetWindowLongPtr (hwndDlg
, GWL_USERDATA
);
1853 /* Save pointer to the global setup data */
1854 SetupData
= (PSETUPDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
1855 SetWindowLongPtr(hwndDlg
, GWL_USERDATA
, (DWORD_PTR
)SetupData
);
1861 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
1862 ULONG MaxProgress
= 0;
1867 /* Disable the Back and Next buttons */
1868 PropSheet_SetWizButtons(GetParent(hwndDlg
), 0);
1870 StartComponentRegistration(hwndDlg
, &MaxProgress
);
1872 SendDlgItemMessage(hwndDlg
, IDC_PROCESSPROGRESS
, PBM_SETRANGE
,
1873 0, MAKELPARAM(0, MaxProgress
));
1874 SendDlgItemMessage(hwndDlg
, IDC_PROCESSPROGRESS
, PBM_SETPOS
,
1882 SetupData
->UnattendSetup
= FALSE
;
1891 case PM_REGISTRATION_NOTIFY
:
1894 RegistrationNotify
= (PREGISTRATIONNOTIFY
) lParam
;
1895 // update if necessary only
1896 if (oldActivityID
!= RegistrationNotify
->ActivityID
)
1898 if (0 != LoadStringW(hDllInstance
, RegistrationNotify
->ActivityID
,
1900 sizeof(Activity
) / sizeof(Activity
[0])))
1902 SendDlgItemMessageW(hwndDlg
, IDC_ACTIVITY
, WM_SETTEXT
,
1903 0, (LPARAM
) Activity
);
1905 oldActivityID
= RegistrationNotify
->ActivityID
;
1907 SendDlgItemMessageW(hwndDlg
, IDC_ITEM
, WM_SETTEXT
, 0,
1908 (LPARAM
)(NULL
== RegistrationNotify
->CurrentItem
?
1909 L
"" : RegistrationNotify
->CurrentItem
));
1910 SendDlgItemMessage(hwndDlg
, IDC_PROCESSPROGRESS
, PBM_SETPOS
,
1911 RegistrationNotify
->Progress
, 0);
1912 if (NULL
!= RegistrationNotify
->ErrorMessage
)
1914 if (0 == LoadStringW(hDllInstance
, IDS_REACTOS_SETUP
,
1915 Title
, sizeof(Title
) / sizeof(Title
[0])))
1917 wcscpy(Title
, L
"ReactOS Setup");
1919 MessageBoxW(hwndDlg
, RegistrationNotify
->ErrorMessage
,
1920 Title
, MB_ICONERROR
| MB_OK
);
1927 if(!SetupData
->UnattendSetup
&& !SetupData
->DisableVmwInst
)
1928 RunVMWInstall(GetParent(hwndDlg
));
1931 /* Enable the Back and Next buttons */
1932 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_NEXT
);
1933 PropSheet_PressButton(GetParent(hwndDlg
), PSBTN_NEXT
);
1947 SetInstallationCompleted(VOID
)
1950 DWORD InProgress
= 0;
1953 if (RegOpenKeyExW( HKEY_LOCAL_MACHINE
,
1957 &hKey
) == ERROR_SUCCESS
)
1959 RegSetValueExW( hKey
, L
"SystemSetupInProgress", 0, REG_DWORD
, (LPBYTE
)&InProgress
, sizeof(InProgress
) );
1960 RegCloseKey( hKey
);
1963 if (RegOpenKeyExW( HKEY_LOCAL_MACHINE
,
1964 L
"Software\\Microsoft\\Windows NT\\CurrentVersion",
1967 &hKey
) == ERROR_SUCCESS
)
1969 InstallDate
= (DWORD
)time(NULL
);
1970 RegSetValueExW( hKey
, L
"InstallDate", 0, REG_DWORD
, (LPBYTE
)&InstallDate
, sizeof(InstallDate
) );
1971 RegCloseKey( hKey
);
1976 static INT_PTR CALLBACK
1977 FinishDlgProc(HWND hwndDlg
,
1987 PSETUPDATA SetupData
;
1989 /* Get pointer to the global setup data */
1990 SetupData
= (PSETUPDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
1992 /* Set title font */
1993 SendDlgItemMessage(hwndDlg
,
1996 (WPARAM
)SetupData
->hTitleFont
,
1998 if (SetupData
->UnattendSetup
)
2000 KillTimer(hwndDlg
, 1);
2001 SetInstallationCompleted();
2009 SetInstallationCompleted();
2019 hWndProgress
= GetDlgItem(hwndDlg
, IDC_RESTART_PROGRESS
);
2020 Position
= SendMessage(hWndProgress
, PBM_GETPOS
, 0, 0);
2021 if (Position
== 300)
2023 KillTimer(hwndDlg
, 1);
2024 PropSheet_PressButton(GetParent(hwndDlg
), PSBTN_FINISH
);
2028 SendMessage(hWndProgress
, PBM_SETPOS
, Position
+ 1, 0);
2035 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
2040 /* Enable the correct buttons on for the active page */
2041 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_FINISH
);
2043 SendDlgItemMessage(hwndDlg
, IDC_RESTART_PROGRESS
, PBM_SETRANGE
, 0,
2044 MAKELPARAM(0, 300));
2045 SendDlgItemMessage(hwndDlg
, IDC_RESTART_PROGRESS
, PBM_SETPOS
, 0, 0);
2046 SetTimer(hwndDlg
, 1, 50, NULL
);
2050 DestroyWindow(GetParent(hwndDlg
));
2066 ProcessUnattendInf(HINF hUnattendedInf
)
2068 INFCONTEXT InfContext
;
2070 WCHAR szValue
[MAX_PATH
];
2074 if (!SetupFindFirstLineW(hUnattendedInf
,
2076 L
"UnattendSetupEnabled",
2079 DPRINT1("Error: Cant find UnattendSetupEnabled Key! %d\n", GetLastError());
2083 if (!SetupGetStringFieldW(&InfContext
,
2086 sizeof(szValue
) / sizeof(WCHAR
),
2089 DPRINT1("Error: SetupGetStringField failed with %d\n", GetLastError());
2093 if (wcscmp(szValue
, L
"yes") != 0)
2095 DPRINT("Unattend setup was disabled by UnattendSetupEnabled key.\n");
2099 if (!SetupFindFirstLineW(hUnattendedInf
,
2104 DPRINT1("Error: SetupFindFirstLine failed %d\n", GetLastError());
2111 if (!SetupGetStringFieldW(&InfContext
,
2114 sizeof(szName
) / sizeof(WCHAR
),
2117 DPRINT1("Error: SetupGetStringField failed with %d\n", GetLastError());
2121 if (!SetupGetStringFieldW(&InfContext
,
2124 sizeof(szValue
) / sizeof(WCHAR
),
2127 DPRINT1("Error: SetupGetStringField failed with %d\n", GetLastError());
2130 DPRINT1("Name %S Value %S\n", szName
, szValue
);
2131 if (!wcscmp(szName
, L
"FullName"))
2133 if ((sizeof(SetupData
.OwnerName
) / sizeof(TCHAR
)) > LineLength
)
2135 wcscpy(SetupData
.OwnerName
, szValue
);
2138 else if (!wcscmp(szName
, L
"OrgName"))
2140 if ((sizeof(SetupData
.OwnerOrganization
) / sizeof(WCHAR
)) > LineLength
)
2142 wcscpy(SetupData
.OwnerOrganization
, szValue
);
2145 else if (!wcscmp(szName
, L
"ComputerName"))
2147 if ((sizeof(SetupData
.ComputerName
) / sizeof(WCHAR
)) > LineLength
)
2149 wcscpy(SetupData
.ComputerName
, szValue
);
2152 else if (!wcscmp(szName
, L
"AdminPassword"))
2154 if ((sizeof(SetupData
.AdminPassword
) / sizeof(WCHAR
)) > LineLength
)
2156 wcscpy(SetupData
.AdminPassword
, szValue
);
2159 else if (!wcscmp(szName
, L
"TimeZoneIndex"))
2161 SetupData
.TimeZoneIndex
= _wtoi(szValue
);
2163 else if (!wcscmp(szName
, L
"DisableAutoDaylightTimeSet"))
2165 SetupData
.DisableAutoDaylightTimeSet
= _wtoi(szValue
);
2167 else if (!wcscmp(szName
, L
"DisableVmwInst"))
2169 if(!wcscmp(szValue
, L
"yes"))
2170 SetupData
.DisableVmwInst
= 1;
2172 SetupData
.DisableVmwInst
= 0;
2176 while (SetupFindNextLine(&InfContext
, &InfContext
));
2178 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
2179 L
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunOnce",
2182 &hKey
) != ERROR_SUCCESS
)
2184 DPRINT1("Error: failed to open HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\RunOnce\n");
2189 if (SetupFindFirstLineW(hUnattendedInf
,
2198 if(SetupGetStringFieldW(&InfContext
,
2201 sizeof(szValue
) / sizeof(WCHAR
),
2204 WCHAR szPath
[MAX_PATH
];
2205 swprintf(szName
, L
"%d", i
);
2206 DPRINT("szName %S szValue %S\n", szName
, szValue
);
2208 if (ExpandEnvironmentStringsW(szValue
, szPath
, MAX_PATH
))
2210 DPRINT("value %S\n", szPath
);
2211 if (RegSetValueExW(hKey
,
2215 (const BYTE
*)szPath
,
2216 (wcslen(szPath
) + 1) * sizeof(WCHAR
)) == ERROR_SUCCESS
)
2222 } while(SetupFindNextLine(&InfContext
, &InfContext
));
2230 * GetRosInstallCD should find the path to ros installation medium
2232 * If there are more than one CDDrive in it containing a ReactOS
2233 * installation cd, then it will pick the first one regardless if
2234 * it is really the installation cd
2236 * The best way to implement this is to set the key
2237 * HKLM\Software\Microsoft\Windows NT\CurrentVersion\SourcePath (REG_SZ)
2241 GetRosInstallCD(WCHAR
* szPath
, DWORD dwPathLength
)
2243 WCHAR szDrives
[512];
2244 WCHAR szDrive
[] = L
"D:\\";
2245 DWORD dwLength
, dwIndex
;
2247 dwLength
= GetLogicalDriveStringsW(sizeof(szDrives
) / sizeof(WCHAR
), szDrives
);
2249 if (dwLength
> (sizeof(szDrives
) / sizeof(WCHAR
)) || dwLength
== 0)
2251 /* buffer too small or failure */
2252 LogItem(SYSSETUP_SEVERITY_INFORMATION
, L
"GetLogicalDriveStringsW failed");
2257 for (dwIndex
= 0; dwIndex
< dwLength
; dwIndex
++)
2259 szDrive
[0] = pDrive
[dwIndex
];
2260 if (GetDriveTypeW(szDrive
) == DRIVE_CDROM
)
2262 WCHAR szBuffer
[MAX_PATH
];
2263 wcscpy(szBuffer
, szDrive
);
2264 wcscat(szBuffer
, L
"reactos\\system32\\ntoskrnl.exe");
2265 LogItem(SYSSETUP_SEVERITY_INFORMATION
, szBuffer
);
2266 if (GetFileAttributesW(szBuffer
) != INVALID_FILE_ATTRIBUTES
)
2268 /* the file exists, so this is the right drive */
2269 wcsncpy(szPath
, szDrive
, dwPathLength
);
2278 ProcessUnattendSetup()
2280 WCHAR szPath
[MAX_PATH
];
2281 HINF hUnattendedInf
;
2284 if (!GetRosInstallCD(szPath
, MAX_PATH
))
2286 /* no cd drive found */
2290 dwLength
= wcslen(szPath
);
2291 if (dwLength
+ 21 > MAX_PATH
)
2294 * allocate bigger buffer
2299 wcscat(szPath
, L
"reactos\\unattend.inf");
2301 hUnattendedInf
= SetupOpenInfFileW(szPath
,
2306 if (hUnattendedInf
!= INVALID_HANDLE_VALUE
)
2308 SetupData
.UnattendSetup
= ProcessUnattendInf(hUnattendedInf
);
2309 SetupCloseInfFile(hUnattendedInf
);
2317 PROPSHEETHEADER psh
;
2318 HPROPSHEETPAGE ahpsp
[8];
2319 PROPSHEETPAGE psp
= {0};
2324 /* Clear setup data */
2325 ZeroMemory(&SetupData
, sizeof(SETUPDATA
));
2327 ProcessUnattendSetup();
2330 /* Create the Welcome page */
2331 psp
.dwSize
= sizeof(PROPSHEETPAGE
);
2332 psp
.dwFlags
= PSP_DEFAULT
| PSP_HIDEHEADER
;
2333 psp
.hInstance
= hDllInstance
;
2334 psp
.lParam
= (LPARAM
)&SetupData
;
2335 psp
.pfnDlgProc
= WelcomeDlgProc
;
2336 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_WELCOMEPAGE
);
2337 ahpsp
[nPages
++] = CreatePropertySheetPage(&psp
);
2339 /* Create the Acknowledgements page */
2340 psp
.dwFlags
= PSP_DEFAULT
| PSP_USEHEADERTITLE
| PSP_USEHEADERSUBTITLE
;
2341 psp
.pszHeaderTitle
= MAKEINTRESOURCE(IDS_ACKTITLE
);
2342 psp
.pszHeaderSubTitle
= MAKEINTRESOURCE(IDS_ACKSUBTITLE
);
2343 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_ACKPAGE
);
2344 psp
.pfnDlgProc
= AckPageDlgProc
;
2345 ahpsp
[nPages
++] = CreatePropertySheetPage(&psp
);
2347 /* Create the Owner page */
2348 psp
.dwFlags
= PSP_DEFAULT
| PSP_USEHEADERTITLE
| PSP_USEHEADERSUBTITLE
;
2349 psp
.pszHeaderTitle
= MAKEINTRESOURCE(IDS_OWNERTITLE
);
2350 psp
.pszHeaderSubTitle
= MAKEINTRESOURCE(IDS_OWNERSUBTITLE
);
2351 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_OWNERPAGE
);
2352 psp
.pfnDlgProc
= OwnerPageDlgProc
;
2353 ahpsp
[nPages
++] = CreatePropertySheetPage(&psp
);
2355 /* Create the Computer page */
2356 psp
.dwFlags
= PSP_DEFAULT
| PSP_USEHEADERTITLE
| PSP_USEHEADERSUBTITLE
;
2357 psp
.pszHeaderTitle
= MAKEINTRESOURCE(IDS_COMPUTERTITLE
);
2358 psp
.pszHeaderSubTitle
= MAKEINTRESOURCE(IDS_COMPUTERSUBTITLE
);
2359 psp
.pfnDlgProc
= ComputerPageDlgProc
;
2360 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_COMPUTERPAGE
);
2361 ahpsp
[nPages
++] = CreatePropertySheetPage(&psp
);
2364 /* Create the Locale page */
2365 psp
.dwFlags
= PSP_DEFAULT
| PSP_USEHEADERTITLE
| PSP_USEHEADERSUBTITLE
;
2366 psp
.pszHeaderTitle
= MAKEINTRESOURCE(IDS_LOCALETITLE
);
2367 psp
.pszHeaderSubTitle
= MAKEINTRESOURCE(IDS_LOCALESUBTITLE
);
2368 psp
.pfnDlgProc
= LocalePageDlgProc
;
2369 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_LOCALEPAGE
);
2370 ahpsp
[nPages
++] = CreatePropertySheetPage(&psp
);
2373 /* Create the DateTime page */
2374 psp
.dwFlags
= PSP_DEFAULT
| PSP_USEHEADERTITLE
| PSP_USEHEADERSUBTITLE
;
2375 psp
.pszHeaderTitle
= MAKEINTRESOURCE(IDS_DATETIMETITLE
);
2376 psp
.pszHeaderSubTitle
= MAKEINTRESOURCE(IDS_DATETIMESUBTITLE
);
2377 psp
.pfnDlgProc
= DateTimePageDlgProc
;
2378 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_DATETIMEPAGE
);
2379 ahpsp
[nPages
++] = CreatePropertySheetPage(&psp
);
2382 /* Create the Process page */
2383 psp
.dwFlags
= PSP_DEFAULT
| PSP_USEHEADERTITLE
| PSP_USEHEADERSUBTITLE
;
2384 psp
.pszHeaderTitle
= MAKEINTRESOURCE(IDS_PROCESSTITLE
);
2385 psp
.pszHeaderSubTitle
= MAKEINTRESOURCE(IDS_PROCESSSUBTITLE
);
2386 psp
.pfnDlgProc
= ProcessPageDlgProc
;
2387 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_PROCESSPAGE
);
2388 ahpsp
[nPages
++] = CreatePropertySheetPage(&psp
);
2391 /* Create the Finish page */
2392 psp
.dwFlags
= PSP_DEFAULT
| PSP_HIDEHEADER
;
2393 psp
.pfnDlgProc
= FinishDlgProc
;
2394 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_FINISHPAGE
);
2395 ahpsp
[nPages
++] = CreatePropertySheetPage(&psp
);
2397 /* Create the property sheet */
2398 psh
.dwSize
= sizeof(PROPSHEETHEADER
);
2399 psh
.dwFlags
= PSH_WIZARD97
| PSH_WATERMARK
| PSH_HEADER
| PSH_MODELESS
;
2400 psh
.hInstance
= hDllInstance
;
2401 psh
.hwndParent
= NULL
;
2402 psh
.nPages
= nPages
;
2405 psh
.pszbmWatermark
= MAKEINTRESOURCE(IDB_WATERMARK
);
2406 psh
.pszbmHeader
= MAKEINTRESOURCE(IDB_HEADER
);
2408 /* Create title font */
2409 SetupData
.hTitleFont
= CreateTitleFont();
2411 /* Display the wizard */
2412 hWnd
= (HWND
)PropertySheet(&psh
);
2413 ShowWindow(hWnd
, SW_SHOW
);
2415 while (GetMessage(&msg
, NULL
, 0, 0))
2417 if(!IsDialogMessage(hWnd
, &msg
))
2419 TranslateMessage(&msg
);
2420 DispatchMessage(&msg
);
2424 DeleteObject(SetupData
.hTitleFont
);