integrate the reboot dialog into the wizard
[reactos.git] / reactos / lib / syssetup / wizard.c
1 /*
2 * ReactOS kernel
3 * Copyright (C) 2004 ReactOS Team
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19 /*
20 * COPYRIGHT: See COPYING in the top level directory
21 * PROJECT: ReactOS system libraries
22 * PURPOSE: System setup
23 * FILE: lib/syssetup/wizard.c
24 * PROGRAMER: Eric Kohl
25 */
26
27 /* INCLUDES *****************************************************************/
28
29 #include <windows.h>
30 #include <windowsx.h>
31 #include <commctrl.h>
32 #include <tchar.h>
33 #include <string.h>
34 #include <setupapi.h>
35
36 #include <syssetup/syssetup.h>
37
38 #include "globals.h"
39 #include "resource.h"
40
41 #define VMWINST
42
43 /* GLOBALS ******************************************************************/
44
45 static SETUPDATA SetupData;
46
47
48 /* FUNCTIONS ****************************************************************/
49
50 #ifdef VMWINST
51 static BOOL
52 RunVMWInstall(HWND hWnd)
53 {
54 PROCESS_INFORMATION ProcInfo;
55 MSG msg;
56 DWORD ret;
57 STARTUPINFO si = {0};
58 WCHAR InstallName[] = L"vmwinst.exe";
59
60 si.cb = sizeof(STARTUPINFO);
61
62 if(CreateProcess(NULL, InstallName, NULL, NULL, TRUE, NORMAL_PRIORITY_CLASS,
63 NULL, NULL, &si, &ProcInfo))
64 {
65 EnableWindow(hWnd, FALSE);
66 for (;;)
67 {
68 while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
69 {
70 if (msg.message == WM_QUIT)
71 goto done;
72 TranslateMessage(&msg);
73 DispatchMessage(&msg);
74 }
75
76 ret = MsgWaitForMultipleObjects(1, &ProcInfo.hProcess, FALSE, INFINITE, QS_ALLEVENTS | QS_ALLINPUT);
77 if (ret == WAIT_OBJECT_0)
78 break;
79 }
80 done:
81 EnableWindow(hWnd, TRUE);
82
83 CloseHandle(ProcInfo.hThread);
84 CloseHandle(ProcInfo.hProcess);
85 return TRUE;
86 }
87 return FALSE;
88 }
89 #endif
90
91 static VOID
92 CenterWindow(HWND hWnd)
93 {
94 HWND hWndParent;
95 RECT rcParent;
96 RECT rcWindow;
97
98 hWndParent = GetParent(hWnd);
99 if (hWndParent == NULL)
100 hWndParent = GetDesktopWindow();
101
102 GetWindowRect(hWndParent, &rcParent);
103 GetWindowRect(hWnd, &rcWindow);
104
105 SetWindowPos(hWnd,
106 HWND_TOP,
107 ((rcParent.right - rcParent.left) - (rcWindow.right - rcWindow.left)) / 2,
108 ((rcParent.bottom - rcParent.top) - (rcWindow.bottom - rcWindow.top)) / 2,
109 0,
110 0,
111 SWP_NOSIZE);
112 }
113
114
115 static HFONT
116 CreateTitleFont(VOID)
117 {
118 NONCLIENTMETRICS ncm;
119 LOGFONT LogFont;
120 HDC hdc;
121 INT FontSize;
122 HFONT hFont;
123
124 ncm.cbSize = sizeof(NONCLIENTMETRICS);
125 SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, &ncm, 0);
126
127 LogFont = ncm.lfMessageFont;
128 LogFont.lfWeight = FW_BOLD;
129 _tcscpy(LogFont.lfFaceName, _T("MS Shell Dlg"));
130
131 hdc = GetDC(NULL);
132 FontSize = 12;
133 LogFont.lfHeight = 0 - GetDeviceCaps (hdc, LOGPIXELSY) * FontSize / 72;
134 hFont = CreateFontIndirect(&LogFont);
135 ReleaseDC(NULL, hdc);
136
137 return hFont;
138 }
139
140
141 static INT_PTR CALLBACK
142 GplDlgProc(HWND hwndDlg,
143 UINT uMsg,
144 WPARAM wParam,
145 LPARAM lParam)
146 {
147 HRSRC GplTextResource;
148 HGLOBAL GplTextMem;
149 PVOID GplTextLocked;
150 PCHAR GplText;
151 DWORD Size;
152
153
154 switch (uMsg)
155 {
156 case WM_INITDIALOG:
157 GplTextResource = FindResource(hDllInstance, MAKEINTRESOURCE(IDR_GPL), _T("RT_TEXT"));
158 if (NULL == GplTextResource)
159 {
160 break;
161 }
162 Size = SizeofResource(hDllInstance, GplTextResource);
163 if (0 == Size)
164 {
165 break;
166 }
167 GplText = HeapAlloc(GetProcessHeap(), 0, Size + 1);
168 if (NULL == GplText)
169 {
170 break;
171 }
172 GplTextMem = LoadResource(hDllInstance, GplTextResource);
173 if (NULL == GplTextMem)
174 {
175 HeapFree(GetProcessHeap(), 0, GplText);
176 break;
177 }
178 GplTextLocked = LockResource(GplTextMem);
179 if (NULL == GplTextLocked)
180 {
181 HeapFree(GetProcessHeap(), 0, GplText);
182 break;
183 }
184 memcpy(GplText, GplTextLocked, Size);
185 GplText[Size] = '\0';
186 SendMessageA(GetDlgItem(hwndDlg, IDC_GPL_TEXT), WM_SETTEXT, 0, (LPARAM) GplText);
187 HeapFree(GetProcessHeap(), 0, GplText);
188 SetFocus(GetDlgItem(hwndDlg, IDOK));
189 return FALSE;
190
191 case WM_CLOSE:
192 EndDialog(hwndDlg, IDCANCEL);
193 break;
194
195 case WM_COMMAND:
196 if (HIWORD(wParam) == BN_CLICKED && IDOK == LOWORD(wParam))
197 {
198 EndDialog(hwndDlg, IDOK);
199 }
200 break;
201
202 default:
203 break;
204 }
205
206 return FALSE;
207 }
208
209
210 static INT_PTR CALLBACK
211 WelcomeDlgProc(HWND hwndDlg,
212 UINT uMsg,
213 WPARAM wParam,
214 LPARAM lParam)
215 {
216 switch (uMsg)
217 {
218 case WM_INITDIALOG:
219 {
220 PSETUPDATA SetupData;
221 HWND hwndControl;
222 DWORD dwStyle;
223
224 /* Get pointer to the global setup data */
225 SetupData = (PSETUPDATA)((LPPROPSHEETPAGE)lParam)->lParam;
226
227 hwndControl = GetParent(hwndDlg);
228
229 /* Center the wizard window */
230 CenterWindow (hwndControl);
231
232 /* Hide the system menu */
233 dwStyle = GetWindowLong(hwndControl, GWL_STYLE);
234 SetWindowLong(hwndControl, GWL_STYLE, dwStyle & ~WS_SYSMENU);
235
236 /* Hide and disable the 'Cancel' button */
237 hwndControl = GetDlgItem(GetParent(hwndDlg), IDCANCEL);
238 ShowWindow (hwndControl, SW_HIDE);
239 EnableWindow (hwndControl, FALSE);
240
241 /* Set title font */
242 SendDlgItemMessage(hwndDlg,
243 IDC_WELCOMETITLE,
244 WM_SETFONT,
245 (WPARAM)SetupData->hTitleFont,
246 (LPARAM)TRUE);
247 }
248 break;
249
250
251 case WM_NOTIFY:
252 {
253 LPNMHDR lpnm = (LPNMHDR)lParam;
254
255 switch (lpnm->code)
256 {
257 case PSN_SETACTIVE:
258 /* Enable the Next button */
259 PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT);
260 break;
261
262 default:
263 break;
264 }
265 }
266 break;
267
268 default:
269 break;
270 }
271
272 return FALSE;
273 }
274
275
276 static INT_PTR CALLBACK
277 AckPageDlgProc(HWND hwndDlg,
278 UINT uMsg,
279 WPARAM wParam,
280 LPARAM lParam)
281 {
282 LPNMHDR lpnm;
283 PWCHAR Projects;
284 PWCHAR End, CurrentProject;
285 INT ProjectsSize, ProjectsCount;
286
287 switch (uMsg)
288 {
289 case WM_INITDIALOG:
290 {
291 Projects = NULL;
292 ProjectsSize = 256;
293 do
294 {
295 Projects = HeapAlloc(GetProcessHeap(), 0, ProjectsSize * sizeof(WCHAR));
296 if (NULL == Projects)
297 {
298 return FALSE;
299 }
300 ProjectsCount = LoadString(hDllInstance, IDS_ACKPROJECTS, Projects, ProjectsSize);
301 if (0 == ProjectsCount)
302 {
303 HeapFree(GetProcessHeap(), 0, Projects);
304 return FALSE;
305 }
306 if (ProjectsCount < ProjectsSize - 1)
307 {
308 break;
309 }
310 HeapFree(GetProcessHeap(), 0, Projects);
311 ProjectsSize *= 2;
312 }
313 while (1);
314 CurrentProject = Projects;
315 while (L'\0' != *CurrentProject)
316 {
317 End = wcschr(CurrentProject, L'\n');
318 if (NULL != End)
319 {
320 *End = L'\0';
321 }
322 ListBox_AddString(GetDlgItem(hwndDlg, IDC_PROJECTS), CurrentProject);
323 if (NULL != End)
324 {
325 CurrentProject = End + 1;
326 }
327 else
328 {
329 CurrentProject += wcslen(CurrentProject);
330 }
331 }
332 HeapFree(GetProcessHeap(), 0, Projects);
333 }
334 break;
335
336 case WM_COMMAND:
337 if (HIWORD(wParam) == BN_CLICKED && IDC_VIEWGPL == LOWORD(wParam))
338 {
339 DialogBox(hDllInstance, MAKEINTRESOURCE(IDD_GPL), NULL, GplDlgProc);
340 }
341 break;
342
343 case WM_NOTIFY:
344 {
345 lpnm = (LPNMHDR)lParam;
346
347 switch (lpnm->code)
348 {
349 case PSN_SETACTIVE:
350 /* Enable the Back and Next buttons */
351 PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK | PSWIZB_NEXT);
352 break;
353
354 default:
355 break;
356 }
357 }
358 break;
359
360 default:
361 break;
362 }
363
364 return FALSE;
365 }
366
367
368 static INT_PTR CALLBACK
369 OwnerPageDlgProc(HWND hwndDlg,
370 UINT uMsg,
371 WPARAM wParam,
372 LPARAM lParam)
373 {
374 TCHAR OwnerName[51];
375 TCHAR OwnerOrganization[51];
376 HKEY hKey;
377 LPNMHDR lpnm;
378
379 switch (uMsg)
380 {
381 case WM_INITDIALOG:
382 {
383 SendDlgItemMessage(hwndDlg, IDC_OWNERNAME, EM_LIMITTEXT, 50, 0);
384 SendDlgItemMessage(hwndDlg, IDC_OWNERORGANIZATION, EM_LIMITTEXT, 50, 0);
385
386 /* Set focus to owner name */
387 SetFocus(GetDlgItem(hwndDlg, IDC_OWNERNAME));
388 }
389 break;
390
391
392 case WM_NOTIFY:
393 {
394 lpnm = (LPNMHDR)lParam;
395
396 switch (lpnm->code)
397 {
398 case PSN_SETACTIVE:
399 /* Enable the Back and Next buttons */
400 PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK | PSWIZB_NEXT);
401 break;
402
403 case PSN_WIZNEXT:
404 OwnerName[0] = 0;
405 if (GetDlgItemText(hwndDlg, IDC_OWNERNAME, OwnerName, 50) == 0)
406 {
407 MessageBox(hwndDlg,
408 _T("Setup cannot continue until you enter your name."),
409 _T("ReactOS Setup"),
410 MB_ICONERROR | MB_OK);
411 SetWindowLong(hwndDlg, DWL_MSGRESULT, -1);
412 return TRUE;
413 }
414
415 OwnerOrganization[0] = 0;
416 GetDlgItemTextW(hwndDlg, IDC_OWNERORGANIZATION, OwnerOrganization, 50);
417
418 RegOpenKeyEx(HKEY_LOCAL_MACHINE,
419 _T("Software\\Microsoft\\Windows NT\\CurrentVersion"),
420 0,
421 KEY_ALL_ACCESS,
422 &hKey);
423 /* FIXME: check error code */
424
425 RegSetValueEx(hKey,
426 _T("RegisteredOwner"),
427 0,
428 REG_SZ,
429 (LPBYTE)OwnerName,
430 (_tcslen(OwnerName) + 1) * sizeof(TCHAR));
431 /* FIXME: check error code */
432
433 RegSetValueEx(hKey,
434 _T("RegisteredOrganization"),
435 0,
436 REG_SZ,
437 (LPBYTE)OwnerOrganization,
438 (_tcslen(OwnerOrganization) + 1) * sizeof(TCHAR));
439 /* FIXME: check error code */
440
441 RegCloseKey(hKey);
442 break;
443
444 default:
445 break;
446 }
447 }
448 break;
449
450 default:
451 break;
452 }
453
454 return FALSE;
455 }
456
457
458 static INT_PTR CALLBACK
459 ComputerPageDlgProc(HWND hwndDlg,
460 UINT uMsg,
461 WPARAM wParam,
462 LPARAM lParam)
463 {
464 TCHAR ComputerName[MAX_COMPUTERNAME_LENGTH + 1];
465 TCHAR Password1[15];
466 TCHAR Password2[15];
467 DWORD Length;
468 LPNMHDR lpnm;
469
470 switch (uMsg)
471 {
472 case WM_INITDIALOG:
473 {
474 /* Retrieve current computer name */
475 Length = MAX_COMPUTERNAME_LENGTH + 1;
476 GetComputerName(ComputerName, &Length);
477
478 /* Display current computer name */
479 SetDlgItemText(hwndDlg, IDC_COMPUTERNAME, ComputerName);
480
481 /* Set text limits */
482 SendDlgItemMessage(hwndDlg, IDC_COMPUTERNAME, EM_LIMITTEXT, 64, 0);
483 SendDlgItemMessage(hwndDlg, IDC_ADMINPASSWORD1, EM_LIMITTEXT, 14, 0);
484 SendDlgItemMessage(hwndDlg, IDC_ADMINPASSWORD2, EM_LIMITTEXT, 14, 0);
485
486 /* Set focus to computer name */
487 SetFocus(GetDlgItem(hwndDlg, IDC_COMPUTERNAME));
488 }
489 break;
490
491
492 case WM_NOTIFY:
493 {
494 lpnm = (LPNMHDR)lParam;
495
496 switch (lpnm->code)
497 {
498 case PSN_SETACTIVE:
499 /* Enable the Back and Next buttons */
500 PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK | PSWIZB_NEXT);
501 break;
502
503 case PSN_WIZNEXT:
504 if (GetDlgItemText(hwndDlg, IDC_COMPUTERNAME, ComputerName, 64) == 0)
505 {
506 MessageBox(hwndDlg,
507 _T("Setup cannot continue until you enter the name of your computer."),
508 _T("ReactOS Setup"),
509 MB_ICONERROR | MB_OK);
510 SetWindowLong(hwndDlg, DWL_MSGRESULT, -1);
511 return TRUE;
512 }
513
514 /* FIXME: check computer name for invalid characters */
515
516 if (!SetComputerName(ComputerName))
517 {
518 MessageBox(hwndDlg,
519 _T("Setup failed to set the computer name."),
520 _T("ReactOS Setup"),
521 MB_ICONERROR | MB_OK);
522 SetWindowLong(hwndDlg, DWL_MSGRESULT, -1);
523 return TRUE;
524 }
525 /* Try to also set DNS hostname */
526 SetComputerNameEx(ComputerNamePhysicalDnsHostname, ComputerName);
527
528 /* Check admin passwords */
529 GetDlgItemText(hwndDlg, IDC_ADMINPASSWORD1, Password1, 15);
530 GetDlgItemText(hwndDlg, IDC_ADMINPASSWORD2, Password2, 15);
531 if (_tcscmp(Password1, Password2))
532 {
533 MessageBox(hwndDlg,
534 _T("The passwords you entered do not match. Please enter "\
535 "the desired password again."),
536 _T("ReactOS Setup"),
537 MB_ICONERROR | MB_OK);
538 SetWindowLong(hwndDlg, DWL_MSGRESULT, -1);
539 return TRUE;
540 }
541
542 /* FIXME: check password for invalid characters */
543
544 /* FIXME: Set admin password */
545 break;
546
547 default:
548 break;
549 }
550 }
551 break;
552
553 default:
554 break;
555 }
556
557 return FALSE;
558 }
559
560
561 static VOID
562 SetKeyboardLayoutName(HWND hwnd)
563 {
564 #if 0
565 TCHAR szLayoutPath[256];
566 TCHAR szLocaleName[32];
567 DWORD dwLocaleSize;
568 HKEY hKey;
569
570 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
571 _T("SYSTEM\\CurrentControlSet\\Control\\NLS\\Locale"),
572 0,
573 KEY_ALL_ACCESS,
574 &hKey))
575 return;
576
577 dwValueSize = 16 * sizeof(TCHAR);
578 if (RegQueryValueEx(hKey,
579 NULL,
580 NULL,
581 NULL,
582 szLocaleName,
583 &dwLocaleSize))
584 {
585 RegCloseKey(hKey);
586 return;
587 }
588
589 _tcscpy(szLayoutPath,
590 _T("SYSTEM\\CurrentControlSet\\Control\\KeyboardLayouts\\"));
591 _tcscat(szLayoutPath,
592 szLocaleName);
593
594 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
595 szLayoutPath,
596 0,
597 KEY_ALL_ACCESS,
598 &hKey))
599 return;
600
601 dwValueSize = 32 * sizeof(TCHAR);
602 if (RegQueryValueEx(hKey,
603 _T("Layout Text"),
604 NULL,
605 NULL,
606 szLocaleName,
607 &dwLocaleSize))
608 {
609 RegCloseKey(hKey);
610 return;
611 }
612
613 RegCloseKey(hKey);
614 #endif
615 }
616
617
618 static VOID
619 RunInputLocalePage(HWND hwnd)
620 {
621 PROPSHEETPAGE psp = {0};
622 PROPSHEETHEADER psh = {0};
623 HMODULE hDll;
624 // TCHAR Caption[256];
625
626 hDll = LoadLibrary(_T("intl.cpl"));
627 if (hDll == NULL)
628 return;
629
630 psp.dwSize = sizeof(PROPSHEETPAGE);
631 psp.dwFlags = PSP_DEFAULT;
632 psp.hInstance = hDll;
633 psp.pszTemplate = MAKEINTRESOURCE(105); /* IDD_LOCALEPAGE from intl.cpl */
634 psp.pfnDlgProc = GetProcAddress(hDll, "LocalePageProc");
635
636 // LoadString(hDll, IDS_CPLNAME, Caption, sizeof(Caption) / sizeof(TCHAR));
637
638 psh.dwSize = sizeof(PROPSHEETHEADER);
639 psh.dwFlags = PSH_PROPSHEETPAGE | PSH_PROPTITLE;
640 // psh.hwndParent = hwnd;
641 // psh.hInstance = hDll;
642 // psh.hIcon = LoadIcon(hApplet, MAKEINTRESOURCE(IDC_CPLICON));
643 psh.pszCaption = _T("Title"); //Caption;
644 psh.nPages = 1;
645 psh.nStartPage = 0;
646 psh.ppsp = &psp;
647
648 PropertySheet(&psh);
649
650 FreeLibrary(hDll);
651 }
652
653
654 static INT_PTR CALLBACK
655 LocalePageDlgProc(HWND hwndDlg,
656 UINT uMsg,
657 WPARAM wParam,
658 LPARAM lParam)
659 {
660 PSETUPDATA SetupData;
661
662 /* Retrieve pointer to the global setup data */
663 SetupData = (PSETUPDATA)GetWindowLongPtr (hwndDlg, GWL_USERDATA);
664
665 switch (uMsg)
666 {
667 case WM_INITDIALOG:
668 {
669 /* Save pointer to the global setup data */
670 SetupData = (PSETUPDATA)((LPPROPSHEETPAGE)lParam)->lParam;
671 SetWindowLongPtr(hwndDlg, GWL_USERDATA, (DWORD_PTR)SetupData);
672
673
674 SetKeyboardLayoutName(GetDlgItem(hwndDlg, IDC_LAYOUTTEXT));
675
676 }
677 break;
678
679 case WM_COMMAND:
680 if (HIWORD(wParam) == BN_CLICKED)
681 {
682 switch (LOWORD(wParam))
683 {
684 case IDC_CUSTOMLOCALE:
685 {
686 RunInputLocalePage(hwndDlg);
687 /* FIXME: Update input locale name */
688 }
689 break;
690
691 case IDC_CUSTOMLAYOUT:
692 {
693 // RunKeyboardLayoutControlPanel(hwndDlg);
694 }
695 break;
696 }
697 }
698 break;
699
700 case WM_NOTIFY:
701 {
702 LPNMHDR lpnm = (LPNMHDR)lParam;
703
704 switch (lpnm->code)
705 {
706 case PSN_SETACTIVE:
707 /* Enable the Back and Next buttons */
708 PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK | PSWIZB_NEXT);
709 break;
710
711 case PSN_WIZNEXT:
712 break;
713
714 default:
715 break;
716 }
717 }
718 break;
719
720 default:
721 break;
722 }
723
724 return FALSE;
725 }
726
727
728 static PTIMEZONE_ENTRY
729 GetLargerTimeZoneEntry(PSETUPDATA SetupData, DWORD Index)
730 {
731 PTIMEZONE_ENTRY Entry;
732
733 Entry = SetupData->TimeZoneListHead;
734 while (Entry != NULL)
735 {
736 if (Entry->Index >= Index)
737 return Entry;
738
739 Entry = Entry->Next;
740 }
741
742 return NULL;
743 }
744
745
746 static VOID
747 CreateTimeZoneList(PSETUPDATA SetupData)
748 {
749 TCHAR szKeyName[256];
750 DWORD dwIndex;
751 DWORD dwNameSize;
752 DWORD dwValueSize;
753 LONG lError;
754 HKEY hZonesKey;
755 HKEY hZoneKey;
756
757 PTIMEZONE_ENTRY Entry;
758 PTIMEZONE_ENTRY Current;
759
760 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
761 _T("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones"),
762 0,
763 KEY_ALL_ACCESS,
764 &hZonesKey))
765 return;
766
767 dwIndex = 0;
768 while (TRUE)
769 {
770 dwNameSize = 256 * sizeof(TCHAR);
771 lError = RegEnumKeyEx(hZonesKey,
772 dwIndex,
773 szKeyName,
774 &dwNameSize,
775 NULL,
776 NULL,
777 NULL,
778 NULL);
779 if (lError != ERROR_SUCCESS && lError != ERROR_MORE_DATA)
780 break;
781
782 if (RegOpenKeyEx(hZonesKey,
783 szKeyName,
784 0,
785 KEY_ALL_ACCESS,
786 &hZoneKey))
787 break;
788
789 Entry = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(TIMEZONE_ENTRY));
790 if (Entry == NULL)
791 {
792 RegCloseKey(hZoneKey);
793 break;
794 }
795
796 dwValueSize = 64 * sizeof(TCHAR);
797 if (RegQueryValueEx(hZoneKey,
798 _T("Display"),
799 NULL,
800 NULL,
801 (LPBYTE)&Entry->Description,
802 &dwValueSize))
803 {
804 RegCloseKey(hZoneKey);
805 break;
806 }
807
808 dwValueSize = 32 * sizeof(TCHAR);
809 if (RegQueryValueEx(hZoneKey,
810 _T("Std"),
811 NULL,
812 NULL,
813 (LPBYTE)&Entry->StandardName,
814 &dwValueSize))
815 {
816 RegCloseKey(hZoneKey);
817 break;
818 }
819
820 dwValueSize = 32 * sizeof(WCHAR);
821 if (RegQueryValueEx(hZoneKey,
822 _T("Dlt"),
823 NULL,
824 NULL,
825 (LPBYTE)&Entry->DaylightName,
826 &dwValueSize))
827 {
828 RegCloseKey(hZoneKey);
829 break;
830 }
831
832 dwValueSize = sizeof(DWORD);
833 if (RegQueryValueEx(hZoneKey,
834 _T("Index"),
835 NULL,
836 NULL,
837 (LPBYTE)&Entry->Index,
838 &dwValueSize))
839 {
840 RegCloseKey(hZoneKey);
841 break;
842 }
843
844 dwValueSize = sizeof(TZ_INFO);
845 if (RegQueryValueEx(hZoneKey,
846 _T("TZI"),
847 NULL,
848 NULL,
849 (LPBYTE)&Entry->TimezoneInfo,
850 &dwValueSize))
851 {
852 RegCloseKey(hZoneKey);
853 break;
854 }
855
856 RegCloseKey(hZoneKey);
857
858 if (SetupData->TimeZoneListHead == NULL &&
859 SetupData->TimeZoneListTail == NULL)
860 {
861 Entry->Prev = NULL;
862 Entry->Next = NULL;
863 SetupData->TimeZoneListHead = Entry;
864 SetupData->TimeZoneListTail = Entry;
865 }
866 else
867 {
868 Current = GetLargerTimeZoneEntry(SetupData, Entry->Index);
869 if (Current != NULL)
870 {
871 if (Current == SetupData->TimeZoneListHead)
872 {
873 /* Prepend to head */
874 Entry->Prev = NULL;
875 Entry->Next = SetupData->TimeZoneListHead;
876 SetupData->TimeZoneListHead->Prev = Entry;
877 SetupData->TimeZoneListHead = Entry;
878 }
879 else
880 {
881 /* Insert before current */
882 Entry->Prev = Current->Prev;
883 Entry->Next = Current;
884 Current->Prev->Next = Entry;
885 Current->Prev = Entry;
886 }
887 }
888 else
889 {
890 /* Append to tail */
891 Entry->Prev = SetupData->TimeZoneListTail;
892 Entry->Next = NULL;
893 SetupData->TimeZoneListTail->Next = Entry;
894 SetupData->TimeZoneListTail = Entry;
895 }
896 }
897
898 dwIndex++;
899 }
900
901 RegCloseKey(hZonesKey);
902 }
903
904
905 static VOID
906 DestroyTimeZoneList(PSETUPDATA SetupData)
907 {
908 PTIMEZONE_ENTRY Entry;
909
910 while (SetupData->TimeZoneListHead != NULL)
911 {
912 Entry = SetupData->TimeZoneListHead;
913
914 SetupData->TimeZoneListHead = Entry->Next;
915 if (SetupData->TimeZoneListHead != NULL)
916 {
917 SetupData->TimeZoneListHead->Prev = NULL;
918 }
919
920 HeapFree(GetProcessHeap(), 0, Entry);
921 }
922
923 SetupData->TimeZoneListTail = NULL;
924 }
925
926 #if 0
927 static BOOL
928 GetTimeZoneListIndex(LPDWORD lpIndex)
929 {
930 TCHAR szLanguageIdString[9];
931 HKEY hKey;
932 DWORD dwValueSize;
933 DWORD Length;
934 LPTSTR Buffer;
935 LPTSTR Ptr;
936 LPTSTR End;
937 BOOL bFound;
938
939 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
940 _T("SYSTEM\\CurrentControlSet\\Control\\NLS\\Language"),
941 0,
942 KEY_ALL_ACCESS,
943 &hKey))
944 return FALSE;
945
946 dwValueSize = 9 * sizeof(TCHAR);
947 if (RegQueryValueEx(hKey,
948 _T("Default"),
949 NULL,
950 NULL,
951 (LPBYTE)szLanguageIdString,
952 &dwValueSize))
953 {
954 RegCloseKey(hKey);
955 return FALSE;
956 }
957
958 RegCloseKey(hKey);
959
960 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
961 _T("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones"),
962 0,
963 KEY_ALL_ACCESS,
964 &hKey))
965 return FALSE;
966
967 dwValueSize = 0;
968 if (RegQueryValueEx(hKey,
969 _T("IndexMapping"),
970 NULL,
971 NULL,
972 NULL,
973 &dwValueSize))
974 {
975 RegCloseKey(hKey);
976 return FALSE;
977 }
978
979 Buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwValueSize);
980 if (Buffer == NULL)
981 {
982 RegCloseKey(hKey);
983 return FALSE;
984 }
985
986 if (RegQueryValueEx(hKey,
987 _T("IndexMapping"),
988 NULL,
989 NULL,
990 (LPBYTE)Buffer,
991 &dwValueSize))
992 {
993 HeapFree(GetProcessHeap(), 0, Buffer);
994 RegCloseKey(hKey);
995 return FALSE;
996 }
997
998 RegCloseKey(hKey);
999
1000 Ptr = Buffer;
1001 while (*Ptr != 0)
1002 {
1003 Length = _tcslen(Ptr);
1004 if (_tcsicmp(Ptr, szLanguageIdString) == 0)
1005 bFound = TRUE;
1006
1007 Ptr = Ptr + Length + 1;
1008 if (*Ptr == 0)
1009 break;
1010
1011 Length = _tcslen(Ptr);
1012
1013 if (bFound)
1014 {
1015 *lpIndex = _tcstoul(Ptr, &End, 10);
1016 HeapFree(GetProcessHeap(), 0, Buffer);
1017 return FALSE;
1018 }
1019
1020 Ptr = Ptr + Length + 1;
1021 }
1022
1023 HeapFree(GetProcessHeap(), 0, Buffer);
1024
1025 return FALSE;
1026 }
1027 #endif
1028
1029
1030 static VOID
1031 ShowTimeZoneList(HWND hwnd, PSETUPDATA SetupData)
1032 {
1033 PTIMEZONE_ENTRY Entry;
1034 DWORD dwIndex = 0;
1035 DWORD dwEntryIndex = 0;
1036 DWORD dwCount;
1037
1038 #if 0
1039 GetTimeZoneListIndex(&dwEntryIndex);
1040 #endif
1041 dwEntryIndex = 85; /* GMT time zone */
1042
1043 Entry = SetupData->TimeZoneListHead;
1044 while (Entry != NULL)
1045 {
1046 dwCount = SendMessage(hwnd,
1047 CB_ADDSTRING,
1048 0,
1049 (LPARAM)Entry->Description);
1050
1051 if (dwEntryIndex != 0 && dwEntryIndex == Entry->Index)
1052 dwIndex = dwCount;
1053
1054 Entry = Entry->Next;
1055 }
1056
1057 SendMessage(hwnd,
1058 CB_SETCURSEL,
1059 (WPARAM)dwIndex,
1060 0);
1061 }
1062
1063
1064 static VOID
1065 SetLocalTimeZone(HWND hwnd, PSETUPDATA SetupData)
1066 {
1067 TIME_ZONE_INFORMATION TimeZoneInformation;
1068 PTIMEZONE_ENTRY Entry;
1069 DWORD dwIndex;
1070 DWORD i;
1071
1072 dwIndex = SendMessage(hwnd,
1073 CB_GETCURSEL,
1074 0,
1075 0);
1076
1077 i = 0;
1078 Entry = SetupData->TimeZoneListHead;
1079 while (i < dwIndex)
1080 {
1081 if (Entry == NULL)
1082 return;
1083
1084 i++;
1085 Entry = Entry->Next;
1086 }
1087
1088 _tcscpy(TimeZoneInformation.StandardName,
1089 Entry->StandardName);
1090 _tcscpy(TimeZoneInformation.DaylightName,
1091 Entry->DaylightName);
1092
1093 TimeZoneInformation.Bias = Entry->TimezoneInfo.Bias;
1094 TimeZoneInformation.StandardBias = Entry->TimezoneInfo.StandardBias;
1095 TimeZoneInformation.DaylightBias = Entry->TimezoneInfo.DaylightBias;
1096
1097 memcpy(&TimeZoneInformation.StandardDate,
1098 &Entry->TimezoneInfo.StandardDate,
1099 sizeof(SYSTEMTIME));
1100 memcpy(&TimeZoneInformation.DaylightDate,
1101 &Entry->TimezoneInfo.DaylightDate,
1102 sizeof(SYSTEMTIME));
1103
1104 /* Set time zone information */
1105 SetTimeZoneInformation(&TimeZoneInformation);
1106 }
1107
1108
1109 static BOOL
1110 GetLocalSystemTime(HWND hwnd, PSETUPDATA SetupData)
1111 {
1112 SYSTEMTIME Date;
1113 SYSTEMTIME Time;
1114
1115 if (DateTime_GetSystemTime(GetDlgItem(hwnd, IDC_DATEPICKER), &Date) != GDT_VALID)
1116 {
1117 return FALSE;
1118 }
1119
1120 if (DateTime_GetSystemTime(GetDlgItem(hwnd, IDC_TIMEPICKER), &Time) != GDT_VALID)
1121 {
1122 return FALSE;
1123 }
1124
1125 SetupData->SystemTime.wYear = Date.wYear;
1126 SetupData->SystemTime.wMonth = Date.wMonth;
1127 SetupData->SystemTime.wDayOfWeek = Date.wDayOfWeek;
1128 SetupData->SystemTime.wDay = Date.wDay;
1129 SetupData->SystemTime.wHour = Time.wHour;
1130 SetupData->SystemTime.wMinute = Time.wMinute;
1131 SetupData->SystemTime.wSecond = Time.wSecond;
1132 SetupData->SystemTime.wMilliseconds = Time.wMilliseconds;
1133
1134 return TRUE;
1135 }
1136
1137
1138 static VOID
1139 SetAutoDaylightInfo(HWND hwnd)
1140 {
1141 HKEY hKey;
1142 DWORD dwValue = 1;
1143
1144 if (SendMessage(hwnd, BM_GETCHECK, 0, 0) == BST_UNCHECKED)
1145 {
1146 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
1147 _T("SYSTEM\\CurrentControlSet\\Control\\TimeZoneInformation"),
1148 0,
1149 KEY_SET_VALUE,
1150 &hKey))
1151 return;
1152
1153 RegSetValueEx(hKey,
1154 _T("DisableAutoDaylightTimeSet"),
1155 0,
1156 REG_DWORD,
1157 (LPBYTE)&dwValue,
1158 sizeof(DWORD));
1159 RegCloseKey(hKey);
1160 }
1161 }
1162
1163
1164 static BOOL
1165 SetSystemLocalTime(HWND hwnd, PSETUPDATA SetupData)
1166 {
1167 HANDLE hToken;
1168 DWORD PrevSize;
1169 TOKEN_PRIVILEGES priv, previouspriv;
1170 BOOL Ret = FALSE;
1171
1172 /*
1173 * enable the SeSystemtimePrivilege privilege
1174 */
1175
1176 if(OpenProcessToken(GetCurrentProcess(),
1177 TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
1178 &hToken))
1179 {
1180 priv.PrivilegeCount = 1;
1181 priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
1182
1183 if(LookupPrivilegeValue(NULL,
1184 SE_SYSTEMTIME_NAME,
1185 &priv.Privileges[0].Luid))
1186 {
1187 if(AdjustTokenPrivileges(hToken,
1188 FALSE,
1189 &priv,
1190 sizeof(previouspriv),
1191 &previouspriv,
1192 &PrevSize) &&
1193 GetLastError() == ERROR_SUCCESS)
1194 {
1195 /*
1196 * we successfully enabled it, we're permitted to change the system time
1197 */
1198 Ret = SetLocalTime(&SetupData->SystemTime);
1199
1200 /*
1201 * for the sake of security, restore the previous status again
1202 */
1203 if(previouspriv.PrivilegeCount > 0)
1204 {
1205 AdjustTokenPrivileges(hToken,
1206 FALSE,
1207 &previouspriv,
1208 0,
1209 NULL,
1210 0);
1211 }
1212 }
1213 }
1214 CloseHandle(hToken);
1215 }
1216
1217 return Ret;
1218 }
1219
1220
1221 static INT_PTR CALLBACK
1222 DateTimePageDlgProc(HWND hwndDlg,
1223 UINT uMsg,
1224 WPARAM wParam,
1225 LPARAM lParam)
1226 {
1227 PSETUPDATA SetupData;
1228
1229 /* Retrieve pointer to the global setup data */
1230 SetupData = (PSETUPDATA)GetWindowLongPtr (hwndDlg, GWL_USERDATA);
1231
1232 switch (uMsg)
1233 {
1234 case WM_INITDIALOG:
1235 {
1236 /* Save pointer to the global setup data */
1237 SetupData = (PSETUPDATA)((LPPROPSHEETPAGE)lParam)->lParam;
1238 SetWindowLongPtr(hwndDlg, GWL_USERDATA, (DWORD_PTR)SetupData);
1239
1240 CreateTimeZoneList(SetupData);
1241
1242 ShowTimeZoneList(GetDlgItem(hwndDlg, IDC_TIMEZONELIST),
1243 SetupData);
1244
1245 SendDlgItemMessage(hwndDlg, IDC_AUTODAYLIGHT, BM_SETCHECK, (WPARAM)BST_CHECKED, 0);
1246 }
1247 break;
1248
1249
1250 case WM_NOTIFY:
1251 {
1252 LPNMHDR lpnm = (LPNMHDR)lParam;
1253
1254 switch (lpnm->code)
1255 {
1256 case PSN_SETACTIVE:
1257 /* Enable the Back and Next buttons */
1258 PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK | PSWIZB_NEXT);
1259 break;
1260
1261 case PSN_WIZNEXT:
1262 {
1263 GetLocalSystemTime(hwndDlg, SetupData);
1264 SetLocalTimeZone(GetDlgItem(hwndDlg, IDC_TIMEZONELIST),
1265 SetupData);
1266 SetAutoDaylightInfo(GetDlgItem(hwndDlg, IDC_AUTODAYLIGHT));
1267 if(!SetSystemLocalTime(hwndDlg, SetupData))
1268 {
1269 MessageBox(hwndDlg,
1270 _T("Setup was unable to set the local time."),
1271 _T("ReactOS Setup"),
1272 MB_ICONWARNING | MB_OK);
1273 }
1274 }
1275 break;
1276
1277 default:
1278 break;
1279 }
1280 }
1281 break;
1282
1283 case WM_DESTROY:
1284 DestroyTimeZoneList(SetupData);
1285 break;
1286
1287 default:
1288 break;
1289 }
1290
1291 return FALSE;
1292 }
1293
1294
1295 static INT_PTR CALLBACK
1296 ProcessPageDlgProc(HWND hwndDlg,
1297 UINT uMsg,
1298 WPARAM wParam,
1299 LPARAM lParam)
1300 {
1301 PSETUPDATA SetupData;
1302
1303 /* Retrieve pointer to the global setup data */
1304 SetupData = (PSETUPDATA)GetWindowLongPtr (hwndDlg, GWL_USERDATA);
1305
1306 switch (uMsg)
1307 {
1308 case WM_INITDIALOG:
1309 {
1310 /* Save pointer to the global setup data */
1311 SetupData = (PSETUPDATA)((LPPROPSHEETPAGE)lParam)->lParam;
1312 SetWindowLongPtr(hwndDlg, GWL_USERDATA, (DWORD_PTR)SetupData);
1313 }
1314 break;
1315
1316 case WM_TIMER:
1317 {
1318 INT Position;
1319 HWND hWndProgress;
1320
1321 hWndProgress = GetDlgItem(hwndDlg, IDC_PROCESSPROGRESS);
1322 Position = SendMessage(hWndProgress, PBM_GETPOS, 0, 0);
1323 if (Position == 2)
1324 {
1325 KillTimer(hwndDlg, 1);
1326
1327 /* Enable the Back and Next buttons */
1328 PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT);
1329 PropSheet_PressButton(GetParent(hwndDlg), PSBTN_NEXT);
1330 }
1331 else
1332 {
1333 #ifdef VMWINST
1334 if (Position == 1)
1335 {
1336 KillTimer(hwndDlg, 1);
1337 RunVMWInstall(GetParent(hwndDlg));
1338 SetTimer(hwndDlg, 1, 50, NULL);
1339 }
1340 #endif
1341 SendMessage(hWndProgress, PBM_SETPOS, Position + 1, 0);
1342 }
1343 }
1344 return TRUE;
1345
1346 case WM_NOTIFY:
1347 {
1348 LPNMHDR lpnm = (LPNMHDR)lParam;
1349
1350 switch (lpnm->code)
1351 {
1352 case PSN_SETACTIVE:
1353 /* Disable the Back and Next buttons */
1354 PropSheet_SetWizButtons(GetParent(hwndDlg), 0);
1355
1356 SendDlgItemMessage(hwndDlg, IDC_PROCESSPROGRESS, PBM_SETRANGE, 0,
1357 MAKELPARAM(0, 2));
1358 SetTimer(hwndDlg, 1, 50, NULL);
1359 break;
1360
1361 case PSN_WIZNEXT:
1362 break;
1363
1364 default:
1365 break;
1366 }
1367 }
1368 break;
1369
1370 default:
1371 break;
1372 }
1373
1374 return FALSE;
1375 }
1376
1377
1378
1379 static INT_PTR CALLBACK
1380 FinishDlgProc(HWND hwndDlg,
1381 UINT uMsg,
1382 WPARAM wParam,
1383 LPARAM lParam)
1384 {
1385
1386 switch (uMsg)
1387 {
1388 case WM_INITDIALOG:
1389 {
1390 PSETUPDATA SetupData;
1391
1392 /* Get pointer to the global setup data */
1393 SetupData = (PSETUPDATA)((LPPROPSHEETPAGE)lParam)->lParam;
1394
1395 /* Set title font */
1396 SendDlgItemMessage(hwndDlg,
1397 IDC_FINISHTITLE,
1398 WM_SETFONT,
1399 (WPARAM)SetupData->hTitleFont,
1400 (LPARAM)TRUE);
1401 }
1402 break;
1403
1404 case WM_TIMER:
1405 {
1406 INT Position;
1407 HWND hWndProgress;
1408
1409 hWndProgress = GetDlgItem(hwndDlg, IDC_RESTART_PROGRESS);
1410 Position = SendMessage(hWndProgress, PBM_GETPOS, 0, 0);
1411 if (Position == 300)
1412 {
1413 KillTimer(hwndDlg, 1);
1414 PropSheet_PressButton(GetParent(hwndDlg), PSBTN_FINISH);
1415 }
1416 else
1417 {
1418 SendMessage(hWndProgress, PBM_SETPOS, Position + 1, 0);
1419 }
1420 }
1421 return TRUE;
1422
1423 case WM_NOTIFY:
1424 {
1425 LPNMHDR lpnm = (LPNMHDR)lParam;
1426
1427 switch (lpnm->code)
1428 {
1429 case PSN_SETACTIVE:
1430 /* Enable the correct buttons on for the active page */
1431 PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK | PSWIZB_FINISH);
1432
1433 SendDlgItemMessage(hwndDlg, IDC_RESTART_PROGRESS, PBM_SETRANGE, 0,
1434 MAKELPARAM(0, 300));
1435 SendDlgItemMessage(hwndDlg, IDC_RESTART_PROGRESS, PBM_SETPOS, 0, 0);
1436 SetTimer(hwndDlg, 1, 50, NULL);
1437 break;
1438
1439 case PSN_WIZBACK:
1440 /* Handle a Back button click, if necessary */
1441 KillTimer(hwndDlg, 1);
1442
1443 /* Skip the progress page */
1444 PropSheet_SetCurSelByID(GetParent(hwndDlg), IDD_DATETIMEPAGE);
1445 SetWindowLong(hwndDlg, DWL_MSGRESULT, -1);
1446 return TRUE;
1447
1448 case PSN_WIZFINISH:
1449 /* Handle a Finish button click, if necessary */
1450 break;
1451
1452 default:
1453 break;
1454 }
1455 }
1456 break;
1457
1458 default:
1459 break;
1460 }
1461
1462 return FALSE;
1463 }
1464
1465
1466 VOID
1467 InstallWizard(VOID)
1468 {
1469 PROPSHEETHEADER psh;
1470 HPROPSHEETPAGE ahpsp[8];
1471 PROPSHEETPAGE psp = {0};
1472 UINT nPages = 0;
1473
1474 /* Clear setup data */
1475 ZeroMemory(&SetupData, sizeof(SETUPDATA));
1476
1477 /* Create the Welcome page */
1478 psp.dwSize = sizeof(PROPSHEETPAGE);
1479 psp.dwFlags = PSP_DEFAULT | PSP_HIDEHEADER;
1480 psp.hInstance = hDllInstance;
1481 psp.lParam = (LPARAM)&SetupData;
1482 psp.pfnDlgProc = WelcomeDlgProc;
1483 psp.pszTemplate = MAKEINTRESOURCE(IDD_WELCOMEPAGE);
1484 ahpsp[nPages++] = CreatePropertySheetPage(&psp);
1485
1486 /* Create the Acknowledgements page */
1487 psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
1488 psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_ACKTITLE);
1489 psp.pszHeaderSubTitle = MAKEINTRESOURCE(IDS_ACKSUBTITLE);
1490 psp.pszTemplate = MAKEINTRESOURCE(IDD_ACKPAGE);
1491 psp.pfnDlgProc = AckPageDlgProc;
1492 ahpsp[nPages++] = CreatePropertySheetPage(&psp);
1493
1494 /* Create the Owner page */
1495 psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
1496 psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_OWNERTITLE);
1497 psp.pszHeaderSubTitle = MAKEINTRESOURCE(IDS_OWNERSUBTITLE);
1498 psp.pszTemplate = MAKEINTRESOURCE(IDD_OWNERPAGE);
1499 psp.pfnDlgProc = OwnerPageDlgProc;
1500 ahpsp[nPages++] = CreatePropertySheetPage(&psp);
1501
1502 /* Create the Computer page */
1503 psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
1504 psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_COMPUTERTITLE);
1505 psp.pszHeaderSubTitle = MAKEINTRESOURCE(IDS_COMPUTERSUBTITLE);
1506 psp.pfnDlgProc = ComputerPageDlgProc;
1507 psp.pszTemplate = MAKEINTRESOURCE(IDD_COMPUTERPAGE);
1508 ahpsp[nPages++] = CreatePropertySheetPage(&psp);
1509
1510
1511 /* Create the Locale page */
1512 psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
1513 psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_LOCALETITLE);
1514 psp.pszHeaderSubTitle = MAKEINTRESOURCE(IDS_LOCALESUBTITLE);
1515 psp.pfnDlgProc = LocalePageDlgProc;
1516 psp.pszTemplate = MAKEINTRESOURCE(IDD_LOCALEPAGE);
1517 ahpsp[nPages++] = CreatePropertySheetPage(&psp);
1518
1519
1520 /* Create the DateTime page */
1521 psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
1522 psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_DATETIMETITLE);
1523 psp.pszHeaderSubTitle = MAKEINTRESOURCE(IDS_DATETIMESUBTITLE);
1524 psp.pfnDlgProc = DateTimePageDlgProc;
1525 psp.pszTemplate = MAKEINTRESOURCE(IDD_DATETIMEPAGE);
1526 ahpsp[nPages++] = CreatePropertySheetPage(&psp);
1527
1528
1529 /* Create the Process page */
1530 psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
1531 psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_PROCESSTITLE);
1532 psp.pszHeaderSubTitle = MAKEINTRESOURCE(IDS_PROCESSSUBTITLE);
1533 psp.pfnDlgProc = ProcessPageDlgProc;
1534 psp.pszTemplate = MAKEINTRESOURCE(IDD_PROCESSPAGE);
1535 ahpsp[nPages++] = CreatePropertySheetPage(&psp);
1536
1537
1538 /* Create the Finish page */
1539 psp.dwFlags = PSP_DEFAULT | PSP_HIDEHEADER;
1540 psp.pfnDlgProc = FinishDlgProc;
1541 psp.pszTemplate = MAKEINTRESOURCE(IDD_FINISHPAGE);
1542 ahpsp[nPages++] = CreatePropertySheetPage(&psp);
1543
1544 /* Create the property sheet */
1545 psh.dwSize = sizeof(PROPSHEETHEADER);
1546 psh.dwFlags = PSH_WIZARD97 | PSH_WATERMARK | PSH_HEADER;
1547 psh.hInstance = hDllInstance;
1548 psh.hwndParent = NULL;
1549 psh.nPages = nPages;
1550 psh.nStartPage = 0;
1551 psh.phpage = ahpsp;
1552 psh.pszbmWatermark = MAKEINTRESOURCE(IDB_WATERMARK);
1553 psh.pszbmHeader = MAKEINTRESOURCE(IDB_HEADER);
1554
1555 /* Create title font */
1556 SetupData.hTitleFont = CreateTitleFont();
1557
1558 /* Display the wizard */
1559 PropertySheet(&psh);
1560
1561 DeleteObject(SetupData.hTitleFont);
1562 }
1563
1564 /* EOF */