2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: System setup
4 * FILE: dll/win32/syssetup/wizard.c
5 * PURPOSE: GUI controls
6 * PROGRAMMERS: Eric Kohl
7 * Pierre Schweitzer <heis_spiter@hotmail.com>
8 * Ismael Ferreras Morezuelas <swyterzone+ros@gmail.com>
9 * Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
10 * Oleg Dubinskiy <oleg.dubinskij30@gmail.com>
13 /* INCLUDES *****************************************************************/
30 #define PM_REGISTRATION_NOTIFY (WM_APP + 1)
31 /* Private Message used to communicate progress from the background
32 registration thread to the main thread.
33 wParam = 0 Registration in progress
34 = 1 Registration completed
35 lParam = Pointer to a REGISTRATIONNOTIFY structure */
37 #define PM_ITEM_START (WM_APP + 2)
38 #define PM_ITEM_END (WM_APP + 3)
39 #define PM_STEP_START (WM_APP + 4)
40 #define PM_STEP_END (WM_APP + 5)
41 #define PM_ITEMS_DONE (WM_APP + 6)
43 typedef struct _REGISTRATIONNOTIFY
51 } REGISTRATIONNOTIFY
, *PREGISTRATIONNOTIFY
;
53 typedef struct _ITEMSDATA
56 } ITEMSDATA
, *PITEMSDATA
;
58 typedef struct _REGISTRATIONDATA
64 } REGISTRATIONDATA
, *PREGISTRATIONDATA
;
66 typedef struct _TIMEZONE_ENTRY
68 struct _TIMEZONE_ENTRY
*Prev
;
69 struct _TIMEZONE_ENTRY
*Next
;
70 WCHAR Description
[128]; /* 'Display' */
71 WCHAR StandardName
[32]; /* 'Std' */
72 WCHAR DaylightName
[32]; /* 'Dlt' */
73 REG_TZI_FORMAT TimezoneInfo
; /* 'TZI' */
75 } TIMEZONE_ENTRY
, *PTIMEZONE_ENTRY
;
78 /* FUNCTIONS ****************************************************************/
80 extern void WINAPI
Control_RunDLLW(HWND hWnd
, HINSTANCE hInst
, LPCWSTR cmd
, DWORD nCmdShow
);
84 CenterWindow(HWND hWnd
)
90 hWndParent
= GetParent(hWnd
);
91 if (hWndParent
== NULL
)
92 hWndParent
= GetDesktopWindow();
94 GetWindowRect(hWndParent
, &rcParent
);
95 GetWindowRect(hWnd
, &rcWindow
);
99 ((rcParent
.right
- rcParent
.left
) - (rcWindow
.right
- rcWindow
.left
)) / 2,
100 ((rcParent
.bottom
- rcParent
.top
) - (rcWindow
.bottom
- rcWindow
.top
)) / 2,
108 CreateTitleFont(VOID
)
110 LOGFONTW LogFont
= {0};
114 LogFont
.lfWeight
= FW_BOLD
;
115 wcscpy(LogFont
.lfFaceName
, L
"MS Shell Dlg");
118 LogFont
.lfHeight
= -MulDiv(12, GetDeviceCaps(hdc
, LOGPIXELSY
), 72);
120 hFont
= CreateFontIndirectW(&LogFont
);
122 ReleaseDC(NULL
, hdc
);
131 LOGFONTW tmpFont
= {0};
135 /* Grabs the Drawing Context */
138 tmpFont
.lfHeight
= -MulDiv(8, GetDeviceCaps(hDc
, LOGPIXELSY
), 72);
139 tmpFont
.lfWeight
= FW_BOLD
;
140 wcscpy(tmpFont
.lfFaceName
, L
"MS Shell Dlg");
142 hBoldFont
= CreateFontIndirectW(&tmpFont
);
144 ReleaseDC(NULL
, hDc
);
149 static INT_PTR CALLBACK
150 GplDlgProc(HWND hwndDlg
,
155 HRSRC GplTextResource
;
165 GplTextResource
= FindResourceW(hDllInstance
, MAKEINTRESOURCE(IDR_GPL
), L
"RT_TEXT");
166 if (NULL
== GplTextResource
)
170 Size
= SizeofResource(hDllInstance
, GplTextResource
);
175 GplText
= HeapAlloc(GetProcessHeap(), 0, Size
+ 1);
180 GplTextMem
= LoadResource(hDllInstance
, GplTextResource
);
181 if (NULL
== GplTextMem
)
183 HeapFree(GetProcessHeap(), 0, GplText
);
186 GplTextLocked
= LockResource(GplTextMem
);
187 if (NULL
== GplTextLocked
)
189 HeapFree(GetProcessHeap(), 0, GplText
);
192 memcpy(GplText
, GplTextLocked
, Size
);
193 GplText
[Size
] = '\0';
194 SendMessageA(GetDlgItem(hwndDlg
, IDC_GPL_TEXT
), WM_SETTEXT
, 0, (LPARAM
) GplText
);
195 HeapFree(GetProcessHeap(), 0, GplText
);
196 SetFocus(GetDlgItem(hwndDlg
, IDOK
));
200 EndDialog(hwndDlg
, IDCANCEL
);
204 if (HIWORD(wParam
) == BN_CLICKED
&& IDOK
== LOWORD(wParam
))
206 EndDialog(hwndDlg
, IDOK
);
218 static INT_PTR CALLBACK
219 WelcomeDlgProc(HWND hwndDlg
,
224 PSETUPDATA pSetupData
;
226 pSetupData
= (PSETUPDATA
)GetWindowLongPtr(hwndDlg
, DWLP_USER
);
235 /* Get pointer to the global setup data */
236 pSetupData
= (PSETUPDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
237 SetWindowLongPtr(hwndDlg
, DWLP_USER
, (LONG_PTR
)pSetupData
);
239 hwndControl
= GetParent(hwndDlg
);
241 /* Center the wizard window */
242 CenterWindow (hwndControl
);
244 /* Hide the system menu */
245 dwStyle
= GetWindowLongPtr(hwndControl
, GWL_STYLE
);
246 SetWindowLongPtr(hwndControl
, GWL_STYLE
, dwStyle
& ~WS_SYSMENU
);
248 /* Hide and disable the 'Cancel' button */
249 hwndControl
= GetDlgItem(GetParent(hwndDlg
), IDCANCEL
);
250 ShowWindow (hwndControl
, SW_HIDE
);
251 EnableWindow (hwndControl
, FALSE
);
254 SendDlgItemMessage(hwndDlg
,
257 (WPARAM
)pSetupData
->hTitleFont
,
265 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
270 LogItem(L
"BEGIN", L
"WelcomePage");
271 /* Enable the Next button */
272 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_NEXT
);
273 if (pSetupData
->UnattendSetup
)
275 SetWindowLongPtr(hwndDlg
, DWLP_MSGRESULT
, IDD_ACKPAGE
);
281 LogItem(L
"END", L
"WelcomePage");
285 pSetupData
->UnattendSetup
= FALSE
;
302 static INT_PTR CALLBACK
303 AckPageDlgProc(HWND hwndDlg
,
310 PWCHAR End
, CurrentProject
;
311 INT ProjectsSize
, ProjectsCount
;
312 PSETUPDATA pSetupData
;
314 pSetupData
= (PSETUPDATA
)GetWindowLongPtr(hwndDlg
, DWLP_USER
);
320 pSetupData
= (PSETUPDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
321 SetWindowLongPtr(hwndDlg
, DWLP_USER
, (LONG_PTR
)pSetupData
);
327 Projects
= HeapAlloc(GetProcessHeap(), 0, ProjectsSize
* sizeof(WCHAR
));
328 if (NULL
== Projects
)
332 ProjectsCount
= LoadStringW(hDllInstance
, IDS_ACKPROJECTS
, Projects
, ProjectsSize
);
333 if (0 == ProjectsCount
)
335 HeapFree(GetProcessHeap(), 0, Projects
);
338 if (ProjectsCount
< ProjectsSize
- 1)
342 HeapFree(GetProcessHeap(), 0, Projects
);
346 CurrentProject
= Projects
;
347 while (*CurrentProject
!= L
'\0')
349 End
= wcschr(CurrentProject
, L
'\n');
354 (void)ListBox_AddString(GetDlgItem(hwndDlg
, IDC_PROJECTS
), CurrentProject
);
357 CurrentProject
= End
+ 1;
361 CurrentProject
+= wcslen(CurrentProject
);
364 HeapFree(GetProcessHeap(), 0, Projects
);
369 if (HIWORD(wParam
) == BN_CLICKED
&& IDC_VIEWGPL
== LOWORD(wParam
))
371 DialogBox(hDllInstance
, MAKEINTRESOURCE(IDD_GPL
), NULL
, GplDlgProc
);
372 SetForegroundWindow(GetParent(hwndDlg
));
378 lpnm
= (LPNMHDR
)lParam
;
383 /* Enable the Back and Next buttons */
384 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_BACK
| PSWIZB_NEXT
);
385 if (pSetupData
->UnattendSetup
)
387 SetWindowLongPtr(hwndDlg
, DWLP_MSGRESULT
, IDD_PRODUCT
);
393 pSetupData
->UnattendSetup
= FALSE
;
409 static const WCHAR s_szProductOptions
[] = L
"SYSTEM\\CurrentControlSet\\Control\\ProductOptions";
410 static const WCHAR s_szRosVersion
[] = L
"SYSTEM\\CurrentControlSet\\Control\\ReactOS\\Settings\\Version";
411 static const WCHAR s_szControlWindows
[] = L
"SYSTEM\\CurrentControlSet\\Control\\Windows";
412 static const WCHAR s_szWinlogon
[] = L
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon";
413 static const WCHAR s_szDefaultSoundEvents
[] = L
"AppEvents\\Schemes\\Apps\\.Default";
414 static const WCHAR s_szExplorerSoundEvents
[] = L
"AppEvents\\Schemes\\Apps\\Explorer";
416 typedef struct _PRODUCT_OPTION_DATA
418 LPCWSTR ProductSuite
;
420 DWORD ReportAsWorkstation
;
423 } PRODUCT_OPTION_DATA
;
425 static const PRODUCT_OPTION_DATA s_ProductOptionData
[] =
427 { L
"Terminal Server\0", L
"ServerNT", 0, 0x200, 0 },
428 { L
"\0", L
"WinNT", 1, 0x300, 1 }
431 static const WCHAR
* s_DefaultSoundEvents
[][2] =
433 { L
".Default", L
"%SystemRoot%\\Media\\ReactOS_Default.wav" },
434 { L
"AppGPFault", L
"" },
436 { L
"CriticalBatteryAlarm", L
"%SystemRoot%\\Media\\ReactOS_Battery_Critical.wav" },
437 { L
"DeviceConnect", L
"%SystemRoot%\\Media\\ReactOS_Hardware_Insert.wav" },
438 { L
"DeviceDisconnect", L
"%SystemRoot%\\Media\\ReactOS_Hardware_Remove.wav" },
439 { L
"DeviceFail", L
"%SystemRoot%\\Media\\ReactOS_Hardware_Fail.wav" },
440 { L
"LowBatteryAlarm", L
"%SystemRoot%\\Media\\ReactOS_Battery_Low.wav" },
441 { L
"MailBeep", L
"%SystemRoot%\\Media\\ReactOS_Notify.wav" },
442 { L
"Maximize", L
"%SystemRoot%\\Media\\ReactOS_Restore.wav" },
443 { L
"MenuCommand", L
"%SystemRoot%\\Media\\ReactOS_Menu_Command.wav" },
444 { L
"MenuPopup", L
"" },
445 { L
"Minimize", L
"%SystemRoot%\\Media\\ReactOS_Minimize.wav" },
447 { L
"PrintComplete", L
"%SystemRoot%\\Media\\ReactOS_Print_Complete.wav" },
448 { L
"RestoreDown", L
"" },
449 { L
"RestoreUp", L
"" },
450 { L
"SystemAsterisk", L
"%SystemRoot%\\Media\\ReactOS_Ding.wav" },
451 { L
"SystemExclamation", L
"%SystemRoot%\\Media\\ReactOS_Exclamation.wav" },
452 { L
"SystemExit", L
"%SystemRoot%\\Media\\ReactOS_Shutdown.wav" },
453 { L
"SystemHand", L
"%SystemRoot%\\Media\\ReactOS_Critical_Stop.wav" },
454 { L
"SystemNotification", L
"%SystemRoot%\\Media\\ReactOS_Balloon.wav" },
455 { L
"SystemQuestion", L
"%SystemRoot%\\Media\\ReactOS_Ding.wav" },
456 { L
"SystemStart", L
"%SystemRoot%\\Media\\ReactOS_Startup.wav" },
457 { L
"WindowsLogoff", L
"%SystemRoot%\\Media\\ReactOS_LogOff.wav" }
458 /* Logon sound is already set by default for both Server and Workstation */
461 static const WCHAR
* s_ExplorerSoundEvents
[][2] =
463 { L
"EmptyRecycleBin", L
"%SystemRoot%\\Media\\ReactOS_Recycle.wav" },
464 { L
"Navigating", L
"%SystemRoot%\\Media\\ReactOS_Start.wav" }
468 DoWriteSoundEvents(HKEY hKey
,
470 LPCWSTR lpEventsArray
[][2],
473 HKEY hRootKey
, hEventKey
, hDefaultKey
;
476 WCHAR szDest
[MAX_PATH
];
480 /* Open the sound events key */
481 error
= RegOpenKeyExW(hKey
, lpSubkey
, 0, KEY_READ
, &hRootKey
);
484 DPRINT1("RegOpenKeyExW failed\n");
488 /* Set each sound event */
489 for (i
= 0; i
< dwSize
; i
++)
492 * Verify that the sound file exists and is an actual file.
495 /* Expand the sound file path */
496 if (!ExpandEnvironmentStringsW(lpEventsArray
[i
][1], szDest
, _countof(szDest
)))
498 /* Failed to expand, continue with the next sound event */
502 /* Check if the sound file exists and isn't a directory */
503 dwAttribs
= GetFileAttributesW(szDest
);
504 if ((dwAttribs
== INVALID_FILE_ATTRIBUTES
) ||
505 (dwAttribs
& FILE_ATTRIBUTE_DIRECTORY
))
507 /* It does not, just continue with the next sound event */
512 * Create the sound event entry.
515 /* Open the sound event subkey */
516 error
= RegOpenKeyExW(hRootKey
, lpEventsArray
[i
][0], 0, KEY_READ
, &hEventKey
);
519 /* Failed to open, continue with next sound event */
523 /* Open .Default subkey */
524 error
= RegOpenKeyExW(hEventKey
, L
".Default", 0, KEY_WRITE
, &hDefaultKey
);
525 RegCloseKey(hEventKey
);
528 /* Failed to open, continue with next sound event */
532 /* Associate the sound file to this sound event */
533 cbData
= (lstrlenW(lpEventsArray
[i
][1]) + 1) * sizeof(WCHAR
);
534 error
= RegSetValueExW(hDefaultKey
, NULL
, 0, REG_EXPAND_SZ
, (const BYTE
*)lpEventsArray
[i
][1], cbData
);
535 RegCloseKey(hDefaultKey
);
538 /* Failed to set the value, continue with next sound event */
545 RegCloseKey(hRootKey
);
547 return error
== ERROR_SUCCESS
;
551 DoWriteProductOption(PRODUCT_OPTION nOption
)
556 DWORD dwValue
, cbData
;
557 const PRODUCT_OPTION_DATA
*pData
= &s_ProductOptionData
[nOption
];
558 ASSERT(0 <= nOption
&& nOption
< _countof(s_ProductOptionData
));
560 /* open ProductOptions key */
561 error
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
, s_szProductOptions
, 0, KEY_WRITE
, &hKey
);
564 DPRINT1("RegOpenKeyExW failed\n");
568 /* write ProductSuite */
569 pszData
= pData
->ProductSuite
;
570 cbData
= (lstrlenW(pszData
) + 2) * sizeof(WCHAR
);
571 error
= RegSetValueExW(hKey
, L
"ProductSuite", 0, REG_MULTI_SZ
, (const BYTE
*)pszData
, cbData
);
574 DPRINT1("RegSetValueExW failed\n");
578 /* write ProductType */
579 pszData
= pData
->ProductType
;
580 cbData
= (lstrlenW(pszData
) + 1) * sizeof(WCHAR
);
581 error
= RegSetValueExW(hKey
, L
"ProductType", 0, REG_SZ
, (const BYTE
*)pszData
, cbData
);
584 DPRINT1("RegSetValueExW failed\n");
590 /* open ReactOS version key */
591 error
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
, s_szRosVersion
, 0, KEY_WRITE
, &hKey
);
594 DPRINT1("RegOpenKeyExW failed\n");
598 /* write ReportAsWorkstation */
599 dwValue
= pData
->ReportAsWorkstation
;
600 cbData
= sizeof(dwValue
);
601 error
= RegSetValueExW(hKey
, L
"ReportAsWorkstation", 0, REG_DWORD
, (const BYTE
*)&dwValue
, cbData
);
604 DPRINT1("RegSetValueExW failed\n");
610 /* open Control Windows key */
611 error
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
, s_szControlWindows
, 0, KEY_WRITE
, &hKey
);
614 DPRINT1("RegOpenKeyExW failed\n");
618 /* write Control Windows CSDVersion */
619 dwValue
= pData
->CSDVersion
;
620 cbData
= sizeof(dwValue
);
621 error
= RegSetValueExW(hKey
, L
"CSDVersion", 0, REG_DWORD
, (const BYTE
*)&dwValue
, cbData
);
624 DPRINT1("RegSetValueExW failed\n");
630 /* open Winlogon key */
631 error
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
, s_szWinlogon
, 0, KEY_WRITE
, &hKey
);
634 DPRINT1("RegOpenKeyExW failed\n");
638 /* write LogonType */
639 dwValue
= pData
->LogonType
;
640 cbData
= sizeof(dwValue
);
641 error
= RegSetValueExW(hKey
, L
"LogonType", 0, REG_DWORD
, (const BYTE
*)&dwValue
, cbData
);
644 DPRINT1("RegSetValueExW failed\n");
648 if (nOption
== PRODUCT_OPTION_WORKSTATION
)
650 /* Write system sound events values for Workstation */
651 DoWriteSoundEvents(HKEY_CURRENT_USER
, s_szDefaultSoundEvents
, s_DefaultSoundEvents
, _countof(s_DefaultSoundEvents
));
652 DoWriteSoundEvents(HKEY_CURRENT_USER
, s_szExplorerSoundEvents
, s_ExplorerSoundEvents
, _countof(s_ExplorerSoundEvents
));
659 return error
== ERROR_SUCCESS
;
663 OnChooseOption(HWND hwndDlg
, PRODUCT_OPTION nOption
)
666 ASSERT(0 <= nOption
&& nOption
< _countof(s_ProductOptionData
));
670 case PRODUCT_OPTION_SERVER
:
671 LoadStringW(hDllInstance
, IDS_PRODUCTSERVERINFO
, szText
, _countof(szText
));
674 case PRODUCT_OPTION_WORKSTATION
:
675 LoadStringW(hDllInstance
, IDS_PRODUCTWORKSTATIONINFO
, szText
, _countof(szText
));
682 SetDlgItemTextW(hwndDlg
, IDC_PRODUCT_DESCRIPTION
, szText
);
685 static INT_PTR CALLBACK
686 ProductPageDlgProc(HWND hwndDlg
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
689 PSETUPDATA pSetupData
;
691 WCHAR szText
[64], szDefault
[64];
694 pSetupData
= (PSETUPDATA
)GetWindowLongPtr(hwndDlg
, DWLP_USER
);
700 pSetupData
= (PSETUPDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
701 SetWindowLongPtr(hwndDlg
, DWLP_USER
, (LONG_PTR
)pSetupData
);
703 LoadStringW(hDllInstance
, IDS_DEFAULT
, szDefault
, _countof(szDefault
));
705 LoadStringW(hDllInstance
, IDS_PRODUCTSERVERNAME
, szText
, _countof(szText
));
706 if (PRODUCT_OPTION_DEFAULT
== PRODUCT_OPTION_SERVER
)
708 StringCchCatW(szText
, _countof(szText
), L
" ");
709 StringCchCatW(szText
, _countof(szText
), szDefault
);
711 SendDlgItemMessageW(hwndDlg
, IDC_PRODUCT_OPTIONS
, CB_ADDSTRING
, 0, (LPARAM
)szText
);
713 LoadStringW(hDllInstance
, IDS_PRODUCTWORKSTATIONNAME
, szText
, _countof(szText
));
714 if (PRODUCT_OPTION_DEFAULT
== PRODUCT_OPTION_WORKSTATION
)
716 StringCchCatW(szText
, _countof(szText
), L
" ");
717 StringCchCatW(szText
, _countof(szText
), szDefault
);
719 SendDlgItemMessageW(hwndDlg
, IDC_PRODUCT_OPTIONS
, CB_ADDSTRING
, 0, (LPARAM
)szText
);
721 SendDlgItemMessageW(hwndDlg
, IDC_PRODUCT_OPTIONS
, CB_SETCURSEL
, PRODUCT_OPTION_DEFAULT
, 0);
722 OnChooseOption(hwndDlg
, PRODUCT_OPTION_DEFAULT
);
724 hIcon
= LoadIcon(NULL
, IDI_WINLOGO
);
725 SendDlgItemMessageW(hwndDlg
, IDC_PRODUCT_ICON
, STM_SETICON
, (WPARAM
)hIcon
, 0);
730 if (HIWORD(wParam
) == CBN_SELCHANGE
&& IDC_PRODUCT_OPTIONS
== LOWORD(wParam
))
732 iItem
= SendDlgItemMessageW(hwndDlg
, IDC_PRODUCT_OPTIONS
, CB_GETCURSEL
, 0, 0);
733 OnChooseOption(hwndDlg
, (PRODUCT_OPTION
)iItem
);
739 lpnm
= (LPNMHDR
)lParam
;
744 /* Enable the Back and Next buttons */
745 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_BACK
| PSWIZB_NEXT
);
746 if (pSetupData
->UnattendSetup
)
748 OnChooseOption(hwndDlg
, pSetupData
->ProductOption
);
749 DoWriteProductOption(pSetupData
->ProductOption
);
750 SetWindowLongPtr(hwndDlg
, DWLP_MSGRESULT
, IDD_LOCALEPAGE
);
756 iItem
= SendDlgItemMessageW(hwndDlg
, IDC_PRODUCT_OPTIONS
, CB_GETCURSEL
, 0, 0);
757 pSetupData
->ProductOption
= (PRODUCT_OPTION
)iItem
;
758 DoWriteProductOption(pSetupData
->ProductOption
);
762 pSetupData
->UnattendSetup
= FALSE
;
780 WriteOwnerSettings(WCHAR
* OwnerName
,
781 WCHAR
* OwnerOrganization
)
786 res
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
787 L
"Software\\Microsoft\\Windows NT\\CurrentVersion",
792 if (res
!= ERROR_SUCCESS
)
797 res
= RegSetValueExW(hKey
,
802 (wcslen(OwnerName
) + 1) * sizeof(WCHAR
));
804 if (res
!= ERROR_SUCCESS
)
810 res
= RegSetValueExW(hKey
,
811 L
"RegisteredOrganization",
814 (LPBYTE
)OwnerOrganization
,
815 (wcslen(OwnerOrganization
) + 1) * sizeof(WCHAR
));
818 return (res
== ERROR_SUCCESS
);
821 static INT_PTR CALLBACK
822 OwnerPageDlgProc(HWND hwndDlg
,
828 WCHAR OwnerOrganization
[51];
830 WCHAR ErrorName
[256];
832 PSETUPDATA pSetupData
;
834 pSetupData
= (PSETUPDATA
)GetWindowLongPtr(hwndDlg
, DWLP_USER
);
840 pSetupData
= (PSETUPDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
841 SetWindowLongPtr(hwndDlg
, DWLP_USER
, (LONG_PTR
)pSetupData
);
843 /* set a localized ('Owner') placeholder string as default */
844 if (LoadStringW(hDllInstance
, IDS_MACHINE_OWNER_NAME
, OwnerName
, _countof(OwnerName
)))
846 SendDlgItemMessage(hwndDlg
, IDC_OWNERNAME
, WM_SETTEXT
, 0, (LPARAM
)OwnerName
);
849 SendDlgItemMessage(hwndDlg
, IDC_OWNERNAME
, EM_LIMITTEXT
, 50, 0);
850 SendDlgItemMessage(hwndDlg
, IDC_OWNERORGANIZATION
, EM_LIMITTEXT
, 50, 0);
852 /* Set focus to owner name */
853 SetFocus(GetDlgItem(hwndDlg
, IDC_OWNERNAME
));
855 /* Select the default text to quickly overwrite it by typing */
856 SendDlgItemMessage(hwndDlg
, IDC_OWNERNAME
, EM_SETSEL
, 0, -1);
863 lpnm
= (LPNMHDR
)lParam
;
868 /* Enable the Back and Next buttons */
869 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_BACK
| PSWIZB_NEXT
);
870 if (pSetupData
->UnattendSetup
)
872 SendMessage(GetDlgItem(hwndDlg
, IDC_OWNERNAME
), WM_SETTEXT
, 0, (LPARAM
)pSetupData
->OwnerName
);
873 SendMessage(GetDlgItem(hwndDlg
, IDC_OWNERORGANIZATION
), WM_SETTEXT
, 0, (LPARAM
)pSetupData
->OwnerOrganization
);
874 if (WriteOwnerSettings(pSetupData
->OwnerName
, pSetupData
->OwnerOrganization
))
876 SetWindowLongPtr(hwndDlg
, DWLP_MSGRESULT
, IDD_COMPUTERPAGE
);
884 if (GetDlgItemTextW(hwndDlg
, IDC_OWNERNAME
, OwnerName
, 50) == 0)
886 if (0 == LoadStringW(hDllInstance
, IDS_REACTOS_SETUP
, Title
, ARRAYSIZE(Title
)))
888 wcscpy(Title
, L
"ReactOS Setup");
890 if (0 == LoadStringW(hDllInstance
, IDS_WZD_NAME
, ErrorName
, ARRAYSIZE(ErrorName
)))
892 wcscpy(ErrorName
, L
"Setup cannot continue until you enter your name.");
894 MessageBoxW(hwndDlg
, ErrorName
, Title
, MB_ICONERROR
| MB_OK
);
896 SetFocus(GetDlgItem(hwndDlg
, IDC_OWNERNAME
));
897 SetWindowLongPtr(hwndDlg
, DWLP_MSGRESULT
, -1);
902 OwnerOrganization
[0] = 0;
903 GetDlgItemTextW(hwndDlg
, IDC_OWNERORGANIZATION
, OwnerOrganization
, 50);
905 if (!WriteOwnerSettings(OwnerName
, OwnerOrganization
))
907 SetFocus(GetDlgItem(hwndDlg
, IDC_OWNERNAME
));
908 SetWindowLongPtr(hwndDlg
, DWLP_MSGRESULT
, -1);
913 pSetupData
->UnattendSetup
= FALSE
;
931 WriteComputerSettings(WCHAR
* ComputerName
, HWND hwndDlg
)
934 WCHAR ErrorComputerName
[256];
938 if (!SetComputerNameW(ComputerName
))
942 if (0 == LoadStringW(hDllInstance
, IDS_REACTOS_SETUP
, Title
, ARRAYSIZE(Title
)))
944 wcscpy(Title
, L
"ReactOS Setup");
946 if (0 == LoadStringW(hDllInstance
, IDS_WZD_SETCOMPUTERNAME
, ErrorComputerName
,
947 ARRAYSIZE(ErrorComputerName
)))
949 wcscpy(ErrorComputerName
, L
"Setup failed to set the computer name.");
951 MessageBoxW(hwndDlg
, ErrorComputerName
, Title
, MB_ICONERROR
| MB_OK
);
957 /* Set the physical DNS domain */
958 SetComputerNameExW(ComputerNamePhysicalDnsDomain
, L
"");
960 /* Set the physical DNS hostname */
961 SetComputerNameExW(ComputerNamePhysicalDnsHostname
, ComputerName
);
963 /* Set the accounts domain name */
964 SetAccountsDomainSid(NULL
, ComputerName
);
966 /* Now we need to set the Hostname */
967 lError
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
968 L
"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters",
972 if (lError
!= ERROR_SUCCESS
)
974 DPRINT1("RegOpenKeyExW for Tcpip\\Parameters failed (%08lX)\n", lError
);
978 lError
= RegSetValueEx(hKey
,
982 (LPBYTE
)ComputerName
,
983 (wcslen(ComputerName
) + 1) * sizeof(WCHAR
));
984 if (lError
!= ERROR_SUCCESS
)
986 DPRINT1("RegSetValueEx(\"Hostname\") failed (%08lX)\n", lError
);
997 WriteDefaultLogonData(LPWSTR Domain
)
999 WCHAR szAdministratorName
[256];
1003 if (LoadStringW(hDllInstance
,
1004 IDS_ADMINISTRATOR_NAME
,
1005 szAdministratorName
,
1006 ARRAYSIZE(szAdministratorName
)) == 0)
1008 wcscpy(szAdministratorName
, L
"Administrator");
1011 lError
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
1012 L
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon",
1016 if (lError
!= ERROR_SUCCESS
)
1019 lError
= RegSetValueEx(hKey
,
1020 L
"DefaultDomainName",
1024 (wcslen(Domain
)+ 1) * sizeof(WCHAR
));
1025 if (lError
!= ERROR_SUCCESS
)
1027 DPRINT1("RegSetValueEx(\"DefaultDomainName\") failed!\n");
1030 lError
= RegSetValueEx(hKey
,
1034 (LPBYTE
)szAdministratorName
,
1035 (wcslen(szAdministratorName
)+ 1) * sizeof(WCHAR
));
1036 if (lError
!= ERROR_SUCCESS
)
1038 DPRINT1("RegSetValueEx(\"DefaultUserName\") failed!\n");
1047 /* lpBuffer will be filled with a 15-char string (plus the null terminator) */
1049 GenerateComputerName(LPWSTR lpBuffer
)
1051 static const WCHAR Chars
[] = L
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
1052 static const unsigned cChars
= sizeof(Chars
) / sizeof(WCHAR
) - 1;
1055 wcscpy(lpBuffer
, L
"REACTOS-");
1057 srand(GetTickCount());
1059 /* fill in 7 characters */
1060 for (i
= 8; i
< 15; i
++)
1061 lpBuffer
[i
] = Chars
[rand() % cChars
];
1063 lpBuffer
[15] = UNICODE_NULL
; /* NULL-terminate */
1066 static INT_PTR CALLBACK
1067 ComputerPageDlgProc(HWND hwndDlg
,
1072 WCHAR ComputerName
[MAX_COMPUTERNAME_LENGTH
+ 1];
1073 WCHAR Password1
[128];
1074 WCHAR Password2
[128];
1077 WCHAR EmptyComputerName
[256], NotMatchPassword
[256], WrongPassword
[256];
1079 PSETUPDATA pSetupData
;
1081 pSetupData
= (PSETUPDATA
)GetWindowLongPtr(hwndDlg
, DWLP_USER
);
1083 if (0 == LoadStringW(hDllInstance
, IDS_REACTOS_SETUP
, Title
, ARRAYSIZE(Title
)))
1085 wcscpy(Title
, L
"ReactOS Setup");
1091 pSetupData
= (PSETUPDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
1092 SetWindowLongPtr(hwndDlg
, DWLP_USER
, (LONG_PTR
)pSetupData
);
1094 /* Generate a new pseudo-random computer name */
1095 GenerateComputerName(ComputerName
);
1097 /* Display current computer name */
1098 SetDlgItemTextW(hwndDlg
, IDC_COMPUTERNAME
, ComputerName
);
1100 /* Set text limits */
1101 SendDlgItemMessage(hwndDlg
, IDC_COMPUTERNAME
, EM_LIMITTEXT
, MAX_COMPUTERNAME_LENGTH
, 0);
1102 SendDlgItemMessage(hwndDlg
, IDC_ADMINPASSWORD1
, EM_LIMITTEXT
, 127, 0);
1103 SendDlgItemMessage(hwndDlg
, IDC_ADMINPASSWORD2
, EM_LIMITTEXT
, 127, 0);
1105 /* Set focus to computer name */
1106 SetFocus(GetDlgItem(hwndDlg
, IDC_COMPUTERNAME
));
1107 if (pSetupData
->UnattendSetup
)
1109 SendMessage(GetDlgItem(hwndDlg
, IDC_COMPUTERNAME
), WM_SETTEXT
, 0, (LPARAM
)pSetupData
->ComputerName
);
1110 SendMessage(GetDlgItem(hwndDlg
, IDC_ADMINPASSWORD1
), WM_SETTEXT
, 0, (LPARAM
)pSetupData
->AdminPassword
);
1111 SendMessage(GetDlgItem(hwndDlg
, IDC_ADMINPASSWORD2
), WM_SETTEXT
, 0, (LPARAM
)pSetupData
->AdminPassword
);
1112 WriteComputerSettings(pSetupData
->ComputerName
, NULL
);
1113 SetAdministratorPassword(pSetupData
->AdminPassword
);
1116 /* Store the administrator account name as the default user name */
1117 WriteDefaultLogonData(pSetupData
->ComputerName
);
1123 lpnm
= (LPNMHDR
)lParam
;
1128 /* Enable the Back and Next buttons */
1129 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_BACK
| PSWIZB_NEXT
);
1130 if (pSetupData
->UnattendSetup
&& WriteComputerSettings(pSetupData
->ComputerName
, hwndDlg
))
1132 SetWindowLongPtr(hwndDlg
, DWLP_MSGRESULT
, IDD_THEMEPAGE
);
1138 if (0 == GetDlgItemTextW(hwndDlg
, IDC_COMPUTERNAME
, ComputerName
, MAX_COMPUTERNAME_LENGTH
+ 1))
1140 if (0 == LoadStringW(hDllInstance
, IDS_WZD_COMPUTERNAME
, EmptyComputerName
,
1141 ARRAYSIZE(EmptyComputerName
)))
1143 wcscpy(EmptyComputerName
, L
"Setup cannot continue until you enter the name of your computer.");
1145 MessageBoxW(hwndDlg
, EmptyComputerName
, Title
, MB_ICONERROR
| MB_OK
);
1146 SetFocus(GetDlgItem(hwndDlg
, IDC_COMPUTERNAME
));
1147 SetWindowLongPtr(hwndDlg
, DWLP_MSGRESULT
, -1);
1151 /* No need to check computer name for invalid characters,
1152 * SetComputerName() will do it for us */
1154 if (!WriteComputerSettings(ComputerName
, hwndDlg
))
1156 SetFocus(GetDlgItem(hwndDlg
, IDC_COMPUTERNAME
));
1157 SetWindowLongPtr(hwndDlg
, DWLP_MSGRESULT
, -1);
1161 #ifdef PASSWORDS_MANDATORY
1162 /* Check if admin passwords have been entered */
1163 if ((GetDlgItemText(hwndDlg
, IDC_ADMINPASSWORD1
, Password1
, 128) == 0) ||
1164 (GetDlgItemText(hwndDlg
, IDC_ADMINPASSWORD2
, Password2
, 128) == 0))
1166 if (0 == LoadStringW(hDllInstance
, IDS_WZD_PASSWORDEMPTY
, EmptyPassword
,
1167 ARRAYSIZE(EmptyPassword
)))
1169 wcscpy(EmptyPassword
, L
"You must enter a password !");
1171 MessageBoxW(hwndDlg
, EmptyPassword
, Title
, MB_ICONERROR
| MB_OK
);
1172 SetWindowLongPtr(hwndDlg
, DWLP_MSGRESULT
, -1);
1176 GetDlgItemTextW(hwndDlg
, IDC_ADMINPASSWORD1
, Password1
, 128);
1177 GetDlgItemTextW(hwndDlg
, IDC_ADMINPASSWORD2
, Password2
, 128);
1179 /* Check if passwords match */
1180 if (wcscmp(Password1
, Password2
))
1182 if (0 == LoadStringW(hDllInstance
, IDS_WZD_PASSWORDMATCH
, NotMatchPassword
,
1183 ARRAYSIZE(NotMatchPassword
)))
1185 wcscpy(NotMatchPassword
, L
"The passwords you entered do not match. Please enter the desired password again.");
1187 MessageBoxW(hwndDlg
, NotMatchPassword
, Title
, MB_ICONERROR
| MB_OK
);
1188 SetWindowLongPtr(hwndDlg
, DWLP_MSGRESULT
, -1);
1192 /* Check password for invalid characters */
1193 Password
= (PWCHAR
)Password1
;
1196 if (!isprint(*Password
))
1198 if (0 == LoadStringW(hDllInstance
, IDS_WZD_PASSWORDCHAR
, WrongPassword
,
1199 ARRAYSIZE(WrongPassword
)))
1201 wcscpy(WrongPassword
, L
"The password you entered contains invalid characters. Please enter a cleaned password.");
1203 MessageBoxW(hwndDlg
, WrongPassword
, Title
, MB_ICONERROR
| MB_OK
);
1204 SetWindowLongPtr(hwndDlg
, DWLP_MSGRESULT
, -1);
1210 /* Set admin password */
1211 SetAdministratorPassword(Password1
);
1215 pSetupData
->UnattendSetup
= FALSE
;
1233 SetUserLocaleName(HWND hwnd
)
1235 WCHAR CurLocale
[256] = L
"";
1236 WCHAR CurGeo
[256] = L
"";
1237 WCHAR ResText
[256] = L
"";
1238 WCHAR LocaleText
[256 * 2];
1240 GetLocaleInfoW(GetUserDefaultLCID(), LOCALE_SLANGUAGE
, CurLocale
, ARRAYSIZE(CurLocale
));
1241 GetGeoInfoW(GetUserGeoID(GEOCLASS_NATION
), GEO_FRIENDLYNAME
, CurGeo
, ARRAYSIZE(CurGeo
), GetThreadLocale());
1243 LoadStringW(hDllInstance
, IDS_LOCALETEXT
, ResText
, ARRAYSIZE(ResText
));
1244 StringCchPrintfW(LocaleText
, ARRAYSIZE(LocaleText
), ResText
, CurLocale
, CurGeo
);
1246 SetWindowTextW(hwnd
, LocaleText
);
1250 SetKeyboardLayoutName(HWND hwnd
)
1253 BOOL LayoutSpecial
= FALSE
;
1254 WCHAR LayoutPath
[256];
1255 WCHAR LocaleName
[32];
1256 WCHAR SpecialId
[5] = L
"";
1257 WCHAR ResText
[256] = L
"";
1262 /* Get the default input language and method */
1263 if (!SystemParametersInfoW(SPI_GETDEFAULTINPUTLANG
, 0, (LPDWORD
)&hkl
, 0))
1265 hkl
= GetKeyboardLayout(0);
1268 if ((HIWORD(hkl
) & 0xF000) == 0xF000)
1270 /* Process keyboard layout with special id */
1271 StringCchPrintfW(SpecialId
, ARRAYSIZE(SpecialId
), L
"%04x", (HIWORD(hkl
) & 0x0FFF));
1272 LayoutSpecial
= TRUE
;
1275 #define MAX_LAYOUTS_PER_LANGID 0x10000
1276 for (i
= 0; i
< (LayoutSpecial
? MAX_LAYOUTS_PER_LANGID
: 1); i
++)
1278 /* Generate a hexadecimal identifier for keyboard layout registry key */
1279 StringCchPrintfW(LocaleName
, ARRAYSIZE(LocaleName
), L
"%08lx", (i
<< 16) | LOWORD(hkl
));
1281 StringCchCopyW(LayoutPath
, ARRAYSIZE(LayoutPath
), L
"SYSTEM\\CurrentControlSet\\Control\\Keyboard Layouts\\");
1282 StringCchCatW(LayoutPath
, ARRAYSIZE(LayoutPath
), LocaleName
);
1283 *LocaleName
= UNICODE_NULL
;
1285 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
1289 &hKey
) == ERROR_SUCCESS
)
1291 /* Make sure the keyboard layout key we opened is the one we need.
1292 * If the layout has no special id, just pass this check. */
1293 dwValueSize
= sizeof(LocaleName
);
1294 if (!LayoutSpecial
||
1295 ((RegQueryValueExW(hKey
,
1300 &dwValueSize
) == ERROR_SUCCESS
) &&
1301 (wcscmp(LocaleName
, SpecialId
) == 0)))
1303 *LocaleName
= UNICODE_NULL
;
1304 dwValueSize
= sizeof(LocaleName
);
1305 RegQueryValueExW(hKey
,
1311 /* Let the loop know where to stop */
1312 i
= MAX_LAYOUTS_PER_LANGID
;
1318 /* Keyboard layout registry keys are expected to go in order without gaps */
1322 #undef MAX_LAYOUTS_PER_LANGID
1324 LoadStringW(hDllInstance
, IDS_LAYOUTTEXT
, ResText
, ARRAYSIZE(ResText
));
1325 StringCchPrintfW(LayoutPath
, ARRAYSIZE(LayoutPath
), ResText
, LocaleName
);
1327 SetWindowTextW(hwnd
, LayoutPath
);
1332 RunControlPanelApplet(HWND hwnd
, PCWSTR pwszCPLParameters
)
1335 HWND MainWindow
= GetParent(hwnd
);
1336 STARTUPINFOW StartupInfo
;
1337 PROCESS_INFORMATION ProcessInformation
;
1338 WCHAR CmdLine
[MAX_PATH
] = L
"rundll32.exe shell32.dll,Control_RunDLL ";
1340 if (!pwszCPLParameters
)
1342 MessageBoxW(hwnd
, L
"Error: Failed to launch the Control Panel Applet.", NULL
, MB_ICONERROR
);
1346 ZeroMemory(&StartupInfo
, sizeof(StartupInfo
));
1347 StartupInfo
.cb
= sizeof(StartupInfo
);
1348 ZeroMemory(&ProcessInformation
, sizeof(ProcessInformation
));
1350 ASSERT(_countof(CmdLine
) > wcslen(CmdLine
) + wcslen(pwszCPLParameters
));
1351 wcscat(CmdLine
, pwszCPLParameters
);
1353 if (!CreateProcessW(NULL
,
1362 &ProcessInformation
))
1364 MessageBoxW(hwnd
, L
"Error: Failed to launch the Control Panel Applet.", NULL
, MB_ICONERROR
);
1368 /* Disable the Back and Next buttons and the main window
1369 * while we're interacting with the control panel applet */
1370 PropSheet_SetWizButtons(MainWindow
, 0);
1371 EnableWindow(MainWindow
, FALSE
);
1373 while ((MsgWaitForMultipleObjects(1, &ProcessInformation
.hProcess
, FALSE
, INFINITE
, QS_ALLINPUT
|QS_ALLPOSTMESSAGE
)) != WAIT_OBJECT_0
)
1375 /* We still need to process main window messages to avoid freeze */
1376 while (PeekMessageW(&msg
, NULL
, 0, 0, PM_REMOVE
))
1378 TranslateMessage(&msg
);
1379 DispatchMessageW(&msg
);
1382 CloseHandle(ProcessInformation
.hThread
);
1383 CloseHandle(ProcessInformation
.hProcess
);
1385 /* Enable the Back and Next buttons and the main window again */
1386 PropSheet_SetWizButtons(MainWindow
, PSWIZB_BACK
| PSWIZB_NEXT
);
1387 EnableWindow(MainWindow
, TRUE
);
1393 WriteUserLocale(VOID
)
1399 lcid
= GetSystemDefaultLCID();
1401 if (GetLocaleInfoW(MAKELCID(lcid
, SORT_DEFAULT
), LOCALE_ILANGUAGE
, Locale
, ARRAYSIZE(Locale
)) != 0)
1403 if (RegCreateKeyExW(HKEY_CURRENT_USER
, L
"Control Panel\\International",
1404 0, NULL
, REG_OPTION_NON_VOLATILE
,
1405 KEY_WRITE
, NULL
, &hKey
, NULL
) == ERROR_SUCCESS
)
1407 RegSetValueExW(hKey
, L
"Locale", 0, REG_SZ
, (LPBYTE
)Locale
, (wcslen(Locale
) + 1) * sizeof(WCHAR
));
1413 static INT_PTR CALLBACK
1414 LocalePageDlgProc(HWND hwndDlg
,
1419 PSETUPDATA SetupData
;
1421 /* Retrieve pointer to the global setup data */
1422 SetupData
= (PSETUPDATA
)GetWindowLongPtr(hwndDlg
, GWLP_USERDATA
);
1428 /* Save pointer to the global setup data */
1429 SetupData
= (PSETUPDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
1430 SetWindowLongPtr(hwndDlg
, GWLP_USERDATA
, (DWORD_PTR
)SetupData
);
1433 SetUserLocaleName(GetDlgItem(hwndDlg
, IDC_LOCALETEXT
));
1434 SetKeyboardLayoutName(GetDlgItem(hwndDlg
, IDC_LAYOUTTEXT
));
1439 if (HIWORD(wParam
) == BN_CLICKED
)
1441 switch (LOWORD(wParam
))
1443 case IDC_CUSTOMLOCALE
:
1444 RunControlPanelApplet(hwndDlg
, L
"intl.cpl,,5");
1445 SetUserLocaleName(GetDlgItem(hwndDlg
, IDC_LOCALETEXT
));
1448 case IDC_CUSTOMLAYOUT
:
1449 RunControlPanelApplet(hwndDlg
, L
"input.dll,@1");
1450 SetKeyboardLayoutName(GetDlgItem(hwndDlg
, IDC_LAYOUTTEXT
));
1458 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
1463 /* Enable the Back and Next buttons */
1464 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_BACK
| PSWIZB_NEXT
);
1465 if (SetupData
->UnattendSetup
)
1467 // if (!*SetupData->SourcePath)
1469 RunControlPanelApplet(hwndDlg
, L
"intl.cpl,,/f:\"$winnt$.inf\""); // Should be in System32
1472 SetWindowLongPtr(hwndDlg
, DWLP_MSGRESULT
, IDD_OWNERPAGE
);
1481 SetupData
->UnattendSetup
= FALSE
;
1498 static PTIMEZONE_ENTRY
1499 GetLargerTimeZoneEntry(PSETUPDATA SetupData
, DWORD Index
)
1501 PTIMEZONE_ENTRY Entry
;
1503 Entry
= SetupData
->TimeZoneListHead
;
1504 while (Entry
!= NULL
)
1506 if (Entry
->Index
>= Index
)
1509 Entry
= Entry
->Next
;
1521 PSETUPDATA SetupData
= (PSETUPDATA
)Context
;
1522 PTIMEZONE_ENTRY Entry
;
1523 PTIMEZONE_ENTRY Current
;
1524 ULONG DescriptionSize
;
1525 ULONG StandardNameSize
;
1526 ULONG DaylightNameSize
;
1528 Entry
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(TIMEZONE_ENTRY
));
1531 return ERROR_NOT_ENOUGH_MEMORY
;
1534 DescriptionSize
= sizeof(Entry
->Description
);
1535 StandardNameSize
= sizeof(Entry
->StandardName
);
1536 DaylightNameSize
= sizeof(Entry
->DaylightName
);
1538 lError
= QueryTimeZoneData(hZoneKey
,
1540 &Entry
->TimezoneInfo
,
1543 Entry
->StandardName
,
1545 Entry
->DaylightName
,
1547 if (lError
!= ERROR_SUCCESS
)
1549 HeapFree(GetProcessHeap(), 0, Entry
);
1553 if (SetupData
->TimeZoneListHead
== NULL
&&
1554 SetupData
->TimeZoneListTail
== NULL
)
1558 SetupData
->TimeZoneListHead
= Entry
;
1559 SetupData
->TimeZoneListTail
= Entry
;
1563 Current
= GetLargerTimeZoneEntry(SetupData
, Entry
->Index
);
1564 if (Current
!= NULL
)
1566 if (Current
== SetupData
->TimeZoneListHead
)
1568 /* Prepend to head */
1570 Entry
->Next
= SetupData
->TimeZoneListHead
;
1571 SetupData
->TimeZoneListHead
->Prev
= Entry
;
1572 SetupData
->TimeZoneListHead
= Entry
;
1576 /* Insert before current */
1577 Entry
->Prev
= Current
->Prev
;
1578 Entry
->Next
= Current
;
1579 Current
->Prev
->Next
= Entry
;
1580 Current
->Prev
= Entry
;
1585 /* Append to tail */
1586 Entry
->Prev
= SetupData
->TimeZoneListTail
;
1588 SetupData
->TimeZoneListTail
->Next
= Entry
;
1589 SetupData
->TimeZoneListTail
= Entry
;
1593 return ERROR_SUCCESS
;
1597 CreateTimeZoneList(PSETUPDATA SetupData
)
1599 EnumerateTimeZoneList(RetrieveTimeZone
, SetupData
);
1603 DestroyTimeZoneList(PSETUPDATA SetupData
)
1605 PTIMEZONE_ENTRY Entry
;
1607 while (SetupData
->TimeZoneListHead
!= NULL
)
1609 Entry
= SetupData
->TimeZoneListHead
;
1611 SetupData
->TimeZoneListHead
= Entry
->Next
;
1612 if (SetupData
->TimeZoneListHead
!= NULL
)
1614 SetupData
->TimeZoneListHead
->Prev
= NULL
;
1617 HeapFree(GetProcessHeap(), 0, Entry
);
1620 SetupData
->TimeZoneListTail
= NULL
;
1625 ShowTimeZoneList(HWND hwnd
, PSETUPDATA SetupData
, DWORD dwEntryIndex
)
1627 PTIMEZONE_ENTRY Entry
;
1631 GetTimeZoneListIndex(&dwEntryIndex
);
1633 Entry
= SetupData
->TimeZoneListHead
;
1634 while (Entry
!= NULL
)
1636 dwCount
= SendMessage(hwnd
,
1639 (LPARAM
)Entry
->Description
);
1641 if (dwEntryIndex
!= 0 && dwEntryIndex
== Entry
->Index
)
1644 Entry
= Entry
->Next
;
1655 SetLocalTimeZone(HWND hwnd
, PSETUPDATA SetupData
)
1657 TIME_ZONE_INFORMATION TimeZoneInformation
;
1658 PTIMEZONE_ENTRY Entry
;
1662 dwIndex
= SendMessage(hwnd
,
1668 Entry
= SetupData
->TimeZoneListHead
;
1675 Entry
= Entry
->Next
;
1678 wcscpy(TimeZoneInformation
.StandardName
,
1679 Entry
->StandardName
);
1680 wcscpy(TimeZoneInformation
.DaylightName
,
1681 Entry
->DaylightName
);
1683 TimeZoneInformation
.Bias
= Entry
->TimezoneInfo
.Bias
;
1684 TimeZoneInformation
.StandardBias
= Entry
->TimezoneInfo
.StandardBias
;
1685 TimeZoneInformation
.DaylightBias
= Entry
->TimezoneInfo
.DaylightBias
;
1687 memcpy(&TimeZoneInformation
.StandardDate
,
1688 &Entry
->TimezoneInfo
.StandardDate
,
1689 sizeof(SYSTEMTIME
));
1690 memcpy(&TimeZoneInformation
.DaylightDate
,
1691 &Entry
->TimezoneInfo
.DaylightDate
,
1692 sizeof(SYSTEMTIME
));
1694 /* Set time zone information */
1695 SetTimeZoneInformation(&TimeZoneInformation
);
1700 GetLocalSystemTime(HWND hwnd
, PSETUPDATA SetupData
)
1705 if (DateTime_GetSystemtime(GetDlgItem(hwnd
, IDC_DATEPICKER
), &Date
) != GDT_VALID
)
1710 if (DateTime_GetSystemtime(GetDlgItem(hwnd
, IDC_TIMEPICKER
), &Time
) != GDT_VALID
)
1715 SetupData
->SystemTime
.wYear
= Date
.wYear
;
1716 SetupData
->SystemTime
.wMonth
= Date
.wMonth
;
1717 SetupData
->SystemTime
.wDayOfWeek
= Date
.wDayOfWeek
;
1718 SetupData
->SystemTime
.wDay
= Date
.wDay
;
1719 SetupData
->SystemTime
.wHour
= Time
.wHour
;
1720 SetupData
->SystemTime
.wMinute
= Time
.wMinute
;
1721 SetupData
->SystemTime
.wSecond
= Time
.wSecond
;
1722 SetupData
->SystemTime
.wMilliseconds
= Time
.wMilliseconds
;
1729 SetSystemLocalTime(HWND hwnd
, PSETUPDATA SetupData
)
1734 * Call SetLocalTime twice to ensure correct results
1736 Ret
= SetLocalTime(&SetupData
->SystemTime
) &&
1737 SetLocalTime(&SetupData
->SystemTime
);
1744 UpdateLocalSystemTime(HWND hwnd
, SYSTEMTIME LocalTime
)
1746 DateTime_SetSystemtime(GetDlgItem(hwnd
, IDC_DATEPICKER
), GDT_VALID
, &LocalTime
);
1747 DateTime_SetSystemtime(GetDlgItem(hwnd
, IDC_TIMEPICKER
), GDT_VALID
, &LocalTime
);
1752 WriteDateTimeSettings(HWND hwndDlg
, PSETUPDATA SetupData
)
1755 WCHAR ErrorLocalTime
[256];
1757 GetLocalSystemTime(hwndDlg
, SetupData
);
1758 SetLocalTimeZone(GetDlgItem(hwndDlg
, IDC_TIMEZONELIST
),
1761 SetAutoDaylight(SendDlgItemMessage(hwndDlg
, IDC_AUTODAYLIGHT
,
1762 BM_GETCHECK
, 0, 0) != BST_UNCHECKED
);
1763 if (!SetSystemLocalTime(hwndDlg
, SetupData
))
1765 if (0 == LoadStringW(hDllInstance
, IDS_REACTOS_SETUP
, Title
, ARRAYSIZE(Title
)))
1767 wcscpy(Title
, L
"ReactOS Setup");
1769 if (0 == LoadStringW(hDllInstance
, IDS_WZD_LOCALTIME
, ErrorLocalTime
,
1770 ARRAYSIZE(ErrorLocalTime
)))
1772 wcscpy(ErrorLocalTime
, L
"Setup was unable to set the local time.");
1774 MessageBoxW(hwndDlg
, ErrorLocalTime
, Title
, MB_ICONWARNING
| MB_OK
);
1782 static INT_PTR CALLBACK
1783 DateTimePageDlgProc(HWND hwndDlg
,
1788 PSETUPDATA SetupData
;
1790 /* Retrieve pointer to the global setup data */
1791 SetupData
= (PSETUPDATA
)GetWindowLongPtr(hwndDlg
, GWLP_USERDATA
);
1797 /* Save pointer to the global setup data */
1798 SetupData
= (PSETUPDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
1799 SetWindowLongPtr(hwndDlg
, GWLP_USERDATA
, (DWORD_PTR
)SetupData
);
1801 CreateTimeZoneList(SetupData
);
1803 if (SetupData
->UnattendSetup
)
1805 ShowTimeZoneList(GetDlgItem(hwndDlg
, IDC_TIMEZONELIST
),
1806 SetupData
, SetupData
->TimeZoneIndex
);
1808 if (!SetupData
->DisableAutoDaylightTimeSet
)
1810 SendDlgItemMessage(hwndDlg
, IDC_AUTODAYLIGHT
, BM_SETCHECK
, (WPARAM
)BST_CHECKED
, 0);
1815 ShowTimeZoneList(GetDlgItem(hwndDlg
, IDC_TIMEZONELIST
),
1818 SendDlgItemMessage(hwndDlg
, IDC_AUTODAYLIGHT
, BM_SETCHECK
, (WPARAM
)BST_CHECKED
, 0);
1825 SYSTEMTIME LocalTime
;
1827 GetLocalTime(&LocalTime
);
1828 UpdateLocalSystemTime(hwndDlg
, LocalTime
);
1831 SetTimer(hwndDlg
, 1, 1000 - LocalTime
.wMilliseconds
, NULL
);
1836 switch (((LPNMHDR
)lParam
)->code
)
1840 SYSTEMTIME LocalTime
;
1842 GetLocalTime(&LocalTime
);
1843 UpdateLocalSystemTime(hwndDlg
, LocalTime
);
1845 /* Enable the Back and Next buttons */
1846 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_BACK
| PSWIZB_NEXT
);
1848 if (SetupData
->UnattendSetup
&& WriteDateTimeSettings(hwndDlg
, SetupData
))
1850 SetWindowLongPtr(hwndDlg
, DWLP_MSGRESULT
, SetupData
->uFirstNetworkWizardPage
);
1854 SetTimer(hwndDlg
, 1, 1000 - LocalTime
.wMilliseconds
, NULL
);
1858 case PSN_KILLACTIVE
:
1859 case DTN_DATETIMECHANGE
:
1860 // NB: Not re-set until changing page (PSN_SETACTIVE).
1861 KillTimer(hwndDlg
, 1);
1865 WriteDateTimeSettings(hwndDlg
, SetupData
);
1869 SetupData
->UnattendSetup
= FALSE
;
1878 DestroyTimeZoneList(SetupData
);
1888 static struct ThemeInfo
1890 LPCWSTR PreviewBitmap
;
1895 { MAKEINTRESOURCE(IDB_CLASSIC
), IDS_CLASSIC
, NULL
},
1896 { MAKEINTRESOURCE(IDB_LAUTUS
), IDS_LAUTUS
, L
"themes\\lautus\\lautus.msstyles" },
1897 { MAKEINTRESOURCE(IDB_LUNAR
), IDS_LUNAR
, L
"themes\\lunar\\lunar.msstyles" },
1898 { MAKEINTRESOURCE(IDB_MIZU
), IDS_MIZU
, L
"themes\\mizu\\mizu.msstyles"},
1901 static INT_PTR CALLBACK
1902 ThemePageDlgProc(HWND hwndDlg
,
1907 PSETUPDATA SetupData
;
1910 /* Retrieve pointer to the global setup data */
1911 SetupData
= (PSETUPDATA
)GetWindowLongPtr(hwndDlg
, GWLP_USERDATA
);
1922 /* Save pointer to the global setup data */
1923 SetupData
= (PSETUPDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
1924 SetWindowLongPtr(hwndDlg
, GWLP_USERDATA
, (DWORD_PTR
)SetupData
);
1926 hListView
= GetDlgItem(hwndDlg
, IDC_THEMEPICKER
);
1929 himl
= ImageList_Create(180, 163, ILC_COLOR32
| ILC_MASK
, ARRAYSIZE(Themes
), 1);
1930 lvi
.mask
= LVIF_TEXT
| LVIF_IMAGE
|LVIF_STATE
;
1932 for (n
= 0; n
< ARRAYSIZE(Themes
); ++n
)
1934 WCHAR DisplayName
[100] = {0};
1935 /* Load the bitmap */
1936 HANDLE image
= LoadImageW(hDllInstance
, Themes
[n
].PreviewBitmap
, IMAGE_BITMAP
, 0, 0, LR_CREATEDIBSECTION
);
1937 ImageList_AddMasked(himl
, image
, RGB(255,0,255));
1939 /* Load the string */
1940 LoadStringW(hDllInstance
, Themes
[n
].DisplayName
, DisplayName
, ARRAYSIZE(DisplayName
));
1941 DisplayName
[ARRAYSIZE(DisplayName
)-1] = UNICODE_NULL
;
1943 /* Add the listview item */
1946 lvi
.pszText
= DisplayName
;
1947 ListView_InsertItem(hListView
, &lvi
);
1950 /* Register the imagelist */
1951 ListView_SetImageList(hListView
, himl
, LVSIL_NORMAL
);
1952 /* Transparant background */
1953 ListView_SetBkColor(hListView
, CLR_NONE
);
1954 ListView_SetTextBkColor(hListView
, CLR_NONE
);
1955 /* Reduce the size between the items */
1956 ListView_SetIconSpacing(hListView
, 190, 173);
1960 switch (((LPNMHDR
)lParam
)->code
)
1962 //case LVN_ITEMCHANGING:
1963 case LVN_ITEMCHANGED
:
1964 pnmv
= (LPNMLISTVIEW
)lParam
;
1965 if ((pnmv
->uChanged
& LVIF_STATE
) && (pnmv
->uNewState
& LVIS_SELECTED
))
1967 int iTheme
= pnmv
->iItem
;
1968 DPRINT1("Selected theme: %u\n", Themes
[iTheme
].DisplayName
);
1970 if (Themes
[iTheme
].ThemeFile
)
1972 WCHAR wszParams
[1024];
1973 WCHAR wszTheme
[MAX_PATH
];
1974 WCHAR
* format
= L
"desk.cpl desk,@Appearance /Action:ActivateMSTheme /file:\"%s\"";
1976 SHGetFolderPathAndSubDirW(0, CSIDL_RESOURCES
, NULL
, SHGFP_TYPE_DEFAULT
, Themes
[iTheme
].ThemeFile
, wszTheme
);
1977 swprintf(wszParams
, format
, wszTheme
);
1978 RunControlPanelApplet(hwndDlg
, wszParams
);
1982 RunControlPanelApplet(hwndDlg
, L
"desk.cpl desk,@Appearance /Action:ActivateMSTheme");
1987 /* Enable the Back and Next buttons */
1988 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_BACK
| PSWIZB_NEXT
);
1989 if (SetupData
->UnattendSetup
)
1991 SetWindowLongPtr(hwndDlg
, DWLP_MSGRESULT
, SetupData
->uFirstNetworkWizardPage
);
2000 SetupData
->UnattendSetup
= FALSE
;
2015 static UINT CALLBACK
2016 RegistrationNotificationProc(PVOID Context
,
2021 PREGISTRATIONDATA RegistrationData
;
2022 REGISTRATIONNOTIFY RegistrationNotify
;
2023 PSP_REGISTER_CONTROL_STATUSW StatusInfo
;
2026 RegistrationData
= (PREGISTRATIONDATA
)Context
;
2028 if (Notification
== SPFILENOTIFY_STARTREGISTRATION
||
2029 Notification
== SPFILENOTIFY_ENDREGISTRATION
)
2031 StatusInfo
= (PSP_REGISTER_CONTROL_STATUSW
) Param1
;
2032 RegistrationNotify
.CurrentItem
= wcsrchr(StatusInfo
->FileName
, L
'\\');
2033 if (RegistrationNotify
.CurrentItem
== NULL
)
2035 RegistrationNotify
.CurrentItem
= StatusInfo
->FileName
;
2039 RegistrationNotify
.CurrentItem
++;
2042 if (Notification
== SPFILENOTIFY_STARTREGISTRATION
)
2044 DPRINT("Received SPFILENOTIFY_STARTREGISTRATION notification for %S\n",
2045 StatusInfo
->FileName
);
2046 RegistrationNotify
.ErrorMessage
= NULL
;
2047 RegistrationNotify
.Progress
= RegistrationData
->Registered
;
2048 SendMessage(RegistrationData
->hwndDlg
, PM_STEP_START
, 0, (LPARAM
)&RegistrationNotify
);
2052 DPRINT("Received SPFILENOTIFY_ENDREGISTRATION notification for %S\n",
2053 StatusInfo
->FileName
);
2054 DPRINT("Win32Error %u FailureCode %u\n", StatusInfo
->Win32Error
,
2055 StatusInfo
->FailureCode
);
2056 if (StatusInfo
->FailureCode
!= SPREG_SUCCESS
)
2058 switch (StatusInfo
->FailureCode
)
2060 case SPREG_LOADLIBRARY
:
2061 MessageID
= IDS_LOADLIBRARY_FAILED
;
2063 case SPREG_GETPROCADDR
:
2064 MessageID
= IDS_GETPROCADDR_FAILED
;
2067 MessageID
= IDS_REGSVR_FAILED
;
2069 case SPREG_DLLINSTALL
:
2070 MessageID
= IDS_DLLINSTALL_FAILED
;
2073 MessageID
= IDS_TIMEOUT
;
2076 MessageID
= IDS_REASON_UNKNOWN
;
2080 RegistrationNotify
.MessageID
= MessageID
;
2081 RegistrationNotify
.LastError
= StatusInfo
->Win32Error
;
2085 RegistrationNotify
.MessageID
= 0;
2086 RegistrationNotify
.LastError
= ERROR_SUCCESS
;
2089 if (RegistrationData
->Registered
< RegistrationData
->DllCount
)
2091 RegistrationData
->Registered
++;
2094 RegistrationNotify
.Progress
= RegistrationData
->Registered
;
2095 SendMessage(RegistrationData
->hwndDlg
, PM_STEP_END
, 0, (LPARAM
)&RegistrationNotify
);
2102 DPRINT1("Received unexpected notification %u\n", Notification
);
2103 return SetupDefaultQueueCallback(RegistrationData
->DefaultContext
,
2104 Notification
, Param1
, Param2
);
2112 PITEMSDATA pItemsData
)
2114 REGISTRATIONDATA RegistrationData
;
2115 WCHAR SectionName
[512];
2118 DWORD LastError
= NO_ERROR
;
2120 ZeroMemory(&RegistrationData
, sizeof(REGISTRATIONDATA
));
2121 RegistrationData
.hwndDlg
= pItemsData
->hwndDlg
;
2122 RegistrationData
.Registered
= 0;
2124 if (!SetupFindFirstLineW(hSysSetupInf
, L
"RegistrationPhase2",
2125 L
"RegisterDlls", &Context
))
2127 DPRINT1("No RegistrationPhase2 section found\n");
2131 if (!SetupGetStringFieldW(&Context
, 1, SectionName
,
2132 ARRAYSIZE(SectionName
),
2135 DPRINT1("Unable to retrieve section name\n");
2139 DllCount
= SetupGetLineCountW(hSysSetupInf
, SectionName
);
2140 DPRINT1("SectionName %S DllCount %ld\n", SectionName
, DllCount
);
2143 SetLastError(STATUS_NOT_FOUND
);
2147 RegistrationData
.DllCount
= (ULONG
)DllCount
;
2148 RegistrationData
.DefaultContext
= SetupInitDefaultQueueCallback(RegistrationData
.hwndDlg
);
2150 SendMessage(pItemsData
->hwndDlg
, PM_ITEM_START
, 0, (LPARAM
)RegistrationData
.DllCount
);
2154 if (!SetupInstallFromInfSectionW(GetParent(RegistrationData
.hwndDlg
),
2156 L
"RegistrationPhase2",
2157 SPINST_REGISTRY
| SPINST_REGISTERCALLBACKAWARE
| SPINST_REGSVR
,
2161 RegistrationNotificationProc
,
2166 LastError
= GetLastError();
2169 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
2171 DPRINT("Catching exception\n");
2172 LastError
= RtlNtStatusToDosError(_SEH2_GetExceptionCode());
2176 SetupTermDefaultQueueCallback(RegistrationData
.DefaultContext
);
2178 SendMessage(pItemsData
->hwndDlg
, PM_ITEM_END
, 0, LastError
);
2187 ItemCompletionThread(
2190 PITEMSDATA pItemsData
;
2193 pItemsData
= (PITEMSDATA
)Parameter
;
2194 hwndDlg
= pItemsData
->hwndDlg
;
2196 RegisterDlls(pItemsData
);
2198 RegisterTypeLibraries(hSysSetupInf
, L
"TypeLibraries");
2200 /* FIXME: Add completion steps here! */
2202 // FIXME: Move this call to a separate cleanup page!
2203 RtlCreateBootStatusDataFile();
2205 /* Free the items data */
2206 HeapFree(GetProcessHeap(), 0, pItemsData
);
2208 /* Tell the wizard page that we are done */
2209 PostMessage(hwndDlg
, PM_ITEMS_DONE
, 0, 0);
2217 RunItemCompletionThread(
2220 HANDLE hCompletionThread
;
2221 PITEMSDATA pItemsData
;
2223 pItemsData
= HeapAlloc(GetProcessHeap(), 0, sizeof(ITEMSDATA
));
2224 if (pItemsData
== NULL
)
2227 pItemsData
->hwndDlg
= hwndDlg
;
2229 hCompletionThread
= CreateThread(NULL
,
2231 ItemCompletionThread
,
2235 if (hCompletionThread
== NULL
)
2237 HeapFree(GetProcessHeap(), 0, pItemsData
);
2241 CloseHandle(hCompletionThread
);
2254 LPWSTR ErrorMessage
= NULL
;
2255 WCHAR UnknownError
[84];
2258 if (FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER
| FORMAT_MESSAGE_FROM_SYSTEM
,
2259 NULL
, LastError
, 0, ErrorMessage
, 0, NULL
) == 0)
2261 if (LoadStringW(hDllInstance
, IDS_UNKNOWN_ERROR
,
2263 ARRAYSIZE(UnknownError
) - 20) == 0)
2265 wcscpy(UnknownError
, L
"Unknown error");
2267 wcscat(UnknownError
, L
" ");
2268 _ultow(LastError
, UnknownError
+ wcslen(UnknownError
), 10);
2269 ErrorMessage
= UnknownError
;
2272 if (ErrorMessage
!= NULL
)
2274 if (LoadStringW(hDllInstance
, IDS_REACTOS_SETUP
,
2275 Title
, ARRAYSIZE(Title
)) == 0)
2277 wcscpy(Title
, L
"ReactOS Setup");
2280 MessageBoxW(hwndDlg
, ErrorMessage
, Title
, MB_ICONERROR
| MB_OK
);
2283 if (ErrorMessage
!= NULL
&&
2284 ErrorMessage
!= UnknownError
)
2286 LocalFree(ErrorMessage
);
2295 PREGISTRATIONNOTIFY RegistrationNotify
)
2297 WCHAR ErrorMessage
[128];
2300 if (LoadStringW(hDllInstance
, RegistrationNotify
->MessageID
,
2302 ARRAYSIZE(ErrorMessage
)) == 0)
2304 ErrorMessage
[0] = L
'\0';
2307 if (RegistrationNotify
->MessageID
!= IDS_TIMEOUT
)
2309 FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM
, NULL
,
2310 RegistrationNotify
->LastError
, 0,
2311 ErrorMessage
+ wcslen(ErrorMessage
),
2312 ARRAYSIZE(ErrorMessage
) - wcslen(ErrorMessage
),
2316 if (ErrorMessage
[0] != L
'\0')
2318 if (LoadStringW(hDllInstance
, IDS_REACTOS_SETUP
,
2319 Title
, ARRAYSIZE(Title
)) == 0)
2321 wcscpy(Title
, L
"ReactOS Setup");
2324 MessageBoxW(hwndDlg
, ErrorMessage
,
2325 Title
, MB_ICONERROR
| MB_OK
);
2330 static INT_PTR CALLBACK
2331 ProcessPageDlgProc(HWND hwndDlg
,
2336 PSETUPDATA SetupData
;
2337 PREGISTRATIONNOTIFY RegistrationNotify
;
2339 /* Retrieve pointer to the global setup data */
2340 SetupData
= (PSETUPDATA
)GetWindowLongPtr(hwndDlg
, GWLP_USERDATA
);
2345 /* Save pointer to the global setup data */
2346 SetupData
= (PSETUPDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
2347 SetWindowLongPtr(hwndDlg
, GWLP_USERDATA
, (DWORD_PTR
)SetupData
);
2348 ShowWindow(GetDlgItem(hwndDlg
, IDC_TASKTEXT2
), SW_HIDE
);
2349 ShowWindow(GetDlgItem(hwndDlg
, IDC_TASKTEXT3
), SW_HIDE
);
2350 ShowWindow(GetDlgItem(hwndDlg
, IDC_TASKTEXT4
), SW_HIDE
);
2354 switch (((LPNMHDR
)lParam
)->code
)
2357 /* Disable the Back and Next buttons */
2358 PropSheet_SetWizButtons(GetParent(hwndDlg
), 0);
2359 RunItemCompletionThread(hwndDlg
);
2366 SetupData
->UnattendSetup
= FALSE
;
2375 DPRINT("PM_ITEM_START %lu\n", (ULONG
)lParam
);
2376 SendDlgItemMessage(hwndDlg
, IDC_PROCESSPROGRESS
, PBM_SETRANGE
, 0, MAKELPARAM(0, (ULONG
)lParam
));
2377 SendDlgItemMessage(hwndDlg
, IDC_PROCESSPROGRESS
, PBM_SETPOS
, 0, 0);
2378 SendDlgItemMessage(hwndDlg
, IDC_TASKTEXT1
+ wParam
, WM_SETFONT
, (WPARAM
)SetupData
->hBoldFont
, (LPARAM
)TRUE
);
2382 DPRINT("PM_ITEM_END\n");
2383 if (lParam
== ERROR_SUCCESS
)
2388 ShowItemError(hwndDlg
, (DWORD
)lParam
);
2393 DPRINT("PM_STEP_START\n");
2394 RegistrationNotify
= (PREGISTRATIONNOTIFY
)lParam
;
2395 SendDlgItemMessage(hwndDlg
, IDC_ITEM
, WM_SETTEXT
, 0,
2396 (LPARAM
)((RegistrationNotify
->CurrentItem
!= NULL
)? RegistrationNotify
->CurrentItem
: L
""));
2400 DPRINT("PM_STEP_END\n");
2401 RegistrationNotify
= (PREGISTRATIONNOTIFY
)lParam
;
2402 SendDlgItemMessage(hwndDlg
, IDC_PROCESSPROGRESS
, PBM_SETPOS
, RegistrationNotify
->Progress
, 0);
2403 if (RegistrationNotify
->LastError
!= ERROR_SUCCESS
)
2405 ShowStepError(hwndDlg
, RegistrationNotify
);
2410 DPRINT("PM_ITEMS_DONE\n");
2411 /* Enable the Back and Next buttons */
2412 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_NEXT
);
2413 PropSheet_PressButton(GetParent(hwndDlg
), PSBTN_NEXT
);
2425 SetInstallationCompleted(VOID
)
2428 DWORD InProgress
= 0;
2431 if (RegOpenKeyExW( HKEY_LOCAL_MACHINE
,
2435 &hKey
) == ERROR_SUCCESS
)
2437 RegSetValueExW( hKey
, L
"SystemSetupInProgress", 0, REG_DWORD
, (LPBYTE
)&InProgress
, sizeof(InProgress
) );
2438 RegCloseKey( hKey
);
2441 if (RegOpenKeyExW( HKEY_LOCAL_MACHINE
,
2442 L
"Software\\Microsoft\\Windows NT\\CurrentVersion",
2445 &hKey
) == ERROR_SUCCESS
)
2447 InstallDate
= (DWORD
)time(NULL
);
2448 RegSetValueExW( hKey
, L
"InstallDate", 0, REG_DWORD
, (LPBYTE
)&InstallDate
, sizeof(InstallDate
) );
2449 RegCloseKey( hKey
);
2453 static INT_PTR CALLBACK
2454 FinishDlgProc(HWND hwndDlg
,
2464 /* Get pointer to the global setup data */
2465 PSETUPDATA SetupData
= (PSETUPDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
2467 if (!SetupData
->UnattendSetup
|| !SetupData
->DisableGeckoInst
)
2469 /* Run the Wine Gecko prompt */
2470 Control_RunDLLW(hwndDlg
, 0, L
"appwiz.cpl install_gecko", SW_SHOW
);
2473 /* Set title font */
2474 SendDlgItemMessage(hwndDlg
,
2477 (WPARAM
)SetupData
->hTitleFont
,
2479 if (SetupData
->UnattendSetup
)
2481 KillTimer(hwndDlg
, 1);
2482 SetInstallationCompleted();
2490 SetInstallationCompleted();
2500 hWndProgress
= GetDlgItem(hwndDlg
, IDC_RESTART_PROGRESS
);
2501 Position
= SendMessage(hWndProgress
, PBM_GETPOS
, 0, 0);
2502 if (Position
== 300)
2504 KillTimer(hwndDlg
, 1);
2505 PropSheet_PressButton(GetParent(hwndDlg
), PSBTN_FINISH
);
2509 SendMessage(hWndProgress
, PBM_SETPOS
, Position
+ 1, 0);
2516 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
2521 /* Enable the correct buttons on for the active page */
2522 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_FINISH
);
2524 SendDlgItemMessage(hwndDlg
, IDC_RESTART_PROGRESS
, PBM_SETRANGE
, 0,
2525 MAKELPARAM(0, 300));
2526 SendDlgItemMessage(hwndDlg
, IDC_RESTART_PROGRESS
, PBM_SETPOS
, 0, 0);
2527 SetTimer(hwndDlg
, 1, 50, NULL
);
2531 DestroyWindow(GetParent(hwndDlg
));
2549 * GetInstallSourceWin32 retrieves the path to the ReactOS installation medium
2550 * in Win32 format, for later use by syssetup and storage in the registry.
2553 GetInstallSourceWin32(
2555 IN DWORD cchPathMax
,
2556 IN PCWSTR pwszNTPath
)
2558 WCHAR wszDrives
[512];
2559 WCHAR wszNTPath
[512]; // MAX_PATH ?
2563 *pwszPath
= UNICODE_NULL
;
2565 cchDrives
= GetLogicalDriveStringsW(_countof(wszDrives
) - 1, wszDrives
);
2566 if (cchDrives
== 0 || cchDrives
>= _countof(wszDrives
))
2568 /* Buffer too small or failure */
2569 LogItem(NULL
, L
"GetLogicalDriveStringsW failed");
2573 for (pwszDrive
= wszDrives
; *pwszDrive
; pwszDrive
+= wcslen(pwszDrive
) + 1)
2575 WCHAR wszBuf
[MAX_PATH
];
2577 /* Retrieve the NT path corresponding to the current Win32 DOS path */
2578 pwszDrive
[2] = UNICODE_NULL
; // Temporarily remove the backslash
2579 QueryDosDeviceW(pwszDrive
, wszNTPath
, _countof(wszNTPath
));
2580 pwszDrive
[2] = L
'\\'; // Restore the backslash
2582 wcscat(wszNTPath
, L
"\\"); // Concat a backslash
2585 wsprintf(wszBuf
, L
"Testing '%s' --> '%s' %s a CD",
2586 pwszDrive
, wszNTPath
,
2587 (GetDriveTypeW(pwszDrive
) == DRIVE_CDROM
) ? L
"is" : L
"is not");
2588 LogItem(NULL
, wszBuf
);
2590 /* Check whether the NT path corresponds to the NT installation source path */
2591 if (!_wcsicmp(wszNTPath
, pwszNTPath
))
2594 wcscpy(pwszPath
, pwszDrive
); // cchPathMax
2597 wsprintf(wszBuf
, L
"GetInstallSourceWin32: %s", pwszPath
);
2598 LogItem(NULL
, wszBuf
);
2599 wcscat(wszBuf
, L
"\n");
2600 OutputDebugStringW(wszBuf
);
2610 ProcessUnattendSection(
2611 IN OUT PSETUPDATA pSetupData
)
2613 INFCONTEXT InfContext
;
2615 WCHAR szValue
[MAX_PATH
];
2619 if (!SetupFindFirstLineW(pSetupData
->hSetupInf
,
2621 L
"UnattendSetupEnabled",
2624 DPRINT1("Error: Cannot find UnattendSetupEnabled Key! %d\n", GetLastError());
2628 if (!SetupGetStringFieldW(&InfContext
,
2634 DPRINT1("Error: SetupGetStringField failed with %d\n", GetLastError());
2638 if (_wcsicmp(szValue
, L
"yes") != 0)
2640 DPRINT("Unattend setup was disabled by UnattendSetupEnabled key.\n");
2644 pSetupData
->UnattendSetup
= TRUE
;
2646 if (!SetupFindFirstLineW(pSetupData
->hSetupInf
,
2651 DPRINT1("Error: SetupFindFirstLine failed %d\n", GetLastError());
2657 if (!SetupGetStringFieldW(&InfContext
,
2663 DPRINT1("Error: SetupGetStringField failed with %d\n", GetLastError());
2667 if (!SetupGetStringFieldW(&InfContext
,
2673 DPRINT1("Error: SetupGetStringField failed with %d\n", GetLastError());
2676 DPRINT1("Name %S Value %S\n", szName
, szValue
);
2677 if (!_wcsicmp(szName
, L
"FullName"))
2679 if (ARRAYSIZE(pSetupData
->OwnerName
) > LineLength
)
2681 wcscpy(pSetupData
->OwnerName
, szValue
);
2684 else if (!_wcsicmp(szName
, L
"OrgName"))
2686 if (ARRAYSIZE(pSetupData
->OwnerOrganization
) > LineLength
)
2688 wcscpy(pSetupData
->OwnerOrganization
, szValue
);
2691 else if (!_wcsicmp(szName
, L
"ComputerName"))
2693 if (ARRAYSIZE(pSetupData
->ComputerName
) > LineLength
)
2695 wcscpy(pSetupData
->ComputerName
, szValue
);
2698 else if (!_wcsicmp(szName
, L
"AdminPassword"))
2700 if (ARRAYSIZE(pSetupData
->AdminPassword
) > LineLength
)
2702 wcscpy(pSetupData
->AdminPassword
, szValue
);
2705 else if (!_wcsicmp(szName
, L
"TimeZoneIndex"))
2707 pSetupData
->TimeZoneIndex
= _wtoi(szValue
);
2709 else if (!_wcsicmp(szName
, L
"DisableAutoDaylightTimeSet"))
2711 pSetupData
->DisableAutoDaylightTimeSet
= _wtoi(szValue
);
2713 else if (!_wcsicmp(szName
, L
"DisableGeckoInst"))
2715 if (!_wcsicmp(szValue
, L
"yes"))
2716 pSetupData
->DisableGeckoInst
= TRUE
;
2718 pSetupData
->DisableGeckoInst
= FALSE
;
2720 else if (!_wcsicmp(szName
, L
"ProductOption"))
2722 pSetupData
->ProductOption
= (PRODUCT_OPTION
)_wtoi(szValue
);
2724 } while (SetupFindNextLine(&InfContext
, &InfContext
));
2726 if (SetupFindFirstLineW(pSetupData
->hSetupInf
,
2731 DEVMODEW dm
= { { 0 } };
2732 dm
.dmSize
= sizeof(dm
);
2733 if (EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &dm
))
2738 if (!SetupGetStringFieldW(&InfContext
,
2744 DPRINT1("Error: SetupGetStringField failed with %d\n", GetLastError());
2748 if (!SetupGetStringFieldW(&InfContext
,
2754 DPRINT1("Error: SetupGetStringField failed with %d\n", GetLastError());
2757 iValue
= _wtoi(szValue
);
2758 DPRINT1("Name %S Value %i\n", szName
, iValue
);
2763 if (!_wcsicmp(szName
, L
"BitsPerPel"))
2765 dm
.dmFields
|= DM_BITSPERPEL
;
2766 dm
.dmBitsPerPel
= iValue
;
2768 else if (!_wcsicmp(szName
, L
"XResolution"))
2770 dm
.dmFields
|= DM_PELSWIDTH
;
2771 dm
.dmPelsWidth
= iValue
;
2773 else if (!_wcsicmp(szName
, L
"YResolution"))
2775 dm
.dmFields
|= DM_PELSHEIGHT
;
2776 dm
.dmPelsHeight
= iValue
;
2778 else if (!_wcsicmp(szName
, L
"VRefresh"))
2780 dm
.dmFields
|= DM_DISPLAYFREQUENCY
;
2781 dm
.dmDisplayFrequency
= iValue
;
2783 } while (SetupFindNextLine(&InfContext
, &InfContext
));
2785 ChangeDisplaySettingsW(&dm
, CDS_UPDATEREGISTRY
);
2789 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
2790 L
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunOnce",
2793 &hKey
) != ERROR_SUCCESS
)
2795 DPRINT1("Error: failed to open HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\RunOnce\n");
2799 if (SetupFindFirstLineW(pSetupData
->hSetupInf
,
2807 if (SetupGetStringFieldW(&InfContext
,
2813 WCHAR szPath
[MAX_PATH
];
2814 swprintf(szName
, L
"%d", i
);
2815 DPRINT("szName %S szValue %S\n", szName
, szValue
);
2817 if (ExpandEnvironmentStringsW(szValue
, szPath
, MAX_PATH
))
2819 DPRINT("value %S\n", szPath
);
2820 if (RegSetValueExW(hKey
,
2824 (const BYTE
*)szPath
,
2825 (wcslen(szPath
) + 1) * sizeof(WCHAR
)) == ERROR_SUCCESS
)
2831 } while (SetupFindNextLine(&InfContext
, &InfContext
));
2836 if (SetupFindFirstLineW(pSetupData
->hSetupInf
,
2841 if (RegCreateKeyExW(
2842 HKEY_LOCAL_MACHINE
, L
"SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment", 0, NULL
,
2843 REG_OPTION_NON_VOLATILE
, KEY_WRITE
| KEY_READ
, NULL
, &hKey
, NULL
) != ERROR_SUCCESS
)
2845 DPRINT1("Error: failed to open HKLM\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment\n");
2850 if (!SetupGetStringFieldW(&InfContext
,
2856 DPRINT1("Error: SetupGetStringField failed with %d\n", GetLastError());
2860 if (!SetupGetStringFieldW(&InfContext
,
2866 DPRINT1("Error: SetupGetStringField failed with %d\n", GetLastError());
2869 DPRINT1("[ENV] %S=%S\n", szName
, szValue
);
2871 DWORD dwType
= wcschr(szValue
, '%') != NULL
? REG_EXPAND_SZ
: REG_SZ
;
2873 if (RegSetValueExW(hKey
, szName
, 0, dwType
, (const BYTE
*)szValue
, (DWORD
)(wcslen(szValue
) + 1) * sizeof(TCHAR
)) != ERROR_SUCCESS
)
2875 DPRINT1(" - Error %d\n", GetLastError());
2878 } while (SetupFindNextLine(&InfContext
, &InfContext
));
2889 WCHAR szPath1
[MAX_PATH
];
2890 WCHAR szPath2
[MAX_PATH
];
2892 /* If something goes wrong, better return TRUE,
2893 * so the calling function returns early.
2895 if (!PathCanonicalizeW(szPath1
, lpPath1
))
2898 if (!PathAddBackslashW(szPath1
))
2901 if (!PathCanonicalizeW(szPath2
, lpPath2
))
2904 if (!PathAddBackslashW(szPath2
))
2907 return (_wcsicmp(szPath1
, szPath2
) == 0);
2911 AddInstallationSource(
2917 DWORD dwPathLength
= 0;
2918 DWORD dwNewLength
= 0;
2919 LPWSTR Buffer
= NULL
;
2922 res
= RegQueryValueExW(
2924 L
"Installation Sources",
2930 if (res
!= ERROR_SUCCESS
||
2931 dwRegType
!= REG_MULTI_SZ
||
2932 dwPathLength
== 0 ||
2933 dwPathLength
% sizeof(WCHAR
) != 0)
2939 /* Reserve space for existing data + new string */
2940 dwNewLength
= dwPathLength
+ (wcslen(lpPath
) + 1) * sizeof(WCHAR
);
2941 Buffer
= HeapAlloc(GetProcessHeap(), 0, dwNewLength
);
2945 ZeroMemory(Buffer
, dwNewLength
);
2947 res
= RegQueryValueExW(
2949 L
"Installation Sources",
2955 if (res
!= ERROR_SUCCESS
)
2957 HeapFree(GetProcessHeap(), 0, Buffer
);
2962 /* Sanity check, these should already be zeros */
2963 Buffer
[dwPathLength
/ sizeof(WCHAR
) - 2] = UNICODE_NULL
;
2964 Buffer
[dwPathLength
/ sizeof(WCHAR
) - 1] = UNICODE_NULL
;
2966 for (Path
= Buffer
; *Path
; Path
+= wcslen(Path
) + 1)
2968 /* Check if path is already added */
2969 if (PathIsEqual(Path
, lpPath
))
2973 Path
= Buffer
+ dwPathLength
/ sizeof(WCHAR
) - 1;
2976 if (dwPathLength
== 0)
2978 dwNewLength
= (wcslen(lpPath
) + 1 + 1) * sizeof(WCHAR
);
2979 Buffer
= HeapAlloc(GetProcessHeap(), 0, dwNewLength
);
2986 StringCbCopyW(Path
, dwNewLength
- (Path
- Buffer
) * sizeof(WCHAR
), lpPath
);
2987 Buffer
[dwNewLength
/ sizeof(WCHAR
) - 1] = UNICODE_NULL
;
2991 L
"Installation Sources",
2998 HeapFree(GetProcessHeap(), 0, Buffer
);
3003 IN OUT PSETUPDATA pSetupData
)
3005 WCHAR szPath
[MAX_PATH
];
3006 WCHAR szValue
[MAX_PATH
];
3007 INFCONTEXT InfContext
;
3012 pSetupData
->hSetupInf
= INVALID_HANDLE_VALUE
;
3014 /* Retrieve the path of the setup INF */
3015 GetSystemDirectoryW(szPath
, _countof(szPath
));
3016 wcscat(szPath
, L
"\\$winnt$.inf");
3018 /* Open the setup INF */
3019 pSetupData
->hSetupInf
= SetupOpenInfFileW(szPath
,
3023 if (pSetupData
->hSetupInf
== INVALID_HANDLE_VALUE
)
3025 DPRINT1("Error: Cannot open the setup information file %S with error %d\n", szPath
, GetLastError());
3030 /* Retrieve the NT source path from which the 1st-stage installer was run */
3031 if (!SetupFindFirstLineW(pSetupData
->hSetupInf
,
3036 DPRINT1("Error: Cannot find sourcepath Key! %d\n", GetLastError());
3040 if (!SetupGetStringFieldW(&InfContext
,
3046 DPRINT1("Error: SetupGetStringField failed with %d\n", GetLastError());
3050 *pSetupData
->SourcePath
= UNICODE_NULL
;
3052 /* Close the setup INF as we are going to modify it manually */
3053 if (pSetupData
->hSetupInf
!= INVALID_HANDLE_VALUE
)
3054 SetupCloseInfFile(pSetupData
->hSetupInf
);
3057 /* Find the installation source path in Win32 format */
3058 if (!GetInstallSourceWin32(pSetupData
->SourcePath
,
3059 _countof(pSetupData
->SourcePath
),
3062 *pSetupData
->SourcePath
= UNICODE_NULL
;
3065 /* Save the path in Win32 format in the setup INF */
3066 swprintf(szValue
, L
"\"%s\"", pSetupData
->SourcePath
);
3067 WritePrivateProfileStringW(L
"data", L
"dospath", szValue
, szPath
);
3070 * Save it also in the registry, in the following keys:
3071 * - HKLM\Software\Microsoft\Windows\CurrentVersion\Setup ,
3072 * values "SourcePath" and "ServicePackSourcePath" (REG_SZ);
3073 * - HKLM\Software\Microsoft\Windows NT\CurrentVersion ,
3074 * value "SourcePath" (REG_SZ); set to the full path (e.g. D:\I386).
3077 res
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
3078 L
"Software\\Microsoft\\Windows NT\\CurrentVersion",
3083 if (res
!= ERROR_SUCCESS
)
3089 res
= RegCreateKeyExW(HKEY_LOCAL_MACHINE
,
3090 L
"Software\\Microsoft\\Windows\\CurrentVersion\\Setup",
3092 REG_OPTION_NON_VOLATILE
,
3093 KEY_ALL_ACCESS
, // KEY_WRITE
3097 if (res
== ERROR_SUCCESS
)
3099 AddInstallationSource(hKey
, pSetupData
->SourcePath
);
3101 res
= RegSetValueExW(hKey
,
3105 (LPBYTE
)pSetupData
->SourcePath
,
3106 (wcslen(pSetupData
->SourcePath
) + 1) * sizeof(WCHAR
));
3108 res
= RegSetValueExW(hKey
,
3109 L
"ServicePackSourcePath",
3112 (LPBYTE
)pSetupData
->SourcePath
,
3113 (wcslen(pSetupData
->SourcePath
) + 1) * sizeof(WCHAR
));
3119 /* Now, re-open the setup INF (this must succeed) */
3120 pSetupData
->hSetupInf
= SetupOpenInfFileW(szPath
,
3124 if (pSetupData
->hSetupInf
== INVALID_HANDLE_VALUE
)
3126 DPRINT1("Error: Cannot open the setup information file %S with error %d\n", szPath
, GetLastError());
3130 /* Process the unattended section of the setup file */
3131 ProcessUnattendSection(pSetupData
);
3134 typedef DWORD(WINAPI
*PFNREQUESTWIZARDPAGES
)(PDWORD
, HPROPSHEETPAGE
*, PSETUPDATA
);
3139 PROPSHEETHEADER psh
= {0};
3140 HPROPSHEETPAGE
*phpage
= NULL
;
3141 PROPSHEETPAGE psp
= {0};
3145 PSETUPDATA pSetupData
= NULL
;
3146 HMODULE hNetShell
= NULL
;
3147 PFNREQUESTWIZARDPAGES pfn
= NULL
;
3148 DWORD dwPageCount
= 10, dwNetworkPageCount
= 0;
3150 LogItem(L
"BEGIN_SECTION", L
"InstallWizard");
3152 /* Allocate setup data */
3153 pSetupData
= HeapAlloc(GetProcessHeap(),
3156 if (pSetupData
== NULL
)
3158 LogItem(NULL
, L
"SetupData allocation failed!");
3160 L
"Setup failed to allocate global data!",
3162 MB_ICONERROR
| MB_OK
);
3165 pSetupData
->ProductOption
= PRODUCT_OPTION_DEFAULT
;
3167 hNetShell
= LoadLibraryW(L
"netshell.dll");
3168 if (hNetShell
!= NULL
)
3170 DPRINT("Netshell.dll loaded!\n");
3172 pfn
= (PFNREQUESTWIZARDPAGES
)GetProcAddress(hNetShell
,
3173 "NetSetupRequestWizardPages");
3176 pfn(&dwNetworkPageCount
, NULL
, NULL
);
3177 dwPageCount
+= dwNetworkPageCount
;
3181 DPRINT("PageCount: %lu\n", dwPageCount
);
3183 phpage
= HeapAlloc(GetProcessHeap(),
3185 dwPageCount
* sizeof(HPROPSHEETPAGE
));
3188 LogItem(NULL
, L
"Page array allocation failed!");
3190 L
"Setup failed to allocate page array!",
3192 MB_ICONERROR
| MB_OK
);
3196 /* Process the $winnt$.inf setup file */
3197 ProcessSetupInf(pSetupData
);
3199 /* Create the Welcome page */
3200 psp
.dwSize
= sizeof(PROPSHEETPAGE
);
3201 psp
.dwFlags
= PSP_DEFAULT
| PSP_HIDEHEADER
;
3202 psp
.hInstance
= hDllInstance
;
3203 psp
.lParam
= (LPARAM
)pSetupData
;
3204 psp
.pfnDlgProc
= WelcomeDlgProc
;
3205 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_WELCOMEPAGE
);
3206 phpage
[nPages
++] = CreatePropertySheetPage(&psp
);
3208 /* Create the Acknowledgements page */
3209 psp
.dwFlags
= PSP_DEFAULT
| PSP_USEHEADERTITLE
| PSP_USEHEADERSUBTITLE
;
3210 psp
.pszHeaderTitle
= MAKEINTRESOURCE(IDS_ACKTITLE
);
3211 psp
.pszHeaderSubTitle
= MAKEINTRESOURCE(IDS_ACKSUBTITLE
);
3212 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_ACKPAGE
);
3213 psp
.pfnDlgProc
= AckPageDlgProc
;
3214 phpage
[nPages
++] = CreatePropertySheetPage(&psp
);
3216 /* Create the Product page */
3217 psp
.dwFlags
= PSP_DEFAULT
| PSP_USEHEADERTITLE
| PSP_USEHEADERSUBTITLE
;
3218 psp
.pszHeaderTitle
= MAKEINTRESOURCE(IDS_PRODUCTTITLE
);
3219 psp
.pszHeaderSubTitle
= MAKEINTRESOURCE(IDS_PRODUCTSUBTITLE
);
3220 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_PRODUCT
);
3221 psp
.pfnDlgProc
= ProductPageDlgProc
;
3222 phpage
[nPages
++] = CreatePropertySheetPage(&psp
);
3224 /* Create the Locale page */
3225 psp
.dwFlags
= PSP_DEFAULT
| PSP_USEHEADERTITLE
| PSP_USEHEADERSUBTITLE
;
3226 psp
.pszHeaderTitle
= MAKEINTRESOURCE(IDS_LOCALETITLE
);
3227 psp
.pszHeaderSubTitle
= MAKEINTRESOURCE(IDS_LOCALESUBTITLE
);
3228 psp
.pfnDlgProc
= LocalePageDlgProc
;
3229 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_LOCALEPAGE
);
3230 phpage
[nPages
++] = CreatePropertySheetPage(&psp
);
3232 /* Create the Owner page */
3233 psp
.dwFlags
= PSP_DEFAULT
| PSP_USEHEADERTITLE
| PSP_USEHEADERSUBTITLE
;
3234 psp
.pszHeaderTitle
= MAKEINTRESOURCE(IDS_OWNERTITLE
);
3235 psp
.pszHeaderSubTitle
= MAKEINTRESOURCE(IDS_OWNERSUBTITLE
);
3236 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_OWNERPAGE
);
3237 psp
.pfnDlgProc
= OwnerPageDlgProc
;
3238 phpage
[nPages
++] = CreatePropertySheetPage(&psp
);
3240 /* Create the Computer page */
3241 psp
.dwFlags
= PSP_DEFAULT
| PSP_USEHEADERTITLE
| PSP_USEHEADERSUBTITLE
;
3242 psp
.pszHeaderTitle
= MAKEINTRESOURCE(IDS_COMPUTERTITLE
);
3243 psp
.pszHeaderSubTitle
= MAKEINTRESOURCE(IDS_COMPUTERSUBTITLE
);
3244 psp
.pfnDlgProc
= ComputerPageDlgProc
;
3245 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_COMPUTERPAGE
);
3246 phpage
[nPages
++] = CreatePropertySheetPage(&psp
);
3248 /* Create the DateTime page */
3249 psp
.dwFlags
= PSP_DEFAULT
| PSP_USEHEADERTITLE
| PSP_USEHEADERSUBTITLE
;
3250 psp
.pszHeaderTitle
= MAKEINTRESOURCE(IDS_DATETIMETITLE
);
3251 psp
.pszHeaderSubTitle
= MAKEINTRESOURCE(IDS_DATETIMESUBTITLE
);
3252 psp
.pfnDlgProc
= DateTimePageDlgProc
;
3253 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_DATETIMEPAGE
);
3254 phpage
[nPages
++] = CreatePropertySheetPage(&psp
);
3256 /* Create the theme selection page */
3257 psp
.dwFlags
= PSP_DEFAULT
| PSP_USEHEADERTITLE
| PSP_USEHEADERSUBTITLE
;
3258 psp
.pszHeaderTitle
= MAKEINTRESOURCE(IDS_THEMESELECTIONTITLE
);
3259 psp
.pszHeaderSubTitle
= MAKEINTRESOURCE(IDS_THEMESELECTIONSUBTITLE
);
3260 psp
.pfnDlgProc
= ThemePageDlgProc
;
3261 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_THEMEPAGE
);
3262 phpage
[nPages
++] = CreatePropertySheetPage(&psp
);
3264 pSetupData
->uFirstNetworkWizardPage
= IDD_PROCESSPAGE
;
3265 pSetupData
->uPostNetworkWizardPage
= IDD_PROCESSPAGE
;
3269 pfn(&dwNetworkPageCount
, &phpage
[nPages
], pSetupData
);
3270 nPages
+= dwNetworkPageCount
;
3273 /* Create the Process page */
3274 psp
.dwFlags
= PSP_DEFAULT
| PSP_USEHEADERTITLE
| PSP_USEHEADERSUBTITLE
;
3275 psp
.pszHeaderTitle
= MAKEINTRESOURCE(IDS_PROCESSTITLE
);
3276 psp
.pszHeaderSubTitle
= MAKEINTRESOURCE(IDS_PROCESSSUBTITLE
);
3277 psp
.pfnDlgProc
= ProcessPageDlgProc
;
3278 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_PROCESSPAGE
);
3279 phpage
[nPages
++] = CreatePropertySheetPage(&psp
);
3281 /* Create the Finish page */
3282 psp
.dwFlags
= PSP_DEFAULT
| PSP_HIDEHEADER
;
3283 psp
.pfnDlgProc
= FinishDlgProc
;
3284 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_FINISHPAGE
);
3285 phpage
[nPages
++] = CreatePropertySheetPage(&psp
);
3287 ASSERT(nPages
== dwPageCount
);
3289 /* Create the property sheet */
3290 psh
.dwSize
= sizeof(PROPSHEETHEADER
);
3291 psh
.dwFlags
= PSH_WIZARD97
| PSH_WATERMARK
| PSH_HEADER
| PSH_MODELESS
;
3292 psh
.hInstance
= hDllInstance
;
3293 psh
.hwndParent
= NULL
;
3294 psh
.nPages
= nPages
;
3296 psh
.phpage
= phpage
;
3297 psh
.pszbmWatermark
= MAKEINTRESOURCE(IDB_WATERMARK
);
3298 psh
.pszbmHeader
= MAKEINTRESOURCE(IDB_HEADER
);
3300 /* Create title font */
3301 pSetupData
->hTitleFont
= CreateTitleFont();
3302 pSetupData
->hBoldFont
= CreateBoldFont();
3304 /* Display the wizard */
3305 hWnd
= (HWND
)PropertySheet(&psh
);
3306 ShowWindow(hWnd
, SW_SHOW
);
3308 while (GetMessage(&msg
, NULL
, 0, 0))
3310 if (!IsDialogMessage(hWnd
, &msg
))
3312 TranslateMessage(&msg
);
3313 DispatchMessage(&msg
);
3317 DeleteObject(pSetupData
->hBoldFont
);
3318 DeleteObject(pSetupData
->hTitleFont
);
3320 if (pSetupData
->hSetupInf
!= INVALID_HANDLE_VALUE
)
3321 SetupCloseInfFile(pSetupData
->hSetupInf
);
3325 HeapFree(GetProcessHeap(), 0, phpage
);
3327 if (hNetShell
!= NULL
)
3328 FreeLibrary(hNetShell
);
3330 if (pSetupData
!= NULL
)
3331 HeapFree(GetProcessHeap(), 0, pSetupData
);
3333 LogItem(L
"END_SECTION", L
"InstallWizard");