xref: /reactos/dll/win32/syssetup/wizard.c (revision d4e38a63)
1c2c66affSColin Finck /*
2c2c66affSColin Finck  * COPYRIGHT:       See COPYING in the top level directory
3c2c66affSColin Finck  * PROJECT:         System setup
4c2c66affSColin Finck  * FILE:            dll/win32/syssetup/wizard.c
5c2c66affSColin Finck  * PURPOSE:         GUI controls
6c2c66affSColin Finck  * PROGRAMMERS:     Eric Kohl
7c2c66affSColin Finck  *                  Pierre Schweitzer <heis_spiter@hotmail.com>
8c2c66affSColin Finck  *                  Ismael Ferreras Morezuelas <swyterzone+ros@gmail.com>
9612729b0SKatayama Hirofumi MZ  *                  Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
105d81de7dSOleg Dubinskiy  *                  Oleg Dubinskiy <oleg.dubinskij30@gmail.com>
11c2c66affSColin Finck  */
12c2c66affSColin Finck 
13c2c66affSColin Finck /* INCLUDES *****************************************************************/
14c2c66affSColin Finck 
15c2c66affSColin Finck #include "precomp.h"
16c2c66affSColin Finck 
17c2c66affSColin Finck #include <stdlib.h>
18c2c66affSColin Finck #include <time.h>
19c2c66affSColin Finck #include <winnls.h>
20c2c66affSColin Finck #include <windowsx.h>
21c2c66affSColin Finck #include <wincon.h>
22c2c66affSColin Finck #include <shlobj.h>
237c3e96a2SHermès Bélusca-Maïto #include <tzlib.h>
24612729b0SKatayama Hirofumi MZ #include <strsafe.h>
257c3e96a2SHermès Bélusca-Maïto 
26c2c66affSColin Finck #define NDEBUG
27c2c66affSColin Finck #include <debug.h>
28c2c66affSColin Finck 
29c2c66affSColin Finck #define PM_REGISTRATION_NOTIFY (WM_APP + 1)
30c2c66affSColin Finck /* Private Message used to communicate progress from the background
31c2c66affSColin Finck    registration thread to the main thread.
32c2c66affSColin Finck    wParam = 0 Registration in progress
33c2c66affSColin Finck           = 1 Registration completed
34c2c66affSColin Finck    lParam = Pointer to a REGISTRATIONNOTIFY structure */
35c2c66affSColin Finck 
363f053db3SEric Kohl #define PM_ITEM_START (WM_APP + 2)
373f053db3SEric Kohl #define PM_ITEM_END   (WM_APP + 3)
383f053db3SEric Kohl #define PM_STEP_START (WM_APP + 4)
393f053db3SEric Kohl #define PM_STEP_END   (WM_APP + 5)
403f053db3SEric Kohl #define PM_ITEMS_DONE (WM_APP + 6)
413f053db3SEric Kohl 
42c2c66affSColin Finck typedef struct _REGISTRATIONNOTIFY
43c2c66affSColin Finck {
44c2c66affSColin Finck     ULONG Progress;
45c2c66affSColin Finck     UINT ActivityID;
46c2c66affSColin Finck     LPCWSTR CurrentItem;
47c2c66affSColin Finck     LPCWSTR ErrorMessage;
483f053db3SEric Kohl     UINT MessageID;
493f053db3SEric Kohl     DWORD LastError;
50c2c66affSColin Finck } REGISTRATIONNOTIFY, *PREGISTRATIONNOTIFY;
51c2c66affSColin Finck 
523f053db3SEric Kohl typedef struct _ITEMSDATA
533f053db3SEric Kohl {
543f053db3SEric Kohl     HWND hwndDlg;
553f053db3SEric Kohl } ITEMSDATA, *PITEMSDATA;
563f053db3SEric Kohl 
57c2c66affSColin Finck typedef struct _REGISTRATIONDATA
58c2c66affSColin Finck {
59c2c66affSColin Finck     HWND hwndDlg;
60c2c66affSColin Finck     ULONG DllCount;
61c2c66affSColin Finck     ULONG Registered;
62c2c66affSColin Finck     PVOID DefaultContext;
63c2c66affSColin Finck } REGISTRATIONDATA, *PREGISTRATIONDATA;
64c2c66affSColin Finck 
657c3e96a2SHermès Bélusca-Maïto typedef struct _TIMEZONE_ENTRY
667c3e96a2SHermès Bélusca-Maïto {
677c3e96a2SHermès Bélusca-Maïto     struct _TIMEZONE_ENTRY *Prev;
687c3e96a2SHermès Bélusca-Maïto     struct _TIMEZONE_ENTRY *Next;
697c3e96a2SHermès Bélusca-Maïto     WCHAR Description[128]; /* 'Display' */
707c3e96a2SHermès Bélusca-Maïto     WCHAR StandardName[32]; /* 'Std' */
717c3e96a2SHermès Bélusca-Maïto     WCHAR DaylightName[32]; /* 'Dlt' */
727c3e96a2SHermès Bélusca-Maïto     REG_TZI_FORMAT TimezoneInfo; /* 'TZI' */
737c3e96a2SHermès Bélusca-Maïto     ULONG Index;
747c3e96a2SHermès Bélusca-Maïto } TIMEZONE_ENTRY, *PTIMEZONE_ENTRY;
757c3e96a2SHermès Bélusca-Maïto 
76c2c66affSColin Finck 
77c2c66affSColin Finck /* FUNCTIONS ****************************************************************/
78c2c66affSColin Finck 
79c2c66affSColin Finck extern void WINAPI Control_RunDLLW(HWND hWnd, HINSTANCE hInst, LPCWSTR cmd, DWORD nCmdShow);
80c2c66affSColin Finck 
81c2c66affSColin Finck 
82c2c66affSColin Finck static VOID
83c2c66affSColin Finck CenterWindow(HWND hWnd)
84c2c66affSColin Finck {
85c2c66affSColin Finck     HWND hWndParent;
86c2c66affSColin Finck     RECT rcParent;
87c2c66affSColin Finck     RECT rcWindow;
88c2c66affSColin Finck 
89c2c66affSColin Finck     hWndParent = GetParent(hWnd);
90c2c66affSColin Finck     if (hWndParent == NULL)
91c2c66affSColin Finck         hWndParent = GetDesktopWindow();
92c2c66affSColin Finck 
93c2c66affSColin Finck     GetWindowRect(hWndParent, &rcParent);
94c2c66affSColin Finck     GetWindowRect(hWnd, &rcWindow);
95c2c66affSColin Finck 
96c2c66affSColin Finck     SetWindowPos(hWnd,
97c2c66affSColin Finck                  HWND_TOP,
98c2c66affSColin Finck                  ((rcParent.right - rcParent.left) - (rcWindow.right - rcWindow.left)) / 2,
99c2c66affSColin Finck                  ((rcParent.bottom - rcParent.top) - (rcWindow.bottom - rcWindow.top)) / 2,
100c2c66affSColin Finck                  0,
101c2c66affSColin Finck                  0,
102c2c66affSColin Finck                  SWP_NOSIZE);
103c2c66affSColin Finck }
104c2c66affSColin Finck 
105c2c66affSColin Finck 
106c2c66affSColin Finck static HFONT
107c2c66affSColin Finck CreateTitleFont(VOID)
108c2c66affSColin Finck {
109c2c66affSColin Finck     LOGFONTW LogFont = {0};
110c2c66affSColin Finck     HDC hdc;
111c2c66affSColin Finck     HFONT hFont;
112c2c66affSColin Finck 
1135972b1e2SKatayama Hirofumi MZ     LogFont.lfWeight = FW_BOLD;
114c2c66affSColin Finck     wcscpy(LogFont.lfFaceName, L"MS Shell Dlg");
115c2c66affSColin Finck 
116c2c66affSColin Finck     hdc = GetDC(NULL);
117c2c66affSColin Finck     LogFont.lfHeight = -MulDiv(12, GetDeviceCaps(hdc, LOGPIXELSY), 72);
118c2c66affSColin Finck 
119c2c66affSColin Finck     hFont = CreateFontIndirectW(&LogFont);
120c2c66affSColin Finck 
121c2c66affSColin Finck     ReleaseDC(NULL, hdc);
122c2c66affSColin Finck 
123c2c66affSColin Finck     return hFont;
124c2c66affSColin Finck }
125c2c66affSColin Finck 
126c2c66affSColin Finck 
127c2c66affSColin Finck static HFONT
128c2c66affSColin Finck CreateBoldFont(VOID)
129c2c66affSColin Finck {
130c2c66affSColin Finck     LOGFONTW tmpFont = {0};
131c2c66affSColin Finck     HFONT hBoldFont;
132c2c66affSColin Finck     HDC hDc;
133c2c66affSColin Finck 
134c2c66affSColin Finck     /* Grabs the Drawing Context */
135c2c66affSColin Finck     hDc = GetDC(NULL);
136c2c66affSColin Finck 
137c2c66affSColin Finck     tmpFont.lfHeight = -MulDiv(8, GetDeviceCaps(hDc, LOGPIXELSY), 72);
138836e3107SKatayama Hirofumi MZ     tmpFont.lfWeight = FW_BOLD;
139c2c66affSColin Finck     wcscpy(tmpFont.lfFaceName, L"MS Shell Dlg");
140c2c66affSColin Finck 
141c2c66affSColin Finck     hBoldFont = CreateFontIndirectW(&tmpFont);
142c2c66affSColin Finck 
143c2c66affSColin Finck     ReleaseDC(NULL, hDc);
144c2c66affSColin Finck 
145c2c66affSColin Finck     return hBoldFont;
146c2c66affSColin Finck }
147c2c66affSColin Finck 
148c2c66affSColin Finck static INT_PTR CALLBACK
149c2c66affSColin Finck GplDlgProc(HWND hwndDlg,
150c2c66affSColin Finck            UINT uMsg,
151c2c66affSColin Finck            WPARAM wParam,
152c2c66affSColin Finck            LPARAM lParam)
153c2c66affSColin Finck {
154c2c66affSColin Finck     HRSRC GplTextResource;
155c2c66affSColin Finck     HGLOBAL GplTextMem;
156c2c66affSColin Finck     PVOID GplTextLocked;
157c2c66affSColin Finck     PCHAR GplText;
158c2c66affSColin Finck     DWORD Size;
159c2c66affSColin Finck 
160c2c66affSColin Finck 
161c2c66affSColin Finck     switch (uMsg)
162c2c66affSColin Finck     {
163c2c66affSColin Finck         case WM_INITDIALOG:
164c2c66affSColin Finck             GplTextResource = FindResourceW(hDllInstance, MAKEINTRESOURCE(IDR_GPL), L"RT_TEXT");
165c2c66affSColin Finck             if (NULL == GplTextResource)
166c2c66affSColin Finck             {
167c2c66affSColin Finck                 break;
168c2c66affSColin Finck             }
169c2c66affSColin Finck             Size = SizeofResource(hDllInstance, GplTextResource);
170c2c66affSColin Finck             if (0 == Size)
171c2c66affSColin Finck             {
172c2c66affSColin Finck                 break;
173c2c66affSColin Finck             }
174c2c66affSColin Finck             GplText = HeapAlloc(GetProcessHeap(), 0, Size + 1);
175c2c66affSColin Finck             if (NULL == GplText)
176c2c66affSColin Finck             {
177c2c66affSColin Finck                 break;
178c2c66affSColin Finck             }
179c2c66affSColin Finck             GplTextMem = LoadResource(hDllInstance, GplTextResource);
180c2c66affSColin Finck             if (NULL == GplTextMem)
181c2c66affSColin Finck             {
182c2c66affSColin Finck                 HeapFree(GetProcessHeap(), 0, GplText);
183c2c66affSColin Finck                 break;
184c2c66affSColin Finck             }
185c2c66affSColin Finck             GplTextLocked = LockResource(GplTextMem);
186c2c66affSColin Finck             if (NULL == GplTextLocked)
187c2c66affSColin Finck             {
188c2c66affSColin Finck                 HeapFree(GetProcessHeap(), 0, GplText);
189c2c66affSColin Finck                 break;
190c2c66affSColin Finck             }
191c2c66affSColin Finck             memcpy(GplText, GplTextLocked, Size);
192c2c66affSColin Finck             GplText[Size] = '\0';
193c2c66affSColin Finck             SendMessageA(GetDlgItem(hwndDlg, IDC_GPL_TEXT), WM_SETTEXT, 0, (LPARAM) GplText);
194c2c66affSColin Finck             HeapFree(GetProcessHeap(), 0, GplText);
195c2c66affSColin Finck             SetFocus(GetDlgItem(hwndDlg, IDOK));
196c2c66affSColin Finck             return FALSE;
197c2c66affSColin Finck 
198c2c66affSColin Finck         case WM_CLOSE:
199c2c66affSColin Finck             EndDialog(hwndDlg, IDCANCEL);
200c2c66affSColin Finck             break;
201c2c66affSColin Finck 
202c2c66affSColin Finck         case WM_COMMAND:
203c2c66affSColin Finck             if (HIWORD(wParam) == BN_CLICKED && IDOK == LOWORD(wParam))
204c2c66affSColin Finck             {
205c2c66affSColin Finck                 EndDialog(hwndDlg, IDOK);
206c2c66affSColin Finck             }
207c2c66affSColin Finck             break;
208c2c66affSColin Finck 
209c2c66affSColin Finck         default:
210c2c66affSColin Finck             break;
211c2c66affSColin Finck     }
212c2c66affSColin Finck 
213c2c66affSColin Finck     return FALSE;
214c2c66affSColin Finck }
215c2c66affSColin Finck 
216c2c66affSColin Finck 
217c2c66affSColin Finck static INT_PTR CALLBACK
218c2c66affSColin Finck WelcomeDlgProc(HWND hwndDlg,
219c2c66affSColin Finck                UINT uMsg,
220c2c66affSColin Finck                WPARAM wParam,
221c2c66affSColin Finck                LPARAM lParam)
222c2c66affSColin Finck {
223c2c66affSColin Finck     PSETUPDATA pSetupData;
224c2c66affSColin Finck 
225c2c66affSColin Finck     pSetupData = (PSETUPDATA)GetWindowLongPtr(hwndDlg, DWLP_USER);
226c2c66affSColin Finck 
227c2c66affSColin Finck     switch (uMsg)
228c2c66affSColin Finck     {
229c2c66affSColin Finck         case WM_INITDIALOG:
230c2c66affSColin Finck         {
231c2c66affSColin Finck             HWND hwndControl;
232c2c66affSColin Finck             DWORD dwStyle;
233c2c66affSColin Finck 
234c2c66affSColin Finck             /* Get pointer to the global setup data */
235c2c66affSColin Finck             pSetupData = (PSETUPDATA)((LPPROPSHEETPAGE)lParam)->lParam;
236c2c66affSColin Finck             SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pSetupData);
237c2c66affSColin Finck 
238c2c66affSColin Finck             hwndControl = GetParent(hwndDlg);
239c2c66affSColin Finck 
240c2c66affSColin Finck             /* Center the wizard window */
241c2c66affSColin Finck             CenterWindow (hwndControl);
242c2c66affSColin Finck 
243c2c66affSColin Finck             /* Hide the system menu */
244c2c66affSColin Finck             dwStyle = GetWindowLongPtr(hwndControl, GWL_STYLE);
245c2c66affSColin Finck             SetWindowLongPtr(hwndControl, GWL_STYLE, dwStyle & ~WS_SYSMENU);
246c2c66affSColin Finck 
247c2c66affSColin Finck             /* Hide and disable the 'Cancel' button */
248c2c66affSColin Finck             hwndControl = GetDlgItem(GetParent(hwndDlg), IDCANCEL);
249c2c66affSColin Finck             ShowWindow (hwndControl, SW_HIDE);
250c2c66affSColin Finck             EnableWindow (hwndControl, FALSE);
251c2c66affSColin Finck 
252c2c66affSColin Finck             /* Set title font */
253c2c66affSColin Finck             SendDlgItemMessage(hwndDlg,
254c2c66affSColin Finck                                IDC_WELCOMETITLE,
255c2c66affSColin Finck                                WM_SETFONT,
256c2c66affSColin Finck                                (WPARAM)pSetupData->hTitleFont,
257c2c66affSColin Finck                                (LPARAM)TRUE);
258c2c66affSColin Finck         }
259c2c66affSColin Finck         break;
260c2c66affSColin Finck 
261c2c66affSColin Finck 
262c2c66affSColin Finck         case WM_NOTIFY:
263c2c66affSColin Finck         {
264c2c66affSColin Finck             LPNMHDR lpnm = (LPNMHDR)lParam;
265c2c66affSColin Finck 
266c2c66affSColin Finck             switch (lpnm->code)
267c2c66affSColin Finck             {
268c2c66affSColin Finck                 case PSN_SETACTIVE:
269c2c66affSColin Finck                     LogItem(L"BEGIN", L"WelcomePage");
270c2c66affSColin Finck                     /* Enable the Next button */
271c2c66affSColin Finck                     PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT);
272c2c66affSColin Finck                     if (pSetupData->UnattendSetup)
273c2c66affSColin Finck                     {
2740182dcd7STimo Kreuzer                         SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_ACKPAGE);
275c2c66affSColin Finck                         return TRUE;
276c2c66affSColin Finck                     }
277c2c66affSColin Finck                     break;
278c2c66affSColin Finck 
279c2c66affSColin Finck                 case PSN_WIZNEXT:
280c2c66affSColin Finck                     LogItem(L"END", L"WelcomePage");
281c2c66affSColin Finck                     break;
282c2c66affSColin Finck 
283c2c66affSColin Finck                 case PSN_WIZBACK:
284c2c66affSColin Finck                     pSetupData->UnattendSetup = FALSE;
285c2c66affSColin Finck                     break;
286c2c66affSColin Finck 
287c2c66affSColin Finck                 default:
288c2c66affSColin Finck                     break;
289c2c66affSColin Finck             }
290c2c66affSColin Finck         }
291c2c66affSColin Finck         break;
292c2c66affSColin Finck 
293c2c66affSColin Finck         default:
294c2c66affSColin Finck             break;
295c2c66affSColin Finck     }
296c2c66affSColin Finck 
297c2c66affSColin Finck     return FALSE;
298c2c66affSColin Finck }
299c2c66affSColin Finck 
300c2c66affSColin Finck 
301c2c66affSColin Finck static INT_PTR CALLBACK
302c2c66affSColin Finck AckPageDlgProc(HWND hwndDlg,
303c2c66affSColin Finck                UINT uMsg,
304c2c66affSColin Finck                WPARAM wParam,
305c2c66affSColin Finck                LPARAM lParam)
306c2c66affSColin Finck {
307c2c66affSColin Finck     LPNMHDR lpnm;
308c2c66affSColin Finck     PWCHAR Projects;
309c2c66affSColin Finck     PWCHAR End, CurrentProject;
310c2c66affSColin Finck     INT ProjectsSize, ProjectsCount;
311c2c66affSColin Finck     PSETUPDATA pSetupData;
312c2c66affSColin Finck 
313c2c66affSColin Finck     pSetupData = (PSETUPDATA)GetWindowLongPtr(hwndDlg, DWLP_USER);
314c2c66affSColin Finck 
315c2c66affSColin Finck     switch (uMsg)
316c2c66affSColin Finck     {
317c2c66affSColin Finck         case WM_INITDIALOG:
318c2c66affSColin Finck         {
319c2c66affSColin Finck             pSetupData = (PSETUPDATA)((LPPROPSHEETPAGE)lParam)->lParam;
320c2c66affSColin Finck             SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pSetupData);
321c2c66affSColin Finck 
322c2c66affSColin Finck             Projects = NULL;
323c2c66affSColin Finck             ProjectsSize = 256;
324e9893906SHermès Bélusca-Maïto             while (TRUE)
325c2c66affSColin Finck             {
326c2c66affSColin Finck                 Projects = HeapAlloc(GetProcessHeap(), 0, ProjectsSize * sizeof(WCHAR));
327c2c66affSColin Finck                 if (NULL == Projects)
328c2c66affSColin Finck                 {
329c2c66affSColin Finck                     return FALSE;
330c2c66affSColin Finck                 }
331c2c66affSColin Finck                 ProjectsCount =  LoadStringW(hDllInstance, IDS_ACKPROJECTS, Projects, ProjectsSize);
332c2c66affSColin Finck                 if (0 == ProjectsCount)
333c2c66affSColin Finck                 {
334c2c66affSColin Finck                     HeapFree(GetProcessHeap(), 0, Projects);
335c2c66affSColin Finck                     return FALSE;
336c2c66affSColin Finck                 }
337c2c66affSColin Finck                 if (ProjectsCount < ProjectsSize - 1)
338c2c66affSColin Finck                 {
339c2c66affSColin Finck                     break;
340c2c66affSColin Finck                 }
341c2c66affSColin Finck                 HeapFree(GetProcessHeap(), 0, Projects);
342c2c66affSColin Finck                 ProjectsSize *= 2;
343c2c66affSColin Finck             }
344e9893906SHermès Bélusca-Maïto 
345c2c66affSColin Finck             CurrentProject = Projects;
346e9893906SHermès Bélusca-Maïto             while (*CurrentProject != L'\0')
347c2c66affSColin Finck             {
348c2c66affSColin Finck                 End = wcschr(CurrentProject, L'\n');
349c2c66affSColin Finck                 if (NULL != End)
350c2c66affSColin Finck                 {
351c2c66affSColin Finck                     *End = L'\0';
352c2c66affSColin Finck                 }
353c2c66affSColin Finck                 (void)ListBox_AddString(GetDlgItem(hwndDlg, IDC_PROJECTS), CurrentProject);
354c2c66affSColin Finck                 if (NULL != End)
355c2c66affSColin Finck                 {
356c2c66affSColin Finck                     CurrentProject = End + 1;
357c2c66affSColin Finck                 }
358c2c66affSColin Finck                 else
359c2c66affSColin Finck                 {
360c2c66affSColin Finck                     CurrentProject += wcslen(CurrentProject);
361c2c66affSColin Finck                 }
362c2c66affSColin Finck             }
363c2c66affSColin Finck             HeapFree(GetProcessHeap(), 0, Projects);
364c2c66affSColin Finck         }
365c2c66affSColin Finck         break;
366c2c66affSColin Finck 
367c2c66affSColin Finck         case WM_COMMAND:
368c2c66affSColin Finck             if (HIWORD(wParam) == BN_CLICKED && IDC_VIEWGPL == LOWORD(wParam))
369c2c66affSColin Finck             {
370c2c66affSColin Finck                 DialogBox(hDllInstance, MAKEINTRESOURCE(IDD_GPL), NULL, GplDlgProc);
371c2c66affSColin Finck                 SetForegroundWindow(GetParent(hwndDlg));
372c2c66affSColin Finck             }
373c2c66affSColin Finck             break;
374c2c66affSColin Finck 
375c2c66affSColin Finck         case WM_NOTIFY:
376c2c66affSColin Finck         {
377c2c66affSColin Finck             lpnm = (LPNMHDR)lParam;
378c2c66affSColin Finck 
379c2c66affSColin Finck             switch (lpnm->code)
380c2c66affSColin Finck             {
381c2c66affSColin Finck                 case PSN_SETACTIVE:
382c2c66affSColin Finck                     /* Enable the Back and Next buttons */
383c2c66affSColin Finck                     PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK | PSWIZB_NEXT);
384c2c66affSColin Finck                     if (pSetupData->UnattendSetup)
385c2c66affSColin Finck                     {
38648160c74SKatayama Hirofumi MZ                         SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_PRODUCT);
38748160c74SKatayama Hirofumi MZ                         return TRUE;
38848160c74SKatayama Hirofumi MZ                     }
38948160c74SKatayama Hirofumi MZ                     break;
39048160c74SKatayama Hirofumi MZ 
39148160c74SKatayama Hirofumi MZ                 case PSN_WIZBACK:
39248160c74SKatayama Hirofumi MZ                     pSetupData->UnattendSetup = FALSE;
39348160c74SKatayama Hirofumi MZ                     break;
39448160c74SKatayama Hirofumi MZ 
39548160c74SKatayama Hirofumi MZ                 default:
39648160c74SKatayama Hirofumi MZ                     break;
39748160c74SKatayama Hirofumi MZ             }
39848160c74SKatayama Hirofumi MZ         }
39948160c74SKatayama Hirofumi MZ         break;
40048160c74SKatayama Hirofumi MZ 
40148160c74SKatayama Hirofumi MZ         default:
40248160c74SKatayama Hirofumi MZ             break;
40348160c74SKatayama Hirofumi MZ     }
40448160c74SKatayama Hirofumi MZ 
40548160c74SKatayama Hirofumi MZ     return FALSE;
40648160c74SKatayama Hirofumi MZ }
40748160c74SKatayama Hirofumi MZ 
408612729b0SKatayama Hirofumi MZ static const WCHAR s_szProductOptions[] = L"SYSTEM\\CurrentControlSet\\Control\\ProductOptions";
409612729b0SKatayama Hirofumi MZ static const WCHAR s_szRosVersion[] = L"SYSTEM\\CurrentControlSet\\Control\\ReactOS\\Settings\\Version";
410612729b0SKatayama Hirofumi MZ static const WCHAR s_szControlWindows[] = L"SYSTEM\\CurrentControlSet\\Control\\Windows";
4112edcb58eSVladimir Barinov static const WCHAR s_szWinlogon[] = L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon";
412cbf8b367SOleg Dubinskiy static const WCHAR s_szDefaultSoundEvents[] = L"AppEvents\\Schemes\\Apps\\.Default";
413cbf8b367SOleg Dubinskiy static const WCHAR s_szExplorerSoundEvents[] = L"AppEvents\\Schemes\\Apps\\Explorer";
414612729b0SKatayama Hirofumi MZ 
415ef6711c9SSerge Gautherie typedef struct _PRODUCT_OPTION_DATA
416612729b0SKatayama Hirofumi MZ {
417612729b0SKatayama Hirofumi MZ     LPCWSTR ProductSuite;
418612729b0SKatayama Hirofumi MZ     LPCWSTR ProductType;
419612729b0SKatayama Hirofumi MZ     DWORD ReportAsWorkstation;
420612729b0SKatayama Hirofumi MZ     DWORD CSDVersion;
4212edcb58eSVladimir Barinov     DWORD LogonType;
422ef6711c9SSerge Gautherie } PRODUCT_OPTION_DATA;
423612729b0SKatayama Hirofumi MZ 
424612729b0SKatayama Hirofumi MZ static const PRODUCT_OPTION_DATA s_ProductOptionData[] =
425612729b0SKatayama Hirofumi MZ {
4262edcb58eSVladimir Barinov     { L"Terminal Server\0", L"ServerNT", 0, 0x200, 0 },
4272edcb58eSVladimir Barinov     { L"\0", L"WinNT", 1, 0x300, 1 }
428612729b0SKatayama Hirofumi MZ };
429612729b0SKatayama Hirofumi MZ 
430cbf8b367SOleg Dubinskiy static const WCHAR* s_DefaultSoundEvents[][2] =
431cbf8b367SOleg Dubinskiy {
432cbf8b367SOleg Dubinskiy     { L".Default", L"%SystemRoot%\\Media\\ReactOS_Default.wav" },
433cbf8b367SOleg Dubinskiy     { L"AppGPFault", L"" },
434cbf8b367SOleg Dubinskiy     { L"Close", L"" },
435cbf8b367SOleg Dubinskiy     { L"CriticalBatteryAlarm", L"%SystemRoot%\\Media\\ReactOS_Battery_Critical.wav" },
436cbf8b367SOleg Dubinskiy     { L"DeviceConnect",  L"%SystemRoot%\\Media\\ReactOS_Hardware_Insert.wav" },
437cbf8b367SOleg Dubinskiy     { L"DeviceDisconnect", L"%SystemRoot%\\Media\\ReactOS_Hardware_Remove.wav" },
438cbf8b367SOleg Dubinskiy     { L"DeviceFail", L"%SystemRoot%\\Media\\ReactOS_Hardware_Fail.wav" },
439cbf8b367SOleg Dubinskiy     { L"LowBatteryAlarm", L"%SystemRoot%\\Media\\ReactOS_Battery_Low.wav" },
440cbf8b367SOleg Dubinskiy     { L"MailBeep", L"%SystemRoot%\\Media\\ReactOS_Notify.wav" },
441cbf8b367SOleg Dubinskiy     { L"Maximize", L"%SystemRoot%\\Media\\ReactOS_Restore.wav" },
442cbf8b367SOleg Dubinskiy     { L"MenuCommand", L"%SystemRoot%\\Media\\ReactOS_Menu_Command.wav" },
443cbf8b367SOleg Dubinskiy     { L"MenuPopup", L"" },
444cbf8b367SOleg Dubinskiy     { L"Minimize", L"%SystemRoot%\\Media\\ReactOS_Minimize.wav" },
445cbf8b367SOleg Dubinskiy     { L"Open", L"" },
446cbf8b367SOleg Dubinskiy     { L"PrintComplete", L"%SystemRoot%\\Media\\ReactOS_Print_Complete.wav" },
447cbf8b367SOleg Dubinskiy     { L"RestoreDown", L"" },
448cbf8b367SOleg Dubinskiy     { L"RestoreUp", L"" },
449cbf8b367SOleg Dubinskiy     { L"SystemAsterisk", L"%SystemRoot%\\Media\\ReactOS_Ding.wav" },
450cbf8b367SOleg Dubinskiy     { L"SystemExclamation", L"%SystemRoot%\\Media\\ReactOS_Exclamation.wav" },
451cbf8b367SOleg Dubinskiy     { L"SystemExit", L"%SystemRoot%\\Media\\ReactOS_Shutdown.wav" },
452cbf8b367SOleg Dubinskiy     { L"SystemHand", L"%SystemRoot%\\Media\\ReactOS_Critical_Stop.wav" },
453cbf8b367SOleg Dubinskiy     { L"SystemNotification", L"%SystemRoot%\\Media\\ReactOS_Balloon.wav" },
454cbf8b367SOleg Dubinskiy     { L"SystemQuestion", L"%SystemRoot%\\Media\\ReactOS_Ding.wav" },
455cbf8b367SOleg Dubinskiy     { L"SystemStart", L"%SystemRoot%\\Media\\ReactOS_Startup.wav" },
456cbf8b367SOleg Dubinskiy     { L"WindowsLogoff", L"%SystemRoot%\\Media\\ReactOS_LogOff.wav" }
457cbf8b367SOleg Dubinskiy /* Logon sound is already set by default for both Server and Workstation */
458cbf8b367SOleg Dubinskiy };
459cbf8b367SOleg Dubinskiy 
460cbf8b367SOleg Dubinskiy static const WCHAR* s_ExplorerSoundEvents[][2] =
461cbf8b367SOleg Dubinskiy {
462cbf8b367SOleg Dubinskiy     { L"EmptyRecycleBin", L"%SystemRoot%\\Media\\ReactOS_Recycle.wav" },
463cbf8b367SOleg Dubinskiy     { L"Navigating", L"%SystemRoot%\\Media\\ReactOS_Start.wav" }
464cbf8b367SOleg Dubinskiy };
465cbf8b367SOleg Dubinskiy 
466cbf8b367SOleg Dubinskiy static BOOL
467cbf8b367SOleg Dubinskiy DoWriteSoundEvents(HKEY hKey,
468cbf8b367SOleg Dubinskiy                    LPCWSTR lpSubkey,
469cbf8b367SOleg Dubinskiy                    LPCWSTR lpEventsArray[][2],
470cbf8b367SOleg Dubinskiy                    DWORD dwSize)
471cbf8b367SOleg Dubinskiy {
472cbf8b367SOleg Dubinskiy     HKEY hRootKey, hEventKey, hDefaultKey;
473cbf8b367SOleg Dubinskiy     LONG error;
474cbf8b367SOleg Dubinskiy     ULONG i;
475cbf8b367SOleg Dubinskiy     WCHAR szDest[MAX_PATH];
476cbf8b367SOleg Dubinskiy     DWORD dwAttribs;
477cbf8b367SOleg Dubinskiy     DWORD cbData;
478cbf8b367SOleg Dubinskiy 
479cbf8b367SOleg Dubinskiy     /* Open the sound events key */
480cbf8b367SOleg Dubinskiy     error = RegOpenKeyExW(hKey, lpSubkey, 0, KEY_READ, &hRootKey);
481cbf8b367SOleg Dubinskiy     if (error)
482cbf8b367SOleg Dubinskiy     {
483cbf8b367SOleg Dubinskiy         DPRINT1("RegOpenKeyExW failed\n");
484cbf8b367SOleg Dubinskiy         goto Error;
485cbf8b367SOleg Dubinskiy     }
486cbf8b367SOleg Dubinskiy 
487cbf8b367SOleg Dubinskiy     /* Set each sound event */
488cbf8b367SOleg Dubinskiy     for (i = 0; i < dwSize; i++)
489cbf8b367SOleg Dubinskiy     {
490cbf8b367SOleg Dubinskiy         /*
491cbf8b367SOleg Dubinskiy          * Verify that the sound file exists and is an actual file.
492cbf8b367SOleg Dubinskiy          */
493cbf8b367SOleg Dubinskiy 
494cbf8b367SOleg Dubinskiy         /* Expand the sound file path */
495cbf8b367SOleg Dubinskiy         if (!ExpandEnvironmentStringsW(lpEventsArray[i][1], szDest, _countof(szDest)))
496cbf8b367SOleg Dubinskiy         {
497cbf8b367SOleg Dubinskiy             /* Failed to expand, continue with the next sound event */
498cbf8b367SOleg Dubinskiy             continue;
499cbf8b367SOleg Dubinskiy         }
500cbf8b367SOleg Dubinskiy 
501cbf8b367SOleg Dubinskiy         /* Check if the sound file exists and isn't a directory */
502cbf8b367SOleg Dubinskiy         dwAttribs = GetFileAttributesW(szDest);
503cbf8b367SOleg Dubinskiy         if ((dwAttribs == INVALID_FILE_ATTRIBUTES) ||
504cbf8b367SOleg Dubinskiy             (dwAttribs & FILE_ATTRIBUTE_DIRECTORY))
505cbf8b367SOleg Dubinskiy         {
506cbf8b367SOleg Dubinskiy             /* It does not, just continue with the next sound event */
507cbf8b367SOleg Dubinskiy             continue;
508cbf8b367SOleg Dubinskiy         }
509cbf8b367SOleg Dubinskiy 
510cbf8b367SOleg Dubinskiy         /*
511cbf8b367SOleg Dubinskiy          * Create the sound event entry.
512cbf8b367SOleg Dubinskiy          */
513cbf8b367SOleg Dubinskiy 
514cbf8b367SOleg Dubinskiy         /* Open the sound event subkey */
515cbf8b367SOleg Dubinskiy         error = RegOpenKeyExW(hRootKey, lpEventsArray[i][0], 0, KEY_READ, &hEventKey);
516cbf8b367SOleg Dubinskiy         if (error)
517cbf8b367SOleg Dubinskiy         {
518cbf8b367SOleg Dubinskiy             /* Failed to open, continue with next sound event */
519cbf8b367SOleg Dubinskiy             continue;
520cbf8b367SOleg Dubinskiy         }
521cbf8b367SOleg Dubinskiy 
522cbf8b367SOleg Dubinskiy         /* Open .Default subkey */
523cbf8b367SOleg Dubinskiy         error = RegOpenKeyExW(hEventKey, L".Default", 0, KEY_WRITE, &hDefaultKey);
524cbf8b367SOleg Dubinskiy         RegCloseKey(hEventKey);
525cbf8b367SOleg Dubinskiy         if (error)
526cbf8b367SOleg Dubinskiy         {
527cbf8b367SOleg Dubinskiy             /* Failed to open, continue with next sound event */
528cbf8b367SOleg Dubinskiy             continue;
529cbf8b367SOleg Dubinskiy         }
530cbf8b367SOleg Dubinskiy 
531cbf8b367SOleg Dubinskiy         /* Associate the sound file to this sound event */
532cbf8b367SOleg Dubinskiy         cbData = (lstrlenW(lpEventsArray[i][1]) + 1) * sizeof(WCHAR);
533cbf8b367SOleg Dubinskiy         error = RegSetValueExW(hDefaultKey, NULL, 0, REG_EXPAND_SZ, (const BYTE *)lpEventsArray[i][1], cbData);
534cbf8b367SOleg Dubinskiy         RegCloseKey(hDefaultKey);
535cbf8b367SOleg Dubinskiy         if (error)
536cbf8b367SOleg Dubinskiy         {
537cbf8b367SOleg Dubinskiy             /* Failed to set the value, continue with next sound event */
538cbf8b367SOleg Dubinskiy             continue;
539cbf8b367SOleg Dubinskiy         }
540cbf8b367SOleg Dubinskiy     }
541cbf8b367SOleg Dubinskiy 
542cbf8b367SOleg Dubinskiy Error:
543cbf8b367SOleg Dubinskiy     if (hRootKey)
544cbf8b367SOleg Dubinskiy         RegCloseKey(hRootKey);
545cbf8b367SOleg Dubinskiy 
546cbf8b367SOleg Dubinskiy     return error == ERROR_SUCCESS;
547cbf8b367SOleg Dubinskiy }
548cbf8b367SOleg Dubinskiy 
54948160c74SKatayama Hirofumi MZ static BOOL
55048160c74SKatayama Hirofumi MZ DoWriteProductOption(PRODUCT_OPTION nOption)
55148160c74SKatayama Hirofumi MZ {
55248160c74SKatayama Hirofumi MZ     HKEY hKey;
55348160c74SKatayama Hirofumi MZ     LONG error;
554612729b0SKatayama Hirofumi MZ     LPCWSTR pszData;
555612729b0SKatayama Hirofumi MZ     DWORD dwValue, cbData;
556612729b0SKatayama Hirofumi MZ     const PRODUCT_OPTION_DATA *pData = &s_ProductOptionData[nOption];
557612729b0SKatayama Hirofumi MZ     ASSERT(0 <= nOption && nOption < _countof(s_ProductOptionData));
55848160c74SKatayama Hirofumi MZ 
559612729b0SKatayama Hirofumi MZ     /* open ProductOptions key */
56048160c74SKatayama Hirofumi MZ     error = RegOpenKeyExW(HKEY_LOCAL_MACHINE, s_szProductOptions, 0, KEY_WRITE, &hKey);
56148160c74SKatayama Hirofumi MZ     if (error)
56248160c74SKatayama Hirofumi MZ     {
563612729b0SKatayama Hirofumi MZ         DPRINT1("RegOpenKeyExW failed\n");
564612729b0SKatayama Hirofumi MZ         goto Error;
565612729b0SKatayama Hirofumi MZ     }
566612729b0SKatayama Hirofumi MZ 
56748160c74SKatayama Hirofumi MZ     /* write ProductSuite */
568612729b0SKatayama Hirofumi MZ     pszData = pData->ProductSuite;
569612729b0SKatayama Hirofumi MZ     cbData = (lstrlenW(pszData) + 2) * sizeof(WCHAR);
570ef6711c9SSerge Gautherie     error = RegSetValueExW(hKey, L"ProductSuite", 0, REG_MULTI_SZ, (const BYTE *)pszData, cbData);
57148160c74SKatayama Hirofumi MZ     if (error)
572612729b0SKatayama Hirofumi MZ     {
573612729b0SKatayama Hirofumi MZ         DPRINT1("RegSetValueExW failed\n");
574612729b0SKatayama Hirofumi MZ         goto Error;
575612729b0SKatayama Hirofumi MZ     }
57648160c74SKatayama Hirofumi MZ 
57748160c74SKatayama Hirofumi MZ     /* write ProductType */
578612729b0SKatayama Hirofumi MZ     pszData = pData->ProductType;
579612729b0SKatayama Hirofumi MZ     cbData = (lstrlenW(pszData) + 1) * sizeof(WCHAR);
580ef6711c9SSerge Gautherie     error = RegSetValueExW(hKey, L"ProductType", 0, REG_SZ, (const BYTE *)pszData, cbData);
58148160c74SKatayama Hirofumi MZ     if (error)
582612729b0SKatayama Hirofumi MZ     {
583612729b0SKatayama Hirofumi MZ         DPRINT1("RegSetValueExW failed\n");
584612729b0SKatayama Hirofumi MZ         goto Error;
58548160c74SKatayama Hirofumi MZ     }
58648160c74SKatayama Hirofumi MZ 
58748160c74SKatayama Hirofumi MZ     RegCloseKey(hKey);
5880a7a747dSKatayama Hirofumi MZ 
589612729b0SKatayama Hirofumi MZ     /* open ReactOS version key */
5900a7a747dSKatayama Hirofumi MZ     error = RegOpenKeyExW(HKEY_LOCAL_MACHINE, s_szRosVersion, 0, KEY_WRITE, &hKey);
5910a7a747dSKatayama Hirofumi MZ     if (error)
592612729b0SKatayama Hirofumi MZ     {
593612729b0SKatayama Hirofumi MZ         DPRINT1("RegOpenKeyExW failed\n");
594612729b0SKatayama Hirofumi MZ         goto Error;
595612729b0SKatayama Hirofumi MZ     }
5960a7a747dSKatayama Hirofumi MZ 
597612729b0SKatayama Hirofumi MZ     /* write ReportAsWorkstation */
598612729b0SKatayama Hirofumi MZ     dwValue = pData->ReportAsWorkstation;
5990a7a747dSKatayama Hirofumi MZ     cbData = sizeof(dwValue);
600612729b0SKatayama Hirofumi MZ     error = RegSetValueExW(hKey, L"ReportAsWorkstation", 0, REG_DWORD, (const BYTE *)&dwValue, cbData);
601612729b0SKatayama Hirofumi MZ     if (error)
602612729b0SKatayama Hirofumi MZ     {
603612729b0SKatayama Hirofumi MZ         DPRINT1("RegSetValueExW failed\n");
604612729b0SKatayama Hirofumi MZ         goto Error;
605612729b0SKatayama Hirofumi MZ     }
6060a7a747dSKatayama Hirofumi MZ 
6070a7a747dSKatayama Hirofumi MZ     RegCloseKey(hKey);
6080a7a747dSKatayama Hirofumi MZ 
609612729b0SKatayama Hirofumi MZ     /* open Control Windows key */
610612729b0SKatayama Hirofumi MZ     error = RegOpenKeyExW(HKEY_LOCAL_MACHINE, s_szControlWindows, 0, KEY_WRITE, &hKey);
611612729b0SKatayama Hirofumi MZ     if (error)
612612729b0SKatayama Hirofumi MZ     {
613612729b0SKatayama Hirofumi MZ         DPRINT1("RegOpenKeyExW failed\n");
614612729b0SKatayama Hirofumi MZ         goto Error;
615612729b0SKatayama Hirofumi MZ     }
616612729b0SKatayama Hirofumi MZ 
617612729b0SKatayama Hirofumi MZ     /* write Control Windows CSDVersion */
618612729b0SKatayama Hirofumi MZ     dwValue = pData->CSDVersion;
619612729b0SKatayama Hirofumi MZ     cbData = sizeof(dwValue);
620612729b0SKatayama Hirofumi MZ     error = RegSetValueExW(hKey, L"CSDVersion", 0, REG_DWORD, (const BYTE *)&dwValue, cbData);
621612729b0SKatayama Hirofumi MZ     if (error)
622612729b0SKatayama Hirofumi MZ     {
623612729b0SKatayama Hirofumi MZ         DPRINT1("RegSetValueExW failed\n");
624612729b0SKatayama Hirofumi MZ         goto Error;
625612729b0SKatayama Hirofumi MZ     }
626612729b0SKatayama Hirofumi MZ 
6272edcb58eSVladimir Barinov     RegCloseKey(hKey);
6282edcb58eSVladimir Barinov 
6292edcb58eSVladimir Barinov     /* open Winlogon key */
6302edcb58eSVladimir Barinov     error = RegOpenKeyExW(HKEY_LOCAL_MACHINE, s_szWinlogon, 0, KEY_WRITE, &hKey);
6312edcb58eSVladimir Barinov     if (error)
6322edcb58eSVladimir Barinov     {
6332edcb58eSVladimir Barinov         DPRINT1("RegOpenKeyExW failed\n");
6342edcb58eSVladimir Barinov         goto Error;
6352edcb58eSVladimir Barinov     }
6362edcb58eSVladimir Barinov 
6372edcb58eSVladimir Barinov     /* write LogonType */
6382edcb58eSVladimir Barinov     dwValue = pData->LogonType;
6392edcb58eSVladimir Barinov     cbData = sizeof(dwValue);
6402edcb58eSVladimir Barinov     error = RegSetValueExW(hKey, L"LogonType", 0, REG_DWORD, (const BYTE *)&dwValue, cbData);
6412edcb58eSVladimir Barinov     if (error)
6422edcb58eSVladimir Barinov     {
6432edcb58eSVladimir Barinov         DPRINT1("RegSetValueExW failed\n");
6442edcb58eSVladimir Barinov         goto Error;
6452edcb58eSVladimir Barinov     }
6462edcb58eSVladimir Barinov 
647cbf8b367SOleg Dubinskiy     if (nOption == PRODUCT_OPTION_WORKSTATION)
648cbf8b367SOleg Dubinskiy     {
649cbf8b367SOleg Dubinskiy         /* Write system sound events values for Workstation */
650cbf8b367SOleg Dubinskiy         DoWriteSoundEvents(HKEY_CURRENT_USER, s_szDefaultSoundEvents, s_DefaultSoundEvents, _countof(s_DefaultSoundEvents));
651cbf8b367SOleg Dubinskiy         DoWriteSoundEvents(HKEY_CURRENT_USER, s_szExplorerSoundEvents, s_ExplorerSoundEvents, _countof(s_ExplorerSoundEvents));
652cbf8b367SOleg Dubinskiy     }
653cbf8b367SOleg Dubinskiy 
654612729b0SKatayama Hirofumi MZ Error:
655612729b0SKatayama Hirofumi MZ     if (hKey)
656612729b0SKatayama Hirofumi MZ         RegCloseKey(hKey);
657612729b0SKatayama Hirofumi MZ 
65848160c74SKatayama Hirofumi MZ     return error == ERROR_SUCCESS;
65948160c74SKatayama Hirofumi MZ }
66048160c74SKatayama Hirofumi MZ 
66148160c74SKatayama Hirofumi MZ static void
662612729b0SKatayama Hirofumi MZ OnChooseOption(HWND hwndDlg, PRODUCT_OPTION nOption)
66348160c74SKatayama Hirofumi MZ {
66448160c74SKatayama Hirofumi MZ     WCHAR szText[256];
665612729b0SKatayama Hirofumi MZ     ASSERT(0 <= nOption && nOption < _countof(s_ProductOptionData));
66648160c74SKatayama Hirofumi MZ 
667612729b0SKatayama Hirofumi MZ     switch (nOption)
668612729b0SKatayama Hirofumi MZ     {
669612729b0SKatayama Hirofumi MZ         case PRODUCT_OPTION_SERVER:
67048160c74SKatayama Hirofumi MZ             LoadStringW(hDllInstance, IDS_PRODUCTSERVERINFO, szText, _countof(szText));
671612729b0SKatayama Hirofumi MZ             break;
672612729b0SKatayama Hirofumi MZ 
673612729b0SKatayama Hirofumi MZ         case PRODUCT_OPTION_WORKSTATION:
674612729b0SKatayama Hirofumi MZ             LoadStringW(hDllInstance, IDS_PRODUCTWORKSTATIONINFO, szText, _countof(szText));
675612729b0SKatayama Hirofumi MZ             break;
676612729b0SKatayama Hirofumi MZ 
677612729b0SKatayama Hirofumi MZ         default:
678612729b0SKatayama Hirofumi MZ             return;
67948160c74SKatayama Hirofumi MZ     }
68048160c74SKatayama Hirofumi MZ 
68148160c74SKatayama Hirofumi MZ     SetDlgItemTextW(hwndDlg, IDC_PRODUCT_DESCRIPTION, szText);
68248160c74SKatayama Hirofumi MZ }
68348160c74SKatayama Hirofumi MZ 
68448160c74SKatayama Hirofumi MZ static INT_PTR CALLBACK
68548160c74SKatayama Hirofumi MZ ProductPageDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
68648160c74SKatayama Hirofumi MZ {
68748160c74SKatayama Hirofumi MZ     LPNMHDR lpnm;
68848160c74SKatayama Hirofumi MZ     PSETUPDATA pSetupData;
68948160c74SKatayama Hirofumi MZ     INT iItem;
6904cbb2176SJoachim Henze     WCHAR szText[64], szDefault[64];
69148160c74SKatayama Hirofumi MZ     HICON hIcon;
69248160c74SKatayama Hirofumi MZ 
69348160c74SKatayama Hirofumi MZ     pSetupData = (PSETUPDATA)GetWindowLongPtr(hwndDlg, DWLP_USER);
69448160c74SKatayama Hirofumi MZ 
69548160c74SKatayama Hirofumi MZ     switch (uMsg)
69648160c74SKatayama Hirofumi MZ     {
69748160c74SKatayama Hirofumi MZ         case WM_INITDIALOG:
69848160c74SKatayama Hirofumi MZ         {
69948160c74SKatayama Hirofumi MZ             pSetupData = (PSETUPDATA)((LPPROPSHEETPAGE)lParam)->lParam;
70048160c74SKatayama Hirofumi MZ             SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pSetupData);
70148160c74SKatayama Hirofumi MZ 
702612729b0SKatayama Hirofumi MZ             LoadStringW(hDllInstance, IDS_DEFAULT, szDefault, _countof(szDefault));
703612729b0SKatayama Hirofumi MZ 
70448160c74SKatayama Hirofumi MZ             LoadStringW(hDllInstance, IDS_PRODUCTSERVERNAME, szText, _countof(szText));
705612729b0SKatayama Hirofumi MZ             if (PRODUCT_OPTION_DEFAULT == PRODUCT_OPTION_SERVER)
706612729b0SKatayama Hirofumi MZ             {
707612729b0SKatayama Hirofumi MZ                 StringCchCatW(szText, _countof(szText), L" ");
708612729b0SKatayama Hirofumi MZ                 StringCchCatW(szText, _countof(szText), szDefault);
709612729b0SKatayama Hirofumi MZ             }
71048160c74SKatayama Hirofumi MZ             SendDlgItemMessageW(hwndDlg, IDC_PRODUCT_OPTIONS, CB_ADDSTRING, 0, (LPARAM)szText);
71148160c74SKatayama Hirofumi MZ 
71248160c74SKatayama Hirofumi MZ             LoadStringW(hDllInstance, IDS_PRODUCTWORKSTATIONNAME, szText, _countof(szText));
713612729b0SKatayama Hirofumi MZ             if (PRODUCT_OPTION_DEFAULT == PRODUCT_OPTION_WORKSTATION)
714612729b0SKatayama Hirofumi MZ             {
715612729b0SKatayama Hirofumi MZ                 StringCchCatW(szText, _countof(szText), L" ");
716612729b0SKatayama Hirofumi MZ                 StringCchCatW(szText, _countof(szText), szDefault);
717612729b0SKatayama Hirofumi MZ             }
71848160c74SKatayama Hirofumi MZ             SendDlgItemMessageW(hwndDlg, IDC_PRODUCT_OPTIONS, CB_ADDSTRING, 0, (LPARAM)szText);
71948160c74SKatayama Hirofumi MZ 
720612729b0SKatayama Hirofumi MZ             SendDlgItemMessageW(hwndDlg, IDC_PRODUCT_OPTIONS, CB_SETCURSEL, PRODUCT_OPTION_DEFAULT, 0);
721612729b0SKatayama Hirofumi MZ             OnChooseOption(hwndDlg, PRODUCT_OPTION_DEFAULT);
72248160c74SKatayama Hirofumi MZ 
72348160c74SKatayama Hirofumi MZ             hIcon = LoadIcon(NULL, IDI_WINLOGO);
72448160c74SKatayama Hirofumi MZ             SendDlgItemMessageW(hwndDlg, IDC_PRODUCT_ICON, STM_SETICON, (WPARAM)hIcon, 0);
72548160c74SKatayama Hirofumi MZ             return TRUE;
72648160c74SKatayama Hirofumi MZ         }
72748160c74SKatayama Hirofumi MZ 
72848160c74SKatayama Hirofumi MZ         case WM_COMMAND:
72948160c74SKatayama Hirofumi MZ             if (HIWORD(wParam) == CBN_SELCHANGE && IDC_PRODUCT_OPTIONS == LOWORD(wParam))
73048160c74SKatayama Hirofumi MZ             {
73148160c74SKatayama Hirofumi MZ                 iItem = SendDlgItemMessageW(hwndDlg, IDC_PRODUCT_OPTIONS, CB_GETCURSEL, 0, 0);
732612729b0SKatayama Hirofumi MZ                 OnChooseOption(hwndDlg, (PRODUCT_OPTION)iItem);
73348160c74SKatayama Hirofumi MZ             }
73448160c74SKatayama Hirofumi MZ             break;
73548160c74SKatayama Hirofumi MZ 
73648160c74SKatayama Hirofumi MZ         case WM_NOTIFY:
73748160c74SKatayama Hirofumi MZ         {
73848160c74SKatayama Hirofumi MZ             lpnm = (LPNMHDR)lParam;
73948160c74SKatayama Hirofumi MZ 
74048160c74SKatayama Hirofumi MZ             switch (lpnm->code)
74148160c74SKatayama Hirofumi MZ             {
74248160c74SKatayama Hirofumi MZ                 case PSN_SETACTIVE:
74348160c74SKatayama Hirofumi MZ                     /* Enable the Back and Next buttons */
74448160c74SKatayama Hirofumi MZ                     PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK | PSWIZB_NEXT);
74548160c74SKatayama Hirofumi MZ                     if (pSetupData->UnattendSetup)
74648160c74SKatayama Hirofumi MZ                     {
747612729b0SKatayama Hirofumi MZ                         OnChooseOption(hwndDlg, pSetupData->ProductOption);
74848160c74SKatayama Hirofumi MZ                         DoWriteProductOption(pSetupData->ProductOption);
7490182dcd7STimo Kreuzer                         SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_LOCALEPAGE);
750c2c66affSColin Finck                         return TRUE;
751c2c66affSColin Finck                     }
752c2c66affSColin Finck                     break;
753c2c66affSColin Finck 
75448160c74SKatayama Hirofumi MZ                 case PSN_WIZNEXT:
75548160c74SKatayama Hirofumi MZ                     iItem = SendDlgItemMessageW(hwndDlg, IDC_PRODUCT_OPTIONS, CB_GETCURSEL, 0, 0);
75648160c74SKatayama Hirofumi MZ                     pSetupData->ProductOption = (PRODUCT_OPTION)iItem;
75748160c74SKatayama Hirofumi MZ                     DoWriteProductOption(pSetupData->ProductOption);
75848160c74SKatayama Hirofumi MZ                     break;
75948160c74SKatayama Hirofumi MZ 
760c2c66affSColin Finck                 case PSN_WIZBACK:
761c2c66affSColin Finck                     pSetupData->UnattendSetup = FALSE;
762c2c66affSColin Finck                     break;
763c2c66affSColin Finck 
764c2c66affSColin Finck                 default:
765c2c66affSColin Finck                     break;
766c2c66affSColin Finck             }
767c2c66affSColin Finck         }
768c2c66affSColin Finck         break;
769c2c66affSColin Finck 
770c2c66affSColin Finck         default:
771c2c66affSColin Finck             break;
772c2c66affSColin Finck     }
773c2c66affSColin Finck 
774c2c66affSColin Finck     return FALSE;
775c2c66affSColin Finck }
776c2c66affSColin Finck 
777c2c66affSColin Finck static
778c2c66affSColin Finck BOOL
779c2c66affSColin Finck WriteOwnerSettings(WCHAR * OwnerName,
780c2c66affSColin Finck                    WCHAR * OwnerOrganization)
781c2c66affSColin Finck {
782c2c66affSColin Finck     HKEY hKey;
783c2c66affSColin Finck     LONG res;
784c2c66affSColin Finck 
785c2c66affSColin Finck     res = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
786c2c66affSColin Finck                         L"Software\\Microsoft\\Windows NT\\CurrentVersion",
787c2c66affSColin Finck                         0,
788c2c66affSColin Finck                         KEY_ALL_ACCESS,
789c2c66affSColin Finck                         &hKey);
790c2c66affSColin Finck 
791c2c66affSColin Finck     if (res != ERROR_SUCCESS)
792c2c66affSColin Finck     {
793c2c66affSColin Finck         return FALSE;
794c2c66affSColin Finck     }
795c2c66affSColin Finck 
796c2c66affSColin Finck     res = RegSetValueExW(hKey,
797c2c66affSColin Finck                          L"RegisteredOwner",
798c2c66affSColin Finck                          0,
799c2c66affSColin Finck                          REG_SZ,
800c2c66affSColin Finck                          (LPBYTE)OwnerName,
801c2c66affSColin Finck                          (wcslen(OwnerName) + 1) * sizeof(WCHAR));
802c2c66affSColin Finck 
803c2c66affSColin Finck     if (res != ERROR_SUCCESS)
804c2c66affSColin Finck     {
805c2c66affSColin Finck         RegCloseKey(hKey);
806c2c66affSColin Finck         return FALSE;
807c2c66affSColin Finck     }
808c2c66affSColin Finck 
809c2c66affSColin Finck     res = RegSetValueExW(hKey,
810c2c66affSColin Finck                          L"RegisteredOrganization",
811c2c66affSColin Finck                          0,
812c2c66affSColin Finck                          REG_SZ,
813c2c66affSColin Finck                          (LPBYTE)OwnerOrganization,
814c2c66affSColin Finck                          (wcslen(OwnerOrganization) + 1) * sizeof(WCHAR));
815c2c66affSColin Finck 
816c2c66affSColin Finck     RegCloseKey(hKey);
817c2c66affSColin Finck     return (res == ERROR_SUCCESS);
818c2c66affSColin Finck }
819c2c66affSColin Finck 
820c2c66affSColin Finck static INT_PTR CALLBACK
821c2c66affSColin Finck OwnerPageDlgProc(HWND hwndDlg,
822c2c66affSColin Finck                  UINT uMsg,
823c2c66affSColin Finck                  WPARAM wParam,
824c2c66affSColin Finck                  LPARAM lParam)
825c2c66affSColin Finck {
826c2c66affSColin Finck     WCHAR OwnerName[51];
827c2c66affSColin Finck     WCHAR OwnerOrganization[51];
828c2c66affSColin Finck     WCHAR Title[64];
829c2c66affSColin Finck     WCHAR ErrorName[256];
830c2c66affSColin Finck     LPNMHDR lpnm;
831c2c66affSColin Finck     PSETUPDATA pSetupData;
832c2c66affSColin Finck 
833c2c66affSColin Finck     pSetupData = (PSETUPDATA)GetWindowLongPtr(hwndDlg, DWLP_USER);
834c2c66affSColin Finck 
835c2c66affSColin Finck     switch (uMsg)
836c2c66affSColin Finck     {
837c2c66affSColin Finck         case WM_INITDIALOG:
838c2c66affSColin Finck         {
839c2c66affSColin Finck             pSetupData = (PSETUPDATA)((LPPROPSHEETPAGE)lParam)->lParam;
840c2c66affSColin Finck             SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pSetupData);
841c2c66affSColin Finck 
842c2c66affSColin Finck             /* set a localized ('Owner') placeholder string as default */
843c2c66affSColin Finck             if (LoadStringW(hDllInstance, IDS_MACHINE_OWNER_NAME, OwnerName, _countof(OwnerName)))
844c2c66affSColin Finck             {
845c2c66affSColin Finck                 SendDlgItemMessage(hwndDlg, IDC_OWNERNAME, WM_SETTEXT, 0, (LPARAM)OwnerName);
846c2c66affSColin Finck             }
847c2c66affSColin Finck 
848c2c66affSColin Finck             SendDlgItemMessage(hwndDlg, IDC_OWNERNAME, EM_LIMITTEXT, 50, 0);
849c2c66affSColin Finck             SendDlgItemMessage(hwndDlg, IDC_OWNERORGANIZATION, EM_LIMITTEXT, 50, 0);
850c2c66affSColin Finck 
851c2c66affSColin Finck             /* Set focus to owner name */
852c2c66affSColin Finck             SetFocus(GetDlgItem(hwndDlg, IDC_OWNERNAME));
853c2c66affSColin Finck 
854c2c66affSColin Finck             /* Select the default text to quickly overwrite it by typing */
855c2c66affSColin Finck             SendDlgItemMessage(hwndDlg, IDC_OWNERNAME, EM_SETSEL, 0, -1);
856c2c66affSColin Finck         }
857c2c66affSColin Finck         break;
858c2c66affSColin Finck 
859c2c66affSColin Finck 
860c2c66affSColin Finck         case WM_NOTIFY:
861c2c66affSColin Finck         {
862c2c66affSColin Finck             lpnm = (LPNMHDR)lParam;
863c2c66affSColin Finck 
864c2c66affSColin Finck             switch (lpnm->code)
865c2c66affSColin Finck             {
866c2c66affSColin Finck                 case PSN_SETACTIVE:
867c2c66affSColin Finck                     /* Enable the Back and Next buttons */
868c2c66affSColin Finck                     PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK | PSWIZB_NEXT);
869c2c66affSColin Finck                     if (pSetupData->UnattendSetup)
870c2c66affSColin Finck                     {
871c2c66affSColin Finck                         SendMessage(GetDlgItem(hwndDlg, IDC_OWNERNAME), WM_SETTEXT, 0, (LPARAM)pSetupData->OwnerName);
872c2c66affSColin Finck                         SendMessage(GetDlgItem(hwndDlg, IDC_OWNERORGANIZATION), WM_SETTEXT, 0, (LPARAM)pSetupData->OwnerOrganization);
873c2c66affSColin Finck                         if (WriteOwnerSettings(pSetupData->OwnerName, pSetupData->OwnerOrganization))
874c2c66affSColin Finck                         {
8750182dcd7STimo Kreuzer                             SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_COMPUTERPAGE);
876c2c66affSColin Finck                             return TRUE;
877c2c66affSColin Finck                         }
878c2c66affSColin Finck                     }
879c2c66affSColin Finck                     break;
880c2c66affSColin Finck 
881c2c66affSColin Finck                 case PSN_WIZNEXT:
882c2c66affSColin Finck                     OwnerName[0] = 0;
883c2c66affSColin Finck                     if (GetDlgItemTextW(hwndDlg, IDC_OWNERNAME, OwnerName, 50) == 0)
884c2c66affSColin Finck                     {
88562678985SHermès Bélusca-Maïto                         if (0 == LoadStringW(hDllInstance, IDS_REACTOS_SETUP, Title, ARRAYSIZE(Title)))
886c2c66affSColin Finck                         {
887c2c66affSColin Finck                             wcscpy(Title, L"ReactOS Setup");
888c2c66affSColin Finck                         }
88962678985SHermès Bélusca-Maïto                         if (0 == LoadStringW(hDllInstance, IDS_WZD_NAME, ErrorName, ARRAYSIZE(ErrorName)))
890c2c66affSColin Finck                         {
891c2c66affSColin Finck                             wcscpy(ErrorName, L"Setup cannot continue until you enter your name.");
892c2c66affSColin Finck                         }
893c2c66affSColin Finck                         MessageBoxW(hwndDlg, ErrorName, Title, MB_ICONERROR | MB_OK);
894c2c66affSColin Finck 
895c2c66affSColin Finck                         SetFocus(GetDlgItem(hwndDlg, IDC_OWNERNAME));
8960182dcd7STimo Kreuzer                         SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1);
897c2c66affSColin Finck 
898c2c66affSColin Finck                         return TRUE;
899c2c66affSColin Finck                     }
900c2c66affSColin Finck 
901c2c66affSColin Finck                     OwnerOrganization[0] = 0;
902c2c66affSColin Finck                     GetDlgItemTextW(hwndDlg, IDC_OWNERORGANIZATION, OwnerOrganization, 50);
903c2c66affSColin Finck 
904c2c66affSColin Finck                     if (!WriteOwnerSettings(OwnerName, OwnerOrganization))
905c2c66affSColin Finck                     {
906c2c66affSColin Finck                         SetFocus(GetDlgItem(hwndDlg, IDC_OWNERNAME));
9070182dcd7STimo Kreuzer                         SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1);
908c2c66affSColin Finck                         return TRUE;
909c2c66affSColin Finck                     }
910c2c66affSColin Finck 
911c2c66affSColin Finck                 case PSN_WIZBACK:
912c2c66affSColin Finck                     pSetupData->UnattendSetup = FALSE;
913c2c66affSColin Finck                     break;
914c2c66affSColin Finck 
915c2c66affSColin Finck                 default:
916c2c66affSColin Finck                     break;
917c2c66affSColin Finck             }
918c2c66affSColin Finck         }
919c2c66affSColin Finck         break;
920c2c66affSColin Finck 
921c2c66affSColin Finck         default:
922c2c66affSColin Finck             break;
923c2c66affSColin Finck     }
924c2c66affSColin Finck 
925c2c66affSColin Finck     return FALSE;
926c2c66affSColin Finck }
927c2c66affSColin Finck 
928c2c66affSColin Finck static
929c2c66affSColin Finck BOOL
930c2c66affSColin Finck WriteComputerSettings(WCHAR * ComputerName, HWND hwndDlg)
931c2c66affSColin Finck {
932c2c66affSColin Finck     WCHAR Title[64];
933c2c66affSColin Finck     WCHAR ErrorComputerName[256];
9349a39315dSKatayama Hirofumi MZ     LONG lError;
9359a39315dSKatayama Hirofumi MZ     HKEY hKey = NULL;
936c2c66affSColin Finck 
937c2c66affSColin Finck     if (!SetComputerNameW(ComputerName))
938c2c66affSColin Finck     {
939c2c66affSColin Finck         if (hwndDlg != NULL)
940c2c66affSColin Finck         {
94162678985SHermès Bélusca-Maïto             if (0 == LoadStringW(hDllInstance, IDS_REACTOS_SETUP, Title, ARRAYSIZE(Title)))
942c2c66affSColin Finck             {
943c2c66affSColin Finck                 wcscpy(Title, L"ReactOS Setup");
944c2c66affSColin Finck             }
945c2c66affSColin Finck             if (0 == LoadStringW(hDllInstance, IDS_WZD_SETCOMPUTERNAME, ErrorComputerName,
94662678985SHermès Bélusca-Maïto                                  ARRAYSIZE(ErrorComputerName)))
947c2c66affSColin Finck             {
948c2c66affSColin Finck                 wcscpy(ErrorComputerName, L"Setup failed to set the computer name.");
949c2c66affSColin Finck             }
950c2c66affSColin Finck             MessageBoxW(hwndDlg, ErrorComputerName, Title, MB_ICONERROR | MB_OK);
951c2c66affSColin Finck         }
952c2c66affSColin Finck 
953c2c66affSColin Finck         return FALSE;
954c2c66affSColin Finck     }
955c2c66affSColin Finck 
9569e2ae9b0SEric Kohl     /* Set the physical DNS domain */
9579e2ae9b0SEric Kohl     SetComputerNameExW(ComputerNamePhysicalDnsDomain, L"");
9589e2ae9b0SEric Kohl 
9599e2ae9b0SEric Kohl     /* Set the physical DNS hostname */
960c2c66affSColin Finck     SetComputerNameExW(ComputerNamePhysicalDnsHostname, ComputerName);
961c2c66affSColin Finck 
962c2c66affSColin Finck     /* Set the accounts domain name */
963c2c66affSColin Finck     SetAccountsDomainSid(NULL, ComputerName);
964c2c66affSColin Finck 
9659a39315dSKatayama Hirofumi MZ     /* Now we need to set the Hostname */
9669a39315dSKatayama Hirofumi MZ     lError = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
9679a39315dSKatayama Hirofumi MZ                            L"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters",
9689a39315dSKatayama Hirofumi MZ                            0,
9699a39315dSKatayama Hirofumi MZ                            KEY_SET_VALUE,
9709a39315dSKatayama Hirofumi MZ                            &hKey);
9719a39315dSKatayama Hirofumi MZ     if (lError != ERROR_SUCCESS)
9729a39315dSKatayama Hirofumi MZ     {
9739a39315dSKatayama Hirofumi MZ         DPRINT1("RegOpenKeyExW for Tcpip\\Parameters failed (%08lX)\n", lError);
9749a39315dSKatayama Hirofumi MZ         return TRUE;
9759a39315dSKatayama Hirofumi MZ     }
9769a39315dSKatayama Hirofumi MZ 
9779a39315dSKatayama Hirofumi MZ     lError = RegSetValueEx(hKey,
9789a39315dSKatayama Hirofumi MZ                            L"Hostname",
9799a39315dSKatayama Hirofumi MZ                            0,
9809a39315dSKatayama Hirofumi MZ                            REG_SZ,
9819a39315dSKatayama Hirofumi MZ                            (LPBYTE)ComputerName,
9829a39315dSKatayama Hirofumi MZ                            (wcslen(ComputerName) + 1) * sizeof(WCHAR));
9839a39315dSKatayama Hirofumi MZ     if (lError != ERROR_SUCCESS)
9849a39315dSKatayama Hirofumi MZ     {
9859a39315dSKatayama Hirofumi MZ         DPRINT1("RegSetValueEx(\"Hostname\") failed (%08lX)\n", lError);
9869a39315dSKatayama Hirofumi MZ     }
9879a39315dSKatayama Hirofumi MZ 
9889a39315dSKatayama Hirofumi MZ     RegCloseKey(hKey);
9899a39315dSKatayama Hirofumi MZ 
990c2c66affSColin Finck     return TRUE;
991c2c66affSColin Finck }
992c2c66affSColin Finck 
993c2c66affSColin Finck 
994c2c66affSColin Finck static
995c2c66affSColin Finck BOOL
996c2c66affSColin Finck WriteDefaultLogonData(LPWSTR Domain)
997c2c66affSColin Finck {
998c2c66affSColin Finck     WCHAR szAdministratorName[256];
999c2c66affSColin Finck     HKEY hKey = NULL;
1000c2c66affSColin Finck     LONG lError;
1001c2c66affSColin Finck 
1002c2c66affSColin Finck     if (LoadStringW(hDllInstance,
1003c2c66affSColin Finck                     IDS_ADMINISTRATOR_NAME,
1004c2c66affSColin Finck                     szAdministratorName,
100562678985SHermès Bélusca-Maïto                     ARRAYSIZE(szAdministratorName)) == 0)
1006c2c66affSColin Finck     {
1007c2c66affSColin Finck         wcscpy(szAdministratorName, L"Administrator");
1008c2c66affSColin Finck     }
1009c2c66affSColin Finck 
1010c2c66affSColin Finck     lError = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
1011c2c66affSColin Finck                            L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon",
1012c2c66affSColin Finck                            0,
1013c2c66affSColin Finck                            KEY_SET_VALUE,
1014c2c66affSColin Finck                            &hKey);
1015c2c66affSColin Finck     if (lError != ERROR_SUCCESS)
1016c2c66affSColin Finck         return FALSE;
1017c2c66affSColin Finck 
1018c2c66affSColin Finck     lError = RegSetValueEx(hKey,
1019b784c7bfSEric Kohl                            L"DefaultDomainName",
1020c2c66affSColin Finck                            0,
1021c2c66affSColin Finck                            REG_SZ,
1022c2c66affSColin Finck                            (LPBYTE)Domain,
1023c2c66affSColin Finck                            (wcslen(Domain)+ 1) * sizeof(WCHAR));
1024c2c66affSColin Finck     if (lError != ERROR_SUCCESS)
1025c2c66affSColin Finck     {
1026b784c7bfSEric Kohl         DPRINT1("RegSetValueEx(\"DefaultDomainName\") failed!\n");
1027c2c66affSColin Finck     }
1028c2c66affSColin Finck 
1029c2c66affSColin Finck     lError = RegSetValueEx(hKey,
1030c2c66affSColin Finck                            L"DefaultUserName",
1031c2c66affSColin Finck                            0,
1032c2c66affSColin Finck                            REG_SZ,
1033c2c66affSColin Finck                            (LPBYTE)szAdministratorName,
1034c2c66affSColin Finck                            (wcslen(szAdministratorName)+ 1) * sizeof(WCHAR));
1035c2c66affSColin Finck     if (lError != ERROR_SUCCESS)
1036c2c66affSColin Finck     {
1037c2c66affSColin Finck         DPRINT1("RegSetValueEx(\"DefaultUserName\") failed!\n");
1038c2c66affSColin Finck     }
1039c2c66affSColin Finck 
1040c2c66affSColin Finck     RegCloseKey(hKey);
1041c2c66affSColin Finck 
1042c2c66affSColin Finck     return TRUE;
1043c2c66affSColin Finck }
1044c2c66affSColin Finck 
1045c2c66affSColin Finck 
1046c2c66affSColin Finck /* lpBuffer will be filled with a 15-char string (plus the null terminator) */
1047c2c66affSColin Finck static void
1048c2c66affSColin Finck GenerateComputerName(LPWSTR lpBuffer)
1049c2c66affSColin Finck {
1050c2c66affSColin Finck     static const WCHAR Chars[] = L"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
1051c2c66affSColin Finck     static const unsigned cChars = sizeof(Chars) / sizeof(WCHAR) - 1;
1052c2c66affSColin Finck     unsigned i;
1053c2c66affSColin Finck 
1054c2c66affSColin Finck     wcscpy(lpBuffer, L"REACTOS-");
1055c2c66affSColin Finck 
1056c2c66affSColin Finck     srand(GetTickCount());
1057c2c66affSColin Finck 
1058c2c66affSColin Finck     /* fill in 7 characters */
1059c2c66affSColin Finck     for (i = 8; i < 15; i++)
1060c2c66affSColin Finck         lpBuffer[i] = Chars[rand() % cChars];
1061c2c66affSColin Finck 
1062c2c66affSColin Finck     lpBuffer[15] = UNICODE_NULL; /* NULL-terminate */
1063c2c66affSColin Finck }
1064c2c66affSColin Finck 
1065c2c66affSColin Finck static INT_PTR CALLBACK
1066c2c66affSColin Finck ComputerPageDlgProc(HWND hwndDlg,
1067c2c66affSColin Finck                     UINT uMsg,
1068c2c66affSColin Finck                     WPARAM wParam,
1069c2c66affSColin Finck                     LPARAM lParam)
1070c2c66affSColin Finck {
1071c2c66affSColin Finck     WCHAR ComputerName[MAX_COMPUTERNAME_LENGTH + 1];
1072c2c66affSColin Finck     WCHAR Password1[128];
1073c2c66affSColin Finck     WCHAR Password2[128];
1074c2c66affSColin Finck     PWCHAR Password;
1075c2c66affSColin Finck     WCHAR Title[64];
1076c2c66affSColin Finck     WCHAR EmptyComputerName[256], NotMatchPassword[256], WrongPassword[256];
1077c2c66affSColin Finck     LPNMHDR lpnm;
1078c2c66affSColin Finck     PSETUPDATA pSetupData;
1079c2c66affSColin Finck 
1080c2c66affSColin Finck     pSetupData = (PSETUPDATA)GetWindowLongPtr(hwndDlg, DWLP_USER);
1081c2c66affSColin Finck 
108262678985SHermès Bélusca-Maïto     if (0 == LoadStringW(hDllInstance, IDS_REACTOS_SETUP, Title, ARRAYSIZE(Title)))
1083c2c66affSColin Finck     {
1084c2c66affSColin Finck         wcscpy(Title, L"ReactOS Setup");
1085c2c66affSColin Finck     }
1086c2c66affSColin Finck 
1087c2c66affSColin Finck     switch (uMsg)
1088c2c66affSColin Finck     {
1089c2c66affSColin Finck         case WM_INITDIALOG:
1090c2c66affSColin Finck             pSetupData = (PSETUPDATA)((LPPROPSHEETPAGE)lParam)->lParam;
1091c2c66affSColin Finck             SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pSetupData);
1092c2c66affSColin Finck 
1093c2c66affSColin Finck             /* Generate a new pseudo-random computer name */
1094c2c66affSColin Finck             GenerateComputerName(ComputerName);
1095c2c66affSColin Finck 
1096c2c66affSColin Finck             /* Display current computer name */
1097c2c66affSColin Finck             SetDlgItemTextW(hwndDlg, IDC_COMPUTERNAME, ComputerName);
1098c2c66affSColin Finck 
1099c2c66affSColin Finck             /* Set text limits */
1100c2c66affSColin Finck             SendDlgItemMessage(hwndDlg, IDC_COMPUTERNAME, EM_LIMITTEXT, MAX_COMPUTERNAME_LENGTH, 0);
1101c2c66affSColin Finck             SendDlgItemMessage(hwndDlg, IDC_ADMINPASSWORD1, EM_LIMITTEXT, 127, 0);
1102c2c66affSColin Finck             SendDlgItemMessage(hwndDlg, IDC_ADMINPASSWORD2, EM_LIMITTEXT, 127, 0);
1103c2c66affSColin Finck 
1104c2c66affSColin Finck             /* Set focus to computer name */
1105c2c66affSColin Finck             SetFocus(GetDlgItem(hwndDlg, IDC_COMPUTERNAME));
1106c2c66affSColin Finck             if (pSetupData->UnattendSetup)
1107c2c66affSColin Finck             {
1108c2c66affSColin Finck                 SendMessage(GetDlgItem(hwndDlg, IDC_COMPUTERNAME), WM_SETTEXT, 0, (LPARAM)pSetupData->ComputerName);
1109c2c66affSColin Finck                 SendMessage(GetDlgItem(hwndDlg, IDC_ADMINPASSWORD1), WM_SETTEXT, 0, (LPARAM)pSetupData->AdminPassword);
1110c2c66affSColin Finck                 SendMessage(GetDlgItem(hwndDlg, IDC_ADMINPASSWORD2), WM_SETTEXT, 0, (LPARAM)pSetupData->AdminPassword);
1111c2c66affSColin Finck                 WriteComputerSettings(pSetupData->ComputerName, NULL);
1112c2c66affSColin Finck                 SetAdministratorPassword(pSetupData->AdminPassword);
1113c2c66affSColin Finck             }
1114c2c66affSColin Finck 
1115c2c66affSColin Finck             /* Store the administrator account name as the default user name */
1116c2c66affSColin Finck             WriteDefaultLogonData(pSetupData->ComputerName);
1117c2c66affSColin Finck             break;
1118c2c66affSColin Finck 
1119c2c66affSColin Finck 
1120c2c66affSColin Finck         case WM_NOTIFY:
1121c2c66affSColin Finck         {
1122c2c66affSColin Finck             lpnm = (LPNMHDR)lParam;
1123c2c66affSColin Finck 
1124c2c66affSColin Finck             switch (lpnm->code)
1125c2c66affSColin Finck             {
1126c2c66affSColin Finck                 case PSN_SETACTIVE:
1127c2c66affSColin Finck                     /* Enable the Back and Next buttons */
1128c2c66affSColin Finck                     PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK | PSWIZB_NEXT);
1129c2c66affSColin Finck                     if (pSetupData->UnattendSetup && WriteComputerSettings(pSetupData->ComputerName, hwndDlg))
1130c2c66affSColin Finck                     {
11310182dcd7STimo Kreuzer                         SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_THEMEPAGE);
1132c2c66affSColin Finck                         return TRUE;
1133c2c66affSColin Finck                     }
1134c2c66affSColin Finck                     break;
1135c2c66affSColin Finck 
1136c2c66affSColin Finck                 case PSN_WIZNEXT:
1137c2c66affSColin Finck                     if (0 == GetDlgItemTextW(hwndDlg, IDC_COMPUTERNAME, ComputerName, MAX_COMPUTERNAME_LENGTH + 1))
1138c2c66affSColin Finck                     {
1139c2c66affSColin Finck                         if (0 == LoadStringW(hDllInstance, IDS_WZD_COMPUTERNAME, EmptyComputerName,
114062678985SHermès Bélusca-Maïto                                              ARRAYSIZE(EmptyComputerName)))
1141c2c66affSColin Finck                         {
1142c2c66affSColin Finck                             wcscpy(EmptyComputerName, L"Setup cannot continue until you enter the name of your computer.");
1143c2c66affSColin Finck                         }
1144c2c66affSColin Finck                         MessageBoxW(hwndDlg, EmptyComputerName, Title, MB_ICONERROR | MB_OK);
1145c2c66affSColin Finck                         SetFocus(GetDlgItem(hwndDlg, IDC_COMPUTERNAME));
11460182dcd7STimo Kreuzer                         SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1);
1147c2c66affSColin Finck                         return TRUE;
1148c2c66affSColin Finck                     }
1149c2c66affSColin Finck 
1150c2c66affSColin Finck                     /* No need to check computer name for invalid characters,
1151c2c66affSColin Finck                      * SetComputerName() will do it for us */
1152c2c66affSColin Finck 
1153c2c66affSColin Finck                     if (!WriteComputerSettings(ComputerName, hwndDlg))
1154c2c66affSColin Finck                     {
1155c2c66affSColin Finck                         SetFocus(GetDlgItem(hwndDlg, IDC_COMPUTERNAME));
11560182dcd7STimo Kreuzer                         SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1);
1157c2c66affSColin Finck                         return TRUE;
1158c2c66affSColin Finck                     }
1159c2c66affSColin Finck 
11601769793bSErkin Alp Güney #ifdef PASSWORDS_MANDATORY
1161c2c66affSColin Finck                     /* Check if admin passwords have been entered */
1162c2c66affSColin Finck                     if ((GetDlgItemText(hwndDlg, IDC_ADMINPASSWORD1, Password1, 128) == 0) ||
1163c2c66affSColin Finck                         (GetDlgItemText(hwndDlg, IDC_ADMINPASSWORD2, Password2, 128) == 0))
1164c2c66affSColin Finck                     {
1165c2c66affSColin Finck                         if (0 == LoadStringW(hDllInstance, IDS_WZD_PASSWORDEMPTY, EmptyPassword,
116662678985SHermès Bélusca-Maïto                                              ARRAYSIZE(EmptyPassword)))
1167c2c66affSColin Finck                         {
1168c2c66affSColin Finck                             wcscpy(EmptyPassword, L"You must enter a password !");
1169c2c66affSColin Finck                         }
1170c2c66affSColin Finck                         MessageBoxW(hwndDlg, EmptyPassword, Title, MB_ICONERROR | MB_OK);
11710182dcd7STimo Kreuzer                         SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1);
1172c2c66affSColin Finck                         return TRUE;
1173c2c66affSColin Finck                     }
1174c2c66affSColin Finck #else
1175c2c66affSColin Finck                     GetDlgItemTextW(hwndDlg, IDC_ADMINPASSWORD1, Password1, 128);
1176c2c66affSColin Finck                     GetDlgItemTextW(hwndDlg, IDC_ADMINPASSWORD2, Password2, 128);
1177c2c66affSColin Finck #endif
1178c2c66affSColin Finck                     /* Check if passwords match */
1179c2c66affSColin Finck                     if (wcscmp(Password1, Password2))
1180c2c66affSColin Finck                     {
1181c2c66affSColin Finck                         if (0 == LoadStringW(hDllInstance, IDS_WZD_PASSWORDMATCH, NotMatchPassword,
118262678985SHermès Bélusca-Maïto                                              ARRAYSIZE(NotMatchPassword)))
1183c2c66affSColin Finck                         {
1184c2c66affSColin Finck                             wcscpy(NotMatchPassword, L"The passwords you entered do not match. Please enter the desired password again.");
1185c2c66affSColin Finck                         }
1186c2c66affSColin Finck                         MessageBoxW(hwndDlg, NotMatchPassword, Title, MB_ICONERROR | MB_OK);
11870182dcd7STimo Kreuzer                         SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1);
1188c2c66affSColin Finck                         return TRUE;
1189c2c66affSColin Finck                     }
1190c2c66affSColin Finck 
1191c2c66affSColin Finck                     /* Check password for invalid characters */
1192c2c66affSColin Finck                     Password = (PWCHAR)Password1;
1193c2c66affSColin Finck                     while (*Password)
1194c2c66affSColin Finck                     {
1195c2c66affSColin Finck                         if (!isprint(*Password))
1196c2c66affSColin Finck                         {
1197c2c66affSColin Finck                             if (0 == LoadStringW(hDllInstance, IDS_WZD_PASSWORDCHAR, WrongPassword,
119862678985SHermès Bélusca-Maïto                                                  ARRAYSIZE(WrongPassword)))
1199c2c66affSColin Finck                             {
1200c2c66affSColin Finck                                 wcscpy(WrongPassword, L"The password you entered contains invalid characters. Please enter a cleaned password.");
1201c2c66affSColin Finck                             }
1202c2c66affSColin Finck                             MessageBoxW(hwndDlg, WrongPassword, Title, MB_ICONERROR | MB_OK);
12030182dcd7STimo Kreuzer                             SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1);
1204c2c66affSColin Finck                             return TRUE;
1205c2c66affSColin Finck                         }
1206c2c66affSColin Finck                         Password++;
1207c2c66affSColin Finck                     }
1208c2c66affSColin Finck 
1209c2c66affSColin Finck                     /* Set admin password */
1210c2c66affSColin Finck                     SetAdministratorPassword(Password1);
1211c2c66affSColin Finck                     break;
1212c2c66affSColin Finck 
1213c2c66affSColin Finck                 case PSN_WIZBACK:
1214c2c66affSColin Finck                     pSetupData->UnattendSetup = FALSE;
1215c2c66affSColin Finck                     break;
1216c2c66affSColin Finck 
1217c2c66affSColin Finck                 default:
1218c2c66affSColin Finck                     break;
1219c2c66affSColin Finck             }
1220c2c66affSColin Finck         }
1221c2c66affSColin Finck         break;
1222c2c66affSColin Finck 
1223c2c66affSColin Finck         default:
1224c2c66affSColin Finck             break;
1225c2c66affSColin Finck     }
1226c2c66affSColin Finck 
1227c2c66affSColin Finck     return FALSE;
1228c2c66affSColin Finck }
1229c2c66affSColin Finck 
1230c2c66affSColin Finck 
1231c2c66affSColin Finck static VOID
123217cb1e1aSStanislav Motylkov SetUserLocaleName(HWND hwnd)
123317cb1e1aSStanislav Motylkov {
12346d09885cSStanislav Motylkov     WCHAR CurLocale[256] = L"";
12356d09885cSStanislav Motylkov     WCHAR CurGeo[256] = L"";
12366d09885cSStanislav Motylkov     WCHAR ResText[256] = L"";
12376d09885cSStanislav Motylkov     WCHAR LocaleText[256 * 2];
12386d09885cSStanislav Motylkov 
12396d09885cSStanislav Motylkov     GetLocaleInfoW(GetUserDefaultLCID(), LOCALE_SLANGUAGE, CurLocale, ARRAYSIZE(CurLocale));
12409635f45bSStanislav Motylkov     GetGeoInfoW(GetUserGeoID(GEOCLASS_NATION), GEO_FRIENDLYNAME, CurGeo, ARRAYSIZE(CurGeo), GetThreadLocale());
12416d09885cSStanislav Motylkov 
12426d09885cSStanislav Motylkov     LoadStringW(hDllInstance, IDS_LOCALETEXT, ResText, ARRAYSIZE(ResText));
12436d09885cSStanislav Motylkov     StringCchPrintfW(LocaleText, ARRAYSIZE(LocaleText), ResText, CurLocale, CurGeo);
12446d09885cSStanislav Motylkov 
12456d09885cSStanislav Motylkov     SetWindowTextW(hwnd, LocaleText);
124617cb1e1aSStanislav Motylkov }
124717cb1e1aSStanislav Motylkov 
124817cb1e1aSStanislav Motylkov static VOID
1249c2c66affSColin Finck SetKeyboardLayoutName(HWND hwnd)
1250c2c66affSColin Finck {
12516d09885cSStanislav Motylkov     HKL hkl;
12526d09885cSStanislav Motylkov     BOOL LayoutSpecial = FALSE;
12536d09885cSStanislav Motylkov     WCHAR LayoutPath[256];
12546d09885cSStanislav Motylkov     WCHAR LocaleName[32];
12556d09885cSStanislav Motylkov     WCHAR SpecialId[5] = L"";
12566d09885cSStanislav Motylkov     WCHAR ResText[256] = L"";
12576d09885cSStanislav Motylkov     DWORD dwValueSize;
1258c2c66affSColin Finck     HKEY hKey;
12596d09885cSStanislav Motylkov     UINT i;
1260c2c66affSColin Finck 
12616d09885cSStanislav Motylkov     /* Get the default input language and method */
12626d09885cSStanislav Motylkov     if (!SystemParametersInfoW(SPI_GETDEFAULTINPUTLANG, 0, (LPDWORD)&hkl, 0))
1263c2c66affSColin Finck     {
12646d09885cSStanislav Motylkov         hkl = GetKeyboardLayout(0);
1265c2c66affSColin Finck     }
1266c2c66affSColin Finck 
12676d09885cSStanislav Motylkov     if ((HIWORD(hkl) & 0xF000) == 0xF000)
1268c2c66affSColin Finck     {
12696d09885cSStanislav Motylkov         /* Process keyboard layout with special id */
12706d09885cSStanislav Motylkov         StringCchPrintfW(SpecialId, ARRAYSIZE(SpecialId), L"%04x", (HIWORD(hkl) & 0x0FFF));
12716d09885cSStanislav Motylkov         LayoutSpecial = TRUE;
1272c2c66affSColin Finck     }
1273c2c66affSColin Finck 
12746d09885cSStanislav Motylkov #define MAX_LAYOUTS_PER_LANGID 0x10000
12756d09885cSStanislav Motylkov     for (i = 0; i < (LayoutSpecial ? MAX_LAYOUTS_PER_LANGID : 1); i++)
12766d09885cSStanislav Motylkov     {
12776d09885cSStanislav Motylkov         /* Generate a hexadecimal identifier for keyboard layout registry key */
12786d09885cSStanislav Motylkov         StringCchPrintfW(LocaleName, ARRAYSIZE(LocaleName), L"%08lx", (i << 16) | LOWORD(hkl));
12796d09885cSStanislav Motylkov 
12806d09885cSStanislav Motylkov         StringCchCopyW(LayoutPath, ARRAYSIZE(LayoutPath), L"SYSTEM\\CurrentControlSet\\Control\\Keyboard Layouts\\");
12816d09885cSStanislav Motylkov         StringCchCatW(LayoutPath, ARRAYSIZE(LayoutPath), LocaleName);
12826d09885cSStanislav Motylkov         *LocaleName = UNICODE_NULL;
12836d09885cSStanislav Motylkov 
12846d09885cSStanislav Motylkov         if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,
12856d09885cSStanislav Motylkov                           LayoutPath,
12866d09885cSStanislav Motylkov                           0,
12876d09885cSStanislav Motylkov                           KEY_ALL_ACCESS,
12886d09885cSStanislav Motylkov                           &hKey) == ERROR_SUCCESS)
12896d09885cSStanislav Motylkov         {
12906d09885cSStanislav Motylkov             /* Make sure the keyboard layout key we opened is the one we need.
12916d09885cSStanislav Motylkov              * If the layout has no special id, just pass this check. */
12926d09885cSStanislav Motylkov             dwValueSize = sizeof(LocaleName);
12936d09885cSStanislav Motylkov             if (!LayoutSpecial ||
12946d09885cSStanislav Motylkov                 ((RegQueryValueExW(hKey,
12956d09885cSStanislav Motylkov                                    L"Layout Id",
12966d09885cSStanislav Motylkov                                    NULL,
12976d09885cSStanislav Motylkov                                    NULL,
12986d09885cSStanislav Motylkov                                    (PVOID)&LocaleName,
12996d09885cSStanislav Motylkov                                    &dwValueSize) == ERROR_SUCCESS) &&
13006d09885cSStanislav Motylkov                 (wcscmp(LocaleName, SpecialId) == 0)))
13016d09885cSStanislav Motylkov             {
13026d09885cSStanislav Motylkov                 *LocaleName = UNICODE_NULL;
13036d09885cSStanislav Motylkov                 dwValueSize = sizeof(LocaleName);
13046d09885cSStanislav Motylkov                 RegQueryValueExW(hKey,
13056d09885cSStanislav Motylkov                                  L"Layout Text",
13066d09885cSStanislav Motylkov                                  NULL,
13076d09885cSStanislav Motylkov                                  NULL,
13086d09885cSStanislav Motylkov                                  (PVOID)&LocaleName,
13096d09885cSStanislav Motylkov                                  &dwValueSize);
13106d09885cSStanislav Motylkov                 /* Let the loop know where to stop */
13116d09885cSStanislav Motylkov                 i = MAX_LAYOUTS_PER_LANGID;
13126d09885cSStanislav Motylkov             }
1313c2c66affSColin Finck             RegCloseKey(hKey);
13146d09885cSStanislav Motylkov         }
13156d09885cSStanislav Motylkov         else
13166d09885cSStanislav Motylkov         {
13176d09885cSStanislav Motylkov             /* Keyboard layout registry keys are expected to go in order without gaps */
13186d09885cSStanislav Motylkov             break;
13196d09885cSStanislav Motylkov         }
13206d09885cSStanislav Motylkov     }
13216d09885cSStanislav Motylkov #undef MAX_LAYOUTS_PER_LANGID
13226d09885cSStanislav Motylkov 
13236d09885cSStanislav Motylkov     LoadStringW(hDllInstance, IDS_LAYOUTTEXT, ResText, ARRAYSIZE(ResText));
13246d09885cSStanislav Motylkov     StringCchPrintfW(LayoutPath, ARRAYSIZE(LayoutPath), ResText, LocaleName);
13256d09885cSStanislav Motylkov 
13266d09885cSStanislav Motylkov     SetWindowTextW(hwnd, LayoutPath);
1327c2c66affSColin Finck }
1328c2c66affSColin Finck 
1329c2c66affSColin Finck 
1330c2c66affSColin Finck static BOOL
1331c2c66affSColin Finck RunControlPanelApplet(HWND hwnd, PCWSTR pwszCPLParameters)
1332c2c66affSColin Finck {
1333c2c66affSColin Finck     MSG msg;
13346d09885cSStanislav Motylkov     HWND MainWindow = GetParent(hwnd);
1335c2c66affSColin Finck     STARTUPINFOW StartupInfo;
1336c2c66affSColin Finck     PROCESS_INFORMATION ProcessInformation;
1337c2c66affSColin Finck     WCHAR CmdLine[MAX_PATH] = L"rundll32.exe shell32.dll,Control_RunDLL ";
1338c2c66affSColin Finck 
1339e9893906SHermès Bélusca-Maïto     if (!pwszCPLParameters)
1340e9893906SHermès Bélusca-Maïto     {
1341e9893906SHermès Bélusca-Maïto         MessageBoxW(hwnd, L"Error: Failed to launch the Control Panel Applet.", NULL, MB_ICONERROR);
1342e9893906SHermès Bélusca-Maïto         return FALSE;
1343e9893906SHermès Bélusca-Maïto     }
1344e9893906SHermès Bélusca-Maïto 
1345c2c66affSColin Finck     ZeroMemory(&StartupInfo, sizeof(StartupInfo));
1346c2c66affSColin Finck     StartupInfo.cb = sizeof(StartupInfo);
1347e9893906SHermès Bélusca-Maïto     ZeroMemory(&ProcessInformation, sizeof(ProcessInformation));
1348c2c66affSColin Finck 
1349c2c66affSColin Finck     ASSERT(_countof(CmdLine) > wcslen(CmdLine) + wcslen(pwszCPLParameters));
1350c2c66affSColin Finck     wcscat(CmdLine, pwszCPLParameters);
1351c2c66affSColin Finck 
1352c2c66affSColin Finck     if (!CreateProcessW(NULL,
1353c2c66affSColin Finck                         CmdLine,
1354c2c66affSColin Finck                         NULL,
1355c2c66affSColin Finck                         NULL,
1356c2c66affSColin Finck                         FALSE,
1357c2c66affSColin Finck                         0,
1358c2c66affSColin Finck                         NULL,
1359c2c66affSColin Finck                         NULL,
1360c2c66affSColin Finck                         &StartupInfo,
1361c2c66affSColin Finck                         &ProcessInformation))
1362c2c66affSColin Finck     {
1363c2c66affSColin Finck         MessageBoxW(hwnd, L"Error: Failed to launch the Control Panel Applet.", NULL, MB_ICONERROR);
1364c2c66affSColin Finck         return FALSE;
1365c2c66affSColin Finck     }
1366c2c66affSColin Finck 
13676d09885cSStanislav Motylkov     /* Disable the Back and Next buttons and the main window
13686d09885cSStanislav Motylkov      * while we're interacting with the control panel applet */
13696d09885cSStanislav Motylkov     PropSheet_SetWizButtons(MainWindow, 0);
13706d09885cSStanislav Motylkov     EnableWindow(MainWindow, FALSE);
13716d09885cSStanislav Motylkov 
1372c2c66affSColin Finck     while ((MsgWaitForMultipleObjects(1, &ProcessInformation.hProcess, FALSE, INFINITE, QS_ALLINPUT|QS_ALLPOSTMESSAGE )) != WAIT_OBJECT_0)
1373c2c66affSColin Finck     {
13746d09885cSStanislav Motylkov        /* We still need to process main window messages to avoid freeze */
1375c2c66affSColin Finck        while (PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE))
1376c2c66affSColin Finck        {
1377c2c66affSColin Finck            TranslateMessage(&msg);
1378c2c66affSColin Finck            DispatchMessageW(&msg);
1379c2c66affSColin Finck        }
1380c2c66affSColin Finck     }
1381c2c66affSColin Finck     CloseHandle(ProcessInformation.hThread);
1382c2c66affSColin Finck     CloseHandle(ProcessInformation.hProcess);
13836d09885cSStanislav Motylkov 
13846d09885cSStanislav Motylkov     /* Enable the Back and Next buttons and the main window again */
13856d09885cSStanislav Motylkov     PropSheet_SetWizButtons(MainWindow, PSWIZB_BACK | PSWIZB_NEXT);
13866d09885cSStanislav Motylkov     EnableWindow(MainWindow, TRUE);
13876d09885cSStanislav Motylkov 
1388c2c66affSColin Finck     return TRUE;
1389c2c66affSColin Finck }
1390c2c66affSColin Finck 
1391c2c66affSColin Finck static VOID
1392c2c66affSColin Finck WriteUserLocale(VOID)
1393c2c66affSColin Finck {
1394c2c66affSColin Finck     HKEY hKey;
1395c2c66affSColin Finck     LCID lcid;
1396c2c66affSColin Finck     WCHAR Locale[12];
1397c2c66affSColin Finck 
1398c2c66affSColin Finck     lcid = GetSystemDefaultLCID();
1399c2c66affSColin Finck 
140062678985SHermès Bélusca-Maïto     if (GetLocaleInfoW(MAKELCID(lcid, SORT_DEFAULT), LOCALE_ILANGUAGE, Locale, ARRAYSIZE(Locale)) != 0)
1401c2c66affSColin Finck     {
1402c2c66affSColin Finck         if (RegCreateKeyExW(HKEY_CURRENT_USER, L"Control Panel\\International",
1403c2c66affSColin Finck                             0, NULL, REG_OPTION_NON_VOLATILE,
1404c2c66affSColin Finck                             KEY_WRITE, NULL, &hKey, NULL) == ERROR_SUCCESS)
1405c2c66affSColin Finck         {
1406c2c66affSColin Finck             RegSetValueExW(hKey, L"Locale", 0, REG_SZ, (LPBYTE)Locale, (wcslen(Locale) + 1) * sizeof(WCHAR));
1407c2c66affSColin Finck             RegCloseKey(hKey);
1408c2c66affSColin Finck         }
1409c2c66affSColin Finck     }
1410c2c66affSColin Finck }
1411c2c66affSColin Finck 
1412c2c66affSColin Finck static INT_PTR CALLBACK
1413c2c66affSColin Finck LocalePageDlgProc(HWND hwndDlg,
1414c2c66affSColin Finck                   UINT uMsg,
1415c2c66affSColin Finck                   WPARAM wParam,
1416c2c66affSColin Finck                   LPARAM lParam)
1417c2c66affSColin Finck {
1418c2c66affSColin Finck     PSETUPDATA SetupData;
1419c2c66affSColin Finck 
1420c2c66affSColin Finck     /* Retrieve pointer to the global setup data */
1421d281d14fSTimo Kreuzer     SetupData = (PSETUPDATA)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
1422c2c66affSColin Finck 
1423c2c66affSColin Finck     switch (uMsg)
1424c2c66affSColin Finck     {
1425c2c66affSColin Finck         case WM_INITDIALOG:
1426c2c66affSColin Finck         {
1427c2c66affSColin Finck             /* Save pointer to the global setup data */
1428c2c66affSColin Finck             SetupData = (PSETUPDATA)((LPPROPSHEETPAGE)lParam)->lParam;
1429d281d14fSTimo Kreuzer             SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (DWORD_PTR)SetupData);
1430c2c66affSColin Finck             WriteUserLocale();
1431c2c66affSColin Finck 
143217cb1e1aSStanislav Motylkov             SetUserLocaleName(GetDlgItem(hwndDlg, IDC_LOCALETEXT));
1433c2c66affSColin Finck             SetKeyboardLayoutName(GetDlgItem(hwndDlg, IDC_LAYOUTTEXT));
1434c2c66affSColin Finck         }
1435c2c66affSColin Finck         break;
1436c2c66affSColin Finck 
1437c2c66affSColin Finck         case WM_COMMAND:
1438c2c66affSColin Finck             if (HIWORD(wParam) == BN_CLICKED)
1439c2c66affSColin Finck             {
1440c2c66affSColin Finck                 switch (LOWORD(wParam))
1441c2c66affSColin Finck                 {
1442c2c66affSColin Finck                     case IDC_CUSTOMLOCALE:
1443c2c66affSColin Finck                         RunControlPanelApplet(hwndDlg, L"intl.cpl,,5");
14446d09885cSStanislav Motylkov                         SetUserLocaleName(GetDlgItem(hwndDlg, IDC_LOCALETEXT));
1445c2c66affSColin Finck                         break;
1446c2c66affSColin Finck 
1447c2c66affSColin Finck                     case IDC_CUSTOMLAYOUT:
1448c2c66affSColin Finck                         RunControlPanelApplet(hwndDlg, L"input.dll,@1");
14496d09885cSStanislav Motylkov                         SetKeyboardLayoutName(GetDlgItem(hwndDlg, IDC_LAYOUTTEXT));
1450c2c66affSColin Finck                         break;
1451c2c66affSColin Finck                 }
1452c2c66affSColin Finck             }
1453c2c66affSColin Finck             break;
1454c2c66affSColin Finck 
1455c2c66affSColin Finck         case WM_NOTIFY:
1456c2c66affSColin Finck         {
1457c2c66affSColin Finck             LPNMHDR lpnm = (LPNMHDR)lParam;
1458c2c66affSColin Finck 
1459c2c66affSColin Finck             switch (lpnm->code)
1460c2c66affSColin Finck             {
1461c2c66affSColin Finck                 case PSN_SETACTIVE:
1462c2c66affSColin Finck                     /* Enable the Back and Next buttons */
1463c2c66affSColin Finck                     PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK | PSWIZB_NEXT);
1464c2c66affSColin Finck                     if (SetupData->UnattendSetup)
1465c2c66affSColin Finck                     {
1466c8d37c1aSHermès Bélusca-Maïto                         // if (!*SetupData->SourcePath)
1467c2c66affSColin Finck                         {
1468c8d37c1aSHermès Bélusca-Maïto                             RunControlPanelApplet(hwndDlg, L"intl.cpl,,/f:\"$winnt$.inf\""); // Should be in System32
1469c2c66affSColin Finck                         }
1470c2c66affSColin Finck 
14710182dcd7STimo Kreuzer                         SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_OWNERPAGE);
1472c2c66affSColin Finck                         return TRUE;
1473c2c66affSColin Finck                     }
1474c2c66affSColin Finck                     break;
1475c2c66affSColin Finck 
1476c2c66affSColin Finck                 case PSN_WIZNEXT:
1477c2c66affSColin Finck                     break;
1478c2c66affSColin Finck 
1479c2c66affSColin Finck                 case PSN_WIZBACK:
1480c2c66affSColin Finck                     SetupData->UnattendSetup = FALSE;
1481c2c66affSColin Finck                     break;
1482c2c66affSColin Finck 
1483c2c66affSColin Finck                 default:
1484c2c66affSColin Finck                     break;
1485c2c66affSColin Finck             }
1486c2c66affSColin Finck         }
1487c2c66affSColin Finck         break;
1488c2c66affSColin Finck 
1489c2c66affSColin Finck         default:
1490c2c66affSColin Finck             break;
1491c2c66affSColin Finck     }
1492c2c66affSColin Finck 
1493c2c66affSColin Finck     return FALSE;
1494c2c66affSColin Finck }
1495c2c66affSColin Finck 
1496c2c66affSColin Finck 
1497c2c66affSColin Finck static PTIMEZONE_ENTRY
1498c2c66affSColin Finck GetLargerTimeZoneEntry(PSETUPDATA SetupData, DWORD Index)
1499c2c66affSColin Finck {
1500c2c66affSColin Finck     PTIMEZONE_ENTRY Entry;
1501c2c66affSColin Finck 
1502c2c66affSColin Finck     Entry = SetupData->TimeZoneListHead;
1503c2c66affSColin Finck     while (Entry != NULL)
1504c2c66affSColin Finck     {
1505c2c66affSColin Finck         if (Entry->Index >= Index)
1506c2c66affSColin Finck             return Entry;
1507c2c66affSColin Finck 
1508c2c66affSColin Finck         Entry = Entry->Next;
1509c2c66affSColin Finck     }
1510c2c66affSColin Finck 
1511c2c66affSColin Finck     return NULL;
1512c2c66affSColin Finck }
1513c2c66affSColin Finck 
15147c3e96a2SHermès Bélusca-Maïto static LONG
15157c3e96a2SHermès Bélusca-Maïto RetrieveTimeZone(
15167c3e96a2SHermès Bélusca-Maïto     IN HKEY hZoneKey,
15177c3e96a2SHermès Bélusca-Maïto     IN PVOID Context)
1518c2c66affSColin Finck {
1519c2c66affSColin Finck     LONG lError;
15207c3e96a2SHermès Bélusca-Maïto     PSETUPDATA SetupData = (PSETUPDATA)Context;
1521c2c66affSColin Finck     PTIMEZONE_ENTRY Entry;
1522c2c66affSColin Finck     PTIMEZONE_ENTRY Current;
15237c3e96a2SHermès Bélusca-Maïto     ULONG DescriptionSize;
15247c3e96a2SHermès Bélusca-Maïto     ULONG StandardNameSize;
15257c3e96a2SHermès Bélusca-Maïto     ULONG DaylightNameSize;
1526c2c66affSColin Finck 
1527c2c66affSColin Finck     Entry = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(TIMEZONE_ENTRY));
1528c2c66affSColin Finck     if (Entry == NULL)
1529c2c66affSColin Finck     {
15307c3e96a2SHermès Bélusca-Maïto         return ERROR_NOT_ENOUGH_MEMORY;
1531c2c66affSColin Finck     }
1532c2c66affSColin Finck 
15337c3e96a2SHermès Bélusca-Maïto     DescriptionSize  = sizeof(Entry->Description);
15347c3e96a2SHermès Bélusca-Maïto     StandardNameSize = sizeof(Entry->StandardName);
15357c3e96a2SHermès Bélusca-Maïto     DaylightNameSize = sizeof(Entry->DaylightName);
15367c3e96a2SHermès Bélusca-Maïto 
15377c3e96a2SHermès Bélusca-Maïto     lError = QueryTimeZoneData(hZoneKey,
15387c3e96a2SHermès Bélusca-Maïto                                &Entry->Index,
15397c3e96a2SHermès Bélusca-Maïto                                &Entry->TimezoneInfo,
15407c3e96a2SHermès Bélusca-Maïto                                Entry->Description,
15417c3e96a2SHermès Bélusca-Maïto                                &DescriptionSize,
15427c3e96a2SHermès Bélusca-Maïto                                Entry->StandardName,
15437c3e96a2SHermès Bélusca-Maïto                                &StandardNameSize,
15447c3e96a2SHermès Bélusca-Maïto                                Entry->DaylightName,
15457c3e96a2SHermès Bélusca-Maïto                                &DaylightNameSize);
15467c3e96a2SHermès Bélusca-Maïto     if (lError != ERROR_SUCCESS)
1547c2c66affSColin Finck     {
15487c3e96a2SHermès Bélusca-Maïto         HeapFree(GetProcessHeap(), 0, Entry);
15497c3e96a2SHermès Bélusca-Maïto         return lError;
1550c2c66affSColin Finck     }
1551c2c66affSColin Finck 
1552c2c66affSColin Finck     if (SetupData->TimeZoneListHead == NULL &&
1553c2c66affSColin Finck         SetupData->TimeZoneListTail == NULL)
1554c2c66affSColin Finck     {
1555c2c66affSColin Finck         Entry->Prev = NULL;
1556c2c66affSColin Finck         Entry->Next = NULL;
1557c2c66affSColin Finck         SetupData->TimeZoneListHead = Entry;
1558c2c66affSColin Finck         SetupData->TimeZoneListTail = Entry;
1559c2c66affSColin Finck     }
1560c2c66affSColin Finck     else
1561c2c66affSColin Finck     {
1562c2c66affSColin Finck         Current = GetLargerTimeZoneEntry(SetupData, Entry->Index);
1563c2c66affSColin Finck         if (Current != NULL)
1564c2c66affSColin Finck         {
1565c2c66affSColin Finck             if (Current == SetupData->TimeZoneListHead)
1566c2c66affSColin Finck             {
1567c2c66affSColin Finck                 /* Prepend to head */
1568c2c66affSColin Finck                 Entry->Prev = NULL;
1569c2c66affSColin Finck                 Entry->Next = SetupData->TimeZoneListHead;
1570c2c66affSColin Finck                 SetupData->TimeZoneListHead->Prev = Entry;
1571c2c66affSColin Finck                 SetupData->TimeZoneListHead = Entry;
1572c2c66affSColin Finck             }
1573c2c66affSColin Finck             else
1574c2c66affSColin Finck             {
1575c2c66affSColin Finck                 /* Insert before current */
1576c2c66affSColin Finck                 Entry->Prev = Current->Prev;
1577c2c66affSColin Finck                 Entry->Next = Current;
1578c2c66affSColin Finck                 Current->Prev->Next = Entry;
1579c2c66affSColin Finck                 Current->Prev = Entry;
1580c2c66affSColin Finck             }
1581c2c66affSColin Finck         }
1582c2c66affSColin Finck         else
1583c2c66affSColin Finck         {
1584c2c66affSColin Finck             /* Append to tail */
1585c2c66affSColin Finck             Entry->Prev = SetupData->TimeZoneListTail;
1586c2c66affSColin Finck             Entry->Next = NULL;
1587c2c66affSColin Finck             SetupData->TimeZoneListTail->Next = Entry;
1588c2c66affSColin Finck             SetupData->TimeZoneListTail = Entry;
1589c2c66affSColin Finck         }
1590c2c66affSColin Finck     }
1591c2c66affSColin Finck 
15927c3e96a2SHermès Bélusca-Maïto     return ERROR_SUCCESS;
1593c2c66affSColin Finck }
1594c2c66affSColin Finck 
15957c3e96a2SHermès Bélusca-Maïto static VOID
15967c3e96a2SHermès Bélusca-Maïto CreateTimeZoneList(PSETUPDATA SetupData)
15977c3e96a2SHermès Bélusca-Maïto {
15987c3e96a2SHermès Bélusca-Maïto     EnumerateTimeZoneList(RetrieveTimeZone, SetupData);
1599c2c66affSColin Finck }
1600c2c66affSColin Finck 
1601c2c66affSColin Finck static VOID
1602c2c66affSColin Finck DestroyTimeZoneList(PSETUPDATA SetupData)
1603c2c66affSColin Finck {
1604c2c66affSColin Finck     PTIMEZONE_ENTRY Entry;
1605c2c66affSColin Finck 
1606c2c66affSColin Finck     while (SetupData->TimeZoneListHead != NULL)
1607c2c66affSColin Finck     {
1608c2c66affSColin Finck         Entry = SetupData->TimeZoneListHead;
1609c2c66affSColin Finck 
1610c2c66affSColin Finck         SetupData->TimeZoneListHead = Entry->Next;
1611c2c66affSColin Finck         if (SetupData->TimeZoneListHead != NULL)
1612c2c66affSColin Finck         {
1613c2c66affSColin Finck             SetupData->TimeZoneListHead->Prev = NULL;
1614c2c66affSColin Finck         }
1615c2c66affSColin Finck 
1616c2c66affSColin Finck         HeapFree(GetProcessHeap(), 0, Entry);
1617c2c66affSColin Finck     }
1618c2c66affSColin Finck 
1619c2c66affSColin Finck     SetupData->TimeZoneListTail = NULL;
1620c2c66affSColin Finck }
1621c2c66affSColin Finck 
1622c2c66affSColin Finck 
1623c2c66affSColin Finck static VOID
1624c2c66affSColin Finck ShowTimeZoneList(HWND hwnd, PSETUPDATA SetupData, DWORD dwEntryIndex)
1625c2c66affSColin Finck {
1626c2c66affSColin Finck     PTIMEZONE_ENTRY Entry;
1627c2c66affSColin Finck     DWORD dwIndex = 0;
1628c2c66affSColin Finck     DWORD dwCount;
1629c2c66affSColin Finck 
1630c2c66affSColin Finck     GetTimeZoneListIndex(&dwEntryIndex);
1631c2c66affSColin Finck 
1632c2c66affSColin Finck     Entry = SetupData->TimeZoneListHead;
1633c2c66affSColin Finck     while (Entry != NULL)
1634c2c66affSColin Finck     {
1635c2c66affSColin Finck         dwCount = SendMessage(hwnd,
1636c2c66affSColin Finck                               CB_ADDSTRING,
1637c2c66affSColin Finck                               0,
1638c2c66affSColin Finck                               (LPARAM)Entry->Description);
1639c2c66affSColin Finck 
1640c2c66affSColin Finck         if (dwEntryIndex != 0 && dwEntryIndex == Entry->Index)
1641c2c66affSColin Finck             dwIndex = dwCount;
1642c2c66affSColin Finck 
1643c2c66affSColin Finck         Entry = Entry->Next;
1644c2c66affSColin Finck     }
1645c2c66affSColin Finck 
1646c2c66affSColin Finck     SendMessage(hwnd,
1647c2c66affSColin Finck                 CB_SETCURSEL,
1648c2c66affSColin Finck                 (WPARAM)dwIndex,
1649c2c66affSColin Finck                 0);
1650c2c66affSColin Finck }
1651c2c66affSColin Finck 
1652c2c66affSColin Finck 
1653c2c66affSColin Finck static VOID
1654c2c66affSColin Finck SetLocalTimeZone(HWND hwnd, PSETUPDATA SetupData)
1655c2c66affSColin Finck {
1656c2c66affSColin Finck     TIME_ZONE_INFORMATION TimeZoneInformation;
1657c2c66affSColin Finck     PTIMEZONE_ENTRY Entry;
1658c2c66affSColin Finck     DWORD dwIndex;
1659c2c66affSColin Finck     DWORD i;
1660c2c66affSColin Finck 
1661c2c66affSColin Finck     dwIndex = SendMessage(hwnd,
1662c2c66affSColin Finck                           CB_GETCURSEL,
1663c2c66affSColin Finck                           0,
1664c2c66affSColin Finck                           0);
1665c2c66affSColin Finck 
1666c2c66affSColin Finck     i = 0;
1667c2c66affSColin Finck     Entry = SetupData->TimeZoneListHead;
1668c2c66affSColin Finck     while (i < dwIndex)
1669c2c66affSColin Finck     {
1670c2c66affSColin Finck         if (Entry == NULL)
1671c2c66affSColin Finck             return;
1672c2c66affSColin Finck 
1673c2c66affSColin Finck         i++;
1674c2c66affSColin Finck         Entry = Entry->Next;
1675c2c66affSColin Finck     }
1676c2c66affSColin Finck 
1677c2c66affSColin Finck     wcscpy(TimeZoneInformation.StandardName,
1678c2c66affSColin Finck            Entry->StandardName);
1679c2c66affSColin Finck     wcscpy(TimeZoneInformation.DaylightName,
1680c2c66affSColin Finck            Entry->DaylightName);
1681c2c66affSColin Finck 
1682c2c66affSColin Finck     TimeZoneInformation.Bias = Entry->TimezoneInfo.Bias;
1683c2c66affSColin Finck     TimeZoneInformation.StandardBias = Entry->TimezoneInfo.StandardBias;
1684c2c66affSColin Finck     TimeZoneInformation.DaylightBias = Entry->TimezoneInfo.DaylightBias;
1685c2c66affSColin Finck 
1686c2c66affSColin Finck     memcpy(&TimeZoneInformation.StandardDate,
1687c2c66affSColin Finck            &Entry->TimezoneInfo.StandardDate,
1688c2c66affSColin Finck            sizeof(SYSTEMTIME));
1689c2c66affSColin Finck     memcpy(&TimeZoneInformation.DaylightDate,
1690c2c66affSColin Finck            &Entry->TimezoneInfo.DaylightDate,
1691c2c66affSColin Finck            sizeof(SYSTEMTIME));
1692c2c66affSColin Finck 
1693c2c66affSColin Finck     /* Set time zone information */
1694c2c66affSColin Finck     SetTimeZoneInformation(&TimeZoneInformation);
1695c2c66affSColin Finck }
1696c2c66affSColin Finck 
1697c2c66affSColin Finck 
1698c2c66affSColin Finck static BOOL
1699c2c66affSColin Finck GetLocalSystemTime(HWND hwnd, PSETUPDATA SetupData)
1700c2c66affSColin Finck {
1701c2c66affSColin Finck     SYSTEMTIME Date;
1702c2c66affSColin Finck     SYSTEMTIME Time;
1703c2c66affSColin Finck 
1704c2c66affSColin Finck     if (DateTime_GetSystemtime(GetDlgItem(hwnd, IDC_DATEPICKER), &Date) != GDT_VALID)
1705c2c66affSColin Finck     {
1706c2c66affSColin Finck         return FALSE;
1707c2c66affSColin Finck     }
1708c2c66affSColin Finck 
1709c2c66affSColin Finck     if (DateTime_GetSystemtime(GetDlgItem(hwnd, IDC_TIMEPICKER), &Time) != GDT_VALID)
1710c2c66affSColin Finck     {
1711c2c66affSColin Finck         return FALSE;
1712c2c66affSColin Finck     }
1713c2c66affSColin Finck 
1714c2c66affSColin Finck     SetupData->SystemTime.wYear = Date.wYear;
1715c2c66affSColin Finck     SetupData->SystemTime.wMonth = Date.wMonth;
1716c2c66affSColin Finck     SetupData->SystemTime.wDayOfWeek = Date.wDayOfWeek;
1717c2c66affSColin Finck     SetupData->SystemTime.wDay = Date.wDay;
1718c2c66affSColin Finck     SetupData->SystemTime.wHour = Time.wHour;
1719c2c66affSColin Finck     SetupData->SystemTime.wMinute = Time.wMinute;
1720c2c66affSColin Finck     SetupData->SystemTime.wSecond = Time.wSecond;
1721c2c66affSColin Finck     SetupData->SystemTime.wMilliseconds = Time.wMilliseconds;
1722c2c66affSColin Finck 
1723c2c66affSColin Finck     return TRUE;
1724c2c66affSColin Finck }
1725c2c66affSColin Finck 
1726c2c66affSColin Finck 
1727c2c66affSColin Finck static BOOL
1728c2c66affSColin Finck SetSystemLocalTime(HWND hwnd, PSETUPDATA SetupData)
1729c2c66affSColin Finck {
1730c2c66affSColin Finck     BOOL Ret = FALSE;
1731c2c66affSColin Finck 
1732c2c66affSColin Finck     /*
1733c2c66affSColin Finck      * Call SetLocalTime twice to ensure correct results
1734c2c66affSColin Finck      */
1735c2c66affSColin Finck     Ret = SetLocalTime(&SetupData->SystemTime) &&
1736c2c66affSColin Finck           SetLocalTime(&SetupData->SystemTime);
1737c2c66affSColin Finck 
1738c2c66affSColin Finck     return Ret;
1739c2c66affSColin Finck }
1740c2c66affSColin Finck 
1741c2c66affSColin Finck 
1742c2c66affSColin Finck static VOID
17434cd92f0dSSerge Gautherie UpdateLocalSystemTime(HWND hwnd, SYSTEMTIME LocalTime)
1744c2c66affSColin Finck {
1745c2c66affSColin Finck     DateTime_SetSystemtime(GetDlgItem(hwnd, IDC_DATEPICKER), GDT_VALID, &LocalTime);
1746c2c66affSColin Finck     DateTime_SetSystemtime(GetDlgItem(hwnd, IDC_TIMEPICKER), GDT_VALID, &LocalTime);
1747c2c66affSColin Finck }
1748c2c66affSColin Finck 
1749c2c66affSColin Finck 
1750c2c66affSColin Finck static BOOL
1751c2c66affSColin Finck WriteDateTimeSettings(HWND hwndDlg, PSETUPDATA SetupData)
1752c2c66affSColin Finck {
1753c2c66affSColin Finck     WCHAR Title[64];
1754c2c66affSColin Finck     WCHAR ErrorLocalTime[256];
1755c2c66affSColin Finck 
1756c2c66affSColin Finck     GetLocalSystemTime(hwndDlg, SetupData);
1757c2c66affSColin Finck     SetLocalTimeZone(GetDlgItem(hwndDlg, IDC_TIMEZONELIST),
1758c2c66affSColin Finck                      SetupData);
1759c2c66affSColin Finck 
17607c3e96a2SHermès Bélusca-Maïto     SetAutoDaylight(SendDlgItemMessage(hwndDlg, IDC_AUTODAYLIGHT,
17617c3e96a2SHermès Bélusca-Maïto                                        BM_GETCHECK, 0, 0) != BST_UNCHECKED);
1762c2c66affSColin Finck     if (!SetSystemLocalTime(hwndDlg, SetupData))
1763c2c66affSColin Finck     {
176462678985SHermès Bélusca-Maïto         if (0 == LoadStringW(hDllInstance, IDS_REACTOS_SETUP, Title, ARRAYSIZE(Title)))
1765c2c66affSColin Finck         {
1766c2c66affSColin Finck             wcscpy(Title, L"ReactOS Setup");
1767c2c66affSColin Finck         }
1768c2c66affSColin Finck         if (0 == LoadStringW(hDllInstance, IDS_WZD_LOCALTIME, ErrorLocalTime,
176962678985SHermès Bélusca-Maïto                              ARRAYSIZE(ErrorLocalTime)))
1770c2c66affSColin Finck         {
1771c2c66affSColin Finck             wcscpy(ErrorLocalTime, L"Setup was unable to set the local time.");
1772c2c66affSColin Finck         }
1773c2c66affSColin Finck         MessageBoxW(hwndDlg, ErrorLocalTime, Title, MB_ICONWARNING | MB_OK);
1774c2c66affSColin Finck         return FALSE;
1775c2c66affSColin Finck     }
1776c2c66affSColin Finck 
1777c2c66affSColin Finck     return TRUE;
1778c2c66affSColin Finck }
1779c2c66affSColin Finck 
1780c2c66affSColin Finck 
1781c2c66affSColin Finck static INT_PTR CALLBACK
1782c2c66affSColin Finck DateTimePageDlgProc(HWND hwndDlg,
1783c2c66affSColin Finck                     UINT uMsg,
1784c2c66affSColin Finck                     WPARAM wParam,
1785c2c66affSColin Finck                     LPARAM lParam)
1786c2c66affSColin Finck {
1787c2c66affSColin Finck     PSETUPDATA SetupData;
1788c2c66affSColin Finck 
1789c2c66affSColin Finck     /* Retrieve pointer to the global setup data */
1790d281d14fSTimo Kreuzer     SetupData = (PSETUPDATA)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
1791c2c66affSColin Finck 
1792c2c66affSColin Finck     switch (uMsg)
1793c2c66affSColin Finck     {
1794c2c66affSColin Finck         case WM_INITDIALOG:
17957c3e96a2SHermès Bélusca-Maïto         {
1796c2c66affSColin Finck             /* Save pointer to the global setup data */
1797c2c66affSColin Finck             SetupData = (PSETUPDATA)((LPPROPSHEETPAGE)lParam)->lParam;
1798d281d14fSTimo Kreuzer             SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (DWORD_PTR)SetupData);
1799c2c66affSColin Finck 
1800c2c66affSColin Finck             CreateTimeZoneList(SetupData);
1801c2c66affSColin Finck 
1802c2c66affSColin Finck             if (SetupData->UnattendSetup)
1803c2c66affSColin Finck             {
1804c2c66affSColin Finck                 ShowTimeZoneList(GetDlgItem(hwndDlg, IDC_TIMEZONELIST),
1805c2c66affSColin Finck                                  SetupData, SetupData->TimeZoneIndex);
1806c2c66affSColin Finck 
1807c2c66affSColin Finck                 if (!SetupData->DisableAutoDaylightTimeSet)
1808c2c66affSColin Finck                 {
1809c2c66affSColin Finck                     SendDlgItemMessage(hwndDlg, IDC_AUTODAYLIGHT, BM_SETCHECK, (WPARAM)BST_CHECKED, 0);
1810c2c66affSColin Finck                 }
1811c2c66affSColin Finck             }
1812c2c66affSColin Finck             else
1813c2c66affSColin Finck             {
1814c2c66affSColin Finck                 ShowTimeZoneList(GetDlgItem(hwndDlg, IDC_TIMEZONELIST),
1815c2c66affSColin Finck                                  SetupData, -1);
1816c2c66affSColin Finck 
1817c2c66affSColin Finck                 SendDlgItemMessage(hwndDlg, IDC_AUTODAYLIGHT, BM_SETCHECK, (WPARAM)BST_CHECKED, 0);
1818c2c66affSColin Finck             }
1819c2c66affSColin Finck             break;
18207c3e96a2SHermès Bélusca-Maïto         }
1821c2c66affSColin Finck 
1822c2c66affSColin Finck         case WM_TIMER:
18234cd92f0dSSerge Gautherie         {
18244cd92f0dSSerge Gautherie             SYSTEMTIME LocalTime;
18254cd92f0dSSerge Gautherie 
18264cd92f0dSSerge Gautherie             GetLocalTime(&LocalTime);
18274cd92f0dSSerge Gautherie             UpdateLocalSystemTime(hwndDlg, LocalTime);
18284cd92f0dSSerge Gautherie 
18294cd92f0dSSerge Gautherie             // Reset timeout.
18304cd92f0dSSerge Gautherie             SetTimer(hwndDlg, 1, 1000 - LocalTime.wMilliseconds, NULL);
1831c2c66affSColin Finck             break;
18324cd92f0dSSerge Gautherie         }
1833c2c66affSColin Finck 
1834c2c66affSColin Finck         case WM_NOTIFY:
1835c2c66affSColin Finck             switch (((LPNMHDR)lParam)->code)
1836c2c66affSColin Finck             {
1837c2c66affSColin Finck                 case PSN_SETACTIVE:
18384cd92f0dSSerge Gautherie                 {
18394cd92f0dSSerge Gautherie                     SYSTEMTIME LocalTime;
18404cd92f0dSSerge Gautherie 
18414cd92f0dSSerge Gautherie                     GetLocalTime(&LocalTime);
18424cd92f0dSSerge Gautherie                     UpdateLocalSystemTime(hwndDlg, LocalTime);
18434cd92f0dSSerge Gautherie 
1844c2c66affSColin Finck                     /* Enable the Back and Next buttons */
1845c2c66affSColin Finck                     PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK | PSWIZB_NEXT);
18464cd92f0dSSerge Gautherie 
1847c2c66affSColin Finck                     if (SetupData->UnattendSetup && WriteDateTimeSettings(hwndDlg, SetupData))
1848c2c66affSColin Finck                     {
18490182dcd7STimo Kreuzer                         SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, SetupData->uFirstNetworkWizardPage);
1850c2c66affSColin Finck                         return TRUE;
1851c2c66affSColin Finck                     }
18524cd92f0dSSerge Gautherie 
18534cd92f0dSSerge Gautherie                     SetTimer(hwndDlg, 1, 1000 - LocalTime.wMilliseconds, NULL);
1854c2c66affSColin Finck                     break;
18554cd92f0dSSerge Gautherie                 }
1856c2c66affSColin Finck 
1857c2c66affSColin Finck                 case PSN_KILLACTIVE:
1858c2c66affSColin Finck                 case DTN_DATETIMECHANGE:
18594cd92f0dSSerge Gautherie                     // NB: Not re-set until changing page (PSN_SETACTIVE).
1860c2c66affSColin Finck                     KillTimer(hwndDlg, 1);
1861c2c66affSColin Finck                     break;
1862c2c66affSColin Finck 
1863c2c66affSColin Finck                 case PSN_WIZNEXT:
1864c2c66affSColin Finck                     WriteDateTimeSettings(hwndDlg, SetupData);
1865c2c66affSColin Finck                     break;
1866c2c66affSColin Finck 
1867c2c66affSColin Finck                 case PSN_WIZBACK:
1868c2c66affSColin Finck                     SetupData->UnattendSetup = FALSE;
1869c2c66affSColin Finck                     break;
1870c2c66affSColin Finck 
1871c2c66affSColin Finck                 default:
1872c2c66affSColin Finck                     break;
1873c2c66affSColin Finck             }
1874c2c66affSColin Finck             break;
1875c2c66affSColin Finck 
1876c2c66affSColin Finck         case WM_DESTROY:
1877c2c66affSColin Finck             DestroyTimeZoneList(SetupData);
1878c2c66affSColin Finck             break;
1879c2c66affSColin Finck 
1880c2c66affSColin Finck         default:
1881c2c66affSColin Finck             break;
1882c2c66affSColin Finck     }
1883c2c66affSColin Finck 
1884c2c66affSColin Finck     return FALSE;
1885c2c66affSColin Finck }
1886c2c66affSColin Finck 
18875d4d48a8SMark Jansen static struct ThemeInfo
18885d4d48a8SMark Jansen {
18895d4d48a8SMark Jansen     LPCWSTR PreviewBitmap;
18905d4d48a8SMark Jansen     UINT DisplayName;
18915d4d48a8SMark Jansen     LPCWSTR ThemeFile;
18925d4d48a8SMark Jansen 
18935d4d48a8SMark Jansen } Themes[] = {
18945d4d48a8SMark Jansen     { MAKEINTRESOURCE(IDB_CLASSIC), IDS_CLASSIC, NULL },
18955d4d48a8SMark Jansen     { MAKEINTRESOURCE(IDB_LAUTUS), IDS_LAUTUS, L"themes\\lautus\\lautus.msstyles" },
189621b7648fSAdam Słaboń     { MAKEINTRESOURCE(IDB_LUNAR), IDS_LUNAR, L"themes\\lunar\\lunar.msstyles" },
1897ea799b74SFoxlet     { MAKEINTRESOURCE(IDB_MIZU), IDS_MIZU, L"themes\\mizu\\mizu.msstyles"},
18985d4d48a8SMark Jansen };
1899c2c66affSColin Finck 
1900c2c66affSColin Finck static INT_PTR CALLBACK
1901c2c66affSColin Finck ThemePageDlgProc(HWND hwndDlg,
1902c2c66affSColin Finck                     UINT uMsg,
1903c2c66affSColin Finck                     WPARAM wParam,
1904c2c66affSColin Finck                     LPARAM lParam)
1905c2c66affSColin Finck {
1906c2c66affSColin Finck     PSETUPDATA SetupData;
19075d4d48a8SMark Jansen     LPNMLISTVIEW pnmv;
1908c2c66affSColin Finck 
1909c2c66affSColin Finck     /* Retrieve pointer to the global setup data */
1910d281d14fSTimo Kreuzer     SetupData = (PSETUPDATA)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
1911c2c66affSColin Finck 
1912c2c66affSColin Finck     switch (uMsg)
1913c2c66affSColin Finck     {
1914c2c66affSColin Finck         case WM_INITDIALOG:
1915c2c66affSColin Finck         {
19165d4d48a8SMark Jansen             HWND hListView;
19175d4d48a8SMark Jansen             HIMAGELIST himl;
19185d4d48a8SMark Jansen             DWORD n;
19195d4d48a8SMark Jansen             LVITEM lvi = {0};
1920c2c66affSColin Finck 
1921c2c66affSColin Finck             /* Save pointer to the global setup data */
1922c2c66affSColin Finck             SetupData = (PSETUPDATA)((LPPROPSHEETPAGE)lParam)->lParam;
1923d281d14fSTimo Kreuzer             SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (DWORD_PTR)SetupData);
1924c2c66affSColin Finck 
19255d4d48a8SMark Jansen             hListView = GetDlgItem(hwndDlg, IDC_THEMEPICKER);
1926c2c66affSColin Finck 
19275d4d48a8SMark Jansen             /* Common */
19285d4d48a8SMark Jansen             himl = ImageList_Create(180, 163, ILC_COLOR32 | ILC_MASK, ARRAYSIZE(Themes), 1);
19295d4d48a8SMark Jansen             lvi.mask = LVIF_TEXT | LVIF_IMAGE |LVIF_STATE;
1930c2c66affSColin Finck 
19315d4d48a8SMark Jansen             for (n = 0; n < ARRAYSIZE(Themes); ++n)
19325d4d48a8SMark Jansen             {
19335d4d48a8SMark Jansen                 WCHAR DisplayName[100] = {0};
19345d4d48a8SMark Jansen                 /* Load the bitmap */
19355d4d48a8SMark Jansen                 HANDLE image = LoadImageW(hDllInstance, Themes[n].PreviewBitmap, IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION);
19365d4d48a8SMark Jansen                 ImageList_AddMasked(himl, image, RGB(255,0,255));
19375d4d48a8SMark Jansen 
19385d4d48a8SMark Jansen                 /* Load the string */
19395d4d48a8SMark Jansen                 LoadStringW(hDllInstance, Themes[n].DisplayName, DisplayName, ARRAYSIZE(DisplayName));
19405d4d48a8SMark Jansen                 DisplayName[ARRAYSIZE(DisplayName)-1] = UNICODE_NULL;
19415d4d48a8SMark Jansen 
19425d4d48a8SMark Jansen                 /* Add the listview item */
19435d4d48a8SMark Jansen                 lvi.iItem  = n;
19445d4d48a8SMark Jansen                 lvi.iImage = n;
19455d4d48a8SMark Jansen                 lvi.pszText = DisplayName;
19465d4d48a8SMark Jansen                 ListView_InsertItem(hListView, &lvi);
19475d4d48a8SMark Jansen             }
19485d4d48a8SMark Jansen 
19495d4d48a8SMark Jansen             /* Register the imagelist */
19505d4d48a8SMark Jansen             ListView_SetImageList(hListView, himl, LVSIL_NORMAL);
19515d4d48a8SMark Jansen             /* Transparant background */
19525d4d48a8SMark Jansen             ListView_SetBkColor(hListView, CLR_NONE);
19535d4d48a8SMark Jansen             ListView_SetTextBkColor(hListView, CLR_NONE);
19545d4d48a8SMark Jansen             /* Reduce the size between the items */
19555d4d48a8SMark Jansen             ListView_SetIconSpacing(hListView, 190, 173);
1956c2c66affSColin Finck             break;
1957c2c66affSColin Finck         }
19585d4d48a8SMark Jansen         case WM_NOTIFY:
19595d4d48a8SMark Jansen             switch (((LPNMHDR)lParam)->code)
1960c2c66affSColin Finck             {
19615d4d48a8SMark Jansen                 //case LVN_ITEMCHANGING:
19625d4d48a8SMark Jansen                 case LVN_ITEMCHANGED:
19635d4d48a8SMark Jansen                     pnmv = (LPNMLISTVIEW)lParam;
19645d4d48a8SMark Jansen                     if ((pnmv->uChanged & LVIF_STATE) && (pnmv->uNewState & LVIS_SELECTED))
1965c2c66affSColin Finck                     {
19665d4d48a8SMark Jansen                         int iTheme = pnmv->iItem;
1967774f4977SMark Jansen                         DPRINT1("Selected theme: %u\n", Themes[iTheme].DisplayName);
19685d4d48a8SMark Jansen 
19695d4d48a8SMark Jansen                         if (Themes[iTheme].ThemeFile)
1970c2c66affSColin Finck                         {
1971c2c66affSColin Finck                             WCHAR wszParams[1024];
1972c2c66affSColin Finck                             WCHAR wszTheme[MAX_PATH];
1973c2c66affSColin Finck                             WCHAR* format = L"desk.cpl desk,@Appearance /Action:ActivateMSTheme /file:\"%s\"";
1974c2c66affSColin Finck 
19755d4d48a8SMark Jansen                             SHGetFolderPathAndSubDirW(0, CSIDL_RESOURCES, NULL, SHGFP_TYPE_DEFAULT, Themes[iTheme].ThemeFile, wszTheme);
1976c2c66affSColin Finck                             swprintf(wszParams, format, wszTheme);
1977c2c66affSColin Finck                             RunControlPanelApplet(hwndDlg, wszParams);
1978c2c66affSColin Finck                         }
19795d4d48a8SMark Jansen                         else
1980c2c66affSColin Finck                         {
19815d4d48a8SMark Jansen                             RunControlPanelApplet(hwndDlg, L"desk.cpl desk,@Appearance /Action:ActivateMSTheme");
19825d4d48a8SMark Jansen                         }
19835d4d48a8SMark Jansen                     }
19845d4d48a8SMark Jansen                     break;
1985c2c66affSColin Finck                 case PSN_SETACTIVE:
1986c2c66affSColin Finck                     /* Enable the Back and Next buttons */
1987c2c66affSColin Finck                     PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK | PSWIZB_NEXT);
1988c2c66affSColin Finck                     if (SetupData->UnattendSetup)
1989c2c66affSColin Finck                     {
19900182dcd7STimo Kreuzer                         SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, SetupData->uFirstNetworkWizardPage);
1991c2c66affSColin Finck                         return TRUE;
1992c2c66affSColin Finck                     }
1993c2c66affSColin Finck                     break;
1994c2c66affSColin Finck 
1995c2c66affSColin Finck                 case PSN_WIZNEXT:
1996c2c66affSColin Finck                     break;
1997c2c66affSColin Finck 
1998c2c66affSColin Finck                 case PSN_WIZBACK:
1999c2c66affSColin Finck                     SetupData->UnattendSetup = FALSE;
2000c2c66affSColin Finck                     break;
2001c2c66affSColin Finck 
2002c2c66affSColin Finck                 default:
2003c2c66affSColin Finck                     break;
2004c2c66affSColin Finck             }
2005c2c66affSColin Finck             break;
2006c2c66affSColin Finck 
2007c2c66affSColin Finck         default:
2008c2c66affSColin Finck             break;
2009c2c66affSColin Finck     }
2010c2c66affSColin Finck 
2011c2c66affSColin Finck     return FALSE;
2012c2c66affSColin Finck }
2013c2c66affSColin Finck 
2014c2c66affSColin Finck static UINT CALLBACK
2015c2c66affSColin Finck RegistrationNotificationProc(PVOID Context,
2016c2c66affSColin Finck                              UINT Notification,
2017c2c66affSColin Finck                              UINT_PTR Param1,
2018c2c66affSColin Finck                              UINT_PTR Param2)
2019c2c66affSColin Finck {
2020c2c66affSColin Finck     PREGISTRATIONDATA RegistrationData;
2021c2c66affSColin Finck     REGISTRATIONNOTIFY RegistrationNotify;
2022c2c66affSColin Finck     PSP_REGISTER_CONTROL_STATUSW StatusInfo;
2023c2c66affSColin Finck     UINT MessageID;
2024c2c66affSColin Finck 
2025c2c66affSColin Finck     RegistrationData = (PREGISTRATIONDATA)Context;
2026c2c66affSColin Finck 
20273f053db3SEric Kohl     if (Notification == SPFILENOTIFY_STARTREGISTRATION ||
20283f053db3SEric Kohl         Notification == SPFILENOTIFY_ENDREGISTRATION)
2029c2c66affSColin Finck     {
2030c2c66affSColin Finck         StatusInfo = (PSP_REGISTER_CONTROL_STATUSW) Param1;
2031c2c66affSColin Finck         RegistrationNotify.CurrentItem = wcsrchr(StatusInfo->FileName, L'\\');
20323f053db3SEric Kohl         if (RegistrationNotify.CurrentItem == NULL)
2033c2c66affSColin Finck         {
2034c2c66affSColin Finck             RegistrationNotify.CurrentItem = StatusInfo->FileName;
2035c2c66affSColin Finck         }
2036c2c66affSColin Finck         else
2037c2c66affSColin Finck         {
2038c2c66affSColin Finck             RegistrationNotify.CurrentItem++;
2039c2c66affSColin Finck         }
2040c2c66affSColin Finck 
20413f053db3SEric Kohl         if (Notification == SPFILENOTIFY_STARTREGISTRATION)
2042c2c66affSColin Finck         {
2043c2c66affSColin Finck             DPRINT("Received SPFILENOTIFY_STARTREGISTRATION notification for %S\n",
2044c2c66affSColin Finck                    StatusInfo->FileName);
2045c2c66affSColin Finck             RegistrationNotify.ErrorMessage = NULL;
2046c2c66affSColin Finck             RegistrationNotify.Progress = RegistrationData->Registered;
20473f053db3SEric Kohl             SendMessage(RegistrationData->hwndDlg, PM_STEP_START, 0, (LPARAM)&RegistrationNotify);
2048c2c66affSColin Finck         }
2049c2c66affSColin Finck         else
2050c2c66affSColin Finck         {
2051c2c66affSColin Finck             DPRINT("Received SPFILENOTIFY_ENDREGISTRATION notification for %S\n",
2052c2c66affSColin Finck                    StatusInfo->FileName);
2053c2c66affSColin Finck             DPRINT("Win32Error %u FailureCode %u\n", StatusInfo->Win32Error,
2054c2c66affSColin Finck                    StatusInfo->FailureCode);
20553f053db3SEric Kohl             if (StatusInfo->FailureCode != SPREG_SUCCESS)
2056c2c66affSColin Finck             {
2057c2c66affSColin Finck                 switch (StatusInfo->FailureCode)
2058c2c66affSColin Finck                 {
2059c2c66affSColin Finck                     case SPREG_LOADLIBRARY:
2060c2c66affSColin Finck                         MessageID = IDS_LOADLIBRARY_FAILED;
2061c2c66affSColin Finck                         break;
2062c2c66affSColin Finck                     case SPREG_GETPROCADDR:
2063c2c66affSColin Finck                         MessageID = IDS_GETPROCADDR_FAILED;
2064c2c66affSColin Finck                         break;
2065c2c66affSColin Finck                     case SPREG_REGSVR:
2066c2c66affSColin Finck                         MessageID = IDS_REGSVR_FAILED;
2067c2c66affSColin Finck                         break;
2068c2c66affSColin Finck                     case SPREG_DLLINSTALL:
2069c2c66affSColin Finck                         MessageID = IDS_DLLINSTALL_FAILED;
2070c2c66affSColin Finck                         break;
2071c2c66affSColin Finck                     case SPREG_TIMEOUT:
2072c2c66affSColin Finck                         MessageID = IDS_TIMEOUT;
2073c2c66affSColin Finck                         break;
2074c2c66affSColin Finck                     default:
2075c2c66affSColin Finck                         MessageID = IDS_REASON_UNKNOWN;
2076c2c66affSColin Finck                         break;
2077c2c66affSColin Finck                 }
20783f053db3SEric Kohl 
20793f053db3SEric Kohl                 RegistrationNotify.MessageID = MessageID;
20803f053db3SEric Kohl                 RegistrationNotify.LastError = StatusInfo->Win32Error;
2081c2c66affSColin Finck             }
2082c2c66affSColin Finck             else
2083c2c66affSColin Finck             {
20843f053db3SEric Kohl                 RegistrationNotify.MessageID = 0;
20853f053db3SEric Kohl                 RegistrationNotify.LastError = ERROR_SUCCESS;
2086c2c66affSColin Finck             }
20873f053db3SEric Kohl 
2088c2c66affSColin Finck             if (RegistrationData->Registered < RegistrationData->DllCount)
2089c2c66affSColin Finck             {
2090c2c66affSColin Finck                 RegistrationData->Registered++;
2091c2c66affSColin Finck             }
2092c2c66affSColin Finck 
2093c2c66affSColin Finck             RegistrationNotify.Progress = RegistrationData->Registered;
20943f053db3SEric Kohl             SendMessage(RegistrationData->hwndDlg, PM_STEP_END, 0, (LPARAM)&RegistrationNotify);
20953f053db3SEric Kohl         }
2096c2c66affSColin Finck 
2097c2c66affSColin Finck         return FILEOP_DOIT;
2098c2c66affSColin Finck     }
2099c2c66affSColin Finck     else
2100c2c66affSColin Finck     {
2101c2c66affSColin Finck         DPRINT1("Received unexpected notification %u\n", Notification);
2102c2c66affSColin Finck         return SetupDefaultQueueCallback(RegistrationData->DefaultContext,
2103c2c66affSColin Finck                                          Notification, Param1, Param2);
2104c2c66affSColin Finck     }
2105c2c66affSColin Finck }
2106c2c66affSColin Finck 
2107c2c66affSColin Finck 
21083f053db3SEric Kohl static
21093f053db3SEric Kohl DWORD
21103f053db3SEric Kohl RegisterDlls(
21113f053db3SEric Kohl     PITEMSDATA pItemsData)
2112c2c66affSColin Finck {
21133f053db3SEric Kohl     REGISTRATIONDATA RegistrationData;
21143f053db3SEric Kohl     WCHAR SectionName[512];
21153f053db3SEric Kohl     INFCONTEXT Context;
21163f053db3SEric Kohl     LONG DllCount = 0;
2117c2c66affSColin Finck     DWORD LastError = NO_ERROR;
2118c2c66affSColin Finck 
21193f053db3SEric Kohl     ZeroMemory(&RegistrationData, sizeof(REGISTRATIONDATA));
21203f053db3SEric Kohl     RegistrationData.hwndDlg = pItemsData->hwndDlg;
21213f053db3SEric Kohl     RegistrationData.Registered = 0;
21223f053db3SEric Kohl 
21233f053db3SEric Kohl     if (!SetupFindFirstLineW(hSysSetupInf, L"RegistrationPhase2",
21243f053db3SEric Kohl                              L"RegisterDlls", &Context))
21253f053db3SEric Kohl     {
21263f053db3SEric Kohl         DPRINT1("No RegistrationPhase2 section found\n");
21273f053db3SEric Kohl         return FALSE;
21283f053db3SEric Kohl     }
21293f053db3SEric Kohl 
21303f053db3SEric Kohl     if (!SetupGetStringFieldW(&Context, 1, SectionName,
21313f053db3SEric Kohl                               ARRAYSIZE(SectionName),
21323f053db3SEric Kohl                               NULL))
21333f053db3SEric Kohl     {
21343f053db3SEric Kohl         DPRINT1("Unable to retrieve section name\n");
21353f053db3SEric Kohl         return FALSE;
21363f053db3SEric Kohl     }
21373f053db3SEric Kohl 
21383f053db3SEric Kohl     DllCount = SetupGetLineCountW(hSysSetupInf, SectionName);
21393f053db3SEric Kohl     DPRINT1("SectionName %S DllCount %ld\n", SectionName, DllCount);
21403f053db3SEric Kohl     if (DllCount < 0)
21413f053db3SEric Kohl     {
21423f053db3SEric Kohl         SetLastError(STATUS_NOT_FOUND);
21433f053db3SEric Kohl         return FALSE;
21443f053db3SEric Kohl     }
21453f053db3SEric Kohl 
21463f053db3SEric Kohl     RegistrationData.DllCount = (ULONG)DllCount;
21473f053db3SEric Kohl     RegistrationData.DefaultContext = SetupInitDefaultQueueCallback(RegistrationData.hwndDlg);
21483f053db3SEric Kohl 
21493f053db3SEric Kohl     SendMessage(pItemsData->hwndDlg, PM_ITEM_START, 0, (LPARAM)RegistrationData.DllCount);
2150c2c66affSColin Finck 
2151c2c66affSColin Finck     _SEH2_TRY
2152c2c66affSColin Finck     {
21533f053db3SEric Kohl         if (!SetupInstallFromInfSectionW(GetParent(RegistrationData.hwndDlg),
2154c2c66affSColin Finck                                          hSysSetupInf,
2155c2c66affSColin Finck                                          L"RegistrationPhase2",
21563f053db3SEric Kohl                                          SPINST_REGISTRY | SPINST_REGISTERCALLBACKAWARE | SPINST_REGSVR,
2157c2c66affSColin Finck                                          0,
2158c2c66affSColin Finck                                          NULL,
2159c2c66affSColin Finck                                          0,
2160c2c66affSColin Finck                                          RegistrationNotificationProc,
21613f053db3SEric Kohl                                          &RegistrationData,
2162c2c66affSColin Finck                                          NULL,
2163c2c66affSColin Finck                                          NULL))
2164c2c66affSColin Finck         {
2165c2c66affSColin Finck             LastError = GetLastError();
2166c2c66affSColin Finck         }
2167c2c66affSColin Finck     }
2168c2c66affSColin Finck     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
2169c2c66affSColin Finck     {
2170c2c66affSColin Finck         DPRINT("Catching exception\n");
2171c2c66affSColin Finck         LastError = RtlNtStatusToDosError(_SEH2_GetExceptionCode());
2172c2c66affSColin Finck     }
2173c2c66affSColin Finck     _SEH2_END;
2174c2c66affSColin Finck 
21753f053db3SEric Kohl     SetupTermDefaultQueueCallback(RegistrationData.DefaultContext);
2176c2c66affSColin Finck 
21773f053db3SEric Kohl     SendMessage(pItemsData->hwndDlg, PM_ITEM_END, 0, LastError);
2178c2c66affSColin Finck 
2179c2c66affSColin Finck     return 0;
2180c2c66affSColin Finck }
2181c2c66affSColin Finck 
2182c2c66affSColin Finck 
21833f053db3SEric Kohl static
21843f053db3SEric Kohl DWORD
21853f053db3SEric Kohl CALLBACK
21863f053db3SEric Kohl ItemCompletionThread(
21873f053db3SEric Kohl     LPVOID Parameter)
2188c2c66affSColin Finck {
21893f053db3SEric Kohl     PITEMSDATA pItemsData;
21903f053db3SEric Kohl     HWND hwndDlg;
2191c2c66affSColin Finck 
21923f053db3SEric Kohl     pItemsData = (PITEMSDATA)Parameter;
21933f053db3SEric Kohl     hwndDlg = pItemsData->hwndDlg;
21943f053db3SEric Kohl 
21953f053db3SEric Kohl     RegisterDlls(pItemsData);
21963f053db3SEric Kohl 
21973f053db3SEric Kohl     RegisterTypeLibraries(hSysSetupInf, L"TypeLibraries");
21983f053db3SEric Kohl 
21993f053db3SEric Kohl     /* FIXME: Add completion steps here! */
22003f053db3SEric Kohl 
22013f053db3SEric Kohl     // FIXME: Move this call to a separate cleanup page!
22023f053db3SEric Kohl     RtlCreateBootStatusDataFile();
22033f053db3SEric Kohl 
22043f053db3SEric Kohl     /* Free the items data */
22053f053db3SEric Kohl     HeapFree(GetProcessHeap(), 0, pItemsData);
22063f053db3SEric Kohl 
22073f053db3SEric Kohl     /* Tell the wizard page that we are done */
22083f053db3SEric Kohl     PostMessage(hwndDlg, PM_ITEMS_DONE, 0, 0);
22093f053db3SEric Kohl 
22103f053db3SEric Kohl     return 0;
2211c2c66affSColin Finck }
2212c2c66affSColin Finck 
2213c2c66affSColin Finck 
22143f053db3SEric Kohl static
22153f053db3SEric Kohl BOOL
22163f053db3SEric Kohl RunItemCompletionThread(
22173f053db3SEric Kohl     _In_ HWND hwndDlg)
2218c2c66affSColin Finck {
22193f053db3SEric Kohl     HANDLE hCompletionThread;
22203f053db3SEric Kohl     PITEMSDATA pItemsData;
22213f053db3SEric Kohl 
22223f053db3SEric Kohl     pItemsData = HeapAlloc(GetProcessHeap(), 0, sizeof(ITEMSDATA));
22233f053db3SEric Kohl     if (pItemsData == NULL)
22243f053db3SEric Kohl         return FALSE;
22253f053db3SEric Kohl 
22263f053db3SEric Kohl     pItemsData->hwndDlg = hwndDlg;
22273f053db3SEric Kohl 
22283f053db3SEric Kohl     hCompletionThread = CreateThread(NULL,
22293f053db3SEric Kohl                                      0,
22303f053db3SEric Kohl                                      ItemCompletionThread,
22313f053db3SEric Kohl                                      pItemsData,
22323f053db3SEric Kohl                                      0,
22333f053db3SEric Kohl                                      NULL);
22343f053db3SEric Kohl     if (hCompletionThread == NULL)
2235c2c66affSColin Finck     {
22363f053db3SEric Kohl         HeapFree(GetProcessHeap(), 0, pItemsData);
2237c2c66affSColin Finck     }
2238c2c66affSColin Finck     else
2239c2c66affSColin Finck     {
22403f053db3SEric Kohl         CloseHandle(hCompletionThread);
2241c2c66affSColin Finck         return TRUE;
2242c2c66affSColin Finck     }
2243c2c66affSColin Finck 
22443f053db3SEric Kohl     return FALSE;
22453f053db3SEric Kohl }
22463f053db3SEric Kohl 
22473f053db3SEric Kohl static
22483f053db3SEric Kohl VOID
22493f053db3SEric Kohl ShowItemError(
22503f053db3SEric Kohl     HWND hwndDlg,
22513f053db3SEric Kohl     DWORD LastError)
22523f053db3SEric Kohl {
22533f053db3SEric Kohl     LPWSTR ErrorMessage = NULL;
22543f053db3SEric Kohl     WCHAR UnknownError[84];
22553f053db3SEric Kohl     WCHAR Title[64];
22563f053db3SEric Kohl 
22573f053db3SEric Kohl     if (FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
22583f053db3SEric Kohl                        NULL, LastError, 0, ErrorMessage, 0, NULL) == 0)
22593f053db3SEric Kohl     {
22603f053db3SEric Kohl         if (LoadStringW(hDllInstance, IDS_UNKNOWN_ERROR,
22613f053db3SEric Kohl                         UnknownError,
22623f053db3SEric Kohl                         ARRAYSIZE(UnknownError) - 20) == 0)
22633f053db3SEric Kohl         {
22643f053db3SEric Kohl             wcscpy(UnknownError, L"Unknown error");
22653f053db3SEric Kohl         }
22663f053db3SEric Kohl         wcscat(UnknownError, L" ");
22673f053db3SEric Kohl         _ultow(LastError, UnknownError + wcslen(UnknownError), 10);
22683f053db3SEric Kohl         ErrorMessage = UnknownError;
22693f053db3SEric Kohl     }
22703f053db3SEric Kohl 
22713f053db3SEric Kohl     if (ErrorMessage != NULL)
22723f053db3SEric Kohl     {
22733f053db3SEric Kohl         if (LoadStringW(hDllInstance, IDS_REACTOS_SETUP,
22743f053db3SEric Kohl                         Title, ARRAYSIZE(Title)) == 0)
22753f053db3SEric Kohl         {
22763f053db3SEric Kohl             wcscpy(Title, L"ReactOS Setup");
22773f053db3SEric Kohl         }
22783f053db3SEric Kohl 
22793f053db3SEric Kohl         MessageBoxW(hwndDlg, ErrorMessage, Title, MB_ICONERROR | MB_OK);
22803f053db3SEric Kohl     }
22813f053db3SEric Kohl 
22823f053db3SEric Kohl     if (ErrorMessage != NULL &&
22833f053db3SEric Kohl         ErrorMessage != UnknownError)
22843f053db3SEric Kohl     {
22853f053db3SEric Kohl         LocalFree(ErrorMessage);
22863f053db3SEric Kohl     }
22873f053db3SEric Kohl }
22883f053db3SEric Kohl 
22893f053db3SEric Kohl 
22903f053db3SEric Kohl static
22913f053db3SEric Kohl VOID
22923f053db3SEric Kohl ShowStepError(
22933f053db3SEric Kohl     HWND hwndDlg,
22943f053db3SEric Kohl     PREGISTRATIONNOTIFY RegistrationNotify)
22953f053db3SEric Kohl {
22963f053db3SEric Kohl     WCHAR ErrorMessage[128];
22973f053db3SEric Kohl     WCHAR Title[64];
22983f053db3SEric Kohl 
22993f053db3SEric Kohl     if (LoadStringW(hDllInstance, RegistrationNotify->MessageID,
23003f053db3SEric Kohl                     ErrorMessage,
23013f053db3SEric Kohl                     ARRAYSIZE(ErrorMessage)) == 0)
23023f053db3SEric Kohl     {
23033f053db3SEric Kohl         ErrorMessage[0] = L'\0';
23043f053db3SEric Kohl     }
23053f053db3SEric Kohl 
23063f053db3SEric Kohl     if (RegistrationNotify->MessageID != IDS_TIMEOUT)
23073f053db3SEric Kohl     {
23083f053db3SEric Kohl         FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM, NULL,
23093f053db3SEric Kohl                        RegistrationNotify->LastError, 0,
23103f053db3SEric Kohl                        ErrorMessage + wcslen(ErrorMessage),
23113f053db3SEric Kohl                        ARRAYSIZE(ErrorMessage) - wcslen(ErrorMessage),
23123f053db3SEric Kohl                        NULL);
23133f053db3SEric Kohl     }
23143f053db3SEric Kohl 
23153f053db3SEric Kohl     if (ErrorMessage[0] != L'\0')
23163f053db3SEric Kohl     {
23173f053db3SEric Kohl         if (LoadStringW(hDllInstance, IDS_REACTOS_SETUP,
23183f053db3SEric Kohl                         Title, ARRAYSIZE(Title)) == 0)
23193f053db3SEric Kohl         {
23203f053db3SEric Kohl             wcscpy(Title, L"ReactOS Setup");
23213f053db3SEric Kohl         }
23223f053db3SEric Kohl 
23233f053db3SEric Kohl         MessageBoxW(hwndDlg, ErrorMessage,
23243f053db3SEric Kohl                     Title, MB_ICONERROR | MB_OK);
23253f053db3SEric Kohl     }
23263f053db3SEric Kohl }
23273f053db3SEric Kohl 
2328c2c66affSColin Finck 
2329c2c66affSColin Finck static INT_PTR CALLBACK
2330c2c66affSColin Finck ProcessPageDlgProc(HWND hwndDlg,
2331c2c66affSColin Finck                    UINT uMsg,
2332c2c66affSColin Finck                    WPARAM wParam,
2333c2c66affSColin Finck                    LPARAM lParam)
2334c2c66affSColin Finck {
2335c2c66affSColin Finck     PSETUPDATA SetupData;
2336c2c66affSColin Finck     PREGISTRATIONNOTIFY RegistrationNotify;
2337c2c66affSColin Finck 
2338c2c66affSColin Finck     /* Retrieve pointer to the global setup data */
2339d281d14fSTimo Kreuzer     SetupData = (PSETUPDATA)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
2340c2c66affSColin Finck 
2341c2c66affSColin Finck     switch (uMsg)
2342c2c66affSColin Finck     {
2343c2c66affSColin Finck         case WM_INITDIALOG:
2344c2c66affSColin Finck             /* Save pointer to the global setup data */
2345c2c66affSColin Finck             SetupData = (PSETUPDATA)((LPPROPSHEETPAGE)lParam)->lParam;
2346d281d14fSTimo Kreuzer             SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (DWORD_PTR)SetupData);
23473f053db3SEric Kohl             ShowWindow(GetDlgItem(hwndDlg, IDC_TASKTEXT2), SW_HIDE);
23483f053db3SEric Kohl             ShowWindow(GetDlgItem(hwndDlg, IDC_TASKTEXT3), SW_HIDE);
23493f053db3SEric Kohl             ShowWindow(GetDlgItem(hwndDlg, IDC_TASKTEXT4), SW_HIDE);
2350c2c66affSColin Finck             break;
2351c2c66affSColin Finck 
2352c2c66affSColin Finck         case WM_NOTIFY:
23533f053db3SEric Kohl             switch (((LPNMHDR)lParam)->code)
2354c2c66affSColin Finck             {
2355c2c66affSColin Finck                 case PSN_SETACTIVE:
2356c2c66affSColin Finck                     /* Disable the Back and Next buttons */
2357c2c66affSColin Finck                     PropSheet_SetWizButtons(GetParent(hwndDlg), 0);
23583f053db3SEric Kohl                     RunItemCompletionThread(hwndDlg);
2359c2c66affSColin Finck                     break;
2360c2c66affSColin Finck 
2361c2c66affSColin Finck                 case PSN_WIZNEXT:
2362c2c66affSColin Finck                     break;
2363c2c66affSColin Finck 
2364c2c66affSColin Finck                 case PSN_WIZBACK:
2365c2c66affSColin Finck                     SetupData->UnattendSetup = FALSE;
2366c2c66affSColin Finck                     break;
2367c2c66affSColin Finck 
2368c2c66affSColin Finck                 default:
2369c2c66affSColin Finck                     break;
2370c2c66affSColin Finck             }
23713f053db3SEric Kohl             break;
23723f053db3SEric Kohl 
23733f053db3SEric Kohl         case PM_ITEM_START:
2374b76d49bcSEric Kohl             DPRINT("PM_ITEM_START %lu\n", (ULONG)lParam);
23753f053db3SEric Kohl             SendDlgItemMessage(hwndDlg, IDC_PROCESSPROGRESS, PBM_SETRANGE, 0, MAKELPARAM(0, (ULONG)lParam));
23763f053db3SEric Kohl             SendDlgItemMessage(hwndDlg, IDC_PROCESSPROGRESS, PBM_SETPOS, 0, 0);
23773f053db3SEric Kohl             SendDlgItemMessage(hwndDlg, IDC_TASKTEXT1 + wParam, WM_SETFONT, (WPARAM)SetupData->hBoldFont, (LPARAM)TRUE);
23783f053db3SEric Kohl             break;
23793f053db3SEric Kohl 
23803f053db3SEric Kohl         case PM_ITEM_END:
2381b76d49bcSEric Kohl             DPRINT("PM_ITEM_END\n");
23823f053db3SEric Kohl             if (lParam == ERROR_SUCCESS)
23833f053db3SEric Kohl             {
23843f053db3SEric Kohl             }
23853f053db3SEric Kohl             else
23863f053db3SEric Kohl             {
23873f053db3SEric Kohl                 ShowItemError(hwndDlg, (DWORD)lParam);
2388c2c66affSColin Finck             }
2389c2c66affSColin Finck             break;
2390c2c66affSColin Finck 
23913f053db3SEric Kohl         case PM_STEP_START:
2392b76d49bcSEric Kohl             DPRINT("PM_STEP_START\n");
2393c2c66affSColin Finck             RegistrationNotify = (PREGISTRATIONNOTIFY)lParam;
23943f053db3SEric Kohl             SendDlgItemMessage(hwndDlg, IDC_ITEM, WM_SETTEXT, 0,
23953f053db3SEric Kohl                                (LPARAM)((RegistrationNotify->CurrentItem != NULL)? RegistrationNotify->CurrentItem : L""));
23963f053db3SEric Kohl             break;
2397c2c66affSColin Finck 
23983f053db3SEric Kohl         case PM_STEP_END:
2399b76d49bcSEric Kohl             DPRINT("PM_STEP_END\n");
24003f053db3SEric Kohl             RegistrationNotify = (PREGISTRATIONNOTIFY)lParam;
24013f053db3SEric Kohl             SendDlgItemMessage(hwndDlg, IDC_PROCESSPROGRESS, PBM_SETPOS, RegistrationNotify->Progress, 0);
24023f053db3SEric Kohl             if (RegistrationNotify->LastError != ERROR_SUCCESS)
2403c2c66affSColin Finck             {
24043f053db3SEric Kohl                 ShowStepError(hwndDlg, RegistrationNotify);
24053f053db3SEric Kohl             }
24063f053db3SEric Kohl             break;
24073f053db3SEric Kohl 
24083f053db3SEric Kohl         case PM_ITEMS_DONE:
2409b76d49bcSEric Kohl             DPRINT("PM_ITEMS_DONE\n");
2410c2c66affSColin Finck             /* Enable the Back and Next buttons */
2411c2c66affSColin Finck             PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT);
2412c2c66affSColin Finck             PropSheet_PressButton(GetParent(hwndDlg), PSBTN_NEXT);
24133f053db3SEric Kohl             break;
2414c2c66affSColin Finck 
2415c2c66affSColin Finck         default:
2416c2c66affSColin Finck             break;
2417c2c66affSColin Finck     }
2418c2c66affSColin Finck 
2419c2c66affSColin Finck     return FALSE;
2420c2c66affSColin Finck }
2421c2c66affSColin Finck 
2422c2c66affSColin Finck 
2423c2c66affSColin Finck static VOID
2424c2c66affSColin Finck SetInstallationCompleted(VOID)
2425c2c66affSColin Finck {
2426c2c66affSColin Finck     HKEY hKey = 0;
2427c2c66affSColin Finck     DWORD InProgress = 0;
2428c2c66affSColin Finck     DWORD InstallDate;
2429c2c66affSColin Finck 
2430c2c66affSColin Finck     if (RegOpenKeyExW( HKEY_LOCAL_MACHINE,
2431c2c66affSColin Finck                        L"SYSTEM\\Setup",
2432c2c66affSColin Finck                        0,
2433c2c66affSColin Finck                        KEY_WRITE,
2434c2c66affSColin Finck                        &hKey ) == ERROR_SUCCESS)
2435c2c66affSColin Finck     {
2436c2c66affSColin Finck         RegSetValueExW( hKey, L"SystemSetupInProgress", 0, REG_DWORD, (LPBYTE)&InProgress, sizeof(InProgress) );
2437c2c66affSColin Finck         RegCloseKey( hKey );
2438c2c66affSColin Finck     }
2439c2c66affSColin Finck 
2440c2c66affSColin Finck     if (RegOpenKeyExW( HKEY_LOCAL_MACHINE,
2441c2c66affSColin Finck                        L"Software\\Microsoft\\Windows NT\\CurrentVersion",
2442c2c66affSColin Finck                        0,
2443c2c66affSColin Finck                        KEY_WRITE,
2444c2c66affSColin Finck                        &hKey ) == ERROR_SUCCESS)
2445c2c66affSColin Finck     {
2446c2c66affSColin Finck         InstallDate = (DWORD)time(NULL);
2447c2c66affSColin Finck         RegSetValueExW( hKey, L"InstallDate", 0, REG_DWORD, (LPBYTE)&InstallDate, sizeof(InstallDate) );
2448c2c66affSColin Finck         RegCloseKey( hKey );
2449c2c66affSColin Finck     }
2450c2c66affSColin Finck }
2451c2c66affSColin Finck 
2452c2c66affSColin Finck static INT_PTR CALLBACK
2453c2c66affSColin Finck FinishDlgProc(HWND hwndDlg,
2454c2c66affSColin Finck               UINT uMsg,
2455c2c66affSColin Finck               WPARAM wParam,
2456c2c66affSColin Finck               LPARAM lParam)
2457c2c66affSColin Finck {
2458c2c66affSColin Finck 
2459c2c66affSColin Finck     switch (uMsg)
2460c2c66affSColin Finck     {
2461c2c66affSColin Finck         case WM_INITDIALOG:
2462c2c66affSColin Finck         {
2463c2c66affSColin Finck             /* Get pointer to the global setup data */
2464c2c66affSColin Finck             PSETUPDATA SetupData = (PSETUPDATA)((LPPROPSHEETPAGE)lParam)->lParam;
2465c2c66affSColin Finck 
2466c2c66affSColin Finck             if (!SetupData->UnattendSetup || !SetupData->DisableGeckoInst)
2467c2c66affSColin Finck             {
2468c2c66affSColin Finck                 /* Run the Wine Gecko prompt */
2469c2c66affSColin Finck                 Control_RunDLLW(hwndDlg, 0, L"appwiz.cpl install_gecko", SW_SHOW);
2470c2c66affSColin Finck             }
2471c2c66affSColin Finck 
2472c2c66affSColin Finck             /* Set title font */
2473c2c66affSColin Finck             SendDlgItemMessage(hwndDlg,
2474c2c66affSColin Finck                                IDC_FINISHTITLE,
2475c2c66affSColin Finck                                WM_SETFONT,
2476c2c66affSColin Finck                                (WPARAM)SetupData->hTitleFont,
2477c2c66affSColin Finck                                (LPARAM)TRUE);
2478c2c66affSColin Finck             if (SetupData->UnattendSetup)
2479c2c66affSColin Finck             {
2480c2c66affSColin Finck                 KillTimer(hwndDlg, 1);
2481c2c66affSColin Finck                 SetInstallationCompleted();
2482c2c66affSColin Finck                 PostQuitMessage(0);
2483c2c66affSColin Finck             }
2484c2c66affSColin Finck         }
2485c2c66affSColin Finck         break;
2486c2c66affSColin Finck 
2487c2c66affSColin Finck         case WM_DESTROY:
2488c2c66affSColin Finck         {
2489c2c66affSColin Finck             SetInstallationCompleted();
2490c2c66affSColin Finck             PostQuitMessage(0);
2491c2c66affSColin Finck             return TRUE;
2492c2c66affSColin Finck         }
2493c2c66affSColin Finck 
2494c2c66affSColin Finck         case WM_TIMER:
2495c2c66affSColin Finck         {
2496c2c66affSColin Finck             INT Position;
2497c2c66affSColin Finck             HWND hWndProgress;
2498c2c66affSColin Finck 
2499c2c66affSColin Finck             hWndProgress = GetDlgItem(hwndDlg, IDC_RESTART_PROGRESS);
2500c2c66affSColin Finck             Position = SendMessage(hWndProgress, PBM_GETPOS, 0, 0);
2501c2c66affSColin Finck             if (Position == 300)
2502c2c66affSColin Finck             {
2503c2c66affSColin Finck                 KillTimer(hwndDlg, 1);
2504c2c66affSColin Finck                 PropSheet_PressButton(GetParent(hwndDlg), PSBTN_FINISH);
2505c2c66affSColin Finck             }
2506c2c66affSColin Finck             else
2507c2c66affSColin Finck             {
2508c2c66affSColin Finck                 SendMessage(hWndProgress, PBM_SETPOS, Position + 1, 0);
2509c2c66affSColin Finck             }
2510c2c66affSColin Finck         }
2511c2c66affSColin Finck         return TRUE;
2512c2c66affSColin Finck 
2513c2c66affSColin Finck         case WM_NOTIFY:
2514c2c66affSColin Finck         {
2515c2c66affSColin Finck             LPNMHDR lpnm = (LPNMHDR)lParam;
2516c2c66affSColin Finck 
2517c2c66affSColin Finck             switch (lpnm->code)
2518c2c66affSColin Finck             {
2519c2c66affSColin Finck                 case PSN_SETACTIVE:
2520c2c66affSColin Finck                     /* Enable the correct buttons on for the active page */
2521c2c66affSColin Finck                     PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_FINISH);
2522c2c66affSColin Finck 
2523c2c66affSColin Finck                     SendDlgItemMessage(hwndDlg, IDC_RESTART_PROGRESS, PBM_SETRANGE, 0,
2524c2c66affSColin Finck                                        MAKELPARAM(0, 300));
2525c2c66affSColin Finck                     SendDlgItemMessage(hwndDlg, IDC_RESTART_PROGRESS, PBM_SETPOS, 0, 0);
2526c2c66affSColin Finck                     SetTimer(hwndDlg, 1, 50, NULL);
2527c2c66affSColin Finck                     break;
2528c2c66affSColin Finck 
2529c2c66affSColin Finck                 case PSN_WIZFINISH:
2530c2c66affSColin Finck                     DestroyWindow(GetParent(hwndDlg));
2531c2c66affSColin Finck                     break;
2532c2c66affSColin Finck 
2533c2c66affSColin Finck                 default:
2534c2c66affSColin Finck                     break;
2535c2c66affSColin Finck             }
2536c2c66affSColin Finck         }
2537c2c66affSColin Finck         break;
2538c2c66affSColin Finck 
2539c2c66affSColin Finck         default:
2540c2c66affSColin Finck             break;
2541c2c66affSColin Finck     }
2542c2c66affSColin Finck 
2543c2c66affSColin Finck     return FALSE;
2544c2c66affSColin Finck }
2545c2c66affSColin Finck 
2546c2c66affSColin Finck 
2547c8d37c1aSHermès Bélusca-Maïto /*
2548c8d37c1aSHermès Bélusca-Maïto  * GetInstallSourceWin32 retrieves the path to the ReactOS installation medium
2549c8d37c1aSHermès Bélusca-Maïto  * in Win32 format, for later use by syssetup and storage in the registry.
2550c8d37c1aSHermès Bélusca-Maïto  */
2551c8d37c1aSHermès Bélusca-Maïto static BOOL
2552c8d37c1aSHermès Bélusca-Maïto GetInstallSourceWin32(
2553c8d37c1aSHermès Bélusca-Maïto     OUT PWSTR pwszPath,
2554c8d37c1aSHermès Bélusca-Maïto     IN DWORD cchPathMax,
2555c8d37c1aSHermès Bélusca-Maïto     IN PCWSTR pwszNTPath)
2556c8d37c1aSHermès Bélusca-Maïto {
2557c8d37c1aSHermès Bélusca-Maïto     WCHAR wszDrives[512];
2558c8d37c1aSHermès Bélusca-Maïto     WCHAR wszNTPath[512]; // MAX_PATH ?
2559c8d37c1aSHermès Bélusca-Maïto     DWORD cchDrives;
2560c8d37c1aSHermès Bélusca-Maïto     PWCHAR pwszDrive;
2561c8d37c1aSHermès Bélusca-Maïto 
2562c8d37c1aSHermès Bélusca-Maïto     *pwszPath = UNICODE_NULL;
2563c8d37c1aSHermès Bélusca-Maïto 
2564c8d37c1aSHermès Bélusca-Maïto     cchDrives = GetLogicalDriveStringsW(_countof(wszDrives) - 1, wszDrives);
2565c8d37c1aSHermès Bélusca-Maïto     if (cchDrives == 0 || cchDrives >= _countof(wszDrives))
2566c8d37c1aSHermès Bélusca-Maïto     {
2567c8d37c1aSHermès Bélusca-Maïto         /* Buffer too small or failure */
2568c8d37c1aSHermès Bélusca-Maïto         LogItem(NULL, L"GetLogicalDriveStringsW failed");
2569c8d37c1aSHermès Bélusca-Maïto         return FALSE;
2570c8d37c1aSHermès Bélusca-Maïto     }
2571c8d37c1aSHermès Bélusca-Maïto 
2572c8d37c1aSHermès Bélusca-Maïto     for (pwszDrive = wszDrives; *pwszDrive; pwszDrive += wcslen(pwszDrive) + 1)
2573c8d37c1aSHermès Bélusca-Maïto     {
2574c8d37c1aSHermès Bélusca-Maïto         WCHAR wszBuf[MAX_PATH];
2575c8d37c1aSHermès Bélusca-Maïto 
2576c8d37c1aSHermès Bélusca-Maïto         /* Retrieve the NT path corresponding to the current Win32 DOS path */
2577c8d37c1aSHermès Bélusca-Maïto         pwszDrive[2] = UNICODE_NULL; // Temporarily remove the backslash
2578c8d37c1aSHermès Bélusca-Maïto         QueryDosDeviceW(pwszDrive, wszNTPath, _countof(wszNTPath));
2579c8d37c1aSHermès Bélusca-Maïto         pwszDrive[2] = L'\\';        // Restore the backslash
2580c8d37c1aSHermès Bélusca-Maïto 
2581c8d37c1aSHermès Bélusca-Maïto         wcscat(wszNTPath, L"\\");    // Concat a backslash
2582c8d37c1aSHermès Bélusca-Maïto 
2583c8d37c1aSHermès Bélusca-Maïto         /* Logging */
2584c8d37c1aSHermès Bélusca-Maïto         wsprintf(wszBuf, L"Testing '%s' --> '%s' %s a CD",
2585c8d37c1aSHermès Bélusca-Maïto                  pwszDrive, wszNTPath,
2586c8d37c1aSHermès Bélusca-Maïto                  (GetDriveTypeW(pwszDrive) == DRIVE_CDROM) ? L"is" : L"is not");
2587c8d37c1aSHermès Bélusca-Maïto         LogItem(NULL, wszBuf);
2588c8d37c1aSHermès Bélusca-Maïto 
2589c8d37c1aSHermès Bélusca-Maïto         /* Check whether the NT path corresponds to the NT installation source path */
2590c8d37c1aSHermès Bélusca-Maïto         if (!_wcsicmp(wszNTPath, pwszNTPath))
2591c8d37c1aSHermès Bélusca-Maïto         {
2592c8d37c1aSHermès Bélusca-Maïto             /* Found it! */
2593c8d37c1aSHermès Bélusca-Maïto             wcscpy(pwszPath, pwszDrive); // cchPathMax
2594c8d37c1aSHermès Bélusca-Maïto 
2595c8d37c1aSHermès Bélusca-Maïto             /* Logging */
2596c8d37c1aSHermès Bélusca-Maïto             wsprintf(wszBuf, L"GetInstallSourceWin32: %s", pwszPath);
2597c8d37c1aSHermès Bélusca-Maïto             LogItem(NULL, wszBuf);
2598c8d37c1aSHermès Bélusca-Maïto             wcscat(wszBuf, L"\n");
2599c8d37c1aSHermès Bélusca-Maïto             OutputDebugStringW(wszBuf);
2600c8d37c1aSHermès Bélusca-Maïto 
2601c8d37c1aSHermès Bélusca-Maïto             return TRUE;
2602c8d37c1aSHermès Bélusca-Maïto         }
2603c8d37c1aSHermès Bélusca-Maïto     }
2604c8d37c1aSHermès Bélusca-Maïto 
2605c8d37c1aSHermès Bélusca-Maïto     return FALSE;
2606c8d37c1aSHermès Bélusca-Maïto }
2607c8d37c1aSHermès Bélusca-Maïto 
2608c2c66affSColin Finck VOID
2609c8d37c1aSHermès Bélusca-Maïto ProcessUnattendSection(
2610c8d37c1aSHermès Bélusca-Maïto     IN OUT PSETUPDATA pSetupData)
2611c2c66affSColin Finck {
2612c2c66affSColin Finck     INFCONTEXT InfContext;
2613c2c66affSColin Finck     WCHAR szName[256];
2614c2c66affSColin Finck     WCHAR szValue[MAX_PATH];
2615c2c66affSColin Finck     DWORD LineLength;
2616c2c66affSColin Finck     HKEY hKey;
2617c2c66affSColin Finck 
2618c8d37c1aSHermès Bélusca-Maïto     if (!SetupFindFirstLineW(pSetupData->hSetupInf,
2619c2c66affSColin Finck                              L"Unattend",
2620c2c66affSColin Finck                              L"UnattendSetupEnabled",
2621c2c66affSColin Finck                              &InfContext))
2622c2c66affSColin Finck     {
2623e9893906SHermès Bélusca-Maïto         DPRINT1("Error: Cannot find UnattendSetupEnabled Key! %d\n", GetLastError());
2624c2c66affSColin Finck         return;
2625c2c66affSColin Finck     }
2626c2c66affSColin Finck 
2627c2c66affSColin Finck     if (!SetupGetStringFieldW(&InfContext,
2628c2c66affSColin Finck                               1,
2629c2c66affSColin Finck                               szValue,
263062678985SHermès Bélusca-Maïto                               ARRAYSIZE(szValue),
2631c2c66affSColin Finck                               &LineLength))
2632c2c66affSColin Finck     {
2633c2c66affSColin Finck         DPRINT1("Error: SetupGetStringField failed with %d\n", GetLastError());
2634c2c66affSColin Finck         return;
2635c2c66affSColin Finck     }
2636c2c66affSColin Finck 
263762678985SHermès Bélusca-Maïto     if (_wcsicmp(szValue, L"yes") != 0)
2638c2c66affSColin Finck     {
2639c2c66affSColin Finck         DPRINT("Unattend setup was disabled by UnattendSetupEnabled key.\n");
2640c2c66affSColin Finck         return;
2641c2c66affSColin Finck     }
2642c2c66affSColin Finck 
2643c2c66affSColin Finck     pSetupData->UnattendSetup = TRUE;
2644c2c66affSColin Finck 
2645c8d37c1aSHermès Bélusca-Maïto     if (!SetupFindFirstLineW(pSetupData->hSetupInf,
2646c2c66affSColin Finck                              L"Unattend",
2647c2c66affSColin Finck                              NULL,
2648c2c66affSColin Finck                              &InfContext))
2649c2c66affSColin Finck     {
2650c2c66affSColin Finck         DPRINT1("Error: SetupFindFirstLine failed %d\n", GetLastError());
2651c2c66affSColin Finck         return;
2652c2c66affSColin Finck     }
2653c2c66affSColin Finck 
2654c2c66affSColin Finck     do
2655c2c66affSColin Finck     {
2656c2c66affSColin Finck         if (!SetupGetStringFieldW(&InfContext,
2657c2c66affSColin Finck                                   0,
2658c2c66affSColin Finck                                   szName,
265962678985SHermès Bélusca-Maïto                                   ARRAYSIZE(szName),
2660c2c66affSColin Finck                                   &LineLength))
2661c2c66affSColin Finck         {
2662c2c66affSColin Finck             DPRINT1("Error: SetupGetStringField failed with %d\n", GetLastError());
2663c2c66affSColin Finck             return;
2664c2c66affSColin Finck         }
2665c2c66affSColin Finck 
2666c2c66affSColin Finck         if (!SetupGetStringFieldW(&InfContext,
2667c2c66affSColin Finck                                   1,
2668c2c66affSColin Finck                                   szValue,
266962678985SHermès Bélusca-Maïto                                   ARRAYSIZE(szValue),
2670c2c66affSColin Finck                                   &LineLength))
2671c2c66affSColin Finck         {
2672c2c66affSColin Finck             DPRINT1("Error: SetupGetStringField failed with %d\n", GetLastError());
2673c2c66affSColin Finck             return;
2674c2c66affSColin Finck         }
2675c2c66affSColin Finck         DPRINT1("Name %S Value %S\n", szName, szValue);
267662678985SHermès Bélusca-Maïto         if (!_wcsicmp(szName, L"FullName"))
2677c2c66affSColin Finck         {
267862678985SHermès Bélusca-Maïto             if (ARRAYSIZE(pSetupData->OwnerName) > LineLength)
2679c2c66affSColin Finck             {
2680c2c66affSColin Finck                 wcscpy(pSetupData->OwnerName, szValue);
2681c2c66affSColin Finck             }
2682c2c66affSColin Finck         }
268362678985SHermès Bélusca-Maïto         else if (!_wcsicmp(szName, L"OrgName"))
2684c2c66affSColin Finck         {
268562678985SHermès Bélusca-Maïto             if (ARRAYSIZE(pSetupData->OwnerOrganization) > LineLength)
2686c2c66affSColin Finck             {
2687c2c66affSColin Finck                 wcscpy(pSetupData->OwnerOrganization, szValue);
2688c2c66affSColin Finck             }
2689c2c66affSColin Finck         }
269062678985SHermès Bélusca-Maïto         else if (!_wcsicmp(szName, L"ComputerName"))
2691c2c66affSColin Finck         {
269262678985SHermès Bélusca-Maïto             if (ARRAYSIZE(pSetupData->ComputerName) > LineLength)
2693c2c66affSColin Finck             {
2694c2c66affSColin Finck                 wcscpy(pSetupData->ComputerName, szValue);
2695c2c66affSColin Finck             }
2696c2c66affSColin Finck         }
269762678985SHermès Bélusca-Maïto         else if (!_wcsicmp(szName, L"AdminPassword"))
2698c2c66affSColin Finck         {
269962678985SHermès Bélusca-Maïto             if (ARRAYSIZE(pSetupData->AdminPassword) > LineLength)
2700c2c66affSColin Finck             {
2701c2c66affSColin Finck                 wcscpy(pSetupData->AdminPassword, szValue);
2702c2c66affSColin Finck             }
2703c2c66affSColin Finck         }
270462678985SHermès Bélusca-Maïto         else if (!_wcsicmp(szName, L"TimeZoneIndex"))
2705c2c66affSColin Finck         {
2706c2c66affSColin Finck             pSetupData->TimeZoneIndex = _wtoi(szValue);
2707c2c66affSColin Finck         }
270862678985SHermès Bélusca-Maïto         else if (!_wcsicmp(szName, L"DisableAutoDaylightTimeSet"))
2709c2c66affSColin Finck         {
2710c2c66affSColin Finck             pSetupData->DisableAutoDaylightTimeSet = _wtoi(szValue);
2711c2c66affSColin Finck         }
271262678985SHermès Bélusca-Maïto         else if (!_wcsicmp(szName, L"DisableGeckoInst"))
2713c2c66affSColin Finck         {
271462678985SHermès Bélusca-Maïto             if (!_wcsicmp(szValue, L"yes"))
2715e9893906SHermès Bélusca-Maïto                 pSetupData->DisableGeckoInst = TRUE;
2716c2c66affSColin Finck             else
2717e9893906SHermès Bélusca-Maïto                 pSetupData->DisableGeckoInst = FALSE;
2718c2c66affSColin Finck         }
2719612729b0SKatayama Hirofumi MZ         else if (!_wcsicmp(szName, L"ProductOption"))
2720612729b0SKatayama Hirofumi MZ         {
2721612729b0SKatayama Hirofumi MZ             pSetupData->ProductOption = (PRODUCT_OPTION)_wtoi(szValue);
2722612729b0SKatayama Hirofumi MZ         }
2723e9893906SHermès Bélusca-Maïto     } while (SetupFindNextLine(&InfContext, &InfContext));
2724c2c66affSColin Finck 
2725c8d37c1aSHermès Bélusca-Maïto     if (SetupFindFirstLineW(pSetupData->hSetupInf,
2726c2c66affSColin Finck                             L"Display",
2727c2c66affSColin Finck                             NULL,
2728c2c66affSColin Finck                             &InfContext))
2729c2c66affSColin Finck     {
2730c2c66affSColin Finck         DEVMODEW dm = { { 0 } };
2731c2c66affSColin Finck         dm.dmSize = sizeof(dm);
2732c2c66affSColin Finck         if (EnumDisplaySettingsW(NULL, ENUM_CURRENT_SETTINGS, &dm))
2733c2c66affSColin Finck         {
2734c2c66affSColin Finck             do
2735c2c66affSColin Finck             {
2736c2c66affSColin Finck                 int iValue;
2737c2c66affSColin Finck                 if (!SetupGetStringFieldW(&InfContext,
2738c2c66affSColin Finck                                           0,
2739c2c66affSColin Finck                                           szName,
274062678985SHermès Bélusca-Maïto                                           ARRAYSIZE(szName),
2741c2c66affSColin Finck                                           &LineLength))
2742c2c66affSColin Finck                 {
2743c2c66affSColin Finck                     DPRINT1("Error: SetupGetStringField failed with %d\n", GetLastError());
2744c2c66affSColin Finck                     return;
2745c2c66affSColin Finck                 }
2746c2c66affSColin Finck 
2747c2c66affSColin Finck                 if (!SetupGetStringFieldW(&InfContext,
2748c2c66affSColin Finck                                           1,
2749c2c66affSColin Finck                                           szValue,
275062678985SHermès Bélusca-Maïto                                           ARRAYSIZE(szValue),
2751c2c66affSColin Finck                                           &LineLength))
2752c2c66affSColin Finck                 {
2753c2c66affSColin Finck                     DPRINT1("Error: SetupGetStringField failed with %d\n", GetLastError());
2754c2c66affSColin Finck                     return;
2755c2c66affSColin Finck                 }
2756c2c66affSColin Finck                 iValue = _wtoi(szValue);
2757c2c66affSColin Finck                 DPRINT1("Name %S Value %i\n", szName, iValue);
2758c2c66affSColin Finck 
2759c2c66affSColin Finck                 if (!iValue)
2760c2c66affSColin Finck                     continue;
2761c2c66affSColin Finck 
276262678985SHermès Bélusca-Maïto                 if (!_wcsicmp(szName, L"BitsPerPel"))
2763c2c66affSColin Finck                 {
2764c2c66affSColin Finck                     dm.dmFields |= DM_BITSPERPEL;
2765c2c66affSColin Finck                     dm.dmBitsPerPel = iValue;
2766c2c66affSColin Finck                 }
276762678985SHermès Bélusca-Maïto                 else if (!_wcsicmp(szName, L"XResolution"))
2768c2c66affSColin Finck                 {
2769c2c66affSColin Finck                     dm.dmFields |= DM_PELSWIDTH;
2770c2c66affSColin Finck                     dm.dmPelsWidth = iValue;
2771c2c66affSColin Finck                 }
277262678985SHermès Bélusca-Maïto                 else if (!_wcsicmp(szName, L"YResolution"))
2773c2c66affSColin Finck                 {
2774c2c66affSColin Finck                     dm.dmFields |= DM_PELSHEIGHT;
2775c2c66affSColin Finck                     dm.dmPelsHeight = iValue;
2776c2c66affSColin Finck                 }
277762678985SHermès Bélusca-Maïto                 else if (!_wcsicmp(szName, L"VRefresh"))
2778c2c66affSColin Finck                 {
2779c2c66affSColin Finck                     dm.dmFields |= DM_DISPLAYFREQUENCY;
2780c2c66affSColin Finck                     dm.dmDisplayFrequency = iValue;
2781c2c66affSColin Finck                 }
2782e9893906SHermès Bélusca-Maïto             } while (SetupFindNextLine(&InfContext, &InfContext));
2783c2c66affSColin Finck 
2784c2c66affSColin Finck             ChangeDisplaySettingsW(&dm, CDS_UPDATEREGISTRY);
2785c2c66affSColin Finck         }
2786c2c66affSColin Finck     }
2787c2c66affSColin Finck 
2788c2c66affSColin Finck     if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,
2789c2c66affSColin Finck                       L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunOnce",
2790c2c66affSColin Finck                       0,
2791c2c66affSColin Finck                       KEY_SET_VALUE,
2792c2c66affSColin Finck                       &hKey) != ERROR_SUCCESS)
2793c2c66affSColin Finck     {
2794c2c66affSColin Finck         DPRINT1("Error: failed to open HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\RunOnce\n");
2795c2c66affSColin Finck         return;
2796c2c66affSColin Finck     }
2797c2c66affSColin Finck 
2798c8d37c1aSHermès Bélusca-Maïto     if (SetupFindFirstLineW(pSetupData->hSetupInf,
2799c2c66affSColin Finck                             L"GuiRunOnce",
2800c2c66affSColin Finck                             NULL,
2801c2c66affSColin Finck                             &InfContext))
2802c2c66affSColin Finck     {
2803c2c66affSColin Finck         int i = 0;
2804c2c66affSColin Finck         do
2805c2c66affSColin Finck         {
2806c2c66affSColin Finck             if (SetupGetStringFieldW(&InfContext,
2807c2c66affSColin Finck                                      0,
2808c2c66affSColin Finck                                      szValue,
280962678985SHermès Bélusca-Maïto                                      ARRAYSIZE(szValue),
2810c2c66affSColin Finck                                      NULL))
2811c2c66affSColin Finck             {
2812c2c66affSColin Finck                 WCHAR szPath[MAX_PATH];
2813c2c66affSColin Finck                 swprintf(szName, L"%d", i);
2814c2c66affSColin Finck                 DPRINT("szName %S szValue %S\n", szName, szValue);
2815c2c66affSColin Finck 
2816c2c66affSColin Finck                 if (ExpandEnvironmentStringsW(szValue, szPath, MAX_PATH))
2817c2c66affSColin Finck                 {
2818c2c66affSColin Finck                     DPRINT("value %S\n", szPath);
2819c2c66affSColin Finck                     if (RegSetValueExW(hKey,
2820c2c66affSColin Finck                                        szName,
2821c2c66affSColin Finck                                        0,
2822c2c66affSColin Finck                                        REG_SZ,
2823c2c66affSColin Finck                                        (const BYTE*)szPath,
2824c2c66affSColin Finck                                        (wcslen(szPath) + 1) * sizeof(WCHAR)) == ERROR_SUCCESS)
2825c2c66affSColin Finck                     {
2826c2c66affSColin Finck                         i++;
2827c2c66affSColin Finck                     }
2828c2c66affSColin Finck                 }
2829c2c66affSColin Finck             }
2830c2c66affSColin Finck         } while (SetupFindNextLine(&InfContext, &InfContext));
2831c2c66affSColin Finck     }
2832c2c66affSColin Finck 
2833c2c66affSColin Finck     RegCloseKey(hKey);
2834*d4e38a63SMark Jansen 
2835*d4e38a63SMark Jansen     if (SetupFindFirstLineW(pSetupData->hSetupInf,
2836*d4e38a63SMark Jansen         L"Env",
2837*d4e38a63SMark Jansen         NULL,
2838*d4e38a63SMark Jansen         &InfContext))
2839*d4e38a63SMark Jansen     {
2840*d4e38a63SMark Jansen         if (RegCreateKeyExW(
2841*d4e38a63SMark Jansen                 HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment", 0, NULL,
2842*d4e38a63SMark Jansen                 REG_OPTION_NON_VOLATILE, KEY_WRITE | KEY_READ, NULL, &hKey, NULL) != ERROR_SUCCESS)
2843*d4e38a63SMark Jansen         {
2844*d4e38a63SMark Jansen             DPRINT1("Error: failed to open HKLM\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment\n");
2845*d4e38a63SMark Jansen             return;
2846*d4e38a63SMark Jansen         }
2847*d4e38a63SMark Jansen         do
2848*d4e38a63SMark Jansen         {
2849*d4e38a63SMark Jansen             if (!SetupGetStringFieldW(&InfContext,
2850*d4e38a63SMark Jansen                 0,
2851*d4e38a63SMark Jansen                 szName,
2852*d4e38a63SMark Jansen                 ARRAYSIZE(szName),
2853*d4e38a63SMark Jansen                 &LineLength))
2854*d4e38a63SMark Jansen             {
2855*d4e38a63SMark Jansen                 DPRINT1("Error: SetupGetStringField failed with %d\n", GetLastError());
2856*d4e38a63SMark Jansen                 return;
2857*d4e38a63SMark Jansen             }
2858*d4e38a63SMark Jansen 
2859*d4e38a63SMark Jansen             if (!SetupGetStringFieldW(&InfContext,
2860*d4e38a63SMark Jansen                 1,
2861*d4e38a63SMark Jansen                 szValue,
2862*d4e38a63SMark Jansen                 ARRAYSIZE(szValue),
2863*d4e38a63SMark Jansen                 &LineLength))
2864*d4e38a63SMark Jansen             {
2865*d4e38a63SMark Jansen                 DPRINT1("Error: SetupGetStringField failed with %d\n", GetLastError());
2866*d4e38a63SMark Jansen                 return;
2867*d4e38a63SMark Jansen             }
2868*d4e38a63SMark Jansen             DPRINT1("[ENV] %S=%S\n", szName, szValue);
2869*d4e38a63SMark Jansen 
2870*d4e38a63SMark Jansen             DWORD dwType = wcschr(szValue, '%') != NULL ? REG_EXPAND_SZ : REG_SZ;
2871*d4e38a63SMark Jansen 
2872*d4e38a63SMark Jansen             if (RegSetValueExW(hKey, szName, 0, dwType, (const BYTE*)szValue, (DWORD)(wcslen(szValue) + 1) * sizeof(TCHAR)) != ERROR_SUCCESS)
2873*d4e38a63SMark Jansen             {
2874*d4e38a63SMark Jansen                 DPRINT1(" - Error %d\n", GetLastError());
2875*d4e38a63SMark Jansen             }
2876*d4e38a63SMark Jansen 
2877*d4e38a63SMark Jansen         } while (SetupFindNextLine(&InfContext, &InfContext));
2878*d4e38a63SMark Jansen 
2879*d4e38a63SMark Jansen         RegCloseKey(hKey);
2880*d4e38a63SMark Jansen     }
2881c2c66affSColin Finck }
2882c2c66affSColin Finck 
2883c2c66affSColin Finck VOID
2884c8d37c1aSHermès Bélusca-Maïto ProcessSetupInf(
2885c8d37c1aSHermès Bélusca-Maïto     IN OUT PSETUPDATA pSetupData)
2886c2c66affSColin Finck {
2887c2c66affSColin Finck     WCHAR szPath[MAX_PATH];
2888c8d37c1aSHermès Bélusca-Maïto     WCHAR szValue[MAX_PATH];
2889c8d37c1aSHermès Bélusca-Maïto     INFCONTEXT InfContext;
2890c8d37c1aSHermès Bélusca-Maïto     DWORD LineLength;
2891c8d37c1aSHermès Bélusca-Maïto     HKEY hKey;
2892c8d37c1aSHermès Bélusca-Maïto     LONG res;
2893c2c66affSColin Finck 
2894c8d37c1aSHermès Bélusca-Maïto     pSetupData->hSetupInf = INVALID_HANDLE_VALUE;
2895c2c66affSColin Finck 
2896c8d37c1aSHermès Bélusca-Maïto     /* Retrieve the path of the setup INF */
2897c8d37c1aSHermès Bélusca-Maïto     GetSystemDirectoryW(szPath, _countof(szPath));
2898c8d37c1aSHermès Bélusca-Maïto     wcscat(szPath, L"\\$winnt$.inf");
2899c2c66affSColin Finck 
2900c8d37c1aSHermès Bélusca-Maïto     /* Open the setup INF */
2901c8d37c1aSHermès Bélusca-Maïto     pSetupData->hSetupInf = SetupOpenInfFileW(szPath,
2902c2c66affSColin Finck                                               NULL,
2903c2c66affSColin Finck                                               INF_STYLE_OLDNT,
2904c2c66affSColin Finck                                               NULL);
2905c8d37c1aSHermès Bélusca-Maïto     if (pSetupData->hSetupInf == INVALID_HANDLE_VALUE)
2906c2c66affSColin Finck     {
2907c8d37c1aSHermès Bélusca-Maïto         DPRINT1("Error: Cannot open the setup information file %S with error %d\n", szPath, GetLastError());
2908c8d37c1aSHermès Bélusca-Maïto         return;
2909c2c66affSColin Finck     }
2910c8d37c1aSHermès Bélusca-Maïto 
2911c8d37c1aSHermès Bélusca-Maïto 
2912c8d37c1aSHermès Bélusca-Maïto     /* Retrieve the NT source path from which the 1st-stage installer was run */
2913c8d37c1aSHermès Bélusca-Maïto     if (!SetupFindFirstLineW(pSetupData->hSetupInf,
2914c8d37c1aSHermès Bélusca-Maïto                              L"data",
2915c8d37c1aSHermès Bélusca-Maïto                              L"sourcepath",
2916c8d37c1aSHermès Bélusca-Maïto                              &InfContext))
2917c8d37c1aSHermès Bélusca-Maïto     {
2918bae08335SMark Jansen         DPRINT1("Error: Cannot find sourcepath Key! %d\n", GetLastError());
2919c8d37c1aSHermès Bélusca-Maïto         return;
2920c8d37c1aSHermès Bélusca-Maïto     }
2921c8d37c1aSHermès Bélusca-Maïto 
2922c8d37c1aSHermès Bélusca-Maïto     if (!SetupGetStringFieldW(&InfContext,
2923c8d37c1aSHermès Bélusca-Maïto                               1,
2924c8d37c1aSHermès Bélusca-Maïto                               szValue,
2925c8d37c1aSHermès Bélusca-Maïto                               ARRAYSIZE(szValue),
2926c8d37c1aSHermès Bélusca-Maïto                               &LineLength))
2927c8d37c1aSHermès Bélusca-Maïto     {
2928c8d37c1aSHermès Bélusca-Maïto         DPRINT1("Error: SetupGetStringField failed with %d\n", GetLastError());
2929c8d37c1aSHermès Bélusca-Maïto         return;
2930c8d37c1aSHermès Bélusca-Maïto     }
2931c8d37c1aSHermès Bélusca-Maïto 
2932c8d37c1aSHermès Bélusca-Maïto     *pSetupData->SourcePath = UNICODE_NULL;
2933c8d37c1aSHermès Bélusca-Maïto 
2934c8d37c1aSHermès Bélusca-Maïto     /* Close the setup INF as we are going to modify it manually */
2935c8d37c1aSHermès Bélusca-Maïto     if (pSetupData->hSetupInf != INVALID_HANDLE_VALUE)
2936c8d37c1aSHermès Bélusca-Maïto         SetupCloseInfFile(pSetupData->hSetupInf);
2937c8d37c1aSHermès Bélusca-Maïto 
2938c8d37c1aSHermès Bélusca-Maïto 
2939c8d37c1aSHermès Bélusca-Maïto     /* Find the installation source path in Win32 format */
2940c8d37c1aSHermès Bélusca-Maïto     if (!GetInstallSourceWin32(pSetupData->SourcePath,
2941c8d37c1aSHermès Bélusca-Maïto                                _countof(pSetupData->SourcePath),
2942c8d37c1aSHermès Bélusca-Maïto                                szValue))
2943c8d37c1aSHermès Bélusca-Maïto     {
2944c8d37c1aSHermès Bélusca-Maïto         *pSetupData->SourcePath = UNICODE_NULL;
2945c8d37c1aSHermès Bélusca-Maïto     }
2946c8d37c1aSHermès Bélusca-Maïto 
2947c8d37c1aSHermès Bélusca-Maïto     /* Save the path in Win32 format in the setup INF */
2948c8d37c1aSHermès Bélusca-Maïto     swprintf(szValue, L"\"%s\"", pSetupData->SourcePath);
2949c8d37c1aSHermès Bélusca-Maïto     WritePrivateProfileStringW(L"data", L"dospath", szValue, szPath);
2950c8d37c1aSHermès Bélusca-Maïto 
2951c8d37c1aSHermès Bélusca-Maïto     /*
2952c8d37c1aSHermès Bélusca-Maïto      * Save it also in the registry, in the following keys:
2953c8d37c1aSHermès Bélusca-Maïto      * - HKLM\Software\Microsoft\Windows\CurrentVersion\Setup ,
2954c8d37c1aSHermès Bélusca-Maïto      *   values "SourcePath" and "ServicePackSourcePath" (REG_SZ);
2955c8d37c1aSHermès Bélusca-Maïto      * - HKLM\Software\Microsoft\Windows NT\CurrentVersion ,
2956c8d37c1aSHermès Bélusca-Maïto      *   value "SourcePath" (REG_SZ); set to the full path (e.g. D:\I386).
2957c8d37c1aSHermès Bélusca-Maïto      */
2958c8d37c1aSHermès Bélusca-Maïto #if 0
2959c8d37c1aSHermès Bélusca-Maïto     res = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
2960c8d37c1aSHermès Bélusca-Maïto                         L"Software\\Microsoft\\Windows NT\\CurrentVersion",
2961c8d37c1aSHermès Bélusca-Maïto                         0,
2962c8d37c1aSHermès Bélusca-Maïto                         KEY_ALL_ACCESS,
2963c8d37c1aSHermès Bélusca-Maïto                         &hKey);
2964c8d37c1aSHermès Bélusca-Maïto 
2965c8d37c1aSHermès Bélusca-Maïto     if (res != ERROR_SUCCESS)
2966c8d37c1aSHermès Bélusca-Maïto     {
2967c8d37c1aSHermès Bélusca-Maïto         return FALSE;
2968c8d37c1aSHermès Bélusca-Maïto     }
2969c8d37c1aSHermès Bélusca-Maïto #endif
2970c8d37c1aSHermès Bélusca-Maïto 
2971c8d37c1aSHermès Bélusca-Maïto     res = RegCreateKeyExW(HKEY_LOCAL_MACHINE,
2972c8d37c1aSHermès Bélusca-Maïto                           L"Software\\Microsoft\\Windows\\CurrentVersion\\Setup",
2973c8d37c1aSHermès Bélusca-Maïto                           0, NULL,
2974c8d37c1aSHermès Bélusca-Maïto                           REG_OPTION_NON_VOLATILE,
2975c8d37c1aSHermès Bélusca-Maïto                           KEY_ALL_ACCESS, // KEY_WRITE
2976c8d37c1aSHermès Bélusca-Maïto                           NULL,
2977c8d37c1aSHermès Bélusca-Maïto                           &hKey,
2978c8d37c1aSHermès Bélusca-Maïto                           NULL);
2979c8d37c1aSHermès Bélusca-Maïto     if (res == ERROR_SUCCESS)
2980c8d37c1aSHermès Bélusca-Maïto     {
2981c8d37c1aSHermès Bélusca-Maïto         res = RegSetValueExW(hKey,
2982c8d37c1aSHermès Bélusca-Maïto                              L"SourcePath",
2983c8d37c1aSHermès Bélusca-Maïto                              0,
2984c8d37c1aSHermès Bélusca-Maïto                              REG_SZ,
2985c8d37c1aSHermès Bélusca-Maïto                              (LPBYTE)pSetupData->SourcePath,
2986c8d37c1aSHermès Bélusca-Maïto                              (wcslen(pSetupData->SourcePath) + 1) * sizeof(WCHAR));
2987c8d37c1aSHermès Bélusca-Maïto 
2988c8d37c1aSHermès Bélusca-Maïto         res = RegSetValueExW(hKey,
2989c8d37c1aSHermès Bélusca-Maïto                              L"ServicePackSourcePath",
2990c8d37c1aSHermès Bélusca-Maïto                              0,
2991c8d37c1aSHermès Bélusca-Maïto                              REG_SZ,
2992c8d37c1aSHermès Bélusca-Maïto                              (LPBYTE)pSetupData->SourcePath,
2993c8d37c1aSHermès Bélusca-Maïto                              (wcslen(pSetupData->SourcePath) + 1) * sizeof(WCHAR));
2994c8d37c1aSHermès Bélusca-Maïto 
2995c8d37c1aSHermès Bélusca-Maïto         RegCloseKey(hKey);
2996c8d37c1aSHermès Bélusca-Maïto     }
2997c8d37c1aSHermès Bélusca-Maïto 
2998c8d37c1aSHermès Bélusca-Maïto 
2999c8d37c1aSHermès Bélusca-Maïto     /* Now, re-open the setup INF (this must succeed) */
3000c8d37c1aSHermès Bélusca-Maïto     pSetupData->hSetupInf = SetupOpenInfFileW(szPath,
3001c8d37c1aSHermès Bélusca-Maïto                                               NULL,
3002c8d37c1aSHermès Bélusca-Maïto                                               INF_STYLE_OLDNT,
3003c8d37c1aSHermès Bélusca-Maïto                                               NULL);
3004c8d37c1aSHermès Bélusca-Maïto     if (pSetupData->hSetupInf == INVALID_HANDLE_VALUE)
3005c8d37c1aSHermès Bélusca-Maïto     {
3006c8d37c1aSHermès Bélusca-Maïto         DPRINT1("Error: Cannot open the setup information file %S with error %d\n", szPath, GetLastError());
3007c8d37c1aSHermès Bélusca-Maïto         return;
3008c8d37c1aSHermès Bélusca-Maïto     }
3009c8d37c1aSHermès Bélusca-Maïto 
3010c8d37c1aSHermès Bélusca-Maïto     /* Process the unattended section of the setup file */
3011c8d37c1aSHermès Bélusca-Maïto     ProcessUnattendSection(pSetupData);
3012c2c66affSColin Finck }
3013c2c66affSColin Finck 
3014c2c66affSColin Finck typedef DWORD(WINAPI *PFNREQUESTWIZARDPAGES)(PDWORD, HPROPSHEETPAGE *, PSETUPDATA);
3015c2c66affSColin Finck 
3016c2c66affSColin Finck VOID
3017c2c66affSColin Finck InstallWizard(VOID)
3018c2c66affSColin Finck {
301909edc062SMark Jansen     PROPSHEETHEADER psh = {0};
3020c2c66affSColin Finck     HPROPSHEETPAGE *phpage = NULL;
3021c2c66affSColin Finck     PROPSHEETPAGE psp = {0};
3022c2c66affSColin Finck     UINT nPages = 0;
3023c2c66affSColin Finck     HWND hWnd;
3024c2c66affSColin Finck     MSG msg;
3025c2c66affSColin Finck     PSETUPDATA pSetupData = NULL;
3026c2c66affSColin Finck     HMODULE hNetShell = NULL;
3027c2c66affSColin Finck     PFNREQUESTWIZARDPAGES pfn = NULL;
302848160c74SKatayama Hirofumi MZ     DWORD dwPageCount = 10, dwNetworkPageCount = 0;
3029c2c66affSColin Finck 
3030c2c66affSColin Finck     LogItem(L"BEGIN_SECTION", L"InstallWizard");
3031c2c66affSColin Finck 
3032c2c66affSColin Finck     /* Allocate setup data */
3033c2c66affSColin Finck     pSetupData = HeapAlloc(GetProcessHeap(),
3034c2c66affSColin Finck                            HEAP_ZERO_MEMORY,
3035c2c66affSColin Finck                            sizeof(SETUPDATA));
3036c2c66affSColin Finck     if (pSetupData == NULL)
3037c2c66affSColin Finck     {
3038c2c66affSColin Finck         LogItem(NULL, L"SetupData allocation failed!");
3039c2c66affSColin Finck         MessageBoxW(NULL,
3040c2c66affSColin Finck                     L"Setup failed to allocate global data!",
3041c2c66affSColin Finck                     L"ReactOS Setup",
3042c2c66affSColin Finck                     MB_ICONERROR | MB_OK);
3043c2c66affSColin Finck         goto done;
3044c2c66affSColin Finck     }
3045612729b0SKatayama Hirofumi MZ     pSetupData->ProductOption = PRODUCT_OPTION_DEFAULT;
3046c2c66affSColin Finck 
3047c2c66affSColin Finck     hNetShell = LoadLibraryW(L"netshell.dll");
3048c2c66affSColin Finck     if (hNetShell != NULL)
3049c2c66affSColin Finck     {
3050c2c66affSColin Finck         DPRINT("Netshell.dll loaded!\n");
3051c2c66affSColin Finck 
3052c2c66affSColin Finck         pfn = (PFNREQUESTWIZARDPAGES)GetProcAddress(hNetShell,
3053c2c66affSColin Finck                                                     "NetSetupRequestWizardPages");
3054c2c66affSColin Finck         if (pfn != NULL)
3055c2c66affSColin Finck         {
3056c2c66affSColin Finck             pfn(&dwNetworkPageCount, NULL, NULL);
3057c2c66affSColin Finck             dwPageCount += dwNetworkPageCount;
3058c2c66affSColin Finck         }
3059c2c66affSColin Finck     }
3060c2c66affSColin Finck 
3061c2c66affSColin Finck     DPRINT("PageCount: %lu\n", dwPageCount);
3062c2c66affSColin Finck 
3063c2c66affSColin Finck     phpage = HeapAlloc(GetProcessHeap(),
3064c2c66affSColin Finck                        HEAP_ZERO_MEMORY,
3065c2c66affSColin Finck                        dwPageCount * sizeof(HPROPSHEETPAGE));
3066c2c66affSColin Finck     if (phpage == NULL)
3067c2c66affSColin Finck     {
3068c2c66affSColin Finck         LogItem(NULL, L"Page array allocation failed!");
3069c2c66affSColin Finck         MessageBoxW(NULL,
3070c2c66affSColin Finck                     L"Setup failed to allocate page array!",
3071c2c66affSColin Finck                     L"ReactOS Setup",
3072c2c66affSColin Finck                     MB_ICONERROR | MB_OK);
3073c2c66affSColin Finck         goto done;
3074c2c66affSColin Finck     }
3075c2c66affSColin Finck 
3076c8d37c1aSHermès Bélusca-Maïto     /* Process the $winnt$.inf setup file */
3077c8d37c1aSHermès Bélusca-Maïto     ProcessSetupInf(pSetupData);
3078c2c66affSColin Finck 
3079c2c66affSColin Finck     /* Create the Welcome page */
3080c2c66affSColin Finck     psp.dwSize = sizeof(PROPSHEETPAGE);
3081c2c66affSColin Finck     psp.dwFlags = PSP_DEFAULT | PSP_HIDEHEADER;
3082c2c66affSColin Finck     psp.hInstance = hDllInstance;
3083c2c66affSColin Finck     psp.lParam = (LPARAM)pSetupData;
3084c2c66affSColin Finck     psp.pfnDlgProc = WelcomeDlgProc;
3085c2c66affSColin Finck     psp.pszTemplate = MAKEINTRESOURCE(IDD_WELCOMEPAGE);
3086c2c66affSColin Finck     phpage[nPages++] = CreatePropertySheetPage(&psp);
3087c2c66affSColin Finck 
3088c2c66affSColin Finck     /* Create the Acknowledgements page */
3089c2c66affSColin Finck     psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
3090c2c66affSColin Finck     psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_ACKTITLE);
3091c2c66affSColin Finck     psp.pszHeaderSubTitle = MAKEINTRESOURCE(IDS_ACKSUBTITLE);
3092c2c66affSColin Finck     psp.pszTemplate = MAKEINTRESOURCE(IDD_ACKPAGE);
3093c2c66affSColin Finck     psp.pfnDlgProc = AckPageDlgProc;
3094c2c66affSColin Finck     phpage[nPages++] = CreatePropertySheetPage(&psp);
3095c2c66affSColin Finck 
309648160c74SKatayama Hirofumi MZ     /* Create the Product page */
309748160c74SKatayama Hirofumi MZ     psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
309848160c74SKatayama Hirofumi MZ     psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_PRODUCTTITLE);
309948160c74SKatayama Hirofumi MZ     psp.pszHeaderSubTitle = MAKEINTRESOURCE(IDS_PRODUCTSUBTITLE);
310048160c74SKatayama Hirofumi MZ     psp.pszTemplate = MAKEINTRESOURCE(IDD_PRODUCT);
310148160c74SKatayama Hirofumi MZ     psp.pfnDlgProc = ProductPageDlgProc;
310248160c74SKatayama Hirofumi MZ     phpage[nPages++] = CreatePropertySheetPage(&psp);
310348160c74SKatayama Hirofumi MZ 
3104c2c66affSColin Finck     /* Create the Locale page */
3105c2c66affSColin Finck     psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
3106c2c66affSColin Finck     psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_LOCALETITLE);
3107c2c66affSColin Finck     psp.pszHeaderSubTitle = MAKEINTRESOURCE(IDS_LOCALESUBTITLE);
3108c2c66affSColin Finck     psp.pfnDlgProc = LocalePageDlgProc;
3109c2c66affSColin Finck     psp.pszTemplate = MAKEINTRESOURCE(IDD_LOCALEPAGE);
3110c2c66affSColin Finck     phpage[nPages++] = CreatePropertySheetPage(&psp);
3111c2c66affSColin Finck 
3112c2c66affSColin Finck     /* Create the Owner page */
3113c2c66affSColin Finck     psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
3114c2c66affSColin Finck     psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_OWNERTITLE);
3115c2c66affSColin Finck     psp.pszHeaderSubTitle = MAKEINTRESOURCE(IDS_OWNERSUBTITLE);
3116c2c66affSColin Finck     psp.pszTemplate = MAKEINTRESOURCE(IDD_OWNERPAGE);
3117c2c66affSColin Finck     psp.pfnDlgProc = OwnerPageDlgProc;
3118c2c66affSColin Finck     phpage[nPages++] = CreatePropertySheetPage(&psp);
3119c2c66affSColin Finck 
3120c2c66affSColin Finck     /* Create the Computer page */
3121c2c66affSColin Finck     psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
3122c2c66affSColin Finck     psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_COMPUTERTITLE);
3123c2c66affSColin Finck     psp.pszHeaderSubTitle = MAKEINTRESOURCE(IDS_COMPUTERSUBTITLE);
3124c2c66affSColin Finck     psp.pfnDlgProc = ComputerPageDlgProc;
3125c2c66affSColin Finck     psp.pszTemplate = MAKEINTRESOURCE(IDD_COMPUTERPAGE);
3126c2c66affSColin Finck     phpage[nPages++] = CreatePropertySheetPage(&psp);
3127c2c66affSColin Finck 
3128c2c66affSColin Finck     /* Create the DateTime page */
3129c2c66affSColin Finck     psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
3130c2c66affSColin Finck     psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_DATETIMETITLE);
3131c2c66affSColin Finck     psp.pszHeaderSubTitle = MAKEINTRESOURCE(IDS_DATETIMESUBTITLE);
3132c2c66affSColin Finck     psp.pfnDlgProc = DateTimePageDlgProc;
3133c2c66affSColin Finck     psp.pszTemplate = MAKEINTRESOURCE(IDD_DATETIMEPAGE);
3134c2c66affSColin Finck     phpage[nPages++] = CreatePropertySheetPage(&psp);
3135c2c66affSColin Finck 
3136c2c66affSColin Finck     /* Create the theme selection page */
3137c2c66affSColin Finck     psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
3138c2c66affSColin Finck     psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_THEMESELECTIONTITLE);
3139c2c66affSColin Finck     psp.pszHeaderSubTitle = MAKEINTRESOURCE(IDS_THEMESELECTIONSUBTITLE);
3140c2c66affSColin Finck     psp.pfnDlgProc = ThemePageDlgProc;
3141c2c66affSColin Finck     psp.pszTemplate = MAKEINTRESOURCE(IDD_THEMEPAGE);
3142c2c66affSColin Finck     phpage[nPages++] = CreatePropertySheetPage(&psp);
3143c2c66affSColin Finck 
3144c2c66affSColin Finck     pSetupData->uFirstNetworkWizardPage = IDD_PROCESSPAGE;
3145c2c66affSColin Finck     pSetupData->uPostNetworkWizardPage = IDD_PROCESSPAGE;
3146c2c66affSColin Finck 
3147c2c66affSColin Finck     if (pfn)
3148c2c66affSColin Finck     {
3149c2c66affSColin Finck         pfn(&dwNetworkPageCount, &phpage[nPages], pSetupData);
3150c2c66affSColin Finck         nPages += dwNetworkPageCount;
3151c2c66affSColin Finck     }
3152c2c66affSColin Finck 
3153c2c66affSColin Finck     /* Create the Process page */
3154c2c66affSColin Finck     psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
3155c2c66affSColin Finck     psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_PROCESSTITLE);
3156c2c66affSColin Finck     psp.pszHeaderSubTitle = MAKEINTRESOURCE(IDS_PROCESSSUBTITLE);
3157c2c66affSColin Finck     psp.pfnDlgProc = ProcessPageDlgProc;
3158c2c66affSColin Finck     psp.pszTemplate = MAKEINTRESOURCE(IDD_PROCESSPAGE);
3159c2c66affSColin Finck     phpage[nPages++] = CreatePropertySheetPage(&psp);
3160c2c66affSColin Finck 
3161c2c66affSColin Finck     /* Create the Finish page */
3162c2c66affSColin Finck     psp.dwFlags = PSP_DEFAULT | PSP_HIDEHEADER;
3163c2c66affSColin Finck     psp.pfnDlgProc = FinishDlgProc;
3164c2c66affSColin Finck     psp.pszTemplate = MAKEINTRESOURCE(IDD_FINISHPAGE);
3165c2c66affSColin Finck     phpage[nPages++] = CreatePropertySheetPage(&psp);
3166c2c66affSColin Finck 
31671668527aSSerge Gautherie     ASSERT(nPages == dwPageCount);
31681668527aSSerge Gautherie 
3169c2c66affSColin Finck     /* Create the property sheet */
3170c2c66affSColin Finck     psh.dwSize = sizeof(PROPSHEETHEADER);
3171c2c66affSColin Finck     psh.dwFlags = PSH_WIZARD97 | PSH_WATERMARK | PSH_HEADER | PSH_MODELESS;
3172c2c66affSColin Finck     psh.hInstance = hDllInstance;
3173c2c66affSColin Finck     psh.hwndParent = NULL;
3174c2c66affSColin Finck     psh.nPages = nPages;
3175c2c66affSColin Finck     psh.nStartPage = 0;
3176c2c66affSColin Finck     psh.phpage = phpage;
3177c2c66affSColin Finck     psh.pszbmWatermark = MAKEINTRESOURCE(IDB_WATERMARK);
3178c2c66affSColin Finck     psh.pszbmHeader = MAKEINTRESOURCE(IDB_HEADER);
3179c2c66affSColin Finck 
3180c2c66affSColin Finck     /* Create title font */
3181c2c66affSColin Finck     pSetupData->hTitleFont = CreateTitleFont();
3182c2c66affSColin Finck     pSetupData->hBoldFont  = CreateBoldFont();
3183c2c66affSColin Finck 
3184c2c66affSColin Finck     /* Display the wizard */
3185c2c66affSColin Finck     hWnd = (HWND)PropertySheet(&psh);
3186c2c66affSColin Finck     ShowWindow(hWnd, SW_SHOW);
3187c2c66affSColin Finck 
3188c2c66affSColin Finck     while (GetMessage(&msg, NULL, 0, 0))
3189c2c66affSColin Finck     {
3190c2c66affSColin Finck         if (!IsDialogMessage(hWnd, &msg))
3191c2c66affSColin Finck         {
3192c2c66affSColin Finck             TranslateMessage(&msg);
3193c2c66affSColin Finck             DispatchMessage(&msg);
3194c2c66affSColin Finck         }
3195c2c66affSColin Finck     }
3196c2c66affSColin Finck 
31978468ad5cSHermès Bélusca-Maïto     DeleteObject(pSetupData->hBoldFont);
31988468ad5cSHermès Bélusca-Maïto     DeleteObject(pSetupData->hTitleFont);
31998468ad5cSHermès Bélusca-Maïto 
3200c8d37c1aSHermès Bélusca-Maïto     if (pSetupData->hSetupInf != INVALID_HANDLE_VALUE)
3201c8d37c1aSHermès Bélusca-Maïto         SetupCloseInfFile(pSetupData->hSetupInf);
3202c2c66affSColin Finck 
3203c2c66affSColin Finck done:
3204c2c66affSColin Finck     if (phpage != NULL)
3205c2c66affSColin Finck         HeapFree(GetProcessHeap(), 0, phpage);
3206c2c66affSColin Finck 
3207c2c66affSColin Finck     if (hNetShell != NULL)
3208c2c66affSColin Finck         FreeLibrary(hNetShell);
3209c2c66affSColin Finck 
3210c2c66affSColin Finck     if (pSetupData != NULL)
3211c2c66affSColin Finck         HeapFree(GetProcessHeap(), 0, pSetupData);
3212c2c66affSColin Finck 
3213c2c66affSColin Finck     LogItem(L"END_SECTION", L"InstallWizard");
3214c2c66affSColin Finck }
3215c2c66affSColin Finck 
3216c2c66affSColin Finck /* EOF */
3217