xref: /reactos/dll/win32/syssetup/wizard.c (revision 50d260a7)
1c2c66affSColin Finck /*
2c2c66affSColin Finck  * COPYRIGHT:       See COPYING in the top level directory
3c2c66affSColin Finck  * PROJECT:         System setup
4c2c66affSColin Finck  * FILE:            dll/win32/syssetup/wizard.c
5c2c66affSColin Finck  * PURPOSE:         GUI controls
6c2c66affSColin Finck  * PROGRAMMERS:     Eric Kohl
7c2c66affSColin Finck  *                  Pierre Schweitzer <heis_spiter@hotmail.com>
8c2c66affSColin Finck  *                  Ismael Ferreras Morezuelas <swyterzone+ros@gmail.com>
9612729b0SKatayama Hirofumi MZ  *                  Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
105d81de7dSOleg Dubinskiy  *                  Oleg Dubinskiy <oleg.dubinskij30@gmail.com>
11c2c66affSColin Finck  */
12c2c66affSColin Finck 
13c2c66affSColin Finck /* INCLUDES *****************************************************************/
14c2c66affSColin Finck 
15c2c66affSColin Finck #include "precomp.h"
16c2c66affSColin Finck 
17c2c66affSColin Finck #include <stdlib.h>
18c2c66affSColin Finck #include <time.h>
19c2c66affSColin Finck #include <winnls.h>
20c2c66affSColin Finck #include <windowsx.h>
21c2c66affSColin Finck #include <wincon.h>
22c2c66affSColin Finck #include <shlobj.h>
2345c8e4dcSJose Carlos Jesus #include <shlwapi.h>
247c3e96a2SHermès Bélusca-Maïto #include <tzlib.h>
25612729b0SKatayama Hirofumi MZ #include <strsafe.h>
267c3e96a2SHermès Bélusca-Maïto 
27c2c66affSColin Finck #define NDEBUG
28c2c66affSColin Finck #include <debug.h>
29c2c66affSColin Finck 
30c2c66affSColin Finck #define PM_REGISTRATION_NOTIFY (WM_APP + 1)
31c2c66affSColin Finck /* Private Message used to communicate progress from the background
32c2c66affSColin Finck    registration thread to the main thread.
33c2c66affSColin Finck    wParam = 0 Registration in progress
34c2c66affSColin Finck           = 1 Registration completed
35c2c66affSColin Finck    lParam = Pointer to a REGISTRATIONNOTIFY structure */
36c2c66affSColin Finck 
373f053db3SEric Kohl #define PM_ITEM_START (WM_APP + 2)
383f053db3SEric Kohl #define PM_ITEM_END   (WM_APP + 3)
393f053db3SEric Kohl #define PM_STEP_START (WM_APP + 4)
403f053db3SEric Kohl #define PM_STEP_END   (WM_APP + 5)
413f053db3SEric Kohl #define PM_ITEMS_DONE (WM_APP + 6)
423f053db3SEric Kohl 
43c2c66affSColin Finck typedef struct _REGISTRATIONNOTIFY
44c2c66affSColin Finck {
45c2c66affSColin Finck     ULONG Progress;
46c2c66affSColin Finck     UINT ActivityID;
47c2c66affSColin Finck     LPCWSTR CurrentItem;
48c2c66affSColin Finck     LPCWSTR ErrorMessage;
493f053db3SEric Kohl     UINT MessageID;
503f053db3SEric Kohl     DWORD LastError;
51c2c66affSColin Finck } REGISTRATIONNOTIFY, *PREGISTRATIONNOTIFY;
52c2c66affSColin Finck 
533f053db3SEric Kohl typedef struct _ITEMSDATA
543f053db3SEric Kohl {
553f053db3SEric Kohl     HWND hwndDlg;
563f053db3SEric Kohl } ITEMSDATA, *PITEMSDATA;
573f053db3SEric Kohl 
58c2c66affSColin Finck typedef struct _REGISTRATIONDATA
59c2c66affSColin Finck {
60c2c66affSColin Finck     HWND hwndDlg;
61c2c66affSColin Finck     ULONG DllCount;
62c2c66affSColin Finck     ULONG Registered;
63c2c66affSColin Finck     PVOID DefaultContext;
64c2c66affSColin Finck } REGISTRATIONDATA, *PREGISTRATIONDATA;
65c2c66affSColin Finck 
667c3e96a2SHermès Bélusca-Maïto typedef struct _TIMEZONE_ENTRY
677c3e96a2SHermès Bélusca-Maïto {
687c3e96a2SHermès Bélusca-Maïto     struct _TIMEZONE_ENTRY *Prev;
697c3e96a2SHermès Bélusca-Maïto     struct _TIMEZONE_ENTRY *Next;
707c3e96a2SHermès Bélusca-Maïto     WCHAR Description[128]; /* 'Display' */
717c3e96a2SHermès Bélusca-Maïto     WCHAR StandardName[32]; /* 'Std' */
727c3e96a2SHermès Bélusca-Maïto     WCHAR DaylightName[32]; /* 'Dlt' */
737c3e96a2SHermès Bélusca-Maïto     REG_TZI_FORMAT TimezoneInfo; /* 'TZI' */
747c3e96a2SHermès Bélusca-Maïto     ULONG Index;
757c3e96a2SHermès Bélusca-Maïto } TIMEZONE_ENTRY, *PTIMEZONE_ENTRY;
767c3e96a2SHermès Bélusca-Maïto 
77c2c66affSColin Finck 
78c2c66affSColin Finck /* FUNCTIONS ****************************************************************/
79c2c66affSColin Finck 
80c2c66affSColin Finck extern void WINAPI Control_RunDLLW(HWND hWnd, HINSTANCE hInst, LPCWSTR cmd, DWORD nCmdShow);
81c2c66affSColin Finck 
82c2c66affSColin Finck 
83c2c66affSColin Finck static VOID
CenterWindow(HWND hWnd)84c2c66affSColin Finck CenterWindow(HWND hWnd)
85c2c66affSColin Finck {
86c2c66affSColin Finck     HWND hWndParent;
87c2c66affSColin Finck     RECT rcParent;
88c2c66affSColin Finck     RECT rcWindow;
89c2c66affSColin Finck 
90c2c66affSColin Finck     hWndParent = GetParent(hWnd);
91c2c66affSColin Finck     if (hWndParent == NULL)
92c2c66affSColin Finck         hWndParent = GetDesktopWindow();
93c2c66affSColin Finck 
94c2c66affSColin Finck     GetWindowRect(hWndParent, &rcParent);
95c2c66affSColin Finck     GetWindowRect(hWnd, &rcWindow);
96c2c66affSColin Finck 
97c2c66affSColin Finck     SetWindowPos(hWnd,
98c2c66affSColin Finck                  HWND_TOP,
99c2c66affSColin Finck                  ((rcParent.right - rcParent.left) - (rcWindow.right - rcWindow.left)) / 2,
100c2c66affSColin Finck                  ((rcParent.bottom - rcParent.top) - (rcWindow.bottom - rcWindow.top)) / 2,
101c2c66affSColin Finck                  0,
102c2c66affSColin Finck                  0,
103c2c66affSColin Finck                  SWP_NOSIZE);
104c2c66affSColin Finck }
105c2c66affSColin Finck 
106c2c66affSColin Finck 
107c2c66affSColin Finck static HFONT
CreateTitleFont(VOID)108c2c66affSColin Finck CreateTitleFont(VOID)
109c2c66affSColin Finck {
110c2c66affSColin Finck     LOGFONTW LogFont = {0};
111c2c66affSColin Finck     HDC hdc;
112c2c66affSColin Finck     HFONT hFont;
113c2c66affSColin Finck 
1145972b1e2SKatayama Hirofumi MZ     LogFont.lfWeight = FW_BOLD;
115c2c66affSColin Finck     wcscpy(LogFont.lfFaceName, L"MS Shell Dlg");
116c2c66affSColin Finck 
117c2c66affSColin Finck     hdc = GetDC(NULL);
118c2c66affSColin Finck     LogFont.lfHeight = -MulDiv(12, GetDeviceCaps(hdc, LOGPIXELSY), 72);
119c2c66affSColin Finck 
120c2c66affSColin Finck     hFont = CreateFontIndirectW(&LogFont);
121c2c66affSColin Finck 
122c2c66affSColin Finck     ReleaseDC(NULL, hdc);
123c2c66affSColin Finck 
124c2c66affSColin Finck     return hFont;
125c2c66affSColin Finck }
126c2c66affSColin Finck 
127c2c66affSColin Finck 
128c2c66affSColin Finck static HFONT
CreateBoldFont(VOID)129c2c66affSColin Finck CreateBoldFont(VOID)
130c2c66affSColin Finck {
131c2c66affSColin Finck     LOGFONTW tmpFont = {0};
132c2c66affSColin Finck     HFONT hBoldFont;
133c2c66affSColin Finck     HDC hDc;
134c2c66affSColin Finck 
135c2c66affSColin Finck     /* Grabs the Drawing Context */
136c2c66affSColin Finck     hDc = GetDC(NULL);
137c2c66affSColin Finck 
138c2c66affSColin Finck     tmpFont.lfHeight = -MulDiv(8, GetDeviceCaps(hDc, LOGPIXELSY), 72);
139836e3107SKatayama Hirofumi MZ     tmpFont.lfWeight = FW_BOLD;
140c2c66affSColin Finck     wcscpy(tmpFont.lfFaceName, L"MS Shell Dlg");
141c2c66affSColin Finck 
142c2c66affSColin Finck     hBoldFont = CreateFontIndirectW(&tmpFont);
143c2c66affSColin Finck 
144c2c66affSColin Finck     ReleaseDC(NULL, hDc);
145c2c66affSColin Finck 
146c2c66affSColin Finck     return hBoldFont;
147c2c66affSColin Finck }
148c2c66affSColin Finck 
149c2c66affSColin Finck static INT_PTR CALLBACK
GplDlgProc(HWND hwndDlg,UINT uMsg,WPARAM wParam,LPARAM lParam)150c2c66affSColin Finck GplDlgProc(HWND hwndDlg,
151c2c66affSColin Finck            UINT uMsg,
152c2c66affSColin Finck            WPARAM wParam,
153c2c66affSColin Finck            LPARAM lParam)
154c2c66affSColin Finck {
155c2c66affSColin Finck     HRSRC GplTextResource;
156c2c66affSColin Finck     HGLOBAL GplTextMem;
157c2c66affSColin Finck     PVOID GplTextLocked;
158c2c66affSColin Finck     PCHAR GplText;
159c2c66affSColin Finck     DWORD Size;
160c2c66affSColin Finck 
161c2c66affSColin Finck 
162c2c66affSColin Finck     switch (uMsg)
163c2c66affSColin Finck     {
164c2c66affSColin Finck         case WM_INITDIALOG:
165c2c66affSColin Finck             GplTextResource = FindResourceW(hDllInstance, MAKEINTRESOURCE(IDR_GPL), L"RT_TEXT");
166c2c66affSColin Finck             if (NULL == GplTextResource)
167c2c66affSColin Finck             {
168c2c66affSColin Finck                 break;
169c2c66affSColin Finck             }
170c2c66affSColin Finck             Size = SizeofResource(hDllInstance, GplTextResource);
171c2c66affSColin Finck             if (0 == Size)
172c2c66affSColin Finck             {
173c2c66affSColin Finck                 break;
174c2c66affSColin Finck             }
175c2c66affSColin Finck             GplText = HeapAlloc(GetProcessHeap(), 0, Size + 1);
176c2c66affSColin Finck             if (NULL == GplText)
177c2c66affSColin Finck             {
178c2c66affSColin Finck                 break;
179c2c66affSColin Finck             }
180c2c66affSColin Finck             GplTextMem = LoadResource(hDllInstance, GplTextResource);
181c2c66affSColin Finck             if (NULL == GplTextMem)
182c2c66affSColin Finck             {
183c2c66affSColin Finck                 HeapFree(GetProcessHeap(), 0, GplText);
184c2c66affSColin Finck                 break;
185c2c66affSColin Finck             }
186c2c66affSColin Finck             GplTextLocked = LockResource(GplTextMem);
187c2c66affSColin Finck             if (NULL == GplTextLocked)
188c2c66affSColin Finck             {
189c2c66affSColin Finck                 HeapFree(GetProcessHeap(), 0, GplText);
190c2c66affSColin Finck                 break;
191c2c66affSColin Finck             }
192c2c66affSColin Finck             memcpy(GplText, GplTextLocked, Size);
193c2c66affSColin Finck             GplText[Size] = '\0';
194c2c66affSColin Finck             SendMessageA(GetDlgItem(hwndDlg, IDC_GPL_TEXT), WM_SETTEXT, 0, (LPARAM) GplText);
195c2c66affSColin Finck             HeapFree(GetProcessHeap(), 0, GplText);
196c2c66affSColin Finck             SetFocus(GetDlgItem(hwndDlg, IDOK));
197c2c66affSColin Finck             return FALSE;
198c2c66affSColin Finck 
199c2c66affSColin Finck         case WM_CLOSE:
200c2c66affSColin Finck             EndDialog(hwndDlg, IDCANCEL);
201c2c66affSColin Finck             break;
202c2c66affSColin Finck 
203c2c66affSColin Finck         case WM_COMMAND:
204c2c66affSColin Finck             if (HIWORD(wParam) == BN_CLICKED && IDOK == LOWORD(wParam))
205c2c66affSColin Finck             {
206c2c66affSColin Finck                 EndDialog(hwndDlg, IDOK);
207c2c66affSColin Finck             }
208c2c66affSColin Finck             break;
209c2c66affSColin Finck 
210c2c66affSColin Finck         default:
211c2c66affSColin Finck             break;
212c2c66affSColin Finck     }
213c2c66affSColin Finck 
214c2c66affSColin Finck     return FALSE;
215c2c66affSColin Finck }
216c2c66affSColin Finck 
217c2c66affSColin Finck 
218c2c66affSColin Finck static INT_PTR CALLBACK
WelcomeDlgProc(HWND hwndDlg,UINT uMsg,WPARAM wParam,LPARAM lParam)219c2c66affSColin Finck WelcomeDlgProc(HWND hwndDlg,
220c2c66affSColin Finck                UINT uMsg,
221c2c66affSColin Finck                WPARAM wParam,
222c2c66affSColin Finck                LPARAM lParam)
223c2c66affSColin Finck {
224c2c66affSColin Finck     PSETUPDATA pSetupData;
225c2c66affSColin Finck 
226c2c66affSColin Finck     pSetupData = (PSETUPDATA)GetWindowLongPtr(hwndDlg, DWLP_USER);
227c2c66affSColin Finck 
228c2c66affSColin Finck     switch (uMsg)
229c2c66affSColin Finck     {
230c2c66affSColin Finck         case WM_INITDIALOG:
231c2c66affSColin Finck         {
232c2c66affSColin Finck             HWND hwndControl;
233c2c66affSColin Finck             DWORD dwStyle;
234c2c66affSColin Finck 
235c2c66affSColin Finck             /* Get pointer to the global setup data */
236c2c66affSColin Finck             pSetupData = (PSETUPDATA)((LPPROPSHEETPAGE)lParam)->lParam;
237c2c66affSColin Finck             SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pSetupData);
238c2c66affSColin Finck 
239c2c66affSColin Finck             hwndControl = GetParent(hwndDlg);
240c2c66affSColin Finck 
241c2c66affSColin Finck             /* Center the wizard window */
242c2c66affSColin Finck             CenterWindow (hwndControl);
243c2c66affSColin Finck 
244c2c66affSColin Finck             /* Hide the system menu */
245c2c66affSColin Finck             dwStyle = GetWindowLongPtr(hwndControl, GWL_STYLE);
246c2c66affSColin Finck             SetWindowLongPtr(hwndControl, GWL_STYLE, dwStyle & ~WS_SYSMENU);
247c2c66affSColin Finck 
248c2c66affSColin Finck             /* Hide and disable the 'Cancel' button */
249c2c66affSColin Finck             hwndControl = GetDlgItem(GetParent(hwndDlg), IDCANCEL);
250c2c66affSColin Finck             ShowWindow (hwndControl, SW_HIDE);
251c2c66affSColin Finck             EnableWindow (hwndControl, FALSE);
252c2c66affSColin Finck 
253c2c66affSColin Finck             /* Set title font */
254c2c66affSColin Finck             SendDlgItemMessage(hwndDlg,
255c2c66affSColin Finck                                IDC_WELCOMETITLE,
256c2c66affSColin Finck                                WM_SETFONT,
257c2c66affSColin Finck                                (WPARAM)pSetupData->hTitleFont,
258c2c66affSColin Finck                                (LPARAM)TRUE);
259c2c66affSColin Finck         }
260c2c66affSColin Finck         break;
261c2c66affSColin Finck 
262c2c66affSColin Finck 
263c2c66affSColin Finck         case WM_NOTIFY:
264c2c66affSColin Finck         {
265c2c66affSColin Finck             LPNMHDR lpnm = (LPNMHDR)lParam;
266c2c66affSColin Finck 
267c2c66affSColin Finck             switch (lpnm->code)
268c2c66affSColin Finck             {
269c2c66affSColin Finck                 case PSN_SETACTIVE:
270c2c66affSColin Finck                     LogItem(L"BEGIN", L"WelcomePage");
271c2c66affSColin Finck                     /* Enable the Next button */
272c2c66affSColin Finck                     PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT);
273c2c66affSColin Finck                     if (pSetupData->UnattendSetup)
274c2c66affSColin Finck                     {
2750182dcd7STimo Kreuzer                         SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_ACKPAGE);
276c2c66affSColin Finck                         return TRUE;
277c2c66affSColin Finck                     }
278c2c66affSColin Finck                     break;
279c2c66affSColin Finck 
280c2c66affSColin Finck                 case PSN_WIZNEXT:
281c2c66affSColin Finck                     LogItem(L"END", L"WelcomePage");
282c2c66affSColin Finck                     break;
283c2c66affSColin Finck 
284c2c66affSColin Finck                 case PSN_WIZBACK:
285c2c66affSColin Finck                     pSetupData->UnattendSetup = FALSE;
286c2c66affSColin Finck                     break;
287c2c66affSColin Finck 
288c2c66affSColin Finck                 default:
289c2c66affSColin Finck                     break;
290c2c66affSColin Finck             }
291c2c66affSColin Finck         }
292c2c66affSColin Finck         break;
293c2c66affSColin Finck 
294c2c66affSColin Finck         default:
295c2c66affSColin Finck             break;
296c2c66affSColin Finck     }
297c2c66affSColin Finck 
298c2c66affSColin Finck     return FALSE;
299c2c66affSColin Finck }
300c2c66affSColin Finck 
301c2c66affSColin Finck 
302c2c66affSColin Finck static INT_PTR CALLBACK
AckPageDlgProc(HWND hwndDlg,UINT uMsg,WPARAM wParam,LPARAM lParam)303c2c66affSColin Finck AckPageDlgProc(HWND hwndDlg,
304c2c66affSColin Finck                UINT uMsg,
305c2c66affSColin Finck                WPARAM wParam,
306c2c66affSColin Finck                LPARAM lParam)
307c2c66affSColin Finck {
308c2c66affSColin Finck     LPNMHDR lpnm;
309c2c66affSColin Finck     PWCHAR Projects;
310c2c66affSColin Finck     PWCHAR End, CurrentProject;
311c2c66affSColin Finck     INT ProjectsSize, ProjectsCount;
312c2c66affSColin Finck     PSETUPDATA pSetupData;
313c2c66affSColin Finck 
314c2c66affSColin Finck     pSetupData = (PSETUPDATA)GetWindowLongPtr(hwndDlg, DWLP_USER);
315c2c66affSColin Finck 
316c2c66affSColin Finck     switch (uMsg)
317c2c66affSColin Finck     {
318c2c66affSColin Finck         case WM_INITDIALOG:
319c2c66affSColin Finck         {
320c2c66affSColin Finck             pSetupData = (PSETUPDATA)((LPPROPSHEETPAGE)lParam)->lParam;
321c2c66affSColin Finck             SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pSetupData);
322c2c66affSColin Finck 
323c2c66affSColin Finck             Projects = NULL;
324c2c66affSColin Finck             ProjectsSize = 256;
325e9893906SHermès Bélusca-Maïto             while (TRUE)
326c2c66affSColin Finck             {
327c2c66affSColin Finck                 Projects = HeapAlloc(GetProcessHeap(), 0, ProjectsSize * sizeof(WCHAR));
328c2c66affSColin Finck                 if (NULL == Projects)
329c2c66affSColin Finck                 {
330c2c66affSColin Finck                     return FALSE;
331c2c66affSColin Finck                 }
332c2c66affSColin Finck                 ProjectsCount =  LoadStringW(hDllInstance, IDS_ACKPROJECTS, Projects, ProjectsSize);
333c2c66affSColin Finck                 if (0 == ProjectsCount)
334c2c66affSColin Finck                 {
335c2c66affSColin Finck                     HeapFree(GetProcessHeap(), 0, Projects);
336c2c66affSColin Finck                     return FALSE;
337c2c66affSColin Finck                 }
338c2c66affSColin Finck                 if (ProjectsCount < ProjectsSize - 1)
339c2c66affSColin Finck                 {
340c2c66affSColin Finck                     break;
341c2c66affSColin Finck                 }
342c2c66affSColin Finck                 HeapFree(GetProcessHeap(), 0, Projects);
343c2c66affSColin Finck                 ProjectsSize *= 2;
344c2c66affSColin Finck             }
345e9893906SHermès Bélusca-Maïto 
346c2c66affSColin Finck             CurrentProject = Projects;
347e9893906SHermès Bélusca-Maïto             while (*CurrentProject != L'\0')
348c2c66affSColin Finck             {
349c2c66affSColin Finck                 End = wcschr(CurrentProject, L'\n');
350c2c66affSColin Finck                 if (NULL != End)
351c2c66affSColin Finck                 {
352c2c66affSColin Finck                     *End = L'\0';
353c2c66affSColin Finck                 }
354c2c66affSColin Finck                 (void)ListBox_AddString(GetDlgItem(hwndDlg, IDC_PROJECTS), CurrentProject);
355c2c66affSColin Finck                 if (NULL != End)
356c2c66affSColin Finck                 {
357c2c66affSColin Finck                     CurrentProject = End + 1;
358c2c66affSColin Finck                 }
359c2c66affSColin Finck                 else
360c2c66affSColin Finck                 {
361c2c66affSColin Finck                     CurrentProject += wcslen(CurrentProject);
362c2c66affSColin Finck                 }
363c2c66affSColin Finck             }
364c2c66affSColin Finck             HeapFree(GetProcessHeap(), 0, Projects);
365c2c66affSColin Finck         }
366c2c66affSColin Finck         break;
367c2c66affSColin Finck 
368c2c66affSColin Finck         case WM_COMMAND:
369c2c66affSColin Finck             if (HIWORD(wParam) == BN_CLICKED && IDC_VIEWGPL == LOWORD(wParam))
370c2c66affSColin Finck             {
371c2c66affSColin Finck                 DialogBox(hDllInstance, MAKEINTRESOURCE(IDD_GPL), NULL, GplDlgProc);
372c2c66affSColin Finck                 SetForegroundWindow(GetParent(hwndDlg));
373c2c66affSColin Finck             }
374c2c66affSColin Finck             break;
375c2c66affSColin Finck 
376c2c66affSColin Finck         case WM_NOTIFY:
377c2c66affSColin Finck         {
378c2c66affSColin Finck             lpnm = (LPNMHDR)lParam;
379c2c66affSColin Finck 
380c2c66affSColin Finck             switch (lpnm->code)
381c2c66affSColin Finck             {
382c2c66affSColin Finck                 case PSN_SETACTIVE:
383c2c66affSColin Finck                     /* Enable the Back and Next buttons */
384c2c66affSColin Finck                     PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK | PSWIZB_NEXT);
385c2c66affSColin Finck                     if (pSetupData->UnattendSetup)
386c2c66affSColin Finck                     {
38748160c74SKatayama Hirofumi MZ                         SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_PRODUCT);
38848160c74SKatayama Hirofumi MZ                         return TRUE;
38948160c74SKatayama Hirofumi MZ                     }
39048160c74SKatayama Hirofumi MZ                     break;
39148160c74SKatayama Hirofumi MZ 
39248160c74SKatayama Hirofumi MZ                 case PSN_WIZBACK:
39348160c74SKatayama Hirofumi MZ                     pSetupData->UnattendSetup = FALSE;
39448160c74SKatayama Hirofumi MZ                     break;
39548160c74SKatayama Hirofumi MZ 
39648160c74SKatayama Hirofumi MZ                 default:
39748160c74SKatayama Hirofumi MZ                     break;
39848160c74SKatayama Hirofumi MZ             }
39948160c74SKatayama Hirofumi MZ         }
40048160c74SKatayama Hirofumi MZ         break;
40148160c74SKatayama Hirofumi MZ 
40248160c74SKatayama Hirofumi MZ         default:
40348160c74SKatayama Hirofumi MZ             break;
40448160c74SKatayama Hirofumi MZ     }
40548160c74SKatayama Hirofumi MZ 
40648160c74SKatayama Hirofumi MZ     return FALSE;
40748160c74SKatayama Hirofumi MZ }
40848160c74SKatayama Hirofumi MZ 
409612729b0SKatayama Hirofumi MZ static const WCHAR s_szProductOptions[] = L"SYSTEM\\CurrentControlSet\\Control\\ProductOptions";
410612729b0SKatayama Hirofumi MZ static const WCHAR s_szRosVersion[] = L"SYSTEM\\CurrentControlSet\\Control\\ReactOS\\Settings\\Version";
411612729b0SKatayama Hirofumi MZ static const WCHAR s_szControlWindows[] = L"SYSTEM\\CurrentControlSet\\Control\\Windows";
4122edcb58eSVladimir Barinov static const WCHAR s_szWinlogon[] = L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon";
413cbf8b367SOleg Dubinskiy static const WCHAR s_szDefaultSoundEvents[] = L"AppEvents\\Schemes\\Apps\\.Default";
414cbf8b367SOleg Dubinskiy static const WCHAR s_szExplorerSoundEvents[] = L"AppEvents\\Schemes\\Apps\\Explorer";
415612729b0SKatayama Hirofumi MZ 
416ef6711c9SSerge Gautherie typedef struct _PRODUCT_OPTION_DATA
417612729b0SKatayama Hirofumi MZ {
418612729b0SKatayama Hirofumi MZ     LPCWSTR ProductSuite;
419612729b0SKatayama Hirofumi MZ     LPCWSTR ProductType;
420612729b0SKatayama Hirofumi MZ     DWORD ReportAsWorkstation;
421612729b0SKatayama Hirofumi MZ     DWORD CSDVersion;
4222edcb58eSVladimir Barinov     DWORD LogonType;
423ef6711c9SSerge Gautherie } PRODUCT_OPTION_DATA;
424612729b0SKatayama Hirofumi MZ 
425612729b0SKatayama Hirofumi MZ static const PRODUCT_OPTION_DATA s_ProductOptionData[] =
426612729b0SKatayama Hirofumi MZ {
4272edcb58eSVladimir Barinov     { L"Terminal Server\0", L"ServerNT", 0, 0x200, 0 },
4282edcb58eSVladimir Barinov     { L"\0", L"WinNT", 1, 0x300, 1 }
429612729b0SKatayama Hirofumi MZ };
430612729b0SKatayama Hirofumi MZ 
431cbf8b367SOleg Dubinskiy static const WCHAR* s_DefaultSoundEvents[][2] =
432cbf8b367SOleg Dubinskiy {
433cbf8b367SOleg Dubinskiy     { L".Default", L"%SystemRoot%\\Media\\ReactOS_Default.wav" },
434cbf8b367SOleg Dubinskiy     { L"AppGPFault", L"" },
435cbf8b367SOleg Dubinskiy     { L"Close", L"" },
436cbf8b367SOleg Dubinskiy     { L"CriticalBatteryAlarm", L"%SystemRoot%\\Media\\ReactOS_Battery_Critical.wav" },
437cbf8b367SOleg Dubinskiy     { L"DeviceConnect",  L"%SystemRoot%\\Media\\ReactOS_Hardware_Insert.wav" },
438cbf8b367SOleg Dubinskiy     { L"DeviceDisconnect", L"%SystemRoot%\\Media\\ReactOS_Hardware_Remove.wav" },
439cbf8b367SOleg Dubinskiy     { L"DeviceFail", L"%SystemRoot%\\Media\\ReactOS_Hardware_Fail.wav" },
440cbf8b367SOleg Dubinskiy     { L"LowBatteryAlarm", L"%SystemRoot%\\Media\\ReactOS_Battery_Low.wav" },
441cbf8b367SOleg Dubinskiy     { L"MailBeep", L"%SystemRoot%\\Media\\ReactOS_Notify.wav" },
442cbf8b367SOleg Dubinskiy     { L"Maximize", L"%SystemRoot%\\Media\\ReactOS_Restore.wav" },
443cbf8b367SOleg Dubinskiy     { L"MenuCommand", L"%SystemRoot%\\Media\\ReactOS_Menu_Command.wav" },
444cbf8b367SOleg Dubinskiy     { L"MenuPopup", L"" },
445cbf8b367SOleg Dubinskiy     { L"Minimize", L"%SystemRoot%\\Media\\ReactOS_Minimize.wav" },
446cbf8b367SOleg Dubinskiy     { L"Open", L"" },
447cbf8b367SOleg Dubinskiy     { L"PrintComplete", L"%SystemRoot%\\Media\\ReactOS_Print_Complete.wav" },
448cbf8b367SOleg Dubinskiy     { L"RestoreDown", L"" },
449cbf8b367SOleg Dubinskiy     { L"RestoreUp", L"" },
450cbf8b367SOleg Dubinskiy     { L"SystemAsterisk", L"%SystemRoot%\\Media\\ReactOS_Ding.wav" },
451cbf8b367SOleg Dubinskiy     { L"SystemExclamation", L"%SystemRoot%\\Media\\ReactOS_Exclamation.wav" },
452cbf8b367SOleg Dubinskiy     { L"SystemExit", L"%SystemRoot%\\Media\\ReactOS_Shutdown.wav" },
453cbf8b367SOleg Dubinskiy     { L"SystemHand", L"%SystemRoot%\\Media\\ReactOS_Critical_Stop.wav" },
454cbf8b367SOleg Dubinskiy     { L"SystemNotification", L"%SystemRoot%\\Media\\ReactOS_Balloon.wav" },
455cbf8b367SOleg Dubinskiy     { L"SystemQuestion", L"%SystemRoot%\\Media\\ReactOS_Ding.wav" },
456cbf8b367SOleg Dubinskiy     { L"SystemStart", L"%SystemRoot%\\Media\\ReactOS_Startup.wav" },
457cbf8b367SOleg Dubinskiy     { L"WindowsLogoff", L"%SystemRoot%\\Media\\ReactOS_LogOff.wav" }
458cbf8b367SOleg Dubinskiy /* Logon sound is already set by default for both Server and Workstation */
459cbf8b367SOleg Dubinskiy };
460cbf8b367SOleg Dubinskiy 
461cbf8b367SOleg Dubinskiy static const WCHAR* s_ExplorerSoundEvents[][2] =
462cbf8b367SOleg Dubinskiy {
463cbf8b367SOleg Dubinskiy     { L"EmptyRecycleBin", L"%SystemRoot%\\Media\\ReactOS_Recycle.wav" },
464cbf8b367SOleg Dubinskiy     { L"Navigating", L"%SystemRoot%\\Media\\ReactOS_Start.wav" }
465cbf8b367SOleg Dubinskiy };
466cbf8b367SOleg Dubinskiy 
467cbf8b367SOleg Dubinskiy static BOOL
DoWriteSoundEvents(HKEY hKey,LPCWSTR lpSubkey,LPCWSTR lpEventsArray[][2],DWORD dwSize)468cbf8b367SOleg Dubinskiy DoWriteSoundEvents(HKEY hKey,
469cbf8b367SOleg Dubinskiy                    LPCWSTR lpSubkey,
470cbf8b367SOleg Dubinskiy                    LPCWSTR lpEventsArray[][2],
471cbf8b367SOleg Dubinskiy                    DWORD dwSize)
472cbf8b367SOleg Dubinskiy {
473cbf8b367SOleg Dubinskiy     HKEY hRootKey, hEventKey, hDefaultKey;
474cbf8b367SOleg Dubinskiy     LONG error;
475cbf8b367SOleg Dubinskiy     ULONG i;
476cbf8b367SOleg Dubinskiy     WCHAR szDest[MAX_PATH];
477cbf8b367SOleg Dubinskiy     DWORD dwAttribs;
478cbf8b367SOleg Dubinskiy     DWORD cbData;
479cbf8b367SOleg Dubinskiy 
480cbf8b367SOleg Dubinskiy     /* Open the sound events key */
481cbf8b367SOleg Dubinskiy     error = RegOpenKeyExW(hKey, lpSubkey, 0, KEY_READ, &hRootKey);
482cbf8b367SOleg Dubinskiy     if (error)
483cbf8b367SOleg Dubinskiy     {
484cbf8b367SOleg Dubinskiy         DPRINT1("RegOpenKeyExW failed\n");
485cbf8b367SOleg Dubinskiy         goto Error;
486cbf8b367SOleg Dubinskiy     }
487cbf8b367SOleg Dubinskiy 
488cbf8b367SOleg Dubinskiy     /* Set each sound event */
489cbf8b367SOleg Dubinskiy     for (i = 0; i < dwSize; i++)
490cbf8b367SOleg Dubinskiy     {
491cbf8b367SOleg Dubinskiy         /*
492cbf8b367SOleg Dubinskiy          * Verify that the sound file exists and is an actual file.
493cbf8b367SOleg Dubinskiy          */
494cbf8b367SOleg Dubinskiy 
495cbf8b367SOleg Dubinskiy         /* Expand the sound file path */
496cbf8b367SOleg Dubinskiy         if (!ExpandEnvironmentStringsW(lpEventsArray[i][1], szDest, _countof(szDest)))
497cbf8b367SOleg Dubinskiy         {
498cbf8b367SOleg Dubinskiy             /* Failed to expand, continue with the next sound event */
499cbf8b367SOleg Dubinskiy             continue;
500cbf8b367SOleg Dubinskiy         }
501cbf8b367SOleg Dubinskiy 
502cbf8b367SOleg Dubinskiy         /* Check if the sound file exists and isn't a directory */
503cbf8b367SOleg Dubinskiy         dwAttribs = GetFileAttributesW(szDest);
504cbf8b367SOleg Dubinskiy         if ((dwAttribs == INVALID_FILE_ATTRIBUTES) ||
505cbf8b367SOleg Dubinskiy             (dwAttribs & FILE_ATTRIBUTE_DIRECTORY))
506cbf8b367SOleg Dubinskiy         {
507cbf8b367SOleg Dubinskiy             /* It does not, just continue with the next sound event */
508cbf8b367SOleg Dubinskiy             continue;
509cbf8b367SOleg Dubinskiy         }
510cbf8b367SOleg Dubinskiy 
511cbf8b367SOleg Dubinskiy         /*
512cbf8b367SOleg Dubinskiy          * Create the sound event entry.
513cbf8b367SOleg Dubinskiy          */
514cbf8b367SOleg Dubinskiy 
515cbf8b367SOleg Dubinskiy         /* Open the sound event subkey */
516cbf8b367SOleg Dubinskiy         error = RegOpenKeyExW(hRootKey, lpEventsArray[i][0], 0, KEY_READ, &hEventKey);
517cbf8b367SOleg Dubinskiy         if (error)
518cbf8b367SOleg Dubinskiy         {
519cbf8b367SOleg Dubinskiy             /* Failed to open, continue with next sound event */
520cbf8b367SOleg Dubinskiy             continue;
521cbf8b367SOleg Dubinskiy         }
522cbf8b367SOleg Dubinskiy 
523cbf8b367SOleg Dubinskiy         /* Open .Default subkey */
524cbf8b367SOleg Dubinskiy         error = RegOpenKeyExW(hEventKey, L".Default", 0, KEY_WRITE, &hDefaultKey);
525cbf8b367SOleg Dubinskiy         RegCloseKey(hEventKey);
526cbf8b367SOleg Dubinskiy         if (error)
527cbf8b367SOleg Dubinskiy         {
528cbf8b367SOleg Dubinskiy             /* Failed to open, continue with next sound event */
529cbf8b367SOleg Dubinskiy             continue;
530cbf8b367SOleg Dubinskiy         }
531cbf8b367SOleg Dubinskiy 
532cbf8b367SOleg Dubinskiy         /* Associate the sound file to this sound event */
533cbf8b367SOleg Dubinskiy         cbData = (lstrlenW(lpEventsArray[i][1]) + 1) * sizeof(WCHAR);
534cbf8b367SOleg Dubinskiy         error = RegSetValueExW(hDefaultKey, NULL, 0, REG_EXPAND_SZ, (const BYTE *)lpEventsArray[i][1], cbData);
535cbf8b367SOleg Dubinskiy         RegCloseKey(hDefaultKey);
536cbf8b367SOleg Dubinskiy         if (error)
537cbf8b367SOleg Dubinskiy         {
538cbf8b367SOleg Dubinskiy             /* Failed to set the value, continue with next sound event */
539cbf8b367SOleg Dubinskiy             continue;
540cbf8b367SOleg Dubinskiy         }
541cbf8b367SOleg Dubinskiy     }
542cbf8b367SOleg Dubinskiy 
543cbf8b367SOleg Dubinskiy Error:
544cbf8b367SOleg Dubinskiy     if (hRootKey)
545cbf8b367SOleg Dubinskiy         RegCloseKey(hRootKey);
546cbf8b367SOleg Dubinskiy 
547cbf8b367SOleg Dubinskiy     return error == ERROR_SUCCESS;
548cbf8b367SOleg Dubinskiy }
549cbf8b367SOleg Dubinskiy 
55048160c74SKatayama Hirofumi MZ static BOOL
DoWriteProductOption(PRODUCT_OPTION nOption)55148160c74SKatayama Hirofumi MZ DoWriteProductOption(PRODUCT_OPTION nOption)
55248160c74SKatayama Hirofumi MZ {
55348160c74SKatayama Hirofumi MZ     HKEY hKey;
55448160c74SKatayama Hirofumi MZ     LONG error;
555612729b0SKatayama Hirofumi MZ     LPCWSTR pszData;
556612729b0SKatayama Hirofumi MZ     DWORD dwValue, cbData;
557612729b0SKatayama Hirofumi MZ     const PRODUCT_OPTION_DATA *pData = &s_ProductOptionData[nOption];
558612729b0SKatayama Hirofumi MZ     ASSERT(0 <= nOption && nOption < _countof(s_ProductOptionData));
55948160c74SKatayama Hirofumi MZ 
560612729b0SKatayama Hirofumi MZ     /* open ProductOptions key */
56148160c74SKatayama Hirofumi MZ     error = RegOpenKeyExW(HKEY_LOCAL_MACHINE, s_szProductOptions, 0, KEY_WRITE, &hKey);
56248160c74SKatayama Hirofumi MZ     if (error)
56348160c74SKatayama Hirofumi MZ     {
564612729b0SKatayama Hirofumi MZ         DPRINT1("RegOpenKeyExW failed\n");
565612729b0SKatayama Hirofumi MZ         goto Error;
566612729b0SKatayama Hirofumi MZ     }
567612729b0SKatayama Hirofumi MZ 
56848160c74SKatayama Hirofumi MZ     /* write ProductSuite */
569612729b0SKatayama Hirofumi MZ     pszData = pData->ProductSuite;
570612729b0SKatayama Hirofumi MZ     cbData = (lstrlenW(pszData) + 2) * sizeof(WCHAR);
571ef6711c9SSerge Gautherie     error = RegSetValueExW(hKey, L"ProductSuite", 0, REG_MULTI_SZ, (const BYTE *)pszData, cbData);
57248160c74SKatayama Hirofumi MZ     if (error)
573612729b0SKatayama Hirofumi MZ     {
574612729b0SKatayama Hirofumi MZ         DPRINT1("RegSetValueExW failed\n");
575612729b0SKatayama Hirofumi MZ         goto Error;
576612729b0SKatayama Hirofumi MZ     }
57748160c74SKatayama Hirofumi MZ 
57848160c74SKatayama Hirofumi MZ     /* write ProductType */
579612729b0SKatayama Hirofumi MZ     pszData = pData->ProductType;
580612729b0SKatayama Hirofumi MZ     cbData = (lstrlenW(pszData) + 1) * sizeof(WCHAR);
581ef6711c9SSerge Gautherie     error = RegSetValueExW(hKey, L"ProductType", 0, REG_SZ, (const BYTE *)pszData, cbData);
58248160c74SKatayama Hirofumi MZ     if (error)
583612729b0SKatayama Hirofumi MZ     {
584612729b0SKatayama Hirofumi MZ         DPRINT1("RegSetValueExW failed\n");
585612729b0SKatayama Hirofumi MZ         goto Error;
58648160c74SKatayama Hirofumi MZ     }
58748160c74SKatayama Hirofumi MZ 
58848160c74SKatayama Hirofumi MZ     RegCloseKey(hKey);
5890a7a747dSKatayama Hirofumi MZ 
590612729b0SKatayama Hirofumi MZ     /* open ReactOS version key */
5910a7a747dSKatayama Hirofumi MZ     error = RegOpenKeyExW(HKEY_LOCAL_MACHINE, s_szRosVersion, 0, KEY_WRITE, &hKey);
5920a7a747dSKatayama Hirofumi MZ     if (error)
593612729b0SKatayama Hirofumi MZ     {
594612729b0SKatayama Hirofumi MZ         DPRINT1("RegOpenKeyExW failed\n");
595612729b0SKatayama Hirofumi MZ         goto Error;
596612729b0SKatayama Hirofumi MZ     }
5970a7a747dSKatayama Hirofumi MZ 
598612729b0SKatayama Hirofumi MZ     /* write ReportAsWorkstation */
599612729b0SKatayama Hirofumi MZ     dwValue = pData->ReportAsWorkstation;
6000a7a747dSKatayama Hirofumi MZ     cbData = sizeof(dwValue);
601612729b0SKatayama Hirofumi MZ     error = RegSetValueExW(hKey, L"ReportAsWorkstation", 0, REG_DWORD, (const BYTE *)&dwValue, cbData);
602612729b0SKatayama Hirofumi MZ     if (error)
603612729b0SKatayama Hirofumi MZ     {
604612729b0SKatayama Hirofumi MZ         DPRINT1("RegSetValueExW failed\n");
605612729b0SKatayama Hirofumi MZ         goto Error;
606612729b0SKatayama Hirofumi MZ     }
6070a7a747dSKatayama Hirofumi MZ 
6080a7a747dSKatayama Hirofumi MZ     RegCloseKey(hKey);
6090a7a747dSKatayama Hirofumi MZ 
610612729b0SKatayama Hirofumi MZ     /* open Control Windows key */
611612729b0SKatayama Hirofumi MZ     error = RegOpenKeyExW(HKEY_LOCAL_MACHINE, s_szControlWindows, 0, KEY_WRITE, &hKey);
612612729b0SKatayama Hirofumi MZ     if (error)
613612729b0SKatayama Hirofumi MZ     {
614612729b0SKatayama Hirofumi MZ         DPRINT1("RegOpenKeyExW failed\n");
615612729b0SKatayama Hirofumi MZ         goto Error;
616612729b0SKatayama Hirofumi MZ     }
617612729b0SKatayama Hirofumi MZ 
618612729b0SKatayama Hirofumi MZ     /* write Control Windows CSDVersion */
619612729b0SKatayama Hirofumi MZ     dwValue = pData->CSDVersion;
620612729b0SKatayama Hirofumi MZ     cbData = sizeof(dwValue);
621612729b0SKatayama Hirofumi MZ     error = RegSetValueExW(hKey, L"CSDVersion", 0, REG_DWORD, (const BYTE *)&dwValue, cbData);
622612729b0SKatayama Hirofumi MZ     if (error)
623612729b0SKatayama Hirofumi MZ     {
624612729b0SKatayama Hirofumi MZ         DPRINT1("RegSetValueExW failed\n");
625612729b0SKatayama Hirofumi MZ         goto Error;
626612729b0SKatayama Hirofumi MZ     }
627612729b0SKatayama Hirofumi MZ 
6282edcb58eSVladimir Barinov     RegCloseKey(hKey);
6292edcb58eSVladimir Barinov 
6302edcb58eSVladimir Barinov     /* open Winlogon key */
6312edcb58eSVladimir Barinov     error = RegOpenKeyExW(HKEY_LOCAL_MACHINE, s_szWinlogon, 0, KEY_WRITE, &hKey);
6322edcb58eSVladimir Barinov     if (error)
6332edcb58eSVladimir Barinov     {
6342edcb58eSVladimir Barinov         DPRINT1("RegOpenKeyExW failed\n");
6352edcb58eSVladimir Barinov         goto Error;
6362edcb58eSVladimir Barinov     }
6372edcb58eSVladimir Barinov 
6382edcb58eSVladimir Barinov     /* write LogonType */
6392edcb58eSVladimir Barinov     dwValue = pData->LogonType;
6402edcb58eSVladimir Barinov     cbData = sizeof(dwValue);
6412edcb58eSVladimir Barinov     error = RegSetValueExW(hKey, L"LogonType", 0, REG_DWORD, (const BYTE *)&dwValue, cbData);
6422edcb58eSVladimir Barinov     if (error)
6432edcb58eSVladimir Barinov     {
6442edcb58eSVladimir Barinov         DPRINT1("RegSetValueExW failed\n");
6452edcb58eSVladimir Barinov         goto Error;
6462edcb58eSVladimir Barinov     }
6472edcb58eSVladimir Barinov 
648cbf8b367SOleg Dubinskiy     if (nOption == PRODUCT_OPTION_WORKSTATION)
649cbf8b367SOleg Dubinskiy     {
650cbf8b367SOleg Dubinskiy         /* Write system sound events values for Workstation */
651cbf8b367SOleg Dubinskiy         DoWriteSoundEvents(HKEY_CURRENT_USER, s_szDefaultSoundEvents, s_DefaultSoundEvents, _countof(s_DefaultSoundEvents));
652cbf8b367SOleg Dubinskiy         DoWriteSoundEvents(HKEY_CURRENT_USER, s_szExplorerSoundEvents, s_ExplorerSoundEvents, _countof(s_ExplorerSoundEvents));
653cbf8b367SOleg Dubinskiy     }
654cbf8b367SOleg Dubinskiy 
655612729b0SKatayama Hirofumi MZ Error:
656612729b0SKatayama Hirofumi MZ     if (hKey)
657612729b0SKatayama Hirofumi MZ         RegCloseKey(hKey);
658612729b0SKatayama Hirofumi MZ 
65948160c74SKatayama Hirofumi MZ     return error == ERROR_SUCCESS;
66048160c74SKatayama Hirofumi MZ }
66148160c74SKatayama Hirofumi MZ 
66248160c74SKatayama Hirofumi MZ static void
OnChooseOption(HWND hwndDlg,PRODUCT_OPTION nOption)663612729b0SKatayama Hirofumi MZ OnChooseOption(HWND hwndDlg, PRODUCT_OPTION nOption)
66448160c74SKatayama Hirofumi MZ {
66548160c74SKatayama Hirofumi MZ     WCHAR szText[256];
666612729b0SKatayama Hirofumi MZ     ASSERT(0 <= nOption && nOption < _countof(s_ProductOptionData));
66748160c74SKatayama Hirofumi MZ 
668612729b0SKatayama Hirofumi MZ     switch (nOption)
669612729b0SKatayama Hirofumi MZ     {
670612729b0SKatayama Hirofumi MZ         case PRODUCT_OPTION_SERVER:
67148160c74SKatayama Hirofumi MZ             LoadStringW(hDllInstance, IDS_PRODUCTSERVERINFO, szText, _countof(szText));
672612729b0SKatayama Hirofumi MZ             break;
673612729b0SKatayama Hirofumi MZ 
674612729b0SKatayama Hirofumi MZ         case PRODUCT_OPTION_WORKSTATION:
675612729b0SKatayama Hirofumi MZ             LoadStringW(hDllInstance, IDS_PRODUCTWORKSTATIONINFO, szText, _countof(szText));
676612729b0SKatayama Hirofumi MZ             break;
677612729b0SKatayama Hirofumi MZ 
678612729b0SKatayama Hirofumi MZ         default:
679612729b0SKatayama Hirofumi MZ             return;
68048160c74SKatayama Hirofumi MZ     }
68148160c74SKatayama Hirofumi MZ 
68248160c74SKatayama Hirofumi MZ     SetDlgItemTextW(hwndDlg, IDC_PRODUCT_DESCRIPTION, szText);
68348160c74SKatayama Hirofumi MZ }
68448160c74SKatayama Hirofumi MZ 
68548160c74SKatayama Hirofumi MZ static INT_PTR CALLBACK
ProductPageDlgProc(HWND hwndDlg,UINT uMsg,WPARAM wParam,LPARAM lParam)68648160c74SKatayama Hirofumi MZ ProductPageDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
68748160c74SKatayama Hirofumi MZ {
68848160c74SKatayama Hirofumi MZ     LPNMHDR lpnm;
68948160c74SKatayama Hirofumi MZ     PSETUPDATA pSetupData;
69048160c74SKatayama Hirofumi MZ     INT iItem;
6914cbb2176SJoachim Henze     WCHAR szText[64], szDefault[64];
69248160c74SKatayama Hirofumi MZ     HICON hIcon;
69348160c74SKatayama Hirofumi MZ 
69448160c74SKatayama Hirofumi MZ     pSetupData = (PSETUPDATA)GetWindowLongPtr(hwndDlg, DWLP_USER);
69548160c74SKatayama Hirofumi MZ 
69648160c74SKatayama Hirofumi MZ     switch (uMsg)
69748160c74SKatayama Hirofumi MZ     {
69848160c74SKatayama Hirofumi MZ         case WM_INITDIALOG:
69948160c74SKatayama Hirofumi MZ         {
70048160c74SKatayama Hirofumi MZ             pSetupData = (PSETUPDATA)((LPPROPSHEETPAGE)lParam)->lParam;
70148160c74SKatayama Hirofumi MZ             SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pSetupData);
70248160c74SKatayama Hirofumi MZ 
703612729b0SKatayama Hirofumi MZ             LoadStringW(hDllInstance, IDS_DEFAULT, szDefault, _countof(szDefault));
704612729b0SKatayama Hirofumi MZ 
70548160c74SKatayama Hirofumi MZ             LoadStringW(hDllInstance, IDS_PRODUCTSERVERNAME, szText, _countof(szText));
706612729b0SKatayama Hirofumi MZ             if (PRODUCT_OPTION_DEFAULT == PRODUCT_OPTION_SERVER)
707612729b0SKatayama Hirofumi MZ             {
708612729b0SKatayama Hirofumi MZ                 StringCchCatW(szText, _countof(szText), L" ");
709612729b0SKatayama Hirofumi MZ                 StringCchCatW(szText, _countof(szText), szDefault);
710612729b0SKatayama Hirofumi MZ             }
71148160c74SKatayama Hirofumi MZ             SendDlgItemMessageW(hwndDlg, IDC_PRODUCT_OPTIONS, CB_ADDSTRING, 0, (LPARAM)szText);
71248160c74SKatayama Hirofumi MZ 
71348160c74SKatayama Hirofumi MZ             LoadStringW(hDllInstance, IDS_PRODUCTWORKSTATIONNAME, szText, _countof(szText));
714612729b0SKatayama Hirofumi MZ             if (PRODUCT_OPTION_DEFAULT == PRODUCT_OPTION_WORKSTATION)
715612729b0SKatayama Hirofumi MZ             {
716612729b0SKatayama Hirofumi MZ                 StringCchCatW(szText, _countof(szText), L" ");
717612729b0SKatayama Hirofumi MZ                 StringCchCatW(szText, _countof(szText), szDefault);
718612729b0SKatayama Hirofumi MZ             }
71948160c74SKatayama Hirofumi MZ             SendDlgItemMessageW(hwndDlg, IDC_PRODUCT_OPTIONS, CB_ADDSTRING, 0, (LPARAM)szText);
72048160c74SKatayama Hirofumi MZ 
721612729b0SKatayama Hirofumi MZ             SendDlgItemMessageW(hwndDlg, IDC_PRODUCT_OPTIONS, CB_SETCURSEL, PRODUCT_OPTION_DEFAULT, 0);
722612729b0SKatayama Hirofumi MZ             OnChooseOption(hwndDlg, PRODUCT_OPTION_DEFAULT);
72348160c74SKatayama Hirofumi MZ 
72448160c74SKatayama Hirofumi MZ             hIcon = LoadIcon(NULL, IDI_WINLOGO);
72548160c74SKatayama Hirofumi MZ             SendDlgItemMessageW(hwndDlg, IDC_PRODUCT_ICON, STM_SETICON, (WPARAM)hIcon, 0);
72648160c74SKatayama Hirofumi MZ             return TRUE;
72748160c74SKatayama Hirofumi MZ         }
72848160c74SKatayama Hirofumi MZ 
72948160c74SKatayama Hirofumi MZ         case WM_COMMAND:
73048160c74SKatayama Hirofumi MZ             if (HIWORD(wParam) == CBN_SELCHANGE && IDC_PRODUCT_OPTIONS == LOWORD(wParam))
73148160c74SKatayama Hirofumi MZ             {
73248160c74SKatayama Hirofumi MZ                 iItem = SendDlgItemMessageW(hwndDlg, IDC_PRODUCT_OPTIONS, CB_GETCURSEL, 0, 0);
733612729b0SKatayama Hirofumi MZ                 OnChooseOption(hwndDlg, (PRODUCT_OPTION)iItem);
73448160c74SKatayama Hirofumi MZ             }
73548160c74SKatayama Hirofumi MZ             break;
73648160c74SKatayama Hirofumi MZ 
73748160c74SKatayama Hirofumi MZ         case WM_NOTIFY:
73848160c74SKatayama Hirofumi MZ         {
73948160c74SKatayama Hirofumi MZ             lpnm = (LPNMHDR)lParam;
74048160c74SKatayama Hirofumi MZ 
74148160c74SKatayama Hirofumi MZ             switch (lpnm->code)
74248160c74SKatayama Hirofumi MZ             {
74348160c74SKatayama Hirofumi MZ                 case PSN_SETACTIVE:
74448160c74SKatayama Hirofumi MZ                     /* Enable the Back and Next buttons */
74548160c74SKatayama Hirofumi MZ                     PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK | PSWIZB_NEXT);
74648160c74SKatayama Hirofumi MZ                     if (pSetupData->UnattendSetup)
74748160c74SKatayama Hirofumi MZ                     {
748612729b0SKatayama Hirofumi MZ                         OnChooseOption(hwndDlg, pSetupData->ProductOption);
74948160c74SKatayama Hirofumi MZ                         DoWriteProductOption(pSetupData->ProductOption);
7500182dcd7STimo Kreuzer                         SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_LOCALEPAGE);
751c2c66affSColin Finck                         return TRUE;
752c2c66affSColin Finck                     }
753c2c66affSColin Finck                     break;
754c2c66affSColin Finck 
75548160c74SKatayama Hirofumi MZ                 case PSN_WIZNEXT:
75648160c74SKatayama Hirofumi MZ                     iItem = SendDlgItemMessageW(hwndDlg, IDC_PRODUCT_OPTIONS, CB_GETCURSEL, 0, 0);
75748160c74SKatayama Hirofumi MZ                     pSetupData->ProductOption = (PRODUCT_OPTION)iItem;
75848160c74SKatayama Hirofumi MZ                     DoWriteProductOption(pSetupData->ProductOption);
75948160c74SKatayama Hirofumi MZ                     break;
76048160c74SKatayama Hirofumi MZ 
761c2c66affSColin Finck                 case PSN_WIZBACK:
762c2c66affSColin Finck                     pSetupData->UnattendSetup = FALSE;
763c2c66affSColin Finck                     break;
764c2c66affSColin Finck 
765c2c66affSColin Finck                 default:
766c2c66affSColin Finck                     break;
767c2c66affSColin Finck             }
768c2c66affSColin Finck         }
769c2c66affSColin Finck         break;
770c2c66affSColin Finck 
771c2c66affSColin Finck         default:
772c2c66affSColin Finck             break;
773c2c66affSColin Finck     }
774c2c66affSColin Finck 
775c2c66affSColin Finck     return FALSE;
776c2c66affSColin Finck }
777c2c66affSColin Finck 
778c2c66affSColin Finck static
779c2c66affSColin Finck BOOL
WriteOwnerSettings(WCHAR * OwnerName,WCHAR * OwnerOrganization)780c2c66affSColin Finck WriteOwnerSettings(WCHAR * OwnerName,
781c2c66affSColin Finck                    WCHAR * OwnerOrganization)
782c2c66affSColin Finck {
783c2c66affSColin Finck     HKEY hKey;
784c2c66affSColin Finck     LONG res;
785c2c66affSColin Finck 
786c2c66affSColin Finck     res = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
787c2c66affSColin Finck                         L"Software\\Microsoft\\Windows NT\\CurrentVersion",
788c2c66affSColin Finck                         0,
789c2c66affSColin Finck                         KEY_ALL_ACCESS,
790c2c66affSColin Finck                         &hKey);
791c2c66affSColin Finck 
792c2c66affSColin Finck     if (res != ERROR_SUCCESS)
793c2c66affSColin Finck     {
794c2c66affSColin Finck         return FALSE;
795c2c66affSColin Finck     }
796c2c66affSColin Finck 
797c2c66affSColin Finck     res = RegSetValueExW(hKey,
798c2c66affSColin Finck                          L"RegisteredOwner",
799c2c66affSColin Finck                          0,
800c2c66affSColin Finck                          REG_SZ,
801c2c66affSColin Finck                          (LPBYTE)OwnerName,
802c2c66affSColin Finck                          (wcslen(OwnerName) + 1) * sizeof(WCHAR));
803c2c66affSColin Finck 
804c2c66affSColin Finck     if (res != ERROR_SUCCESS)
805c2c66affSColin Finck     {
806c2c66affSColin Finck         RegCloseKey(hKey);
807c2c66affSColin Finck         return FALSE;
808c2c66affSColin Finck     }
809c2c66affSColin Finck 
810c2c66affSColin Finck     res = RegSetValueExW(hKey,
811c2c66affSColin Finck                          L"RegisteredOrganization",
812c2c66affSColin Finck                          0,
813c2c66affSColin Finck                          REG_SZ,
814c2c66affSColin Finck                          (LPBYTE)OwnerOrganization,
815c2c66affSColin Finck                          (wcslen(OwnerOrganization) + 1) * sizeof(WCHAR));
816c2c66affSColin Finck 
817c2c66affSColin Finck     RegCloseKey(hKey);
818c2c66affSColin Finck     return (res == ERROR_SUCCESS);
819c2c66affSColin Finck }
820c2c66affSColin Finck 
821c2c66affSColin Finck static INT_PTR CALLBACK
OwnerPageDlgProc(HWND hwndDlg,UINT uMsg,WPARAM wParam,LPARAM lParam)822c2c66affSColin Finck OwnerPageDlgProc(HWND hwndDlg,
823c2c66affSColin Finck                  UINT uMsg,
824c2c66affSColin Finck                  WPARAM wParam,
825c2c66affSColin Finck                  LPARAM lParam)
826c2c66affSColin Finck {
827c2c66affSColin Finck     WCHAR OwnerName[51];
828c2c66affSColin Finck     WCHAR OwnerOrganization[51];
829c2c66affSColin Finck     WCHAR Title[64];
830c2c66affSColin Finck     WCHAR ErrorName[256];
831c2c66affSColin Finck     LPNMHDR lpnm;
832c2c66affSColin Finck     PSETUPDATA pSetupData;
833c2c66affSColin Finck 
834c2c66affSColin Finck     pSetupData = (PSETUPDATA)GetWindowLongPtr(hwndDlg, DWLP_USER);
835c2c66affSColin Finck 
836c2c66affSColin Finck     switch (uMsg)
837c2c66affSColin Finck     {
838c2c66affSColin Finck         case WM_INITDIALOG:
839c2c66affSColin Finck         {
840c2c66affSColin Finck             pSetupData = (PSETUPDATA)((LPPROPSHEETPAGE)lParam)->lParam;
841c2c66affSColin Finck             SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pSetupData);
842c2c66affSColin Finck 
843c2c66affSColin Finck             /* set a localized ('Owner') placeholder string as default */
844c2c66affSColin Finck             if (LoadStringW(hDllInstance, IDS_MACHINE_OWNER_NAME, OwnerName, _countof(OwnerName)))
845c2c66affSColin Finck             {
846c2c66affSColin Finck                 SendDlgItemMessage(hwndDlg, IDC_OWNERNAME, WM_SETTEXT, 0, (LPARAM)OwnerName);
847c2c66affSColin Finck             }
848c2c66affSColin Finck 
849c2c66affSColin Finck             SendDlgItemMessage(hwndDlg, IDC_OWNERNAME, EM_LIMITTEXT, 50, 0);
850c2c66affSColin Finck             SendDlgItemMessage(hwndDlg, IDC_OWNERORGANIZATION, EM_LIMITTEXT, 50, 0);
851c2c66affSColin Finck 
852c2c66affSColin Finck             /* Set focus to owner name */
853c2c66affSColin Finck             SetFocus(GetDlgItem(hwndDlg, IDC_OWNERNAME));
854c2c66affSColin Finck 
855c2c66affSColin Finck             /* Select the default text to quickly overwrite it by typing */
856c2c66affSColin Finck             SendDlgItemMessage(hwndDlg, IDC_OWNERNAME, EM_SETSEL, 0, -1);
857c2c66affSColin Finck         }
858c2c66affSColin Finck         break;
859c2c66affSColin Finck 
860c2c66affSColin Finck 
861c2c66affSColin Finck         case WM_NOTIFY:
862c2c66affSColin Finck         {
863c2c66affSColin Finck             lpnm = (LPNMHDR)lParam;
864c2c66affSColin Finck 
865c2c66affSColin Finck             switch (lpnm->code)
866c2c66affSColin Finck             {
867c2c66affSColin Finck                 case PSN_SETACTIVE:
868c2c66affSColin Finck                     /* Enable the Back and Next buttons */
869c2c66affSColin Finck                     PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK | PSWIZB_NEXT);
870c2c66affSColin Finck                     if (pSetupData->UnattendSetup)
871c2c66affSColin Finck                     {
872c2c66affSColin Finck                         SendMessage(GetDlgItem(hwndDlg, IDC_OWNERNAME), WM_SETTEXT, 0, (LPARAM)pSetupData->OwnerName);
873c2c66affSColin Finck                         SendMessage(GetDlgItem(hwndDlg, IDC_OWNERORGANIZATION), WM_SETTEXT, 0, (LPARAM)pSetupData->OwnerOrganization);
874c2c66affSColin Finck                         if (WriteOwnerSettings(pSetupData->OwnerName, pSetupData->OwnerOrganization))
875c2c66affSColin Finck                         {
8760182dcd7STimo Kreuzer                             SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_COMPUTERPAGE);
877c2c66affSColin Finck                             return TRUE;
878c2c66affSColin Finck                         }
879c2c66affSColin Finck                     }
880c2c66affSColin Finck                     break;
881c2c66affSColin Finck 
882c2c66affSColin Finck                 case PSN_WIZNEXT:
883c2c66affSColin Finck                     OwnerName[0] = 0;
884c2c66affSColin Finck                     if (GetDlgItemTextW(hwndDlg, IDC_OWNERNAME, OwnerName, 50) == 0)
885c2c66affSColin Finck                     {
88662678985SHermès Bélusca-Maïto                         if (0 == LoadStringW(hDllInstance, IDS_REACTOS_SETUP, Title, ARRAYSIZE(Title)))
887c2c66affSColin Finck                         {
888c2c66affSColin Finck                             wcscpy(Title, L"ReactOS Setup");
889c2c66affSColin Finck                         }
89062678985SHermès Bélusca-Maïto                         if (0 == LoadStringW(hDllInstance, IDS_WZD_NAME, ErrorName, ARRAYSIZE(ErrorName)))
891c2c66affSColin Finck                         {
892c2c66affSColin Finck                             wcscpy(ErrorName, L"Setup cannot continue until you enter your name.");
893c2c66affSColin Finck                         }
894c2c66affSColin Finck                         MessageBoxW(hwndDlg, ErrorName, Title, MB_ICONERROR | MB_OK);
895c2c66affSColin Finck 
896c2c66affSColin Finck                         SetFocus(GetDlgItem(hwndDlg, IDC_OWNERNAME));
8970182dcd7STimo Kreuzer                         SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1);
898c2c66affSColin Finck 
899c2c66affSColin Finck                         return TRUE;
900c2c66affSColin Finck                     }
901c2c66affSColin Finck 
902c2c66affSColin Finck                     OwnerOrganization[0] = 0;
903c2c66affSColin Finck                     GetDlgItemTextW(hwndDlg, IDC_OWNERORGANIZATION, OwnerOrganization, 50);
904c2c66affSColin Finck 
905c2c66affSColin Finck                     if (!WriteOwnerSettings(OwnerName, OwnerOrganization))
906c2c66affSColin Finck                     {
907c2c66affSColin Finck                         SetFocus(GetDlgItem(hwndDlg, IDC_OWNERNAME));
9080182dcd7STimo Kreuzer                         SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1);
909c2c66affSColin Finck                         return TRUE;
910c2c66affSColin Finck                     }
911c2c66affSColin Finck 
912c2c66affSColin Finck                 case PSN_WIZBACK:
913c2c66affSColin Finck                     pSetupData->UnattendSetup = FALSE;
914c2c66affSColin Finck                     break;
915c2c66affSColin Finck 
916c2c66affSColin Finck                 default:
917c2c66affSColin Finck                     break;
918c2c66affSColin Finck             }
919c2c66affSColin Finck         }
920c2c66affSColin Finck         break;
921c2c66affSColin Finck 
922c2c66affSColin Finck         default:
923c2c66affSColin Finck             break;
924c2c66affSColin Finck     }
925c2c66affSColin Finck 
926c2c66affSColin Finck     return FALSE;
927c2c66affSColin Finck }
928c2c66affSColin Finck 
929c2c66affSColin Finck static
930c2c66affSColin Finck BOOL
WriteComputerSettings(WCHAR * ComputerName,HWND hwndDlg)931c2c66affSColin Finck WriteComputerSettings(WCHAR * ComputerName, HWND hwndDlg)
932c2c66affSColin Finck {
933c2c66affSColin Finck     WCHAR Title[64];
934c2c66affSColin Finck     WCHAR ErrorComputerName[256];
9359a39315dSKatayama Hirofumi MZ     LONG lError;
9369a39315dSKatayama Hirofumi MZ     HKEY hKey = NULL;
937c2c66affSColin Finck 
938c2c66affSColin Finck     if (!SetComputerNameW(ComputerName))
939c2c66affSColin Finck     {
940c2c66affSColin Finck         if (hwndDlg != NULL)
941c2c66affSColin Finck         {
94262678985SHermès Bélusca-Maïto             if (0 == LoadStringW(hDllInstance, IDS_REACTOS_SETUP, Title, ARRAYSIZE(Title)))
943c2c66affSColin Finck             {
944c2c66affSColin Finck                 wcscpy(Title, L"ReactOS Setup");
945c2c66affSColin Finck             }
946c2c66affSColin Finck             if (0 == LoadStringW(hDllInstance, IDS_WZD_SETCOMPUTERNAME, ErrorComputerName,
94762678985SHermès Bélusca-Maïto                                  ARRAYSIZE(ErrorComputerName)))
948c2c66affSColin Finck             {
949c2c66affSColin Finck                 wcscpy(ErrorComputerName, L"Setup failed to set the computer name.");
950c2c66affSColin Finck             }
951c2c66affSColin Finck             MessageBoxW(hwndDlg, ErrorComputerName, Title, MB_ICONERROR | MB_OK);
952c2c66affSColin Finck         }
953c2c66affSColin Finck 
954c2c66affSColin Finck         return FALSE;
955c2c66affSColin Finck     }
956c2c66affSColin Finck 
9579e2ae9b0SEric Kohl     /* Set the physical DNS domain */
9589e2ae9b0SEric Kohl     SetComputerNameExW(ComputerNamePhysicalDnsDomain, L"");
9599e2ae9b0SEric Kohl 
9609e2ae9b0SEric Kohl     /* Set the physical DNS hostname */
961c2c66affSColin Finck     SetComputerNameExW(ComputerNamePhysicalDnsHostname, ComputerName);
962c2c66affSColin Finck 
963c2c66affSColin Finck     /* Set the accounts domain name */
964c2c66affSColin Finck     SetAccountsDomainSid(NULL, ComputerName);
965c2c66affSColin Finck 
9669a39315dSKatayama Hirofumi MZ     /* Now we need to set the Hostname */
9679a39315dSKatayama Hirofumi MZ     lError = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
9689a39315dSKatayama Hirofumi MZ                            L"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters",
9699a39315dSKatayama Hirofumi MZ                            0,
9709a39315dSKatayama Hirofumi MZ                            KEY_SET_VALUE,
9719a39315dSKatayama Hirofumi MZ                            &hKey);
9729a39315dSKatayama Hirofumi MZ     if (lError != ERROR_SUCCESS)
9739a39315dSKatayama Hirofumi MZ     {
9749a39315dSKatayama Hirofumi MZ         DPRINT1("RegOpenKeyExW for Tcpip\\Parameters failed (%08lX)\n", lError);
9759a39315dSKatayama Hirofumi MZ         return TRUE;
9769a39315dSKatayama Hirofumi MZ     }
9779a39315dSKatayama Hirofumi MZ 
9789a39315dSKatayama Hirofumi MZ     lError = RegSetValueEx(hKey,
9799a39315dSKatayama Hirofumi MZ                            L"Hostname",
9809a39315dSKatayama Hirofumi MZ                            0,
9819a39315dSKatayama Hirofumi MZ                            REG_SZ,
9829a39315dSKatayama Hirofumi MZ                            (LPBYTE)ComputerName,
9839a39315dSKatayama Hirofumi MZ                            (wcslen(ComputerName) + 1) * sizeof(WCHAR));
9849a39315dSKatayama Hirofumi MZ     if (lError != ERROR_SUCCESS)
9859a39315dSKatayama Hirofumi MZ     {
9869a39315dSKatayama Hirofumi MZ         DPRINT1("RegSetValueEx(\"Hostname\") failed (%08lX)\n", lError);
9879a39315dSKatayama Hirofumi MZ     }
9889a39315dSKatayama Hirofumi MZ 
9899a39315dSKatayama Hirofumi MZ     RegCloseKey(hKey);
9909a39315dSKatayama Hirofumi MZ 
991c2c66affSColin Finck     return TRUE;
992c2c66affSColin Finck }
993c2c66affSColin Finck 
994c2c66affSColin Finck 
995c2c66affSColin Finck static
996c2c66affSColin Finck BOOL
WriteDefaultLogonData(LPWSTR Domain)997c2c66affSColin Finck WriteDefaultLogonData(LPWSTR Domain)
998c2c66affSColin Finck {
999c2c66affSColin Finck     WCHAR szAdministratorName[256];
1000c2c66affSColin Finck     HKEY hKey = NULL;
1001c2c66affSColin Finck     LONG lError;
1002c2c66affSColin Finck 
1003c2c66affSColin Finck     if (LoadStringW(hDllInstance,
1004c2c66affSColin Finck                     IDS_ADMINISTRATOR_NAME,
1005c2c66affSColin Finck                     szAdministratorName,
100662678985SHermès Bélusca-Maïto                     ARRAYSIZE(szAdministratorName)) == 0)
1007c2c66affSColin Finck     {
1008c2c66affSColin Finck         wcscpy(szAdministratorName, L"Administrator");
1009c2c66affSColin Finck     }
1010c2c66affSColin Finck 
1011c2c66affSColin Finck     lError = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
1012c2c66affSColin Finck                            L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon",
1013c2c66affSColin Finck                            0,
1014c2c66affSColin Finck                            KEY_SET_VALUE,
1015c2c66affSColin Finck                            &hKey);
1016c2c66affSColin Finck     if (lError != ERROR_SUCCESS)
1017c2c66affSColin Finck         return FALSE;
1018c2c66affSColin Finck 
1019c2c66affSColin Finck     lError = RegSetValueEx(hKey,
1020b784c7bfSEric Kohl                            L"DefaultDomainName",
1021c2c66affSColin Finck                            0,
1022c2c66affSColin Finck                            REG_SZ,
1023c2c66affSColin Finck                            (LPBYTE)Domain,
1024c2c66affSColin Finck                            (wcslen(Domain)+ 1) * sizeof(WCHAR));
1025c2c66affSColin Finck     if (lError != ERROR_SUCCESS)
1026c2c66affSColin Finck     {
1027b784c7bfSEric Kohl         DPRINT1("RegSetValueEx(\"DefaultDomainName\") failed!\n");
1028c2c66affSColin Finck     }
1029c2c66affSColin Finck 
1030c2c66affSColin Finck     lError = RegSetValueEx(hKey,
1031c2c66affSColin Finck                            L"DefaultUserName",
1032c2c66affSColin Finck                            0,
1033c2c66affSColin Finck                            REG_SZ,
1034c2c66affSColin Finck                            (LPBYTE)szAdministratorName,
1035c2c66affSColin Finck                            (wcslen(szAdministratorName)+ 1) * sizeof(WCHAR));
1036c2c66affSColin Finck     if (lError != ERROR_SUCCESS)
1037c2c66affSColin Finck     {
1038c2c66affSColin Finck         DPRINT1("RegSetValueEx(\"DefaultUserName\") failed!\n");
1039c2c66affSColin Finck     }
1040c2c66affSColin Finck 
1041c2c66affSColin Finck     RegCloseKey(hKey);
1042c2c66affSColin Finck 
1043c2c66affSColin Finck     return TRUE;
1044c2c66affSColin Finck }
1045c2c66affSColin Finck 
1046c2c66affSColin Finck 
1047c2c66affSColin Finck /* lpBuffer will be filled with a 15-char string (plus the null terminator) */
1048c2c66affSColin Finck static void
GenerateComputerName(LPWSTR lpBuffer)1049c2c66affSColin Finck GenerateComputerName(LPWSTR lpBuffer)
1050c2c66affSColin Finck {
1051c2c66affSColin Finck     static const WCHAR Chars[] = L"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
1052c2c66affSColin Finck     static const unsigned cChars = sizeof(Chars) / sizeof(WCHAR) - 1;
1053c2c66affSColin Finck     unsigned i;
1054c2c66affSColin Finck 
1055c2c66affSColin Finck     wcscpy(lpBuffer, L"REACTOS-");
1056c2c66affSColin Finck 
1057c2c66affSColin Finck     srand(GetTickCount());
1058c2c66affSColin Finck 
1059c2c66affSColin Finck     /* fill in 7 characters */
1060c2c66affSColin Finck     for (i = 8; i < 15; i++)
1061c2c66affSColin Finck         lpBuffer[i] = Chars[rand() % cChars];
1062c2c66affSColin Finck 
1063c2c66affSColin Finck     lpBuffer[15] = UNICODE_NULL; /* NULL-terminate */
1064c2c66affSColin Finck }
1065c2c66affSColin Finck 
1066c2c66affSColin Finck static INT_PTR CALLBACK
ComputerPageDlgProc(HWND hwndDlg,UINT uMsg,WPARAM wParam,LPARAM lParam)1067c2c66affSColin Finck ComputerPageDlgProc(HWND hwndDlg,
1068c2c66affSColin Finck                     UINT uMsg,
1069c2c66affSColin Finck                     WPARAM wParam,
1070c2c66affSColin Finck                     LPARAM lParam)
1071c2c66affSColin Finck {
1072c2c66affSColin Finck     WCHAR ComputerName[MAX_COMPUTERNAME_LENGTH + 1];
1073c2c66affSColin Finck     WCHAR Password1[128];
1074c2c66affSColin Finck     WCHAR Password2[128];
1075c2c66affSColin Finck     PWCHAR Password;
1076c2c66affSColin Finck     WCHAR Title[64];
1077c2c66affSColin Finck     WCHAR EmptyComputerName[256], NotMatchPassword[256], WrongPassword[256];
1078c2c66affSColin Finck     LPNMHDR lpnm;
1079c2c66affSColin Finck     PSETUPDATA pSetupData;
1080c2c66affSColin Finck 
1081c2c66affSColin Finck     pSetupData = (PSETUPDATA)GetWindowLongPtr(hwndDlg, DWLP_USER);
1082c2c66affSColin Finck 
108362678985SHermès Bélusca-Maïto     if (0 == LoadStringW(hDllInstance, IDS_REACTOS_SETUP, Title, ARRAYSIZE(Title)))
1084c2c66affSColin Finck     {
1085c2c66affSColin Finck         wcscpy(Title, L"ReactOS Setup");
1086c2c66affSColin Finck     }
1087c2c66affSColin Finck 
1088c2c66affSColin Finck     switch (uMsg)
1089c2c66affSColin Finck     {
1090c2c66affSColin Finck         case WM_INITDIALOG:
1091c2c66affSColin Finck             pSetupData = (PSETUPDATA)((LPPROPSHEETPAGE)lParam)->lParam;
1092c2c66affSColin Finck             SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pSetupData);
1093c2c66affSColin Finck 
1094c2c66affSColin Finck             /* Generate a new pseudo-random computer name */
1095c2c66affSColin Finck             GenerateComputerName(ComputerName);
1096c2c66affSColin Finck 
1097c2c66affSColin Finck             /* Display current computer name */
1098c2c66affSColin Finck             SetDlgItemTextW(hwndDlg, IDC_COMPUTERNAME, ComputerName);
1099c2c66affSColin Finck 
1100c2c66affSColin Finck             /* Set text limits */
1101c2c66affSColin Finck             SendDlgItemMessage(hwndDlg, IDC_COMPUTERNAME, EM_LIMITTEXT, MAX_COMPUTERNAME_LENGTH, 0);
1102c2c66affSColin Finck             SendDlgItemMessage(hwndDlg, IDC_ADMINPASSWORD1, EM_LIMITTEXT, 127, 0);
1103c2c66affSColin Finck             SendDlgItemMessage(hwndDlg, IDC_ADMINPASSWORD2, EM_LIMITTEXT, 127, 0);
1104c2c66affSColin Finck 
1105c2c66affSColin Finck             /* Set focus to computer name */
1106c2c66affSColin Finck             SetFocus(GetDlgItem(hwndDlg, IDC_COMPUTERNAME));
1107c2c66affSColin Finck             if (pSetupData->UnattendSetup)
1108c2c66affSColin Finck             {
1109c2c66affSColin Finck                 SendMessage(GetDlgItem(hwndDlg, IDC_COMPUTERNAME), WM_SETTEXT, 0, (LPARAM)pSetupData->ComputerName);
1110c2c66affSColin Finck                 SendMessage(GetDlgItem(hwndDlg, IDC_ADMINPASSWORD1), WM_SETTEXT, 0, (LPARAM)pSetupData->AdminPassword);
1111c2c66affSColin Finck                 SendMessage(GetDlgItem(hwndDlg, IDC_ADMINPASSWORD2), WM_SETTEXT, 0, (LPARAM)pSetupData->AdminPassword);
1112c2c66affSColin Finck                 WriteComputerSettings(pSetupData->ComputerName, NULL);
1113c2c66affSColin Finck                 SetAdministratorPassword(pSetupData->AdminPassword);
1114c2c66affSColin Finck             }
1115c2c66affSColin Finck 
1116c2c66affSColin Finck             /* Store the administrator account name as the default user name */
1117c2c66affSColin Finck             WriteDefaultLogonData(pSetupData->ComputerName);
1118c2c66affSColin Finck             break;
1119c2c66affSColin Finck 
1120c2c66affSColin Finck 
1121c2c66affSColin Finck         case WM_NOTIFY:
1122c2c66affSColin Finck         {
1123c2c66affSColin Finck             lpnm = (LPNMHDR)lParam;
1124c2c66affSColin Finck 
1125c2c66affSColin Finck             switch (lpnm->code)
1126c2c66affSColin Finck             {
1127c2c66affSColin Finck                 case PSN_SETACTIVE:
1128c2c66affSColin Finck                     /* Enable the Back and Next buttons */
1129c2c66affSColin Finck                     PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK | PSWIZB_NEXT);
1130c2c66affSColin Finck                     if (pSetupData->UnattendSetup && WriteComputerSettings(pSetupData->ComputerName, hwndDlg))
1131c2c66affSColin Finck                     {
11320182dcd7STimo Kreuzer                         SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_THEMEPAGE);
1133c2c66affSColin Finck                         return TRUE;
1134c2c66affSColin Finck                     }
1135c2c66affSColin Finck                     break;
1136c2c66affSColin Finck 
1137c2c66affSColin Finck                 case PSN_WIZNEXT:
1138c2c66affSColin Finck                     if (0 == GetDlgItemTextW(hwndDlg, IDC_COMPUTERNAME, ComputerName, MAX_COMPUTERNAME_LENGTH + 1))
1139c2c66affSColin Finck                     {
1140c2c66affSColin Finck                         if (0 == LoadStringW(hDllInstance, IDS_WZD_COMPUTERNAME, EmptyComputerName,
114162678985SHermès Bélusca-Maïto                                              ARRAYSIZE(EmptyComputerName)))
1142c2c66affSColin Finck                         {
1143c2c66affSColin Finck                             wcscpy(EmptyComputerName, L"Setup cannot continue until you enter the name of your computer.");
1144c2c66affSColin Finck                         }
1145c2c66affSColin Finck                         MessageBoxW(hwndDlg, EmptyComputerName, Title, MB_ICONERROR | MB_OK);
1146c2c66affSColin Finck                         SetFocus(GetDlgItem(hwndDlg, IDC_COMPUTERNAME));
11470182dcd7STimo Kreuzer                         SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1);
1148c2c66affSColin Finck                         return TRUE;
1149c2c66affSColin Finck                     }
1150c2c66affSColin Finck 
1151c2c66affSColin Finck                     /* No need to check computer name for invalid characters,
1152c2c66affSColin Finck                      * SetComputerName() will do it for us */
1153c2c66affSColin Finck 
1154c2c66affSColin Finck                     if (!WriteComputerSettings(ComputerName, hwndDlg))
1155c2c66affSColin Finck                     {
1156c2c66affSColin Finck                         SetFocus(GetDlgItem(hwndDlg, IDC_COMPUTERNAME));
11570182dcd7STimo Kreuzer                         SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1);
1158c2c66affSColin Finck                         return TRUE;
1159c2c66affSColin Finck                     }
1160c2c66affSColin Finck 
11611769793bSErkin Alp Güney #ifdef PASSWORDS_MANDATORY
1162c2c66affSColin Finck                     /* Check if admin passwords have been entered */
1163c2c66affSColin Finck                     if ((GetDlgItemText(hwndDlg, IDC_ADMINPASSWORD1, Password1, 128) == 0) ||
1164c2c66affSColin Finck                         (GetDlgItemText(hwndDlg, IDC_ADMINPASSWORD2, Password2, 128) == 0))
1165c2c66affSColin Finck                     {
1166c2c66affSColin Finck                         if (0 == LoadStringW(hDllInstance, IDS_WZD_PASSWORDEMPTY, EmptyPassword,
116762678985SHermès Bélusca-Maïto                                              ARRAYSIZE(EmptyPassword)))
1168c2c66affSColin Finck                         {
1169c2c66affSColin Finck                             wcscpy(EmptyPassword, L"You must enter a password !");
1170c2c66affSColin Finck                         }
1171c2c66affSColin Finck                         MessageBoxW(hwndDlg, EmptyPassword, Title, MB_ICONERROR | MB_OK);
11720182dcd7STimo Kreuzer                         SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1);
1173c2c66affSColin Finck                         return TRUE;
1174c2c66affSColin Finck                     }
1175c2c66affSColin Finck #else
1176c2c66affSColin Finck                     GetDlgItemTextW(hwndDlg, IDC_ADMINPASSWORD1, Password1, 128);
1177c2c66affSColin Finck                     GetDlgItemTextW(hwndDlg, IDC_ADMINPASSWORD2, Password2, 128);
1178c2c66affSColin Finck #endif
1179c2c66affSColin Finck                     /* Check if passwords match */
1180c2c66affSColin Finck                     if (wcscmp(Password1, Password2))
1181c2c66affSColin Finck                     {
1182c2c66affSColin Finck                         if (0 == LoadStringW(hDllInstance, IDS_WZD_PASSWORDMATCH, NotMatchPassword,
118362678985SHermès Bélusca-Maïto                                              ARRAYSIZE(NotMatchPassword)))
1184c2c66affSColin Finck                         {
1185c2c66affSColin Finck                             wcscpy(NotMatchPassword, L"The passwords you entered do not match. Please enter the desired password again.");
1186c2c66affSColin Finck                         }
1187c2c66affSColin Finck                         MessageBoxW(hwndDlg, NotMatchPassword, Title, MB_ICONERROR | MB_OK);
11880182dcd7STimo Kreuzer                         SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1);
1189c2c66affSColin Finck                         return TRUE;
1190c2c66affSColin Finck                     }
1191c2c66affSColin Finck 
1192c2c66affSColin Finck                     /* Check password for invalid characters */
1193c2c66affSColin Finck                     Password = (PWCHAR)Password1;
1194c2c66affSColin Finck                     while (*Password)
1195c2c66affSColin Finck                     {
1196c2c66affSColin Finck                         if (!isprint(*Password))
1197c2c66affSColin Finck                         {
1198c2c66affSColin Finck                             if (0 == LoadStringW(hDllInstance, IDS_WZD_PASSWORDCHAR, WrongPassword,
119962678985SHermès Bélusca-Maïto                                                  ARRAYSIZE(WrongPassword)))
1200c2c66affSColin Finck                             {
1201c2c66affSColin Finck                                 wcscpy(WrongPassword, L"The password you entered contains invalid characters. Please enter a cleaned password.");
1202c2c66affSColin Finck                             }
1203c2c66affSColin Finck                             MessageBoxW(hwndDlg, WrongPassword, Title, MB_ICONERROR | MB_OK);
12040182dcd7STimo Kreuzer                             SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1);
1205c2c66affSColin Finck                             return TRUE;
1206c2c66affSColin Finck                         }
1207c2c66affSColin Finck                         Password++;
1208c2c66affSColin Finck                     }
1209c2c66affSColin Finck 
1210c2c66affSColin Finck                     /* Set admin password */
1211c2c66affSColin Finck                     SetAdministratorPassword(Password1);
1212c2c66affSColin Finck                     break;
1213c2c66affSColin Finck 
1214c2c66affSColin Finck                 case PSN_WIZBACK:
1215c2c66affSColin Finck                     pSetupData->UnattendSetup = FALSE;
1216c2c66affSColin Finck                     break;
1217c2c66affSColin Finck 
1218c2c66affSColin Finck                 default:
1219c2c66affSColin Finck                     break;
1220c2c66affSColin Finck             }
1221c2c66affSColin Finck         }
1222c2c66affSColin Finck         break;
1223c2c66affSColin Finck 
1224c2c66affSColin Finck         default:
1225c2c66affSColin Finck             break;
1226c2c66affSColin Finck     }
1227c2c66affSColin Finck 
1228c2c66affSColin Finck     return FALSE;
1229c2c66affSColin Finck }
1230c2c66affSColin Finck 
1231c2c66affSColin Finck 
1232c2c66affSColin Finck static VOID
SetUserLocaleName(HWND hwnd)123317cb1e1aSStanislav Motylkov SetUserLocaleName(HWND hwnd)
123417cb1e1aSStanislav Motylkov {
12356d09885cSStanislav Motylkov     WCHAR CurLocale[256] = L"";
12366d09885cSStanislav Motylkov     WCHAR CurGeo[256] = L"";
12376d09885cSStanislav Motylkov     WCHAR ResText[256] = L"";
12386d09885cSStanislav Motylkov     WCHAR LocaleText[256 * 2];
12396d09885cSStanislav Motylkov 
12406d09885cSStanislav Motylkov     GetLocaleInfoW(GetUserDefaultLCID(), LOCALE_SLANGUAGE, CurLocale, ARRAYSIZE(CurLocale));
12419635f45bSStanislav Motylkov     GetGeoInfoW(GetUserGeoID(GEOCLASS_NATION), GEO_FRIENDLYNAME, CurGeo, ARRAYSIZE(CurGeo), GetThreadLocale());
12426d09885cSStanislav Motylkov 
12436d09885cSStanislav Motylkov     LoadStringW(hDllInstance, IDS_LOCALETEXT, ResText, ARRAYSIZE(ResText));
12446d09885cSStanislav Motylkov     StringCchPrintfW(LocaleText, ARRAYSIZE(LocaleText), ResText, CurLocale, CurGeo);
12456d09885cSStanislav Motylkov 
12466d09885cSStanislav Motylkov     SetWindowTextW(hwnd, LocaleText);
124717cb1e1aSStanislav Motylkov }
124817cb1e1aSStanislav Motylkov 
124917cb1e1aSStanislav Motylkov static VOID
SetKeyboardLayoutName(HWND hwnd)1250c2c66affSColin Finck SetKeyboardLayoutName(HWND hwnd)
1251c2c66affSColin Finck {
12526d09885cSStanislav Motylkov     HKL hkl;
12536d09885cSStanislav Motylkov     BOOL LayoutSpecial = FALSE;
12546d09885cSStanislav Motylkov     WCHAR LayoutPath[256];
12556d09885cSStanislav Motylkov     WCHAR LocaleName[32];
12566d09885cSStanislav Motylkov     WCHAR SpecialId[5] = L"";
12576d09885cSStanislav Motylkov     WCHAR ResText[256] = L"";
12586d09885cSStanislav Motylkov     DWORD dwValueSize;
1259c2c66affSColin Finck     HKEY hKey;
12606d09885cSStanislav Motylkov     UINT i;
1261c2c66affSColin Finck 
12626d09885cSStanislav Motylkov     /* Get the default input language and method */
12636d09885cSStanislav Motylkov     if (!SystemParametersInfoW(SPI_GETDEFAULTINPUTLANG, 0, (LPDWORD)&hkl, 0))
1264c2c66affSColin Finck     {
12656d09885cSStanislav Motylkov         hkl = GetKeyboardLayout(0);
1266c2c66affSColin Finck     }
1267c2c66affSColin Finck 
12686d09885cSStanislav Motylkov     if ((HIWORD(hkl) & 0xF000) == 0xF000)
1269c2c66affSColin Finck     {
12706d09885cSStanislav Motylkov         /* Process keyboard layout with special id */
12716d09885cSStanislav Motylkov         StringCchPrintfW(SpecialId, ARRAYSIZE(SpecialId), L"%04x", (HIWORD(hkl) & 0x0FFF));
12726d09885cSStanislav Motylkov         LayoutSpecial = TRUE;
1273c2c66affSColin Finck     }
1274c2c66affSColin Finck 
12756d09885cSStanislav Motylkov #define MAX_LAYOUTS_PER_LANGID 0x10000
12766d09885cSStanislav Motylkov     for (i = 0; i < (LayoutSpecial ? MAX_LAYOUTS_PER_LANGID : 1); i++)
12776d09885cSStanislav Motylkov     {
12786d09885cSStanislav Motylkov         /* Generate a hexadecimal identifier for keyboard layout registry key */
12796d09885cSStanislav Motylkov         StringCchPrintfW(LocaleName, ARRAYSIZE(LocaleName), L"%08lx", (i << 16) | LOWORD(hkl));
12806d09885cSStanislav Motylkov 
12816d09885cSStanislav Motylkov         StringCchCopyW(LayoutPath, ARRAYSIZE(LayoutPath), L"SYSTEM\\CurrentControlSet\\Control\\Keyboard Layouts\\");
12826d09885cSStanislav Motylkov         StringCchCatW(LayoutPath, ARRAYSIZE(LayoutPath), LocaleName);
12836d09885cSStanislav Motylkov         *LocaleName = UNICODE_NULL;
12846d09885cSStanislav Motylkov 
12856d09885cSStanislav Motylkov         if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,
12866d09885cSStanislav Motylkov                           LayoutPath,
12876d09885cSStanislav Motylkov                           0,
12886d09885cSStanislav Motylkov                           KEY_ALL_ACCESS,
12896d09885cSStanislav Motylkov                           &hKey) == ERROR_SUCCESS)
12906d09885cSStanislav Motylkov         {
12916d09885cSStanislav Motylkov             /* Make sure the keyboard layout key we opened is the one we need.
12926d09885cSStanislav Motylkov              * If the layout has no special id, just pass this check. */
12936d09885cSStanislav Motylkov             dwValueSize = sizeof(LocaleName);
12946d09885cSStanislav Motylkov             if (!LayoutSpecial ||
12956d09885cSStanislav Motylkov                 ((RegQueryValueExW(hKey,
12966d09885cSStanislav Motylkov                                    L"Layout Id",
12976d09885cSStanislav Motylkov                                    NULL,
12986d09885cSStanislav Motylkov                                    NULL,
12996d09885cSStanislav Motylkov                                    (PVOID)&LocaleName,
13006d09885cSStanislav Motylkov                                    &dwValueSize) == ERROR_SUCCESS) &&
13016d09885cSStanislav Motylkov                 (wcscmp(LocaleName, SpecialId) == 0)))
13026d09885cSStanislav Motylkov             {
13036d09885cSStanislav Motylkov                 *LocaleName = UNICODE_NULL;
13046d09885cSStanislav Motylkov                 dwValueSize = sizeof(LocaleName);
13056d09885cSStanislav Motylkov                 RegQueryValueExW(hKey,
13066d09885cSStanislav Motylkov                                  L"Layout Text",
13076d09885cSStanislav Motylkov                                  NULL,
13086d09885cSStanislav Motylkov                                  NULL,
13096d09885cSStanislav Motylkov                                  (PVOID)&LocaleName,
13106d09885cSStanislav Motylkov                                  &dwValueSize);
13116d09885cSStanislav Motylkov                 /* Let the loop know where to stop */
13126d09885cSStanislav Motylkov                 i = MAX_LAYOUTS_PER_LANGID;
13136d09885cSStanislav Motylkov             }
1314c2c66affSColin Finck             RegCloseKey(hKey);
13156d09885cSStanislav Motylkov         }
13166d09885cSStanislav Motylkov         else
13176d09885cSStanislav Motylkov         {
13186d09885cSStanislav Motylkov             /* Keyboard layout registry keys are expected to go in order without gaps */
13196d09885cSStanislav Motylkov             break;
13206d09885cSStanislav Motylkov         }
13216d09885cSStanislav Motylkov     }
13226d09885cSStanislav Motylkov #undef MAX_LAYOUTS_PER_LANGID
13236d09885cSStanislav Motylkov 
13246d09885cSStanislav Motylkov     LoadStringW(hDllInstance, IDS_LAYOUTTEXT, ResText, ARRAYSIZE(ResText));
13256d09885cSStanislav Motylkov     StringCchPrintfW(LayoutPath, ARRAYSIZE(LayoutPath), ResText, LocaleName);
13266d09885cSStanislav Motylkov 
13276d09885cSStanislav Motylkov     SetWindowTextW(hwnd, LayoutPath);
1328c2c66affSColin Finck }
1329c2c66affSColin Finck 
1330c2c66affSColin Finck 
1331c2c66affSColin Finck static BOOL
RunControlPanelApplet(HWND hwnd,PCWSTR pwszCPLParameters)1332c2c66affSColin Finck RunControlPanelApplet(HWND hwnd, PCWSTR pwszCPLParameters)
1333c2c66affSColin Finck {
1334c2c66affSColin Finck     MSG msg;
13356d09885cSStanislav Motylkov     HWND MainWindow = GetParent(hwnd);
1336c2c66affSColin Finck     STARTUPINFOW StartupInfo;
1337c2c66affSColin Finck     PROCESS_INFORMATION ProcessInformation;
1338c2c66affSColin Finck     WCHAR CmdLine[MAX_PATH] = L"rundll32.exe shell32.dll,Control_RunDLL ";
1339c2c66affSColin Finck 
1340e9893906SHermès Bélusca-Maïto     if (!pwszCPLParameters)
1341e9893906SHermès Bélusca-Maïto     {
1342e9893906SHermès Bélusca-Maïto         MessageBoxW(hwnd, L"Error: Failed to launch the Control Panel Applet.", NULL, MB_ICONERROR);
1343e9893906SHermès Bélusca-Maïto         return FALSE;
1344e9893906SHermès Bélusca-Maïto     }
1345e9893906SHermès Bélusca-Maïto 
1346c2c66affSColin Finck     ZeroMemory(&StartupInfo, sizeof(StartupInfo));
1347c2c66affSColin Finck     StartupInfo.cb = sizeof(StartupInfo);
1348e9893906SHermès Bélusca-Maïto     ZeroMemory(&ProcessInformation, sizeof(ProcessInformation));
1349c2c66affSColin Finck 
1350c2c66affSColin Finck     ASSERT(_countof(CmdLine) > wcslen(CmdLine) + wcslen(pwszCPLParameters));
1351c2c66affSColin Finck     wcscat(CmdLine, pwszCPLParameters);
1352c2c66affSColin Finck 
1353c2c66affSColin Finck     if (!CreateProcessW(NULL,
1354c2c66affSColin Finck                         CmdLine,
1355c2c66affSColin Finck                         NULL,
1356c2c66affSColin Finck                         NULL,
1357c2c66affSColin Finck                         FALSE,
1358c2c66affSColin Finck                         0,
1359c2c66affSColin Finck                         NULL,
1360c2c66affSColin Finck                         NULL,
1361c2c66affSColin Finck                         &StartupInfo,
1362c2c66affSColin Finck                         &ProcessInformation))
1363c2c66affSColin Finck     {
1364c2c66affSColin Finck         MessageBoxW(hwnd, L"Error: Failed to launch the Control Panel Applet.", NULL, MB_ICONERROR);
1365c2c66affSColin Finck         return FALSE;
1366c2c66affSColin Finck     }
1367c2c66affSColin Finck 
13686d09885cSStanislav Motylkov     /* Disable the Back and Next buttons and the main window
13696d09885cSStanislav Motylkov      * while we're interacting with the control panel applet */
13706d09885cSStanislav Motylkov     PropSheet_SetWizButtons(MainWindow, 0);
13716d09885cSStanislav Motylkov     EnableWindow(MainWindow, FALSE);
13726d09885cSStanislav Motylkov 
1373c2c66affSColin Finck     while ((MsgWaitForMultipleObjects(1, &ProcessInformation.hProcess, FALSE, INFINITE, QS_ALLINPUT|QS_ALLPOSTMESSAGE )) != WAIT_OBJECT_0)
1374c2c66affSColin Finck     {
13756d09885cSStanislav Motylkov        /* We still need to process main window messages to avoid freeze */
1376c2c66affSColin Finck        while (PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE))
1377c2c66affSColin Finck        {
1378c2c66affSColin Finck            TranslateMessage(&msg);
1379c2c66affSColin Finck            DispatchMessageW(&msg);
1380c2c66affSColin Finck        }
1381c2c66affSColin Finck     }
1382c2c66affSColin Finck     CloseHandle(ProcessInformation.hThread);
1383c2c66affSColin Finck     CloseHandle(ProcessInformation.hProcess);
13846d09885cSStanislav Motylkov 
13856d09885cSStanislav Motylkov     /* Enable the Back and Next buttons and the main window again */
13866d09885cSStanislav Motylkov     PropSheet_SetWizButtons(MainWindow, PSWIZB_BACK | PSWIZB_NEXT);
13876d09885cSStanislav Motylkov     EnableWindow(MainWindow, TRUE);
13886d09885cSStanislav Motylkov 
1389c2c66affSColin Finck     return TRUE;
1390c2c66affSColin Finck }
1391c2c66affSColin Finck 
1392c2c66affSColin Finck static VOID
WriteUserLocale(VOID)1393c2c66affSColin Finck WriteUserLocale(VOID)
1394c2c66affSColin Finck {
1395c2c66affSColin Finck     HKEY hKey;
1396c2c66affSColin Finck     LCID lcid;
1397c2c66affSColin Finck     WCHAR Locale[12];
1398c2c66affSColin Finck 
1399c2c66affSColin Finck     lcid = GetSystemDefaultLCID();
1400c2c66affSColin Finck 
140162678985SHermès Bélusca-Maïto     if (GetLocaleInfoW(MAKELCID(lcid, SORT_DEFAULT), LOCALE_ILANGUAGE, Locale, ARRAYSIZE(Locale)) != 0)
1402c2c66affSColin Finck     {
1403c2c66affSColin Finck         if (RegCreateKeyExW(HKEY_CURRENT_USER, L"Control Panel\\International",
1404c2c66affSColin Finck                             0, NULL, REG_OPTION_NON_VOLATILE,
1405c2c66affSColin Finck                             KEY_WRITE, NULL, &hKey, NULL) == ERROR_SUCCESS)
1406c2c66affSColin Finck         {
1407c2c66affSColin Finck             RegSetValueExW(hKey, L"Locale", 0, REG_SZ, (LPBYTE)Locale, (wcslen(Locale) + 1) * sizeof(WCHAR));
1408c2c66affSColin Finck             RegCloseKey(hKey);
1409c2c66affSColin Finck         }
1410c2c66affSColin Finck     }
1411c2c66affSColin Finck }
1412c2c66affSColin Finck 
1413c2c66affSColin Finck static INT_PTR CALLBACK
LocalePageDlgProc(HWND hwndDlg,UINT uMsg,WPARAM wParam,LPARAM lParam)1414c2c66affSColin Finck LocalePageDlgProc(HWND hwndDlg,
1415c2c66affSColin Finck                   UINT uMsg,
1416c2c66affSColin Finck                   WPARAM wParam,
1417c2c66affSColin Finck                   LPARAM lParam)
1418c2c66affSColin Finck {
1419c2c66affSColin Finck     PSETUPDATA SetupData;
1420c2c66affSColin Finck 
1421c2c66affSColin Finck     /* Retrieve pointer to the global setup data */
1422d281d14fSTimo Kreuzer     SetupData = (PSETUPDATA)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
1423c2c66affSColin Finck 
1424c2c66affSColin Finck     switch (uMsg)
1425c2c66affSColin Finck     {
1426c2c66affSColin Finck         case WM_INITDIALOG:
1427c2c66affSColin Finck         {
1428c2c66affSColin Finck             /* Save pointer to the global setup data */
1429c2c66affSColin Finck             SetupData = (PSETUPDATA)((LPPROPSHEETPAGE)lParam)->lParam;
1430d281d14fSTimo Kreuzer             SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (DWORD_PTR)SetupData);
1431c2c66affSColin Finck             WriteUserLocale();
1432c2c66affSColin Finck 
143317cb1e1aSStanislav Motylkov             SetUserLocaleName(GetDlgItem(hwndDlg, IDC_LOCALETEXT));
1434c2c66affSColin Finck             SetKeyboardLayoutName(GetDlgItem(hwndDlg, IDC_LAYOUTTEXT));
1435c2c66affSColin Finck         }
1436c2c66affSColin Finck         break;
1437c2c66affSColin Finck 
1438c2c66affSColin Finck         case WM_COMMAND:
1439c2c66affSColin Finck             if (HIWORD(wParam) == BN_CLICKED)
1440c2c66affSColin Finck             {
1441c2c66affSColin Finck                 switch (LOWORD(wParam))
1442c2c66affSColin Finck                 {
1443c2c66affSColin Finck                     case IDC_CUSTOMLOCALE:
1444c2c66affSColin Finck                         RunControlPanelApplet(hwndDlg, L"intl.cpl,,5");
14456d09885cSStanislav Motylkov                         SetUserLocaleName(GetDlgItem(hwndDlg, IDC_LOCALETEXT));
1446c2c66affSColin Finck                         break;
1447c2c66affSColin Finck 
1448c2c66affSColin Finck                     case IDC_CUSTOMLAYOUT:
1449c2c66affSColin Finck                         RunControlPanelApplet(hwndDlg, L"input.dll,@1");
14506d09885cSStanislav Motylkov                         SetKeyboardLayoutName(GetDlgItem(hwndDlg, IDC_LAYOUTTEXT));
1451c2c66affSColin Finck                         break;
1452c2c66affSColin Finck                 }
1453c2c66affSColin Finck             }
1454c2c66affSColin Finck             break;
1455c2c66affSColin Finck 
1456c2c66affSColin Finck         case WM_NOTIFY:
1457c2c66affSColin Finck         {
1458c2c66affSColin Finck             LPNMHDR lpnm = (LPNMHDR)lParam;
1459c2c66affSColin Finck 
1460c2c66affSColin Finck             switch (lpnm->code)
1461c2c66affSColin Finck             {
1462c2c66affSColin Finck                 case PSN_SETACTIVE:
1463c2c66affSColin Finck                     /* Enable the Back and Next buttons */
1464c2c66affSColin Finck                     PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK | PSWIZB_NEXT);
1465c2c66affSColin Finck                     if (SetupData->UnattendSetup)
1466c2c66affSColin Finck                     {
1467c8d37c1aSHermès Bélusca-Maïto                         // if (!*SetupData->SourcePath)
1468c2c66affSColin Finck                         {
1469c8d37c1aSHermès Bélusca-Maïto                             RunControlPanelApplet(hwndDlg, L"intl.cpl,,/f:\"$winnt$.inf\""); // Should be in System32
1470c2c66affSColin Finck                         }
1471c2c66affSColin Finck 
14720182dcd7STimo Kreuzer                         SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_OWNERPAGE);
1473c2c66affSColin Finck                         return TRUE;
1474c2c66affSColin Finck                     }
1475c2c66affSColin Finck                     break;
1476c2c66affSColin Finck 
1477c2c66affSColin Finck                 case PSN_WIZNEXT:
1478c2c66affSColin Finck                     break;
1479c2c66affSColin Finck 
1480c2c66affSColin Finck                 case PSN_WIZBACK:
1481c2c66affSColin Finck                     SetupData->UnattendSetup = FALSE;
1482c2c66affSColin Finck                     break;
1483c2c66affSColin Finck 
1484c2c66affSColin Finck                 default:
1485c2c66affSColin Finck                     break;
1486c2c66affSColin Finck             }
1487c2c66affSColin Finck         }
1488c2c66affSColin Finck         break;
1489c2c66affSColin Finck 
1490c2c66affSColin Finck         default:
1491c2c66affSColin Finck             break;
1492c2c66affSColin Finck     }
1493c2c66affSColin Finck 
1494c2c66affSColin Finck     return FALSE;
1495c2c66affSColin Finck }
1496c2c66affSColin Finck 
1497c2c66affSColin Finck 
1498c2c66affSColin Finck static PTIMEZONE_ENTRY
GetLargerTimeZoneEntry(PSETUPDATA SetupData,DWORD Index)1499c2c66affSColin Finck GetLargerTimeZoneEntry(PSETUPDATA SetupData, DWORD Index)
1500c2c66affSColin Finck {
1501c2c66affSColin Finck     PTIMEZONE_ENTRY Entry;
1502c2c66affSColin Finck 
1503c2c66affSColin Finck     Entry = SetupData->TimeZoneListHead;
1504c2c66affSColin Finck     while (Entry != NULL)
1505c2c66affSColin Finck     {
1506c2c66affSColin Finck         if (Entry->Index >= Index)
1507c2c66affSColin Finck             return Entry;
1508c2c66affSColin Finck 
1509c2c66affSColin Finck         Entry = Entry->Next;
1510c2c66affSColin Finck     }
1511c2c66affSColin Finck 
1512c2c66affSColin Finck     return NULL;
1513c2c66affSColin Finck }
1514c2c66affSColin Finck 
15157c3e96a2SHermès Bélusca-Maïto static LONG
RetrieveTimeZone(IN HKEY hZoneKey,IN PVOID Context)15167c3e96a2SHermès Bélusca-Maïto RetrieveTimeZone(
15177c3e96a2SHermès Bélusca-Maïto     IN HKEY hZoneKey,
15187c3e96a2SHermès Bélusca-Maïto     IN PVOID Context)
1519c2c66affSColin Finck {
1520c2c66affSColin Finck     LONG lError;
15217c3e96a2SHermès Bélusca-Maïto     PSETUPDATA SetupData = (PSETUPDATA)Context;
1522c2c66affSColin Finck     PTIMEZONE_ENTRY Entry;
1523c2c66affSColin Finck     PTIMEZONE_ENTRY Current;
15247c3e96a2SHermès Bélusca-Maïto     ULONG DescriptionSize;
15257c3e96a2SHermès Bélusca-Maïto     ULONG StandardNameSize;
15267c3e96a2SHermès Bélusca-Maïto     ULONG DaylightNameSize;
1527c2c66affSColin Finck 
1528c2c66affSColin Finck     Entry = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(TIMEZONE_ENTRY));
1529c2c66affSColin Finck     if (Entry == NULL)
1530c2c66affSColin Finck     {
15317c3e96a2SHermès Bélusca-Maïto         return ERROR_NOT_ENOUGH_MEMORY;
1532c2c66affSColin Finck     }
1533c2c66affSColin Finck 
15347c3e96a2SHermès Bélusca-Maïto     DescriptionSize  = sizeof(Entry->Description);
15357c3e96a2SHermès Bélusca-Maïto     StandardNameSize = sizeof(Entry->StandardName);
15367c3e96a2SHermès Bélusca-Maïto     DaylightNameSize = sizeof(Entry->DaylightName);
15377c3e96a2SHermès Bélusca-Maïto 
15387c3e96a2SHermès Bélusca-Maïto     lError = QueryTimeZoneData(hZoneKey,
15397c3e96a2SHermès Bélusca-Maïto                                &Entry->Index,
15407c3e96a2SHermès Bélusca-Maïto                                &Entry->TimezoneInfo,
15417c3e96a2SHermès Bélusca-Maïto                                Entry->Description,
15427c3e96a2SHermès Bélusca-Maïto                                &DescriptionSize,
15437c3e96a2SHermès Bélusca-Maïto                                Entry->StandardName,
15447c3e96a2SHermès Bélusca-Maïto                                &StandardNameSize,
15457c3e96a2SHermès Bélusca-Maïto                                Entry->DaylightName,
15467c3e96a2SHermès Bélusca-Maïto                                &DaylightNameSize);
15477c3e96a2SHermès Bélusca-Maïto     if (lError != ERROR_SUCCESS)
1548c2c66affSColin Finck     {
15497c3e96a2SHermès Bélusca-Maïto         HeapFree(GetProcessHeap(), 0, Entry);
15507c3e96a2SHermès Bélusca-Maïto         return lError;
1551c2c66affSColin Finck     }
1552c2c66affSColin Finck 
1553c2c66affSColin Finck     if (SetupData->TimeZoneListHead == NULL &&
1554c2c66affSColin Finck         SetupData->TimeZoneListTail == NULL)
1555c2c66affSColin Finck     {
1556c2c66affSColin Finck         Entry->Prev = NULL;
1557c2c66affSColin Finck         Entry->Next = NULL;
1558c2c66affSColin Finck         SetupData->TimeZoneListHead = Entry;
1559c2c66affSColin Finck         SetupData->TimeZoneListTail = Entry;
1560c2c66affSColin Finck     }
1561c2c66affSColin Finck     else
1562c2c66affSColin Finck     {
1563c2c66affSColin Finck         Current = GetLargerTimeZoneEntry(SetupData, Entry->Index);
1564c2c66affSColin Finck         if (Current != NULL)
1565c2c66affSColin Finck         {
1566c2c66affSColin Finck             if (Current == SetupData->TimeZoneListHead)
1567c2c66affSColin Finck             {
1568c2c66affSColin Finck                 /* Prepend to head */
1569c2c66affSColin Finck                 Entry->Prev = NULL;
1570c2c66affSColin Finck                 Entry->Next = SetupData->TimeZoneListHead;
1571c2c66affSColin Finck                 SetupData->TimeZoneListHead->Prev = Entry;
1572c2c66affSColin Finck                 SetupData->TimeZoneListHead = Entry;
1573c2c66affSColin Finck             }
1574c2c66affSColin Finck             else
1575c2c66affSColin Finck             {
1576c2c66affSColin Finck                 /* Insert before current */
1577c2c66affSColin Finck                 Entry->Prev = Current->Prev;
1578c2c66affSColin Finck                 Entry->Next = Current;
1579c2c66affSColin Finck                 Current->Prev->Next = Entry;
1580c2c66affSColin Finck                 Current->Prev = Entry;
1581c2c66affSColin Finck             }
1582c2c66affSColin Finck         }
1583c2c66affSColin Finck         else
1584c2c66affSColin Finck         {
1585c2c66affSColin Finck             /* Append to tail */
1586c2c66affSColin Finck             Entry->Prev = SetupData->TimeZoneListTail;
1587c2c66affSColin Finck             Entry->Next = NULL;
1588c2c66affSColin Finck             SetupData->TimeZoneListTail->Next = Entry;
1589c2c66affSColin Finck             SetupData->TimeZoneListTail = Entry;
1590c2c66affSColin Finck         }
1591c2c66affSColin Finck     }
1592c2c66affSColin Finck 
15937c3e96a2SHermès Bélusca-Maïto     return ERROR_SUCCESS;
1594c2c66affSColin Finck }
1595c2c66affSColin Finck 
15967c3e96a2SHermès Bélusca-Maïto static VOID
CreateTimeZoneList(PSETUPDATA SetupData)15977c3e96a2SHermès Bélusca-Maïto CreateTimeZoneList(PSETUPDATA SetupData)
15987c3e96a2SHermès Bélusca-Maïto {
15997c3e96a2SHermès Bélusca-Maïto     EnumerateTimeZoneList(RetrieveTimeZone, SetupData);
1600c2c66affSColin Finck }
1601c2c66affSColin Finck 
1602c2c66affSColin Finck static VOID
DestroyTimeZoneList(PSETUPDATA SetupData)1603c2c66affSColin Finck DestroyTimeZoneList(PSETUPDATA SetupData)
1604c2c66affSColin Finck {
1605c2c66affSColin Finck     PTIMEZONE_ENTRY Entry;
1606c2c66affSColin Finck 
1607c2c66affSColin Finck     while (SetupData->TimeZoneListHead != NULL)
1608c2c66affSColin Finck     {
1609c2c66affSColin Finck         Entry = SetupData->TimeZoneListHead;
1610c2c66affSColin Finck 
1611c2c66affSColin Finck         SetupData->TimeZoneListHead = Entry->Next;
1612c2c66affSColin Finck         if (SetupData->TimeZoneListHead != NULL)
1613c2c66affSColin Finck         {
1614c2c66affSColin Finck             SetupData->TimeZoneListHead->Prev = NULL;
1615c2c66affSColin Finck         }
1616c2c66affSColin Finck 
1617c2c66affSColin Finck         HeapFree(GetProcessHeap(), 0, Entry);
1618c2c66affSColin Finck     }
1619c2c66affSColin Finck 
1620c2c66affSColin Finck     SetupData->TimeZoneListTail = NULL;
1621c2c66affSColin Finck }
1622c2c66affSColin Finck 
1623c2c66affSColin Finck 
1624c2c66affSColin Finck static VOID
ShowTimeZoneList(HWND hwnd,PSETUPDATA SetupData,DWORD dwEntryIndex)1625c2c66affSColin Finck ShowTimeZoneList(HWND hwnd, PSETUPDATA SetupData, DWORD dwEntryIndex)
1626c2c66affSColin Finck {
1627c2c66affSColin Finck     PTIMEZONE_ENTRY Entry;
1628c2c66affSColin Finck     DWORD dwIndex = 0;
1629c2c66affSColin Finck     DWORD dwCount;
1630c2c66affSColin Finck 
1631c2c66affSColin Finck     GetTimeZoneListIndex(&dwEntryIndex);
1632c2c66affSColin Finck 
1633c2c66affSColin Finck     Entry = SetupData->TimeZoneListHead;
1634c2c66affSColin Finck     while (Entry != NULL)
1635c2c66affSColin Finck     {
1636c2c66affSColin Finck         dwCount = SendMessage(hwnd,
1637c2c66affSColin Finck                               CB_ADDSTRING,
1638c2c66affSColin Finck                               0,
1639c2c66affSColin Finck                               (LPARAM)Entry->Description);
1640c2c66affSColin Finck 
1641c2c66affSColin Finck         if (dwEntryIndex != 0 && dwEntryIndex == Entry->Index)
1642c2c66affSColin Finck             dwIndex = dwCount;
1643c2c66affSColin Finck 
1644c2c66affSColin Finck         Entry = Entry->Next;
1645c2c66affSColin Finck     }
1646c2c66affSColin Finck 
1647c2c66affSColin Finck     SendMessage(hwnd,
1648c2c66affSColin Finck                 CB_SETCURSEL,
1649c2c66affSColin Finck                 (WPARAM)dwIndex,
1650c2c66affSColin Finck                 0);
1651c2c66affSColin Finck }
1652c2c66affSColin Finck 
1653c2c66affSColin Finck 
1654c2c66affSColin Finck static VOID
SetLocalTimeZone(HWND hwnd,PSETUPDATA SetupData)1655c2c66affSColin Finck SetLocalTimeZone(HWND hwnd, PSETUPDATA SetupData)
1656c2c66affSColin Finck {
1657c2c66affSColin Finck     TIME_ZONE_INFORMATION TimeZoneInformation;
1658c2c66affSColin Finck     PTIMEZONE_ENTRY Entry;
1659c2c66affSColin Finck     DWORD dwIndex;
1660c2c66affSColin Finck     DWORD i;
1661c2c66affSColin Finck 
1662c2c66affSColin Finck     dwIndex = SendMessage(hwnd,
1663c2c66affSColin Finck                           CB_GETCURSEL,
1664c2c66affSColin Finck                           0,
1665c2c66affSColin Finck                           0);
1666c2c66affSColin Finck 
1667c2c66affSColin Finck     i = 0;
1668c2c66affSColin Finck     Entry = SetupData->TimeZoneListHead;
1669c2c66affSColin Finck     while (i < dwIndex)
1670c2c66affSColin Finck     {
1671c2c66affSColin Finck         if (Entry == NULL)
1672c2c66affSColin Finck             return;
1673c2c66affSColin Finck 
1674c2c66affSColin Finck         i++;
1675c2c66affSColin Finck         Entry = Entry->Next;
1676c2c66affSColin Finck     }
1677c2c66affSColin Finck 
1678c2c66affSColin Finck     wcscpy(TimeZoneInformation.StandardName,
1679c2c66affSColin Finck            Entry->StandardName);
1680c2c66affSColin Finck     wcscpy(TimeZoneInformation.DaylightName,
1681c2c66affSColin Finck            Entry->DaylightName);
1682c2c66affSColin Finck 
1683c2c66affSColin Finck     TimeZoneInformation.Bias = Entry->TimezoneInfo.Bias;
1684c2c66affSColin Finck     TimeZoneInformation.StandardBias = Entry->TimezoneInfo.StandardBias;
1685c2c66affSColin Finck     TimeZoneInformation.DaylightBias = Entry->TimezoneInfo.DaylightBias;
1686c2c66affSColin Finck 
1687c2c66affSColin Finck     memcpy(&TimeZoneInformation.StandardDate,
1688c2c66affSColin Finck            &Entry->TimezoneInfo.StandardDate,
1689c2c66affSColin Finck            sizeof(SYSTEMTIME));
1690c2c66affSColin Finck     memcpy(&TimeZoneInformation.DaylightDate,
1691c2c66affSColin Finck            &Entry->TimezoneInfo.DaylightDate,
1692c2c66affSColin Finck            sizeof(SYSTEMTIME));
1693c2c66affSColin Finck 
1694c2c66affSColin Finck     /* Set time zone information */
1695c2c66affSColin Finck     SetTimeZoneInformation(&TimeZoneInformation);
1696c2c66affSColin Finck }
1697c2c66affSColin Finck 
1698c2c66affSColin Finck 
1699c2c66affSColin Finck static BOOL
GetLocalSystemTime(HWND hwnd,PSETUPDATA SetupData)1700c2c66affSColin Finck GetLocalSystemTime(HWND hwnd, PSETUPDATA SetupData)
1701c2c66affSColin Finck {
1702c2c66affSColin Finck     SYSTEMTIME Date;
1703c2c66affSColin Finck     SYSTEMTIME Time;
1704c2c66affSColin Finck 
1705c2c66affSColin Finck     if (DateTime_GetSystemtime(GetDlgItem(hwnd, IDC_DATEPICKER), &Date) != GDT_VALID)
1706c2c66affSColin Finck     {
1707c2c66affSColin Finck         return FALSE;
1708c2c66affSColin Finck     }
1709c2c66affSColin Finck 
1710c2c66affSColin Finck     if (DateTime_GetSystemtime(GetDlgItem(hwnd, IDC_TIMEPICKER), &Time) != GDT_VALID)
1711c2c66affSColin Finck     {
1712c2c66affSColin Finck         return FALSE;
1713c2c66affSColin Finck     }
1714c2c66affSColin Finck 
1715c2c66affSColin Finck     SetupData->SystemTime.wYear = Date.wYear;
1716c2c66affSColin Finck     SetupData->SystemTime.wMonth = Date.wMonth;
1717c2c66affSColin Finck     SetupData->SystemTime.wDayOfWeek = Date.wDayOfWeek;
1718c2c66affSColin Finck     SetupData->SystemTime.wDay = Date.wDay;
1719c2c66affSColin Finck     SetupData->SystemTime.wHour = Time.wHour;
1720c2c66affSColin Finck     SetupData->SystemTime.wMinute = Time.wMinute;
1721c2c66affSColin Finck     SetupData->SystemTime.wSecond = Time.wSecond;
1722c2c66affSColin Finck     SetupData->SystemTime.wMilliseconds = Time.wMilliseconds;
1723c2c66affSColin Finck 
1724c2c66affSColin Finck     return TRUE;
1725c2c66affSColin Finck }
1726c2c66affSColin Finck 
1727c2c66affSColin Finck 
1728c2c66affSColin Finck static BOOL
SetSystemLocalTime(HWND hwnd,PSETUPDATA SetupData)1729c2c66affSColin Finck SetSystemLocalTime(HWND hwnd, PSETUPDATA SetupData)
1730c2c66affSColin Finck {
1731c2c66affSColin Finck     BOOL Ret = FALSE;
1732c2c66affSColin Finck 
1733c2c66affSColin Finck     /*
1734c2c66affSColin Finck      * Call SetLocalTime twice to ensure correct results
1735c2c66affSColin Finck      */
1736c2c66affSColin Finck     Ret = SetLocalTime(&SetupData->SystemTime) &&
1737c2c66affSColin Finck           SetLocalTime(&SetupData->SystemTime);
1738c2c66affSColin Finck 
1739c2c66affSColin Finck     return Ret;
1740c2c66affSColin Finck }
1741c2c66affSColin Finck 
1742c2c66affSColin Finck 
1743c2c66affSColin Finck static VOID
UpdateLocalSystemTime(HWND hwnd,SYSTEMTIME LocalTime)17444cd92f0dSSerge Gautherie UpdateLocalSystemTime(HWND hwnd, SYSTEMTIME LocalTime)
1745c2c66affSColin Finck {
1746c2c66affSColin Finck     DateTime_SetSystemtime(GetDlgItem(hwnd, IDC_DATEPICKER), GDT_VALID, &LocalTime);
1747c2c66affSColin Finck     DateTime_SetSystemtime(GetDlgItem(hwnd, IDC_TIMEPICKER), GDT_VALID, &LocalTime);
1748c2c66affSColin Finck }
1749c2c66affSColin Finck 
1750c2c66affSColin Finck 
1751c2c66affSColin Finck static BOOL
WriteDateTimeSettings(HWND hwndDlg,PSETUPDATA SetupData)1752c2c66affSColin Finck WriteDateTimeSettings(HWND hwndDlg, PSETUPDATA SetupData)
1753c2c66affSColin Finck {
1754c2c66affSColin Finck     WCHAR Title[64];
1755c2c66affSColin Finck     WCHAR ErrorLocalTime[256];
1756c2c66affSColin Finck 
1757c2c66affSColin Finck     GetLocalSystemTime(hwndDlg, SetupData);
1758c2c66affSColin Finck     SetLocalTimeZone(GetDlgItem(hwndDlg, IDC_TIMEZONELIST),
1759c2c66affSColin Finck                      SetupData);
1760c2c66affSColin Finck 
17617c3e96a2SHermès Bélusca-Maïto     SetAutoDaylight(SendDlgItemMessage(hwndDlg, IDC_AUTODAYLIGHT,
17627c3e96a2SHermès Bélusca-Maïto                                        BM_GETCHECK, 0, 0) != BST_UNCHECKED);
1763c2c66affSColin Finck     if (!SetSystemLocalTime(hwndDlg, SetupData))
1764c2c66affSColin Finck     {
176562678985SHermès Bélusca-Maïto         if (0 == LoadStringW(hDllInstance, IDS_REACTOS_SETUP, Title, ARRAYSIZE(Title)))
1766c2c66affSColin Finck         {
1767c2c66affSColin Finck             wcscpy(Title, L"ReactOS Setup");
1768c2c66affSColin Finck         }
1769c2c66affSColin Finck         if (0 == LoadStringW(hDllInstance, IDS_WZD_LOCALTIME, ErrorLocalTime,
177062678985SHermès Bélusca-Maïto                              ARRAYSIZE(ErrorLocalTime)))
1771c2c66affSColin Finck         {
1772c2c66affSColin Finck             wcscpy(ErrorLocalTime, L"Setup was unable to set the local time.");
1773c2c66affSColin Finck         }
1774c2c66affSColin Finck         MessageBoxW(hwndDlg, ErrorLocalTime, Title, MB_ICONWARNING | MB_OK);
1775c2c66affSColin Finck         return FALSE;
1776c2c66affSColin Finck     }
1777c2c66affSColin Finck 
1778c2c66affSColin Finck     return TRUE;
1779c2c66affSColin Finck }
1780c2c66affSColin Finck 
1781c2c66affSColin Finck 
1782c2c66affSColin Finck static INT_PTR CALLBACK
DateTimePageDlgProc(HWND hwndDlg,UINT uMsg,WPARAM wParam,LPARAM lParam)1783c2c66affSColin Finck DateTimePageDlgProc(HWND hwndDlg,
1784c2c66affSColin Finck                     UINT uMsg,
1785c2c66affSColin Finck                     WPARAM wParam,
1786c2c66affSColin Finck                     LPARAM lParam)
1787c2c66affSColin Finck {
1788c2c66affSColin Finck     PSETUPDATA SetupData;
1789c2c66affSColin Finck 
1790c2c66affSColin Finck     /* Retrieve pointer to the global setup data */
1791d281d14fSTimo Kreuzer     SetupData = (PSETUPDATA)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
1792c2c66affSColin Finck 
1793c2c66affSColin Finck     switch (uMsg)
1794c2c66affSColin Finck     {
1795c2c66affSColin Finck         case WM_INITDIALOG:
17967c3e96a2SHermès Bélusca-Maïto         {
1797c2c66affSColin Finck             /* Save pointer to the global setup data */
1798c2c66affSColin Finck             SetupData = (PSETUPDATA)((LPPROPSHEETPAGE)lParam)->lParam;
1799d281d14fSTimo Kreuzer             SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (DWORD_PTR)SetupData);
1800c2c66affSColin Finck 
1801c2c66affSColin Finck             CreateTimeZoneList(SetupData);
1802c2c66affSColin Finck 
1803c2c66affSColin Finck             if (SetupData->UnattendSetup)
1804c2c66affSColin Finck             {
1805c2c66affSColin Finck                 ShowTimeZoneList(GetDlgItem(hwndDlg, IDC_TIMEZONELIST),
1806c2c66affSColin Finck                                  SetupData, SetupData->TimeZoneIndex);
1807c2c66affSColin Finck 
1808c2c66affSColin Finck                 if (!SetupData->DisableAutoDaylightTimeSet)
1809c2c66affSColin Finck                 {
1810c2c66affSColin Finck                     SendDlgItemMessage(hwndDlg, IDC_AUTODAYLIGHT, BM_SETCHECK, (WPARAM)BST_CHECKED, 0);
1811c2c66affSColin Finck                 }
1812c2c66affSColin Finck             }
1813c2c66affSColin Finck             else
1814c2c66affSColin Finck             {
1815c2c66affSColin Finck                 ShowTimeZoneList(GetDlgItem(hwndDlg, IDC_TIMEZONELIST),
1816c2c66affSColin Finck                                  SetupData, -1);
1817c2c66affSColin Finck 
1818c2c66affSColin Finck                 SendDlgItemMessage(hwndDlg, IDC_AUTODAYLIGHT, BM_SETCHECK, (WPARAM)BST_CHECKED, 0);
1819c2c66affSColin Finck             }
1820c2c66affSColin Finck             break;
18217c3e96a2SHermès Bélusca-Maïto         }
1822c2c66affSColin Finck 
1823c2c66affSColin Finck         case WM_TIMER:
18244cd92f0dSSerge Gautherie         {
18254cd92f0dSSerge Gautherie             SYSTEMTIME LocalTime;
18264cd92f0dSSerge Gautherie 
18274cd92f0dSSerge Gautherie             GetLocalTime(&LocalTime);
18284cd92f0dSSerge Gautherie             UpdateLocalSystemTime(hwndDlg, LocalTime);
18294cd92f0dSSerge Gautherie 
18304cd92f0dSSerge Gautherie             // Reset timeout.
18314cd92f0dSSerge Gautherie             SetTimer(hwndDlg, 1, 1000 - LocalTime.wMilliseconds, NULL);
1832c2c66affSColin Finck             break;
18334cd92f0dSSerge Gautherie         }
1834c2c66affSColin Finck 
1835c2c66affSColin Finck         case WM_NOTIFY:
1836c2c66affSColin Finck             switch (((LPNMHDR)lParam)->code)
1837c2c66affSColin Finck             {
1838c2c66affSColin Finck                 case PSN_SETACTIVE:
18394cd92f0dSSerge Gautherie                 {
18404cd92f0dSSerge Gautherie                     SYSTEMTIME LocalTime;
18414cd92f0dSSerge Gautherie 
18424cd92f0dSSerge Gautherie                     GetLocalTime(&LocalTime);
18434cd92f0dSSerge Gautherie                     UpdateLocalSystemTime(hwndDlg, LocalTime);
18444cd92f0dSSerge Gautherie 
1845c2c66affSColin Finck                     /* Enable the Back and Next buttons */
1846c2c66affSColin Finck                     PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK | PSWIZB_NEXT);
18474cd92f0dSSerge Gautherie 
1848c2c66affSColin Finck                     if (SetupData->UnattendSetup && WriteDateTimeSettings(hwndDlg, SetupData))
1849c2c66affSColin Finck                     {
18500182dcd7STimo Kreuzer                         SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, SetupData->uFirstNetworkWizardPage);
1851c2c66affSColin Finck                         return TRUE;
1852c2c66affSColin Finck                     }
18534cd92f0dSSerge Gautherie 
18544cd92f0dSSerge Gautherie                     SetTimer(hwndDlg, 1, 1000 - LocalTime.wMilliseconds, NULL);
1855c2c66affSColin Finck                     break;
18564cd92f0dSSerge Gautherie                 }
1857c2c66affSColin Finck 
1858c2c66affSColin Finck                 case PSN_KILLACTIVE:
1859c2c66affSColin Finck                 case DTN_DATETIMECHANGE:
18604cd92f0dSSerge Gautherie                     // NB: Not re-set until changing page (PSN_SETACTIVE).
1861c2c66affSColin Finck                     KillTimer(hwndDlg, 1);
1862c2c66affSColin Finck                     break;
1863c2c66affSColin Finck 
1864c2c66affSColin Finck                 case PSN_WIZNEXT:
1865c2c66affSColin Finck                     WriteDateTimeSettings(hwndDlg, SetupData);
1866c2c66affSColin Finck                     break;
1867c2c66affSColin Finck 
1868c2c66affSColin Finck                 case PSN_WIZBACK:
1869c2c66affSColin Finck                     SetupData->UnattendSetup = FALSE;
1870c2c66affSColin Finck                     break;
1871c2c66affSColin Finck 
1872c2c66affSColin Finck                 default:
1873c2c66affSColin Finck                     break;
1874c2c66affSColin Finck             }
1875c2c66affSColin Finck             break;
1876c2c66affSColin Finck 
1877c2c66affSColin Finck         case WM_DESTROY:
1878c2c66affSColin Finck             DestroyTimeZoneList(SetupData);
1879c2c66affSColin Finck             break;
1880c2c66affSColin Finck 
1881c2c66affSColin Finck         default:
1882c2c66affSColin Finck             break;
1883c2c66affSColin Finck     }
1884c2c66affSColin Finck 
1885c2c66affSColin Finck     return FALSE;
1886c2c66affSColin Finck }
1887c2c66affSColin Finck 
18885d4d48a8SMark Jansen static struct ThemeInfo
18895d4d48a8SMark Jansen {
18905d4d48a8SMark Jansen     LPCWSTR PreviewBitmap;
18915d4d48a8SMark Jansen     UINT DisplayName;
18925d4d48a8SMark Jansen     LPCWSTR ThemeFile;
18935d4d48a8SMark Jansen 
18945d4d48a8SMark Jansen } Themes[] = {
18955d4d48a8SMark Jansen     { MAKEINTRESOURCE(IDB_CLASSIC), IDS_CLASSIC, NULL },
18965d4d48a8SMark Jansen     { MAKEINTRESOURCE(IDB_LAUTUS), IDS_LAUTUS, L"themes\\lautus\\lautus.msstyles" },
189721b7648fSAdam Słaboń     { MAKEINTRESOURCE(IDB_LUNAR), IDS_LUNAR, L"themes\\lunar\\lunar.msstyles" },
1898ea799b74SFoxlet     { MAKEINTRESOURCE(IDB_MIZU), IDS_MIZU, L"themes\\mizu\\mizu.msstyles"},
18995d4d48a8SMark Jansen };
1900c2c66affSColin Finck 
1901c2c66affSColin Finck static INT_PTR CALLBACK
ThemePageDlgProc(HWND hwndDlg,UINT uMsg,WPARAM wParam,LPARAM lParam)1902c2c66affSColin Finck ThemePageDlgProc(HWND hwndDlg,
1903c2c66affSColin Finck                     UINT uMsg,
1904c2c66affSColin Finck                     WPARAM wParam,
1905c2c66affSColin Finck                     LPARAM lParam)
1906c2c66affSColin Finck {
1907c2c66affSColin Finck     PSETUPDATA SetupData;
19085d4d48a8SMark Jansen     LPNMLISTVIEW pnmv;
1909c2c66affSColin Finck 
1910c2c66affSColin Finck     /* Retrieve pointer to the global setup data */
1911d281d14fSTimo Kreuzer     SetupData = (PSETUPDATA)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
1912c2c66affSColin Finck 
1913c2c66affSColin Finck     switch (uMsg)
1914c2c66affSColin Finck     {
1915c2c66affSColin Finck         case WM_INITDIALOG:
1916c2c66affSColin Finck         {
19175d4d48a8SMark Jansen             HWND hListView;
19185d4d48a8SMark Jansen             HIMAGELIST himl;
19195d4d48a8SMark Jansen             DWORD n;
19205d4d48a8SMark Jansen             LVITEM lvi = {0};
1921c2c66affSColin Finck 
1922c2c66affSColin Finck             /* Save pointer to the global setup data */
1923c2c66affSColin Finck             SetupData = (PSETUPDATA)((LPPROPSHEETPAGE)lParam)->lParam;
1924d281d14fSTimo Kreuzer             SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (DWORD_PTR)SetupData);
1925c2c66affSColin Finck 
19265d4d48a8SMark Jansen             hListView = GetDlgItem(hwndDlg, IDC_THEMEPICKER);
1927c2c66affSColin Finck 
19285d4d48a8SMark Jansen             /* Common */
19295d4d48a8SMark Jansen             himl = ImageList_Create(180, 163, ILC_COLOR32 | ILC_MASK, ARRAYSIZE(Themes), 1);
19305d4d48a8SMark Jansen             lvi.mask = LVIF_TEXT | LVIF_IMAGE |LVIF_STATE;
1931c2c66affSColin Finck 
19325d4d48a8SMark Jansen             for (n = 0; n < ARRAYSIZE(Themes); ++n)
19335d4d48a8SMark Jansen             {
19345d4d48a8SMark Jansen                 WCHAR DisplayName[100] = {0};
19355d4d48a8SMark Jansen                 /* Load the bitmap */
19365d4d48a8SMark Jansen                 HANDLE image = LoadImageW(hDllInstance, Themes[n].PreviewBitmap, IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION);
19375d4d48a8SMark Jansen                 ImageList_AddMasked(himl, image, RGB(255,0,255));
19385d4d48a8SMark Jansen 
19395d4d48a8SMark Jansen                 /* Load the string */
19405d4d48a8SMark Jansen                 LoadStringW(hDllInstance, Themes[n].DisplayName, DisplayName, ARRAYSIZE(DisplayName));
19415d4d48a8SMark Jansen                 DisplayName[ARRAYSIZE(DisplayName)-1] = UNICODE_NULL;
19425d4d48a8SMark Jansen 
19435d4d48a8SMark Jansen                 /* Add the listview item */
19445d4d48a8SMark Jansen                 lvi.iItem  = n;
19455d4d48a8SMark Jansen                 lvi.iImage = n;
19465d4d48a8SMark Jansen                 lvi.pszText = DisplayName;
19475d4d48a8SMark Jansen                 ListView_InsertItem(hListView, &lvi);
19485d4d48a8SMark Jansen             }
19495d4d48a8SMark Jansen 
19505d4d48a8SMark Jansen             /* Register the imagelist */
19515d4d48a8SMark Jansen             ListView_SetImageList(hListView, himl, LVSIL_NORMAL);
19525d4d48a8SMark Jansen             /* Transparant background */
19535d4d48a8SMark Jansen             ListView_SetBkColor(hListView, CLR_NONE);
19545d4d48a8SMark Jansen             ListView_SetTextBkColor(hListView, CLR_NONE);
19555d4d48a8SMark Jansen             /* Reduce the size between the items */
19565d4d48a8SMark Jansen             ListView_SetIconSpacing(hListView, 190, 173);
1957c2c66affSColin Finck             break;
1958c2c66affSColin Finck         }
19595d4d48a8SMark Jansen         case WM_NOTIFY:
19605d4d48a8SMark Jansen             switch (((LPNMHDR)lParam)->code)
1961c2c66affSColin Finck             {
19625d4d48a8SMark Jansen                 //case LVN_ITEMCHANGING:
19635d4d48a8SMark Jansen                 case LVN_ITEMCHANGED:
19645d4d48a8SMark Jansen                     pnmv = (LPNMLISTVIEW)lParam;
19655d4d48a8SMark Jansen                     if ((pnmv->uChanged & LVIF_STATE) && (pnmv->uNewState & LVIS_SELECTED))
1966c2c66affSColin Finck                     {
19675d4d48a8SMark Jansen                         int iTheme = pnmv->iItem;
1968774f4977SMark Jansen                         DPRINT1("Selected theme: %u\n", Themes[iTheme].DisplayName);
19695d4d48a8SMark Jansen 
19705d4d48a8SMark Jansen                         if (Themes[iTheme].ThemeFile)
1971c2c66affSColin Finck                         {
1972c2c66affSColin Finck                             WCHAR wszParams[1024];
1973c2c66affSColin Finck                             WCHAR wszTheme[MAX_PATH];
1974*50d260a7SSplitwirez                             WCHAR* format = L"desk.cpl,,2 /Action:ActivateMSTheme /file:\"%s\"";
1975c2c66affSColin Finck 
19765d4d48a8SMark Jansen                             SHGetFolderPathAndSubDirW(0, CSIDL_RESOURCES, NULL, SHGFP_TYPE_DEFAULT, Themes[iTheme].ThemeFile, wszTheme);
1977c2c66affSColin Finck                             swprintf(wszParams, format, wszTheme);
1978c2c66affSColin Finck                             RunControlPanelApplet(hwndDlg, wszParams);
1979c2c66affSColin Finck                         }
19805d4d48a8SMark Jansen                         else
1981c2c66affSColin Finck                         {
1982*50d260a7SSplitwirez                             RunControlPanelApplet(hwndDlg, L"desk.cpl,,2 /Action:ActivateMSTheme");
19835d4d48a8SMark Jansen                         }
19845d4d48a8SMark Jansen                     }
19855d4d48a8SMark Jansen                     break;
1986c2c66affSColin Finck                 case PSN_SETACTIVE:
1987c2c66affSColin Finck                     /* Enable the Back and Next buttons */
1988c2c66affSColin Finck                     PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK | PSWIZB_NEXT);
1989c2c66affSColin Finck                     if (SetupData->UnattendSetup)
1990c2c66affSColin Finck                     {
19910182dcd7STimo Kreuzer                         SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, SetupData->uFirstNetworkWizardPage);
1992c2c66affSColin Finck                         return TRUE;
1993c2c66affSColin Finck                     }
1994c2c66affSColin Finck                     break;
1995c2c66affSColin Finck 
1996c2c66affSColin Finck                 case PSN_WIZNEXT:
1997c2c66affSColin Finck                     break;
1998c2c66affSColin Finck 
1999c2c66affSColin Finck                 case PSN_WIZBACK:
2000c2c66affSColin Finck                     SetupData->UnattendSetup = FALSE;
2001c2c66affSColin Finck                     break;
2002c2c66affSColin Finck 
2003c2c66affSColin Finck                 default:
2004c2c66affSColin Finck                     break;
2005c2c66affSColin Finck             }
2006c2c66affSColin Finck             break;
2007c2c66affSColin Finck 
2008c2c66affSColin Finck         default:
2009c2c66affSColin Finck             break;
2010c2c66affSColin Finck     }
2011c2c66affSColin Finck 
2012c2c66affSColin Finck     return FALSE;
2013c2c66affSColin Finck }
2014c2c66affSColin Finck 
2015c2c66affSColin Finck static UINT CALLBACK
RegistrationNotificationProc(PVOID Context,UINT Notification,UINT_PTR Param1,UINT_PTR Param2)2016c2c66affSColin Finck RegistrationNotificationProc(PVOID Context,
2017c2c66affSColin Finck                              UINT Notification,
2018c2c66affSColin Finck                              UINT_PTR Param1,
2019c2c66affSColin Finck                              UINT_PTR Param2)
2020c2c66affSColin Finck {
2021c2c66affSColin Finck     PREGISTRATIONDATA RegistrationData;
2022c2c66affSColin Finck     REGISTRATIONNOTIFY RegistrationNotify;
2023c2c66affSColin Finck     PSP_REGISTER_CONTROL_STATUSW StatusInfo;
2024c2c66affSColin Finck     UINT MessageID;
2025c2c66affSColin Finck 
2026c2c66affSColin Finck     RegistrationData = (PREGISTRATIONDATA)Context;
2027c2c66affSColin Finck 
20283f053db3SEric Kohl     if (Notification == SPFILENOTIFY_STARTREGISTRATION ||
20293f053db3SEric Kohl         Notification == SPFILENOTIFY_ENDREGISTRATION)
2030c2c66affSColin Finck     {
2031c2c66affSColin Finck         StatusInfo = (PSP_REGISTER_CONTROL_STATUSW) Param1;
2032c2c66affSColin Finck         RegistrationNotify.CurrentItem = wcsrchr(StatusInfo->FileName, L'\\');
20333f053db3SEric Kohl         if (RegistrationNotify.CurrentItem == NULL)
2034c2c66affSColin Finck         {
2035c2c66affSColin Finck             RegistrationNotify.CurrentItem = StatusInfo->FileName;
2036c2c66affSColin Finck         }
2037c2c66affSColin Finck         else
2038c2c66affSColin Finck         {
2039c2c66affSColin Finck             RegistrationNotify.CurrentItem++;
2040c2c66affSColin Finck         }
2041c2c66affSColin Finck 
20423f053db3SEric Kohl         if (Notification == SPFILENOTIFY_STARTREGISTRATION)
2043c2c66affSColin Finck         {
2044c2c66affSColin Finck             DPRINT("Received SPFILENOTIFY_STARTREGISTRATION notification for %S\n",
2045c2c66affSColin Finck                    StatusInfo->FileName);
2046c2c66affSColin Finck             RegistrationNotify.ErrorMessage = NULL;
2047c2c66affSColin Finck             RegistrationNotify.Progress = RegistrationData->Registered;
20483f053db3SEric Kohl             SendMessage(RegistrationData->hwndDlg, PM_STEP_START, 0, (LPARAM)&RegistrationNotify);
2049c2c66affSColin Finck         }
2050c2c66affSColin Finck         else
2051c2c66affSColin Finck         {
2052c2c66affSColin Finck             DPRINT("Received SPFILENOTIFY_ENDREGISTRATION notification for %S\n",
2053c2c66affSColin Finck                    StatusInfo->FileName);
2054c2c66affSColin Finck             DPRINT("Win32Error %u FailureCode %u\n", StatusInfo->Win32Error,
2055c2c66affSColin Finck                    StatusInfo->FailureCode);
20563f053db3SEric Kohl             if (StatusInfo->FailureCode != SPREG_SUCCESS)
2057c2c66affSColin Finck             {
2058c2c66affSColin Finck                 switch (StatusInfo->FailureCode)
2059c2c66affSColin Finck                 {
2060c2c66affSColin Finck                     case SPREG_LOADLIBRARY:
2061c2c66affSColin Finck                         MessageID = IDS_LOADLIBRARY_FAILED;
2062c2c66affSColin Finck                         break;
2063c2c66affSColin Finck                     case SPREG_GETPROCADDR:
2064c2c66affSColin Finck                         MessageID = IDS_GETPROCADDR_FAILED;
2065c2c66affSColin Finck                         break;
2066c2c66affSColin Finck                     case SPREG_REGSVR:
2067c2c66affSColin Finck                         MessageID = IDS_REGSVR_FAILED;
2068c2c66affSColin Finck                         break;
2069c2c66affSColin Finck                     case SPREG_DLLINSTALL:
2070c2c66affSColin Finck                         MessageID = IDS_DLLINSTALL_FAILED;
2071c2c66affSColin Finck                         break;
2072c2c66affSColin Finck                     case SPREG_TIMEOUT:
2073c2c66affSColin Finck                         MessageID = IDS_TIMEOUT;
2074c2c66affSColin Finck                         break;
2075c2c66affSColin Finck                     default:
2076c2c66affSColin Finck                         MessageID = IDS_REASON_UNKNOWN;
2077c2c66affSColin Finck                         break;
2078c2c66affSColin Finck                 }
20793f053db3SEric Kohl 
20803f053db3SEric Kohl                 RegistrationNotify.MessageID = MessageID;
20813f053db3SEric Kohl                 RegistrationNotify.LastError = StatusInfo->Win32Error;
2082c2c66affSColin Finck             }
2083c2c66affSColin Finck             else
2084c2c66affSColin Finck             {
20853f053db3SEric Kohl                 RegistrationNotify.MessageID = 0;
20863f053db3SEric Kohl                 RegistrationNotify.LastError = ERROR_SUCCESS;
2087c2c66affSColin Finck             }
20883f053db3SEric Kohl 
2089c2c66affSColin Finck             if (RegistrationData->Registered < RegistrationData->DllCount)
2090c2c66affSColin Finck             {
2091c2c66affSColin Finck                 RegistrationData->Registered++;
2092c2c66affSColin Finck             }
2093c2c66affSColin Finck 
2094c2c66affSColin Finck             RegistrationNotify.Progress = RegistrationData->Registered;
20953f053db3SEric Kohl             SendMessage(RegistrationData->hwndDlg, PM_STEP_END, 0, (LPARAM)&RegistrationNotify);
20963f053db3SEric Kohl         }
2097c2c66affSColin Finck 
2098c2c66affSColin Finck         return FILEOP_DOIT;
2099c2c66affSColin Finck     }
2100c2c66affSColin Finck     else
2101c2c66affSColin Finck     {
2102c2c66affSColin Finck         DPRINT1("Received unexpected notification %u\n", Notification);
2103c2c66affSColin Finck         return SetupDefaultQueueCallback(RegistrationData->DefaultContext,
2104c2c66affSColin Finck                                          Notification, Param1, Param2);
2105c2c66affSColin Finck     }
2106c2c66affSColin Finck }
2107c2c66affSColin Finck 
2108c2c66affSColin Finck 
21093f053db3SEric Kohl static
21103f053db3SEric Kohl DWORD
RegisterDlls(PITEMSDATA pItemsData)21113f053db3SEric Kohl RegisterDlls(
21123f053db3SEric Kohl     PITEMSDATA pItemsData)
2113c2c66affSColin Finck {
21143f053db3SEric Kohl     REGISTRATIONDATA RegistrationData;
21153f053db3SEric Kohl     WCHAR SectionName[512];
21163f053db3SEric Kohl     INFCONTEXT Context;
21173f053db3SEric Kohl     LONG DllCount = 0;
2118c2c66affSColin Finck     DWORD LastError = NO_ERROR;
2119c2c66affSColin Finck 
21203f053db3SEric Kohl     ZeroMemory(&RegistrationData, sizeof(REGISTRATIONDATA));
21213f053db3SEric Kohl     RegistrationData.hwndDlg = pItemsData->hwndDlg;
21223f053db3SEric Kohl     RegistrationData.Registered = 0;
21233f053db3SEric Kohl 
21243f053db3SEric Kohl     if (!SetupFindFirstLineW(hSysSetupInf, L"RegistrationPhase2",
21253f053db3SEric Kohl                              L"RegisterDlls", &Context))
21263f053db3SEric Kohl     {
21273f053db3SEric Kohl         DPRINT1("No RegistrationPhase2 section found\n");
21283f053db3SEric Kohl         return FALSE;
21293f053db3SEric Kohl     }
21303f053db3SEric Kohl 
21313f053db3SEric Kohl     if (!SetupGetStringFieldW(&Context, 1, SectionName,
21323f053db3SEric Kohl                               ARRAYSIZE(SectionName),
21333f053db3SEric Kohl                               NULL))
21343f053db3SEric Kohl     {
21353f053db3SEric Kohl         DPRINT1("Unable to retrieve section name\n");
21363f053db3SEric Kohl         return FALSE;
21373f053db3SEric Kohl     }
21383f053db3SEric Kohl 
21393f053db3SEric Kohl     DllCount = SetupGetLineCountW(hSysSetupInf, SectionName);
21403f053db3SEric Kohl     DPRINT1("SectionName %S DllCount %ld\n", SectionName, DllCount);
21413f053db3SEric Kohl     if (DllCount < 0)
21423f053db3SEric Kohl     {
21433f053db3SEric Kohl         SetLastError(STATUS_NOT_FOUND);
21443f053db3SEric Kohl         return FALSE;
21453f053db3SEric Kohl     }
21463f053db3SEric Kohl 
21473f053db3SEric Kohl     RegistrationData.DllCount = (ULONG)DllCount;
21483f053db3SEric Kohl     RegistrationData.DefaultContext = SetupInitDefaultQueueCallback(RegistrationData.hwndDlg);
21493f053db3SEric Kohl 
21503f053db3SEric Kohl     SendMessage(pItemsData->hwndDlg, PM_ITEM_START, 0, (LPARAM)RegistrationData.DllCount);
2151c2c66affSColin Finck 
2152c2c66affSColin Finck     _SEH2_TRY
2153c2c66affSColin Finck     {
21543f053db3SEric Kohl         if (!SetupInstallFromInfSectionW(GetParent(RegistrationData.hwndDlg),
2155c2c66affSColin Finck                                          hSysSetupInf,
2156c2c66affSColin Finck                                          L"RegistrationPhase2",
21573f053db3SEric Kohl                                          SPINST_REGISTRY | SPINST_REGISTERCALLBACKAWARE | SPINST_REGSVR,
2158c2c66affSColin Finck                                          0,
2159c2c66affSColin Finck                                          NULL,
2160c2c66affSColin Finck                                          0,
2161c2c66affSColin Finck                                          RegistrationNotificationProc,
21623f053db3SEric Kohl                                          &RegistrationData,
2163c2c66affSColin Finck                                          NULL,
2164c2c66affSColin Finck                                          NULL))
2165c2c66affSColin Finck         {
2166c2c66affSColin Finck             LastError = GetLastError();
2167c2c66affSColin Finck         }
2168c2c66affSColin Finck     }
2169c2c66affSColin Finck     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
2170c2c66affSColin Finck     {
2171c2c66affSColin Finck         DPRINT("Catching exception\n");
2172c2c66affSColin Finck         LastError = RtlNtStatusToDosError(_SEH2_GetExceptionCode());
2173c2c66affSColin Finck     }
2174c2c66affSColin Finck     _SEH2_END;
2175c2c66affSColin Finck 
21763f053db3SEric Kohl     SetupTermDefaultQueueCallback(RegistrationData.DefaultContext);
2177c2c66affSColin Finck 
21783f053db3SEric Kohl     SendMessage(pItemsData->hwndDlg, PM_ITEM_END, 0, LastError);
2179c2c66affSColin Finck 
2180c2c66affSColin Finck     return 0;
2181c2c66affSColin Finck }
2182c2c66affSColin Finck 
2183c2c66affSColin Finck 
21843f053db3SEric Kohl static
21853f053db3SEric Kohl DWORD
21863f053db3SEric Kohl CALLBACK
ItemCompletionThread(LPVOID Parameter)21873f053db3SEric Kohl ItemCompletionThread(
21883f053db3SEric Kohl     LPVOID Parameter)
2189c2c66affSColin Finck {
21903f053db3SEric Kohl     PITEMSDATA pItemsData;
21913f053db3SEric Kohl     HWND hwndDlg;
2192c2c66affSColin Finck 
21933f053db3SEric Kohl     pItemsData = (PITEMSDATA)Parameter;
21943f053db3SEric Kohl     hwndDlg = pItemsData->hwndDlg;
21953f053db3SEric Kohl 
21963f053db3SEric Kohl     RegisterDlls(pItemsData);
21973f053db3SEric Kohl 
21983f053db3SEric Kohl     RegisterTypeLibraries(hSysSetupInf, L"TypeLibraries");
21993f053db3SEric Kohl 
22003f053db3SEric Kohl     /* FIXME: Add completion steps here! */
22013f053db3SEric Kohl 
22023f053db3SEric Kohl     // FIXME: Move this call to a separate cleanup page!
22033f053db3SEric Kohl     RtlCreateBootStatusDataFile();
22043f053db3SEric Kohl 
22053f053db3SEric Kohl     /* Free the items data */
22063f053db3SEric Kohl     HeapFree(GetProcessHeap(), 0, pItemsData);
22073f053db3SEric Kohl 
22083f053db3SEric Kohl     /* Tell the wizard page that we are done */
22093f053db3SEric Kohl     PostMessage(hwndDlg, PM_ITEMS_DONE, 0, 0);
22103f053db3SEric Kohl 
22113f053db3SEric Kohl     return 0;
2212c2c66affSColin Finck }
2213c2c66affSColin Finck 
2214c2c66affSColin Finck 
22153f053db3SEric Kohl static
22163f053db3SEric Kohl BOOL
RunItemCompletionThread(_In_ HWND hwndDlg)22173f053db3SEric Kohl RunItemCompletionThread(
22183f053db3SEric Kohl     _In_ HWND hwndDlg)
2219c2c66affSColin Finck {
22203f053db3SEric Kohl     HANDLE hCompletionThread;
22213f053db3SEric Kohl     PITEMSDATA pItemsData;
22223f053db3SEric Kohl 
22233f053db3SEric Kohl     pItemsData = HeapAlloc(GetProcessHeap(), 0, sizeof(ITEMSDATA));
22243f053db3SEric Kohl     if (pItemsData == NULL)
22253f053db3SEric Kohl         return FALSE;
22263f053db3SEric Kohl 
22273f053db3SEric Kohl     pItemsData->hwndDlg = hwndDlg;
22283f053db3SEric Kohl 
22293f053db3SEric Kohl     hCompletionThread = CreateThread(NULL,
22303f053db3SEric Kohl                                      0,
22313f053db3SEric Kohl                                      ItemCompletionThread,
22323f053db3SEric Kohl                                      pItemsData,
22333f053db3SEric Kohl                                      0,
22343f053db3SEric Kohl                                      NULL);
22353f053db3SEric Kohl     if (hCompletionThread == NULL)
2236c2c66affSColin Finck     {
22373f053db3SEric Kohl         HeapFree(GetProcessHeap(), 0, pItemsData);
2238c2c66affSColin Finck     }
2239c2c66affSColin Finck     else
2240c2c66affSColin Finck     {
22413f053db3SEric Kohl         CloseHandle(hCompletionThread);
2242c2c66affSColin Finck         return TRUE;
2243c2c66affSColin Finck     }
2244c2c66affSColin Finck 
22453f053db3SEric Kohl     return FALSE;
22463f053db3SEric Kohl }
22473f053db3SEric Kohl 
22483f053db3SEric Kohl static
22493f053db3SEric Kohl VOID
ShowItemError(HWND hwndDlg,DWORD LastError)22503f053db3SEric Kohl ShowItemError(
22513f053db3SEric Kohl     HWND hwndDlg,
22523f053db3SEric Kohl     DWORD LastError)
22533f053db3SEric Kohl {
22543f053db3SEric Kohl     LPWSTR ErrorMessage = NULL;
22553f053db3SEric Kohl     WCHAR UnknownError[84];
22563f053db3SEric Kohl     WCHAR Title[64];
22573f053db3SEric Kohl 
22583f053db3SEric Kohl     if (FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
22593f053db3SEric Kohl                        NULL, LastError, 0, ErrorMessage, 0, NULL) == 0)
22603f053db3SEric Kohl     {
22613f053db3SEric Kohl         if (LoadStringW(hDllInstance, IDS_UNKNOWN_ERROR,
22623f053db3SEric Kohl                         UnknownError,
22633f053db3SEric Kohl                         ARRAYSIZE(UnknownError) - 20) == 0)
22643f053db3SEric Kohl         {
22653f053db3SEric Kohl             wcscpy(UnknownError, L"Unknown error");
22663f053db3SEric Kohl         }
22673f053db3SEric Kohl         wcscat(UnknownError, L" ");
22683f053db3SEric Kohl         _ultow(LastError, UnknownError + wcslen(UnknownError), 10);
22693f053db3SEric Kohl         ErrorMessage = UnknownError;
22703f053db3SEric Kohl     }
22713f053db3SEric Kohl 
22723f053db3SEric Kohl     if (ErrorMessage != NULL)
22733f053db3SEric Kohl     {
22743f053db3SEric Kohl         if (LoadStringW(hDllInstance, IDS_REACTOS_SETUP,
22753f053db3SEric Kohl                         Title, ARRAYSIZE(Title)) == 0)
22763f053db3SEric Kohl         {
22773f053db3SEric Kohl             wcscpy(Title, L"ReactOS Setup");
22783f053db3SEric Kohl         }
22793f053db3SEric Kohl 
22803f053db3SEric Kohl         MessageBoxW(hwndDlg, ErrorMessage, Title, MB_ICONERROR | MB_OK);
22813f053db3SEric Kohl     }
22823f053db3SEric Kohl 
22833f053db3SEric Kohl     if (ErrorMessage != NULL &&
22843f053db3SEric Kohl         ErrorMessage != UnknownError)
22853f053db3SEric Kohl     {
22863f053db3SEric Kohl         LocalFree(ErrorMessage);
22873f053db3SEric Kohl     }
22883f053db3SEric Kohl }
22893f053db3SEric Kohl 
22903f053db3SEric Kohl 
22913f053db3SEric Kohl static
22923f053db3SEric Kohl VOID
ShowStepError(HWND hwndDlg,PREGISTRATIONNOTIFY RegistrationNotify)22933f053db3SEric Kohl ShowStepError(
22943f053db3SEric Kohl     HWND hwndDlg,
22953f053db3SEric Kohl     PREGISTRATIONNOTIFY RegistrationNotify)
22963f053db3SEric Kohl {
22973f053db3SEric Kohl     WCHAR ErrorMessage[128];
22983f053db3SEric Kohl     WCHAR Title[64];
22993f053db3SEric Kohl 
23003f053db3SEric Kohl     if (LoadStringW(hDllInstance, RegistrationNotify->MessageID,
23013f053db3SEric Kohl                     ErrorMessage,
23023f053db3SEric Kohl                     ARRAYSIZE(ErrorMessage)) == 0)
23033f053db3SEric Kohl     {
23043f053db3SEric Kohl         ErrorMessage[0] = L'\0';
23053f053db3SEric Kohl     }
23063f053db3SEric Kohl 
23073f053db3SEric Kohl     if (RegistrationNotify->MessageID != IDS_TIMEOUT)
23083f053db3SEric Kohl     {
23093f053db3SEric Kohl         FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM, NULL,
23103f053db3SEric Kohl                        RegistrationNotify->LastError, 0,
23113f053db3SEric Kohl                        ErrorMessage + wcslen(ErrorMessage),
23123f053db3SEric Kohl                        ARRAYSIZE(ErrorMessage) - wcslen(ErrorMessage),
23133f053db3SEric Kohl                        NULL);
23143f053db3SEric Kohl     }
23153f053db3SEric Kohl 
23163f053db3SEric Kohl     if (ErrorMessage[0] != L'\0')
23173f053db3SEric Kohl     {
23183f053db3SEric Kohl         if (LoadStringW(hDllInstance, IDS_REACTOS_SETUP,
23193f053db3SEric Kohl                         Title, ARRAYSIZE(Title)) == 0)
23203f053db3SEric Kohl         {
23213f053db3SEric Kohl             wcscpy(Title, L"ReactOS Setup");
23223f053db3SEric Kohl         }
23233f053db3SEric Kohl 
23243f053db3SEric Kohl         MessageBoxW(hwndDlg, ErrorMessage,
23253f053db3SEric Kohl                     Title, MB_ICONERROR | MB_OK);
23263f053db3SEric Kohl     }
23273f053db3SEric Kohl }
23283f053db3SEric Kohl 
2329c2c66affSColin Finck 
2330c2c66affSColin Finck static INT_PTR CALLBACK
ProcessPageDlgProc(HWND hwndDlg,UINT uMsg,WPARAM wParam,LPARAM lParam)2331c2c66affSColin Finck ProcessPageDlgProc(HWND hwndDlg,
2332c2c66affSColin Finck                    UINT uMsg,
2333c2c66affSColin Finck                    WPARAM wParam,
2334c2c66affSColin Finck                    LPARAM lParam)
2335c2c66affSColin Finck {
2336c2c66affSColin Finck     PSETUPDATA SetupData;
2337c2c66affSColin Finck     PREGISTRATIONNOTIFY RegistrationNotify;
2338c2c66affSColin Finck 
2339c2c66affSColin Finck     /* Retrieve pointer to the global setup data */
2340d281d14fSTimo Kreuzer     SetupData = (PSETUPDATA)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
2341c2c66affSColin Finck 
2342c2c66affSColin Finck     switch (uMsg)
2343c2c66affSColin Finck     {
2344c2c66affSColin Finck         case WM_INITDIALOG:
2345c2c66affSColin Finck             /* Save pointer to the global setup data */
2346c2c66affSColin Finck             SetupData = (PSETUPDATA)((LPPROPSHEETPAGE)lParam)->lParam;
2347d281d14fSTimo Kreuzer             SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (DWORD_PTR)SetupData);
23483f053db3SEric Kohl             ShowWindow(GetDlgItem(hwndDlg, IDC_TASKTEXT2), SW_HIDE);
23493f053db3SEric Kohl             ShowWindow(GetDlgItem(hwndDlg, IDC_TASKTEXT3), SW_HIDE);
23503f053db3SEric Kohl             ShowWindow(GetDlgItem(hwndDlg, IDC_TASKTEXT4), SW_HIDE);
2351c2c66affSColin Finck             break;
2352c2c66affSColin Finck 
2353c2c66affSColin Finck         case WM_NOTIFY:
23543f053db3SEric Kohl             switch (((LPNMHDR)lParam)->code)
2355c2c66affSColin Finck             {
2356c2c66affSColin Finck                 case PSN_SETACTIVE:
2357c2c66affSColin Finck                     /* Disable the Back and Next buttons */
2358c2c66affSColin Finck                     PropSheet_SetWizButtons(GetParent(hwndDlg), 0);
23593f053db3SEric Kohl                     RunItemCompletionThread(hwndDlg);
2360c2c66affSColin Finck                     break;
2361c2c66affSColin Finck 
2362c2c66affSColin Finck                 case PSN_WIZNEXT:
2363c2c66affSColin Finck                     break;
2364c2c66affSColin Finck 
2365c2c66affSColin Finck                 case PSN_WIZBACK:
2366c2c66affSColin Finck                     SetupData->UnattendSetup = FALSE;
2367c2c66affSColin Finck                     break;
2368c2c66affSColin Finck 
2369c2c66affSColin Finck                 default:
2370c2c66affSColin Finck                     break;
2371c2c66affSColin Finck             }
23723f053db3SEric Kohl             break;
23733f053db3SEric Kohl 
23743f053db3SEric Kohl         case PM_ITEM_START:
2375b76d49bcSEric Kohl             DPRINT("PM_ITEM_START %lu\n", (ULONG)lParam);
23763f053db3SEric Kohl             SendDlgItemMessage(hwndDlg, IDC_PROCESSPROGRESS, PBM_SETRANGE, 0, MAKELPARAM(0, (ULONG)lParam));
23773f053db3SEric Kohl             SendDlgItemMessage(hwndDlg, IDC_PROCESSPROGRESS, PBM_SETPOS, 0, 0);
23783f053db3SEric Kohl             SendDlgItemMessage(hwndDlg, IDC_TASKTEXT1 + wParam, WM_SETFONT, (WPARAM)SetupData->hBoldFont, (LPARAM)TRUE);
23793f053db3SEric Kohl             break;
23803f053db3SEric Kohl 
23813f053db3SEric Kohl         case PM_ITEM_END:
2382b76d49bcSEric Kohl             DPRINT("PM_ITEM_END\n");
23833f053db3SEric Kohl             if (lParam == ERROR_SUCCESS)
23843f053db3SEric Kohl             {
23853f053db3SEric Kohl             }
23863f053db3SEric Kohl             else
23873f053db3SEric Kohl             {
23883f053db3SEric Kohl                 ShowItemError(hwndDlg, (DWORD)lParam);
2389c2c66affSColin Finck             }
2390c2c66affSColin Finck             break;
2391c2c66affSColin Finck 
23923f053db3SEric Kohl         case PM_STEP_START:
2393b76d49bcSEric Kohl             DPRINT("PM_STEP_START\n");
2394c2c66affSColin Finck             RegistrationNotify = (PREGISTRATIONNOTIFY)lParam;
23953f053db3SEric Kohl             SendDlgItemMessage(hwndDlg, IDC_ITEM, WM_SETTEXT, 0,
23963f053db3SEric Kohl                                (LPARAM)((RegistrationNotify->CurrentItem != NULL)? RegistrationNotify->CurrentItem : L""));
23973f053db3SEric Kohl             break;
2398c2c66affSColin Finck 
23993f053db3SEric Kohl         case PM_STEP_END:
2400b76d49bcSEric Kohl             DPRINT("PM_STEP_END\n");
24013f053db3SEric Kohl             RegistrationNotify = (PREGISTRATIONNOTIFY)lParam;
24023f053db3SEric Kohl             SendDlgItemMessage(hwndDlg, IDC_PROCESSPROGRESS, PBM_SETPOS, RegistrationNotify->Progress, 0);
24033f053db3SEric Kohl             if (RegistrationNotify->LastError != ERROR_SUCCESS)
2404c2c66affSColin Finck             {
24053f053db3SEric Kohl                 ShowStepError(hwndDlg, RegistrationNotify);
24063f053db3SEric Kohl             }
24073f053db3SEric Kohl             break;
24083f053db3SEric Kohl 
24093f053db3SEric Kohl         case PM_ITEMS_DONE:
2410b76d49bcSEric Kohl             DPRINT("PM_ITEMS_DONE\n");
2411c2c66affSColin Finck             /* Enable the Back and Next buttons */
2412c2c66affSColin Finck             PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT);
2413c2c66affSColin Finck             PropSheet_PressButton(GetParent(hwndDlg), PSBTN_NEXT);
24143f053db3SEric Kohl             break;
2415c2c66affSColin Finck 
2416c2c66affSColin Finck         default:
2417c2c66affSColin Finck             break;
2418c2c66affSColin Finck     }
2419c2c66affSColin Finck 
2420c2c66affSColin Finck     return FALSE;
2421c2c66affSColin Finck }
2422c2c66affSColin Finck 
2423c2c66affSColin Finck 
2424c2c66affSColin Finck static VOID
SetInstallationCompleted(VOID)2425c2c66affSColin Finck SetInstallationCompleted(VOID)
2426c2c66affSColin Finck {
2427c2c66affSColin Finck     HKEY hKey = 0;
2428c2c66affSColin Finck     DWORD InProgress = 0;
2429c2c66affSColin Finck     DWORD InstallDate;
2430c2c66affSColin Finck 
2431c2c66affSColin Finck     if (RegOpenKeyExW( HKEY_LOCAL_MACHINE,
2432c2c66affSColin Finck                        L"SYSTEM\\Setup",
2433c2c66affSColin Finck                        0,
2434c2c66affSColin Finck                        KEY_WRITE,
2435c2c66affSColin Finck                        &hKey ) == ERROR_SUCCESS)
2436c2c66affSColin Finck     {
2437c2c66affSColin Finck         RegSetValueExW( hKey, L"SystemSetupInProgress", 0, REG_DWORD, (LPBYTE)&InProgress, sizeof(InProgress) );
2438c2c66affSColin Finck         RegCloseKey( hKey );
2439c2c66affSColin Finck     }
2440c2c66affSColin Finck 
2441c2c66affSColin Finck     if (RegOpenKeyExW( HKEY_LOCAL_MACHINE,
2442c2c66affSColin Finck                        L"Software\\Microsoft\\Windows NT\\CurrentVersion",
2443c2c66affSColin Finck                        0,
2444c2c66affSColin Finck                        KEY_WRITE,
2445c2c66affSColin Finck                        &hKey ) == ERROR_SUCCESS)
2446c2c66affSColin Finck     {
2447c2c66affSColin Finck         InstallDate = (DWORD)time(NULL);
2448c2c66affSColin Finck         RegSetValueExW( hKey, L"InstallDate", 0, REG_DWORD, (LPBYTE)&InstallDate, sizeof(InstallDate) );
2449c2c66affSColin Finck         RegCloseKey( hKey );
2450c2c66affSColin Finck     }
2451c2c66affSColin Finck }
2452c2c66affSColin Finck 
2453c2c66affSColin Finck static INT_PTR CALLBACK
FinishDlgProc(HWND hwndDlg,UINT uMsg,WPARAM wParam,LPARAM lParam)2454c2c66affSColin Finck FinishDlgProc(HWND hwndDlg,
2455c2c66affSColin Finck               UINT uMsg,
2456c2c66affSColin Finck               WPARAM wParam,
2457c2c66affSColin Finck               LPARAM lParam)
2458c2c66affSColin Finck {
2459c2c66affSColin Finck 
2460c2c66affSColin Finck     switch (uMsg)
2461c2c66affSColin Finck     {
2462c2c66affSColin Finck         case WM_INITDIALOG:
2463c2c66affSColin Finck         {
2464c2c66affSColin Finck             /* Get pointer to the global setup data */
2465c2c66affSColin Finck             PSETUPDATA SetupData = (PSETUPDATA)((LPPROPSHEETPAGE)lParam)->lParam;
2466c2c66affSColin Finck 
2467c2c66affSColin Finck             if (!SetupData->UnattendSetup || !SetupData->DisableGeckoInst)
2468c2c66affSColin Finck             {
2469c2c66affSColin Finck                 /* Run the Wine Gecko prompt */
2470dcf9eb06SMarcin Jabłoński                 Control_RunDLLW(hwndDlg, 0, L"appwiz.cpl,,install_gecko", SW_SHOW);
2471c2c66affSColin Finck             }
2472c2c66affSColin Finck 
2473c2c66affSColin Finck             /* Set title font */
2474c2c66affSColin Finck             SendDlgItemMessage(hwndDlg,
2475c2c66affSColin Finck                                IDC_FINISHTITLE,
2476c2c66affSColin Finck                                WM_SETFONT,
2477c2c66affSColin Finck                                (WPARAM)SetupData->hTitleFont,
2478c2c66affSColin Finck                                (LPARAM)TRUE);
2479c2c66affSColin Finck             if (SetupData->UnattendSetup)
2480c2c66affSColin Finck             {
2481c2c66affSColin Finck                 KillTimer(hwndDlg, 1);
2482c2c66affSColin Finck                 SetInstallationCompleted();
2483c2c66affSColin Finck                 PostQuitMessage(0);
2484c2c66affSColin Finck             }
2485c2c66affSColin Finck         }
2486c2c66affSColin Finck         break;
2487c2c66affSColin Finck 
2488c2c66affSColin Finck         case WM_DESTROY:
2489c2c66affSColin Finck         {
2490c2c66affSColin Finck             SetInstallationCompleted();
2491c2c66affSColin Finck             PostQuitMessage(0);
2492c2c66affSColin Finck             return TRUE;
2493c2c66affSColin Finck         }
2494c2c66affSColin Finck 
2495c2c66affSColin Finck         case WM_TIMER:
2496c2c66affSColin Finck         {
2497c2c66affSColin Finck             INT Position;
2498c2c66affSColin Finck             HWND hWndProgress;
2499c2c66affSColin Finck 
2500c2c66affSColin Finck             hWndProgress = GetDlgItem(hwndDlg, IDC_RESTART_PROGRESS);
2501c2c66affSColin Finck             Position = SendMessage(hWndProgress, PBM_GETPOS, 0, 0);
2502c2c66affSColin Finck             if (Position == 300)
2503c2c66affSColin Finck             {
2504c2c66affSColin Finck                 KillTimer(hwndDlg, 1);
2505c2c66affSColin Finck                 PropSheet_PressButton(GetParent(hwndDlg), PSBTN_FINISH);
2506c2c66affSColin Finck             }
2507c2c66affSColin Finck             else
2508c2c66affSColin Finck             {
2509c2c66affSColin Finck                 SendMessage(hWndProgress, PBM_SETPOS, Position + 1, 0);
2510c2c66affSColin Finck             }
2511c2c66affSColin Finck         }
2512c2c66affSColin Finck         return TRUE;
2513c2c66affSColin Finck 
2514c2c66affSColin Finck         case WM_NOTIFY:
2515c2c66affSColin Finck         {
2516c2c66affSColin Finck             LPNMHDR lpnm = (LPNMHDR)lParam;
2517c2c66affSColin Finck 
2518c2c66affSColin Finck             switch (lpnm->code)
2519c2c66affSColin Finck             {
2520c2c66affSColin Finck                 case PSN_SETACTIVE:
2521c2c66affSColin Finck                     /* Enable the correct buttons on for the active page */
2522c2c66affSColin Finck                     PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_FINISH);
2523c2c66affSColin Finck 
2524c2c66affSColin Finck                     SendDlgItemMessage(hwndDlg, IDC_RESTART_PROGRESS, PBM_SETRANGE, 0,
2525c2c66affSColin Finck                                        MAKELPARAM(0, 300));
2526c2c66affSColin Finck                     SendDlgItemMessage(hwndDlg, IDC_RESTART_PROGRESS, PBM_SETPOS, 0, 0);
2527c2c66affSColin Finck                     SetTimer(hwndDlg, 1, 50, NULL);
2528c2c66affSColin Finck                     break;
2529c2c66affSColin Finck 
2530c2c66affSColin Finck                 case PSN_WIZFINISH:
2531c2c66affSColin Finck                     DestroyWindow(GetParent(hwndDlg));
2532c2c66affSColin Finck                     break;
2533c2c66affSColin Finck 
2534c2c66affSColin Finck                 default:
2535c2c66affSColin Finck                     break;
2536c2c66affSColin Finck             }
2537c2c66affSColin Finck         }
2538c2c66affSColin Finck         break;
2539c2c66affSColin Finck 
2540c2c66affSColin Finck         default:
2541c2c66affSColin Finck             break;
2542c2c66affSColin Finck     }
2543c2c66affSColin Finck 
2544c2c66affSColin Finck     return FALSE;
2545c2c66affSColin Finck }
2546c2c66affSColin Finck 
2547c2c66affSColin Finck 
2548c8d37c1aSHermès Bélusca-Maïto /*
2549c8d37c1aSHermès Bélusca-Maïto  * GetInstallSourceWin32 retrieves the path to the ReactOS installation medium
2550c8d37c1aSHermès Bélusca-Maïto  * in Win32 format, for later use by syssetup and storage in the registry.
2551c8d37c1aSHermès Bélusca-Maïto  */
2552c8d37c1aSHermès Bélusca-Maïto static BOOL
GetInstallSourceWin32(OUT PWSTR pwszPath,IN DWORD cchPathMax,IN PCWSTR pwszNTPath)2553c8d37c1aSHermès Bélusca-Maïto GetInstallSourceWin32(
2554c8d37c1aSHermès Bélusca-Maïto     OUT PWSTR pwszPath,
2555c8d37c1aSHermès Bélusca-Maïto     IN DWORD cchPathMax,
2556c8d37c1aSHermès Bélusca-Maïto     IN PCWSTR pwszNTPath)
2557c8d37c1aSHermès Bélusca-Maïto {
2558c8d37c1aSHermès Bélusca-Maïto     WCHAR wszDrives[512];
2559c8d37c1aSHermès Bélusca-Maïto     WCHAR wszNTPath[512]; // MAX_PATH ?
2560c8d37c1aSHermès Bélusca-Maïto     DWORD cchDrives;
2561c8d37c1aSHermès Bélusca-Maïto     PWCHAR pwszDrive;
2562c8d37c1aSHermès Bélusca-Maïto 
2563c8d37c1aSHermès Bélusca-Maïto     *pwszPath = UNICODE_NULL;
2564c8d37c1aSHermès Bélusca-Maïto 
2565c8d37c1aSHermès Bélusca-Maïto     cchDrives = GetLogicalDriveStringsW(_countof(wszDrives) - 1, wszDrives);
2566c8d37c1aSHermès Bélusca-Maïto     if (cchDrives == 0 || cchDrives >= _countof(wszDrives))
2567c8d37c1aSHermès Bélusca-Maïto     {
2568c8d37c1aSHermès Bélusca-Maïto         /* Buffer too small or failure */
2569c8d37c1aSHermès Bélusca-Maïto         LogItem(NULL, L"GetLogicalDriveStringsW failed");
2570c8d37c1aSHermès Bélusca-Maïto         return FALSE;
2571c8d37c1aSHermès Bélusca-Maïto     }
2572c8d37c1aSHermès Bélusca-Maïto 
2573c8d37c1aSHermès Bélusca-Maïto     for (pwszDrive = wszDrives; *pwszDrive; pwszDrive += wcslen(pwszDrive) + 1)
2574c8d37c1aSHermès Bélusca-Maïto     {
2575c8d37c1aSHermès Bélusca-Maïto         WCHAR wszBuf[MAX_PATH];
2576c8d37c1aSHermès Bélusca-Maïto 
2577c8d37c1aSHermès Bélusca-Maïto         /* Retrieve the NT path corresponding to the current Win32 DOS path */
2578c8d37c1aSHermès Bélusca-Maïto         pwszDrive[2] = UNICODE_NULL; // Temporarily remove the backslash
2579c8d37c1aSHermès Bélusca-Maïto         QueryDosDeviceW(pwszDrive, wszNTPath, _countof(wszNTPath));
2580c8d37c1aSHermès Bélusca-Maïto         pwszDrive[2] = L'\\';        // Restore the backslash
2581c8d37c1aSHermès Bélusca-Maïto 
2582c8d37c1aSHermès Bélusca-Maïto         wcscat(wszNTPath, L"\\");    // Concat a backslash
2583c8d37c1aSHermès Bélusca-Maïto 
2584c8d37c1aSHermès Bélusca-Maïto         /* Logging */
2585c8d37c1aSHermès Bélusca-Maïto         wsprintf(wszBuf, L"Testing '%s' --> '%s' %s a CD",
2586c8d37c1aSHermès Bélusca-Maïto                  pwszDrive, wszNTPath,
2587c8d37c1aSHermès Bélusca-Maïto                  (GetDriveTypeW(pwszDrive) == DRIVE_CDROM) ? L"is" : L"is not");
2588c8d37c1aSHermès Bélusca-Maïto         LogItem(NULL, wszBuf);
2589c8d37c1aSHermès Bélusca-Maïto 
2590c8d37c1aSHermès Bélusca-Maïto         /* Check whether the NT path corresponds to the NT installation source path */
2591c8d37c1aSHermès Bélusca-Maïto         if (!_wcsicmp(wszNTPath, pwszNTPath))
2592c8d37c1aSHermès Bélusca-Maïto         {
2593c8d37c1aSHermès Bélusca-Maïto             /* Found it! */
2594c8d37c1aSHermès Bélusca-Maïto             wcscpy(pwszPath, pwszDrive); // cchPathMax
2595c8d37c1aSHermès Bélusca-Maïto 
2596c8d37c1aSHermès Bélusca-Maïto             /* Logging */
2597c8d37c1aSHermès Bélusca-Maïto             wsprintf(wszBuf, L"GetInstallSourceWin32: %s", pwszPath);
2598c8d37c1aSHermès Bélusca-Maïto             LogItem(NULL, wszBuf);
2599c8d37c1aSHermès Bélusca-Maïto             wcscat(wszBuf, L"\n");
2600c8d37c1aSHermès Bélusca-Maïto             OutputDebugStringW(wszBuf);
2601c8d37c1aSHermès Bélusca-Maïto 
2602c8d37c1aSHermès Bélusca-Maïto             return TRUE;
2603c8d37c1aSHermès Bélusca-Maïto         }
2604c8d37c1aSHermès Bélusca-Maïto     }
2605c8d37c1aSHermès Bélusca-Maïto 
2606c8d37c1aSHermès Bélusca-Maïto     return FALSE;
2607c8d37c1aSHermès Bélusca-Maïto }
2608c8d37c1aSHermès Bélusca-Maïto 
2609c2c66affSColin Finck VOID
ProcessUnattendSection(IN OUT PSETUPDATA pSetupData)2610c8d37c1aSHermès Bélusca-Maïto ProcessUnattendSection(
2611c8d37c1aSHermès Bélusca-Maïto     IN OUT PSETUPDATA pSetupData)
2612c2c66affSColin Finck {
2613c2c66affSColin Finck     INFCONTEXT InfContext;
2614c2c66affSColin Finck     WCHAR szName[256];
2615c2c66affSColin Finck     WCHAR szValue[MAX_PATH];
2616c2c66affSColin Finck     DWORD LineLength;
2617c2c66affSColin Finck     HKEY hKey;
2618c2c66affSColin Finck 
2619c8d37c1aSHermès Bélusca-Maïto     if (!SetupFindFirstLineW(pSetupData->hSetupInf,
2620c2c66affSColin Finck                              L"Unattend",
2621c2c66affSColin Finck                              L"UnattendSetupEnabled",
2622c2c66affSColin Finck                              &InfContext))
2623c2c66affSColin Finck     {
2624e9893906SHermès Bélusca-Maïto         DPRINT1("Error: Cannot find UnattendSetupEnabled Key! %d\n", GetLastError());
2625c2c66affSColin Finck         return;
2626c2c66affSColin Finck     }
2627c2c66affSColin Finck 
2628c2c66affSColin Finck     if (!SetupGetStringFieldW(&InfContext,
2629c2c66affSColin Finck                               1,
2630c2c66affSColin Finck                               szValue,
263162678985SHermès Bélusca-Maïto                               ARRAYSIZE(szValue),
2632c2c66affSColin Finck                               &LineLength))
2633c2c66affSColin Finck     {
2634c2c66affSColin Finck         DPRINT1("Error: SetupGetStringField failed with %d\n", GetLastError());
2635c2c66affSColin Finck         return;
2636c2c66affSColin Finck     }
2637c2c66affSColin Finck 
263862678985SHermès Bélusca-Maïto     if (_wcsicmp(szValue, L"yes") != 0)
2639c2c66affSColin Finck     {
2640c2c66affSColin Finck         DPRINT("Unattend setup was disabled by UnattendSetupEnabled key.\n");
2641c2c66affSColin Finck         return;
2642c2c66affSColin Finck     }
2643c2c66affSColin Finck 
2644c2c66affSColin Finck     pSetupData->UnattendSetup = TRUE;
2645c2c66affSColin Finck 
2646c8d37c1aSHermès Bélusca-Maïto     if (!SetupFindFirstLineW(pSetupData->hSetupInf,
2647c2c66affSColin Finck                              L"Unattend",
2648c2c66affSColin Finck                              NULL,
2649c2c66affSColin Finck                              &InfContext))
2650c2c66affSColin Finck     {
2651c2c66affSColin Finck         DPRINT1("Error: SetupFindFirstLine failed %d\n", GetLastError());
2652c2c66affSColin Finck         return;
2653c2c66affSColin Finck     }
2654c2c66affSColin Finck 
2655c2c66affSColin Finck     do
2656c2c66affSColin Finck     {
2657c2c66affSColin Finck         if (!SetupGetStringFieldW(&InfContext,
2658c2c66affSColin Finck                                   0,
2659c2c66affSColin Finck                                   szName,
266062678985SHermès Bélusca-Maïto                                   ARRAYSIZE(szName),
2661c2c66affSColin Finck                                   &LineLength))
2662c2c66affSColin Finck         {
2663c2c66affSColin Finck             DPRINT1("Error: SetupGetStringField failed with %d\n", GetLastError());
2664c2c66affSColin Finck             return;
2665c2c66affSColin Finck         }
2666c2c66affSColin Finck 
2667c2c66affSColin Finck         if (!SetupGetStringFieldW(&InfContext,
2668c2c66affSColin Finck                                   1,
2669c2c66affSColin Finck                                   szValue,
267062678985SHermès Bélusca-Maïto                                   ARRAYSIZE(szValue),
2671c2c66affSColin Finck                                   &LineLength))
2672c2c66affSColin Finck         {
2673c2c66affSColin Finck             DPRINT1("Error: SetupGetStringField failed with %d\n", GetLastError());
2674c2c66affSColin Finck             return;
2675c2c66affSColin Finck         }
2676c2c66affSColin Finck         DPRINT1("Name %S Value %S\n", szName, szValue);
267762678985SHermès Bélusca-Maïto         if (!_wcsicmp(szName, L"FullName"))
2678c2c66affSColin Finck         {
267962678985SHermès Bélusca-Maïto             if (ARRAYSIZE(pSetupData->OwnerName) > LineLength)
2680c2c66affSColin Finck             {
2681c2c66affSColin Finck                 wcscpy(pSetupData->OwnerName, szValue);
2682c2c66affSColin Finck             }
2683c2c66affSColin Finck         }
268462678985SHermès Bélusca-Maïto         else if (!_wcsicmp(szName, L"OrgName"))
2685c2c66affSColin Finck         {
268662678985SHermès Bélusca-Maïto             if (ARRAYSIZE(pSetupData->OwnerOrganization) > LineLength)
2687c2c66affSColin Finck             {
2688c2c66affSColin Finck                 wcscpy(pSetupData->OwnerOrganization, szValue);
2689c2c66affSColin Finck             }
2690c2c66affSColin Finck         }
269162678985SHermès Bélusca-Maïto         else if (!_wcsicmp(szName, L"ComputerName"))
2692c2c66affSColin Finck         {
269362678985SHermès Bélusca-Maïto             if (ARRAYSIZE(pSetupData->ComputerName) > LineLength)
2694c2c66affSColin Finck             {
2695c2c66affSColin Finck                 wcscpy(pSetupData->ComputerName, szValue);
2696c2c66affSColin Finck             }
2697c2c66affSColin Finck         }
269862678985SHermès Bélusca-Maïto         else if (!_wcsicmp(szName, L"AdminPassword"))
2699c2c66affSColin Finck         {
270062678985SHermès Bélusca-Maïto             if (ARRAYSIZE(pSetupData->AdminPassword) > LineLength)
2701c2c66affSColin Finck             {
2702c2c66affSColin Finck                 wcscpy(pSetupData->AdminPassword, szValue);
2703c2c66affSColin Finck             }
2704c2c66affSColin Finck         }
270562678985SHermès Bélusca-Maïto         else if (!_wcsicmp(szName, L"TimeZoneIndex"))
2706c2c66affSColin Finck         {
2707c2c66affSColin Finck             pSetupData->TimeZoneIndex = _wtoi(szValue);
2708c2c66affSColin Finck         }
270962678985SHermès Bélusca-Maïto         else if (!_wcsicmp(szName, L"DisableAutoDaylightTimeSet"))
2710c2c66affSColin Finck         {
2711c2c66affSColin Finck             pSetupData->DisableAutoDaylightTimeSet = _wtoi(szValue);
2712c2c66affSColin Finck         }
271362678985SHermès Bélusca-Maïto         else if (!_wcsicmp(szName, L"DisableGeckoInst"))
2714c2c66affSColin Finck         {
271562678985SHermès Bélusca-Maïto             if (!_wcsicmp(szValue, L"yes"))
2716e9893906SHermès Bélusca-Maïto                 pSetupData->DisableGeckoInst = TRUE;
2717c2c66affSColin Finck             else
2718e9893906SHermès Bélusca-Maïto                 pSetupData->DisableGeckoInst = FALSE;
2719c2c66affSColin Finck         }
2720612729b0SKatayama Hirofumi MZ         else if (!_wcsicmp(szName, L"ProductOption"))
2721612729b0SKatayama Hirofumi MZ         {
2722612729b0SKatayama Hirofumi MZ             pSetupData->ProductOption = (PRODUCT_OPTION)_wtoi(szValue);
2723612729b0SKatayama Hirofumi MZ         }
2724e9893906SHermès Bélusca-Maïto     } while (SetupFindNextLine(&InfContext, &InfContext));
2725c2c66affSColin Finck 
2726c8d37c1aSHermès Bélusca-Maïto     if (SetupFindFirstLineW(pSetupData->hSetupInf,
2727c2c66affSColin Finck                             L"Display",
2728c2c66affSColin Finck                             NULL,
2729c2c66affSColin Finck                             &InfContext))
2730c2c66affSColin Finck     {
2731c2c66affSColin Finck         DEVMODEW dm = { { 0 } };
2732c2c66affSColin Finck         dm.dmSize = sizeof(dm);
2733c2c66affSColin Finck         if (EnumDisplaySettingsW(NULL, ENUM_CURRENT_SETTINGS, &dm))
2734c2c66affSColin Finck         {
2735c2c66affSColin Finck             do
2736c2c66affSColin Finck             {
2737c2c66affSColin Finck                 int iValue;
2738c2c66affSColin Finck                 if (!SetupGetStringFieldW(&InfContext,
2739c2c66affSColin Finck                                           0,
2740c2c66affSColin Finck                                           szName,
274162678985SHermès Bélusca-Maïto                                           ARRAYSIZE(szName),
2742c2c66affSColin Finck                                           &LineLength))
2743c2c66affSColin Finck                 {
2744c2c66affSColin Finck                     DPRINT1("Error: SetupGetStringField failed with %d\n", GetLastError());
2745c2c66affSColin Finck                     return;
2746c2c66affSColin Finck                 }
2747c2c66affSColin Finck 
2748c2c66affSColin Finck                 if (!SetupGetStringFieldW(&InfContext,
2749c2c66affSColin Finck                                           1,
2750c2c66affSColin Finck                                           szValue,
275162678985SHermès Bélusca-Maïto                                           ARRAYSIZE(szValue),
2752c2c66affSColin Finck                                           &LineLength))
2753c2c66affSColin Finck                 {
2754c2c66affSColin Finck                     DPRINT1("Error: SetupGetStringField failed with %d\n", GetLastError());
2755c2c66affSColin Finck                     return;
2756c2c66affSColin Finck                 }
2757c2c66affSColin Finck                 iValue = _wtoi(szValue);
2758c2c66affSColin Finck                 DPRINT1("Name %S Value %i\n", szName, iValue);
2759c2c66affSColin Finck 
2760c2c66affSColin Finck                 if (!iValue)
2761c2c66affSColin Finck                     continue;
2762c2c66affSColin Finck 
276362678985SHermès Bélusca-Maïto                 if (!_wcsicmp(szName, L"BitsPerPel"))
2764c2c66affSColin Finck                 {
2765c2c66affSColin Finck                     dm.dmFields |= DM_BITSPERPEL;
2766c2c66affSColin Finck                     dm.dmBitsPerPel = iValue;
2767c2c66affSColin Finck                 }
276862678985SHermès Bélusca-Maïto                 else if (!_wcsicmp(szName, L"XResolution"))
2769c2c66affSColin Finck                 {
2770c2c66affSColin Finck                     dm.dmFields |= DM_PELSWIDTH;
2771c2c66affSColin Finck                     dm.dmPelsWidth = iValue;
2772c2c66affSColin Finck                 }
277362678985SHermès Bélusca-Maïto                 else if (!_wcsicmp(szName, L"YResolution"))
2774c2c66affSColin Finck                 {
2775c2c66affSColin Finck                     dm.dmFields |= DM_PELSHEIGHT;
2776c2c66affSColin Finck                     dm.dmPelsHeight = iValue;
2777c2c66affSColin Finck                 }
277862678985SHermès Bélusca-Maïto                 else if (!_wcsicmp(szName, L"VRefresh"))
2779c2c66affSColin Finck                 {
2780c2c66affSColin Finck                     dm.dmFields |= DM_DISPLAYFREQUENCY;
2781c2c66affSColin Finck                     dm.dmDisplayFrequency = iValue;
2782c2c66affSColin Finck                 }
2783e9893906SHermès Bélusca-Maïto             } while (SetupFindNextLine(&InfContext, &InfContext));
2784c2c66affSColin Finck 
2785c2c66affSColin Finck             ChangeDisplaySettingsW(&dm, CDS_UPDATEREGISTRY);
2786c2c66affSColin Finck         }
2787c2c66affSColin Finck     }
2788c2c66affSColin Finck 
2789c2c66affSColin Finck     if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,
2790c2c66affSColin Finck                       L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunOnce",
2791c2c66affSColin Finck                       0,
2792c2c66affSColin Finck                       KEY_SET_VALUE,
2793c2c66affSColin Finck                       &hKey) != ERROR_SUCCESS)
2794c2c66affSColin Finck     {
2795c2c66affSColin Finck         DPRINT1("Error: failed to open HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\RunOnce\n");
2796c2c66affSColin Finck         return;
2797c2c66affSColin Finck     }
2798c2c66affSColin Finck 
2799c8d37c1aSHermès Bélusca-Maïto     if (SetupFindFirstLineW(pSetupData->hSetupInf,
2800c2c66affSColin Finck                             L"GuiRunOnce",
2801c2c66affSColin Finck                             NULL,
2802c2c66affSColin Finck                             &InfContext))
2803c2c66affSColin Finck     {
2804c2c66affSColin Finck         int i = 0;
2805c2c66affSColin Finck         do
2806c2c66affSColin Finck         {
2807c2c66affSColin Finck             if (SetupGetStringFieldW(&InfContext,
2808c2c66affSColin Finck                                      0,
2809c2c66affSColin Finck                                      szValue,
281062678985SHermès Bélusca-Maïto                                      ARRAYSIZE(szValue),
2811c2c66affSColin Finck                                      NULL))
2812c2c66affSColin Finck             {
2813c2c66affSColin Finck                 WCHAR szPath[MAX_PATH];
2814c2c66affSColin Finck                 swprintf(szName, L"%d", i);
2815c2c66affSColin Finck                 DPRINT("szName %S szValue %S\n", szName, szValue);
2816c2c66affSColin Finck 
2817c2c66affSColin Finck                 if (ExpandEnvironmentStringsW(szValue, szPath, MAX_PATH))
2818c2c66affSColin Finck                 {
2819c2c66affSColin Finck                     DPRINT("value %S\n", szPath);
2820c2c66affSColin Finck                     if (RegSetValueExW(hKey,
2821c2c66affSColin Finck                                        szName,
2822c2c66affSColin Finck                                        0,
2823c2c66affSColin Finck                                        REG_SZ,
2824c2c66affSColin Finck                                        (const BYTE*)szPath,
2825c2c66affSColin Finck                                        (wcslen(szPath) + 1) * sizeof(WCHAR)) == ERROR_SUCCESS)
2826c2c66affSColin Finck                     {
2827c2c66affSColin Finck                         i++;
2828c2c66affSColin Finck                     }
2829c2c66affSColin Finck                 }
2830c2c66affSColin Finck             }
2831c2c66affSColin Finck         } while (SetupFindNextLine(&InfContext, &InfContext));
2832c2c66affSColin Finck     }
2833c2c66affSColin Finck 
2834c2c66affSColin Finck     RegCloseKey(hKey);
2835d4e38a63SMark Jansen 
2836d4e38a63SMark Jansen     if (SetupFindFirstLineW(pSetupData->hSetupInf,
2837d4e38a63SMark Jansen         L"Env",
2838d4e38a63SMark Jansen         NULL,
2839d4e38a63SMark Jansen         &InfContext))
2840d4e38a63SMark Jansen     {
2841d4e38a63SMark Jansen         if (RegCreateKeyExW(
2842d4e38a63SMark Jansen                 HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment", 0, NULL,
2843d4e38a63SMark Jansen                 REG_OPTION_NON_VOLATILE, KEY_WRITE | KEY_READ, NULL, &hKey, NULL) != ERROR_SUCCESS)
2844d4e38a63SMark Jansen         {
2845d4e38a63SMark Jansen             DPRINT1("Error: failed to open HKLM\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment\n");
2846d4e38a63SMark Jansen             return;
2847d4e38a63SMark Jansen         }
2848d4e38a63SMark Jansen         do
2849d4e38a63SMark Jansen         {
2850d4e38a63SMark Jansen             if (!SetupGetStringFieldW(&InfContext,
2851d4e38a63SMark Jansen                 0,
2852d4e38a63SMark Jansen                 szName,
2853d4e38a63SMark Jansen                 ARRAYSIZE(szName),
2854d4e38a63SMark Jansen                 &LineLength))
2855d4e38a63SMark Jansen             {
2856d4e38a63SMark Jansen                 DPRINT1("Error: SetupGetStringField failed with %d\n", GetLastError());
2857d4e38a63SMark Jansen                 return;
2858d4e38a63SMark Jansen             }
2859d4e38a63SMark Jansen 
2860d4e38a63SMark Jansen             if (!SetupGetStringFieldW(&InfContext,
2861d4e38a63SMark Jansen                 1,
2862d4e38a63SMark Jansen                 szValue,
2863d4e38a63SMark Jansen                 ARRAYSIZE(szValue),
2864d4e38a63SMark Jansen                 &LineLength))
2865d4e38a63SMark Jansen             {
2866d4e38a63SMark Jansen                 DPRINT1("Error: SetupGetStringField failed with %d\n", GetLastError());
2867d4e38a63SMark Jansen                 return;
2868d4e38a63SMark Jansen             }
2869d4e38a63SMark Jansen             DPRINT1("[ENV] %S=%S\n", szName, szValue);
2870d4e38a63SMark Jansen 
2871d4e38a63SMark Jansen             DWORD dwType = wcschr(szValue, '%') != NULL ? REG_EXPAND_SZ : REG_SZ;
2872d4e38a63SMark Jansen 
2873d4e38a63SMark Jansen             if (RegSetValueExW(hKey, szName, 0, dwType, (const BYTE*)szValue, (DWORD)(wcslen(szValue) + 1) * sizeof(TCHAR)) != ERROR_SUCCESS)
2874d4e38a63SMark Jansen             {
2875d4e38a63SMark Jansen                 DPRINT1(" - Error %d\n", GetLastError());
2876d4e38a63SMark Jansen             }
2877d4e38a63SMark Jansen 
2878d4e38a63SMark Jansen         } while (SetupFindNextLine(&InfContext, &InfContext));
2879d4e38a63SMark Jansen 
2880d4e38a63SMark Jansen         RegCloseKey(hKey);
2881d4e38a63SMark Jansen     }
2882c2c66affSColin Finck }
2883c2c66affSColin Finck 
288445c8e4dcSJose Carlos Jesus static BOOL
PathIsEqual(IN LPCWSTR lpPath1,IN LPCWSTR lpPath2)288545c8e4dcSJose Carlos Jesus PathIsEqual(
288645c8e4dcSJose Carlos Jesus     IN LPCWSTR lpPath1,
288745c8e4dcSJose Carlos Jesus     IN LPCWSTR lpPath2)
288845c8e4dcSJose Carlos Jesus {
288945c8e4dcSJose Carlos Jesus     WCHAR szPath1[MAX_PATH];
289045c8e4dcSJose Carlos Jesus     WCHAR szPath2[MAX_PATH];
289145c8e4dcSJose Carlos Jesus 
289245c8e4dcSJose Carlos Jesus     /* If something goes wrong, better return TRUE,
289345c8e4dcSJose Carlos Jesus      * so the calling function returns early.
289445c8e4dcSJose Carlos Jesus      */
289545c8e4dcSJose Carlos Jesus     if (!PathCanonicalizeW(szPath1, lpPath1))
289645c8e4dcSJose Carlos Jesus         return TRUE;
289745c8e4dcSJose Carlos Jesus 
289845c8e4dcSJose Carlos Jesus     if (!PathAddBackslashW(szPath1))
289945c8e4dcSJose Carlos Jesus         return TRUE;
290045c8e4dcSJose Carlos Jesus 
290145c8e4dcSJose Carlos Jesus     if (!PathCanonicalizeW(szPath2, lpPath2))
290245c8e4dcSJose Carlos Jesus         return TRUE;
290345c8e4dcSJose Carlos Jesus 
290445c8e4dcSJose Carlos Jesus     if (!PathAddBackslashW(szPath2))
290545c8e4dcSJose Carlos Jesus         return TRUE;
290645c8e4dcSJose Carlos Jesus 
290745c8e4dcSJose Carlos Jesus     return (_wcsicmp(szPath1, szPath2) == 0);
290845c8e4dcSJose Carlos Jesus }
290945c8e4dcSJose Carlos Jesus 
291045c8e4dcSJose Carlos Jesus static VOID
AddInstallationSource(IN HKEY hKey,IN LPWSTR lpPath)291145c8e4dcSJose Carlos Jesus AddInstallationSource(
291245c8e4dcSJose Carlos Jesus     IN HKEY hKey,
291345c8e4dcSJose Carlos Jesus     IN LPWSTR lpPath)
291445c8e4dcSJose Carlos Jesus {
291545c8e4dcSJose Carlos Jesus     LONG res;
291645c8e4dcSJose Carlos Jesus     DWORD dwRegType;
291745c8e4dcSJose Carlos Jesus     DWORD dwPathLength = 0;
291845c8e4dcSJose Carlos Jesus     DWORD dwNewLength = 0;
291945c8e4dcSJose Carlos Jesus     LPWSTR Buffer = NULL;
292045c8e4dcSJose Carlos Jesus     LPWSTR Path;
292145c8e4dcSJose Carlos Jesus 
292245c8e4dcSJose Carlos Jesus     res = RegQueryValueExW(
292345c8e4dcSJose Carlos Jesus         hKey,
292445c8e4dcSJose Carlos Jesus         L"Installation Sources",
292545c8e4dcSJose Carlos Jesus         NULL,
292645c8e4dcSJose Carlos Jesus         &dwRegType,
292745c8e4dcSJose Carlos Jesus         NULL,
292845c8e4dcSJose Carlos Jesus         &dwPathLength);
292945c8e4dcSJose Carlos Jesus 
293045c8e4dcSJose Carlos Jesus     if (res != ERROR_SUCCESS ||
293145c8e4dcSJose Carlos Jesus         dwRegType != REG_MULTI_SZ ||
293245c8e4dcSJose Carlos Jesus         dwPathLength == 0 ||
293345c8e4dcSJose Carlos Jesus         dwPathLength % sizeof(WCHAR) != 0)
293445c8e4dcSJose Carlos Jesus     {
293545c8e4dcSJose Carlos Jesus         dwPathLength = 0;
293645c8e4dcSJose Carlos Jesus         goto set;
293745c8e4dcSJose Carlos Jesus     }
293845c8e4dcSJose Carlos Jesus 
293945c8e4dcSJose Carlos Jesus     /* Reserve space for existing data + new string */
294045c8e4dcSJose Carlos Jesus     dwNewLength = dwPathLength + (wcslen(lpPath) + 1) * sizeof(WCHAR);
294145c8e4dcSJose Carlos Jesus     Buffer = HeapAlloc(GetProcessHeap(), 0, dwNewLength);
294245c8e4dcSJose Carlos Jesus     if (!Buffer)
294345c8e4dcSJose Carlos Jesus         return;
294445c8e4dcSJose Carlos Jesus 
294545c8e4dcSJose Carlos Jesus     ZeroMemory(Buffer, dwNewLength);
294645c8e4dcSJose Carlos Jesus 
294745c8e4dcSJose Carlos Jesus     res = RegQueryValueExW(
294845c8e4dcSJose Carlos Jesus         hKey,
294945c8e4dcSJose Carlos Jesus         L"Installation Sources",
295045c8e4dcSJose Carlos Jesus         NULL,
295145c8e4dcSJose Carlos Jesus         NULL,
295245c8e4dcSJose Carlos Jesus         (LPBYTE)Buffer,
295345c8e4dcSJose Carlos Jesus         &dwPathLength);
295445c8e4dcSJose Carlos Jesus 
295545c8e4dcSJose Carlos Jesus     if (res != ERROR_SUCCESS)
295645c8e4dcSJose Carlos Jesus     {
295745c8e4dcSJose Carlos Jesus         HeapFree(GetProcessHeap(), 0, Buffer);
295845c8e4dcSJose Carlos Jesus         dwPathLength = 0;
295945c8e4dcSJose Carlos Jesus         goto set;
296045c8e4dcSJose Carlos Jesus     }
296145c8e4dcSJose Carlos Jesus 
296245c8e4dcSJose Carlos Jesus     /* Sanity check, these should already be zeros */
296345c8e4dcSJose Carlos Jesus     Buffer[dwPathLength / sizeof(WCHAR) - 2] = UNICODE_NULL;
296445c8e4dcSJose Carlos Jesus     Buffer[dwPathLength / sizeof(WCHAR) - 1] = UNICODE_NULL;
296545c8e4dcSJose Carlos Jesus 
296645c8e4dcSJose Carlos Jesus     for (Path = Buffer; *Path; Path += wcslen(Path) + 1)
296745c8e4dcSJose Carlos Jesus     {
296845c8e4dcSJose Carlos Jesus         /* Check if path is already added */
296945c8e4dcSJose Carlos Jesus         if (PathIsEqual(Path, lpPath))
297045c8e4dcSJose Carlos Jesus             goto cleanup;
297145c8e4dcSJose Carlos Jesus     }
297245c8e4dcSJose Carlos Jesus 
297345c8e4dcSJose Carlos Jesus     Path = Buffer + dwPathLength / sizeof(WCHAR) - 1;
297445c8e4dcSJose Carlos Jesus 
297545c8e4dcSJose Carlos Jesus set:
297645c8e4dcSJose Carlos Jesus     if (dwPathLength == 0)
297745c8e4dcSJose Carlos Jesus     {
297845c8e4dcSJose Carlos Jesus         dwNewLength = (wcslen(lpPath) + 1 + 1) * sizeof(WCHAR);
297945c8e4dcSJose Carlos Jesus         Buffer = HeapAlloc(GetProcessHeap(), 0, dwNewLength);
298045c8e4dcSJose Carlos Jesus         if (!Buffer)
298145c8e4dcSJose Carlos Jesus             return;
298245c8e4dcSJose Carlos Jesus 
298345c8e4dcSJose Carlos Jesus         Path = Buffer;
298445c8e4dcSJose Carlos Jesus     }
298545c8e4dcSJose Carlos Jesus 
298645c8e4dcSJose Carlos Jesus     StringCbCopyW(Path, dwNewLength - (Path - Buffer) * sizeof(WCHAR), lpPath);
298745c8e4dcSJose Carlos Jesus     Buffer[dwNewLength / sizeof(WCHAR) - 1] = UNICODE_NULL;
298845c8e4dcSJose Carlos Jesus 
298945c8e4dcSJose Carlos Jesus     RegSetValueExW(
299045c8e4dcSJose Carlos Jesus         hKey,
299145c8e4dcSJose Carlos Jesus         L"Installation Sources",
299245c8e4dcSJose Carlos Jesus         0,
299345c8e4dcSJose Carlos Jesus         REG_MULTI_SZ,
299445c8e4dcSJose Carlos Jesus         (LPBYTE)Buffer,
299545c8e4dcSJose Carlos Jesus         dwNewLength);
299645c8e4dcSJose Carlos Jesus 
299745c8e4dcSJose Carlos Jesus cleanup:
299845c8e4dcSJose Carlos Jesus     HeapFree(GetProcessHeap(), 0, Buffer);
299945c8e4dcSJose Carlos Jesus }
300045c8e4dcSJose Carlos Jesus 
3001c2c66affSColin Finck VOID
ProcessSetupInf(IN OUT PSETUPDATA pSetupData)3002c8d37c1aSHermès Bélusca-Maïto ProcessSetupInf(
3003c8d37c1aSHermès Bélusca-Maïto     IN OUT PSETUPDATA pSetupData)
3004c2c66affSColin Finck {
3005c2c66affSColin Finck     WCHAR szPath[MAX_PATH];
3006c8d37c1aSHermès Bélusca-Maïto     WCHAR szValue[MAX_PATH];
3007c8d37c1aSHermès Bélusca-Maïto     INFCONTEXT InfContext;
3008c8d37c1aSHermès Bélusca-Maïto     DWORD LineLength;
3009c8d37c1aSHermès Bélusca-Maïto     HKEY hKey;
3010c8d37c1aSHermès Bélusca-Maïto     LONG res;
3011c2c66affSColin Finck 
3012c8d37c1aSHermès Bélusca-Maïto     pSetupData->hSetupInf = INVALID_HANDLE_VALUE;
3013c2c66affSColin Finck 
3014c8d37c1aSHermès Bélusca-Maïto     /* Retrieve the path of the setup INF */
3015c8d37c1aSHermès Bélusca-Maïto     GetSystemDirectoryW(szPath, _countof(szPath));
3016c8d37c1aSHermès Bélusca-Maïto     wcscat(szPath, L"\\$winnt$.inf");
3017c2c66affSColin Finck 
3018c8d37c1aSHermès Bélusca-Maïto     /* Open the setup INF */
3019c8d37c1aSHermès Bélusca-Maïto     pSetupData->hSetupInf = SetupOpenInfFileW(szPath,
3020c2c66affSColin Finck                                               NULL,
3021c2c66affSColin Finck                                               INF_STYLE_OLDNT,
3022c2c66affSColin Finck                                               NULL);
3023c8d37c1aSHermès Bélusca-Maïto     if (pSetupData->hSetupInf == INVALID_HANDLE_VALUE)
3024c2c66affSColin Finck     {
3025c8d37c1aSHermès Bélusca-Maïto         DPRINT1("Error: Cannot open the setup information file %S with error %d\n", szPath, GetLastError());
3026c8d37c1aSHermès Bélusca-Maïto         return;
3027c2c66affSColin Finck     }
3028c8d37c1aSHermès Bélusca-Maïto 
3029c8d37c1aSHermès Bélusca-Maïto 
3030c8d37c1aSHermès Bélusca-Maïto     /* Retrieve the NT source path from which the 1st-stage installer was run */
3031c8d37c1aSHermès Bélusca-Maïto     if (!SetupFindFirstLineW(pSetupData->hSetupInf,
3032c8d37c1aSHermès Bélusca-Maïto                              L"data",
3033c8d37c1aSHermès Bélusca-Maïto                              L"sourcepath",
3034c8d37c1aSHermès Bélusca-Maïto                              &InfContext))
3035c8d37c1aSHermès Bélusca-Maïto     {
3036bae08335SMark Jansen         DPRINT1("Error: Cannot find sourcepath Key! %d\n", GetLastError());
3037c8d37c1aSHermès Bélusca-Maïto         return;
3038c8d37c1aSHermès Bélusca-Maïto     }
3039c8d37c1aSHermès Bélusca-Maïto 
3040c8d37c1aSHermès Bélusca-Maïto     if (!SetupGetStringFieldW(&InfContext,
3041c8d37c1aSHermès Bélusca-Maïto                               1,
3042c8d37c1aSHermès Bélusca-Maïto                               szValue,
3043c8d37c1aSHermès Bélusca-Maïto                               ARRAYSIZE(szValue),
3044c8d37c1aSHermès Bélusca-Maïto                               &LineLength))
3045c8d37c1aSHermès Bélusca-Maïto     {
3046c8d37c1aSHermès Bélusca-Maïto         DPRINT1("Error: SetupGetStringField failed with %d\n", GetLastError());
3047c8d37c1aSHermès Bélusca-Maïto         return;
3048c8d37c1aSHermès Bélusca-Maïto     }
3049c8d37c1aSHermès Bélusca-Maïto 
3050c8d37c1aSHermès Bélusca-Maïto     *pSetupData->SourcePath = UNICODE_NULL;
3051c8d37c1aSHermès Bélusca-Maïto 
3052c8d37c1aSHermès Bélusca-Maïto     /* Close the setup INF as we are going to modify it manually */
3053c8d37c1aSHermès Bélusca-Maïto     if (pSetupData->hSetupInf != INVALID_HANDLE_VALUE)
3054c8d37c1aSHermès Bélusca-Maïto         SetupCloseInfFile(pSetupData->hSetupInf);
3055c8d37c1aSHermès Bélusca-Maïto 
3056c8d37c1aSHermès Bélusca-Maïto 
3057c8d37c1aSHermès Bélusca-Maïto     /* Find the installation source path in Win32 format */
3058c8d37c1aSHermès Bélusca-Maïto     if (!GetInstallSourceWin32(pSetupData->SourcePath,
3059c8d37c1aSHermès Bélusca-Maïto                                _countof(pSetupData->SourcePath),
3060c8d37c1aSHermès Bélusca-Maïto                                szValue))
3061c8d37c1aSHermès Bélusca-Maïto     {
3062c8d37c1aSHermès Bélusca-Maïto         *pSetupData->SourcePath = UNICODE_NULL;
3063c8d37c1aSHermès Bélusca-Maïto     }
3064c8d37c1aSHermès Bélusca-Maïto 
3065c8d37c1aSHermès Bélusca-Maïto     /* Save the path in Win32 format in the setup INF */
3066c8d37c1aSHermès Bélusca-Maïto     swprintf(szValue, L"\"%s\"", pSetupData->SourcePath);
3067c8d37c1aSHermès Bélusca-Maïto     WritePrivateProfileStringW(L"data", L"dospath", szValue, szPath);
3068c8d37c1aSHermès Bélusca-Maïto 
3069c8d37c1aSHermès Bélusca-Maïto     /*
3070c8d37c1aSHermès Bélusca-Maïto      * Save it also in the registry, in the following keys:
3071c8d37c1aSHermès Bélusca-Maïto      * - HKLM\Software\Microsoft\Windows\CurrentVersion\Setup ,
3072c8d37c1aSHermès Bélusca-Maïto      *   values "SourcePath" and "ServicePackSourcePath" (REG_SZ);
3073c8d37c1aSHermès Bélusca-Maïto      * - HKLM\Software\Microsoft\Windows NT\CurrentVersion ,
3074c8d37c1aSHermès Bélusca-Maïto      *   value "SourcePath" (REG_SZ); set to the full path (e.g. D:\I386).
3075c8d37c1aSHermès Bélusca-Maïto      */
3076c8d37c1aSHermès Bélusca-Maïto #if 0
3077c8d37c1aSHermès Bélusca-Maïto     res = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
3078c8d37c1aSHermès Bélusca-Maïto                         L"Software\\Microsoft\\Windows NT\\CurrentVersion",
3079c8d37c1aSHermès Bélusca-Maïto                         0,
3080c8d37c1aSHermès Bélusca-Maïto                         KEY_ALL_ACCESS,
3081c8d37c1aSHermès Bélusca-Maïto                         &hKey);
3082c8d37c1aSHermès Bélusca-Maïto 
3083c8d37c1aSHermès Bélusca-Maïto     if (res != ERROR_SUCCESS)
3084c8d37c1aSHermès Bélusca-Maïto     {
3085c8d37c1aSHermès Bélusca-Maïto         return FALSE;
3086c8d37c1aSHermès Bélusca-Maïto     }
3087c8d37c1aSHermès Bélusca-Maïto #endif
3088c8d37c1aSHermès Bélusca-Maïto 
3089c8d37c1aSHermès Bélusca-Maïto     res = RegCreateKeyExW(HKEY_LOCAL_MACHINE,
3090c8d37c1aSHermès Bélusca-Maïto                           L"Software\\Microsoft\\Windows\\CurrentVersion\\Setup",
3091c8d37c1aSHermès Bélusca-Maïto                           0, NULL,
3092c8d37c1aSHermès Bélusca-Maïto                           REG_OPTION_NON_VOLATILE,
3093c8d37c1aSHermès Bélusca-Maïto                           KEY_ALL_ACCESS, // KEY_WRITE
3094c8d37c1aSHermès Bélusca-Maïto                           NULL,
3095c8d37c1aSHermès Bélusca-Maïto                           &hKey,
3096c8d37c1aSHermès Bélusca-Maïto                           NULL);
3097c8d37c1aSHermès Bélusca-Maïto     if (res == ERROR_SUCCESS)
3098c8d37c1aSHermès Bélusca-Maïto     {
309945c8e4dcSJose Carlos Jesus         AddInstallationSource(hKey, pSetupData->SourcePath);
310045c8e4dcSJose Carlos Jesus 
3101c8d37c1aSHermès Bélusca-Maïto         res = RegSetValueExW(hKey,
3102c8d37c1aSHermès Bélusca-Maïto                              L"SourcePath",
3103c8d37c1aSHermès Bélusca-Maïto                              0,
3104c8d37c1aSHermès Bélusca-Maïto                              REG_SZ,
3105c8d37c1aSHermès Bélusca-Maïto                              (LPBYTE)pSetupData->SourcePath,
3106c8d37c1aSHermès Bélusca-Maïto                              (wcslen(pSetupData->SourcePath) + 1) * sizeof(WCHAR));
3107c8d37c1aSHermès Bélusca-Maïto 
3108c8d37c1aSHermès Bélusca-Maïto         res = RegSetValueExW(hKey,
3109c8d37c1aSHermès Bélusca-Maïto                              L"ServicePackSourcePath",
3110c8d37c1aSHermès Bélusca-Maïto                              0,
3111c8d37c1aSHermès Bélusca-Maïto                              REG_SZ,
3112c8d37c1aSHermès Bélusca-Maïto                              (LPBYTE)pSetupData->SourcePath,
3113c8d37c1aSHermès Bélusca-Maïto                              (wcslen(pSetupData->SourcePath) + 1) * sizeof(WCHAR));
3114c8d37c1aSHermès Bélusca-Maïto 
3115c8d37c1aSHermès Bélusca-Maïto         RegCloseKey(hKey);
3116c8d37c1aSHermès Bélusca-Maïto     }
3117c8d37c1aSHermès Bélusca-Maïto 
3118c8d37c1aSHermès Bélusca-Maïto 
3119c8d37c1aSHermès Bélusca-Maïto     /* Now, re-open the setup INF (this must succeed) */
3120c8d37c1aSHermès Bélusca-Maïto     pSetupData->hSetupInf = SetupOpenInfFileW(szPath,
3121c8d37c1aSHermès Bélusca-Maïto                                               NULL,
3122c8d37c1aSHermès Bélusca-Maïto                                               INF_STYLE_OLDNT,
3123c8d37c1aSHermès Bélusca-Maïto                                               NULL);
3124c8d37c1aSHermès Bélusca-Maïto     if (pSetupData->hSetupInf == INVALID_HANDLE_VALUE)
3125c8d37c1aSHermès Bélusca-Maïto     {
3126c8d37c1aSHermès Bélusca-Maïto         DPRINT1("Error: Cannot open the setup information file %S with error %d\n", szPath, GetLastError());
3127c8d37c1aSHermès Bélusca-Maïto         return;
3128c8d37c1aSHermès Bélusca-Maïto     }
3129c8d37c1aSHermès Bélusca-Maïto 
3130c8d37c1aSHermès Bélusca-Maïto     /* Process the unattended section of the setup file */
3131c8d37c1aSHermès Bélusca-Maïto     ProcessUnattendSection(pSetupData);
3132c2c66affSColin Finck }
3133c2c66affSColin Finck 
3134c2c66affSColin Finck typedef DWORD(WINAPI *PFNREQUESTWIZARDPAGES)(PDWORD, HPROPSHEETPAGE *, PSETUPDATA);
3135c2c66affSColin Finck 
3136c2c66affSColin Finck VOID
InstallWizard(VOID)3137c2c66affSColin Finck InstallWizard(VOID)
3138c2c66affSColin Finck {
313909edc062SMark Jansen     PROPSHEETHEADER psh = {0};
3140c2c66affSColin Finck     HPROPSHEETPAGE *phpage = NULL;
3141c2c66affSColin Finck     PROPSHEETPAGE psp = {0};
3142c2c66affSColin Finck     UINT nPages = 0;
3143c2c66affSColin Finck     HWND hWnd;
3144c2c66affSColin Finck     MSG msg;
3145c2c66affSColin Finck     PSETUPDATA pSetupData = NULL;
3146c2c66affSColin Finck     HMODULE hNetShell = NULL;
3147c2c66affSColin Finck     PFNREQUESTWIZARDPAGES pfn = NULL;
314848160c74SKatayama Hirofumi MZ     DWORD dwPageCount = 10, dwNetworkPageCount = 0;
3149c2c66affSColin Finck 
3150c2c66affSColin Finck     LogItem(L"BEGIN_SECTION", L"InstallWizard");
3151c2c66affSColin Finck 
3152c2c66affSColin Finck     /* Allocate setup data */
3153c2c66affSColin Finck     pSetupData = HeapAlloc(GetProcessHeap(),
3154c2c66affSColin Finck                            HEAP_ZERO_MEMORY,
3155c2c66affSColin Finck                            sizeof(SETUPDATA));
3156c2c66affSColin Finck     if (pSetupData == NULL)
3157c2c66affSColin Finck     {
3158c2c66affSColin Finck         LogItem(NULL, L"SetupData allocation failed!");
3159c2c66affSColin Finck         MessageBoxW(NULL,
3160c2c66affSColin Finck                     L"Setup failed to allocate global data!",
3161c2c66affSColin Finck                     L"ReactOS Setup",
3162c2c66affSColin Finck                     MB_ICONERROR | MB_OK);
3163c2c66affSColin Finck         goto done;
3164c2c66affSColin Finck     }
3165612729b0SKatayama Hirofumi MZ     pSetupData->ProductOption = PRODUCT_OPTION_DEFAULT;
3166c2c66affSColin Finck 
3167c2c66affSColin Finck     hNetShell = LoadLibraryW(L"netshell.dll");
3168c2c66affSColin Finck     if (hNetShell != NULL)
3169c2c66affSColin Finck     {
3170c2c66affSColin Finck         DPRINT("Netshell.dll loaded!\n");
3171c2c66affSColin Finck 
3172c2c66affSColin Finck         pfn = (PFNREQUESTWIZARDPAGES)GetProcAddress(hNetShell,
3173c2c66affSColin Finck                                                     "NetSetupRequestWizardPages");
3174c2c66affSColin Finck         if (pfn != NULL)
3175c2c66affSColin Finck         {
3176c2c66affSColin Finck             pfn(&dwNetworkPageCount, NULL, NULL);
3177c2c66affSColin Finck             dwPageCount += dwNetworkPageCount;
3178c2c66affSColin Finck         }
3179c2c66affSColin Finck     }
3180c2c66affSColin Finck 
3181c2c66affSColin Finck     DPRINT("PageCount: %lu\n", dwPageCount);
3182c2c66affSColin Finck 
3183c2c66affSColin Finck     phpage = HeapAlloc(GetProcessHeap(),
3184c2c66affSColin Finck                        HEAP_ZERO_MEMORY,
3185c2c66affSColin Finck                        dwPageCount * sizeof(HPROPSHEETPAGE));
3186c2c66affSColin Finck     if (phpage == NULL)
3187c2c66affSColin Finck     {
3188c2c66affSColin Finck         LogItem(NULL, L"Page array allocation failed!");
3189c2c66affSColin Finck         MessageBoxW(NULL,
3190c2c66affSColin Finck                     L"Setup failed to allocate page array!",
3191c2c66affSColin Finck                     L"ReactOS Setup",
3192c2c66affSColin Finck                     MB_ICONERROR | MB_OK);
3193c2c66affSColin Finck         goto done;
3194c2c66affSColin Finck     }
3195c2c66affSColin Finck 
3196c8d37c1aSHermès Bélusca-Maïto     /* Process the $winnt$.inf setup file */
3197c8d37c1aSHermès Bélusca-Maïto     ProcessSetupInf(pSetupData);
3198c2c66affSColin Finck 
3199c2c66affSColin Finck     /* Create the Welcome page */
3200c2c66affSColin Finck     psp.dwSize = sizeof(PROPSHEETPAGE);
3201c2c66affSColin Finck     psp.dwFlags = PSP_DEFAULT | PSP_HIDEHEADER;
3202c2c66affSColin Finck     psp.hInstance = hDllInstance;
3203c2c66affSColin Finck     psp.lParam = (LPARAM)pSetupData;
3204c2c66affSColin Finck     psp.pfnDlgProc = WelcomeDlgProc;
3205c2c66affSColin Finck     psp.pszTemplate = MAKEINTRESOURCE(IDD_WELCOMEPAGE);
3206c2c66affSColin Finck     phpage[nPages++] = CreatePropertySheetPage(&psp);
3207c2c66affSColin Finck 
3208c2c66affSColin Finck     /* Create the Acknowledgements page */
3209c2c66affSColin Finck     psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
3210c2c66affSColin Finck     psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_ACKTITLE);
3211c2c66affSColin Finck     psp.pszHeaderSubTitle = MAKEINTRESOURCE(IDS_ACKSUBTITLE);
3212c2c66affSColin Finck     psp.pszTemplate = MAKEINTRESOURCE(IDD_ACKPAGE);
3213c2c66affSColin Finck     psp.pfnDlgProc = AckPageDlgProc;
3214c2c66affSColin Finck     phpage[nPages++] = CreatePropertySheetPage(&psp);
3215c2c66affSColin Finck 
321648160c74SKatayama Hirofumi MZ     /* Create the Product page */
321748160c74SKatayama Hirofumi MZ     psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
321848160c74SKatayama Hirofumi MZ     psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_PRODUCTTITLE);
321948160c74SKatayama Hirofumi MZ     psp.pszHeaderSubTitle = MAKEINTRESOURCE(IDS_PRODUCTSUBTITLE);
322048160c74SKatayama Hirofumi MZ     psp.pszTemplate = MAKEINTRESOURCE(IDD_PRODUCT);
322148160c74SKatayama Hirofumi MZ     psp.pfnDlgProc = ProductPageDlgProc;
322248160c74SKatayama Hirofumi MZ     phpage[nPages++] = CreatePropertySheetPage(&psp);
322348160c74SKatayama Hirofumi MZ 
3224c2c66affSColin Finck     /* Create the Locale page */
3225c2c66affSColin Finck     psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
3226c2c66affSColin Finck     psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_LOCALETITLE);
3227c2c66affSColin Finck     psp.pszHeaderSubTitle = MAKEINTRESOURCE(IDS_LOCALESUBTITLE);
3228c2c66affSColin Finck     psp.pfnDlgProc = LocalePageDlgProc;
3229c2c66affSColin Finck     psp.pszTemplate = MAKEINTRESOURCE(IDD_LOCALEPAGE);
3230c2c66affSColin Finck     phpage[nPages++] = CreatePropertySheetPage(&psp);
3231c2c66affSColin Finck 
3232c2c66affSColin Finck     /* Create the Owner page */
3233c2c66affSColin Finck     psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
3234c2c66affSColin Finck     psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_OWNERTITLE);
3235c2c66affSColin Finck     psp.pszHeaderSubTitle = MAKEINTRESOURCE(IDS_OWNERSUBTITLE);
3236c2c66affSColin Finck     psp.pszTemplate = MAKEINTRESOURCE(IDD_OWNERPAGE);
3237c2c66affSColin Finck     psp.pfnDlgProc = OwnerPageDlgProc;
3238c2c66affSColin Finck     phpage[nPages++] = CreatePropertySheetPage(&psp);
3239c2c66affSColin Finck 
3240c2c66affSColin Finck     /* Create the Computer page */
3241c2c66affSColin Finck     psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
3242c2c66affSColin Finck     psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_COMPUTERTITLE);
3243c2c66affSColin Finck     psp.pszHeaderSubTitle = MAKEINTRESOURCE(IDS_COMPUTERSUBTITLE);
3244c2c66affSColin Finck     psp.pfnDlgProc = ComputerPageDlgProc;
3245c2c66affSColin Finck     psp.pszTemplate = MAKEINTRESOURCE(IDD_COMPUTERPAGE);
3246c2c66affSColin Finck     phpage[nPages++] = CreatePropertySheetPage(&psp);
3247c2c66affSColin Finck 
3248c2c66affSColin Finck     /* Create the DateTime page */
3249c2c66affSColin Finck     psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
3250c2c66affSColin Finck     psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_DATETIMETITLE);
3251c2c66affSColin Finck     psp.pszHeaderSubTitle = MAKEINTRESOURCE(IDS_DATETIMESUBTITLE);
3252c2c66affSColin Finck     psp.pfnDlgProc = DateTimePageDlgProc;
3253c2c66affSColin Finck     psp.pszTemplate = MAKEINTRESOURCE(IDD_DATETIMEPAGE);
3254c2c66affSColin Finck     phpage[nPages++] = CreatePropertySheetPage(&psp);
3255c2c66affSColin Finck 
3256c2c66affSColin Finck     /* Create the theme selection page */
3257c2c66affSColin Finck     psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
3258c2c66affSColin Finck     psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_THEMESELECTIONTITLE);
3259c2c66affSColin Finck     psp.pszHeaderSubTitle = MAKEINTRESOURCE(IDS_THEMESELECTIONSUBTITLE);
3260c2c66affSColin Finck     psp.pfnDlgProc = ThemePageDlgProc;
3261c2c66affSColin Finck     psp.pszTemplate = MAKEINTRESOURCE(IDD_THEMEPAGE);
3262c2c66affSColin Finck     phpage[nPages++] = CreatePropertySheetPage(&psp);
3263c2c66affSColin Finck 
3264c2c66affSColin Finck     pSetupData->uFirstNetworkWizardPage = IDD_PROCESSPAGE;
3265c2c66affSColin Finck     pSetupData->uPostNetworkWizardPage = IDD_PROCESSPAGE;
3266c2c66affSColin Finck 
3267c2c66affSColin Finck     if (pfn)
3268c2c66affSColin Finck     {
3269c2c66affSColin Finck         pfn(&dwNetworkPageCount, &phpage[nPages], pSetupData);
3270c2c66affSColin Finck         nPages += dwNetworkPageCount;
3271c2c66affSColin Finck     }
3272c2c66affSColin Finck 
3273c2c66affSColin Finck     /* Create the Process page */
3274c2c66affSColin Finck     psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
3275c2c66affSColin Finck     psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_PROCESSTITLE);
3276c2c66affSColin Finck     psp.pszHeaderSubTitle = MAKEINTRESOURCE(IDS_PROCESSSUBTITLE);
3277c2c66affSColin Finck     psp.pfnDlgProc = ProcessPageDlgProc;
3278c2c66affSColin Finck     psp.pszTemplate = MAKEINTRESOURCE(IDD_PROCESSPAGE);
3279c2c66affSColin Finck     phpage[nPages++] = CreatePropertySheetPage(&psp);
3280c2c66affSColin Finck 
3281c2c66affSColin Finck     /* Create the Finish page */
3282c2c66affSColin Finck     psp.dwFlags = PSP_DEFAULT | PSP_HIDEHEADER;
3283c2c66affSColin Finck     psp.pfnDlgProc = FinishDlgProc;
3284c2c66affSColin Finck     psp.pszTemplate = MAKEINTRESOURCE(IDD_FINISHPAGE);
3285c2c66affSColin Finck     phpage[nPages++] = CreatePropertySheetPage(&psp);
3286c2c66affSColin Finck 
32871668527aSSerge Gautherie     ASSERT(nPages == dwPageCount);
32881668527aSSerge Gautherie 
3289c2c66affSColin Finck     /* Create the property sheet */
3290c2c66affSColin Finck     psh.dwSize = sizeof(PROPSHEETHEADER);
3291c2c66affSColin Finck     psh.dwFlags = PSH_WIZARD97 | PSH_WATERMARK | PSH_HEADER | PSH_MODELESS;
3292c2c66affSColin Finck     psh.hInstance = hDllInstance;
3293c2c66affSColin Finck     psh.hwndParent = NULL;
3294c2c66affSColin Finck     psh.nPages = nPages;
3295c2c66affSColin Finck     psh.nStartPage = 0;
3296c2c66affSColin Finck     psh.phpage = phpage;
3297c2c66affSColin Finck     psh.pszbmWatermark = MAKEINTRESOURCE(IDB_WATERMARK);
3298c2c66affSColin Finck     psh.pszbmHeader = MAKEINTRESOURCE(IDB_HEADER);
3299c2c66affSColin Finck 
3300c2c66affSColin Finck     /* Create title font */
3301c2c66affSColin Finck     pSetupData->hTitleFont = CreateTitleFont();
3302c2c66affSColin Finck     pSetupData->hBoldFont  = CreateBoldFont();
3303c2c66affSColin Finck 
3304c2c66affSColin Finck     /* Display the wizard */
3305c2c66affSColin Finck     hWnd = (HWND)PropertySheet(&psh);
3306c2c66affSColin Finck     ShowWindow(hWnd, SW_SHOW);
3307c2c66affSColin Finck 
3308c2c66affSColin Finck     while (GetMessage(&msg, NULL, 0, 0))
3309c2c66affSColin Finck     {
3310c2c66affSColin Finck         if (!IsDialogMessage(hWnd, &msg))
3311c2c66affSColin Finck         {
3312c2c66affSColin Finck             TranslateMessage(&msg);
3313c2c66affSColin Finck             DispatchMessage(&msg);
3314c2c66affSColin Finck         }
3315c2c66affSColin Finck     }
3316c2c66affSColin Finck 
33178468ad5cSHermès Bélusca-Maïto     DeleteObject(pSetupData->hBoldFont);
33188468ad5cSHermès Bélusca-Maïto     DeleteObject(pSetupData->hTitleFont);
33198468ad5cSHermès Bélusca-Maïto 
3320c8d37c1aSHermès Bélusca-Maïto     if (pSetupData->hSetupInf != INVALID_HANDLE_VALUE)
3321c8d37c1aSHermès Bélusca-Maïto         SetupCloseInfFile(pSetupData->hSetupInf);
3322c2c66affSColin Finck 
3323c2c66affSColin Finck done:
3324c2c66affSColin Finck     if (phpage != NULL)
3325c2c66affSColin Finck         HeapFree(GetProcessHeap(), 0, phpage);
3326c2c66affSColin Finck 
3327c2c66affSColin Finck     if (hNetShell != NULL)
3328c2c66affSColin Finck         FreeLibrary(hNetShell);
3329c2c66affSColin Finck 
3330c2c66affSColin Finck     if (pSetupData != NULL)
3331c2c66affSColin Finck         HeapFree(GetProcessHeap(), 0, pSetupData);
3332c2c66affSColin Finck 
3333c2c66affSColin Finck     LogItem(L"END_SECTION", L"InstallWizard");
3334c2c66affSColin Finck }
3335c2c66affSColin Finck 
3336c2c66affSColin Finck /* EOF */
3337