3 * Copyright (C) 2004-2008 ReactOS Team
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 * COPYRIGHT: See COPYING in the top level directory
21 * PROJECT: ReactOS GUI first stage setup application
22 * FILE: base/setup/reactos/reactos.c
23 * PROGRAMMERS: Matthias Kupfer
24 * Dmitry Chapyshev (dmitry@reactos.org)
33 /* GLOBALS ******************************************************************/
36 BOOLEAN IsUnattendedSetup
= FALSE
;
40 /* FUNCTIONS ****************************************************************/
43 CenterWindow(HWND hWnd
)
49 hWndParent
= GetParent(hWnd
);
50 if (hWndParent
== NULL
)
51 hWndParent
= GetDesktopWindow();
53 GetWindowRect(hWndParent
, &rcParent
);
54 GetWindowRect(hWnd
, &rcWindow
);
58 ((rcParent
.right
- rcParent
.left
) - (rcWindow
.right
- rcWindow
.left
)) / 2,
59 ((rcParent
.bottom
- rcParent
.top
) - (rcWindow
.bottom
- rcWindow
.top
)) / 2,
74 ncm
.cbSize
= sizeof(NONCLIENTMETRICS
);
75 SystemParametersInfo(SPI_GETNONCLIENTMETRICS
, 0, &ncm
, 0);
77 LogFont
= ncm
.lfMessageFont
;
78 LogFont
.lfWeight
= FW_BOLD
;
79 _tcscpy(LogFont
.lfFaceName
, _T("MS Shell Dlg"));
83 LogFont
.lfHeight
= 0 - GetDeviceCaps (hdc
, LOGPIXELSY
) * FontSize
/ 72;
84 hFont
= CreateFontIndirect(&LogFont
);
91 IN HWND hParentWnd OPTIONAL
,
95 WCHAR message
[512], caption
[64];
97 LoadStringW(SetupData
.hInstance
, uIDMessage
, message
, ARRAYSIZE(message
));
98 LoadStringW(SetupData
.hInstance
, uIDTitle
, caption
, ARRAYSIZE(caption
));
100 return MessageBoxW(hParentWnd
, message
, caption
, MB_OK
| MB_ICONERROR
);
103 static INT_PTR CALLBACK
110 PSETUPDATA pSetupData
;
112 /* Retrieve pointer to the global setup data */
113 pSetupData
= (PSETUPDATA
)GetWindowLongPtrW(hwndDlg
, GWLP_USERDATA
);
118 /* Save pointer to the global setup data */
119 pSetupData
= (PSETUPDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
120 SetWindowLongPtrW(hwndDlg
, GWLP_USERDATA
, (DWORD_PTR
)pSetupData
);
122 /* Center the wizard window */
123 CenterWindow(GetParent(hwndDlg
));
126 SendDlgItemMessage(hwndDlg
,
129 (WPARAM
)pSetupData
->hTitleFont
,
135 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
140 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_NEXT
);
157 static INT_PTR CALLBACK
164 PSETUPDATA pSetupData
;
166 /* Retrieve pointer to the global setup data */
167 pSetupData
= (PSETUPDATA
)GetWindowLongPtrW(hwndDlg
, GWLP_USERDATA
);
173 /* Save pointer to the global setup data */
174 pSetupData
= (PSETUPDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
175 SetWindowLongPtrW(hwndDlg
, GWLP_USERDATA
, (DWORD_PTR
)pSetupData
);
177 /* Check the 'install' radio button */
178 CheckDlgButton(hwndDlg
, IDC_INSTALL
, BST_CHECKED
);
181 * Enable the 'update' radio button and text only if we have
182 * available NT installations, otherwise disable them.
184 if (pSetupData
->NtOsInstallsList
&&
185 GetNumberOfListEntries(pSetupData
->NtOsInstallsList
) != 0)
187 EnableWindow(GetDlgItem(hwndDlg
, IDC_UPDATE
), TRUE
);
188 EnableWindow(GetDlgItem(hwndDlg
, IDC_UPDATETEXT
), TRUE
);
192 EnableWindow(GetDlgItem(hwndDlg
, IDC_UPDATE
), FALSE
);
193 EnableWindow(GetDlgItem(hwndDlg
, IDC_UPDATETEXT
), FALSE
);
201 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
206 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_NEXT
| PSWIZB_BACK
);
209 case PSN_QUERYCANCEL
:
210 SetWindowLongPtrW(hwndDlg
,
212 MessageBoxW(GetParent(hwndDlg
),
213 pSetupData
->szAbortMessage
,
214 pSetupData
->szAbortTitle
,
215 MB_YESNO
| MB_ICONQUESTION
) != IDYES
);
218 case PSN_WIZNEXT
: /* Set the selected data */
220 pSetupData
->RepairUpdateFlag
=
221 !(SendMessageW(GetDlgItem(hwndDlg
, IDC_INSTALL
),
223 0, 0) == BST_CHECKED
);
226 * Display the existing NT installations page only
227 * if we have more than one available NT installations.
229 if (pSetupData
->NtOsInstallsList
&&
230 GetNumberOfListEntries(pSetupData
->NtOsInstallsList
) > 1)
232 /* Actually the best would be to dynamically insert the page only when needed */
233 SetWindowLongPtrW(hwndDlg
, DWLP_MSGRESULT
, IDD_UPDATEREPAIRPAGE
);
237 SetWindowLongPtrW(hwndDlg
, DWLP_MSGRESULT
, IDD_DEVICEPAGE
);
259 (NTAPI
*PGET_ENTRY_DESCRIPTION
)(
260 IN PGENERIC_LIST_ENTRY Entry
,
262 IN SIZE_T cchBufferSize
);
265 InitGenericComboList(
267 IN PGENERIC_LIST List
,
268 IN PGET_ENTRY_DESCRIPTION GetEntryDescriptionProc
)
270 INT Index
, CurrentEntryIndex
= 0;
271 PGENERIC_LIST_ENTRY ListEntry
;
273 WCHAR CurrentItemText
[256];
275 for (Entry
= List
->ListHead
.Flink
;
276 Entry
!= &List
->ListHead
;
277 Entry
= Entry
->Flink
)
279 ListEntry
= CONTAINING_RECORD(Entry
, GENERIC_LIST_ENTRY
, Entry
);
281 if (GetEntryDescriptionProc
)
283 GetEntryDescriptionProc(ListEntry
,
285 ARRAYSIZE(CurrentItemText
));
286 Index
= SendMessageW(hWndList
, CB_ADDSTRING
, 0, (LPARAM
)CurrentItemText
);
290 Index
= SendMessageW(hWndList
, CB_ADDSTRING
, 0, (LPARAM
)L
"n/a");
293 if (ListEntry
== List
->CurrentEntry
)
294 CurrentEntryIndex
= Index
;
296 SendMessageW(hWndList
, CB_SETITEMDATA
, Index
, (LPARAM
)ListEntry
);
299 SendMessageW(hWndList
, CB_SETCURSEL
, CurrentEntryIndex
, 0);
303 GetSelectedComboListItem(
308 Index
= SendMessageW(hWndList
, CB_GETCURSEL
, 0, 0);
312 // TODO: Update List->CurrentEntry?
313 // return SendMessageW(hWndList, CB_GETITEMDATA, (WPARAM)Index, 0);
318 (NTAPI
*PADD_ENTRY_ITEM
)(
321 IN PGENERIC_LIST_ENTRY Entry
,
323 IN SIZE_T cchBufferSize
);
328 IN PGENERIC_LIST List
,
329 IN PADD_ENTRY_ITEM AddEntryItemProc
)
331 INT CurrentEntryIndex
= 0;
333 PGENERIC_LIST_ENTRY ListEntry
;
335 WCHAR CurrentItemText
[256];
337 for (Entry
= List
->ListHead
.Flink
;
338 Entry
!= &List
->ListHead
;
339 Entry
= Entry
->Flink
)
341 ListEntry
= CONTAINING_RECORD(Entry
, GENERIC_LIST_ENTRY
, Entry
);
343 if (!AddEntryItemProc
)
346 AddEntryItemProc(hWndList
,
350 ARRAYSIZE(CurrentItemText
));
352 if (ListEntry
== List
->CurrentEntry
)
353 CurrentEntryIndex
= lvItem
.iItem
;
356 SendMessageW(hWndList
, LVM_ENSUREVISIBLE
, CurrentEntryIndex
, FALSE
);
357 ListView_SetItemState(hWndList
, CurrentEntryIndex
, LVIS_SELECTED
, LVIS_SELECTED
);
358 ListView_SetItemState(hWndList
, CurrentEntryIndex
, LVIS_FOCUSED
, LVIS_FOCUSED
);
364 GetSettingDescription(
365 IN PGENERIC_LIST_ENTRY Entry
,
367 IN SIZE_T cchBufferSize
)
369 StringCchCopyW(Buffer
, cchBufferSize
,
370 ((PGENENTRY
)GetListEntryData(Entry
))->Value
);
375 AddNTOSInstallationItem(
378 IN PGENERIC_LIST_ENTRY Entry
,
379 IN OUT PWSTR Buffer
, // SystemRootPath
380 IN SIZE_T cchBufferSize
)
382 PNTOS_INSTALLATION NtOsInstall
= (PNTOS_INSTALLATION
)GetListEntryData(Entry
);
383 PPARTENTRY PartEntry
= NtOsInstall
->PartEntry
;
385 if (PartEntry
&& PartEntry
->DriveLetter
)
387 /* We have retrieved a partition that is mounted */
388 StringCchPrintfW(Buffer
, cchBufferSize
,
390 PartEntry
->DriveLetter
,
391 NtOsInstall
->PathComponent
);
395 /* We failed somewhere, just show the NT path */
396 StringCchPrintfW(Buffer
, cchBufferSize
,
398 &NtOsInstall
->SystemNtPath
);
401 plvItem
->mask
= LVIF_IMAGE
| LVIF_TEXT
| LVIF_PARAM
;
403 plvItem
->iSubItem
= 0;
404 plvItem
->lParam
= (LPARAM
)Entry
;
405 plvItem
->pszText
= NtOsInstall
->InstallationName
;
407 /* Associate vendor icon */
408 if (FindSubStrI(NtOsInstall
->VendorName
, VENDOR_REACTOS
))
410 plvItem
->mask
|= LVIF_IMAGE
;
413 else if (FindSubStrI(NtOsInstall
->VendorName
, VENDOR_MICROSOFT
))
415 plvItem
->mask
|= LVIF_IMAGE
;
419 plvItem
->iItem
= SendMessageW(hWndList
, LVM_INSERTITEMW
, 0, (LPARAM
)plvItem
);
421 plvItem
->iSubItem
= 1;
422 plvItem
->pszText
= Buffer
; // SystemRootPath;
423 SendMessageW(hWndList
, LVM_SETITEMTEXTW
, plvItem
->iItem
, (LPARAM
)plvItem
);
425 plvItem
->iSubItem
= 2;
426 plvItem
->pszText
= NtOsInstall
->VendorName
;
427 SendMessageW(hWndList
, LVM_SETITEMTEXTW
, plvItem
->iItem
, (LPARAM
)plvItem
);
431 #define IDS_LIST_COLUMN_FIRST IDS_INSTALLATION_NAME
432 #define IDS_LIST_COLUMN_LAST IDS_INSTALLATION_VENDOR
434 #define MAX_LIST_COLUMNS (IDS_LIST_COLUMN_LAST - IDS_LIST_COLUMN_FIRST + 1)
435 static const UINT column_ids
[MAX_LIST_COLUMNS
] = {IDS_LIST_COLUMN_FIRST
, IDS_LIST_COLUMN_FIRST
+ 1, IDS_LIST_COLUMN_FIRST
+ 2};
436 static const INT column_widths
[MAX_LIST_COLUMNS
] = {200, 150, 100};
437 static const INT column_alignment
[MAX_LIST_COLUMNS
] = {LVCFMT_LEFT
, LVCFMT_LEFT
, LVCFMT_LEFT
};
439 static INT_PTR CALLBACK
440 UpgradeRepairDlgProc(
446 PSETUPDATA pSetupData
;
450 /* Retrieve pointer to the global setup data */
451 pSetupData
= (PSETUPDATA
)GetWindowLongPtrW(hwndDlg
, GWLP_USERDATA
);
457 /* Save pointer to the global setup data */
458 pSetupData
= (PSETUPDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
459 SetWindowLongPtrW(hwndDlg
, GWLP_USERDATA
, (DWORD_PTR
)pSetupData
);
461 hList
= GetDlgItem(hwndDlg
, IDC_NTOSLIST
);
463 CreateListViewColumns(pSetupData
->hInstance
,
470 /* Create the ImageList */
471 hSmall
= ImageList_Create(GetSystemMetrics(SM_CXSMICON
),
472 GetSystemMetrics(SM_CYSMICON
),
473 ILC_COLOR32
| ILC_MASK
, // ILC_COLOR24
476 /* Add event type icons to the ImageList */
477 ImageList_AddIcon(hSmall
, LoadIconW(pSetupData
->hInstance
, MAKEINTRESOURCEW(IDI_ROSICON
)));
478 ImageList_AddIcon(hSmall
, LoadIconW(pSetupData
->hInstance
, MAKEINTRESOURCEW(IDI_WINICON
)));
480 /* Assign the ImageList to the List View */
481 ListView_SetImageList(hList
, hSmall
, LVSIL_SMALL
);
483 InitGenericListView(hList
, pSetupData
->NtOsInstallsList
, AddNTOSInstallationItem
);
490 hList
= GetDlgItem(hwndDlg
, IDC_NTOSLIST
);
491 hSmall
= ListView_GetImageList(hList
, LVSIL_SMALL
);
492 ListView_SetImageList(hList
, NULL
, LVSIL_SMALL
);
493 ImageList_Destroy(hSmall
);
499 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
504 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_NEXT
| PSWIZB_BACK
);
507 case PSN_QUERYCANCEL
:
508 SetWindowLongPtrW(hwndDlg
,
510 MessageBoxW(GetParent(hwndDlg
),
511 pSetupData
->szAbortMessage
,
512 pSetupData
->szAbortTitle
,
513 MB_YESNO
| MB_ICONQUESTION
) != IDYES
);
516 case PSN_WIZNEXT
: /* Set the selected data */
517 pSetupData
->RepairUpdateFlag
=
518 !(SendMessageW(GetDlgItem(hwndDlg
, IDC_INSTALL
),
520 0, 0) == BST_CHECKED
);
536 static INT_PTR CALLBACK
543 PSETUPDATA pSetupData
;
546 /* Retrieve pointer to the global setup data */
547 pSetupData
= (PSETUPDATA
)GetWindowLongPtrW(hwndDlg
, GWLP_USERDATA
);
553 /* Save pointer to the global setup data */
554 pSetupData
= (PSETUPDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
555 SetWindowLongPtrW(hwndDlg
, GWLP_USERDATA
, (DWORD_PTR
)pSetupData
);
557 hList
= GetDlgItem(hwndDlg
, IDC_COMPUTER
);
558 InitGenericComboList(hList
, pSetupData
->ComputerList
, GetSettingDescription
);
560 hList
= GetDlgItem(hwndDlg
, IDC_DISPLAY
);
561 InitGenericComboList(hList
, pSetupData
->DisplayList
, GetSettingDescription
);
563 hList
= GetDlgItem(hwndDlg
, IDC_KEYBOARD
);
564 InitGenericComboList(hList
, pSetupData
->KeyboardList
, GetSettingDescription
);
566 // hList = GetDlgItem(hwndDlg, IDC_KEYBOARD_LAYOUT);
567 // InitGenericComboList(hList, pSetupData->LayoutList, GetSettingDescription);
574 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
579 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_NEXT
| PSWIZB_BACK
);
582 case PSN_QUERYCANCEL
:
583 SetWindowLongPtrW(hwndDlg
,
585 MessageBoxW(GetParent(hwndDlg
),
586 pSetupData
->szAbortMessage
,
587 pSetupData
->szAbortTitle
,
588 MB_YESNO
| MB_ICONQUESTION
) != IDYES
);
591 case PSN_WIZNEXT
: /* Set the selected data */
593 hList
= GetDlgItem(hwndDlg
, IDC_COMPUTER
);
594 pSetupData
->SelectedComputer
= GetSelectedComboListItem(hList
);
596 hList
= GetDlgItem(hwndDlg
, IDC_DISPLAY
);
597 pSetupData
->SelectedDisplay
= GetSelectedComboListItem(hList
);
599 hList
= GetDlgItem(hwndDlg
, IDC_KEYBOARD
);
600 pSetupData
->SelectedKeyboard
= GetSelectedComboListItem(hList
);
618 static INT_PTR CALLBACK
625 PSETUPDATA pSetupData
;
627 /* Retrieve pointer to the global setup data */
628 pSetupData
= (PSETUPDATA
)GetWindowLongPtrW(hwndDlg
, GWLP_USERDATA
);
633 /* Save pointer to the global setup data */
634 pSetupData
= (PSETUPDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
635 SetWindowLongPtrW(hwndDlg
, GWLP_USERDATA
, (DWORD_PTR
)pSetupData
);
640 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
645 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_NEXT
| PSWIZB_BACK
);
648 case PSN_QUERYCANCEL
:
649 SetWindowLongPtrW(hwndDlg
,
651 MessageBoxW(GetParent(hwndDlg
),
652 pSetupData
->szAbortMessage
,
653 pSetupData
->szAbortTitle
,
654 MB_YESNO
| MB_ICONQUESTION
) != IDYES
);
670 static INT_PTR CALLBACK
677 PSETUPDATA pSetupData
;
679 /* Retrieve pointer to the global setup data */
680 pSetupData
= (PSETUPDATA
)GetWindowLongPtrW(hwndDlg
, GWLP_USERDATA
);
685 /* Save pointer to the global setup data */
686 pSetupData
= (PSETUPDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
687 SetWindowLongPtrW(hwndDlg
, GWLP_USERDATA
, (DWORD_PTR
)pSetupData
);
692 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
697 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_NEXT
);
698 // disable all buttons during installation process
699 // PropSheet_SetWizButtons(GetParent(hwndDlg), 0 );
701 case PSN_QUERYCANCEL
:
702 SetWindowLongPtrW(hwndDlg
,
704 MessageBoxW(GetParent(hwndDlg
),
705 pSetupData
->szAbortMessage
,
706 pSetupData
->szAbortTitle
,
707 MB_YESNO
| MB_ICONQUESTION
) != IDYES
);
724 static INT_PTR CALLBACK
731 PSETUPDATA pSetupData
;
733 /* Retrieve pointer to the global setup data */
734 pSetupData
= (PSETUPDATA
)GetWindowLongPtrW(hwndDlg
, GWLP_USERDATA
);
739 /* Save pointer to the global setup data */
740 pSetupData
= (PSETUPDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
741 SetWindowLongPtrW(hwndDlg
, GWLP_USERDATA
, (DWORD_PTR
)pSetupData
);
744 /*SendDlgItemMessage(hwndDlg,
756 hWndProgress
= GetDlgItem(hwndDlg
, IDC_RESTART_PROGRESS
);
757 Position
= SendMessageW(hWndProgress
, PBM_GETPOS
, 0, 0);
760 KillTimer(hwndDlg
, 1);
761 PropSheet_PressButton(GetParent(hwndDlg
), PSBTN_FINISH
);
765 SendMessageW(hWndProgress
, PBM_SETPOS
, Position
+ 1, 0);
775 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
779 case PSN_SETACTIVE
: // Only "Finish" for closing the App
780 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_FINISH
);
781 SendDlgItemMessage(hwndDlg
, IDC_RESTART_PROGRESS
, PBM_SETRANGE
, 0, MAKELPARAM(0, 300));
782 SendDlgItemMessage(hwndDlg
, IDC_RESTART_PROGRESS
, PBM_SETPOS
, 0, 0);
783 SetTimer(hwndDlg
, 1, 50, NULL
);
801 IN OUT PSETUPDATA pSetupData
)
804 // INFCONTEXT InfContext;
809 /* Load the hardware, language and keyboard layout lists */
811 pSetupData
->ComputerList
= CreateComputerTypeList(pSetupData
->SetupInf
);
812 pSetupData
->DisplayList
= CreateDisplayDriverList(pSetupData
->SetupInf
);
813 pSetupData
->KeyboardList
= CreateKeyboardDriverList(pSetupData
->SetupInf
);
815 pSetupData
->LanguageList
= CreateLanguageList(pSetupData
->SetupInf
, pSetupData
->DefaultLanguage
);
817 pSetupData
->PartitionList
= CreatePartitionList();
819 pSetupData
->NtOsInstallsList
= CreateNTOSInstallationsList(pSetupData
->PartitionList
);
820 if (!pSetupData
->NtOsInstallsList
)
821 DPRINT1("Failed to get a list of NTOS installations; continue installation...\n");
825 pSetupData
->SelectedLanguageId
= pSetupData
->DefaultLanguage
;
826 wcscpy(pSetupData
->DefaultLanguage
, pSetupData
->USetupData
.LocaleID
);
827 pSetupData
->USetupData
.LanguageId
= (LANGID
)(wcstol(pSetupData
->SelectedLanguageId
, NULL
, 16) & 0xFFFF);
829 pSetupData
->LayoutList
= CreateKeyboardLayoutList(pSetupData
->SetupInf
, pSetupData
->SelectedLanguageId
, pSetupData
->DefaultKBLayout
);
832 // get default for keyboard and language
833 pSetupData
->DefaultKBLayout
= -1;
834 pSetupData
->DefaultLang
= -1;
836 // TODO: get defaults from underlaying running system
837 if (SetupFindFirstLine(pSetupData
->SetupInf
, _T("NLS"), _T("DefaultLayout"), &InfContext
))
839 SetupGetStringField(&InfContext
, 1, tmp
, ARRAYSIZE(tmp
), &LineLength
);
840 for (Count
= 0; Count
< pSetupData
->KbLayoutCount
; Count
++)
842 if (_tcscmp(tmp
, pSetupData
->pKbLayouts
[Count
].LayoutId
) == 0)
844 pSetupData
->DefaultKBLayout
= Count
;
850 if (SetupFindFirstLine(pSetupData
->SetupInf
, _T("NLS"), _T("DefaultLanguage"), &InfContext
))
852 SetupGetStringField(&InfContext
, 1, tmp
, ARRAYSIZE(tmp
), &LineLength
);
853 for (Count
= 0; Count
< pSetupData
->LangCount
; Count
++)
855 if (_tcscmp(tmp
, pSetupData
->pLanguages
[Count
].LangId
) == 0)
857 pSetupData
->DefaultLang
= Count
;
868 * Attempts to convert a pure NT file path into a corresponding Win32 path.
869 * Adapted from GetInstallSourceWin32() in dll/win32/syssetup/wizard.c
872 ConvertNtPathToWin32Path(
875 IN PCWSTR pwszNTPath
)
877 WCHAR wszDrives
[512];
878 WCHAR wszNTPath
[512]; // MAX_PATH ?
882 *pwszPath
= UNICODE_NULL
;
884 cchDrives
= GetLogicalDriveStringsW(_countof(wszDrives
) - 1, wszDrives
);
885 if (cchDrives
== 0 || cchDrives
>= _countof(wszDrives
))
887 /* Buffer too small or failure */
888 DPRINT1("GetLogicalDriveStringsW failed\n");
892 for (pwszDrive
= wszDrives
; *pwszDrive
; pwszDrive
+= wcslen(pwszDrive
) + 1)
894 /* Retrieve the NT path corresponding to the current Win32 DOS path */
895 pwszDrive
[2] = UNICODE_NULL
; // Temporarily remove the backslash
896 QueryDosDeviceW(pwszDrive
, wszNTPath
, _countof(wszNTPath
));
897 pwszDrive
[2] = L
'\\'; // Restore the backslash
899 wcscat(wszNTPath
, L
"\\"); // Concat a backslash
901 DPRINT1("Testing '%S' --> '%S'\n", pwszDrive
, wszNTPath
);
903 /* Check whether the NT path corresponds to the NT installation source path */
904 if (!_wcsnicmp(wszNTPath
, pwszNTPath
, wcslen(wszNTPath
)))
907 wsprintf(pwszPath
, L
"%s%s", // cchPathMax
908 pwszDrive
, pwszNTPath
+ wcslen(wszNTPath
));
909 DPRINT1("ConvertNtPathToWin32Path: %S\n", pwszPath
);
917 /* Used to enable and disable the shutdown privilege */
919 EnablePrivilege(LPCWSTR lpszPrivilegeName
, BOOL bEnablePrivilege
)
925 Success
= OpenProcessToken(GetCurrentProcess(),
926 TOKEN_ADJUST_PRIVILEGES
,
928 if (!Success
) return Success
;
930 Success
= LookupPrivilegeValueW(NULL
,
932 &tp
.Privileges
[0].Luid
);
933 if (!Success
) goto Quit
;
935 tp
.PrivilegeCount
= 1;
936 tp
.Privileges
[0].Attributes
= (bEnablePrivilege
? SE_PRIVILEGE_ENABLED
: 0);
938 Success
= AdjustTokenPrivileges(hToken
, FALSE
, &tp
, 0, NULL
, NULL
);
946 _tWinMain(HINSTANCE hInst
,
947 HINSTANCE hPrevInstance
,
953 INITCOMMONCONTROLSEX iccx
;
955 HPROPSHEETPAGE ahpsp
[8];
956 PROPSHEETPAGE psp
= {0};
959 ProcessHeap
= GetProcessHeap();
961 /* Initialize global unicode strings */
962 RtlInitUnicodeString(&SetupData
.USetupData
.SourcePath
, NULL
);
963 RtlInitUnicodeString(&SetupData
.USetupData
.SourceRootPath
, NULL
);
964 RtlInitUnicodeString(&SetupData
.USetupData
.SourceRootDir
, NULL
);
965 // RtlInitUnicodeString(&InstallPath, NULL);
966 RtlInitUnicodeString(&SetupData
.USetupData
.DestinationPath
, NULL
);
967 RtlInitUnicodeString(&SetupData
.USetupData
.DestinationArcPath
, NULL
);
968 RtlInitUnicodeString(&SetupData
.USetupData
.DestinationRootPath
, NULL
);
969 RtlInitUnicodeString(&SetupData
.USetupData
.SystemRootPath
, NULL
);
971 /* Get the source path and source root path */
973 // NOTE: Sometimes the source path may not be in SystemRoot !!
974 // (and this is the case when using the 1st-stage GUI setup!)
976 Status
= GetSourcePaths(&SetupData
.USetupData
.SourcePath
,
977 &SetupData
.USetupData
.SourceRootPath
,
978 &SetupData
.USetupData
.SourceRootDir
);
979 if (!NT_SUCCESS(Status
))
981 DPRINT1("GetSourcePaths() failed (Status 0x%08lx)", Status
);
982 // MUIDisplayError(ERROR_NO_SOURCE_DRIVE, Ir, POPUP_WAIT_ENTER);
983 MessageBoxW(NULL
, L
"GetSourcePaths failed!", L
"Error", MB_ICONERROR
);
986 DPRINT1("SourcePath: '%wZ'\n", &SetupData
.USetupData
.SourcePath
);
987 DPRINT1("SourceRootPath: '%wZ'\n", &SetupData
.USetupData
.SourceRootPath
);
988 DPRINT1("SourceRootDir: '%wZ'\n", &SetupData
.USetupData
.SourceRootDir
);
990 /* Load 'txtsetup.sif' from the installation media */
991 Error
= LoadSetupInf(&SetupData
.SetupInf
, &SetupData
.USetupData
);
992 if (Error
!= ERROR_SUCCESS
)
994 // MUIDisplayError(Error, Ir, POPUP_WAIT_ENTER);
995 DisplayError(NULL
, IDS_CAPTION
, IDS_NO_TXTSETUP_SIF
);
999 /* Load extra setup data (HW lists etc...) */
1000 if (!LoadSetupData(&SetupData
))
1003 SetupData
.hInstance
= hInst
;
1005 CheckUnattendedSetup(&SetupData
.USetupData
);
1006 SetupData
.bUnattend
= IsUnattendedSetup
;
1008 /* Cache commonly-used strings */
1009 LoadStringW(hInst
, IDS_ABORTSETUP
, SetupData
.szAbortMessage
, ARRAYSIZE(SetupData
.szAbortMessage
));
1010 LoadStringW(hInst
, IDS_ABORTSETUP2
, SetupData
.szAbortTitle
, ARRAYSIZE(SetupData
.szAbortTitle
));
1012 /* Whenever any of the common controls are used in your app,
1013 * you must call InitCommonControlsEx() to register the classes
1014 * for those controls. */
1015 iccx
.dwSize
= sizeof(iccx
);
1016 iccx
.dwICC
= ICC_LISTVIEW_CLASSES
| ICC_TREEVIEW_CLASSES
/* | ICC_PROGRESS_CLASS */;
1017 InitCommonControlsEx(&iccx
);
1019 /* Create title font */
1020 SetupData
.hTitleFont
= CreateTitleFont();
1022 if (!SetupData
.bUnattend
)
1024 /* Create the Start page, until setup is working */
1025 // NOTE: What does "until setup is working" mean??
1026 psp
.dwSize
= sizeof(PROPSHEETPAGE
);
1027 psp
.dwFlags
= PSP_DEFAULT
| PSP_HIDEHEADER
;
1028 psp
.hInstance
= hInst
;
1029 psp
.lParam
= (LPARAM
)&SetupData
;
1030 psp
.pfnDlgProc
= StartDlgProc
;
1031 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_STARTPAGE
);
1032 ahpsp
[nPages
++] = CreatePropertySheetPage(&psp
);
1034 /* Create the install type selection page */
1035 psp
.dwSize
= sizeof(PROPSHEETPAGE
);
1036 psp
.dwFlags
= PSP_DEFAULT
| PSP_USEHEADERTITLE
| PSP_USEHEADERSUBTITLE
;
1037 psp
.pszHeaderTitle
= MAKEINTRESOURCE(IDS_TYPETITLE
);
1038 psp
.pszHeaderSubTitle
= MAKEINTRESOURCE(IDS_TYPESUBTITLE
);
1039 psp
.hInstance
= hInst
;
1040 psp
.lParam
= (LPARAM
)&SetupData
;
1041 psp
.pfnDlgProc
= TypeDlgProc
;
1042 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_TYPEPAGE
);
1043 ahpsp
[nPages
++] = CreatePropertySheetPage(&psp
);
1045 /* Create the upgrade/repair selection page */
1046 psp
.dwSize
= sizeof(PROPSHEETPAGE
);
1047 psp
.dwFlags
= PSP_DEFAULT
| PSP_USEHEADERTITLE
| PSP_USEHEADERSUBTITLE
;
1048 psp
.pszHeaderTitle
= MAKEINTRESOURCE(IDS_TYPETITLE
);
1049 psp
.pszHeaderSubTitle
= MAKEINTRESOURCE(IDS_TYPESUBTITLE
);
1050 psp
.hInstance
= hInst
;
1051 psp
.lParam
= (LPARAM
)&SetupData
;
1052 psp
.pfnDlgProc
= UpgradeRepairDlgProc
;
1053 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_UPDATEREPAIRPAGE
);
1054 ahpsp
[nPages
++] = CreatePropertySheetPage(&psp
);
1056 /* Create the device settings page */
1057 psp
.dwSize
= sizeof(PROPSHEETPAGE
);
1058 psp
.dwFlags
= PSP_DEFAULT
| PSP_USEHEADERTITLE
| PSP_USEHEADERSUBTITLE
;
1059 psp
.pszHeaderTitle
= MAKEINTRESOURCE(IDS_DEVICETITLE
);
1060 psp
.pszHeaderSubTitle
= MAKEINTRESOURCE(IDS_DEVICESUBTITLE
);
1061 psp
.hInstance
= hInst
;
1062 psp
.lParam
= (LPARAM
)&SetupData
;
1063 psp
.pfnDlgProc
= DeviceDlgProc
;
1064 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_DEVICEPAGE
);
1065 ahpsp
[nPages
++] = CreatePropertySheetPage(&psp
);
1067 /* Create the install device settings page / boot method / install directory */
1068 psp
.dwSize
= sizeof(PROPSHEETPAGE
);
1069 psp
.dwFlags
= PSP_DEFAULT
| PSP_USEHEADERTITLE
| PSP_USEHEADERSUBTITLE
;
1070 psp
.pszHeaderTitle
= MAKEINTRESOURCE(IDS_DRIVETITLE
);
1071 psp
.pszHeaderSubTitle
= MAKEINTRESOURCE(IDS_DRIVESUBTITLE
);
1072 psp
.hInstance
= hInst
;
1073 psp
.lParam
= (LPARAM
)&SetupData
;
1074 psp
.pfnDlgProc
= DriveDlgProc
;
1075 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_DRIVEPAGE
);
1076 ahpsp
[nPages
++] = CreatePropertySheetPage(&psp
);
1078 /* Create the summary page */
1079 psp
.dwSize
= sizeof(PROPSHEETPAGE
);
1080 psp
.dwFlags
= PSP_DEFAULT
| PSP_USEHEADERTITLE
| PSP_USEHEADERSUBTITLE
;
1081 psp
.pszHeaderTitle
= MAKEINTRESOURCE(IDS_SUMMARYTITLE
);
1082 psp
.pszHeaderSubTitle
= MAKEINTRESOURCE(IDS_SUMMARYSUBTITLE
);
1083 psp
.hInstance
= hInst
;
1084 psp
.lParam
= (LPARAM
)&SetupData
;
1085 psp
.pfnDlgProc
= SummaryDlgProc
;
1086 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_SUMMARYPAGE
);
1087 ahpsp
[nPages
++] = CreatePropertySheetPage(&psp
);
1090 /* Create the installation progress page */
1091 psp
.dwSize
= sizeof(PROPSHEETPAGE
);
1092 psp
.dwFlags
= PSP_DEFAULT
| PSP_USEHEADERTITLE
| PSP_USEHEADERSUBTITLE
;
1093 psp
.pszHeaderTitle
= MAKEINTRESOURCE(IDS_PROCESSTITLE
);
1094 psp
.pszHeaderSubTitle
= MAKEINTRESOURCE(IDS_PROCESSSUBTITLE
);
1095 psp
.hInstance
= hInst
;
1096 psp
.lParam
= (LPARAM
)&SetupData
;
1097 psp
.pfnDlgProc
= ProcessDlgProc
;
1098 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_PROCESSPAGE
);
1099 ahpsp
[nPages
++] = CreatePropertySheetPage(&psp
);
1101 /* Create the finish-and-reboot page */
1102 psp
.dwSize
= sizeof(PROPSHEETPAGE
);
1103 psp
.dwFlags
= PSP_DEFAULT
| PSP_HIDEHEADER
;
1104 psp
.hInstance
= hInst
;
1105 psp
.lParam
= (LPARAM
)&SetupData
;
1106 psp
.pfnDlgProc
= RestartDlgProc
;
1107 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_RESTARTPAGE
);
1108 ahpsp
[nPages
++] = CreatePropertySheetPage(&psp
);
1110 /* Create the property sheet */
1111 psh
.dwSize
= sizeof(PROPSHEETHEADER
);
1112 psh
.dwFlags
= PSH_WIZARD97
| PSH_WATERMARK
| PSH_HEADER
;
1113 psh
.hInstance
= hInst
;
1114 psh
.hwndParent
= NULL
;
1115 psh
.nPages
= nPages
;
1118 psh
.pszbmWatermark
= MAKEINTRESOURCE(IDB_WATERMARK
);
1119 psh
.pszbmHeader
= MAKEINTRESOURCE(IDB_HEADER
);
1121 /* Display the wizard */
1122 PropertySheet(&psh
);
1124 if (SetupData
.hTitleFont
)
1125 DeleteObject(SetupData
.hTitleFont
);
1127 SetupCloseInfFile(SetupData
.SetupInf
);
1131 #if 0 // NOTE: Disabled for testing purposes only!
1132 EnablePrivilege(SE_SHUTDOWN_NAME
, TRUE
);
1133 ExitWindowsEx(EWX_REBOOT
, 0);
1134 EnablePrivilege(SE_SHUTDOWN_NAME
, FALSE
);