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