Enable automatic adjustment of daylight savings changes.
[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 /* $Id: wizard.c,v 1.12 2004/11/11 12:23:43 ekohl Exp $
20 *
21 * COPYRIGHT: See COPYING in the top level directory
22 * PROJECT: ReactOS system libraries
23 * PURPOSE: System setup
24 * FILE: lib/syssetup/wizard.c
25 * PROGRAMER: Eric Kohl
26 */
27
28 /* INCLUDES *****************************************************************/
29
30 #include <windows.h>
31 #include <commctrl.h>
32
33 #include <string.h>
34 #include <tchar.h>
35 #include <setupapi.h>
36
37 #include <syssetup.h>
38
39
40 #include "globals.h"
41 #include "resource.h"
42
43
44 /* GLOBALS ******************************************************************/
45
46 static SETUPDATA SetupData;
47
48
49 /* FUNCTIONS ****************************************************************/
50
51 static VOID
52 CenterWindow(HWND hWnd)
53 {
54 HWND hWndParent;
55 RECT rcParent;
56 RECT rcWindow;
57
58 hWndParent = GetParent(hWnd);
59 if (hWndParent == NULL)
60 hWndParent = GetDesktopWindow();
61
62 GetWindowRect(hWndParent, &rcParent);
63 GetWindowRect(hWnd, &rcWindow);
64
65 SetWindowPos(hWnd,
66 HWND_TOP,
67 ((rcParent.right - rcParent.left) - (rcWindow.right - rcWindow.left)) / 2,
68 ((rcParent.bottom - rcParent.top) - (rcWindow.bottom - rcWindow.top)) / 2,
69 0,
70 0,
71 SWP_NOSIZE);
72 }
73
74
75 static HFONT
76 CreateTitleFont(VOID)
77 {
78 NONCLIENTMETRICS ncm;
79 LOGFONT LogFont;
80 HDC hdc;
81 INT FontSize;
82 HFONT hFont;
83
84 ncm.cbSize = sizeof(NONCLIENTMETRICS);
85 SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, &ncm, 0);
86
87 LogFont = ncm.lfMessageFont;
88 LogFont.lfWeight = FW_BOLD;
89 _tcscpy(LogFont.lfFaceName, TEXT("MS Shell Dlg"));
90
91 hdc = GetDC(NULL);
92 FontSize = 12;
93 LogFont.lfHeight = 0 - GetDeviceCaps (hdc, LOGPIXELSY) * FontSize / 72;
94 hFont = CreateFontIndirect(&LogFont);
95 ReleaseDC(NULL, hdc);
96
97 return hFont;
98 }
99
100
101 INT_PTR CALLBACK
102 WelcomeDlgProc(HWND hwndDlg,
103 UINT uMsg,
104 WPARAM wParam,
105 LPARAM lParam)
106 {
107 switch (uMsg)
108 {
109 case WM_INITDIALOG:
110 {
111 PSETUPDATA SetupData;
112 HWND hwndControl;
113 DWORD dwStyle;
114
115 /* Get pointer to the global setup data */
116 SetupData = (PSETUPDATA)((LPPROPSHEETPAGE)lParam)->lParam;
117
118 hwndControl = GetParent(hwndDlg);
119
120 /* Center the wizard window */
121 CenterWindow (hwndControl);
122
123 /* Hide the system menu */
124 dwStyle = GetWindowLong(hwndControl, GWL_STYLE);
125 SetWindowLong(hwndControl, GWL_STYLE, dwStyle & ~WS_SYSMENU);
126
127 /* Hide and disable the 'Cancel' button */
128 hwndControl = GetDlgItem(GetParent(hwndDlg), IDCANCEL);
129 ShowWindow (hwndControl, SW_HIDE);
130 EnableWindow (hwndControl, FALSE);
131
132 /* Set title font */
133 SendDlgItemMessage(hwndDlg,
134 IDC_WELCOMETITLE,
135 WM_SETFONT,
136 (WPARAM)SetupData->hTitleFont,
137 (LPARAM)TRUE);
138 }
139 break;
140
141
142 case WM_NOTIFY:
143 {
144 LPNMHDR lpnm = (LPNMHDR)lParam;
145
146 switch (lpnm->code)
147 {
148 case PSN_SETACTIVE:
149 /* Enable the Next button */
150 PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT);
151 break;
152
153 default:
154 break;
155 }
156 }
157 break;
158
159 default:
160 break;
161 }
162
163 return FALSE;
164 }
165
166
167 INT_PTR CALLBACK
168 OwnerPageDlgProc(HWND hwndDlg,
169 UINT uMsg,
170 WPARAM wParam,
171 LPARAM lParam)
172 {
173 TCHAR OwnerName[51];
174 TCHAR OwnerOrganization[51];
175 HKEY hKey;
176 LPNMHDR lpnm;
177
178 switch (uMsg)
179 {
180 case WM_INITDIALOG:
181 {
182 SendDlgItemMessage(hwndDlg, IDC_OWNERNAME, EM_LIMITTEXT, 50, 0);
183 SendDlgItemMessage(hwndDlg, IDC_OWNERORGANIZATION, EM_LIMITTEXT, 50, 0);
184
185 /* Set focus to owner name */
186 SetFocus(GetDlgItem(hwndDlg, IDC_OWNERNAME));
187 }
188 break;
189
190
191 case WM_NOTIFY:
192 {
193 lpnm = (LPNMHDR)lParam;
194
195 switch (lpnm->code)
196 {
197 case PSN_SETACTIVE:
198 /* Enable the Back and Next buttons */
199 PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK | PSWIZB_NEXT);
200 break;
201
202 case PSN_WIZNEXT:
203 OwnerName[0] = 0;
204 if (GetDlgItemText(hwndDlg, IDC_OWNERNAME, OwnerName, 50) == 0)
205 {
206 MessageBox(hwndDlg,
207 _T("Setup cannot continue until you enter your name."),
208 _T("ReactOS Setup"),
209 MB_ICONERROR | MB_OK);
210 SetWindowLong(hwndDlg, DWL_MSGRESULT, -1);
211 return TRUE;
212 }
213
214 OwnerOrganization[0] = 0;
215 GetDlgItemText(hwndDlg, IDC_OWNERORGANIZATION, OwnerOrganization, 50);
216
217 RegOpenKeyEx(HKEY_LOCAL_MACHINE,
218 _T("Software\\Microsoft\\Windows NT\\CurrentVersion"),
219 0,
220 KEY_ALL_ACCESS,
221 &hKey);
222 /* FIXME: check error code */
223
224 RegSetValueEx(hKey,
225 _T("RegisteredOwner"),
226 0,
227 REG_SZ,
228 OwnerName,
229 (_tcslen(OwnerName) + 1) * sizeof(TCHAR));
230 /* FIXME: check error code */
231
232 RegSetValueEx(hKey,
233 _T("RegisteredOrganization"),
234 0,
235 REG_SZ,
236 OwnerOrganization,
237 (_tcslen(OwnerOrganization) + 1) * sizeof(TCHAR));
238 /* FIXME: check error code */
239
240 RegCloseKey(hKey);
241 break;
242
243 default:
244 break;
245 }
246 }
247 break;
248
249 default:
250 break;
251 }
252
253 return FALSE;
254 }
255
256
257 INT_PTR CALLBACK
258 ComputerPageDlgProc(HWND hwndDlg,
259 UINT uMsg,
260 WPARAM wParam,
261 LPARAM lParam)
262 {
263 TCHAR ComputerName[MAX_COMPUTERNAME_LENGTH + 1];
264 TCHAR Password1[15];
265 TCHAR Password2[15];
266 DWORD Length;
267 LPNMHDR lpnm;
268
269 switch (uMsg)
270 {
271 case WM_INITDIALOG:
272 {
273 /* Retrieve current computer name */
274 Length = MAX_COMPUTERNAME_LENGTH + 1;
275 GetComputerName(ComputerName, &Length);
276
277 /* Display current computer name */
278 SetDlgItemText(hwndDlg, IDC_COMPUTERNAME, ComputerName);
279
280 /* Set text limits */
281 SendDlgItemMessage(hwndDlg, IDC_COMPUTERNAME, EM_LIMITTEXT, 64, 0);
282 SendDlgItemMessage(hwndDlg, IDC_ADMINPASSWORD1, EM_LIMITTEXT, 14, 0);
283 SendDlgItemMessage(hwndDlg, IDC_ADMINPASSWORD2, EM_LIMITTEXT, 14, 0);
284
285 /* Set focus to computer name */
286 SetFocus(GetDlgItem(hwndDlg, IDC_COMPUTERNAME));
287 }
288 break;
289
290
291 case WM_NOTIFY:
292 {
293 lpnm = (LPNMHDR)lParam;
294
295 switch (lpnm->code)
296 {
297 case PSN_SETACTIVE:
298 /* Enable the Back and Next buttons */
299 PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK | PSWIZB_NEXT);
300 break;
301
302 case PSN_WIZNEXT:
303 if (GetDlgItemText(hwndDlg, IDC_COMPUTERNAME, ComputerName, 64) == 0)
304 {
305 MessageBox(hwndDlg,
306 _T("Setup cannot continue until you enter the name of your computer."),
307 _T("ReactOS Setup"),
308 MB_ICONERROR | MB_OK);
309 SetWindowLong(hwndDlg, DWL_MSGRESULT, -1);
310 return TRUE;
311 }
312
313 /* FIXME: check computer name for invalid characters */
314
315 if (!SetComputerName(ComputerName))
316 {
317 MessageBox(hwndDlg,
318 _T("Setup failed to set the computer name."),
319 _T("ReactOS Setup"),
320 MB_ICONERROR | MB_OK);
321 SetWindowLong(hwndDlg, DWL_MSGRESULT, -1);
322 return TRUE;
323 }
324
325 /* Check admin passwords */
326 GetDlgItemText(hwndDlg, IDC_ADMINPASSWORD1, Password1, 15);
327 GetDlgItemText(hwndDlg, IDC_ADMINPASSWORD2, Password2, 15);
328 if (_tcscmp(Password1, Password2))
329 {
330 MessageBox(hwndDlg,
331 _T("The passwords you entered do not match. Please enter "\
332 "the desired password again."),
333 _T("ReactOS Setup"),
334 MB_ICONERROR | MB_OK);
335 SetWindowLong(hwndDlg, DWL_MSGRESULT, -1);
336 return TRUE;
337 }
338
339 /* FIXME: check password for invalid characters */
340
341 /* FIXME: Set admin password */
342 break;
343
344 default:
345 break;
346 }
347 }
348 break;
349
350 default:
351 break;
352 }
353
354 return FALSE;
355 }
356
357
358 static VOID
359 SetKeyboardLayoutName(HWND hwnd)
360 {
361 #if 0
362 WCHAR szLayoutPath[256];
363 WCHAR szLocaleName[32];
364 DWORD dwLocaleSize;
365 HKEY hKey;
366
367 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,
368 L"SYSTEM\\CurrentControlSet\\Control\\NLS\\Locale",
369 0,
370 KEY_ALL_ACCESS,
371 &hKey))
372 return;
373
374 dwValueSize = 16 * sizeof(WCHAR);
375 if (RegQueryValueExW(hKey,
376 NULL,
377 NULL,
378 NULL,
379 szLocaleName,
380 &dwLocaleSize))
381 {
382 RegCloseKey(hKey);
383 return;
384 }
385
386 wcscpy(szLayoutPath,
387 L"SYSTEM\\CurrentControlSet\\Control\\KeyboardLayouts\\"
388 wcscat(szLayoutPath,
389 szLocaleName);
390
391 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,
392 szLayoutPath,
393 0,
394 KEY_ALL_ACCESS,
395 &hKey))
396 return;
397
398 dwValueSize = 32 * sizeof(WCHAR);
399 if (RegQueryValueExW(hKey,
400 L"Layout Text",
401 NULL,
402 NULL,
403 szLocaleName,
404 &dwLocaleSize))
405 {
406 RegCloseKey(hKey);
407 return;
408 }
409
410 RegCloseKey(hKey);
411 #endif
412 }
413
414 static VOID
415 RunLocalePage(VOID)
416 {
417 PROPSHEETPAGE psp;
418 PROPSHEETHEADER psh;
419 HMODULE hDll;
420 // TCHAR Caption[256];
421
422 hDll = LoadLibraryW(L"intl.cpl");
423
424 ZeroMemory(&psp, sizeof(PROPSHEETPAGE));
425 psp.dwSize = sizeof(PROPSHEETPAGE);
426 psp.dwFlags = PSP_DEFAULT;
427 psp.hInstance = hDll;
428 psp.pszTemplate = MAKEINTRESOURCE(IDD_LOCALEPAGE);
429 psp.pfnDlgProc = GetProcAddress(hDll, "LocalePageProc");
430
431
432 // LoadString(hDll, IDS_CPLNAME, Caption, sizeof(Caption) / sizeof(TCHAR));
433
434 ZeroMemory(&psh, sizeof(PROPSHEETHEADER));
435 psh.dwSize = sizeof(PROPSHEETHEADER);
436 psh.dwFlags = PSH_PROPSHEETPAGE; // | PSH_PROPTITLE;
437 psh.hwndParent = NULL;
438 psh.hInstance = hDll;
439 // psh.hIcon = LoadIcon(hApplet, MAKEINTRESOURCE(IDC_CPLICON));
440 // psh.pszCaption = Caption;
441 psh.nPages = 1;
442 psh.nStartPage = 0;
443 psh.ppsp = &psp;
444
445 PropertySheet(&psh);
446
447 FreeLibrary(hDll);
448 }
449
450
451 INT_PTR CALLBACK
452 LocalePageDlgProc(HWND hwndDlg,
453 UINT uMsg,
454 WPARAM wParam,
455 LPARAM lParam)
456 {
457 PSETUPDATA SetupData;
458
459 /* Retrieve pointer to the global setup data */
460 SetupData = (PSETUPDATA)GetWindowLongPtr (hwndDlg, GWL_USERDATA);
461
462 switch (uMsg)
463 {
464 case WM_INITDIALOG:
465 {
466 /* Save pointer to the global setup data */
467 SetupData = (PSETUPDATA)((LPPROPSHEETPAGE)lParam)->lParam;
468 SetWindowLongPtr(hwndDlg, GWL_USERDATA, (DWORD_PTR)SetupData);
469
470
471 SetKeyboardLayoutName(GetDlgItem(hwndDlg, IDC_LAYOUTTEXT));
472
473 }
474 break;
475
476 case WM_COMMAND:
477 if (HIWORD(wParam) == BN_CLICKED)
478 {
479 switch (LOWORD(wParam))
480 {
481 case IDC_CUSTOMLOCALE:
482 {
483 RunLocalePage();
484 }
485 break;
486 }
487 }
488 break;
489
490 case WM_NOTIFY:
491 {
492 LPNMHDR lpnm = (LPNMHDR)lParam;
493
494 switch (lpnm->code)
495 {
496 case PSN_SETACTIVE:
497 /* Enable the Back and Next buttons */
498 PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK | PSWIZB_NEXT);
499 break;
500
501 case PSN_WIZNEXT:
502 break;
503
504 default:
505 break;
506 }
507 }
508 break;
509
510 default:
511 break;
512 }
513
514 return FALSE;
515 }
516
517
518 static PTIMEZONE_ENTRY
519 GetLargerTimeZoneEntry(PSETUPDATA SetupData, DWORD Index)
520 {
521 PTIMEZONE_ENTRY Entry;
522
523 Entry = SetupData->TimeZoneListHead;
524 while (Entry != NULL)
525 {
526 if (Entry->Index >= Index)
527 return Entry;
528
529 Entry = Entry->Next;
530 }
531
532 return NULL;
533 }
534
535
536 static VOID
537 CreateTimeZoneList(PSETUPDATA SetupData)
538 {
539 WCHAR szKeyName[256];
540 DWORD dwIndex;
541 DWORD dwNameSize;
542 DWORD dwValueSize;
543 LONG lError;
544 HKEY hZonesKey;
545 HKEY hZoneKey;
546
547 PTIMEZONE_ENTRY Entry;
548 PTIMEZONE_ENTRY Current;
549
550 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,
551 L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones",
552 0,
553 KEY_ALL_ACCESS,
554 &hZonesKey))
555 return;
556
557 dwIndex = 0;
558 while (TRUE)
559 {
560 dwNameSize = 256;
561 lError = RegEnumKeyExW(hZonesKey,
562 dwIndex,
563 szKeyName,
564 &dwNameSize,
565 NULL,
566 NULL,
567 NULL,
568 NULL);
569 if (lError != ERROR_SUCCESS && lError != ERROR_MORE_DATA)
570 break;
571
572 if (RegOpenKeyExW(hZonesKey,
573 szKeyName,
574 0,
575 KEY_ALL_ACCESS,
576 &hZoneKey))
577 break;
578
579 Entry = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(TIMEZONE_ENTRY));
580 if (Entry == NULL)
581 {
582 RegCloseKey(hZoneKey);
583 break;
584 }
585
586 dwValueSize = 64 * sizeof(WCHAR);
587 if (RegQueryValueExW(hZoneKey,
588 L"Display",
589 NULL,
590 NULL,
591 (LPBYTE)&Entry->Description,
592 &dwValueSize))
593 {
594 RegCloseKey(hZoneKey);
595 break;
596 }
597
598 dwValueSize = 32 * sizeof(WCHAR);
599 if (RegQueryValueExW(hZoneKey,
600 L"Std",
601 NULL,
602 NULL,
603 (LPBYTE)&Entry->StandardName,
604 &dwValueSize))
605 {
606 RegCloseKey(hZoneKey);
607 break;
608 }
609
610 dwValueSize = 32 * sizeof(WCHAR);
611 if (RegQueryValueExW(hZoneKey,
612 L"Dlt",
613 NULL,
614 NULL,
615 (LPBYTE)&Entry->DaylightName,
616 &dwValueSize))
617 {
618 RegCloseKey(hZoneKey);
619 break;
620 }
621
622 dwValueSize = sizeof(DWORD);
623 if (RegQueryValueExW(hZoneKey,
624 L"Index",
625 NULL,
626 NULL,
627 (LPBYTE)&Entry->Index,
628 &dwValueSize))
629 {
630 RegCloseKey(hZoneKey);
631 break;
632 }
633
634 dwValueSize = sizeof(TZ_INFO);
635 if (RegQueryValueExW(hZoneKey,
636 L"TZI",
637 NULL,
638 NULL,
639 (LPBYTE)&Entry->TimezoneInfo,
640 &dwValueSize))
641 {
642 RegCloseKey(hZoneKey);
643 break;
644 }
645
646 RegCloseKey(hZoneKey);
647
648 if (SetupData->TimeZoneListHead == NULL &&
649 SetupData->TimeZoneListTail == NULL)
650 {
651 Entry->Prev = NULL;
652 Entry->Next = NULL;
653 SetupData->TimeZoneListHead = Entry;
654 SetupData->TimeZoneListTail = Entry;
655 }
656 else
657 {
658 Current = GetLargerTimeZoneEntry(SetupData, Entry->Index);
659 if (Current != NULL)
660 {
661 if (Current == SetupData->TimeZoneListHead)
662 {
663 /* Prepend to head */
664 Entry->Prev = NULL;
665 Entry->Next = SetupData->TimeZoneListHead;
666 SetupData->TimeZoneListHead->Prev = Entry;
667 SetupData->TimeZoneListHead = Entry;
668 }
669 else
670 {
671 /* Insert before current */
672 Entry->Prev = Current->Prev;
673 Entry->Next = Current;
674 Current->Prev->Next = Entry;
675 Current->Prev = Entry;
676 }
677 }
678 else
679 {
680 /* Append to tail */
681 Entry->Prev = SetupData->TimeZoneListTail;
682 Entry->Next = NULL;
683 SetupData->TimeZoneListTail->Next = Entry;
684 SetupData->TimeZoneListTail = Entry;
685 }
686 }
687
688 dwIndex++;
689 }
690
691 RegCloseKey(hZonesKey);
692 }
693
694
695 static VOID
696 DestroyTimeZoneList(PSETUPDATA SetupData)
697 {
698 PTIMEZONE_ENTRY Entry;
699
700 while (SetupData->TimeZoneListHead != NULL)
701 {
702 Entry = SetupData->TimeZoneListHead;
703
704 SetupData->TimeZoneListHead = Entry->Next;
705 if (SetupData->TimeZoneListHead != NULL)
706 {
707 SetupData->TimeZoneListHead->Prev = NULL;
708 }
709
710 HeapFree(GetProcessHeap(), 0, Entry);
711 }
712
713 SetupData->TimeZoneListTail = NULL;
714 }
715
716
717 static VOID
718 ShowTimeZoneList(HWND hwnd, PSETUPDATA SetupData)
719 {
720 PTIMEZONE_ENTRY Entry;
721
722 Entry = SetupData->TimeZoneListHead;
723 while (Entry != NULL)
724 {
725 SendMessageW(hwnd,
726 CB_ADDSTRING,
727 0,
728 (LPARAM)Entry->Description);
729
730
731 Entry = Entry->Next;
732 }
733
734 SendMessageW(hwnd,
735 CB_SETCURSEL,
736 (WPARAM)0, // index
737 0);
738 }
739
740
741 static VOID
742 SetLocalTimeZone(HWND hwnd, PSETUPDATA SetupData)
743 {
744 TIME_ZONE_INFORMATION TimeZoneInformation;
745 PTIMEZONE_ENTRY Entry;
746 DWORD dwIndex;
747 DWORD i;
748
749 dwIndex = SendMessage(hwnd,
750 CB_GETCURSEL,
751 0,
752 0);
753
754 i = 0;
755 Entry = SetupData->TimeZoneListHead;
756 while (i < dwIndex)
757 {
758 if (Entry == NULL)
759 return;
760
761 i++;
762 Entry = Entry->Next;
763 }
764
765 wcscpy(TimeZoneInformation.StandardName,
766 Entry->StandardName);
767 wcscpy(TimeZoneInformation.DaylightName,
768 Entry->DaylightName);
769
770 TimeZoneInformation.Bias = Entry->TimezoneInfo.Bias;
771 TimeZoneInformation.StandardBias = Entry->TimezoneInfo.StandardBias;
772 TimeZoneInformation.DaylightBias = Entry->TimezoneInfo.DaylightBias;
773
774 memcpy(&TimeZoneInformation.StandardDate,
775 &Entry->TimezoneInfo.StandardDate,
776 sizeof(SYSTEMTIME));
777 memcpy(&TimeZoneInformation.DaylightDate,
778 &Entry->TimezoneInfo.DaylightDate,
779 sizeof(SYSTEMTIME));
780
781 /* Set time zone information */
782 SetTimeZoneInformation(&TimeZoneInformation);
783 }
784
785
786 static BOOL
787 GetLocalSystemTime(HWND hwnd, PSETUPDATA SetupData)
788 {
789 SYSTEMTIME Date;
790 SYSTEMTIME Time;
791
792 if (DateTime_GetSystemTime(GetDlgItem(hwnd, IDC_DATEPICKER), &Date) != GDT_VALID)
793 {
794 return FALSE;
795 }
796
797 if (DateTime_GetSystemTime(GetDlgItem(hwnd, IDC_TIMEPICKER), &Time) != GDT_VALID)
798 {
799 return FALSE;
800 }
801
802 SetupData->SystemTime.wYear = Date.wYear;
803 SetupData->SystemTime.wMonth = Date.wMonth;
804 SetupData->SystemTime.wDayOfWeek = Date.wDayOfWeek;
805 SetupData->SystemTime.wDay = Date.wDay;
806 SetupData->SystemTime.wHour = Time.wHour;
807 SetupData->SystemTime.wMinute = Time.wMinute;
808 SetupData->SystemTime.wSecond = Time.wSecond;
809 SetupData->SystemTime.wMilliseconds = Time.wMilliseconds;
810
811 return TRUE;
812 }
813
814
815 static VOID
816 SetAutoDaylightInfo(HWND hwnd)
817 {
818 HKEY hKey;
819 DWORD dwValue = 1;
820
821 if (SendMessage(hwnd, BM_GETCHECK, 0, 0) == BST_UNCHECKED)
822 {
823 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,
824 L"SYSTEM\\CurrentControlSet\\Control\\TimeZoneInformation",
825 0,
826 KEY_SET_VALUE,
827 &hKey))
828 return;
829
830 RegSetValueExW(hKey,
831 L"DisableAutoDaylightTimeSet",
832 0,
833 REG_DWORD,
834 (LPBYTE)&dwValue,
835 sizeof(DWORD));
836 RegCloseKey(hKey);
837 }
838 }
839
840
841 INT_PTR CALLBACK
842 DateTimePageDlgProc(HWND hwndDlg,
843 UINT uMsg,
844 WPARAM wParam,
845 LPARAM lParam)
846 {
847 PSETUPDATA SetupData;
848
849 /* Retrieve pointer to the global setup data */
850 SetupData = (PSETUPDATA)GetWindowLongPtr (hwndDlg, GWL_USERDATA);
851
852 switch (uMsg)
853 {
854 case WM_INITDIALOG:
855 {
856 /* Save pointer to the global setup data */
857 SetupData = (PSETUPDATA)((LPPROPSHEETPAGE)lParam)->lParam;
858 SetWindowLongPtr(hwndDlg, GWL_USERDATA, (DWORD_PTR)SetupData);
859
860 CreateTimeZoneList(SetupData);
861
862 ShowTimeZoneList(GetDlgItem(hwndDlg, IDC_TIMEZONELIST),
863 SetupData);
864
865 SendDlgItemMessage(hwndDlg, IDC_AUTODAYLIGHT, BM_SETCHECK, (WPARAM)BST_CHECKED, 0);
866 }
867 break;
868
869
870 case WM_NOTIFY:
871 {
872 LPNMHDR lpnm = (LPNMHDR)lParam;
873
874 switch (lpnm->code)
875 {
876 case PSN_SETACTIVE:
877 /* Enable the Back and Next buttons */
878 PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK | PSWIZB_NEXT);
879 break;
880
881 case PSN_WIZNEXT:
882 {
883 GetLocalSystemTime(hwndDlg, SetupData);
884 SetLocalTimeZone(GetDlgItem(hwndDlg, IDC_TIMEZONELIST),
885 SetupData);
886 SetAutoDaylightInfo(GetDlgItem(hwndDlg, IDC_AUTODAYLIGHT));
887 SetLocalTime(&SetupData->SystemTime);
888 }
889 break;
890
891 default:
892 break;
893 }
894 }
895 break;
896
897 case WM_DESTROY:
898 DestroyTimeZoneList(SetupData);
899 break;
900
901 default:
902 break;
903 }
904
905 return FALSE;
906 }
907
908
909 INT_PTR CALLBACK
910 ProcessPageDlgProc(HWND hwndDlg,
911 UINT uMsg,
912 WPARAM wParam,
913 LPARAM lParam)
914 {
915 PSETUPDATA SetupData;
916
917 /* Retrieve pointer to the global setup data */
918 SetupData = (PSETUPDATA)GetWindowLongPtr (hwndDlg, GWL_USERDATA);
919
920 switch (uMsg)
921 {
922 case WM_INITDIALOG:
923 {
924 /* Save pointer to the global setup data */
925 SetupData = (PSETUPDATA)((LPPROPSHEETPAGE)lParam)->lParam;
926 SetWindowLongPtr(hwndDlg, GWL_USERDATA, (DWORD_PTR)SetupData);
927 }
928 break;
929
930 case WM_TIMER:
931 {
932 INT Position;
933 HWND hWndProgress;
934
935 hWndProgress = GetDlgItem(hwndDlg, IDC_PROCESSPROGRESS);
936 Position = SendMessage(hWndProgress, PBM_GETPOS, 0, 0);
937 if (Position == 300)
938 {
939 PropSheet_PressButton(GetParent(hwndDlg), PSBTN_NEXT);
940 }
941 else
942 {
943 SendMessage(hWndProgress, PBM_SETPOS, Position + 1, 0);
944 }
945 }
946 return TRUE;
947
948 case WM_NOTIFY:
949 {
950 LPNMHDR lpnm = (LPNMHDR)lParam;
951
952 switch (lpnm->code)
953 {
954 case PSN_SETACTIVE:
955 /* Disable the Back and Next buttons */
956 PropSheet_SetWizButtons(GetParent(hwndDlg), 0);
957
958 SendDlgItemMessage(hwndDlg, IDC_PROCESSPROGRESS, PBM_SETRANGE, 0,
959 MAKELPARAM(0, 300));
960 SetTimer(hwndDlg, 0, 50, NULL);
961 break;
962
963 case PSN_WIZNEXT:
964
965 /* Enable the Back and Next buttons */
966 PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK | PSWIZB_NEXT);
967 break;
968
969 default:
970 break;
971 }
972 }
973 break;
974
975 default:
976 break;
977 }
978
979 return FALSE;
980 }
981
982
983
984 INT_PTR CALLBACK
985 FinishDlgProc(HWND hwndDlg,
986 UINT uMsg,
987 WPARAM wParam,
988 LPARAM lParam)
989 {
990
991 switch (uMsg)
992 {
993 case WM_INITDIALOG:
994 {
995 PSETUPDATA SetupData;
996
997 /* Get pointer to the global setup data */
998 SetupData = (PSETUPDATA)((LPPROPSHEETPAGE)lParam)->lParam;
999
1000 /* Set title font */
1001 SendDlgItemMessage(hwndDlg,
1002 IDC_FINISHTITLE,
1003 WM_SETFONT,
1004 (WPARAM)SetupData->hTitleFont,
1005 (LPARAM)TRUE);
1006 }
1007 break;
1008
1009 case WM_NOTIFY:
1010 {
1011 LPNMHDR lpnm = (LPNMHDR)lParam;
1012
1013 switch (lpnm->code)
1014 {
1015 case PSN_SETACTIVE:
1016 /* Enable the correct buttons on for the active page */
1017 PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK | PSWIZB_FINISH);
1018 break;
1019
1020 case PSN_WIZBACK:
1021 /* Handle a Back button click, if necessary */
1022 break;
1023
1024 case PSN_WIZFINISH:
1025 /* Handle a Finish button click, if necessary */
1026 break;
1027
1028 default:
1029 break;
1030 }
1031 }
1032 break;
1033
1034 default:
1035 break;
1036 }
1037
1038 return FALSE;
1039 }
1040
1041
1042 VOID
1043 InstallWizard(VOID)
1044 {
1045 PROPSHEETHEADER psh;
1046 HPROPSHEETPAGE ahpsp[6];
1047 PROPSHEETPAGE psp;
1048
1049 /* Clear setup data */
1050 ZeroMemory(&SetupData, sizeof(SETUPDATA));
1051
1052 /* Create the Welcome page */
1053 ZeroMemory (&psp, sizeof(PROPSHEETPAGE));
1054 psp.dwSize = sizeof(PROPSHEETPAGE);
1055 psp.dwFlags = PSP_DEFAULT | PSP_HIDEHEADER;
1056 psp.hInstance = hDllInstance;
1057 psp.lParam = (LPARAM)&SetupData;
1058 psp.pfnDlgProc = WelcomeDlgProc;
1059 psp.pszTemplate = MAKEINTRESOURCE(IDD_WELCOMEPAGE);
1060 ahpsp[0] = CreatePropertySheetPage(&psp);
1061
1062 /* Create the Owner page */
1063 psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
1064 psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_OWNERTITLE);
1065 psp.pszHeaderSubTitle = MAKEINTRESOURCE(IDS_OWNERSUBTITLE);
1066 psp.pszTemplate = MAKEINTRESOURCE(IDD_OWNERPAGE);
1067 psp.pfnDlgProc = OwnerPageDlgProc;
1068 ahpsp[1] = CreatePropertySheetPage(&psp);
1069
1070 /* Create the Computer page */
1071 psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
1072 psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_COMPUTERTITLE);
1073 psp.pszHeaderSubTitle = MAKEINTRESOURCE(IDS_COMPUTERSUBTITLE);
1074 psp.pfnDlgProc = ComputerPageDlgProc;
1075 psp.pszTemplate = MAKEINTRESOURCE(IDD_COMPUTERPAGE);
1076 ahpsp[2] = CreatePropertySheetPage(&psp);
1077
1078
1079 /* Create the Locale page */
1080 psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
1081 psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_LOCALETITLE);
1082 psp.pszHeaderSubTitle = MAKEINTRESOURCE(IDS_LOCALESUBTITLE);
1083 psp.pfnDlgProc = LocalePageDlgProc;
1084 psp.pszTemplate = MAKEINTRESOURCE(IDD_LOCALEPAGE);
1085 ahpsp[3] = CreatePropertySheetPage(&psp);
1086
1087
1088 /* Create the DateTime page */
1089 psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
1090 psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_DATETIMETITLE);
1091 psp.pszHeaderSubTitle = MAKEINTRESOURCE(IDS_DATETIMESUBTITLE);
1092 psp.pfnDlgProc = DateTimePageDlgProc;
1093 psp.pszTemplate = MAKEINTRESOURCE(IDD_DATETIMEPAGE);
1094 ahpsp[4] = CreatePropertySheetPage(&psp);
1095
1096
1097 /* Create the Process page */
1098 psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
1099 psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_PROCESSTITLE);
1100 psp.pszHeaderSubTitle = MAKEINTRESOURCE(IDS_PROCESSSUBTITLE);
1101 psp.pfnDlgProc = ProcessPageDlgProc;
1102 psp.pszTemplate = MAKEINTRESOURCE(IDD_PROCESSPAGE);
1103 ahpsp[5] = CreatePropertySheetPage(&psp);
1104
1105
1106 /* Create the Finish page */
1107 psp.dwFlags = PSP_DEFAULT | PSP_HIDEHEADER;
1108 psp.pfnDlgProc = FinishDlgProc;
1109 psp.pszTemplate = MAKEINTRESOURCE(IDD_FINISHPAGE);
1110 ahpsp[6] = CreatePropertySheetPage(&psp);
1111
1112 /* Create the property sheet */
1113 psh.dwSize = sizeof(PROPSHEETHEADER);
1114 psh.dwFlags = PSH_WIZARD97 | PSH_WATERMARK | PSH_HEADER;
1115 psh.hInstance = hDllInstance;
1116 psh.hwndParent = NULL;
1117 psh.nPages = 7;
1118 psh.nStartPage = 0;
1119 psh.phpage = ahpsp;
1120 psh.pszbmWatermark = MAKEINTRESOURCE(IDB_WATERMARK);
1121 psh.pszbmHeader = MAKEINTRESOURCE(IDB_HEADER);
1122
1123 /* Create title font */
1124 SetupData.hTitleFont = CreateTitleFont();
1125
1126 /* Display the wizard */
1127 PropertySheet(&psh);
1128
1129 DeleteObject(SetupData.hTitleFont);
1130 }
1131
1132 /* EOF */