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
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 * COPYRIGHT: See COPYING in the top level directory
22 * PROJECT: ReactOS GUI first stage setup application
23 * FILE: subsys/system/reactos/reactos.c
24 * PROGRAMMERS: Eric Kohl
33 #include <wine/unicode.h>
37 /* GLOBALS ******************************************************************/
48 typedef struct _KBLAYOUT
51 TCHAR LayoutName
[128];
53 } KBLAYOUT
, *PKBLAYOUT
;
58 LONG DestDiskNumber
; // physical disk
59 LONG DestPartNumber
; // partition on disk
60 LONG DestPartSize
; // if partition doesn't exist, size of partition
61 LONG FSType
; // file system type on partition
62 LONG MBRInstallType
; // install bootloader
63 LONG FormatPart
; // type of format the partition
64 TCHAR SelectedLangId
[9]; // selected language
65 TCHAR SelectedKBLayout
[9]; // selected kayboard layout
66 WCHAR InstallationDirectory
[MAX_PATH
]; // installation directory on hdd
67 BOOLEAN RepairUpdateFlag
; // flag for update/repair an installed reactos
69 TCHAR DefaultLang
[20]; // default language
70 TCHAR DefaultKBLayout
[20]; // default keyboard layout
77 typedef struct _IMGINFO
84 TCHAR abort_msg
[512],abort_title
[64];
88 /* FUNCTIONS ****************************************************************/
91 CenterWindow(HWND hWnd
)
97 hWndParent
= GetParent(hWnd
);
98 if (hWndParent
== NULL
)
99 hWndParent
= GetDesktopWindow();
101 GetWindowRect(hWndParent
, &rcParent
);
102 GetWindowRect(hWnd
, &rcWindow
);
106 ((rcParent
.right
- rcParent
.left
) - (rcWindow
.right
- rcWindow
.left
)) / 2,
107 ((rcParent
.bottom
- rcParent
.top
) - (rcWindow
.bottom
- rcWindow
.top
)) / 2,
114 CreateTitleFont(VOID
)
116 NONCLIENTMETRICS ncm
;
122 ncm
.cbSize
= sizeof(NONCLIENTMETRICS
);
123 SystemParametersInfo(SPI_GETNONCLIENTMETRICS
, 0, &ncm
, 0);
125 LogFont
= ncm
.lfMessageFont
;
126 LogFont
.lfWeight
= FW_BOLD
;
127 _tcscpy(LogFont
.lfFaceName
, _T("MS Shell Dlg"));
131 LogFont
.lfHeight
= 0 - GetDeviceCaps (hdc
, LOGPIXELSY
) * FontSize
/ 72;
132 hFont
= CreateFontIndirect(&LogFont
);
133 ReleaseDC(NULL
, hdc
);
139 InitImageInfo(PIMGINFO ImgInfo
)
143 ZeroMemory(ImgInfo
, sizeof(*ImgInfo
));
145 ImgInfo
->hBitmap
= LoadImage(hInstance
,
146 MAKEINTRESOURCE(IDB_ROSLOGO
),
152 if (ImgInfo
->hBitmap
!= NULL
)
154 GetObject(ImgInfo
->hBitmap
, sizeof(BITMAP
), &bitmap
);
156 ImgInfo
->cxSource
= bitmap
.bmWidth
;
157 ImgInfo
->cySource
= bitmap
.bmHeight
;
161 static INT_PTR CALLBACK
162 StartDlgProc(HWND hwndDlg
,
174 hwndControl
= GetParent(hwndDlg
);
176 /* Center the wizard window */
177 CenterWindow (hwndControl
);
179 dwStyle
= GetWindowLong(hwndControl
, GWL_STYLE
);
180 SetWindowLong(hwndControl
, GWL_STYLE
, dwStyle
& ~WS_SYSMENU
);
182 /* Hide and disable the 'Cancel' button at the moment,
183 * we use this button to cancel the setup process
186 hwndControl
= GetDlgItem(GetParent(hwndDlg
), IDCANCEL
);
187 ShowWindow (hwndControl
, SW_HIDE
);
188 EnableWindow (hwndControl
, FALSE
);
191 SendDlgItemMessage(hwndDlg
,
200 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
204 case PSN_SETACTIVE
: // Only "Finish" for closing the App
205 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_FINISH
);
206 //PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT);
220 static INT_PTR CALLBACK
221 LangSelDlgProc(HWND hwndDlg
,
228 pImgInfo
= (PIMGINFO
)GetWindowLongPtr(hwndDlg
, DWLP_USER
);
236 hwndControl
= GetParent(hwndDlg
);
238 dwStyle
= GetWindowLong(hwndControl
, GWL_STYLE
);
239 SetWindowLong(hwndControl
, GWL_STYLE
, dwStyle
& ~WS_SYSMENU
);
241 hwndControl
= GetDlgItem(GetParent(hwndDlg
), IDCANCEL
);
242 ShowWindow (hwndControl
, SW_SHOW
);
243 EnableWindow (hwndControl
, TRUE
);
245 pImgInfo
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IMGINFO
));
246 if (pImgInfo
== NULL
)
248 EndDialog(hwndDlg
, 0);
252 SetWindowLongPtr(hwndDlg
, DWLP_USER
, (LONG_PTR
)pImgInfo
);
254 InitImageInfo(pImgInfo
);
257 /*SendDlgItemMessage(hwndDlg,
262 for (i
=0; i
< SetupData
.LangCount
;i
++)
263 (void)ComboBox_AddString(GetDlgItem(hwndDlg
,IDC_LANGUAGES
),SetupData
.pLanguages
[i
].LangName
);
264 for (i
=0; i
< SetupData
.KbLayoutCount
;i
++)
265 (void)ComboBox_AddString(GetDlgItem(hwndDlg
,IDC_KEYLAYOUT
),SetupData
.pKbLayouts
[i
].LayoutName
);
270 LPDRAWITEMSTRUCT lpDrawItem
;
271 lpDrawItem
= (LPDRAWITEMSTRUCT
) lParam
;
272 if (lpDrawItem
->CtlID
== IDB_ROSLOGO
)
277 /* position image in centre of dialog */
278 left
= (lpDrawItem
->rcItem
.right
- pImgInfo
->cxSource
) / 2;
280 hdcMem
= CreateCompatibleDC(lpDrawItem
->hDC
);
283 SelectObject(hdcMem
, pImgInfo
->hBitmap
);
284 BitBlt(lpDrawItem
->hDC
,
286 lpDrawItem
->rcItem
.top
,
287 lpDrawItem
->rcItem
.right
- lpDrawItem
->rcItem
.left
,
288 lpDrawItem
->rcItem
.bottom
- lpDrawItem
->rcItem
.top
,
300 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
305 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_NEXT
| PSWIZB_BACK
);
307 case PSN_QUERYCANCEL
:
308 SetWindowLong(hwndDlg
, DWL_MSGRESULT
,MessageBox(GetParent(hwndDlg
), abort_msg
, abort_title
, MB_YESNO
| MB_ICONQUESTION
) != IDYES
);
322 static INT_PTR CALLBACK
323 TypeDlgProc(HWND hwndDlg
,
335 hwndControl
= GetParent(hwndDlg
);
337 dwStyle
= GetWindowLong(hwndControl
, GWL_STYLE
);
338 SetWindowLong(hwndControl
, GWL_STYLE
, dwStyle
& ~WS_SYSMENU
);
340 CheckDlgButton(hwndDlg
, IDC_INSTALL
, BST_CHECKED
);
343 /*SendDlgItemMessage(hwndDlg,
352 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
357 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_NEXT
| PSWIZB_BACK
);
359 case PSN_QUERYCANCEL
:
360 SetWindowLong(hwndDlg
, DWL_MSGRESULT
,MessageBox(GetParent(hwndDlg
), abort_msg
, abort_title
, MB_YESNO
| MB_ICONQUESTION
) != IDYES
);
374 static INT_PTR CALLBACK
375 DeviceDlgProc(HWND hwndDlg
,
387 hwndControl
= GetParent(hwndDlg
);
389 dwStyle
= GetWindowLong(hwndControl
, GWL_STYLE
);
390 SetWindowLong(hwndControl
, GWL_STYLE
, dwStyle
& ~WS_SYSMENU
);
393 /*SendDlgItemMessage(hwndDlg,
402 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
407 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_NEXT
| PSWIZB_BACK
);
409 case PSN_QUERYCANCEL
:
410 SetWindowLong(hwndDlg
, DWL_MSGRESULT
,MessageBox(GetParent(hwndDlg
), abort_msg
, abort_title
, MB_YESNO
| MB_ICONQUESTION
) != IDYES
);
424 static INT_PTR CALLBACK
425 DriveDlgProc(HWND hwndDlg
,
437 hwndControl
= GetParent(hwndDlg
);
439 dwStyle
= GetWindowLong(hwndControl
, GWL_STYLE
);
440 SetWindowLong(hwndControl
, GWL_STYLE
, dwStyle
& ~WS_SYSMENU
);
442 CheckDlgButton(hwndDlg
, IDC_INSTFREELDR
, BST_CHECKED
);
444 /*SendDlgItemMessage(hwndDlg,
453 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
458 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_NEXT
| PSWIZB_BACK
);
460 case PSN_QUERYCANCEL
:
461 SetWindowLong(hwndDlg
, DWL_MSGRESULT
,MessageBox(GetParent(hwndDlg
), abort_msg
, abort_title
, MB_YESNO
| MB_ICONQUESTION
) != IDYES
);
475 static INT_PTR CALLBACK
476 ProcessDlgProc(HWND hwndDlg
,
488 hwndControl
= GetParent(hwndDlg
);
490 dwStyle
= GetWindowLong(hwndControl
, GWL_STYLE
);
491 SetWindowLong(hwndControl
, GWL_STYLE
, dwStyle
& ~WS_SYSMENU
);
493 hwndControl
= GetDlgItem(GetParent(hwndDlg
), IDCANCEL
);
494 ShowWindow (hwndControl
, SW_HIDE
);
495 EnableWindow (hwndControl
, FALSE
);
498 /*SendDlgItemMessage(hwndDlg,
507 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
512 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_NEXT
);
526 static INT_PTR CALLBACK
527 RestartDlgProc(HWND hwndDlg
,
539 hwndControl
= GetParent(hwndDlg
);
541 dwStyle
= GetWindowLong(hwndControl
, GWL_STYLE
);
542 SetWindowLong(hwndControl
, GWL_STYLE
, dwStyle
& ~WS_SYSMENU
);
545 /*SendDlgItemMessage(hwndDlg,
557 hWndProgress
= GetDlgItem(hwndDlg
, IDC_RESTART_PROGRESS
);
558 Position
= SendMessage(hWndProgress
, PBM_GETPOS
, 0, 0);
561 KillTimer(hwndDlg
, 1);
562 PropSheet_PressButton(GetParent(hwndDlg
), PSBTN_FINISH
);
566 SendMessage(hWndProgress
, PBM_SETPOS
, Position
+ 1, 0);
574 LPNMHDR lpnm
= (LPNMHDR
)lParam
;
578 case PSN_SETACTIVE
: // Only "Finish" for closing the App
579 PropSheet_SetWizButtons(GetParent(hwndDlg
), PSWIZB_FINISH
);
580 SendDlgItemMessage(hwndDlg
, IDC_RESTART_PROGRESS
, PBM_SETRANGE
, 0, MAKELPARAM(0, 300));
581 SendDlgItemMessage(hwndDlg
, IDC_RESTART_PROGRESS
, PBM_SETPOS
, 0, 0);
582 SetTimer(hwndDlg
, 1, 50, NULL
);
598 WCHAR szPath
[MAX_PATH
];
601 INFCONTEXT InfContext
;
602 //TCHAR szValue[MAX_PATH];
607 GetModuleFileNameW(NULL
,szPath
,MAX_PATH
);
608 ch
= strrchrW(szPath
,L
'\\');
612 wcscat(szPath
, L
"\\txtsetup.sif");
613 hTxtsetupSif
= SetupOpenInfFileW(szPath
, NULL
, INF_STYLE_OLDNT
, NULL
);
614 if (hTxtsetupSif
!= INVALID_HANDLE_VALUE
)
617 Count
= SetupGetLineCount(hTxtsetupSif
, _T("Language"));
620 // TODO: alloc memory for all entries and read entries
621 SetupData
.pLanguages
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(LANG
) * Count
);
622 if (SetupData
.pLanguages
!= NULL
)
624 SetupData
.LangCount
= Count
;
626 if (SetupFindFirstLine(hTxtsetupSif
, _T("Language"),
630 SetupGetStringField(&InfContext
, 0, SetupData
.pLanguages
[Count
].LangId
, sizeof(SetupData
.pLanguages
[Count
].LangId
) / sizeof(TCHAR
), &LineLength
);
631 SetupGetStringField(&InfContext
, 1, SetupData
.pLanguages
[Count
].LangName
, sizeof(SetupData
.pLanguages
[Count
].LangName
) / sizeof(TCHAR
), &LineLength
);
634 while (SetupFindNextLine(&InfContext
, &InfContext
) && Count
< SetupData
.LangCount
);
637 // get keyboard layout list
638 Count
= SetupGetLineCount(hTxtsetupSif
, _T("KeyboardLayout"));
641 // TODO: alloc memory for all entries and read entries
642 SetupData
.pKbLayouts
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(KBLAYOUT
) * Count
);
643 if (SetupData
.pKbLayouts
!= NULL
)
645 SetupData
.KbLayoutCount
= Count
;
647 if (SetupFindFirstLine(hTxtsetupSif
, _T("KeyboardLayout"),
651 SetupGetStringField(&InfContext
, 0, SetupData
.pKbLayouts
[Count
].LayoutId
, sizeof(SetupData
.pKbLayouts
[Count
].LayoutId
) / sizeof(TCHAR
), &LineLength
);
652 SetupGetStringField(&InfContext
, 1, SetupData
.pKbLayouts
[Count
].LayoutName
, sizeof(SetupData
.pKbLayouts
[Count
].LayoutName
) / sizeof(TCHAR
), &LineLength
);
655 while (SetupFindNextLine(&InfContext
, &InfContext
) && Count
< SetupData
.LangCount
);
658 SetupCloseInfFile(hTxtsetupSif
);
662 BOOL
isUnattendSetup()
664 WCHAR szPath
[MAX_PATH
];
667 INFCONTEXT InfContext
;
668 TCHAR szValue
[MAX_PATH
];
673 GetModuleFileNameW(NULL
,szPath
,MAX_PATH
);
674 ch
= strrchrW(szPath
,L
'\\');
678 wcscat(szPath
, L
"\\unattend.inf");
679 hUnattendedInf
= SetupOpenInfFileW(szPath
, NULL
, INF_STYLE_OLDNT
, NULL
);
680 if (hUnattendedInf
!= INVALID_HANDLE_VALUE
)
682 if (SetupFindFirstLine(hUnattendedInf
, _T("Unattend"),
683 _T("UnattendSetupEnabled"),&InfContext
))
685 if (SetupGetStringField(&InfContext
, 1, szValue
,
686 sizeof(szValue
) / sizeof(TCHAR
), &LineLength
) &&
687 (_tcsicmp(szValue
, _T("yes"))==0))
689 result
= 1; // unattendSetup enabled
690 // read values and store in SetupData
693 SetupCloseInfFile(hUnattendedInf
);
699 WinMain(HINSTANCE hInst
,
700 HINSTANCE hPrevInstance
,
705 HPROPSHEETPAGE ahpsp
[7];
706 PROPSHEETPAGE psp
= {0};
709 isUnattend
= isUnattendSetup();
714 LoadString(hInst
,IDS_ABORTSETUP
, abort_msg
, sizeof(abort_msg
)/sizeof(TCHAR
));
715 LoadString(hInst
,IDS_ABORTSETUP2
, abort_title
,sizeof(abort_title
)/sizeof(TCHAR
));
719 /* Create the Start page, until setup is working */
720 psp
.dwSize
= sizeof(PROPSHEETPAGE
);
721 psp
.dwFlags
= PSP_DEFAULT
| PSP_HIDEHEADER
;
722 psp
.hInstance
= hInst
;
724 psp
.pfnDlgProc
= StartDlgProc
;
725 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_STARTPAGE
);
726 ahpsp
[nPages
++] = CreatePropertySheetPage(&psp
);
728 /* Create language selection page */
729 psp
.dwSize
= sizeof(PROPSHEETPAGE
);
730 psp
.dwFlags
= PSP_DEFAULT
| PSP_USEHEADERTITLE
| PSP_USEHEADERSUBTITLE
;
731 psp
.pszHeaderTitle
= MAKEINTRESOURCE(IDS_LANGTITLE
);
732 psp
.pszHeaderSubTitle
= MAKEINTRESOURCE(IDS_LANGSUBTITLE
);
733 psp
.hInstance
= hInst
;
735 psp
.pfnDlgProc
= LangSelDlgProc
;
736 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_LANGSELPAGE
);
737 ahpsp
[nPages
++] = CreatePropertySheetPage(&psp
);
738 // Change language with "SetThreadLocale(langid)"
740 /* Create install type selection page */
741 psp
.dwSize
= sizeof(PROPSHEETPAGE
);
742 psp
.dwFlags
= PSP_DEFAULT
| PSP_USEHEADERTITLE
| PSP_USEHEADERSUBTITLE
;
743 psp
.pszHeaderTitle
= MAKEINTRESOURCE(IDS_TYPETITLE
);
744 psp
.pszHeaderSubTitle
= MAKEINTRESOURCE(IDS_TYPESUBTITLE
);
745 psp
.hInstance
= hInst
;
747 psp
.pfnDlgProc
= TypeDlgProc
;
748 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_TYPEPAGE
);
749 ahpsp
[nPages
++] = CreatePropertySheetPage(&psp
);
751 /* Create device settings page */
752 psp
.dwSize
= sizeof(PROPSHEETPAGE
);
753 psp
.dwFlags
= PSP_DEFAULT
| PSP_USEHEADERTITLE
| PSP_USEHEADERSUBTITLE
;
754 psp
.pszHeaderTitle
= MAKEINTRESOURCE(IDS_DEVICETITLE
);
755 psp
.pszHeaderSubTitle
= MAKEINTRESOURCE(IDS_DEVICESUBTITLE
);
756 psp
.hInstance
= hInst
;
758 psp
.pfnDlgProc
= DeviceDlgProc
;
759 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_DEVICEPAGE
);
760 ahpsp
[nPages
++] = CreatePropertySheetPage(&psp
);
762 /* Create install device settings page / boot method / install directory*/
763 psp
.dwSize
= sizeof(PROPSHEETPAGE
);
764 psp
.dwFlags
= PSP_DEFAULT
| PSP_USEHEADERTITLE
| PSP_USEHEADERSUBTITLE
;
765 psp
.pszHeaderTitle
= MAKEINTRESOURCE(IDS_DRIVETITLE
);
766 psp
.pszHeaderSubTitle
= MAKEINTRESOURCE(IDS_DRIVESUBTITLE
);
767 psp
.hInstance
= hInst
;
769 psp
.pfnDlgProc
= DriveDlgProc
;
770 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_DRIVEPAGE
);
771 ahpsp
[nPages
++] = CreatePropertySheetPage(&psp
);
775 /* Create installation progress page */
776 psp
.dwSize
= sizeof(PROPSHEETPAGE
);
777 psp
.dwFlags
= PSP_DEFAULT
| PSP_USEHEADERTITLE
| PSP_USEHEADERSUBTITLE
;
778 psp
.pszHeaderTitle
= MAKEINTRESOURCE(IDS_PROCESSTITLE
);
779 psp
.pszHeaderSubTitle
= MAKEINTRESOURCE(IDS_PROCESSSUBTITLE
);
780 psp
.hInstance
= hInst
;
782 psp
.pfnDlgProc
= ProcessDlgProc
;
783 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_PROCESSPAGE
);
784 ahpsp
[nPages
++] = CreatePropertySheetPage(&psp
);
788 /* Create finish to reboot page */
789 psp
.dwSize
= sizeof(PROPSHEETPAGE
);
790 psp
.dwFlags
= PSP_DEFAULT
| PSP_USEHEADERTITLE
| PSP_USEHEADERSUBTITLE
;
791 psp
.pszHeaderTitle
= MAKEINTRESOURCE(IDS_RESTARTTITLE
);
792 psp
.pszHeaderSubTitle
= MAKEINTRESOURCE(IDS_RESTARTSUBTITLE
);
793 psp
.hInstance
= hInst
;
795 psp
.pfnDlgProc
= RestartDlgProc
;
796 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_RESTARTPAGE
);
797 ahpsp
[nPages
++] = CreatePropertySheetPage(&psp
);
800 /* Create the property sheet */
801 psh
.dwSize
= sizeof(PROPSHEETHEADER
);
802 psh
.dwFlags
= PSH_WIZARD97
| PSH_WATERMARK
| PSH_HEADER
;
803 psh
.hInstance
= hInst
;
804 psh
.hwndParent
= NULL
;
808 psh
.pszbmWatermark
= MAKEINTRESOURCE(IDB_WATERMARK
);
809 psh
.pszbmHeader
= MAKEINTRESOURCE(IDB_HEADER
);
811 /* Create title font */
812 hTitleFont
= CreateTitleFont();
814 /* Display the wizard */
817 DeleteObject(hTitleFont
);