xref: /reactos/dll/win32/syssetup/wizard.c (revision 17cb1e1a)
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>
10c2c66affSColin Finck  */
11c2c66affSColin Finck 
12c2c66affSColin Finck /* INCLUDES *****************************************************************/
13c2c66affSColin Finck 
14c2c66affSColin Finck #include "precomp.h"
15c2c66affSColin Finck 
16c2c66affSColin Finck #include <stdlib.h>
17c2c66affSColin Finck #include <time.h>
18c2c66affSColin Finck #include <winnls.h>
19c2c66affSColin Finck #include <windowsx.h>
20c2c66affSColin Finck #include <wincon.h>
21c2c66affSColin Finck #include <shlobj.h>
227c3e96a2SHermès Bélusca-Maïto #include <tzlib.h>
23612729b0SKatayama Hirofumi MZ #include <strsafe.h>
247c3e96a2SHermès Bélusca-Maïto 
25c2c66affSColin Finck #define NDEBUG
26c2c66affSColin Finck #include <debug.h>
27c2c66affSColin Finck 
28c2c66affSColin Finck #define PM_REGISTRATION_NOTIFY (WM_APP + 1)
29c2c66affSColin Finck /* Private Message used to communicate progress from the background
30c2c66affSColin Finck    registration thread to the main thread.
31c2c66affSColin Finck    wParam = 0 Registration in progress
32c2c66affSColin Finck           = 1 Registration completed
33c2c66affSColin Finck    lParam = Pointer to a REGISTRATIONNOTIFY structure */
34c2c66affSColin Finck 
35c2c66affSColin Finck typedef struct _REGISTRATIONNOTIFY
36c2c66affSColin Finck {
37c2c66affSColin Finck     ULONG Progress;
38c2c66affSColin Finck     UINT ActivityID;
39c2c66affSColin Finck     LPCWSTR CurrentItem;
40c2c66affSColin Finck     LPCWSTR ErrorMessage;
41c2c66affSColin Finck } REGISTRATIONNOTIFY, *PREGISTRATIONNOTIFY;
42c2c66affSColin Finck 
43c2c66affSColin Finck typedef struct _REGISTRATIONDATA
44c2c66affSColin Finck {
45c2c66affSColin Finck     HWND hwndDlg;
46c2c66affSColin Finck     ULONG DllCount;
47c2c66affSColin Finck     ULONG Registered;
48c2c66affSColin Finck     PVOID DefaultContext;
49c2c66affSColin Finck } REGISTRATIONDATA, *PREGISTRATIONDATA;
50c2c66affSColin Finck 
517c3e96a2SHermès Bélusca-Maïto typedef struct _TIMEZONE_ENTRY
527c3e96a2SHermès Bélusca-Maïto {
537c3e96a2SHermès Bélusca-Maïto     struct _TIMEZONE_ENTRY *Prev;
547c3e96a2SHermès Bélusca-Maïto     struct _TIMEZONE_ENTRY *Next;
557c3e96a2SHermès Bélusca-Maïto     WCHAR Description[128]; /* 'Display' */
567c3e96a2SHermès Bélusca-Maïto     WCHAR StandardName[32]; /* 'Std' */
577c3e96a2SHermès Bélusca-Maïto     WCHAR DaylightName[32]; /* 'Dlt' */
587c3e96a2SHermès Bélusca-Maïto     REG_TZI_FORMAT TimezoneInfo; /* 'TZI' */
597c3e96a2SHermès Bélusca-Maïto     ULONG Index;
607c3e96a2SHermès Bélusca-Maïto } TIMEZONE_ENTRY, *PTIMEZONE_ENTRY;
617c3e96a2SHermès Bélusca-Maïto 
62c2c66affSColin Finck 
63c2c66affSColin Finck /* FUNCTIONS ****************************************************************/
64c2c66affSColin Finck 
65c2c66affSColin Finck extern void WINAPI Control_RunDLLW(HWND hWnd, HINSTANCE hInst, LPCWSTR cmd, DWORD nCmdShow);
66c2c66affSColin Finck 
67c2c66affSColin Finck 
68c2c66affSColin Finck static VOID
69c2c66affSColin Finck CenterWindow(HWND hWnd)
70c2c66affSColin Finck {
71c2c66affSColin Finck     HWND hWndParent;
72c2c66affSColin Finck     RECT rcParent;
73c2c66affSColin Finck     RECT rcWindow;
74c2c66affSColin Finck 
75c2c66affSColin Finck     hWndParent = GetParent(hWnd);
76c2c66affSColin Finck     if (hWndParent == NULL)
77c2c66affSColin Finck         hWndParent = GetDesktopWindow();
78c2c66affSColin Finck 
79c2c66affSColin Finck     GetWindowRect(hWndParent, &rcParent);
80c2c66affSColin Finck     GetWindowRect(hWnd, &rcWindow);
81c2c66affSColin Finck 
82c2c66affSColin Finck     SetWindowPos(hWnd,
83c2c66affSColin Finck                  HWND_TOP,
84c2c66affSColin Finck                  ((rcParent.right - rcParent.left) - (rcWindow.right - rcWindow.left)) / 2,
85c2c66affSColin Finck                  ((rcParent.bottom - rcParent.top) - (rcWindow.bottom - rcWindow.top)) / 2,
86c2c66affSColin Finck                  0,
87c2c66affSColin Finck                  0,
88c2c66affSColin Finck                  SWP_NOSIZE);
89c2c66affSColin Finck }
90c2c66affSColin Finck 
91c2c66affSColin Finck 
92c2c66affSColin Finck static HFONT
93c2c66affSColin Finck CreateTitleFont(VOID)
94c2c66affSColin Finck {
95c2c66affSColin Finck     LOGFONTW LogFont = {0};
96c2c66affSColin Finck     HDC hdc;
97c2c66affSColin Finck     HFONT hFont;
98c2c66affSColin Finck 
995972b1e2SKatayama Hirofumi MZ     LogFont.lfWeight = FW_BOLD;
100c2c66affSColin Finck     wcscpy(LogFont.lfFaceName, L"MS Shell Dlg");
101c2c66affSColin Finck 
102c2c66affSColin Finck     hdc = GetDC(NULL);
103c2c66affSColin Finck     LogFont.lfHeight = -MulDiv(12, GetDeviceCaps(hdc, LOGPIXELSY), 72);
104c2c66affSColin Finck 
105c2c66affSColin Finck     hFont = CreateFontIndirectW(&LogFont);
106c2c66affSColin Finck 
107c2c66affSColin Finck     ReleaseDC(NULL, hdc);
108c2c66affSColin Finck 
109c2c66affSColin Finck     return hFont;
110c2c66affSColin Finck }
111c2c66affSColin Finck 
112c2c66affSColin Finck 
113c2c66affSColin Finck static HFONT
114c2c66affSColin Finck CreateBoldFont(VOID)
115c2c66affSColin Finck {
116c2c66affSColin Finck     LOGFONTW tmpFont = {0};
117c2c66affSColin Finck     HFONT hBoldFont;
118c2c66affSColin Finck     HDC hDc;
119c2c66affSColin Finck 
120c2c66affSColin Finck     /* Grabs the Drawing Context */
121c2c66affSColin Finck     hDc = GetDC(NULL);
122c2c66affSColin Finck 
123c2c66affSColin Finck     tmpFont.lfHeight = -MulDiv(8, GetDeviceCaps(hDc, LOGPIXELSY), 72);
124836e3107SKatayama Hirofumi MZ     tmpFont.lfWeight = FW_BOLD;
125c2c66affSColin Finck     wcscpy(tmpFont.lfFaceName, L"MS Shell Dlg");
126c2c66affSColin Finck 
127c2c66affSColin Finck     hBoldFont = CreateFontIndirectW(&tmpFont);
128c2c66affSColin Finck 
129c2c66affSColin Finck     ReleaseDC(NULL, hDc);
130c2c66affSColin Finck 
131c2c66affSColin Finck     return hBoldFont;
132c2c66affSColin Finck }
133c2c66affSColin Finck 
134c2c66affSColin Finck static INT_PTR CALLBACK
135c2c66affSColin Finck GplDlgProc(HWND hwndDlg,
136c2c66affSColin Finck            UINT uMsg,
137c2c66affSColin Finck            WPARAM wParam,
138c2c66affSColin Finck            LPARAM lParam)
139c2c66affSColin Finck {
140c2c66affSColin Finck     HRSRC GplTextResource;
141c2c66affSColin Finck     HGLOBAL GplTextMem;
142c2c66affSColin Finck     PVOID GplTextLocked;
143c2c66affSColin Finck     PCHAR GplText;
144c2c66affSColin Finck     DWORD Size;
145c2c66affSColin Finck 
146c2c66affSColin Finck 
147c2c66affSColin Finck     switch (uMsg)
148c2c66affSColin Finck     {
149c2c66affSColin Finck         case WM_INITDIALOG:
150c2c66affSColin Finck             GplTextResource = FindResourceW(hDllInstance, MAKEINTRESOURCE(IDR_GPL), L"RT_TEXT");
151c2c66affSColin Finck             if (NULL == GplTextResource)
152c2c66affSColin Finck             {
153c2c66affSColin Finck                 break;
154c2c66affSColin Finck             }
155c2c66affSColin Finck             Size = SizeofResource(hDllInstance, GplTextResource);
156c2c66affSColin Finck             if (0 == Size)
157c2c66affSColin Finck             {
158c2c66affSColin Finck                 break;
159c2c66affSColin Finck             }
160c2c66affSColin Finck             GplText = HeapAlloc(GetProcessHeap(), 0, Size + 1);
161c2c66affSColin Finck             if (NULL == GplText)
162c2c66affSColin Finck             {
163c2c66affSColin Finck                 break;
164c2c66affSColin Finck             }
165c2c66affSColin Finck             GplTextMem = LoadResource(hDllInstance, GplTextResource);
166c2c66affSColin Finck             if (NULL == GplTextMem)
167c2c66affSColin Finck             {
168c2c66affSColin Finck                 HeapFree(GetProcessHeap(), 0, GplText);
169c2c66affSColin Finck                 break;
170c2c66affSColin Finck             }
171c2c66affSColin Finck             GplTextLocked = LockResource(GplTextMem);
172c2c66affSColin Finck             if (NULL == GplTextLocked)
173c2c66affSColin Finck             {
174c2c66affSColin Finck                 HeapFree(GetProcessHeap(), 0, GplText);
175c2c66affSColin Finck                 break;
176c2c66affSColin Finck             }
177c2c66affSColin Finck             memcpy(GplText, GplTextLocked, Size);
178c2c66affSColin Finck             GplText[Size] = '\0';
179c2c66affSColin Finck             SendMessageA(GetDlgItem(hwndDlg, IDC_GPL_TEXT), WM_SETTEXT, 0, (LPARAM) GplText);
180c2c66affSColin Finck             HeapFree(GetProcessHeap(), 0, GplText);
181c2c66affSColin Finck             SetFocus(GetDlgItem(hwndDlg, IDOK));
182c2c66affSColin Finck             return FALSE;
183c2c66affSColin Finck 
184c2c66affSColin Finck         case WM_CLOSE:
185c2c66affSColin Finck             EndDialog(hwndDlg, IDCANCEL);
186c2c66affSColin Finck             break;
187c2c66affSColin Finck 
188c2c66affSColin Finck         case WM_COMMAND:
189c2c66affSColin Finck             if (HIWORD(wParam) == BN_CLICKED && IDOK == LOWORD(wParam))
190c2c66affSColin Finck             {
191c2c66affSColin Finck                 EndDialog(hwndDlg, IDOK);
192c2c66affSColin Finck             }
193c2c66affSColin Finck             break;
194c2c66affSColin Finck 
195c2c66affSColin Finck         default:
196c2c66affSColin Finck             break;
197c2c66affSColin Finck     }
198c2c66affSColin Finck 
199c2c66affSColin Finck     return FALSE;
200c2c66affSColin Finck }
201c2c66affSColin Finck 
202c2c66affSColin Finck 
203c2c66affSColin Finck static INT_PTR CALLBACK
204c2c66affSColin Finck WelcomeDlgProc(HWND hwndDlg,
205c2c66affSColin Finck                UINT uMsg,
206c2c66affSColin Finck                WPARAM wParam,
207c2c66affSColin Finck                LPARAM lParam)
208c2c66affSColin Finck {
209c2c66affSColin Finck     PSETUPDATA pSetupData;
210c2c66affSColin Finck 
211c2c66affSColin Finck     pSetupData = (PSETUPDATA)GetWindowLongPtr(hwndDlg, DWLP_USER);
212c2c66affSColin Finck 
213c2c66affSColin Finck     switch (uMsg)
214c2c66affSColin Finck     {
215c2c66affSColin Finck         case WM_INITDIALOG:
216c2c66affSColin Finck         {
217c2c66affSColin Finck             HWND hwndControl;
218c2c66affSColin Finck             DWORD dwStyle;
219c2c66affSColin Finck 
220c2c66affSColin Finck             /* Get pointer to the global setup data */
221c2c66affSColin Finck             pSetupData = (PSETUPDATA)((LPPROPSHEETPAGE)lParam)->lParam;
222c2c66affSColin Finck             SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pSetupData);
223c2c66affSColin Finck 
224c2c66affSColin Finck             hwndControl = GetParent(hwndDlg);
225c2c66affSColin Finck 
226c2c66affSColin Finck             /* Center the wizard window */
227c2c66affSColin Finck             CenterWindow (hwndControl);
228c2c66affSColin Finck 
229c2c66affSColin Finck             /* Hide the system menu */
230c2c66affSColin Finck             dwStyle = GetWindowLongPtr(hwndControl, GWL_STYLE);
231c2c66affSColin Finck             SetWindowLongPtr(hwndControl, GWL_STYLE, dwStyle & ~WS_SYSMENU);
232c2c66affSColin Finck 
233c2c66affSColin Finck             /* Hide and disable the 'Cancel' button */
234c2c66affSColin Finck             hwndControl = GetDlgItem(GetParent(hwndDlg), IDCANCEL);
235c2c66affSColin Finck             ShowWindow (hwndControl, SW_HIDE);
236c2c66affSColin Finck             EnableWindow (hwndControl, FALSE);
237c2c66affSColin Finck 
238c2c66affSColin Finck             /* Set title font */
239c2c66affSColin Finck             SendDlgItemMessage(hwndDlg,
240c2c66affSColin Finck                                IDC_WELCOMETITLE,
241c2c66affSColin Finck                                WM_SETFONT,
242c2c66affSColin Finck                                (WPARAM)pSetupData->hTitleFont,
243c2c66affSColin Finck                                (LPARAM)TRUE);
244c2c66affSColin Finck         }
245c2c66affSColin Finck         break;
246c2c66affSColin Finck 
247c2c66affSColin Finck 
248c2c66affSColin Finck         case WM_NOTIFY:
249c2c66affSColin Finck         {
250c2c66affSColin Finck             LPNMHDR lpnm = (LPNMHDR)lParam;
251c2c66affSColin Finck 
252c2c66affSColin Finck             switch (lpnm->code)
253c2c66affSColin Finck             {
254c2c66affSColin Finck                 case PSN_SETACTIVE:
255c2c66affSColin Finck                     LogItem(L"BEGIN", L"WelcomePage");
256c2c66affSColin Finck                     /* Enable the Next button */
257c2c66affSColin Finck                     PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT);
258c2c66affSColin Finck                     if (pSetupData->UnattendSetup)
259c2c66affSColin Finck                     {
2600182dcd7STimo Kreuzer                         SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_ACKPAGE);
261c2c66affSColin Finck                         return TRUE;
262c2c66affSColin Finck                     }
263c2c66affSColin Finck                     break;
264c2c66affSColin Finck 
265c2c66affSColin Finck                 case PSN_WIZNEXT:
266c2c66affSColin Finck                     LogItem(L"END", L"WelcomePage");
267c2c66affSColin Finck                     break;
268c2c66affSColin Finck 
269c2c66affSColin Finck                 case PSN_WIZBACK:
270c2c66affSColin Finck                     pSetupData->UnattendSetup = FALSE;
271c2c66affSColin Finck                     break;
272c2c66affSColin Finck 
273c2c66affSColin Finck                 default:
274c2c66affSColin Finck                     break;
275c2c66affSColin Finck             }
276c2c66affSColin Finck         }
277c2c66affSColin Finck         break;
278c2c66affSColin Finck 
279c2c66affSColin Finck         default:
280c2c66affSColin Finck             break;
281c2c66affSColin Finck     }
282c2c66affSColin Finck 
283c2c66affSColin Finck     return FALSE;
284c2c66affSColin Finck }
285c2c66affSColin Finck 
286c2c66affSColin Finck 
287c2c66affSColin Finck static INT_PTR CALLBACK
288c2c66affSColin Finck AckPageDlgProc(HWND hwndDlg,
289c2c66affSColin Finck                UINT uMsg,
290c2c66affSColin Finck                WPARAM wParam,
291c2c66affSColin Finck                LPARAM lParam)
292c2c66affSColin Finck {
293c2c66affSColin Finck     LPNMHDR lpnm;
294c2c66affSColin Finck     PWCHAR Projects;
295c2c66affSColin Finck     PWCHAR End, CurrentProject;
296c2c66affSColin Finck     INT ProjectsSize, ProjectsCount;
297c2c66affSColin Finck     PSETUPDATA pSetupData;
298c2c66affSColin Finck 
299c2c66affSColin Finck     pSetupData = (PSETUPDATA)GetWindowLongPtr(hwndDlg, DWLP_USER);
300c2c66affSColin Finck 
301c2c66affSColin Finck     switch (uMsg)
302c2c66affSColin Finck     {
303c2c66affSColin Finck         case WM_INITDIALOG:
304c2c66affSColin Finck         {
305c2c66affSColin Finck             pSetupData = (PSETUPDATA)((LPPROPSHEETPAGE)lParam)->lParam;
306c2c66affSColin Finck             SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pSetupData);
307c2c66affSColin Finck 
308c2c66affSColin Finck             Projects = NULL;
309c2c66affSColin Finck             ProjectsSize = 256;
310e9893906SHermès Bélusca-Maïto             while (TRUE)
311c2c66affSColin Finck             {
312c2c66affSColin Finck                 Projects = HeapAlloc(GetProcessHeap(), 0, ProjectsSize * sizeof(WCHAR));
313c2c66affSColin Finck                 if (NULL == Projects)
314c2c66affSColin Finck                 {
315c2c66affSColin Finck                     return FALSE;
316c2c66affSColin Finck                 }
317c2c66affSColin Finck                 ProjectsCount =  LoadStringW(hDllInstance, IDS_ACKPROJECTS, Projects, ProjectsSize);
318c2c66affSColin Finck                 if (0 == ProjectsCount)
319c2c66affSColin Finck                 {
320c2c66affSColin Finck                     HeapFree(GetProcessHeap(), 0, Projects);
321c2c66affSColin Finck                     return FALSE;
322c2c66affSColin Finck                 }
323c2c66affSColin Finck                 if (ProjectsCount < ProjectsSize - 1)
324c2c66affSColin Finck                 {
325c2c66affSColin Finck                     break;
326c2c66affSColin Finck                 }
327c2c66affSColin Finck                 HeapFree(GetProcessHeap(), 0, Projects);
328c2c66affSColin Finck                 ProjectsSize *= 2;
329c2c66affSColin Finck             }
330e9893906SHermès Bélusca-Maïto 
331c2c66affSColin Finck             CurrentProject = Projects;
332e9893906SHermès Bélusca-Maïto             while (*CurrentProject != L'\0')
333c2c66affSColin Finck             {
334c2c66affSColin Finck                 End = wcschr(CurrentProject, L'\n');
335c2c66affSColin Finck                 if (NULL != End)
336c2c66affSColin Finck                 {
337c2c66affSColin Finck                     *End = L'\0';
338c2c66affSColin Finck                 }
339c2c66affSColin Finck                 (void)ListBox_AddString(GetDlgItem(hwndDlg, IDC_PROJECTS), CurrentProject);
340c2c66affSColin Finck                 if (NULL != End)
341c2c66affSColin Finck                 {
342c2c66affSColin Finck                     CurrentProject = End + 1;
343c2c66affSColin Finck                 }
344c2c66affSColin Finck                 else
345c2c66affSColin Finck                 {
346c2c66affSColin Finck                     CurrentProject += wcslen(CurrentProject);
347c2c66affSColin Finck                 }
348c2c66affSColin Finck             }
349c2c66affSColin Finck             HeapFree(GetProcessHeap(), 0, Projects);
350c2c66affSColin Finck         }
351c2c66affSColin Finck         break;
352c2c66affSColin Finck 
353c2c66affSColin Finck         case WM_COMMAND:
354c2c66affSColin Finck             if (HIWORD(wParam) == BN_CLICKED && IDC_VIEWGPL == LOWORD(wParam))
355c2c66affSColin Finck             {
356c2c66affSColin Finck                 DialogBox(hDllInstance, MAKEINTRESOURCE(IDD_GPL), NULL, GplDlgProc);
357c2c66affSColin Finck                 SetForegroundWindow(GetParent(hwndDlg));
358c2c66affSColin Finck             }
359c2c66affSColin Finck             break;
360c2c66affSColin Finck 
361c2c66affSColin Finck         case WM_NOTIFY:
362c2c66affSColin Finck         {
363c2c66affSColin Finck             lpnm = (LPNMHDR)lParam;
364c2c66affSColin Finck 
365c2c66affSColin Finck             switch (lpnm->code)
366c2c66affSColin Finck             {
367c2c66affSColin Finck                 case PSN_SETACTIVE:
368c2c66affSColin Finck                     /* Enable the Back and Next buttons */
369c2c66affSColin Finck                     PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK | PSWIZB_NEXT);
370c2c66affSColin Finck                     if (pSetupData->UnattendSetup)
371c2c66affSColin Finck                     {
37248160c74SKatayama Hirofumi MZ                         SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_PRODUCT);
37348160c74SKatayama Hirofumi MZ                         return TRUE;
37448160c74SKatayama Hirofumi MZ                     }
37548160c74SKatayama Hirofumi MZ                     break;
37648160c74SKatayama Hirofumi MZ 
37748160c74SKatayama Hirofumi MZ                 case PSN_WIZBACK:
37848160c74SKatayama Hirofumi MZ                     pSetupData->UnattendSetup = FALSE;
37948160c74SKatayama Hirofumi MZ                     break;
38048160c74SKatayama Hirofumi MZ 
38148160c74SKatayama Hirofumi MZ                 default:
38248160c74SKatayama Hirofumi MZ                     break;
38348160c74SKatayama Hirofumi MZ             }
38448160c74SKatayama Hirofumi MZ         }
38548160c74SKatayama Hirofumi MZ         break;
38648160c74SKatayama Hirofumi MZ 
38748160c74SKatayama Hirofumi MZ         default:
38848160c74SKatayama Hirofumi MZ             break;
38948160c74SKatayama Hirofumi MZ     }
39048160c74SKatayama Hirofumi MZ 
39148160c74SKatayama Hirofumi MZ     return FALSE;
39248160c74SKatayama Hirofumi MZ }
39348160c74SKatayama Hirofumi MZ 
394612729b0SKatayama Hirofumi MZ static const WCHAR s_szProductOptions[] = L"SYSTEM\\CurrentControlSet\\Control\\ProductOptions";
395612729b0SKatayama Hirofumi MZ static const WCHAR s_szRosVersion[] = L"SYSTEM\\CurrentControlSet\\Control\\ReactOS\\Settings\\Version";
396612729b0SKatayama Hirofumi MZ static const WCHAR s_szControlWindows[] = L"SYSTEM\\CurrentControlSet\\Control\\Windows";
3972edcb58eSVladimir Barinov static const WCHAR s_szWinlogon[] = L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon";
398612729b0SKatayama Hirofumi MZ 
399ef6711c9SSerge Gautherie typedef struct _PRODUCT_OPTION_DATA
400612729b0SKatayama Hirofumi MZ {
401612729b0SKatayama Hirofumi MZ     LPCWSTR ProductSuite;
402612729b0SKatayama Hirofumi MZ     LPCWSTR ProductType;
403612729b0SKatayama Hirofumi MZ     DWORD ReportAsWorkstation;
404612729b0SKatayama Hirofumi MZ     DWORD CSDVersion;
4052edcb58eSVladimir Barinov     DWORD LogonType;
406ef6711c9SSerge Gautherie } PRODUCT_OPTION_DATA;
407612729b0SKatayama Hirofumi MZ 
408612729b0SKatayama Hirofumi MZ static const PRODUCT_OPTION_DATA s_ProductOptionData[] =
409612729b0SKatayama Hirofumi MZ {
4102edcb58eSVladimir Barinov     { L"Terminal Server\0", L"ServerNT", 0, 0x200, 0 },
4112edcb58eSVladimir Barinov     { L"\0", L"WinNT", 1, 0x300, 1 }
412612729b0SKatayama Hirofumi MZ };
413612729b0SKatayama Hirofumi MZ 
41448160c74SKatayama Hirofumi MZ static BOOL
41548160c74SKatayama Hirofumi MZ DoWriteProductOption(PRODUCT_OPTION nOption)
41648160c74SKatayama Hirofumi MZ {
41748160c74SKatayama Hirofumi MZ     HKEY hKey;
41848160c74SKatayama Hirofumi MZ     LONG error;
419612729b0SKatayama Hirofumi MZ     LPCWSTR pszData;
420612729b0SKatayama Hirofumi MZ     DWORD dwValue, cbData;
421612729b0SKatayama Hirofumi MZ     const PRODUCT_OPTION_DATA *pData = &s_ProductOptionData[nOption];
422612729b0SKatayama Hirofumi MZ     ASSERT(0 <= nOption && nOption < _countof(s_ProductOptionData));
42348160c74SKatayama Hirofumi MZ 
424612729b0SKatayama Hirofumi MZ     /* open ProductOptions key */
42548160c74SKatayama Hirofumi MZ     error = RegOpenKeyExW(HKEY_LOCAL_MACHINE, s_szProductOptions, 0, KEY_WRITE, &hKey);
42648160c74SKatayama Hirofumi MZ     if (error)
42748160c74SKatayama Hirofumi MZ     {
428612729b0SKatayama Hirofumi MZ         DPRINT1("RegOpenKeyExW failed\n");
429612729b0SKatayama Hirofumi MZ         goto Error;
430612729b0SKatayama Hirofumi MZ     }
431612729b0SKatayama Hirofumi MZ 
43248160c74SKatayama Hirofumi MZ     /* write ProductSuite */
433612729b0SKatayama Hirofumi MZ     pszData = pData->ProductSuite;
434612729b0SKatayama Hirofumi MZ     cbData = (lstrlenW(pszData) + 2) * sizeof(WCHAR);
435ef6711c9SSerge Gautherie     error = RegSetValueExW(hKey, L"ProductSuite", 0, REG_MULTI_SZ, (const BYTE *)pszData, cbData);
43648160c74SKatayama Hirofumi MZ     if (error)
437612729b0SKatayama Hirofumi MZ     {
438612729b0SKatayama Hirofumi MZ         DPRINT1("RegSetValueExW failed\n");
439612729b0SKatayama Hirofumi MZ         goto Error;
440612729b0SKatayama Hirofumi MZ     }
44148160c74SKatayama Hirofumi MZ 
44248160c74SKatayama Hirofumi MZ     /* write ProductType */
443612729b0SKatayama Hirofumi MZ     pszData = pData->ProductType;
444612729b0SKatayama Hirofumi MZ     cbData = (lstrlenW(pszData) + 1) * sizeof(WCHAR);
445ef6711c9SSerge Gautherie     error = RegSetValueExW(hKey, L"ProductType", 0, REG_SZ, (const BYTE *)pszData, cbData);
44648160c74SKatayama Hirofumi MZ     if (error)
447612729b0SKatayama Hirofumi MZ     {
448612729b0SKatayama Hirofumi MZ         DPRINT1("RegSetValueExW failed\n");
449612729b0SKatayama Hirofumi MZ         goto Error;
45048160c74SKatayama Hirofumi MZ     }
45148160c74SKatayama Hirofumi MZ 
45248160c74SKatayama Hirofumi MZ     RegCloseKey(hKey);
4530a7a747dSKatayama Hirofumi MZ 
454612729b0SKatayama Hirofumi MZ     /* open ReactOS version key */
4550a7a747dSKatayama Hirofumi MZ     error = RegOpenKeyExW(HKEY_LOCAL_MACHINE, s_szRosVersion, 0, KEY_WRITE, &hKey);
4560a7a747dSKatayama Hirofumi MZ     if (error)
457612729b0SKatayama Hirofumi MZ     {
458612729b0SKatayama Hirofumi MZ         DPRINT1("RegOpenKeyExW failed\n");
459612729b0SKatayama Hirofumi MZ         goto Error;
460612729b0SKatayama Hirofumi MZ     }
4610a7a747dSKatayama Hirofumi MZ 
462612729b0SKatayama Hirofumi MZ     /* write ReportAsWorkstation */
463612729b0SKatayama Hirofumi MZ     dwValue = pData->ReportAsWorkstation;
4640a7a747dSKatayama Hirofumi MZ     cbData = sizeof(dwValue);
465612729b0SKatayama Hirofumi MZ     error = RegSetValueExW(hKey, L"ReportAsWorkstation", 0, REG_DWORD, (const BYTE *)&dwValue, cbData);
466612729b0SKatayama Hirofumi MZ     if (error)
467612729b0SKatayama Hirofumi MZ     {
468612729b0SKatayama Hirofumi MZ         DPRINT1("RegSetValueExW failed\n");
469612729b0SKatayama Hirofumi MZ         goto Error;
470612729b0SKatayama Hirofumi MZ     }
4710a7a747dSKatayama Hirofumi MZ 
4720a7a747dSKatayama Hirofumi MZ     RegCloseKey(hKey);
4730a7a747dSKatayama Hirofumi MZ 
474612729b0SKatayama Hirofumi MZ     /* open Control Windows key */
475612729b0SKatayama Hirofumi MZ     error = RegOpenKeyExW(HKEY_LOCAL_MACHINE, s_szControlWindows, 0, KEY_WRITE, &hKey);
476612729b0SKatayama Hirofumi MZ     if (error)
477612729b0SKatayama Hirofumi MZ     {
478612729b0SKatayama Hirofumi MZ         DPRINT1("RegOpenKeyExW failed\n");
479612729b0SKatayama Hirofumi MZ         goto Error;
480612729b0SKatayama Hirofumi MZ     }
481612729b0SKatayama Hirofumi MZ 
482612729b0SKatayama Hirofumi MZ     /* write Control Windows CSDVersion */
483612729b0SKatayama Hirofumi MZ     dwValue = pData->CSDVersion;
484612729b0SKatayama Hirofumi MZ     cbData = sizeof(dwValue);
485612729b0SKatayama Hirofumi MZ     error = RegSetValueExW(hKey, L"CSDVersion", 0, REG_DWORD, (const BYTE *)&dwValue, cbData);
486612729b0SKatayama Hirofumi MZ     if (error)
487612729b0SKatayama Hirofumi MZ     {
488612729b0SKatayama Hirofumi MZ         DPRINT1("RegSetValueExW failed\n");
489612729b0SKatayama Hirofumi MZ         goto Error;
490612729b0SKatayama Hirofumi MZ     }
491612729b0SKatayama Hirofumi MZ 
4922edcb58eSVladimir Barinov     RegCloseKey(hKey);
4932edcb58eSVladimir Barinov 
4942edcb58eSVladimir Barinov     /* open Winlogon key */
4952edcb58eSVladimir Barinov     error = RegOpenKeyExW(HKEY_LOCAL_MACHINE, s_szWinlogon, 0, KEY_WRITE, &hKey);
4962edcb58eSVladimir Barinov     if (error)
4972edcb58eSVladimir Barinov     {
4982edcb58eSVladimir Barinov         DPRINT1("RegOpenKeyExW failed\n");
4992edcb58eSVladimir Barinov         goto Error;
5002edcb58eSVladimir Barinov     }
5012edcb58eSVladimir Barinov 
5022edcb58eSVladimir Barinov     /* write LogonType */
5032edcb58eSVladimir Barinov     dwValue = pData->LogonType;
5042edcb58eSVladimir Barinov     cbData = sizeof(dwValue);
5052edcb58eSVladimir Barinov     error = RegSetValueExW(hKey, L"LogonType", 0, REG_DWORD, (const BYTE *)&dwValue, cbData);
5062edcb58eSVladimir Barinov     if (error)
5072edcb58eSVladimir Barinov     {
5082edcb58eSVladimir Barinov         DPRINT1("RegSetValueExW failed\n");
5092edcb58eSVladimir Barinov         goto Error;
5102edcb58eSVladimir Barinov     }
5112edcb58eSVladimir Barinov 
512612729b0SKatayama Hirofumi MZ Error:
513612729b0SKatayama Hirofumi MZ     if (hKey)
514612729b0SKatayama Hirofumi MZ         RegCloseKey(hKey);
515612729b0SKatayama Hirofumi MZ 
51648160c74SKatayama Hirofumi MZ     return error == ERROR_SUCCESS;
51748160c74SKatayama Hirofumi MZ }
51848160c74SKatayama Hirofumi MZ 
51948160c74SKatayama Hirofumi MZ static void
520612729b0SKatayama Hirofumi MZ OnChooseOption(HWND hwndDlg, PRODUCT_OPTION nOption)
52148160c74SKatayama Hirofumi MZ {
52248160c74SKatayama Hirofumi MZ     WCHAR szText[256];
523612729b0SKatayama Hirofumi MZ     ASSERT(0 <= nOption && nOption < _countof(s_ProductOptionData));
52448160c74SKatayama Hirofumi MZ 
525612729b0SKatayama Hirofumi MZ     switch (nOption)
526612729b0SKatayama Hirofumi MZ     {
527612729b0SKatayama Hirofumi MZ         case PRODUCT_OPTION_SERVER:
52848160c74SKatayama Hirofumi MZ             LoadStringW(hDllInstance, IDS_PRODUCTSERVERINFO, szText, _countof(szText));
529612729b0SKatayama Hirofumi MZ             break;
530612729b0SKatayama Hirofumi MZ 
531612729b0SKatayama Hirofumi MZ         case PRODUCT_OPTION_WORKSTATION:
532612729b0SKatayama Hirofumi MZ             LoadStringW(hDllInstance, IDS_PRODUCTWORKSTATIONINFO, szText, _countof(szText));
533612729b0SKatayama Hirofumi MZ             break;
534612729b0SKatayama Hirofumi MZ 
535612729b0SKatayama Hirofumi MZ         default:
536612729b0SKatayama Hirofumi MZ             return;
53748160c74SKatayama Hirofumi MZ     }
53848160c74SKatayama Hirofumi MZ 
53948160c74SKatayama Hirofumi MZ     SetDlgItemTextW(hwndDlg, IDC_PRODUCT_DESCRIPTION, szText);
54048160c74SKatayama Hirofumi MZ }
54148160c74SKatayama Hirofumi MZ 
54248160c74SKatayama Hirofumi MZ static INT_PTR CALLBACK
54348160c74SKatayama Hirofumi MZ ProductPageDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
54448160c74SKatayama Hirofumi MZ {
54548160c74SKatayama Hirofumi MZ     LPNMHDR lpnm;
54648160c74SKatayama Hirofumi MZ     PSETUPDATA pSetupData;
54748160c74SKatayama Hirofumi MZ     INT iItem;
5484cbb2176SJoachim Henze     WCHAR szText[64], szDefault[64];
54948160c74SKatayama Hirofumi MZ     HICON hIcon;
55048160c74SKatayama Hirofumi MZ 
55148160c74SKatayama Hirofumi MZ     pSetupData = (PSETUPDATA)GetWindowLongPtr(hwndDlg, DWLP_USER);
55248160c74SKatayama Hirofumi MZ 
55348160c74SKatayama Hirofumi MZ     switch (uMsg)
55448160c74SKatayama Hirofumi MZ     {
55548160c74SKatayama Hirofumi MZ         case WM_INITDIALOG:
55648160c74SKatayama Hirofumi MZ         {
55748160c74SKatayama Hirofumi MZ             pSetupData = (PSETUPDATA)((LPPROPSHEETPAGE)lParam)->lParam;
55848160c74SKatayama Hirofumi MZ             SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pSetupData);
55948160c74SKatayama Hirofumi MZ 
560612729b0SKatayama Hirofumi MZ             LoadStringW(hDllInstance, IDS_DEFAULT, szDefault, _countof(szDefault));
561612729b0SKatayama Hirofumi MZ 
56248160c74SKatayama Hirofumi MZ             LoadStringW(hDllInstance, IDS_PRODUCTSERVERNAME, szText, _countof(szText));
563612729b0SKatayama Hirofumi MZ             if (PRODUCT_OPTION_DEFAULT == PRODUCT_OPTION_SERVER)
564612729b0SKatayama Hirofumi MZ             {
565612729b0SKatayama Hirofumi MZ                 StringCchCatW(szText, _countof(szText), L" ");
566612729b0SKatayama Hirofumi MZ                 StringCchCatW(szText, _countof(szText), szDefault);
567612729b0SKatayama Hirofumi MZ             }
56848160c74SKatayama Hirofumi MZ             SendDlgItemMessageW(hwndDlg, IDC_PRODUCT_OPTIONS, CB_ADDSTRING, 0, (LPARAM)szText);
56948160c74SKatayama Hirofumi MZ 
57048160c74SKatayama Hirofumi MZ             LoadStringW(hDllInstance, IDS_PRODUCTWORKSTATIONNAME, szText, _countof(szText));
571612729b0SKatayama Hirofumi MZ             if (PRODUCT_OPTION_DEFAULT == PRODUCT_OPTION_WORKSTATION)
572612729b0SKatayama Hirofumi MZ             {
573612729b0SKatayama Hirofumi MZ                 StringCchCatW(szText, _countof(szText), L" ");
574612729b0SKatayama Hirofumi MZ                 StringCchCatW(szText, _countof(szText), szDefault);
575612729b0SKatayama Hirofumi MZ             }
57648160c74SKatayama Hirofumi MZ             SendDlgItemMessageW(hwndDlg, IDC_PRODUCT_OPTIONS, CB_ADDSTRING, 0, (LPARAM)szText);
57748160c74SKatayama Hirofumi MZ 
578612729b0SKatayama Hirofumi MZ             SendDlgItemMessageW(hwndDlg, IDC_PRODUCT_OPTIONS, CB_SETCURSEL, PRODUCT_OPTION_DEFAULT, 0);
579612729b0SKatayama Hirofumi MZ             OnChooseOption(hwndDlg, PRODUCT_OPTION_DEFAULT);
58048160c74SKatayama Hirofumi MZ 
58148160c74SKatayama Hirofumi MZ             hIcon = LoadIcon(NULL, IDI_WINLOGO);
58248160c74SKatayama Hirofumi MZ             SendDlgItemMessageW(hwndDlg, IDC_PRODUCT_ICON, STM_SETICON, (WPARAM)hIcon, 0);
58348160c74SKatayama Hirofumi MZ             return TRUE;
58448160c74SKatayama Hirofumi MZ         }
58548160c74SKatayama Hirofumi MZ 
58648160c74SKatayama Hirofumi MZ         case WM_COMMAND:
58748160c74SKatayama Hirofumi MZ             if (HIWORD(wParam) == CBN_SELCHANGE && IDC_PRODUCT_OPTIONS == LOWORD(wParam))
58848160c74SKatayama Hirofumi MZ             {
58948160c74SKatayama Hirofumi MZ                 iItem = SendDlgItemMessageW(hwndDlg, IDC_PRODUCT_OPTIONS, CB_GETCURSEL, 0, 0);
590612729b0SKatayama Hirofumi MZ                 OnChooseOption(hwndDlg, (PRODUCT_OPTION)iItem);
59148160c74SKatayama Hirofumi MZ             }
59248160c74SKatayama Hirofumi MZ             break;
59348160c74SKatayama Hirofumi MZ 
59448160c74SKatayama Hirofumi MZ         case WM_NOTIFY:
59548160c74SKatayama Hirofumi MZ         {
59648160c74SKatayama Hirofumi MZ             lpnm = (LPNMHDR)lParam;
59748160c74SKatayama Hirofumi MZ 
59848160c74SKatayama Hirofumi MZ             switch (lpnm->code)
59948160c74SKatayama Hirofumi MZ             {
60048160c74SKatayama Hirofumi MZ                 case PSN_SETACTIVE:
60148160c74SKatayama Hirofumi MZ                     /* Enable the Back and Next buttons */
60248160c74SKatayama Hirofumi MZ                     PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK | PSWIZB_NEXT);
60348160c74SKatayama Hirofumi MZ                     if (pSetupData->UnattendSetup)
60448160c74SKatayama Hirofumi MZ                     {
605612729b0SKatayama Hirofumi MZ                         OnChooseOption(hwndDlg, pSetupData->ProductOption);
60648160c74SKatayama Hirofumi MZ                         DoWriteProductOption(pSetupData->ProductOption);
6070182dcd7STimo Kreuzer                         SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_LOCALEPAGE);
608c2c66affSColin Finck                         return TRUE;
609c2c66affSColin Finck                     }
610c2c66affSColin Finck                     break;
611c2c66affSColin Finck 
61248160c74SKatayama Hirofumi MZ                 case PSN_WIZNEXT:
61348160c74SKatayama Hirofumi MZ                     iItem = SendDlgItemMessageW(hwndDlg, IDC_PRODUCT_OPTIONS, CB_GETCURSEL, 0, 0);
61448160c74SKatayama Hirofumi MZ                     pSetupData->ProductOption = (PRODUCT_OPTION)iItem;
61548160c74SKatayama Hirofumi MZ                     DoWriteProductOption(pSetupData->ProductOption);
61648160c74SKatayama Hirofumi MZ                     break;
61748160c74SKatayama Hirofumi MZ 
618c2c66affSColin Finck                 case PSN_WIZBACK:
619c2c66affSColin Finck                     pSetupData->UnattendSetup = FALSE;
620c2c66affSColin Finck                     break;
621c2c66affSColin Finck 
622c2c66affSColin Finck                 default:
623c2c66affSColin Finck                     break;
624c2c66affSColin Finck             }
625c2c66affSColin Finck         }
626c2c66affSColin Finck         break;
627c2c66affSColin Finck 
628c2c66affSColin Finck         default:
629c2c66affSColin Finck             break;
630c2c66affSColin Finck     }
631c2c66affSColin Finck 
632c2c66affSColin Finck     return FALSE;
633c2c66affSColin Finck }
634c2c66affSColin Finck 
635c2c66affSColin Finck static
636c2c66affSColin Finck BOOL
637c2c66affSColin Finck WriteOwnerSettings(WCHAR * OwnerName,
638c2c66affSColin Finck                    WCHAR * OwnerOrganization)
639c2c66affSColin Finck {
640c2c66affSColin Finck     HKEY hKey;
641c2c66affSColin Finck     LONG res;
642c2c66affSColin Finck 
643c2c66affSColin Finck     res = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
644c2c66affSColin Finck                         L"Software\\Microsoft\\Windows NT\\CurrentVersion",
645c2c66affSColin Finck                         0,
646c2c66affSColin Finck                         KEY_ALL_ACCESS,
647c2c66affSColin Finck                         &hKey);
648c2c66affSColin Finck 
649c2c66affSColin Finck     if (res != ERROR_SUCCESS)
650c2c66affSColin Finck     {
651c2c66affSColin Finck         return FALSE;
652c2c66affSColin Finck     }
653c2c66affSColin Finck 
654c2c66affSColin Finck     res = RegSetValueExW(hKey,
655c2c66affSColin Finck                          L"RegisteredOwner",
656c2c66affSColin Finck                          0,
657c2c66affSColin Finck                          REG_SZ,
658c2c66affSColin Finck                          (LPBYTE)OwnerName,
659c2c66affSColin Finck                          (wcslen(OwnerName) + 1) * sizeof(WCHAR));
660c2c66affSColin Finck 
661c2c66affSColin Finck     if (res != ERROR_SUCCESS)
662c2c66affSColin Finck     {
663c2c66affSColin Finck         RegCloseKey(hKey);
664c2c66affSColin Finck         return FALSE;
665c2c66affSColin Finck     }
666c2c66affSColin Finck 
667c2c66affSColin Finck     res = RegSetValueExW(hKey,
668c2c66affSColin Finck                          L"RegisteredOrganization",
669c2c66affSColin Finck                          0,
670c2c66affSColin Finck                          REG_SZ,
671c2c66affSColin Finck                          (LPBYTE)OwnerOrganization,
672c2c66affSColin Finck                          (wcslen(OwnerOrganization) + 1) * sizeof(WCHAR));
673c2c66affSColin Finck 
674c2c66affSColin Finck     RegCloseKey(hKey);
675c2c66affSColin Finck     return (res == ERROR_SUCCESS);
676c2c66affSColin Finck }
677c2c66affSColin Finck 
678c2c66affSColin Finck static INT_PTR CALLBACK
679c2c66affSColin Finck OwnerPageDlgProc(HWND hwndDlg,
680c2c66affSColin Finck                  UINT uMsg,
681c2c66affSColin Finck                  WPARAM wParam,
682c2c66affSColin Finck                  LPARAM lParam)
683c2c66affSColin Finck {
684c2c66affSColin Finck     WCHAR OwnerName[51];
685c2c66affSColin Finck     WCHAR OwnerOrganization[51];
686c2c66affSColin Finck     WCHAR Title[64];
687c2c66affSColin Finck     WCHAR ErrorName[256];
688c2c66affSColin Finck     LPNMHDR lpnm;
689c2c66affSColin Finck     PSETUPDATA pSetupData;
690c2c66affSColin Finck 
691c2c66affSColin Finck     pSetupData = (PSETUPDATA)GetWindowLongPtr(hwndDlg, DWLP_USER);
692c2c66affSColin Finck 
693c2c66affSColin Finck     switch (uMsg)
694c2c66affSColin Finck     {
695c2c66affSColin Finck         case WM_INITDIALOG:
696c2c66affSColin Finck         {
697c2c66affSColin Finck             pSetupData = (PSETUPDATA)((LPPROPSHEETPAGE)lParam)->lParam;
698c2c66affSColin Finck             SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pSetupData);
699c2c66affSColin Finck 
700c2c66affSColin Finck             /* set a localized ('Owner') placeholder string as default */
701c2c66affSColin Finck             if (LoadStringW(hDllInstance, IDS_MACHINE_OWNER_NAME, OwnerName, _countof(OwnerName)))
702c2c66affSColin Finck             {
703c2c66affSColin Finck                 SendDlgItemMessage(hwndDlg, IDC_OWNERNAME, WM_SETTEXT, 0, (LPARAM)OwnerName);
704c2c66affSColin Finck             }
705c2c66affSColin Finck 
706c2c66affSColin Finck             SendDlgItemMessage(hwndDlg, IDC_OWNERNAME, EM_LIMITTEXT, 50, 0);
707c2c66affSColin Finck             SendDlgItemMessage(hwndDlg, IDC_OWNERORGANIZATION, EM_LIMITTEXT, 50, 0);
708c2c66affSColin Finck 
709c2c66affSColin Finck             /* Set focus to owner name */
710c2c66affSColin Finck             SetFocus(GetDlgItem(hwndDlg, IDC_OWNERNAME));
711c2c66affSColin Finck 
712c2c66affSColin Finck             /* Select the default text to quickly overwrite it by typing */
713c2c66affSColin Finck             SendDlgItemMessage(hwndDlg, IDC_OWNERNAME, EM_SETSEL, 0, -1);
714c2c66affSColin Finck         }
715c2c66affSColin Finck         break;
716c2c66affSColin Finck 
717c2c66affSColin Finck 
718c2c66affSColin Finck         case WM_NOTIFY:
719c2c66affSColin Finck         {
720c2c66affSColin Finck             lpnm = (LPNMHDR)lParam;
721c2c66affSColin Finck 
722c2c66affSColin Finck             switch (lpnm->code)
723c2c66affSColin Finck             {
724c2c66affSColin Finck                 case PSN_SETACTIVE:
725c2c66affSColin Finck                     /* Enable the Back and Next buttons */
726c2c66affSColin Finck                     PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK | PSWIZB_NEXT);
727c2c66affSColin Finck                     if (pSetupData->UnattendSetup)
728c2c66affSColin Finck                     {
729c2c66affSColin Finck                         SendMessage(GetDlgItem(hwndDlg, IDC_OWNERNAME), WM_SETTEXT, 0, (LPARAM)pSetupData->OwnerName);
730c2c66affSColin Finck                         SendMessage(GetDlgItem(hwndDlg, IDC_OWNERORGANIZATION), WM_SETTEXT, 0, (LPARAM)pSetupData->OwnerOrganization);
731c2c66affSColin Finck                         if (WriteOwnerSettings(pSetupData->OwnerName, pSetupData->OwnerOrganization))
732c2c66affSColin Finck                         {
7330182dcd7STimo Kreuzer                             SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_COMPUTERPAGE);
734c2c66affSColin Finck                             return TRUE;
735c2c66affSColin Finck                         }
736c2c66affSColin Finck                     }
737c2c66affSColin Finck                     break;
738c2c66affSColin Finck 
739c2c66affSColin Finck                 case PSN_WIZNEXT:
740c2c66affSColin Finck                     OwnerName[0] = 0;
741c2c66affSColin Finck                     if (GetDlgItemTextW(hwndDlg, IDC_OWNERNAME, OwnerName, 50) == 0)
742c2c66affSColin Finck                     {
74362678985SHermès Bélusca-Maïto                         if (0 == LoadStringW(hDllInstance, IDS_REACTOS_SETUP, Title, ARRAYSIZE(Title)))
744c2c66affSColin Finck                         {
745c2c66affSColin Finck                             wcscpy(Title, L"ReactOS Setup");
746c2c66affSColin Finck                         }
74762678985SHermès Bélusca-Maïto                         if (0 == LoadStringW(hDllInstance, IDS_WZD_NAME, ErrorName, ARRAYSIZE(ErrorName)))
748c2c66affSColin Finck                         {
749c2c66affSColin Finck                             wcscpy(ErrorName, L"Setup cannot continue until you enter your name.");
750c2c66affSColin Finck                         }
751c2c66affSColin Finck                         MessageBoxW(hwndDlg, ErrorName, Title, MB_ICONERROR | MB_OK);
752c2c66affSColin Finck 
753c2c66affSColin Finck                         SetFocus(GetDlgItem(hwndDlg, IDC_OWNERNAME));
7540182dcd7STimo Kreuzer                         SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1);
755c2c66affSColin Finck 
756c2c66affSColin Finck                         return TRUE;
757c2c66affSColin Finck                     }
758c2c66affSColin Finck 
759c2c66affSColin Finck                     OwnerOrganization[0] = 0;
760c2c66affSColin Finck                     GetDlgItemTextW(hwndDlg, IDC_OWNERORGANIZATION, OwnerOrganization, 50);
761c2c66affSColin Finck 
762c2c66affSColin Finck                     if (!WriteOwnerSettings(OwnerName, OwnerOrganization))
763c2c66affSColin Finck                     {
764c2c66affSColin Finck                         SetFocus(GetDlgItem(hwndDlg, IDC_OWNERNAME));
7650182dcd7STimo Kreuzer                         SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1);
766c2c66affSColin Finck                         return TRUE;
767c2c66affSColin Finck                     }
768c2c66affSColin Finck 
769c2c66affSColin Finck                 case PSN_WIZBACK:
770c2c66affSColin Finck                     pSetupData->UnattendSetup = FALSE;
771c2c66affSColin Finck                     break;
772c2c66affSColin Finck 
773c2c66affSColin Finck                 default:
774c2c66affSColin Finck                     break;
775c2c66affSColin Finck             }
776c2c66affSColin Finck         }
777c2c66affSColin Finck         break;
778c2c66affSColin Finck 
779c2c66affSColin Finck         default:
780c2c66affSColin Finck             break;
781c2c66affSColin Finck     }
782c2c66affSColin Finck 
783c2c66affSColin Finck     return FALSE;
784c2c66affSColin Finck }
785c2c66affSColin Finck 
786c2c66affSColin Finck static
787c2c66affSColin Finck BOOL
788c2c66affSColin Finck WriteComputerSettings(WCHAR * ComputerName, HWND hwndDlg)
789c2c66affSColin Finck {
790c2c66affSColin Finck     WCHAR Title[64];
791c2c66affSColin Finck     WCHAR ErrorComputerName[256];
7929a39315dSKatayama Hirofumi MZ     LONG lError;
7939a39315dSKatayama Hirofumi MZ     HKEY hKey = NULL;
794c2c66affSColin Finck 
795c2c66affSColin Finck     if (!SetComputerNameW(ComputerName))
796c2c66affSColin Finck     {
797c2c66affSColin Finck         if (hwndDlg != NULL)
798c2c66affSColin Finck         {
79962678985SHermès Bélusca-Maïto             if (0 == LoadStringW(hDllInstance, IDS_REACTOS_SETUP, Title, ARRAYSIZE(Title)))
800c2c66affSColin Finck             {
801c2c66affSColin Finck                 wcscpy(Title, L"ReactOS Setup");
802c2c66affSColin Finck             }
803c2c66affSColin Finck             if (0 == LoadStringW(hDllInstance, IDS_WZD_SETCOMPUTERNAME, ErrorComputerName,
80462678985SHermès Bélusca-Maïto                                  ARRAYSIZE(ErrorComputerName)))
805c2c66affSColin Finck             {
806c2c66affSColin Finck                 wcscpy(ErrorComputerName, L"Setup failed to set the computer name.");
807c2c66affSColin Finck             }
808c2c66affSColin Finck             MessageBoxW(hwndDlg, ErrorComputerName, Title, MB_ICONERROR | MB_OK);
809c2c66affSColin Finck         }
810c2c66affSColin Finck 
811c2c66affSColin Finck         return FALSE;
812c2c66affSColin Finck     }
813c2c66affSColin Finck 
8149e2ae9b0SEric Kohl     /* Set the physical DNS domain */
8159e2ae9b0SEric Kohl     SetComputerNameExW(ComputerNamePhysicalDnsDomain, L"");
8169e2ae9b0SEric Kohl 
8179e2ae9b0SEric Kohl     /* Set the physical DNS hostname */
818c2c66affSColin Finck     SetComputerNameExW(ComputerNamePhysicalDnsHostname, ComputerName);
819c2c66affSColin Finck 
820c2c66affSColin Finck     /* Set the accounts domain name */
821c2c66affSColin Finck     SetAccountsDomainSid(NULL, ComputerName);
822c2c66affSColin Finck 
8239a39315dSKatayama Hirofumi MZ     /* Now we need to set the Hostname */
8249a39315dSKatayama Hirofumi MZ     lError = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
8259a39315dSKatayama Hirofumi MZ                            L"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters",
8269a39315dSKatayama Hirofumi MZ                            0,
8279a39315dSKatayama Hirofumi MZ                            KEY_SET_VALUE,
8289a39315dSKatayama Hirofumi MZ                            &hKey);
8299a39315dSKatayama Hirofumi MZ     if (lError != ERROR_SUCCESS)
8309a39315dSKatayama Hirofumi MZ     {
8319a39315dSKatayama Hirofumi MZ         DPRINT1("RegOpenKeyExW for Tcpip\\Parameters failed (%08lX)\n", lError);
8329a39315dSKatayama Hirofumi MZ         return TRUE;
8339a39315dSKatayama Hirofumi MZ     }
8349a39315dSKatayama Hirofumi MZ 
8359a39315dSKatayama Hirofumi MZ     lError = RegSetValueEx(hKey,
8369a39315dSKatayama Hirofumi MZ                            L"Hostname",
8379a39315dSKatayama Hirofumi MZ                            0,
8389a39315dSKatayama Hirofumi MZ                            REG_SZ,
8399a39315dSKatayama Hirofumi MZ                            (LPBYTE)ComputerName,
8409a39315dSKatayama Hirofumi MZ                            (wcslen(ComputerName) + 1) * sizeof(WCHAR));
8419a39315dSKatayama Hirofumi MZ     if (lError != ERROR_SUCCESS)
8429a39315dSKatayama Hirofumi MZ     {
8439a39315dSKatayama Hirofumi MZ         DPRINT1("RegSetValueEx(\"Hostname\") failed (%08lX)\n", lError);
8449a39315dSKatayama Hirofumi MZ     }
8459a39315dSKatayama Hirofumi MZ 
8469a39315dSKatayama Hirofumi MZ     RegCloseKey(hKey);
8479a39315dSKatayama Hirofumi MZ 
848c2c66affSColin Finck     return TRUE;
849c2c66affSColin Finck }
850c2c66affSColin Finck 
851c2c66affSColin Finck 
852c2c66affSColin Finck static
853c2c66affSColin Finck BOOL
854c2c66affSColin Finck WriteDefaultLogonData(LPWSTR Domain)
855c2c66affSColin Finck {
856c2c66affSColin Finck     WCHAR szAdministratorName[256];
857c2c66affSColin Finck     HKEY hKey = NULL;
858c2c66affSColin Finck     LONG lError;
859c2c66affSColin Finck 
860c2c66affSColin Finck     if (LoadStringW(hDllInstance,
861c2c66affSColin Finck                     IDS_ADMINISTRATOR_NAME,
862c2c66affSColin Finck                     szAdministratorName,
86362678985SHermès Bélusca-Maïto                     ARRAYSIZE(szAdministratorName)) == 0)
864c2c66affSColin Finck     {
865c2c66affSColin Finck         wcscpy(szAdministratorName, L"Administrator");
866c2c66affSColin Finck     }
867c2c66affSColin Finck 
868c2c66affSColin Finck     lError = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
869c2c66affSColin Finck                            L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon",
870c2c66affSColin Finck                            0,
871c2c66affSColin Finck                            KEY_SET_VALUE,
872c2c66affSColin Finck                            &hKey);
873c2c66affSColin Finck     if (lError != ERROR_SUCCESS)
874c2c66affSColin Finck         return FALSE;
875c2c66affSColin Finck 
876c2c66affSColin Finck     lError = RegSetValueEx(hKey,
877b784c7bfSEric Kohl                            L"DefaultDomainName",
878c2c66affSColin Finck                            0,
879c2c66affSColin Finck                            REG_SZ,
880c2c66affSColin Finck                            (LPBYTE)Domain,
881c2c66affSColin Finck                            (wcslen(Domain)+ 1) * sizeof(WCHAR));
882c2c66affSColin Finck     if (lError != ERROR_SUCCESS)
883c2c66affSColin Finck     {
884b784c7bfSEric Kohl         DPRINT1("RegSetValueEx(\"DefaultDomainName\") failed!\n");
885c2c66affSColin Finck     }
886c2c66affSColin Finck 
887c2c66affSColin Finck     lError = RegSetValueEx(hKey,
888c2c66affSColin Finck                            L"DefaultUserName",
889c2c66affSColin Finck                            0,
890c2c66affSColin Finck                            REG_SZ,
891c2c66affSColin Finck                            (LPBYTE)szAdministratorName,
892c2c66affSColin Finck                            (wcslen(szAdministratorName)+ 1) * sizeof(WCHAR));
893c2c66affSColin Finck     if (lError != ERROR_SUCCESS)
894c2c66affSColin Finck     {
895c2c66affSColin Finck         DPRINT1("RegSetValueEx(\"DefaultUserName\") failed!\n");
896c2c66affSColin Finck     }
897c2c66affSColin Finck 
898c2c66affSColin Finck     RegCloseKey(hKey);
899c2c66affSColin Finck 
900c2c66affSColin Finck     return TRUE;
901c2c66affSColin Finck }
902c2c66affSColin Finck 
903c2c66affSColin Finck 
904c2c66affSColin Finck /* lpBuffer will be filled with a 15-char string (plus the null terminator) */
905c2c66affSColin Finck static void
906c2c66affSColin Finck GenerateComputerName(LPWSTR lpBuffer)
907c2c66affSColin Finck {
908c2c66affSColin Finck     static const WCHAR Chars[] = L"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
909c2c66affSColin Finck     static const unsigned cChars = sizeof(Chars) / sizeof(WCHAR) - 1;
910c2c66affSColin Finck     unsigned i;
911c2c66affSColin Finck 
912c2c66affSColin Finck     wcscpy(lpBuffer, L"REACTOS-");
913c2c66affSColin Finck 
914c2c66affSColin Finck     srand(GetTickCount());
915c2c66affSColin Finck 
916c2c66affSColin Finck     /* fill in 7 characters */
917c2c66affSColin Finck     for (i = 8; i < 15; i++)
918c2c66affSColin Finck         lpBuffer[i] = Chars[rand() % cChars];
919c2c66affSColin Finck 
920c2c66affSColin Finck     lpBuffer[15] = UNICODE_NULL; /* NULL-terminate */
921c2c66affSColin Finck }
922c2c66affSColin Finck 
923c2c66affSColin Finck static INT_PTR CALLBACK
924c2c66affSColin Finck ComputerPageDlgProc(HWND hwndDlg,
925c2c66affSColin Finck                     UINT uMsg,
926c2c66affSColin Finck                     WPARAM wParam,
927c2c66affSColin Finck                     LPARAM lParam)
928c2c66affSColin Finck {
929c2c66affSColin Finck     WCHAR ComputerName[MAX_COMPUTERNAME_LENGTH + 1];
930c2c66affSColin Finck     WCHAR Password1[128];
931c2c66affSColin Finck     WCHAR Password2[128];
932c2c66affSColin Finck     PWCHAR Password;
933c2c66affSColin Finck     WCHAR Title[64];
934c2c66affSColin Finck     WCHAR EmptyComputerName[256], NotMatchPassword[256], WrongPassword[256];
935c2c66affSColin Finck     LPNMHDR lpnm;
936c2c66affSColin Finck     PSETUPDATA pSetupData;
937c2c66affSColin Finck 
938c2c66affSColin Finck     pSetupData = (PSETUPDATA)GetWindowLongPtr(hwndDlg, DWLP_USER);
939c2c66affSColin Finck 
94062678985SHermès Bélusca-Maïto     if (0 == LoadStringW(hDllInstance, IDS_REACTOS_SETUP, Title, ARRAYSIZE(Title)))
941c2c66affSColin Finck     {
942c2c66affSColin Finck         wcscpy(Title, L"ReactOS Setup");
943c2c66affSColin Finck     }
944c2c66affSColin Finck 
945c2c66affSColin Finck     switch (uMsg)
946c2c66affSColin Finck     {
947c2c66affSColin Finck         case WM_INITDIALOG:
948c2c66affSColin Finck             pSetupData = (PSETUPDATA)((LPPROPSHEETPAGE)lParam)->lParam;
949c2c66affSColin Finck             SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pSetupData);
950c2c66affSColin Finck 
951c2c66affSColin Finck             /* Generate a new pseudo-random computer name */
952c2c66affSColin Finck             GenerateComputerName(ComputerName);
953c2c66affSColin Finck 
954c2c66affSColin Finck             /* Display current computer name */
955c2c66affSColin Finck             SetDlgItemTextW(hwndDlg, IDC_COMPUTERNAME, ComputerName);
956c2c66affSColin Finck 
957c2c66affSColin Finck             /* Set text limits */
958c2c66affSColin Finck             SendDlgItemMessage(hwndDlg, IDC_COMPUTERNAME, EM_LIMITTEXT, MAX_COMPUTERNAME_LENGTH, 0);
959c2c66affSColin Finck             SendDlgItemMessage(hwndDlg, IDC_ADMINPASSWORD1, EM_LIMITTEXT, 127, 0);
960c2c66affSColin Finck             SendDlgItemMessage(hwndDlg, IDC_ADMINPASSWORD2, EM_LIMITTEXT, 127, 0);
961c2c66affSColin Finck 
962c2c66affSColin Finck             /* Set focus to computer name */
963c2c66affSColin Finck             SetFocus(GetDlgItem(hwndDlg, IDC_COMPUTERNAME));
964c2c66affSColin Finck             if (pSetupData->UnattendSetup)
965c2c66affSColin Finck             {
966c2c66affSColin Finck                 SendMessage(GetDlgItem(hwndDlg, IDC_COMPUTERNAME), WM_SETTEXT, 0, (LPARAM)pSetupData->ComputerName);
967c2c66affSColin Finck                 SendMessage(GetDlgItem(hwndDlg, IDC_ADMINPASSWORD1), WM_SETTEXT, 0, (LPARAM)pSetupData->AdminPassword);
968c2c66affSColin Finck                 SendMessage(GetDlgItem(hwndDlg, IDC_ADMINPASSWORD2), WM_SETTEXT, 0, (LPARAM)pSetupData->AdminPassword);
969c2c66affSColin Finck                 WriteComputerSettings(pSetupData->ComputerName, NULL);
970c2c66affSColin Finck                 SetAdministratorPassword(pSetupData->AdminPassword);
971c2c66affSColin Finck             }
972c2c66affSColin Finck 
973c2c66affSColin Finck             /* Store the administrator account name as the default user name */
974c2c66affSColin Finck             WriteDefaultLogonData(pSetupData->ComputerName);
975c2c66affSColin Finck             break;
976c2c66affSColin Finck 
977c2c66affSColin Finck 
978c2c66affSColin Finck         case WM_NOTIFY:
979c2c66affSColin Finck         {
980c2c66affSColin Finck             lpnm = (LPNMHDR)lParam;
981c2c66affSColin Finck 
982c2c66affSColin Finck             switch (lpnm->code)
983c2c66affSColin Finck             {
984c2c66affSColin Finck                 case PSN_SETACTIVE:
985c2c66affSColin Finck                     /* Enable the Back and Next buttons */
986c2c66affSColin Finck                     PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK | PSWIZB_NEXT);
987c2c66affSColin Finck                     if (pSetupData->UnattendSetup && WriteComputerSettings(pSetupData->ComputerName, hwndDlg))
988c2c66affSColin Finck                     {
9890182dcd7STimo Kreuzer                         SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_THEMEPAGE);
990c2c66affSColin Finck                         return TRUE;
991c2c66affSColin Finck                     }
992c2c66affSColin Finck                     break;
993c2c66affSColin Finck 
994c2c66affSColin Finck                 case PSN_WIZNEXT:
995c2c66affSColin Finck                     if (0 == GetDlgItemTextW(hwndDlg, IDC_COMPUTERNAME, ComputerName, MAX_COMPUTERNAME_LENGTH + 1))
996c2c66affSColin Finck                     {
997c2c66affSColin Finck                         if (0 == LoadStringW(hDllInstance, IDS_WZD_COMPUTERNAME, EmptyComputerName,
99862678985SHermès Bélusca-Maïto                                              ARRAYSIZE(EmptyComputerName)))
999c2c66affSColin Finck                         {
1000c2c66affSColin Finck                             wcscpy(EmptyComputerName, L"Setup cannot continue until you enter the name of your computer.");
1001c2c66affSColin Finck                         }
1002c2c66affSColin Finck                         MessageBoxW(hwndDlg, EmptyComputerName, Title, MB_ICONERROR | MB_OK);
1003c2c66affSColin Finck                         SetFocus(GetDlgItem(hwndDlg, IDC_COMPUTERNAME));
10040182dcd7STimo Kreuzer                         SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1);
1005c2c66affSColin Finck                         return TRUE;
1006c2c66affSColin Finck                     }
1007c2c66affSColin Finck 
1008c2c66affSColin Finck                     /* No need to check computer name for invalid characters,
1009c2c66affSColin Finck                      * SetComputerName() will do it for us */
1010c2c66affSColin Finck 
1011c2c66affSColin Finck                     if (!WriteComputerSettings(ComputerName, hwndDlg))
1012c2c66affSColin Finck                     {
1013c2c66affSColin Finck                         SetFocus(GetDlgItem(hwndDlg, IDC_COMPUTERNAME));
10140182dcd7STimo Kreuzer                         SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1);
1015c2c66affSColin Finck                         return TRUE;
1016c2c66affSColin Finck                     }
1017c2c66affSColin Finck 
10181769793bSErkin Alp Güney #ifdef PASSWORDS_MANDATORY
1019c2c66affSColin Finck                     /* Check if admin passwords have been entered */
1020c2c66affSColin Finck                     if ((GetDlgItemText(hwndDlg, IDC_ADMINPASSWORD1, Password1, 128) == 0) ||
1021c2c66affSColin Finck                         (GetDlgItemText(hwndDlg, IDC_ADMINPASSWORD2, Password2, 128) == 0))
1022c2c66affSColin Finck                     {
1023c2c66affSColin Finck                         if (0 == LoadStringW(hDllInstance, IDS_WZD_PASSWORDEMPTY, EmptyPassword,
102462678985SHermès Bélusca-Maïto                                              ARRAYSIZE(EmptyPassword)))
1025c2c66affSColin Finck                         {
1026c2c66affSColin Finck                             wcscpy(EmptyPassword, L"You must enter a password !");
1027c2c66affSColin Finck                         }
1028c2c66affSColin Finck                         MessageBoxW(hwndDlg, EmptyPassword, Title, MB_ICONERROR | MB_OK);
10290182dcd7STimo Kreuzer                         SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1);
1030c2c66affSColin Finck                         return TRUE;
1031c2c66affSColin Finck                     }
1032c2c66affSColin Finck #else
1033c2c66affSColin Finck                     GetDlgItemTextW(hwndDlg, IDC_ADMINPASSWORD1, Password1, 128);
1034c2c66affSColin Finck                     GetDlgItemTextW(hwndDlg, IDC_ADMINPASSWORD2, Password2, 128);
1035c2c66affSColin Finck #endif
1036c2c66affSColin Finck                     /* Check if passwords match */
1037c2c66affSColin Finck                     if (wcscmp(Password1, Password2))
1038c2c66affSColin Finck                     {
1039c2c66affSColin Finck                         if (0 == LoadStringW(hDllInstance, IDS_WZD_PASSWORDMATCH, NotMatchPassword,
104062678985SHermès Bélusca-Maïto                                              ARRAYSIZE(NotMatchPassword)))
1041c2c66affSColin Finck                         {
1042c2c66affSColin Finck                             wcscpy(NotMatchPassword, L"The passwords you entered do not match. Please enter the desired password again.");
1043c2c66affSColin Finck                         }
1044c2c66affSColin Finck                         MessageBoxW(hwndDlg, NotMatchPassword, Title, MB_ICONERROR | MB_OK);
10450182dcd7STimo Kreuzer                         SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1);
1046c2c66affSColin Finck                         return TRUE;
1047c2c66affSColin Finck                     }
1048c2c66affSColin Finck 
1049c2c66affSColin Finck                     /* Check password for invalid characters */
1050c2c66affSColin Finck                     Password = (PWCHAR)Password1;
1051c2c66affSColin Finck                     while (*Password)
1052c2c66affSColin Finck                     {
1053c2c66affSColin Finck                         if (!isprint(*Password))
1054c2c66affSColin Finck                         {
1055c2c66affSColin Finck                             if (0 == LoadStringW(hDllInstance, IDS_WZD_PASSWORDCHAR, WrongPassword,
105662678985SHermès Bélusca-Maïto                                                  ARRAYSIZE(WrongPassword)))
1057c2c66affSColin Finck                             {
1058c2c66affSColin Finck                                 wcscpy(WrongPassword, L"The password you entered contains invalid characters. Please enter a cleaned password.");
1059c2c66affSColin Finck                             }
1060c2c66affSColin Finck                             MessageBoxW(hwndDlg, WrongPassword, Title, MB_ICONERROR | MB_OK);
10610182dcd7STimo Kreuzer                             SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1);
1062c2c66affSColin Finck                             return TRUE;
1063c2c66affSColin Finck                         }
1064c2c66affSColin Finck                         Password++;
1065c2c66affSColin Finck                     }
1066c2c66affSColin Finck 
1067c2c66affSColin Finck                     /* Set admin password */
1068c2c66affSColin Finck                     SetAdministratorPassword(Password1);
1069c2c66affSColin Finck                     break;
1070c2c66affSColin Finck 
1071c2c66affSColin Finck                 case PSN_WIZBACK:
1072c2c66affSColin Finck                     pSetupData->UnattendSetup = FALSE;
1073c2c66affSColin Finck                     break;
1074c2c66affSColin Finck 
1075c2c66affSColin Finck                 default:
1076c2c66affSColin Finck                     break;
1077c2c66affSColin Finck             }
1078c2c66affSColin Finck         }
1079c2c66affSColin Finck         break;
1080c2c66affSColin Finck 
1081c2c66affSColin Finck         default:
1082c2c66affSColin Finck             break;
1083c2c66affSColin Finck     }
1084c2c66affSColin Finck 
1085c2c66affSColin Finck     return FALSE;
1086c2c66affSColin Finck }
1087c2c66affSColin Finck 
1088c2c66affSColin Finck 
1089c2c66affSColin Finck static VOID
1090*17cb1e1aSStanislav Motylkov SetUserLocaleName(HWND hwnd)
1091*17cb1e1aSStanislav Motylkov {
1092*17cb1e1aSStanislav Motylkov     /* FIXME: Set actual locale name */
1093*17cb1e1aSStanislav Motylkov     SetWindowTextW(hwnd, L"");
1094*17cb1e1aSStanislav Motylkov }
1095*17cb1e1aSStanislav Motylkov 
1096*17cb1e1aSStanislav Motylkov static VOID
1097c2c66affSColin Finck SetKeyboardLayoutName(HWND hwnd)
1098c2c66affSColin Finck {
1099c2c66affSColin Finck #if 0
1100c2c66affSColin Finck     TCHAR szLayoutPath[256];
1101c2c66affSColin Finck     TCHAR szLocaleName[32];
1102c2c66affSColin Finck     DWORD dwLocaleSize;
1103c2c66affSColin Finck     HKEY hKey;
1104c2c66affSColin Finck 
1105c2c66affSColin Finck     if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
1106c2c66affSColin Finck                      _T("SYSTEM\\CurrentControlSet\\Control\\NLS\\Locale"),
1107c2c66affSColin Finck                      0,
1108c2c66affSColin Finck                      KEY_ALL_ACCESS,
1109c2c66affSColin Finck                      &hKey))
1110c2c66affSColin Finck         return;
1111c2c66affSColin Finck 
1112c2c66affSColin Finck     dwValueSize = 16 * sizeof(TCHAR);
1113c2c66affSColin Finck     if (RegQueryValueEx(hKey,
1114c2c66affSColin Finck                         NULL,
1115c2c66affSColin Finck                         NULL,
1116c2c66affSColin Finck                         NULL,
1117c2c66affSColin Finck                         szLocaleName,
1118c2c66affSColin Finck                         &dwLocaleSize))
1119c2c66affSColin Finck     {
1120c2c66affSColin Finck         RegCloseKey(hKey);
1121c2c66affSColin Finck         return;
1122c2c66affSColin Finck     }
1123c2c66affSColin Finck 
1124c2c66affSColin Finck     _tcscpy(szLayoutPath,
1125c2c66affSColin Finck             _T("SYSTEM\\CurrentControlSet\\Control\\Keyboard Layouts\\"));
1126c2c66affSColin Finck     _tcscat(szLayoutPath,
1127c2c66affSColin Finck             szLocaleName);
1128c2c66affSColin Finck 
1129c2c66affSColin Finck     if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
1130c2c66affSColin Finck                      szLayoutPath,
1131c2c66affSColin Finck                      0,
1132c2c66affSColin Finck                      KEY_ALL_ACCESS,
1133c2c66affSColin Finck                      &hKey))
1134c2c66affSColin Finck         return;
1135c2c66affSColin Finck 
1136c2c66affSColin Finck     dwValueSize = 32 * sizeof(TCHAR);
1137c2c66affSColin Finck     if (RegQueryValueEx(hKey,
1138c2c66affSColin Finck                         _T("Layout Text"),
1139c2c66affSColin Finck                         NULL,
1140c2c66affSColin Finck                         NULL,
1141c2c66affSColin Finck                         szLocaleName,
1142c2c66affSColin Finck                         &dwLocaleSize))
1143c2c66affSColin Finck     {
1144c2c66affSColin Finck         RegCloseKey(hKey);
1145c2c66affSColin Finck         return;
1146c2c66affSColin Finck     }
1147c2c66affSColin Finck 
1148c2c66affSColin Finck     RegCloseKey(hKey);
1149*17cb1e1aSStanislav Motylkov #else
1150*17cb1e1aSStanislav Motylkov     /* FIXME: Set actual layout name */
1151*17cb1e1aSStanislav Motylkov     SetWindowTextW(hwnd, L"");
1152c2c66affSColin Finck #endif
1153c2c66affSColin Finck }
1154c2c66affSColin Finck 
1155c2c66affSColin Finck 
1156c2c66affSColin Finck static BOOL
1157c2c66affSColin Finck RunControlPanelApplet(HWND hwnd, PCWSTR pwszCPLParameters)
1158c2c66affSColin Finck {
1159c2c66affSColin Finck     MSG msg;
1160c2c66affSColin Finck     STARTUPINFOW StartupInfo;
1161c2c66affSColin Finck     PROCESS_INFORMATION ProcessInformation;
1162c2c66affSColin Finck     WCHAR CmdLine[MAX_PATH] = L"rundll32.exe shell32.dll,Control_RunDLL ";
1163c2c66affSColin Finck 
1164e9893906SHermès Bélusca-Maïto     if (!pwszCPLParameters)
1165e9893906SHermès Bélusca-Maïto     {
1166e9893906SHermès Bélusca-Maïto         MessageBoxW(hwnd, L"Error: Failed to launch the Control Panel Applet.", NULL, MB_ICONERROR);
1167e9893906SHermès Bélusca-Maïto         return FALSE;
1168e9893906SHermès Bélusca-Maïto     }
1169e9893906SHermès Bélusca-Maïto 
1170c2c66affSColin Finck     ZeroMemory(&StartupInfo, sizeof(StartupInfo));
1171c2c66affSColin Finck     StartupInfo.cb = sizeof(StartupInfo);
1172e9893906SHermès Bélusca-Maïto     ZeroMemory(&ProcessInformation, sizeof(ProcessInformation));
1173c2c66affSColin Finck 
1174c2c66affSColin Finck     ASSERT(_countof(CmdLine) > wcslen(CmdLine) + wcslen(pwszCPLParameters));
1175c2c66affSColin Finck     wcscat(CmdLine, pwszCPLParameters);
1176c2c66affSColin Finck 
1177c2c66affSColin Finck     if (!CreateProcessW(NULL,
1178c2c66affSColin Finck                         CmdLine,
1179c2c66affSColin Finck                         NULL,
1180c2c66affSColin Finck                         NULL,
1181c2c66affSColin Finck                         FALSE,
1182c2c66affSColin Finck                         0,
1183c2c66affSColin Finck                         NULL,
1184c2c66affSColin Finck                         NULL,
1185c2c66affSColin Finck                         &StartupInfo,
1186c2c66affSColin Finck                         &ProcessInformation))
1187c2c66affSColin Finck     {
1188c2c66affSColin Finck         MessageBoxW(hwnd, L"Error: Failed to launch the Control Panel Applet.", NULL, MB_ICONERROR);
1189c2c66affSColin Finck         return FALSE;
1190c2c66affSColin Finck     }
1191c2c66affSColin Finck 
1192c2c66affSColin Finck     while ((MsgWaitForMultipleObjects(1, &ProcessInformation.hProcess, FALSE, INFINITE, QS_ALLINPUT|QS_ALLPOSTMESSAGE )) != WAIT_OBJECT_0)
1193c2c66affSColin Finck     {
1194c2c66affSColin Finck        while (PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE))
1195c2c66affSColin Finck        {
1196c2c66affSColin Finck            TranslateMessage(&msg);
1197c2c66affSColin Finck            DispatchMessageW(&msg);
1198c2c66affSColin Finck        }
1199c2c66affSColin Finck     }
1200c2c66affSColin Finck     CloseHandle(ProcessInformation.hThread);
1201c2c66affSColin Finck     CloseHandle(ProcessInformation.hProcess);
1202c2c66affSColin Finck     return TRUE;
1203c2c66affSColin Finck }
1204c2c66affSColin Finck 
1205c2c66affSColin Finck static VOID
1206c2c66affSColin Finck WriteUserLocale(VOID)
1207c2c66affSColin Finck {
1208c2c66affSColin Finck     HKEY hKey;
1209c2c66affSColin Finck     LCID lcid;
1210c2c66affSColin Finck     WCHAR Locale[12];
1211c2c66affSColin Finck 
1212c2c66affSColin Finck     lcid = GetSystemDefaultLCID();
1213c2c66affSColin Finck 
121462678985SHermès Bélusca-Maïto     if (GetLocaleInfoW(MAKELCID(lcid, SORT_DEFAULT), LOCALE_ILANGUAGE, Locale, ARRAYSIZE(Locale)) != 0)
1215c2c66affSColin Finck     {
1216c2c66affSColin Finck         if (RegCreateKeyExW(HKEY_CURRENT_USER, L"Control Panel\\International",
1217c2c66affSColin Finck                             0, NULL, REG_OPTION_NON_VOLATILE,
1218c2c66affSColin Finck                             KEY_WRITE, NULL, &hKey, NULL) == ERROR_SUCCESS)
1219c2c66affSColin Finck         {
1220c2c66affSColin Finck             RegSetValueExW(hKey, L"Locale", 0, REG_SZ, (LPBYTE)Locale, (wcslen(Locale) + 1) * sizeof(WCHAR));
1221c2c66affSColin Finck             RegCloseKey(hKey);
1222c2c66affSColin Finck         }
1223c2c66affSColin Finck     }
1224c2c66affSColin Finck }
1225c2c66affSColin Finck 
1226c2c66affSColin Finck static INT_PTR CALLBACK
1227c2c66affSColin Finck LocalePageDlgProc(HWND hwndDlg,
1228c2c66affSColin Finck                   UINT uMsg,
1229c2c66affSColin Finck                   WPARAM wParam,
1230c2c66affSColin Finck                   LPARAM lParam)
1231c2c66affSColin Finck {
1232c2c66affSColin Finck     PSETUPDATA SetupData;
1233c2c66affSColin Finck 
1234c2c66affSColin Finck     /* Retrieve pointer to the global setup data */
1235d281d14fSTimo Kreuzer     SetupData = (PSETUPDATA)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
1236c2c66affSColin Finck 
1237c2c66affSColin Finck     switch (uMsg)
1238c2c66affSColin Finck     {
1239c2c66affSColin Finck         case WM_INITDIALOG:
1240c2c66affSColin Finck         {
1241c2c66affSColin Finck             /* Save pointer to the global setup data */
1242c2c66affSColin Finck             SetupData = (PSETUPDATA)((LPPROPSHEETPAGE)lParam)->lParam;
1243d281d14fSTimo Kreuzer             SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (DWORD_PTR)SetupData);
1244c2c66affSColin Finck             WriteUserLocale();
1245c2c66affSColin Finck 
1246*17cb1e1aSStanislav Motylkov             SetUserLocaleName(GetDlgItem(hwndDlg, IDC_LOCALETEXT));
1247c2c66affSColin Finck             SetKeyboardLayoutName(GetDlgItem(hwndDlg, IDC_LAYOUTTEXT));
1248c2c66affSColin Finck         }
1249c2c66affSColin Finck         break;
1250c2c66affSColin Finck 
1251c2c66affSColin Finck         case WM_COMMAND:
1252c2c66affSColin Finck             if (HIWORD(wParam) == BN_CLICKED)
1253c2c66affSColin Finck             {
1254c2c66affSColin Finck                 switch (LOWORD(wParam))
1255c2c66affSColin Finck                 {
1256c2c66affSColin Finck                     case IDC_CUSTOMLOCALE:
1257c2c66affSColin Finck                         RunControlPanelApplet(hwndDlg, L"intl.cpl,,5");
1258c2c66affSColin Finck                         /* FIXME: Update input locale name */
1259c2c66affSColin Finck                         break;
1260c2c66affSColin Finck 
1261c2c66affSColin Finck                     case IDC_CUSTOMLAYOUT:
1262c2c66affSColin Finck                         RunControlPanelApplet(hwndDlg, L"input.dll,@1");
1263c2c66affSColin Finck                         break;
1264c2c66affSColin Finck                 }
1265c2c66affSColin Finck             }
1266c2c66affSColin Finck             break;
1267c2c66affSColin Finck 
1268c2c66affSColin Finck         case WM_NOTIFY:
1269c2c66affSColin Finck         {
1270c2c66affSColin Finck             LPNMHDR lpnm = (LPNMHDR)lParam;
1271c2c66affSColin Finck 
1272c2c66affSColin Finck             switch (lpnm->code)
1273c2c66affSColin Finck             {
1274c2c66affSColin Finck                 case PSN_SETACTIVE:
1275c2c66affSColin Finck                     /* Enable the Back and Next buttons */
1276c2c66affSColin Finck                     PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK | PSWIZB_NEXT);
1277c2c66affSColin Finck                     if (SetupData->UnattendSetup)
1278c2c66affSColin Finck                     {
1279c8d37c1aSHermès Bélusca-Maïto                         // if (!*SetupData->SourcePath)
1280c2c66affSColin Finck                         {
1281c8d37c1aSHermès Bélusca-Maïto                             RunControlPanelApplet(hwndDlg, L"intl.cpl,,/f:\"$winnt$.inf\""); // Should be in System32
1282c2c66affSColin Finck                         }
1283c2c66affSColin Finck 
12840182dcd7STimo Kreuzer                         SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_OWNERPAGE);
1285c2c66affSColin Finck                         return TRUE;
1286c2c66affSColin Finck                     }
1287c2c66affSColin Finck                     break;
1288c2c66affSColin Finck 
1289c2c66affSColin Finck                 case PSN_WIZNEXT:
1290c2c66affSColin Finck                     break;
1291c2c66affSColin Finck 
1292c2c66affSColin Finck                 case PSN_WIZBACK:
1293c2c66affSColin Finck                     SetupData->UnattendSetup = FALSE;
1294c2c66affSColin Finck                     break;
1295c2c66affSColin Finck 
1296c2c66affSColin Finck                 default:
1297c2c66affSColin Finck                     break;
1298c2c66affSColin Finck             }
1299c2c66affSColin Finck         }
1300c2c66affSColin Finck         break;
1301c2c66affSColin Finck 
1302c2c66affSColin Finck         default:
1303c2c66affSColin Finck             break;
1304c2c66affSColin Finck     }
1305c2c66affSColin Finck 
1306c2c66affSColin Finck     return FALSE;
1307c2c66affSColin Finck }
1308c2c66affSColin Finck 
1309c2c66affSColin Finck 
1310c2c66affSColin Finck static PTIMEZONE_ENTRY
1311c2c66affSColin Finck GetLargerTimeZoneEntry(PSETUPDATA SetupData, DWORD Index)
1312c2c66affSColin Finck {
1313c2c66affSColin Finck     PTIMEZONE_ENTRY Entry;
1314c2c66affSColin Finck 
1315c2c66affSColin Finck     Entry = SetupData->TimeZoneListHead;
1316c2c66affSColin Finck     while (Entry != NULL)
1317c2c66affSColin Finck     {
1318c2c66affSColin Finck         if (Entry->Index >= Index)
1319c2c66affSColin Finck             return Entry;
1320c2c66affSColin Finck 
1321c2c66affSColin Finck         Entry = Entry->Next;
1322c2c66affSColin Finck     }
1323c2c66affSColin Finck 
1324c2c66affSColin Finck     return NULL;
1325c2c66affSColin Finck }
1326c2c66affSColin Finck 
13277c3e96a2SHermès Bélusca-Maïto static LONG
13287c3e96a2SHermès Bélusca-Maïto RetrieveTimeZone(
13297c3e96a2SHermès Bélusca-Maïto     IN HKEY hZoneKey,
13307c3e96a2SHermès Bélusca-Maïto     IN PVOID Context)
1331c2c66affSColin Finck {
1332c2c66affSColin Finck     LONG lError;
13337c3e96a2SHermès Bélusca-Maïto     PSETUPDATA SetupData = (PSETUPDATA)Context;
1334c2c66affSColin Finck     PTIMEZONE_ENTRY Entry;
1335c2c66affSColin Finck     PTIMEZONE_ENTRY Current;
13367c3e96a2SHermès Bélusca-Maïto     ULONG DescriptionSize;
13377c3e96a2SHermès Bélusca-Maïto     ULONG StandardNameSize;
13387c3e96a2SHermès Bélusca-Maïto     ULONG DaylightNameSize;
1339c2c66affSColin Finck 
1340c2c66affSColin Finck     Entry = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(TIMEZONE_ENTRY));
1341c2c66affSColin Finck     if (Entry == NULL)
1342c2c66affSColin Finck     {
13437c3e96a2SHermès Bélusca-Maïto         return ERROR_NOT_ENOUGH_MEMORY;
1344c2c66affSColin Finck     }
1345c2c66affSColin Finck 
13467c3e96a2SHermès Bélusca-Maïto     DescriptionSize  = sizeof(Entry->Description);
13477c3e96a2SHermès Bélusca-Maïto     StandardNameSize = sizeof(Entry->StandardName);
13487c3e96a2SHermès Bélusca-Maïto     DaylightNameSize = sizeof(Entry->DaylightName);
13497c3e96a2SHermès Bélusca-Maïto 
13507c3e96a2SHermès Bélusca-Maïto     lError = QueryTimeZoneData(hZoneKey,
13517c3e96a2SHermès Bélusca-Maïto                                &Entry->Index,
13527c3e96a2SHermès Bélusca-Maïto                                &Entry->TimezoneInfo,
13537c3e96a2SHermès Bélusca-Maïto                                Entry->Description,
13547c3e96a2SHermès Bélusca-Maïto                                &DescriptionSize,
13557c3e96a2SHermès Bélusca-Maïto                                Entry->StandardName,
13567c3e96a2SHermès Bélusca-Maïto                                &StandardNameSize,
13577c3e96a2SHermès Bélusca-Maïto                                Entry->DaylightName,
13587c3e96a2SHermès Bélusca-Maïto                                &DaylightNameSize);
13597c3e96a2SHermès Bélusca-Maïto     if (lError != ERROR_SUCCESS)
1360c2c66affSColin Finck     {
13617c3e96a2SHermès Bélusca-Maïto         HeapFree(GetProcessHeap(), 0, Entry);
13627c3e96a2SHermès Bélusca-Maïto         return lError;
1363c2c66affSColin Finck     }
1364c2c66affSColin Finck 
1365c2c66affSColin Finck     if (SetupData->TimeZoneListHead == NULL &&
1366c2c66affSColin Finck         SetupData->TimeZoneListTail == NULL)
1367c2c66affSColin Finck     {
1368c2c66affSColin Finck         Entry->Prev = NULL;
1369c2c66affSColin Finck         Entry->Next = NULL;
1370c2c66affSColin Finck         SetupData->TimeZoneListHead = Entry;
1371c2c66affSColin Finck         SetupData->TimeZoneListTail = Entry;
1372c2c66affSColin Finck     }
1373c2c66affSColin Finck     else
1374c2c66affSColin Finck     {
1375c2c66affSColin Finck         Current = GetLargerTimeZoneEntry(SetupData, Entry->Index);
1376c2c66affSColin Finck         if (Current != NULL)
1377c2c66affSColin Finck         {
1378c2c66affSColin Finck             if (Current == SetupData->TimeZoneListHead)
1379c2c66affSColin Finck             {
1380c2c66affSColin Finck                 /* Prepend to head */
1381c2c66affSColin Finck                 Entry->Prev = NULL;
1382c2c66affSColin Finck                 Entry->Next = SetupData->TimeZoneListHead;
1383c2c66affSColin Finck                 SetupData->TimeZoneListHead->Prev = Entry;
1384c2c66affSColin Finck                 SetupData->TimeZoneListHead = Entry;
1385c2c66affSColin Finck             }
1386c2c66affSColin Finck             else
1387c2c66affSColin Finck             {
1388c2c66affSColin Finck                 /* Insert before current */
1389c2c66affSColin Finck                 Entry->Prev = Current->Prev;
1390c2c66affSColin Finck                 Entry->Next = Current;
1391c2c66affSColin Finck                 Current->Prev->Next = Entry;
1392c2c66affSColin Finck                 Current->Prev = Entry;
1393c2c66affSColin Finck             }
1394c2c66affSColin Finck         }
1395c2c66affSColin Finck         else
1396c2c66affSColin Finck         {
1397c2c66affSColin Finck             /* Append to tail */
1398c2c66affSColin Finck             Entry->Prev = SetupData->TimeZoneListTail;
1399c2c66affSColin Finck             Entry->Next = NULL;
1400c2c66affSColin Finck             SetupData->TimeZoneListTail->Next = Entry;
1401c2c66affSColin Finck             SetupData->TimeZoneListTail = Entry;
1402c2c66affSColin Finck         }
1403c2c66affSColin Finck     }
1404c2c66affSColin Finck 
14057c3e96a2SHermès Bélusca-Maïto     return ERROR_SUCCESS;
1406c2c66affSColin Finck }
1407c2c66affSColin Finck 
14087c3e96a2SHermès Bélusca-Maïto static VOID
14097c3e96a2SHermès Bélusca-Maïto CreateTimeZoneList(PSETUPDATA SetupData)
14107c3e96a2SHermès Bélusca-Maïto {
14117c3e96a2SHermès Bélusca-Maïto     EnumerateTimeZoneList(RetrieveTimeZone, SetupData);
1412c2c66affSColin Finck }
1413c2c66affSColin Finck 
1414c2c66affSColin Finck static VOID
1415c2c66affSColin Finck DestroyTimeZoneList(PSETUPDATA SetupData)
1416c2c66affSColin Finck {
1417c2c66affSColin Finck     PTIMEZONE_ENTRY Entry;
1418c2c66affSColin Finck 
1419c2c66affSColin Finck     while (SetupData->TimeZoneListHead != NULL)
1420c2c66affSColin Finck     {
1421c2c66affSColin Finck         Entry = SetupData->TimeZoneListHead;
1422c2c66affSColin Finck 
1423c2c66affSColin Finck         SetupData->TimeZoneListHead = Entry->Next;
1424c2c66affSColin Finck         if (SetupData->TimeZoneListHead != NULL)
1425c2c66affSColin Finck         {
1426c2c66affSColin Finck             SetupData->TimeZoneListHead->Prev = NULL;
1427c2c66affSColin Finck         }
1428c2c66affSColin Finck 
1429c2c66affSColin Finck         HeapFree(GetProcessHeap(), 0, Entry);
1430c2c66affSColin Finck     }
1431c2c66affSColin Finck 
1432c2c66affSColin Finck     SetupData->TimeZoneListTail = NULL;
1433c2c66affSColin Finck }
1434c2c66affSColin Finck 
1435c2c66affSColin Finck 
1436c2c66affSColin Finck static VOID
1437c2c66affSColin Finck ShowTimeZoneList(HWND hwnd, PSETUPDATA SetupData, DWORD dwEntryIndex)
1438c2c66affSColin Finck {
1439c2c66affSColin Finck     PTIMEZONE_ENTRY Entry;
1440c2c66affSColin Finck     DWORD dwIndex = 0;
1441c2c66affSColin Finck     DWORD dwCount;
1442c2c66affSColin Finck 
1443c2c66affSColin Finck     GetTimeZoneListIndex(&dwEntryIndex);
1444c2c66affSColin Finck 
1445c2c66affSColin Finck     Entry = SetupData->TimeZoneListHead;
1446c2c66affSColin Finck     while (Entry != NULL)
1447c2c66affSColin Finck     {
1448c2c66affSColin Finck         dwCount = SendMessage(hwnd,
1449c2c66affSColin Finck                               CB_ADDSTRING,
1450c2c66affSColin Finck                               0,
1451c2c66affSColin Finck                               (LPARAM)Entry->Description);
1452c2c66affSColin Finck 
1453c2c66affSColin Finck         if (dwEntryIndex != 0 && dwEntryIndex == Entry->Index)
1454c2c66affSColin Finck             dwIndex = dwCount;
1455c2c66affSColin Finck 
1456c2c66affSColin Finck         Entry = Entry->Next;
1457c2c66affSColin Finck     }
1458c2c66affSColin Finck 
1459c2c66affSColin Finck     SendMessage(hwnd,
1460c2c66affSColin Finck                 CB_SETCURSEL,
1461c2c66affSColin Finck                 (WPARAM)dwIndex,
1462c2c66affSColin Finck                 0);
1463c2c66affSColin Finck }
1464c2c66affSColin Finck 
1465c2c66affSColin Finck 
1466c2c66affSColin Finck static VOID
1467c2c66affSColin Finck SetLocalTimeZone(HWND hwnd, PSETUPDATA SetupData)
1468c2c66affSColin Finck {
1469c2c66affSColin Finck     TIME_ZONE_INFORMATION TimeZoneInformation;
1470c2c66affSColin Finck     PTIMEZONE_ENTRY Entry;
1471c2c66affSColin Finck     DWORD dwIndex;
1472c2c66affSColin Finck     DWORD i;
1473c2c66affSColin Finck 
1474c2c66affSColin Finck     dwIndex = SendMessage(hwnd,
1475c2c66affSColin Finck                           CB_GETCURSEL,
1476c2c66affSColin Finck                           0,
1477c2c66affSColin Finck                           0);
1478c2c66affSColin Finck 
1479c2c66affSColin Finck     i = 0;
1480c2c66affSColin Finck     Entry = SetupData->TimeZoneListHead;
1481c2c66affSColin Finck     while (i < dwIndex)
1482c2c66affSColin Finck     {
1483c2c66affSColin Finck         if (Entry == NULL)
1484c2c66affSColin Finck             return;
1485c2c66affSColin Finck 
1486c2c66affSColin Finck         i++;
1487c2c66affSColin Finck         Entry = Entry->Next;
1488c2c66affSColin Finck     }
1489c2c66affSColin Finck 
1490c2c66affSColin Finck     wcscpy(TimeZoneInformation.StandardName,
1491c2c66affSColin Finck            Entry->StandardName);
1492c2c66affSColin Finck     wcscpy(TimeZoneInformation.DaylightName,
1493c2c66affSColin Finck            Entry->DaylightName);
1494c2c66affSColin Finck 
1495c2c66affSColin Finck     TimeZoneInformation.Bias = Entry->TimezoneInfo.Bias;
1496c2c66affSColin Finck     TimeZoneInformation.StandardBias = Entry->TimezoneInfo.StandardBias;
1497c2c66affSColin Finck     TimeZoneInformation.DaylightBias = Entry->TimezoneInfo.DaylightBias;
1498c2c66affSColin Finck 
1499c2c66affSColin Finck     memcpy(&TimeZoneInformation.StandardDate,
1500c2c66affSColin Finck            &Entry->TimezoneInfo.StandardDate,
1501c2c66affSColin Finck            sizeof(SYSTEMTIME));
1502c2c66affSColin Finck     memcpy(&TimeZoneInformation.DaylightDate,
1503c2c66affSColin Finck            &Entry->TimezoneInfo.DaylightDate,
1504c2c66affSColin Finck            sizeof(SYSTEMTIME));
1505c2c66affSColin Finck 
1506c2c66affSColin Finck     /* Set time zone information */
1507c2c66affSColin Finck     SetTimeZoneInformation(&TimeZoneInformation);
1508c2c66affSColin Finck }
1509c2c66affSColin Finck 
1510c2c66affSColin Finck 
1511c2c66affSColin Finck static BOOL
1512c2c66affSColin Finck GetLocalSystemTime(HWND hwnd, PSETUPDATA SetupData)
1513c2c66affSColin Finck {
1514c2c66affSColin Finck     SYSTEMTIME Date;
1515c2c66affSColin Finck     SYSTEMTIME Time;
1516c2c66affSColin Finck 
1517c2c66affSColin Finck     if (DateTime_GetSystemtime(GetDlgItem(hwnd, IDC_DATEPICKER), &Date) != GDT_VALID)
1518c2c66affSColin Finck     {
1519c2c66affSColin Finck         return FALSE;
1520c2c66affSColin Finck     }
1521c2c66affSColin Finck 
1522c2c66affSColin Finck     if (DateTime_GetSystemtime(GetDlgItem(hwnd, IDC_TIMEPICKER), &Time) != GDT_VALID)
1523c2c66affSColin Finck     {
1524c2c66affSColin Finck         return FALSE;
1525c2c66affSColin Finck     }
1526c2c66affSColin Finck 
1527c2c66affSColin Finck     SetupData->SystemTime.wYear = Date.wYear;
1528c2c66affSColin Finck     SetupData->SystemTime.wMonth = Date.wMonth;
1529c2c66affSColin Finck     SetupData->SystemTime.wDayOfWeek = Date.wDayOfWeek;
1530c2c66affSColin Finck     SetupData->SystemTime.wDay = Date.wDay;
1531c2c66affSColin Finck     SetupData->SystemTime.wHour = Time.wHour;
1532c2c66affSColin Finck     SetupData->SystemTime.wMinute = Time.wMinute;
1533c2c66affSColin Finck     SetupData->SystemTime.wSecond = Time.wSecond;
1534c2c66affSColin Finck     SetupData->SystemTime.wMilliseconds = Time.wMilliseconds;
1535c2c66affSColin Finck 
1536c2c66affSColin Finck     return TRUE;
1537c2c66affSColin Finck }
1538c2c66affSColin Finck 
1539c2c66affSColin Finck 
1540c2c66affSColin Finck static BOOL
1541c2c66affSColin Finck SetSystemLocalTime(HWND hwnd, PSETUPDATA SetupData)
1542c2c66affSColin Finck {
1543c2c66affSColin Finck     BOOL Ret = FALSE;
1544c2c66affSColin Finck 
1545c2c66affSColin Finck     /*
1546c2c66affSColin Finck      * Call SetLocalTime twice to ensure correct results
1547c2c66affSColin Finck      */
1548c2c66affSColin Finck     Ret = SetLocalTime(&SetupData->SystemTime) &&
1549c2c66affSColin Finck           SetLocalTime(&SetupData->SystemTime);
1550c2c66affSColin Finck 
1551c2c66affSColin Finck     return Ret;
1552c2c66affSColin Finck }
1553c2c66affSColin Finck 
1554c2c66affSColin Finck 
1555c2c66affSColin Finck static VOID
15564cd92f0dSSerge Gautherie UpdateLocalSystemTime(HWND hwnd, SYSTEMTIME LocalTime)
1557c2c66affSColin Finck {
1558c2c66affSColin Finck     DateTime_SetSystemtime(GetDlgItem(hwnd, IDC_DATEPICKER), GDT_VALID, &LocalTime);
1559c2c66affSColin Finck     DateTime_SetSystemtime(GetDlgItem(hwnd, IDC_TIMEPICKER), GDT_VALID, &LocalTime);
1560c2c66affSColin Finck }
1561c2c66affSColin Finck 
1562c2c66affSColin Finck 
1563c2c66affSColin Finck static BOOL
1564c2c66affSColin Finck WriteDateTimeSettings(HWND hwndDlg, PSETUPDATA SetupData)
1565c2c66affSColin Finck {
1566c2c66affSColin Finck     WCHAR Title[64];
1567c2c66affSColin Finck     WCHAR ErrorLocalTime[256];
1568c2c66affSColin Finck 
1569c2c66affSColin Finck     GetLocalSystemTime(hwndDlg, SetupData);
1570c2c66affSColin Finck     SetLocalTimeZone(GetDlgItem(hwndDlg, IDC_TIMEZONELIST),
1571c2c66affSColin Finck                      SetupData);
1572c2c66affSColin Finck 
15737c3e96a2SHermès Bélusca-Maïto     SetAutoDaylight(SendDlgItemMessage(hwndDlg, IDC_AUTODAYLIGHT,
15747c3e96a2SHermès Bélusca-Maïto                                        BM_GETCHECK, 0, 0) != BST_UNCHECKED);
1575c2c66affSColin Finck     if (!SetSystemLocalTime(hwndDlg, SetupData))
1576c2c66affSColin Finck     {
157762678985SHermès Bélusca-Maïto         if (0 == LoadStringW(hDllInstance, IDS_REACTOS_SETUP, Title, ARRAYSIZE(Title)))
1578c2c66affSColin Finck         {
1579c2c66affSColin Finck             wcscpy(Title, L"ReactOS Setup");
1580c2c66affSColin Finck         }
1581c2c66affSColin Finck         if (0 == LoadStringW(hDllInstance, IDS_WZD_LOCALTIME, ErrorLocalTime,
158262678985SHermès Bélusca-Maïto                              ARRAYSIZE(ErrorLocalTime)))
1583c2c66affSColin Finck         {
1584c2c66affSColin Finck             wcscpy(ErrorLocalTime, L"Setup was unable to set the local time.");
1585c2c66affSColin Finck         }
1586c2c66affSColin Finck         MessageBoxW(hwndDlg, ErrorLocalTime, Title, MB_ICONWARNING | MB_OK);
1587c2c66affSColin Finck         return FALSE;
1588c2c66affSColin Finck     }
1589c2c66affSColin Finck 
1590c2c66affSColin Finck     return TRUE;
1591c2c66affSColin Finck }
1592c2c66affSColin Finck 
1593c2c66affSColin Finck 
1594c2c66affSColin Finck static INT_PTR CALLBACK
1595c2c66affSColin Finck DateTimePageDlgProc(HWND hwndDlg,
1596c2c66affSColin Finck                     UINT uMsg,
1597c2c66affSColin Finck                     WPARAM wParam,
1598c2c66affSColin Finck                     LPARAM lParam)
1599c2c66affSColin Finck {
1600c2c66affSColin Finck     PSETUPDATA SetupData;
1601c2c66affSColin Finck 
1602c2c66affSColin Finck     /* Retrieve pointer to the global setup data */
1603d281d14fSTimo Kreuzer     SetupData = (PSETUPDATA)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
1604c2c66affSColin Finck 
1605c2c66affSColin Finck     switch (uMsg)
1606c2c66affSColin Finck     {
1607c2c66affSColin Finck         case WM_INITDIALOG:
16087c3e96a2SHermès Bélusca-Maïto         {
1609c2c66affSColin Finck             /* Save pointer to the global setup data */
1610c2c66affSColin Finck             SetupData = (PSETUPDATA)((LPPROPSHEETPAGE)lParam)->lParam;
1611d281d14fSTimo Kreuzer             SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (DWORD_PTR)SetupData);
1612c2c66affSColin Finck 
1613c2c66affSColin Finck             CreateTimeZoneList(SetupData);
1614c2c66affSColin Finck 
1615c2c66affSColin Finck             if (SetupData->UnattendSetup)
1616c2c66affSColin Finck             {
1617c2c66affSColin Finck                 ShowTimeZoneList(GetDlgItem(hwndDlg, IDC_TIMEZONELIST),
1618c2c66affSColin Finck                                  SetupData, SetupData->TimeZoneIndex);
1619c2c66affSColin Finck 
1620c2c66affSColin Finck                 if (!SetupData->DisableAutoDaylightTimeSet)
1621c2c66affSColin Finck                 {
1622c2c66affSColin Finck                     SendDlgItemMessage(hwndDlg, IDC_AUTODAYLIGHT, BM_SETCHECK, (WPARAM)BST_CHECKED, 0);
1623c2c66affSColin Finck                 }
1624c2c66affSColin Finck             }
1625c2c66affSColin Finck             else
1626c2c66affSColin Finck             {
1627c2c66affSColin Finck                 ShowTimeZoneList(GetDlgItem(hwndDlg, IDC_TIMEZONELIST),
1628c2c66affSColin Finck                                  SetupData, -1);
1629c2c66affSColin Finck 
1630c2c66affSColin Finck                 SendDlgItemMessage(hwndDlg, IDC_AUTODAYLIGHT, BM_SETCHECK, (WPARAM)BST_CHECKED, 0);
1631c2c66affSColin Finck             }
1632c2c66affSColin Finck             break;
16337c3e96a2SHermès Bélusca-Maïto         }
1634c2c66affSColin Finck 
1635c2c66affSColin Finck         case WM_TIMER:
16364cd92f0dSSerge Gautherie         {
16374cd92f0dSSerge Gautherie             SYSTEMTIME LocalTime;
16384cd92f0dSSerge Gautherie 
16394cd92f0dSSerge Gautherie             GetLocalTime(&LocalTime);
16404cd92f0dSSerge Gautherie             UpdateLocalSystemTime(hwndDlg, LocalTime);
16414cd92f0dSSerge Gautherie 
16424cd92f0dSSerge Gautherie             // Reset timeout.
16434cd92f0dSSerge Gautherie             SetTimer(hwndDlg, 1, 1000 - LocalTime.wMilliseconds, NULL);
1644c2c66affSColin Finck             break;
16454cd92f0dSSerge Gautherie         }
1646c2c66affSColin Finck 
1647c2c66affSColin Finck         case WM_NOTIFY:
1648c2c66affSColin Finck             switch (((LPNMHDR)lParam)->code)
1649c2c66affSColin Finck             {
1650c2c66affSColin Finck                 case PSN_SETACTIVE:
16514cd92f0dSSerge Gautherie                 {
16524cd92f0dSSerge Gautherie                     SYSTEMTIME LocalTime;
16534cd92f0dSSerge Gautherie 
16544cd92f0dSSerge Gautherie                     GetLocalTime(&LocalTime);
16554cd92f0dSSerge Gautherie                     UpdateLocalSystemTime(hwndDlg, LocalTime);
16564cd92f0dSSerge Gautherie 
1657c2c66affSColin Finck                     /* Enable the Back and Next buttons */
1658c2c66affSColin Finck                     PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK | PSWIZB_NEXT);
16594cd92f0dSSerge Gautherie 
1660c2c66affSColin Finck                     if (SetupData->UnattendSetup && WriteDateTimeSettings(hwndDlg, SetupData))
1661c2c66affSColin Finck                     {
16620182dcd7STimo Kreuzer                         SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, SetupData->uFirstNetworkWizardPage);
1663c2c66affSColin Finck                         return TRUE;
1664c2c66affSColin Finck                     }
16654cd92f0dSSerge Gautherie 
16664cd92f0dSSerge Gautherie                     SetTimer(hwndDlg, 1, 1000 - LocalTime.wMilliseconds, NULL);
1667c2c66affSColin Finck                     break;
16684cd92f0dSSerge Gautherie                 }
1669c2c66affSColin Finck 
1670c2c66affSColin Finck                 case PSN_KILLACTIVE:
1671c2c66affSColin Finck                 case DTN_DATETIMECHANGE:
16724cd92f0dSSerge Gautherie                     // NB: Not re-set until changing page (PSN_SETACTIVE).
1673c2c66affSColin Finck                     KillTimer(hwndDlg, 1);
1674c2c66affSColin Finck                     break;
1675c2c66affSColin Finck 
1676c2c66affSColin Finck                 case PSN_WIZNEXT:
1677c2c66affSColin Finck                     WriteDateTimeSettings(hwndDlg, SetupData);
1678c2c66affSColin Finck                     break;
1679c2c66affSColin Finck 
1680c2c66affSColin Finck                 case PSN_WIZBACK:
1681c2c66affSColin Finck                     SetupData->UnattendSetup = FALSE;
1682c2c66affSColin Finck                     break;
1683c2c66affSColin Finck 
1684c2c66affSColin Finck                 default:
1685c2c66affSColin Finck                     break;
1686c2c66affSColin Finck             }
1687c2c66affSColin Finck             break;
1688c2c66affSColin Finck 
1689c2c66affSColin Finck         case WM_DESTROY:
1690c2c66affSColin Finck             DestroyTimeZoneList(SetupData);
1691c2c66affSColin Finck             break;
1692c2c66affSColin Finck 
1693c2c66affSColin Finck         default:
1694c2c66affSColin Finck             break;
1695c2c66affSColin Finck     }
1696c2c66affSColin Finck 
1697c2c66affSColin Finck     return FALSE;
1698c2c66affSColin Finck }
1699c2c66affSColin Finck 
17005d4d48a8SMark Jansen static struct ThemeInfo
17015d4d48a8SMark Jansen {
17025d4d48a8SMark Jansen     LPCWSTR PreviewBitmap;
17035d4d48a8SMark Jansen     UINT DisplayName;
17045d4d48a8SMark Jansen     LPCWSTR ThemeFile;
17055d4d48a8SMark Jansen 
17065d4d48a8SMark Jansen } Themes[] = {
17075d4d48a8SMark Jansen     { MAKEINTRESOURCE(IDB_CLASSIC), IDS_CLASSIC, NULL },
17085d4d48a8SMark Jansen     { MAKEINTRESOURCE(IDB_LAUTUS), IDS_LAUTUS, L"themes\\lautus\\lautus.msstyles" },
170921b7648fSAdam Słaboń     { MAKEINTRESOURCE(IDB_LUNAR), IDS_LUNAR, L"themes\\lunar\\lunar.msstyles" },
1710ea799b74SFoxlet     { MAKEINTRESOURCE(IDB_MIZU), IDS_MIZU, L"themes\\mizu\\mizu.msstyles"},
17115d4d48a8SMark Jansen };
1712c2c66affSColin Finck 
1713c2c66affSColin Finck static INT_PTR CALLBACK
1714c2c66affSColin Finck ThemePageDlgProc(HWND hwndDlg,
1715c2c66affSColin Finck                     UINT uMsg,
1716c2c66affSColin Finck                     WPARAM wParam,
1717c2c66affSColin Finck                     LPARAM lParam)
1718c2c66affSColin Finck {
1719c2c66affSColin Finck     PSETUPDATA SetupData;
17205d4d48a8SMark Jansen     LPNMLISTVIEW pnmv;
1721c2c66affSColin Finck 
1722c2c66affSColin Finck     /* Retrieve pointer to the global setup data */
1723d281d14fSTimo Kreuzer     SetupData = (PSETUPDATA)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
1724c2c66affSColin Finck 
1725c2c66affSColin Finck     switch (uMsg)
1726c2c66affSColin Finck     {
1727c2c66affSColin Finck         case WM_INITDIALOG:
1728c2c66affSColin Finck         {
17295d4d48a8SMark Jansen             HWND hListView;
17305d4d48a8SMark Jansen             HIMAGELIST himl;
17315d4d48a8SMark Jansen             DWORD n;
17325d4d48a8SMark Jansen             LVITEM lvi = {0};
1733c2c66affSColin Finck 
1734c2c66affSColin Finck             /* Save pointer to the global setup data */
1735c2c66affSColin Finck             SetupData = (PSETUPDATA)((LPPROPSHEETPAGE)lParam)->lParam;
1736d281d14fSTimo Kreuzer             SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (DWORD_PTR)SetupData);
1737c2c66affSColin Finck 
17385d4d48a8SMark Jansen             hListView = GetDlgItem(hwndDlg, IDC_THEMEPICKER);
1739c2c66affSColin Finck 
17405d4d48a8SMark Jansen             /* Common */
17415d4d48a8SMark Jansen             himl = ImageList_Create(180, 163, ILC_COLOR32 | ILC_MASK, ARRAYSIZE(Themes), 1);
17425d4d48a8SMark Jansen             lvi.mask = LVIF_TEXT | LVIF_IMAGE |LVIF_STATE;
1743c2c66affSColin Finck 
17445d4d48a8SMark Jansen             for (n = 0; n < ARRAYSIZE(Themes); ++n)
17455d4d48a8SMark Jansen             {
17465d4d48a8SMark Jansen                 WCHAR DisplayName[100] = {0};
17475d4d48a8SMark Jansen                 /* Load the bitmap */
17485d4d48a8SMark Jansen                 HANDLE image = LoadImageW(hDllInstance, Themes[n].PreviewBitmap, IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION);
17495d4d48a8SMark Jansen                 ImageList_AddMasked(himl, image, RGB(255,0,255));
17505d4d48a8SMark Jansen 
17515d4d48a8SMark Jansen                 /* Load the string */
17525d4d48a8SMark Jansen                 LoadStringW(hDllInstance, Themes[n].DisplayName, DisplayName, ARRAYSIZE(DisplayName));
17535d4d48a8SMark Jansen                 DisplayName[ARRAYSIZE(DisplayName)-1] = UNICODE_NULL;
17545d4d48a8SMark Jansen 
17555d4d48a8SMark Jansen                 /* Add the listview item */
17565d4d48a8SMark Jansen                 lvi.iItem  = n;
17575d4d48a8SMark Jansen                 lvi.iImage = n;
17585d4d48a8SMark Jansen                 lvi.pszText = DisplayName;
17595d4d48a8SMark Jansen                 ListView_InsertItem(hListView, &lvi);
17605d4d48a8SMark Jansen             }
17615d4d48a8SMark Jansen 
17625d4d48a8SMark Jansen             /* Register the imagelist */
17635d4d48a8SMark Jansen             ListView_SetImageList(hListView, himl, LVSIL_NORMAL);
17645d4d48a8SMark Jansen             /* Transparant background */
17655d4d48a8SMark Jansen             ListView_SetBkColor(hListView, CLR_NONE);
17665d4d48a8SMark Jansen             ListView_SetTextBkColor(hListView, CLR_NONE);
17675d4d48a8SMark Jansen             /* Reduce the size between the items */
17685d4d48a8SMark Jansen             ListView_SetIconSpacing(hListView, 190, 173);
1769c2c66affSColin Finck             break;
1770c2c66affSColin Finck         }
17715d4d48a8SMark Jansen         case WM_NOTIFY:
17725d4d48a8SMark Jansen             switch (((LPNMHDR)lParam)->code)
1773c2c66affSColin Finck             {
17745d4d48a8SMark Jansen                 //case LVN_ITEMCHANGING:
17755d4d48a8SMark Jansen                 case LVN_ITEMCHANGED:
17765d4d48a8SMark Jansen                     pnmv = (LPNMLISTVIEW)lParam;
17775d4d48a8SMark Jansen                     if ((pnmv->uChanged & LVIF_STATE) && (pnmv->uNewState & LVIS_SELECTED))
1778c2c66affSColin Finck                     {
17795d4d48a8SMark Jansen                         int iTheme = pnmv->iItem;
1780774f4977SMark Jansen                         DPRINT1("Selected theme: %u\n", Themes[iTheme].DisplayName);
17815d4d48a8SMark Jansen 
17825d4d48a8SMark Jansen                         if (Themes[iTheme].ThemeFile)
1783c2c66affSColin Finck                         {
1784c2c66affSColin Finck                             WCHAR wszParams[1024];
1785c2c66affSColin Finck                             WCHAR wszTheme[MAX_PATH];
1786c2c66affSColin Finck                             WCHAR* format = L"desk.cpl desk,@Appearance /Action:ActivateMSTheme /file:\"%s\"";
1787c2c66affSColin Finck 
17885d4d48a8SMark Jansen                             SHGetFolderPathAndSubDirW(0, CSIDL_RESOURCES, NULL, SHGFP_TYPE_DEFAULT, Themes[iTheme].ThemeFile, wszTheme);
1789c2c66affSColin Finck                             swprintf(wszParams, format, wszTheme);
1790c2c66affSColin Finck                             RunControlPanelApplet(hwndDlg, wszParams);
1791c2c66affSColin Finck                         }
17925d4d48a8SMark Jansen                         else
1793c2c66affSColin Finck                         {
17945d4d48a8SMark Jansen                             RunControlPanelApplet(hwndDlg, L"desk.cpl desk,@Appearance /Action:ActivateMSTheme");
17955d4d48a8SMark Jansen                         }
17965d4d48a8SMark Jansen                     }
17975d4d48a8SMark Jansen                     break;
1798c2c66affSColin Finck                 case PSN_SETACTIVE:
1799c2c66affSColin Finck                     /* Enable the Back and Next buttons */
1800c2c66affSColin Finck                     PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK | PSWIZB_NEXT);
1801c2c66affSColin Finck                     if (SetupData->UnattendSetup)
1802c2c66affSColin Finck                     {
18030182dcd7STimo Kreuzer                         SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, SetupData->uFirstNetworkWizardPage);
1804c2c66affSColin Finck                         return TRUE;
1805c2c66affSColin Finck                     }
1806c2c66affSColin Finck                     break;
1807c2c66affSColin Finck 
1808c2c66affSColin Finck                 case PSN_WIZNEXT:
1809c2c66affSColin Finck                     break;
1810c2c66affSColin Finck 
1811c2c66affSColin Finck                 case PSN_WIZBACK:
1812c2c66affSColin Finck                     SetupData->UnattendSetup = FALSE;
1813c2c66affSColin Finck                     break;
1814c2c66affSColin Finck 
1815c2c66affSColin Finck                 default:
1816c2c66affSColin Finck                     break;
1817c2c66affSColin Finck             }
1818c2c66affSColin Finck             break;
1819c2c66affSColin Finck 
1820c2c66affSColin Finck         default:
1821c2c66affSColin Finck             break;
1822c2c66affSColin Finck     }
1823c2c66affSColin Finck 
1824c2c66affSColin Finck     return FALSE;
1825c2c66affSColin Finck }
1826c2c66affSColin Finck 
1827c2c66affSColin Finck static UINT CALLBACK
1828c2c66affSColin Finck RegistrationNotificationProc(PVOID Context,
1829c2c66affSColin Finck                              UINT Notification,
1830c2c66affSColin Finck                              UINT_PTR Param1,
1831c2c66affSColin Finck                              UINT_PTR Param2)
1832c2c66affSColin Finck {
1833c2c66affSColin Finck     PREGISTRATIONDATA RegistrationData;
1834c2c66affSColin Finck     REGISTRATIONNOTIFY RegistrationNotify;
1835c2c66affSColin Finck     PSP_REGISTER_CONTROL_STATUSW StatusInfo;
1836c2c66affSColin Finck     UINT MessageID;
1837c2c66affSColin Finck     WCHAR ErrorMessage[128];
1838c2c66affSColin Finck 
1839c2c66affSColin Finck     RegistrationData = (PREGISTRATIONDATA) Context;
1840c2c66affSColin Finck 
1841c2c66affSColin Finck     if (SPFILENOTIFY_STARTREGISTRATION == Notification ||
1842c2c66affSColin Finck             SPFILENOTIFY_ENDREGISTRATION == Notification)
1843c2c66affSColin Finck     {
1844c2c66affSColin Finck         StatusInfo = (PSP_REGISTER_CONTROL_STATUSW) Param1;
1845c2c66affSColin Finck         RegistrationNotify.CurrentItem = wcsrchr(StatusInfo->FileName, L'\\');
1846c2c66affSColin Finck         if (NULL == RegistrationNotify.CurrentItem)
1847c2c66affSColin Finck         {
1848c2c66affSColin Finck             RegistrationNotify.CurrentItem = StatusInfo->FileName;
1849c2c66affSColin Finck         }
1850c2c66affSColin Finck         else
1851c2c66affSColin Finck         {
1852c2c66affSColin Finck             RegistrationNotify.CurrentItem++;
1853c2c66affSColin Finck         }
1854c2c66affSColin Finck 
1855c2c66affSColin Finck         if (SPFILENOTIFY_STARTREGISTRATION == Notification)
1856c2c66affSColin Finck         {
1857c2c66affSColin Finck             DPRINT("Received SPFILENOTIFY_STARTREGISTRATION notification for %S\n",
1858c2c66affSColin Finck                    StatusInfo->FileName);
1859c2c66affSColin Finck             RegistrationNotify.ErrorMessage = NULL;
1860c2c66affSColin Finck             RegistrationNotify.Progress = RegistrationData->Registered;
1861c2c66affSColin Finck         }
1862c2c66affSColin Finck         else
1863c2c66affSColin Finck         {
1864c2c66affSColin Finck             DPRINT("Received SPFILENOTIFY_ENDREGISTRATION notification for %S\n",
1865c2c66affSColin Finck                    StatusInfo->FileName);
1866c2c66affSColin Finck             DPRINT("Win32Error %u FailureCode %u\n", StatusInfo->Win32Error,
1867c2c66affSColin Finck                    StatusInfo->FailureCode);
1868c2c66affSColin Finck             if (SPREG_SUCCESS != StatusInfo->FailureCode)
1869c2c66affSColin Finck             {
1870c2c66affSColin Finck                 switch(StatusInfo->FailureCode)
1871c2c66affSColin Finck                 {
1872c2c66affSColin Finck                     case SPREG_LOADLIBRARY:
1873c2c66affSColin Finck                         MessageID = IDS_LOADLIBRARY_FAILED;
1874c2c66affSColin Finck                         break;
1875c2c66affSColin Finck                     case SPREG_GETPROCADDR:
1876c2c66affSColin Finck                         MessageID = IDS_GETPROCADDR_FAILED;
1877c2c66affSColin Finck                         break;
1878c2c66affSColin Finck                     case SPREG_REGSVR:
1879c2c66affSColin Finck                         MessageID = IDS_REGSVR_FAILED;
1880c2c66affSColin Finck                         break;
1881c2c66affSColin Finck                     case SPREG_DLLINSTALL:
1882c2c66affSColin Finck                         MessageID = IDS_DLLINSTALL_FAILED;
1883c2c66affSColin Finck                         break;
1884c2c66affSColin Finck                     case SPREG_TIMEOUT:
1885c2c66affSColin Finck                         MessageID = IDS_TIMEOUT;
1886c2c66affSColin Finck                         break;
1887c2c66affSColin Finck                     default:
1888c2c66affSColin Finck                         MessageID = IDS_REASON_UNKNOWN;
1889c2c66affSColin Finck                         break;
1890c2c66affSColin Finck                 }
1891c2c66affSColin Finck                 if (0 == LoadStringW(hDllInstance, MessageID,
1892c2c66affSColin Finck                                      ErrorMessage,
189362678985SHermès Bélusca-Maïto                                      ARRAYSIZE(ErrorMessage)))
1894c2c66affSColin Finck                 {
1895c2c66affSColin Finck                     ErrorMessage[0] = L'\0';
1896c2c66affSColin Finck                 }
1897c2c66affSColin Finck                 if (SPREG_TIMEOUT != StatusInfo->FailureCode)
1898c2c66affSColin Finck                 {
1899c2c66affSColin Finck                     FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM, NULL,
1900c2c66affSColin Finck                                    StatusInfo->Win32Error, 0,
1901c2c66affSColin Finck                                    ErrorMessage + wcslen(ErrorMessage),
190262678985SHermès Bélusca-Maïto                                    ARRAYSIZE(ErrorMessage) - wcslen(ErrorMessage),
190362678985SHermès Bélusca-Maïto                                    NULL);
1904c2c66affSColin Finck                 }
1905c2c66affSColin Finck                 RegistrationNotify.ErrorMessage = ErrorMessage;
1906c2c66affSColin Finck             }
1907c2c66affSColin Finck             else
1908c2c66affSColin Finck             {
1909c2c66affSColin Finck                 RegistrationNotify.ErrorMessage = NULL;
1910c2c66affSColin Finck             }
1911c2c66affSColin Finck             if (RegistrationData->Registered < RegistrationData->DllCount)
1912c2c66affSColin Finck             {
1913c2c66affSColin Finck                 RegistrationData->Registered++;
1914c2c66affSColin Finck             }
1915c2c66affSColin Finck         }
1916c2c66affSColin Finck 
1917c2c66affSColin Finck         RegistrationNotify.Progress = RegistrationData->Registered;
1918c2c66affSColin Finck         RegistrationNotify.ActivityID = IDS_REGISTERING_COMPONENTS;
1919c2c66affSColin Finck         SendMessage(RegistrationData->hwndDlg, PM_REGISTRATION_NOTIFY,
1920c2c66affSColin Finck                     0, (LPARAM) &RegistrationNotify);
1921c2c66affSColin Finck 
1922c2c66affSColin Finck         return FILEOP_DOIT;
1923c2c66affSColin Finck     }
1924c2c66affSColin Finck     else
1925c2c66affSColin Finck     {
1926c2c66affSColin Finck         DPRINT1("Received unexpected notification %u\n", Notification);
1927c2c66affSColin Finck         return SetupDefaultQueueCallback(RegistrationData->DefaultContext,
1928c2c66affSColin Finck                                          Notification, Param1, Param2);
1929c2c66affSColin Finck     }
1930c2c66affSColin Finck }
1931c2c66affSColin Finck 
1932c2c66affSColin Finck 
1933c2c66affSColin Finck static DWORD CALLBACK
1934c2c66affSColin Finck RegistrationProc(LPVOID Parameter)
1935c2c66affSColin Finck {
1936c2c66affSColin Finck     PREGISTRATIONDATA RegistrationData;
1937c2c66affSColin Finck     REGISTRATIONNOTIFY RegistrationNotify;
1938c2c66affSColin Finck     DWORD LastError = NO_ERROR;
1939c2c66affSColin Finck     WCHAR UnknownError[84];
1940c2c66affSColin Finck 
1941c2c66affSColin Finck     RegistrationData = (PREGISTRATIONDATA) Parameter;
1942c2c66affSColin Finck     RegistrationData->Registered = 0;
1943c2c66affSColin Finck     RegistrationData->DefaultContext = SetupInitDefaultQueueCallback(RegistrationData->hwndDlg);
1944c2c66affSColin Finck 
1945c2c66affSColin Finck     _SEH2_TRY
1946c2c66affSColin Finck     {
1947c2c66affSColin Finck         if (!SetupInstallFromInfSectionW(GetParent(RegistrationData->hwndDlg),
1948c2c66affSColin Finck         hSysSetupInf,
1949c2c66affSColin Finck         L"RegistrationPhase2",
1950c2c66affSColin Finck         SPINST_REGISTRY |
1951c2c66affSColin Finck         SPINST_REGISTERCALLBACKAWARE  |
1952c2c66affSColin Finck         SPINST_REGSVR,
1953c2c66affSColin Finck         0,
1954c2c66affSColin Finck         NULL,
1955c2c66affSColin Finck         0,
1956c2c66affSColin Finck         RegistrationNotificationProc,
1957c2c66affSColin Finck         RegistrationData,
1958c2c66affSColin Finck         NULL,
1959c2c66affSColin Finck         NULL))
1960c2c66affSColin Finck         {
1961c2c66affSColin Finck             LastError = GetLastError();
1962c2c66affSColin Finck         }
1963c2c66affSColin Finck     }
1964c2c66affSColin Finck     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
1965c2c66affSColin Finck     {
1966c2c66affSColin Finck         DPRINT("Catching exception\n");
1967c2c66affSColin Finck         LastError = RtlNtStatusToDosError(_SEH2_GetExceptionCode());
1968c2c66affSColin Finck     }
1969c2c66affSColin Finck     _SEH2_END;
1970c2c66affSColin Finck 
1971c2c66affSColin Finck     if (NO_ERROR == LastError)
1972c2c66affSColin Finck     {
1973c2c66affSColin Finck         RegistrationNotify.ErrorMessage = NULL;
1974c2c66affSColin Finck     }
1975c2c66affSColin Finck     else
1976c2c66affSColin Finck     {
1977c2c66affSColin Finck         DPRINT1("SetupInstallFromInfSection failed with error %u\n",
1978c2c66affSColin Finck                 LastError);
1979c2c66affSColin Finck         if (0 == FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER |
1980c2c66affSColin Finck                                 FORMAT_MESSAGE_FROM_SYSTEM, NULL, LastError, 0,
1981c2c66affSColin Finck                                 (LPWSTR) &RegistrationNotify.ErrorMessage, 0,
1982c2c66affSColin Finck                                 NULL))
1983c2c66affSColin Finck         {
1984c2c66affSColin Finck             if (0 == LoadStringW(hDllInstance, IDS_UNKNOWN_ERROR,
1985c2c66affSColin Finck                                  UnknownError,
198662678985SHermès Bélusca-Maïto                                  ARRAYSIZE(UnknownError) - 20))
1987c2c66affSColin Finck             {
1988c2c66affSColin Finck                 wcscpy(UnknownError, L"Unknown error");
1989c2c66affSColin Finck             }
1990c2c66affSColin Finck             wcscat(UnknownError, L" ");
1991c2c66affSColin Finck             _ultow(LastError, UnknownError + wcslen(UnknownError), 10);
1992c2c66affSColin Finck             RegistrationNotify.ErrorMessage = UnknownError;
1993c2c66affSColin Finck         }
1994c2c66affSColin Finck     }
1995c2c66affSColin Finck 
1996c2c66affSColin Finck     RegistrationNotify.Progress = RegistrationData->DllCount;
1997c2c66affSColin Finck     RegistrationNotify.ActivityID = IDS_REGISTERING_COMPONENTS;
1998c2c66affSColin Finck     RegistrationNotify.CurrentItem = NULL;
1999c2c66affSColin Finck     SendMessage(RegistrationData->hwndDlg, PM_REGISTRATION_NOTIFY,
2000c2c66affSColin Finck                 1, (LPARAM) &RegistrationNotify);
2001c2c66affSColin Finck     if (NULL != RegistrationNotify.ErrorMessage &&
2002c2c66affSColin Finck             UnknownError != RegistrationNotify.ErrorMessage)
2003c2c66affSColin Finck     {
2004c2c66affSColin Finck         LocalFree((PVOID) RegistrationNotify.ErrorMessage);
2005c2c66affSColin Finck     }
2006c2c66affSColin Finck 
2007c2c66affSColin Finck     SetupTermDefaultQueueCallback(RegistrationData->DefaultContext);
2008c2c66affSColin Finck     HeapFree(GetProcessHeap(), 0, RegistrationData);
2009c2c66affSColin Finck 
2010c2c66affSColin Finck     RegisterTypeLibraries(hSysSetupInf, L"TypeLibraries");
2011c2c66affSColin Finck 
2012c2c66affSColin Finck     // FIXME: Move this call to a separate cleanup page!
2013c2c66affSColin Finck     RtlCreateBootStatusDataFile();
2014c2c66affSColin Finck 
2015c2c66affSColin Finck     return 0;
2016c2c66affSColin Finck }
2017c2c66affSColin Finck 
2018c2c66affSColin Finck 
2019c2c66affSColin Finck static BOOL
2020c2c66affSColin Finck StartComponentRegistration(HWND hwndDlg, PULONG MaxProgress)
2021c2c66affSColin Finck {
2022c2c66affSColin Finck     HANDLE RegistrationThread;
2023c2c66affSColin Finck     LONG DllCount;
2024c2c66affSColin Finck     INFCONTEXT Context;
2025c2c66affSColin Finck     WCHAR SectionName[512];
2026c2c66affSColin Finck     PREGISTRATIONDATA RegistrationData;
2027c2c66affSColin Finck 
2028c2c66affSColin Finck     DllCount = -1;
2029c2c66affSColin Finck     if (!SetupFindFirstLineW(hSysSetupInf, L"RegistrationPhase2",
2030c2c66affSColin Finck                              L"RegisterDlls", &Context))
2031c2c66affSColin Finck     {
2032c2c66affSColin Finck         DPRINT1("No RegistrationPhase2 section found\n");
2033c2c66affSColin Finck         return FALSE;
2034c2c66affSColin Finck     }
2035c2c66affSColin Finck     if (!SetupGetStringFieldW(&Context, 1, SectionName,
203662678985SHermès Bélusca-Maïto                               ARRAYSIZE(SectionName),
2037c2c66affSColin Finck                               NULL))
2038c2c66affSColin Finck     {
2039c2c66affSColin Finck         DPRINT1("Unable to retrieve section name\n");
2040c2c66affSColin Finck         return FALSE;
2041c2c66affSColin Finck     }
2042c2c66affSColin Finck     DllCount = SetupGetLineCountW(hSysSetupInf, SectionName);
2043c2c66affSColin Finck     DPRINT("SectionName %S DllCount %ld\n", SectionName, DllCount);
2044c2c66affSColin Finck     if (DllCount < 0)
2045c2c66affSColin Finck     {
2046c2c66affSColin Finck         SetLastError(STATUS_NOT_FOUND);
2047c2c66affSColin Finck         return FALSE;
2048c2c66affSColin Finck     }
2049c2c66affSColin Finck 
2050c2c66affSColin Finck     *MaxProgress = (ULONG) DllCount;
2051c2c66affSColin Finck 
2052c2c66affSColin Finck     /*
2053c2c66affSColin Finck      * Create a background thread to do the actual registrations, so the
2054c2c66affSColin Finck      * main thread can just run its message loop.
2055c2c66affSColin Finck      */
2056c2c66affSColin Finck     RegistrationThread = NULL;
2057c2c66affSColin Finck     RegistrationData = HeapAlloc(GetProcessHeap(), 0,
2058c2c66affSColin Finck                                  sizeof(REGISTRATIONDATA));
2059c2c66affSColin Finck     if (RegistrationData != NULL)
2060c2c66affSColin Finck     {
2061c2c66affSColin Finck         RegistrationData->hwndDlg = hwndDlg;
2062c2c66affSColin Finck         RegistrationData->DllCount = DllCount;
2063c2c66affSColin Finck         RegistrationThread = CreateThread(NULL, 0, RegistrationProc,
2064c2c66affSColin Finck                                           RegistrationData, 0, NULL);
2065c2c66affSColin Finck         if (RegistrationThread != NULL)
2066c2c66affSColin Finck         {
2067c2c66affSColin Finck             CloseHandle(RegistrationThread);
2068c2c66affSColin Finck         }
2069c2c66affSColin Finck         else
2070c2c66affSColin Finck         {
2071c2c66affSColin Finck             DPRINT1("CreateThread failed, error %u\n", GetLastError());
2072c2c66affSColin Finck             HeapFree(GetProcessHeap(), 0, RegistrationData);
2073c2c66affSColin Finck             return FALSE;
2074c2c66affSColin Finck         }
2075c2c66affSColin Finck     }
2076c2c66affSColin Finck     else
2077c2c66affSColin Finck     {
2078c2c66affSColin Finck         DPRINT1("HeapAlloc() failed, error %u\n", GetLastError());
2079c2c66affSColin Finck         return FALSE;
2080c2c66affSColin Finck     }
2081c2c66affSColin Finck 
2082c2c66affSColin Finck     return TRUE;
2083c2c66affSColin Finck }
2084c2c66affSColin Finck 
2085c2c66affSColin Finck 
2086c2c66affSColin Finck static INT_PTR CALLBACK
2087c2c66affSColin Finck ProcessPageDlgProc(HWND hwndDlg,
2088c2c66affSColin Finck                    UINT uMsg,
2089c2c66affSColin Finck                    WPARAM wParam,
2090c2c66affSColin Finck                    LPARAM lParam)
2091c2c66affSColin Finck {
2092c2c66affSColin Finck     PSETUPDATA SetupData;
2093c2c66affSColin Finck     PREGISTRATIONNOTIFY RegistrationNotify;
2094c2c66affSColin Finck     static UINT oldActivityID = -1;
2095c2c66affSColin Finck     WCHAR Title[64];
2096c2c66affSColin Finck 
2097c2c66affSColin Finck     /* Retrieve pointer to the global setup data */
2098d281d14fSTimo Kreuzer     SetupData = (PSETUPDATA)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
2099c2c66affSColin Finck 
2100c2c66affSColin Finck     switch (uMsg)
2101c2c66affSColin Finck     {
2102c2c66affSColin Finck         case WM_INITDIALOG:
2103c2c66affSColin Finck         {
2104c2c66affSColin Finck             /* Save pointer to the global setup data */
2105c2c66affSColin Finck             SetupData = (PSETUPDATA)((LPPROPSHEETPAGE)lParam)->lParam;
2106d281d14fSTimo Kreuzer             SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (DWORD_PTR)SetupData);
2107c2c66affSColin Finck         }
2108c2c66affSColin Finck         break;
2109c2c66affSColin Finck 
2110c2c66affSColin Finck         case WM_NOTIFY:
2111c2c66affSColin Finck         {
2112c2c66affSColin Finck             LPNMHDR lpnm = (LPNMHDR)lParam;
2113c2c66affSColin Finck             ULONG MaxProgress = 0;
2114c2c66affSColin Finck 
2115c2c66affSColin Finck             switch (lpnm->code)
2116c2c66affSColin Finck             {
2117c2c66affSColin Finck                 case PSN_SETACTIVE:
2118c2c66affSColin Finck                     /* Disable the Back and Next buttons */
2119c2c66affSColin Finck                     PropSheet_SetWizButtons(GetParent(hwndDlg), 0);
2120c2c66affSColin Finck 
2121c2c66affSColin Finck                     StartComponentRegistration(hwndDlg, &MaxProgress);
2122c2c66affSColin Finck 
2123c2c66affSColin Finck                     SendDlgItemMessage(hwndDlg, IDC_PROCESSPROGRESS, PBM_SETRANGE,
2124c2c66affSColin Finck                                        0, MAKELPARAM(0, MaxProgress));
2125c2c66affSColin Finck                     SendDlgItemMessage(hwndDlg, IDC_PROCESSPROGRESS, PBM_SETPOS,
2126c2c66affSColin Finck                                        0, 0);
2127c2c66affSColin Finck                     break;
2128c2c66affSColin Finck 
2129c2c66affSColin Finck                 case PSN_WIZNEXT:
2130c2c66affSColin Finck                     break;
2131c2c66affSColin Finck 
2132c2c66affSColin Finck                 case PSN_WIZBACK:
2133c2c66affSColin Finck                     SetupData->UnattendSetup = FALSE;
2134c2c66affSColin Finck                     break;
2135c2c66affSColin Finck 
2136c2c66affSColin Finck                 default:
2137c2c66affSColin Finck                     break;
2138c2c66affSColin Finck             }
2139c2c66affSColin Finck         }
2140c2c66affSColin Finck         break;
2141c2c66affSColin Finck 
2142c2c66affSColin Finck         case PM_REGISTRATION_NOTIFY:
2143c2c66affSColin Finck         {
2144c2c66affSColin Finck             WCHAR Activity[64];
2145c2c66affSColin Finck             RegistrationNotify = (PREGISTRATIONNOTIFY) lParam;
2146c2c66affSColin Finck             // update if necessary only
2147c2c66affSColin Finck             if (oldActivityID != RegistrationNotify->ActivityID)
2148c2c66affSColin Finck             {
2149c2c66affSColin Finck                 if (0 != LoadStringW(hDllInstance, RegistrationNotify->ActivityID,
2150c2c66affSColin Finck                                      Activity,
215162678985SHermès Bélusca-Maïto                                      ARRAYSIZE(Activity)))
2152c2c66affSColin Finck                 {
2153c2c66affSColin Finck                     SendDlgItemMessageW(hwndDlg, IDC_ACTIVITY, WM_SETTEXT,
2154c2c66affSColin Finck                                         0, (LPARAM) Activity);
2155c2c66affSColin Finck                 }
2156c2c66affSColin Finck                 oldActivityID = RegistrationNotify->ActivityID;
2157c2c66affSColin Finck             }
2158c2c66affSColin Finck             SendDlgItemMessageW(hwndDlg, IDC_ITEM, WM_SETTEXT, 0,
2159c2c66affSColin Finck                                 (LPARAM)(NULL == RegistrationNotify->CurrentItem ?
2160c2c66affSColin Finck                                          L"" : RegistrationNotify->CurrentItem));
2161c2c66affSColin Finck             SendDlgItemMessage(hwndDlg, IDC_PROCESSPROGRESS, PBM_SETPOS,
2162c2c66affSColin Finck                                RegistrationNotify->Progress, 0);
2163c2c66affSColin Finck             if (NULL != RegistrationNotify->ErrorMessage)
2164c2c66affSColin Finck             {
2165c2c66affSColin Finck                 if (0 == LoadStringW(hDllInstance, IDS_REACTOS_SETUP,
216662678985SHermès Bélusca-Maïto                                      Title, ARRAYSIZE(Title)))
2167c2c66affSColin Finck                 {
2168c2c66affSColin Finck                     wcscpy(Title, L"ReactOS Setup");
2169c2c66affSColin Finck                 }
2170c2c66affSColin Finck                 MessageBoxW(hwndDlg, RegistrationNotify->ErrorMessage,
2171c2c66affSColin Finck                             Title, MB_ICONERROR | MB_OK);
2172c2c66affSColin Finck 
2173c2c66affSColin Finck             }
2174c2c66affSColin Finck 
2175c2c66affSColin Finck             if (wParam)
2176c2c66affSColin Finck             {
2177c2c66affSColin Finck                 /* Enable the Back and Next buttons */
2178c2c66affSColin Finck                 PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT);
2179c2c66affSColin Finck                 PropSheet_PressButton(GetParent(hwndDlg), PSBTN_NEXT);
2180c2c66affSColin Finck             }
2181c2c66affSColin Finck         }
2182c2c66affSColin Finck         return TRUE;
2183c2c66affSColin Finck 
2184c2c66affSColin Finck         default:
2185c2c66affSColin Finck             break;
2186c2c66affSColin Finck     }
2187c2c66affSColin Finck 
2188c2c66affSColin Finck     return FALSE;
2189c2c66affSColin Finck }
2190c2c66affSColin Finck 
2191c2c66affSColin Finck 
2192c2c66affSColin Finck static VOID
2193c2c66affSColin Finck SetInstallationCompleted(VOID)
2194c2c66affSColin Finck {
2195c2c66affSColin Finck     HKEY hKey = 0;
2196c2c66affSColin Finck     DWORD InProgress = 0;
2197c2c66affSColin Finck     DWORD InstallDate;
2198c2c66affSColin Finck 
2199c2c66affSColin Finck     if (RegOpenKeyExW( HKEY_LOCAL_MACHINE,
2200c2c66affSColin Finck                        L"SYSTEM\\Setup",
2201c2c66affSColin Finck                        0,
2202c2c66affSColin Finck                        KEY_WRITE,
2203c2c66affSColin Finck                        &hKey ) == ERROR_SUCCESS)
2204c2c66affSColin Finck     {
2205c2c66affSColin Finck         RegSetValueExW( hKey, L"SystemSetupInProgress", 0, REG_DWORD, (LPBYTE)&InProgress, sizeof(InProgress) );
2206c2c66affSColin Finck         RegCloseKey( hKey );
2207c2c66affSColin Finck     }
2208c2c66affSColin Finck 
2209c2c66affSColin Finck     if (RegOpenKeyExW( HKEY_LOCAL_MACHINE,
2210c2c66affSColin Finck                        L"Software\\Microsoft\\Windows NT\\CurrentVersion",
2211c2c66affSColin Finck                        0,
2212c2c66affSColin Finck                        KEY_WRITE,
2213c2c66affSColin Finck                        &hKey ) == ERROR_SUCCESS)
2214c2c66affSColin Finck     {
2215c2c66affSColin Finck         InstallDate = (DWORD)time(NULL);
2216c2c66affSColin Finck         RegSetValueExW( hKey, L"InstallDate", 0, REG_DWORD, (LPBYTE)&InstallDate, sizeof(InstallDate) );
2217c2c66affSColin Finck         RegCloseKey( hKey );
2218c2c66affSColin Finck     }
2219c2c66affSColin Finck }
2220c2c66affSColin Finck 
2221c2c66affSColin Finck static INT_PTR CALLBACK
2222c2c66affSColin Finck FinishDlgProc(HWND hwndDlg,
2223c2c66affSColin Finck               UINT uMsg,
2224c2c66affSColin Finck               WPARAM wParam,
2225c2c66affSColin Finck               LPARAM lParam)
2226c2c66affSColin Finck {
2227c2c66affSColin Finck 
2228c2c66affSColin Finck     switch (uMsg)
2229c2c66affSColin Finck     {
2230c2c66affSColin Finck         case WM_INITDIALOG:
2231c2c66affSColin Finck         {
2232c2c66affSColin Finck             /* Get pointer to the global setup data */
2233c2c66affSColin Finck             PSETUPDATA SetupData = (PSETUPDATA)((LPPROPSHEETPAGE)lParam)->lParam;
2234c2c66affSColin Finck 
2235c2c66affSColin Finck             if (!SetupData->UnattendSetup || !SetupData->DisableGeckoInst)
2236c2c66affSColin Finck             {
2237c2c66affSColin Finck                 /* Run the Wine Gecko prompt */
2238c2c66affSColin Finck                 Control_RunDLLW(hwndDlg, 0, L"appwiz.cpl install_gecko", SW_SHOW);
2239c2c66affSColin Finck             }
2240c2c66affSColin Finck 
2241c2c66affSColin Finck             /* Set title font */
2242c2c66affSColin Finck             SendDlgItemMessage(hwndDlg,
2243c2c66affSColin Finck                                IDC_FINISHTITLE,
2244c2c66affSColin Finck                                WM_SETFONT,
2245c2c66affSColin Finck                                (WPARAM)SetupData->hTitleFont,
2246c2c66affSColin Finck                                (LPARAM)TRUE);
2247c2c66affSColin Finck             if (SetupData->UnattendSetup)
2248c2c66affSColin Finck             {
2249c2c66affSColin Finck                 KillTimer(hwndDlg, 1);
2250c2c66affSColin Finck                 SetInstallationCompleted();
2251c2c66affSColin Finck                 PostQuitMessage(0);
2252c2c66affSColin Finck             }
2253c2c66affSColin Finck         }
2254c2c66affSColin Finck         break;
2255c2c66affSColin Finck 
2256c2c66affSColin Finck         case WM_DESTROY:
2257c2c66affSColin Finck         {
2258c2c66affSColin Finck             SetInstallationCompleted();
2259c2c66affSColin Finck             PostQuitMessage(0);
2260c2c66affSColin Finck             return TRUE;
2261c2c66affSColin Finck         }
2262c2c66affSColin Finck 
2263c2c66affSColin Finck         case WM_TIMER:
2264c2c66affSColin Finck         {
2265c2c66affSColin Finck             INT Position;
2266c2c66affSColin Finck             HWND hWndProgress;
2267c2c66affSColin Finck 
2268c2c66affSColin Finck             hWndProgress = GetDlgItem(hwndDlg, IDC_RESTART_PROGRESS);
2269c2c66affSColin Finck             Position = SendMessage(hWndProgress, PBM_GETPOS, 0, 0);
2270c2c66affSColin Finck             if (Position == 300)
2271c2c66affSColin Finck             {
2272c2c66affSColin Finck                 KillTimer(hwndDlg, 1);
2273c2c66affSColin Finck                 PropSheet_PressButton(GetParent(hwndDlg), PSBTN_FINISH);
2274c2c66affSColin Finck             }
2275c2c66affSColin Finck             else
2276c2c66affSColin Finck             {
2277c2c66affSColin Finck                 SendMessage(hWndProgress, PBM_SETPOS, Position + 1, 0);
2278c2c66affSColin Finck             }
2279c2c66affSColin Finck         }
2280c2c66affSColin Finck         return TRUE;
2281c2c66affSColin Finck 
2282c2c66affSColin Finck         case WM_NOTIFY:
2283c2c66affSColin Finck         {
2284c2c66affSColin Finck             LPNMHDR lpnm = (LPNMHDR)lParam;
2285c2c66affSColin Finck 
2286c2c66affSColin Finck             switch (lpnm->code)
2287c2c66affSColin Finck             {
2288c2c66affSColin Finck                 case PSN_SETACTIVE:
2289c2c66affSColin Finck                     /* Enable the correct buttons on for the active page */
2290c2c66affSColin Finck                     PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_FINISH);
2291c2c66affSColin Finck 
2292c2c66affSColin Finck                     SendDlgItemMessage(hwndDlg, IDC_RESTART_PROGRESS, PBM_SETRANGE, 0,
2293c2c66affSColin Finck                                        MAKELPARAM(0, 300));
2294c2c66affSColin Finck                     SendDlgItemMessage(hwndDlg, IDC_RESTART_PROGRESS, PBM_SETPOS, 0, 0);
2295c2c66affSColin Finck                     SetTimer(hwndDlg, 1, 50, NULL);
2296c2c66affSColin Finck                     break;
2297c2c66affSColin Finck 
2298c2c66affSColin Finck                 case PSN_WIZFINISH:
2299c2c66affSColin Finck                     DestroyWindow(GetParent(hwndDlg));
2300c2c66affSColin Finck                     break;
2301c2c66affSColin Finck 
2302c2c66affSColin Finck                 default:
2303c2c66affSColin Finck                     break;
2304c2c66affSColin Finck             }
2305c2c66affSColin Finck         }
2306c2c66affSColin Finck         break;
2307c2c66affSColin Finck 
2308c2c66affSColin Finck         default:
2309c2c66affSColin Finck             break;
2310c2c66affSColin Finck     }
2311c2c66affSColin Finck 
2312c2c66affSColin Finck     return FALSE;
2313c2c66affSColin Finck }
2314c2c66affSColin Finck 
2315c2c66affSColin Finck 
2316c8d37c1aSHermès Bélusca-Maïto /*
2317c8d37c1aSHermès Bélusca-Maïto  * GetInstallSourceWin32 retrieves the path to the ReactOS installation medium
2318c8d37c1aSHermès Bélusca-Maïto  * in Win32 format, for later use by syssetup and storage in the registry.
2319c8d37c1aSHermès Bélusca-Maïto  */
2320c8d37c1aSHermès Bélusca-Maïto static BOOL
2321c8d37c1aSHermès Bélusca-Maïto GetInstallSourceWin32(
2322c8d37c1aSHermès Bélusca-Maïto     OUT PWSTR pwszPath,
2323c8d37c1aSHermès Bélusca-Maïto     IN DWORD cchPathMax,
2324c8d37c1aSHermès Bélusca-Maïto     IN PCWSTR pwszNTPath)
2325c8d37c1aSHermès Bélusca-Maïto {
2326c8d37c1aSHermès Bélusca-Maïto     WCHAR wszDrives[512];
2327c8d37c1aSHermès Bélusca-Maïto     WCHAR wszNTPath[512]; // MAX_PATH ?
2328c8d37c1aSHermès Bélusca-Maïto     DWORD cchDrives;
2329c8d37c1aSHermès Bélusca-Maïto     PWCHAR pwszDrive;
2330c8d37c1aSHermès Bélusca-Maïto 
2331c8d37c1aSHermès Bélusca-Maïto     *pwszPath = UNICODE_NULL;
2332c8d37c1aSHermès Bélusca-Maïto 
2333c8d37c1aSHermès Bélusca-Maïto     cchDrives = GetLogicalDriveStringsW(_countof(wszDrives) - 1, wszDrives);
2334c8d37c1aSHermès Bélusca-Maïto     if (cchDrives == 0 || cchDrives >= _countof(wszDrives))
2335c8d37c1aSHermès Bélusca-Maïto     {
2336c8d37c1aSHermès Bélusca-Maïto         /* Buffer too small or failure */
2337c8d37c1aSHermès Bélusca-Maïto         LogItem(NULL, L"GetLogicalDriveStringsW failed");
2338c8d37c1aSHermès Bélusca-Maïto         return FALSE;
2339c8d37c1aSHermès Bélusca-Maïto     }
2340c8d37c1aSHermès Bélusca-Maïto 
2341c8d37c1aSHermès Bélusca-Maïto     for (pwszDrive = wszDrives; *pwszDrive; pwszDrive += wcslen(pwszDrive) + 1)
2342c8d37c1aSHermès Bélusca-Maïto     {
2343c8d37c1aSHermès Bélusca-Maïto         WCHAR wszBuf[MAX_PATH];
2344c8d37c1aSHermès Bélusca-Maïto 
2345c8d37c1aSHermès Bélusca-Maïto         /* Retrieve the NT path corresponding to the current Win32 DOS path */
2346c8d37c1aSHermès Bélusca-Maïto         pwszDrive[2] = UNICODE_NULL; // Temporarily remove the backslash
2347c8d37c1aSHermès Bélusca-Maïto         QueryDosDeviceW(pwszDrive, wszNTPath, _countof(wszNTPath));
2348c8d37c1aSHermès Bélusca-Maïto         pwszDrive[2] = L'\\';        // Restore the backslash
2349c8d37c1aSHermès Bélusca-Maïto 
2350c8d37c1aSHermès Bélusca-Maïto         wcscat(wszNTPath, L"\\");    // Concat a backslash
2351c8d37c1aSHermès Bélusca-Maïto 
2352c8d37c1aSHermès Bélusca-Maïto         /* Logging */
2353c8d37c1aSHermès Bélusca-Maïto         wsprintf(wszBuf, L"Testing '%s' --> '%s' %s a CD",
2354c8d37c1aSHermès Bélusca-Maïto                  pwszDrive, wszNTPath,
2355c8d37c1aSHermès Bélusca-Maïto                  (GetDriveTypeW(pwszDrive) == DRIVE_CDROM) ? L"is" : L"is not");
2356c8d37c1aSHermès Bélusca-Maïto         LogItem(NULL, wszBuf);
2357c8d37c1aSHermès Bélusca-Maïto 
2358c8d37c1aSHermès Bélusca-Maïto         /* Check whether the NT path corresponds to the NT installation source path */
2359c8d37c1aSHermès Bélusca-Maïto         if (!_wcsicmp(wszNTPath, pwszNTPath))
2360c8d37c1aSHermès Bélusca-Maïto         {
2361c8d37c1aSHermès Bélusca-Maïto             /* Found it! */
2362c8d37c1aSHermès Bélusca-Maïto             wcscpy(pwszPath, pwszDrive); // cchPathMax
2363c8d37c1aSHermès Bélusca-Maïto 
2364c8d37c1aSHermès Bélusca-Maïto             /* Logging */
2365c8d37c1aSHermès Bélusca-Maïto             wsprintf(wszBuf, L"GetInstallSourceWin32: %s", pwszPath);
2366c8d37c1aSHermès Bélusca-Maïto             LogItem(NULL, wszBuf);
2367c8d37c1aSHermès Bélusca-Maïto             wcscat(wszBuf, L"\n");
2368c8d37c1aSHermès Bélusca-Maïto             OutputDebugStringW(wszBuf);
2369c8d37c1aSHermès Bélusca-Maïto 
2370c8d37c1aSHermès Bélusca-Maïto             return TRUE;
2371c8d37c1aSHermès Bélusca-Maïto         }
2372c8d37c1aSHermès Bélusca-Maïto     }
2373c8d37c1aSHermès Bélusca-Maïto 
2374c8d37c1aSHermès Bélusca-Maïto     return FALSE;
2375c8d37c1aSHermès Bélusca-Maïto }
2376c8d37c1aSHermès Bélusca-Maïto 
2377c2c66affSColin Finck VOID
2378c8d37c1aSHermès Bélusca-Maïto ProcessUnattendSection(
2379c8d37c1aSHermès Bélusca-Maïto     IN OUT PSETUPDATA pSetupData)
2380c2c66affSColin Finck {
2381c2c66affSColin Finck     INFCONTEXT InfContext;
2382c2c66affSColin Finck     WCHAR szName[256];
2383c2c66affSColin Finck     WCHAR szValue[MAX_PATH];
2384c2c66affSColin Finck     DWORD LineLength;
2385c2c66affSColin Finck     HKEY hKey;
2386c2c66affSColin Finck 
2387c8d37c1aSHermès Bélusca-Maïto     if (!SetupFindFirstLineW(pSetupData->hSetupInf,
2388c2c66affSColin Finck                              L"Unattend",
2389c2c66affSColin Finck                              L"UnattendSetupEnabled",
2390c2c66affSColin Finck                              &InfContext))
2391c2c66affSColin Finck     {
2392e9893906SHermès Bélusca-Maïto         DPRINT1("Error: Cannot find UnattendSetupEnabled Key! %d\n", GetLastError());
2393c2c66affSColin Finck         return;
2394c2c66affSColin Finck     }
2395c2c66affSColin Finck 
2396c2c66affSColin Finck     if (!SetupGetStringFieldW(&InfContext,
2397c2c66affSColin Finck                               1,
2398c2c66affSColin Finck                               szValue,
239962678985SHermès Bélusca-Maïto                               ARRAYSIZE(szValue),
2400c2c66affSColin Finck                               &LineLength))
2401c2c66affSColin Finck     {
2402c2c66affSColin Finck         DPRINT1("Error: SetupGetStringField failed with %d\n", GetLastError());
2403c2c66affSColin Finck         return;
2404c2c66affSColin Finck     }
2405c2c66affSColin Finck 
240662678985SHermès Bélusca-Maïto     if (_wcsicmp(szValue, L"yes") != 0)
2407c2c66affSColin Finck     {
2408c2c66affSColin Finck         DPRINT("Unattend setup was disabled by UnattendSetupEnabled key.\n");
2409c2c66affSColin Finck         return;
2410c2c66affSColin Finck     }
2411c2c66affSColin Finck 
2412c2c66affSColin Finck     pSetupData->UnattendSetup = TRUE;
2413c2c66affSColin Finck 
2414c8d37c1aSHermès Bélusca-Maïto     if (!SetupFindFirstLineW(pSetupData->hSetupInf,
2415c2c66affSColin Finck                              L"Unattend",
2416c2c66affSColin Finck                              NULL,
2417c2c66affSColin Finck                              &InfContext))
2418c2c66affSColin Finck     {
2419c2c66affSColin Finck         DPRINT1("Error: SetupFindFirstLine failed %d\n", GetLastError());
2420c2c66affSColin Finck         return;
2421c2c66affSColin Finck     }
2422c2c66affSColin Finck 
2423c2c66affSColin Finck     do
2424c2c66affSColin Finck     {
2425c2c66affSColin Finck         if (!SetupGetStringFieldW(&InfContext,
2426c2c66affSColin Finck                                   0,
2427c2c66affSColin Finck                                   szName,
242862678985SHermès Bélusca-Maïto                                   ARRAYSIZE(szName),
2429c2c66affSColin Finck                                   &LineLength))
2430c2c66affSColin Finck         {
2431c2c66affSColin Finck             DPRINT1("Error: SetupGetStringField failed with %d\n", GetLastError());
2432c2c66affSColin Finck             return;
2433c2c66affSColin Finck         }
2434c2c66affSColin Finck 
2435c2c66affSColin Finck         if (!SetupGetStringFieldW(&InfContext,
2436c2c66affSColin Finck                                   1,
2437c2c66affSColin Finck                                   szValue,
243862678985SHermès Bélusca-Maïto                                   ARRAYSIZE(szValue),
2439c2c66affSColin Finck                                   &LineLength))
2440c2c66affSColin Finck         {
2441c2c66affSColin Finck             DPRINT1("Error: SetupGetStringField failed with %d\n", GetLastError());
2442c2c66affSColin Finck             return;
2443c2c66affSColin Finck         }
2444c2c66affSColin Finck         DPRINT1("Name %S Value %S\n", szName, szValue);
244562678985SHermès Bélusca-Maïto         if (!_wcsicmp(szName, L"FullName"))
2446c2c66affSColin Finck         {
244762678985SHermès Bélusca-Maïto             if (ARRAYSIZE(pSetupData->OwnerName) > LineLength)
2448c2c66affSColin Finck             {
2449c2c66affSColin Finck                 wcscpy(pSetupData->OwnerName, szValue);
2450c2c66affSColin Finck             }
2451c2c66affSColin Finck         }
245262678985SHermès Bélusca-Maïto         else if (!_wcsicmp(szName, L"OrgName"))
2453c2c66affSColin Finck         {
245462678985SHermès Bélusca-Maïto             if (ARRAYSIZE(pSetupData->OwnerOrganization) > LineLength)
2455c2c66affSColin Finck             {
2456c2c66affSColin Finck                 wcscpy(pSetupData->OwnerOrganization, szValue);
2457c2c66affSColin Finck             }
2458c2c66affSColin Finck         }
245962678985SHermès Bélusca-Maïto         else if (!_wcsicmp(szName, L"ComputerName"))
2460c2c66affSColin Finck         {
246162678985SHermès Bélusca-Maïto             if (ARRAYSIZE(pSetupData->ComputerName) > LineLength)
2462c2c66affSColin Finck             {
2463c2c66affSColin Finck                 wcscpy(pSetupData->ComputerName, szValue);
2464c2c66affSColin Finck             }
2465c2c66affSColin Finck         }
246662678985SHermès Bélusca-Maïto         else if (!_wcsicmp(szName, L"AdminPassword"))
2467c2c66affSColin Finck         {
246862678985SHermès Bélusca-Maïto             if (ARRAYSIZE(pSetupData->AdminPassword) > LineLength)
2469c2c66affSColin Finck             {
2470c2c66affSColin Finck                 wcscpy(pSetupData->AdminPassword, szValue);
2471c2c66affSColin Finck             }
2472c2c66affSColin Finck         }
247362678985SHermès Bélusca-Maïto         else if (!_wcsicmp(szName, L"TimeZoneIndex"))
2474c2c66affSColin Finck         {
2475c2c66affSColin Finck             pSetupData->TimeZoneIndex = _wtoi(szValue);
2476c2c66affSColin Finck         }
247762678985SHermès Bélusca-Maïto         else if (!_wcsicmp(szName, L"DisableAutoDaylightTimeSet"))
2478c2c66affSColin Finck         {
2479c2c66affSColin Finck             pSetupData->DisableAutoDaylightTimeSet = _wtoi(szValue);
2480c2c66affSColin Finck         }
248162678985SHermès Bélusca-Maïto         else if (!_wcsicmp(szName, L"DisableGeckoInst"))
2482c2c66affSColin Finck         {
248362678985SHermès Bélusca-Maïto             if (!_wcsicmp(szValue, L"yes"))
2484e9893906SHermès Bélusca-Maïto                 pSetupData->DisableGeckoInst = TRUE;
2485c2c66affSColin Finck             else
2486e9893906SHermès Bélusca-Maïto                 pSetupData->DisableGeckoInst = FALSE;
2487c2c66affSColin Finck         }
2488612729b0SKatayama Hirofumi MZ         else if (!_wcsicmp(szName, L"ProductOption"))
2489612729b0SKatayama Hirofumi MZ         {
2490612729b0SKatayama Hirofumi MZ             pSetupData->ProductOption = (PRODUCT_OPTION)_wtoi(szValue);
2491612729b0SKatayama Hirofumi MZ         }
2492e9893906SHermès Bélusca-Maïto     } while (SetupFindNextLine(&InfContext, &InfContext));
2493c2c66affSColin Finck 
2494c8d37c1aSHermès Bélusca-Maïto     if (SetupFindFirstLineW(pSetupData->hSetupInf,
2495c2c66affSColin Finck                             L"Display",
2496c2c66affSColin Finck                             NULL,
2497c2c66affSColin Finck                             &InfContext))
2498c2c66affSColin Finck     {
2499c2c66affSColin Finck         DEVMODEW dm = { { 0 } };
2500c2c66affSColin Finck         dm.dmSize = sizeof(dm);
2501c2c66affSColin Finck         if (EnumDisplaySettingsW(NULL, ENUM_CURRENT_SETTINGS, &dm))
2502c2c66affSColin Finck         {
2503c2c66affSColin Finck             do
2504c2c66affSColin Finck             {
2505c2c66affSColin Finck                 int iValue;
2506c2c66affSColin Finck                 if (!SetupGetStringFieldW(&InfContext,
2507c2c66affSColin Finck                                           0,
2508c2c66affSColin Finck                                           szName,
250962678985SHermès Bélusca-Maïto                                           ARRAYSIZE(szName),
2510c2c66affSColin Finck                                           &LineLength))
2511c2c66affSColin Finck                 {
2512c2c66affSColin Finck                     DPRINT1("Error: SetupGetStringField failed with %d\n", GetLastError());
2513c2c66affSColin Finck                     return;
2514c2c66affSColin Finck                 }
2515c2c66affSColin Finck 
2516c2c66affSColin Finck                 if (!SetupGetStringFieldW(&InfContext,
2517c2c66affSColin Finck                                           1,
2518c2c66affSColin Finck                                           szValue,
251962678985SHermès Bélusca-Maïto                                           ARRAYSIZE(szValue),
2520c2c66affSColin Finck                                           &LineLength))
2521c2c66affSColin Finck                 {
2522c2c66affSColin Finck                     DPRINT1("Error: SetupGetStringField failed with %d\n", GetLastError());
2523c2c66affSColin Finck                     return;
2524c2c66affSColin Finck                 }
2525c2c66affSColin Finck                 iValue = _wtoi(szValue);
2526c2c66affSColin Finck                 DPRINT1("Name %S Value %i\n", szName, iValue);
2527c2c66affSColin Finck 
2528c2c66affSColin Finck                 if (!iValue)
2529c2c66affSColin Finck                     continue;
2530c2c66affSColin Finck 
253162678985SHermès Bélusca-Maïto                 if (!_wcsicmp(szName, L"BitsPerPel"))
2532c2c66affSColin Finck                 {
2533c2c66affSColin Finck                     dm.dmFields |= DM_BITSPERPEL;
2534c2c66affSColin Finck                     dm.dmBitsPerPel = iValue;
2535c2c66affSColin Finck                 }
253662678985SHermès Bélusca-Maïto                 else if (!_wcsicmp(szName, L"XResolution"))
2537c2c66affSColin Finck                 {
2538c2c66affSColin Finck                     dm.dmFields |= DM_PELSWIDTH;
2539c2c66affSColin Finck                     dm.dmPelsWidth = iValue;
2540c2c66affSColin Finck                 }
254162678985SHermès Bélusca-Maïto                 else if (!_wcsicmp(szName, L"YResolution"))
2542c2c66affSColin Finck                 {
2543c2c66affSColin Finck                     dm.dmFields |= DM_PELSHEIGHT;
2544c2c66affSColin Finck                     dm.dmPelsHeight = iValue;
2545c2c66affSColin Finck                 }
254662678985SHermès Bélusca-Maïto                 else if (!_wcsicmp(szName, L"VRefresh"))
2547c2c66affSColin Finck                 {
2548c2c66affSColin Finck                     dm.dmFields |= DM_DISPLAYFREQUENCY;
2549c2c66affSColin Finck                     dm.dmDisplayFrequency = iValue;
2550c2c66affSColin Finck                 }
2551e9893906SHermès Bélusca-Maïto             } while (SetupFindNextLine(&InfContext, &InfContext));
2552c2c66affSColin Finck 
2553c2c66affSColin Finck             ChangeDisplaySettingsW(&dm, CDS_UPDATEREGISTRY);
2554c2c66affSColin Finck         }
2555c2c66affSColin Finck     }
2556c2c66affSColin Finck 
2557c2c66affSColin Finck     if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,
2558c2c66affSColin Finck                       L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunOnce",
2559c2c66affSColin Finck                       0,
2560c2c66affSColin Finck                       KEY_SET_VALUE,
2561c2c66affSColin Finck                       &hKey) != ERROR_SUCCESS)
2562c2c66affSColin Finck     {
2563c2c66affSColin Finck         DPRINT1("Error: failed to open HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\RunOnce\n");
2564c2c66affSColin Finck         return;
2565c2c66affSColin Finck     }
2566c2c66affSColin Finck 
2567c8d37c1aSHermès Bélusca-Maïto     if (SetupFindFirstLineW(pSetupData->hSetupInf,
2568c2c66affSColin Finck                             L"GuiRunOnce",
2569c2c66affSColin Finck                             NULL,
2570c2c66affSColin Finck                             &InfContext))
2571c2c66affSColin Finck     {
2572c2c66affSColin Finck         int i = 0;
2573c2c66affSColin Finck         do
2574c2c66affSColin Finck         {
2575c2c66affSColin Finck             if (SetupGetStringFieldW(&InfContext,
2576c2c66affSColin Finck                                      0,
2577c2c66affSColin Finck                                      szValue,
257862678985SHermès Bélusca-Maïto                                      ARRAYSIZE(szValue),
2579c2c66affSColin Finck                                      NULL))
2580c2c66affSColin Finck             {
2581c2c66affSColin Finck                 WCHAR szPath[MAX_PATH];
2582c2c66affSColin Finck                 swprintf(szName, L"%d", i);
2583c2c66affSColin Finck                 DPRINT("szName %S szValue %S\n", szName, szValue);
2584c2c66affSColin Finck 
2585c2c66affSColin Finck                 if (ExpandEnvironmentStringsW(szValue, szPath, MAX_PATH))
2586c2c66affSColin Finck                 {
2587c2c66affSColin Finck                     DPRINT("value %S\n", szPath);
2588c2c66affSColin Finck                     if (RegSetValueExW(hKey,
2589c2c66affSColin Finck                                        szName,
2590c2c66affSColin Finck                                        0,
2591c2c66affSColin Finck                                        REG_SZ,
2592c2c66affSColin Finck                                        (const BYTE*)szPath,
2593c2c66affSColin Finck                                        (wcslen(szPath) + 1) * sizeof(WCHAR)) == ERROR_SUCCESS)
2594c2c66affSColin Finck                     {
2595c2c66affSColin Finck                         i++;
2596c2c66affSColin Finck                     }
2597c2c66affSColin Finck                 }
2598c2c66affSColin Finck             }
2599c2c66affSColin Finck         } while (SetupFindNextLine(&InfContext, &InfContext));
2600c2c66affSColin Finck     }
2601c2c66affSColin Finck 
2602c2c66affSColin Finck     RegCloseKey(hKey);
2603c2c66affSColin Finck }
2604c2c66affSColin Finck 
2605c2c66affSColin Finck VOID
2606c8d37c1aSHermès Bélusca-Maïto ProcessSetupInf(
2607c8d37c1aSHermès Bélusca-Maïto     IN OUT PSETUPDATA pSetupData)
2608c2c66affSColin Finck {
2609c2c66affSColin Finck     WCHAR szPath[MAX_PATH];
2610c8d37c1aSHermès Bélusca-Maïto     WCHAR szValue[MAX_PATH];
2611c8d37c1aSHermès Bélusca-Maïto     INFCONTEXT InfContext;
2612c8d37c1aSHermès Bélusca-Maïto     DWORD LineLength;
2613c8d37c1aSHermès Bélusca-Maïto     HKEY hKey;
2614c8d37c1aSHermès Bélusca-Maïto     LONG res;
2615c2c66affSColin Finck 
2616c8d37c1aSHermès Bélusca-Maïto     pSetupData->hSetupInf = INVALID_HANDLE_VALUE;
2617c2c66affSColin Finck 
2618c8d37c1aSHermès Bélusca-Maïto     /* Retrieve the path of the setup INF */
2619c8d37c1aSHermès Bélusca-Maïto     GetSystemDirectoryW(szPath, _countof(szPath));
2620c8d37c1aSHermès Bélusca-Maïto     wcscat(szPath, L"\\$winnt$.inf");
2621c2c66affSColin Finck 
2622c8d37c1aSHermès Bélusca-Maïto     /* Open the setup INF */
2623c8d37c1aSHermès Bélusca-Maïto     pSetupData->hSetupInf = SetupOpenInfFileW(szPath,
2624c2c66affSColin Finck                                               NULL,
2625c2c66affSColin Finck                                               INF_STYLE_OLDNT,
2626c2c66affSColin Finck                                               NULL);
2627c8d37c1aSHermès Bélusca-Maïto     if (pSetupData->hSetupInf == INVALID_HANDLE_VALUE)
2628c2c66affSColin Finck     {
2629c8d37c1aSHermès Bélusca-Maïto         DPRINT1("Error: Cannot open the setup information file %S with error %d\n", szPath, GetLastError());
2630c8d37c1aSHermès Bélusca-Maïto         return;
2631c2c66affSColin Finck     }
2632c8d37c1aSHermès Bélusca-Maïto 
2633c8d37c1aSHermès Bélusca-Maïto 
2634c8d37c1aSHermès Bélusca-Maïto     /* Retrieve the NT source path from which the 1st-stage installer was run */
2635c8d37c1aSHermès Bélusca-Maïto     if (!SetupFindFirstLineW(pSetupData->hSetupInf,
2636c8d37c1aSHermès Bélusca-Maïto                              L"data",
2637c8d37c1aSHermès Bélusca-Maïto                              L"sourcepath",
2638c8d37c1aSHermès Bélusca-Maïto                              &InfContext))
2639c8d37c1aSHermès Bélusca-Maïto     {
2640bae08335SMark Jansen         DPRINT1("Error: Cannot find sourcepath Key! %d\n", GetLastError());
2641c8d37c1aSHermès Bélusca-Maïto         return;
2642c8d37c1aSHermès Bélusca-Maïto     }
2643c8d37c1aSHermès Bélusca-Maïto 
2644c8d37c1aSHermès Bélusca-Maïto     if (!SetupGetStringFieldW(&InfContext,
2645c8d37c1aSHermès Bélusca-Maïto                               1,
2646c8d37c1aSHermès Bélusca-Maïto                               szValue,
2647c8d37c1aSHermès Bélusca-Maïto                               ARRAYSIZE(szValue),
2648c8d37c1aSHermès Bélusca-Maïto                               &LineLength))
2649c8d37c1aSHermès Bélusca-Maïto     {
2650c8d37c1aSHermès Bélusca-Maïto         DPRINT1("Error: SetupGetStringField failed with %d\n", GetLastError());
2651c8d37c1aSHermès Bélusca-Maïto         return;
2652c8d37c1aSHermès Bélusca-Maïto     }
2653c8d37c1aSHermès Bélusca-Maïto 
2654c8d37c1aSHermès Bélusca-Maïto     *pSetupData->SourcePath = UNICODE_NULL;
2655c8d37c1aSHermès Bélusca-Maïto 
2656c8d37c1aSHermès Bélusca-Maïto     /* Close the setup INF as we are going to modify it manually */
2657c8d37c1aSHermès Bélusca-Maïto     if (pSetupData->hSetupInf != INVALID_HANDLE_VALUE)
2658c8d37c1aSHermès Bélusca-Maïto         SetupCloseInfFile(pSetupData->hSetupInf);
2659c8d37c1aSHermès Bélusca-Maïto 
2660c8d37c1aSHermès Bélusca-Maïto 
2661c8d37c1aSHermès Bélusca-Maïto     /* Find the installation source path in Win32 format */
2662c8d37c1aSHermès Bélusca-Maïto     if (!GetInstallSourceWin32(pSetupData->SourcePath,
2663c8d37c1aSHermès Bélusca-Maïto                                _countof(pSetupData->SourcePath),
2664c8d37c1aSHermès Bélusca-Maïto                                szValue))
2665c8d37c1aSHermès Bélusca-Maïto     {
2666c8d37c1aSHermès Bélusca-Maïto         *pSetupData->SourcePath = UNICODE_NULL;
2667c8d37c1aSHermès Bélusca-Maïto     }
2668c8d37c1aSHermès Bélusca-Maïto 
2669c8d37c1aSHermès Bélusca-Maïto     /* Save the path in Win32 format in the setup INF */
2670c8d37c1aSHermès Bélusca-Maïto     swprintf(szValue, L"\"%s\"", pSetupData->SourcePath);
2671c8d37c1aSHermès Bélusca-Maïto     WritePrivateProfileStringW(L"data", L"dospath", szValue, szPath);
2672c8d37c1aSHermès Bélusca-Maïto 
2673c8d37c1aSHermès Bélusca-Maïto     /*
2674c8d37c1aSHermès Bélusca-Maïto      * Save it also in the registry, in the following keys:
2675c8d37c1aSHermès Bélusca-Maïto      * - HKLM\Software\Microsoft\Windows\CurrentVersion\Setup ,
2676c8d37c1aSHermès Bélusca-Maïto      *   values "SourcePath" and "ServicePackSourcePath" (REG_SZ);
2677c8d37c1aSHermès Bélusca-Maïto      * - HKLM\Software\Microsoft\Windows NT\CurrentVersion ,
2678c8d37c1aSHermès Bélusca-Maïto      *   value "SourcePath" (REG_SZ); set to the full path (e.g. D:\I386).
2679c8d37c1aSHermès Bélusca-Maïto      */
2680c8d37c1aSHermès Bélusca-Maïto #if 0
2681c8d37c1aSHermès Bélusca-Maïto     res = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
2682c8d37c1aSHermès Bélusca-Maïto                         L"Software\\Microsoft\\Windows NT\\CurrentVersion",
2683c8d37c1aSHermès Bélusca-Maïto                         0,
2684c8d37c1aSHermès Bélusca-Maïto                         KEY_ALL_ACCESS,
2685c8d37c1aSHermès Bélusca-Maïto                         &hKey);
2686c8d37c1aSHermès Bélusca-Maïto 
2687c8d37c1aSHermès Bélusca-Maïto     if (res != ERROR_SUCCESS)
2688c8d37c1aSHermès Bélusca-Maïto     {
2689c8d37c1aSHermès Bélusca-Maïto         return FALSE;
2690c8d37c1aSHermès Bélusca-Maïto     }
2691c8d37c1aSHermès Bélusca-Maïto #endif
2692c8d37c1aSHermès Bélusca-Maïto 
2693c8d37c1aSHermès Bélusca-Maïto     res = RegCreateKeyExW(HKEY_LOCAL_MACHINE,
2694c8d37c1aSHermès Bélusca-Maïto                           L"Software\\Microsoft\\Windows\\CurrentVersion\\Setup",
2695c8d37c1aSHermès Bélusca-Maïto                           0, NULL,
2696c8d37c1aSHermès Bélusca-Maïto                           REG_OPTION_NON_VOLATILE,
2697c8d37c1aSHermès Bélusca-Maïto                           KEY_ALL_ACCESS, // KEY_WRITE
2698c8d37c1aSHermès Bélusca-Maïto                           NULL,
2699c8d37c1aSHermès Bélusca-Maïto                           &hKey,
2700c8d37c1aSHermès Bélusca-Maïto                           NULL);
2701c8d37c1aSHermès Bélusca-Maïto     if (res == ERROR_SUCCESS)
2702c8d37c1aSHermès Bélusca-Maïto     {
2703c8d37c1aSHermès Bélusca-Maïto         res = RegSetValueExW(hKey,
2704c8d37c1aSHermès Bélusca-Maïto                              L"SourcePath",
2705c8d37c1aSHermès Bélusca-Maïto                              0,
2706c8d37c1aSHermès Bélusca-Maïto                              REG_SZ,
2707c8d37c1aSHermès Bélusca-Maïto                              (LPBYTE)pSetupData->SourcePath,
2708c8d37c1aSHermès Bélusca-Maïto                              (wcslen(pSetupData->SourcePath) + 1) * sizeof(WCHAR));
2709c8d37c1aSHermès Bélusca-Maïto 
2710c8d37c1aSHermès Bélusca-Maïto         res = RegSetValueExW(hKey,
2711c8d37c1aSHermès Bélusca-Maïto                              L"ServicePackSourcePath",
2712c8d37c1aSHermès Bélusca-Maïto                              0,
2713c8d37c1aSHermès Bélusca-Maïto                              REG_SZ,
2714c8d37c1aSHermès Bélusca-Maïto                              (LPBYTE)pSetupData->SourcePath,
2715c8d37c1aSHermès Bélusca-Maïto                              (wcslen(pSetupData->SourcePath) + 1) * sizeof(WCHAR));
2716c8d37c1aSHermès Bélusca-Maïto 
2717c8d37c1aSHermès Bélusca-Maïto         RegCloseKey(hKey);
2718c8d37c1aSHermès Bélusca-Maïto     }
2719c8d37c1aSHermès Bélusca-Maïto 
2720c8d37c1aSHermès Bélusca-Maïto 
2721c8d37c1aSHermès Bélusca-Maïto     /* Now, re-open the setup INF (this must succeed) */
2722c8d37c1aSHermès Bélusca-Maïto     pSetupData->hSetupInf = SetupOpenInfFileW(szPath,
2723c8d37c1aSHermès Bélusca-Maïto                                               NULL,
2724c8d37c1aSHermès Bélusca-Maïto                                               INF_STYLE_OLDNT,
2725c8d37c1aSHermès Bélusca-Maïto                                               NULL);
2726c8d37c1aSHermès Bélusca-Maïto     if (pSetupData->hSetupInf == INVALID_HANDLE_VALUE)
2727c8d37c1aSHermès Bélusca-Maïto     {
2728c8d37c1aSHermès Bélusca-Maïto         DPRINT1("Error: Cannot open the setup information file %S with error %d\n", szPath, GetLastError());
2729c8d37c1aSHermès Bélusca-Maïto         return;
2730c8d37c1aSHermès Bélusca-Maïto     }
2731c8d37c1aSHermès Bélusca-Maïto 
2732c8d37c1aSHermès Bélusca-Maïto     /* Process the unattended section of the setup file */
2733c8d37c1aSHermès Bélusca-Maïto     ProcessUnattendSection(pSetupData);
2734c2c66affSColin Finck }
2735c2c66affSColin Finck 
2736c2c66affSColin Finck typedef DWORD(WINAPI *PFNREQUESTWIZARDPAGES)(PDWORD, HPROPSHEETPAGE *, PSETUPDATA);
2737c2c66affSColin Finck 
2738c2c66affSColin Finck VOID
2739c2c66affSColin Finck InstallWizard(VOID)
2740c2c66affSColin Finck {
274109edc062SMark Jansen     PROPSHEETHEADER psh = {0};
2742c2c66affSColin Finck     HPROPSHEETPAGE *phpage = NULL;
2743c2c66affSColin Finck     PROPSHEETPAGE psp = {0};
2744c2c66affSColin Finck     UINT nPages = 0;
2745c2c66affSColin Finck     HWND hWnd;
2746c2c66affSColin Finck     MSG msg;
2747c2c66affSColin Finck     PSETUPDATA pSetupData = NULL;
2748c2c66affSColin Finck     HMODULE hNetShell = NULL;
2749c2c66affSColin Finck     PFNREQUESTWIZARDPAGES pfn = NULL;
275048160c74SKatayama Hirofumi MZ     DWORD dwPageCount = 10, dwNetworkPageCount = 0;
2751c2c66affSColin Finck 
2752c2c66affSColin Finck     LogItem(L"BEGIN_SECTION", L"InstallWizard");
2753c2c66affSColin Finck 
2754c2c66affSColin Finck     /* Allocate setup data */
2755c2c66affSColin Finck     pSetupData = HeapAlloc(GetProcessHeap(),
2756c2c66affSColin Finck                            HEAP_ZERO_MEMORY,
2757c2c66affSColin Finck                            sizeof(SETUPDATA));
2758c2c66affSColin Finck     if (pSetupData == NULL)
2759c2c66affSColin Finck     {
2760c2c66affSColin Finck         LogItem(NULL, L"SetupData allocation failed!");
2761c2c66affSColin Finck         MessageBoxW(NULL,
2762c2c66affSColin Finck                     L"Setup failed to allocate global data!",
2763c2c66affSColin Finck                     L"ReactOS Setup",
2764c2c66affSColin Finck                     MB_ICONERROR | MB_OK);
2765c2c66affSColin Finck         goto done;
2766c2c66affSColin Finck     }
2767612729b0SKatayama Hirofumi MZ     pSetupData->ProductOption = PRODUCT_OPTION_DEFAULT;
2768c2c66affSColin Finck 
2769c2c66affSColin Finck     hNetShell = LoadLibraryW(L"netshell.dll");
2770c2c66affSColin Finck     if (hNetShell != NULL)
2771c2c66affSColin Finck     {
2772c2c66affSColin Finck         DPRINT("Netshell.dll loaded!\n");
2773c2c66affSColin Finck 
2774c2c66affSColin Finck         pfn = (PFNREQUESTWIZARDPAGES)GetProcAddress(hNetShell,
2775c2c66affSColin Finck                                                     "NetSetupRequestWizardPages");
2776c2c66affSColin Finck         if (pfn != NULL)
2777c2c66affSColin Finck         {
2778c2c66affSColin Finck             pfn(&dwNetworkPageCount, NULL, NULL);
2779c2c66affSColin Finck             dwPageCount += dwNetworkPageCount;
2780c2c66affSColin Finck         }
2781c2c66affSColin Finck     }
2782c2c66affSColin Finck 
2783c2c66affSColin Finck     DPRINT("PageCount: %lu\n", dwPageCount);
2784c2c66affSColin Finck 
2785c2c66affSColin Finck     phpage = HeapAlloc(GetProcessHeap(),
2786c2c66affSColin Finck                        HEAP_ZERO_MEMORY,
2787c2c66affSColin Finck                        dwPageCount * sizeof(HPROPSHEETPAGE));
2788c2c66affSColin Finck     if (phpage == NULL)
2789c2c66affSColin Finck     {
2790c2c66affSColin Finck         LogItem(NULL, L"Page array allocation failed!");
2791c2c66affSColin Finck         MessageBoxW(NULL,
2792c2c66affSColin Finck                     L"Setup failed to allocate page array!",
2793c2c66affSColin Finck                     L"ReactOS Setup",
2794c2c66affSColin Finck                     MB_ICONERROR | MB_OK);
2795c2c66affSColin Finck         goto done;
2796c2c66affSColin Finck     }
2797c2c66affSColin Finck 
2798c8d37c1aSHermès Bélusca-Maïto     /* Process the $winnt$.inf setup file */
2799c8d37c1aSHermès Bélusca-Maïto     ProcessSetupInf(pSetupData);
2800c2c66affSColin Finck 
2801c2c66affSColin Finck     /* Create the Welcome page */
2802c2c66affSColin Finck     psp.dwSize = sizeof(PROPSHEETPAGE);
2803c2c66affSColin Finck     psp.dwFlags = PSP_DEFAULT | PSP_HIDEHEADER;
2804c2c66affSColin Finck     psp.hInstance = hDllInstance;
2805c2c66affSColin Finck     psp.lParam = (LPARAM)pSetupData;
2806c2c66affSColin Finck     psp.pfnDlgProc = WelcomeDlgProc;
2807c2c66affSColin Finck     psp.pszTemplate = MAKEINTRESOURCE(IDD_WELCOMEPAGE);
2808c2c66affSColin Finck     phpage[nPages++] = CreatePropertySheetPage(&psp);
2809c2c66affSColin Finck 
2810c2c66affSColin Finck     /* Create the Acknowledgements page */
2811c2c66affSColin Finck     psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
2812c2c66affSColin Finck     psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_ACKTITLE);
2813c2c66affSColin Finck     psp.pszHeaderSubTitle = MAKEINTRESOURCE(IDS_ACKSUBTITLE);
2814c2c66affSColin Finck     psp.pszTemplate = MAKEINTRESOURCE(IDD_ACKPAGE);
2815c2c66affSColin Finck     psp.pfnDlgProc = AckPageDlgProc;
2816c2c66affSColin Finck     phpage[nPages++] = CreatePropertySheetPage(&psp);
2817c2c66affSColin Finck 
281848160c74SKatayama Hirofumi MZ     /* Create the Product page */
281948160c74SKatayama Hirofumi MZ     psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
282048160c74SKatayama Hirofumi MZ     psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_PRODUCTTITLE);
282148160c74SKatayama Hirofumi MZ     psp.pszHeaderSubTitle = MAKEINTRESOURCE(IDS_PRODUCTSUBTITLE);
282248160c74SKatayama Hirofumi MZ     psp.pszTemplate = MAKEINTRESOURCE(IDD_PRODUCT);
282348160c74SKatayama Hirofumi MZ     psp.pfnDlgProc = ProductPageDlgProc;
282448160c74SKatayama Hirofumi MZ     phpage[nPages++] = CreatePropertySheetPage(&psp);
282548160c74SKatayama Hirofumi MZ 
2826c2c66affSColin Finck     /* Create the Locale page */
2827c2c66affSColin Finck     psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
2828c2c66affSColin Finck     psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_LOCALETITLE);
2829c2c66affSColin Finck     psp.pszHeaderSubTitle = MAKEINTRESOURCE(IDS_LOCALESUBTITLE);
2830c2c66affSColin Finck     psp.pfnDlgProc = LocalePageDlgProc;
2831c2c66affSColin Finck     psp.pszTemplate = MAKEINTRESOURCE(IDD_LOCALEPAGE);
2832c2c66affSColin Finck     phpage[nPages++] = CreatePropertySheetPage(&psp);
2833c2c66affSColin Finck 
2834c2c66affSColin Finck     /* Create the Owner page */
2835c2c66affSColin Finck     psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
2836c2c66affSColin Finck     psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_OWNERTITLE);
2837c2c66affSColin Finck     psp.pszHeaderSubTitle = MAKEINTRESOURCE(IDS_OWNERSUBTITLE);
2838c2c66affSColin Finck     psp.pszTemplate = MAKEINTRESOURCE(IDD_OWNERPAGE);
2839c2c66affSColin Finck     psp.pfnDlgProc = OwnerPageDlgProc;
2840c2c66affSColin Finck     phpage[nPages++] = CreatePropertySheetPage(&psp);
2841c2c66affSColin Finck 
2842c2c66affSColin Finck     /* Create the Computer page */
2843c2c66affSColin Finck     psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
2844c2c66affSColin Finck     psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_COMPUTERTITLE);
2845c2c66affSColin Finck     psp.pszHeaderSubTitle = MAKEINTRESOURCE(IDS_COMPUTERSUBTITLE);
2846c2c66affSColin Finck     psp.pfnDlgProc = ComputerPageDlgProc;
2847c2c66affSColin Finck     psp.pszTemplate = MAKEINTRESOURCE(IDD_COMPUTERPAGE);
2848c2c66affSColin Finck     phpage[nPages++] = CreatePropertySheetPage(&psp);
2849c2c66affSColin Finck 
2850c2c66affSColin Finck     /* Create the DateTime page */
2851c2c66affSColin Finck     psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
2852c2c66affSColin Finck     psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_DATETIMETITLE);
2853c2c66affSColin Finck     psp.pszHeaderSubTitle = MAKEINTRESOURCE(IDS_DATETIMESUBTITLE);
2854c2c66affSColin Finck     psp.pfnDlgProc = DateTimePageDlgProc;
2855c2c66affSColin Finck     psp.pszTemplate = MAKEINTRESOURCE(IDD_DATETIMEPAGE);
2856c2c66affSColin Finck     phpage[nPages++] = CreatePropertySheetPage(&psp);
2857c2c66affSColin Finck 
2858c2c66affSColin Finck     /* Create the theme selection page */
2859c2c66affSColin Finck     psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
2860c2c66affSColin Finck     psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_THEMESELECTIONTITLE);
2861c2c66affSColin Finck     psp.pszHeaderSubTitle = MAKEINTRESOURCE(IDS_THEMESELECTIONSUBTITLE);
2862c2c66affSColin Finck     psp.pfnDlgProc = ThemePageDlgProc;
2863c2c66affSColin Finck     psp.pszTemplate = MAKEINTRESOURCE(IDD_THEMEPAGE);
2864c2c66affSColin Finck     phpage[nPages++] = CreatePropertySheetPage(&psp);
2865c2c66affSColin Finck 
2866c2c66affSColin Finck     pSetupData->uFirstNetworkWizardPage = IDD_PROCESSPAGE;
2867c2c66affSColin Finck     pSetupData->uPostNetworkWizardPage = IDD_PROCESSPAGE;
2868c2c66affSColin Finck 
2869c2c66affSColin Finck     if (pfn)
2870c2c66affSColin Finck     {
2871c2c66affSColin Finck         pfn(&dwNetworkPageCount, &phpage[nPages], pSetupData);
2872c2c66affSColin Finck         nPages += dwNetworkPageCount;
2873c2c66affSColin Finck     }
2874c2c66affSColin Finck 
2875c2c66affSColin Finck     /* Create the Process page */
2876c2c66affSColin Finck     psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
2877c2c66affSColin Finck     psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_PROCESSTITLE);
2878c2c66affSColin Finck     psp.pszHeaderSubTitle = MAKEINTRESOURCE(IDS_PROCESSSUBTITLE);
2879c2c66affSColin Finck     psp.pfnDlgProc = ProcessPageDlgProc;
2880c2c66affSColin Finck     psp.pszTemplate = MAKEINTRESOURCE(IDD_PROCESSPAGE);
2881c2c66affSColin Finck     phpage[nPages++] = CreatePropertySheetPage(&psp);
2882c2c66affSColin Finck 
2883c2c66affSColin Finck     /* Create the Finish page */
2884c2c66affSColin Finck     psp.dwFlags = PSP_DEFAULT | PSP_HIDEHEADER;
2885c2c66affSColin Finck     psp.pfnDlgProc = FinishDlgProc;
2886c2c66affSColin Finck     psp.pszTemplate = MAKEINTRESOURCE(IDD_FINISHPAGE);
2887c2c66affSColin Finck     phpage[nPages++] = CreatePropertySheetPage(&psp);
2888c2c66affSColin Finck 
28891668527aSSerge Gautherie     ASSERT(nPages == dwPageCount);
28901668527aSSerge Gautherie 
2891c2c66affSColin Finck     /* Create the property sheet */
2892c2c66affSColin Finck     psh.dwSize = sizeof(PROPSHEETHEADER);
2893c2c66affSColin Finck     psh.dwFlags = PSH_WIZARD97 | PSH_WATERMARK | PSH_HEADER | PSH_MODELESS;
2894c2c66affSColin Finck     psh.hInstance = hDllInstance;
2895c2c66affSColin Finck     psh.hwndParent = NULL;
2896c2c66affSColin Finck     psh.nPages = nPages;
2897c2c66affSColin Finck     psh.nStartPage = 0;
2898c2c66affSColin Finck     psh.phpage = phpage;
2899c2c66affSColin Finck     psh.pszbmWatermark = MAKEINTRESOURCE(IDB_WATERMARK);
2900c2c66affSColin Finck     psh.pszbmHeader = MAKEINTRESOURCE(IDB_HEADER);
2901c2c66affSColin Finck 
2902c2c66affSColin Finck     /* Create title font */
2903c2c66affSColin Finck     pSetupData->hTitleFont = CreateTitleFont();
2904c2c66affSColin Finck     pSetupData->hBoldFont  = CreateBoldFont();
2905c2c66affSColin Finck 
2906c2c66affSColin Finck     /* Display the wizard */
2907c2c66affSColin Finck     hWnd = (HWND)PropertySheet(&psh);
2908c2c66affSColin Finck     ShowWindow(hWnd, SW_SHOW);
2909c2c66affSColin Finck 
2910c2c66affSColin Finck     while (GetMessage(&msg, NULL, 0, 0))
2911c2c66affSColin Finck     {
2912c2c66affSColin Finck         if (!IsDialogMessage(hWnd, &msg))
2913c2c66affSColin Finck         {
2914c2c66affSColin Finck             TranslateMessage(&msg);
2915c2c66affSColin Finck             DispatchMessage(&msg);
2916c2c66affSColin Finck         }
2917c2c66affSColin Finck     }
2918c2c66affSColin Finck 
29198468ad5cSHermès Bélusca-Maïto     DeleteObject(pSetupData->hBoldFont);
29208468ad5cSHermès Bélusca-Maïto     DeleteObject(pSetupData->hTitleFont);
29218468ad5cSHermès Bélusca-Maïto 
2922c8d37c1aSHermès Bélusca-Maïto     if (pSetupData->hSetupInf != INVALID_HANDLE_VALUE)
2923c8d37c1aSHermès Bélusca-Maïto         SetupCloseInfFile(pSetupData->hSetupInf);
2924c2c66affSColin Finck 
2925c2c66affSColin Finck done:
2926c2c66affSColin Finck     if (phpage != NULL)
2927c2c66affSColin Finck         HeapFree(GetProcessHeap(), 0, phpage);
2928c2c66affSColin Finck 
2929c2c66affSColin Finck     if (hNetShell != NULL)
2930c2c66affSColin Finck         FreeLibrary(hNetShell);
2931c2c66affSColin Finck 
2932c2c66affSColin Finck     if (pSetupData != NULL)
2933c2c66affSColin Finck         HeapFree(GetProcessHeap(), 0, pSetupData);
2934c2c66affSColin Finck 
2935c2c66affSColin Finck     LogItem(L"END_SECTION", L"InstallWizard");
2936c2c66affSColin Finck }
2937c2c66affSColin Finck 
2938c2c66affSColin Finck /* EOF */
2939