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