3 * Copyright (C) 2002, 2003, 2004 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 text-mode setup
22 * FILE: subsys/system/usetup/usetup.c
23 * PURPOSE: Text-mode setup
24 * PROGRAMMER: Eric Kohl
25 * Casper S. Hornstrup (chorns@users.sourceforge.net)
26 * Hervé Poussineau (hpoussin@reactos.org)
34 /* GLOBALS ******************************************************************/
37 UNICODE_STRING SourceRootPath
;
38 UNICODE_STRING SourceRootDir
;
39 UNICODE_STRING SourcePath
;
40 BOOLEAN IsUnattendedSetup
= FALSE
;
41 LONG UnattendDestinationDiskNumber
;
42 LONG UnattendDestinationPartitionNumber
;
43 LONG UnattendMBRInstallType
= -1;
44 LONG UnattendFormatPartition
= 0;
45 LONG AutoPartition
= 0;
46 WCHAR UnattendInstallationDirectory
[MAX_PATH
];
47 PWCHAR SelectedLanguageId
;
49 WCHAR DefaultLanguage
[20];
50 WCHAR DefaultKBLayout
[20];
51 BOOLEAN RepairUpdateFlag
= FALSE
;
52 HANDLE hPnpThread
= INVALID_HANDLE_VALUE
;
54 /* LOCALS *******************************************************************/
56 static PPARTLIST PartitionList
= NULL
;
58 static PFILE_SYSTEM_LIST FileSystemList
= NULL
;
60 static UNICODE_STRING InstallPath
;
62 /* Path to the install directory */
63 static UNICODE_STRING DestinationPath
;
64 static UNICODE_STRING DestinationArcPath
;
65 static UNICODE_STRING DestinationRootPath
;
67 /* Path to the active partition (boot manager) */
68 static UNICODE_STRING SystemRootPath
;
72 static HSPFILEQ SetupFileQueue
= NULL
;
74 static BOOLEAN WarnLinuxPartitions
= TRUE
;
76 static PGENERIC_LIST ComputerList
= NULL
;
77 static PGENERIC_LIST DisplayList
= NULL
;
78 static PGENERIC_LIST KeyboardList
= NULL
;
79 static PGENERIC_LIST LayoutList
= NULL
;
80 static PGENERIC_LIST LanguageList
= NULL
;
82 static LANGID LanguageId
= 0;
84 /* FUNCTIONS ****************************************************************/
87 PrintString(char* fmt
,...)
91 UNICODE_STRING UnicodeString
;
92 ANSI_STRING AnsiString
;
95 vsprintf(buffer
, fmt
, ap
);
98 RtlInitAnsiString(&AnsiString
, buffer
);
99 RtlAnsiStringToUnicodeString(&UnicodeString
, &AnsiString
, TRUE
);
100 NtDisplayString(&UnicodeString
);
101 RtlFreeUnicodeString(&UnicodeString
);
115 /* draw upper left corner */
118 FillConsoleOutputCharacterA(
125 /* draw upper edge */
128 FillConsoleOutputCharacterA(
135 /* draw upper right corner */
136 coPos
.X
= xLeft
+ Width
- 1;
138 FillConsoleOutputCharacterA(
145 /* Draw right edge, inner space and left edge */
146 for (coPos
.Y
= yTop
+ 1; coPos
.Y
< yTop
+ Height
- 1; coPos
.Y
++)
149 FillConsoleOutputCharacterA(
157 FillConsoleOutputCharacterA(
164 coPos
.X
= xLeft
+ Width
- 1;
165 FillConsoleOutputCharacterA(
173 /* draw lower left corner */
175 coPos
.Y
= yTop
+ Height
- 1;
176 FillConsoleOutputCharacterA(
183 /* draw lower edge */
185 coPos
.Y
= yTop
+ Height
- 1;
186 FillConsoleOutputCharacterA(
193 /* draw lower right corner */
194 coPos
.X
= xLeft
+ Width
- 1;
195 coPos
.Y
= yTop
+ Height
- 1;
196 FillConsoleOutputCharacterA(
205 PopupError(PCCH Text
,
223 /* Count text lines and longest line */
230 p
= strchr(pnext
, '\n');
234 Length
= strlen(pnext
);
239 Length
= (ULONG
)(p
- pnext
);
245 if (Length
> MaxLength
)
248 if (LastLine
== TRUE
)
254 /* Check length of status line */
257 Length
= strlen(Status
);
259 if (Length
> MaxLength
)
263 Width
= MaxLength
+ 4;
269 yTop
= (yScreen
- Height
) / 2;
270 xLeft
= (xScreen
- Width
) / 2;
273 /* Set screen attributes */
275 for (coPos
.Y
= yTop
; coPos
.Y
< yTop
+ Height
; coPos
.Y
++)
277 FillConsoleOutputAttribute(StdOutput
,
278 FOREGROUND_RED
| BACKGROUND_WHITE
,
284 DrawBox(xLeft
, yTop
, Width
, Height
);
286 /* Print message text */
291 p
= strchr(pnext
, '\n');
295 Length
= strlen(pnext
);
300 Length
= (ULONG
)(p
- pnext
);
307 WriteConsoleOutputCharacterA(StdOutput
,
314 if (LastLine
== TRUE
)
321 /* Print separator line and status text */
324 coPos
.Y
= yTop
+ Height
- 3;
326 FillConsoleOutputCharacterA(StdOutput
,
333 FillConsoleOutputCharacterA(StdOutput
,
339 coPos
.X
= xLeft
+ Width
- 1;
340 FillConsoleOutputCharacterA(StdOutput
,
348 WriteConsoleOutputCharacterA(StdOutput
,
350 min(strlen(Status
), (SIZE_T
)Width
- 4),
355 if (WaitEvent
== POPUP_WAIT_NONE
)
360 CONSOLE_ConInKey(Ir
);
362 if (WaitEvent
== POPUP_WAIT_ANY_KEY
||
363 Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D)
375 * FALSE: Don't quit setup.
378 ConfirmQuit(PINPUT_RECORD Ir
)
381 MUIDisplayError(ERROR_NOT_INSTALLED
, NULL
, POPUP_WAIT_NONE
);
385 CONSOLE_ConInKey(Ir
);
387 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
388 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
393 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
405 CheckUnattendedSetup(VOID
)
407 WCHAR UnattendInfPath
[MAX_PATH
];
414 if (DoesFileExist(SourcePath
.Buffer
, L
"unattend.inf") == FALSE
)
416 DPRINT("Does not exist: %S\\%S\n", SourcePath
.Buffer
, L
"unattend.inf");
420 wcscpy(UnattendInfPath
, SourcePath
.Buffer
);
421 wcscat(UnattendInfPath
, L
"\\unattend.inf");
423 /* Load 'unattend.inf' from install media. */
424 UnattendInf
= SetupOpenInfFileW(UnattendInfPath
,
430 if (UnattendInf
== INVALID_HANDLE_VALUE
)
432 DPRINT("SetupOpenInfFileW() failed\n");
436 /* Open 'Unattend' section */
437 if (!SetupFindFirstLineW(UnattendInf
, L
"Unattend", L
"Signature", &Context
))
439 DPRINT("SetupFindFirstLineW() failed for section 'Unattend'\n");
440 SetupCloseInfFile(UnattendInf
);
444 /* Get pointer 'Signature' key */
445 if (!INF_GetData(&Context
, NULL
, &Value
))
447 DPRINT("INF_GetData() failed for key 'Signature'\n");
448 SetupCloseInfFile(UnattendInf
);
452 /* Check 'Signature' string */
453 if (_wcsicmp(Value
, L
"$ReactOS$") != 0)
455 DPRINT("Signature not $ReactOS$\n");
456 SetupCloseInfFile(UnattendInf
);
460 /* Check if Unattend setup is enabled */
461 if (!SetupFindFirstLineW(UnattendInf
, L
"Unattend", L
"UnattendSetupEnabled", &Context
))
463 DPRINT("Can't find key 'UnattendSetupEnabled'\n");
464 SetupCloseInfFile(UnattendInf
);
468 if (!INF_GetData(&Context
, NULL
, &Value
))
470 DPRINT("Can't read key 'UnattendSetupEnabled'\n");
471 SetupCloseInfFile(UnattendInf
);
475 if (_wcsicmp(Value
, L
"yes") != 0)
477 DPRINT("Unattend setup is disabled by 'UnattendSetupEnabled' key!\n");
478 SetupCloseInfFile(UnattendInf
);
482 /* Search for 'DestinationDiskNumber' in the 'Unattend' section */
483 if (!SetupFindFirstLineW(UnattendInf
, L
"Unattend", L
"DestinationDiskNumber", &Context
))
485 DPRINT("SetupFindFirstLine() failed for key 'DestinationDiskNumber'\n");
486 SetupCloseInfFile(UnattendInf
);
490 if (!SetupGetIntField(&Context
, 1, &IntValue
))
492 DPRINT("SetupGetIntField() failed for key 'DestinationDiskNumber'\n");
493 SetupCloseInfFile(UnattendInf
);
497 UnattendDestinationDiskNumber
= (LONG
)IntValue
;
499 /* Search for 'DestinationPartitionNumber' in the 'Unattend' section */
500 if (!SetupFindFirstLineW(UnattendInf
, L
"Unattend", L
"DestinationPartitionNumber", &Context
))
502 DPRINT("SetupFindFirstLine() failed for key 'DestinationPartitionNumber'\n");
503 SetupCloseInfFile(UnattendInf
);
507 if (!SetupGetIntField(&Context
, 1, &IntValue
))
509 DPRINT("SetupGetIntField() failed for key 'DestinationPartitionNumber'\n");
510 SetupCloseInfFile(UnattendInf
);
514 UnattendDestinationPartitionNumber
= IntValue
;
516 /* Search for 'DestinationPartitionNumber' in the 'Unattend' section */
517 if (!SetupFindFirstLineW(UnattendInf
, L
"Unattend", L
"DestinationPartitionNumber", &Context
))
519 DPRINT("SetupFindFirstLine() failed for key 'DestinationPartitionNumber'\n");
520 SetupCloseInfFile(UnattendInf
);
524 /* Get pointer 'InstallationDirectory' key */
525 if (!INF_GetData(&Context
, NULL
, &Value
))
527 DPRINT("INF_GetData() failed for key 'InstallationDirectory'\n");
528 SetupCloseInfFile(UnattendInf
);
532 wcscpy(UnattendInstallationDirectory
, Value
);
534 IsUnattendedSetup
= TRUE
;
536 /* Search for 'MBRInstallType' in the 'Unattend' section */
537 if (SetupFindFirstLineW(UnattendInf
, L
"Unattend", L
"MBRInstallType", &Context
))
539 if (SetupGetIntField(&Context
, 1, &IntValue
))
541 UnattendMBRInstallType
= IntValue
;
545 /* Search for 'FormatPartition' in the 'Unattend' section */
546 if (SetupFindFirstLineW(UnattendInf
, L
"Unattend", L
"FormatPartition", &Context
))
548 if (SetupGetIntField(&Context
, 1, &IntValue
))
550 UnattendFormatPartition
= IntValue
;
554 if (SetupFindFirstLineW(UnattendInf
, L
"Unattend", L
"AutoPartition", &Context
))
556 if (SetupGetIntField(&Context
, 1, &IntValue
))
558 AutoPartition
= IntValue
;
562 /* search for LocaleID in the 'Unattend' section*/
563 if (SetupFindFirstLineW (UnattendInf
, L
"Unattend", L
"LocaleID", &Context
)){
564 if (INF_GetData (&Context
, NULL
, &Value
)){
565 LONG Id
= wcstol(Value
, NULL
, 16);
566 swprintf(LocaleID
,L
"%08lx", Id
);
570 SetupCloseInfFile(UnattendInf
);
572 DPRINT("Running unattended setup\n");
578 PGENERIC_LIST_ENTRY ListEntry
;
579 LPCWSTR pszNewLayout
;
581 pszNewLayout
= MUIDefaultKeyboardLayout();
583 if (LayoutList
== NULL
)
585 LayoutList
= CreateKeyboardLayoutList(SetupInf
, DefaultKBLayout
);
586 if (LayoutList
== NULL
)
588 /* FIXME: Handle error! */
593 ListEntry
= GetFirstListEntry(LayoutList
);
595 /* Search for default layout (if provided) */
596 if (pszNewLayout
!= NULL
)
598 while (ListEntry
!= NULL
)
600 if (!wcscmp(pszNewLayout
, GetListEntryUserData(ListEntry
)))
602 SetCurrentListEntry(LayoutList
, ListEntry
);
606 ListEntry
= GetNextListEntry(ListEntry
);
612 LanguagePage(PINPUT_RECORD Ir
)
614 /* Initialize the computer settings list */
615 if (LanguageList
== NULL
)
617 LanguageList
= CreateLanguageList(SetupInf
, DefaultLanguage
);
619 if (LanguageList
== NULL
)
621 PopupError("Setup failed to initialize available translations", NULL
, NULL
, POPUP_WAIT_NONE
);
626 DrawGenericList(LanguageList
,
632 ScrollToPositionGenericList (LanguageList
, GetDefaultLanguageIndex());
634 MUIDisplayPage(LANGUAGE_PAGE
);
638 CONSOLE_ConInKey(Ir
);
640 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
641 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
)) /* DOWN */
644 SelectedLanguageId
= (PWCHAR
)GetListEntryUserData(GetCurrentListEntry(LanguageList
));
646 /* Redraw language selection page in native language */
647 MUIDisplayPage(LANGUAGE_PAGE
);
650 ScrollDownGenericList (LanguageList
);
652 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
653 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_UP
)) /* UP */
656 SelectedLanguageId
= (PWCHAR
)GetListEntryUserData(GetCurrentListEntry(LanguageList
));
658 /* Redraw language selection page in native language */
659 MUIDisplayPage(LANGUAGE_PAGE
);
662 ScrollUpGenericList (LanguageList
);
664 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
665 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_NEXT
)) /* PAGE DOWN */
667 ScrollPageDownGenericList (LanguageList
);
669 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
670 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_PRIOR
)) /* PAGE UP */
672 ScrollPageUpGenericList (LanguageList
);
674 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
675 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
677 if (ConfirmQuit(Ir
) == TRUE
)
680 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
682 SelectedLanguageId
= (PWCHAR
)GetListEntryUserData(GetCurrentListEntry(LanguageList
));
684 LanguageId
= (LANGID
)(wcstol(SelectedLanguageId
, NULL
, 16) & 0xFFFF);
686 if (wcscmp(SelectedLanguageId
, DefaultLanguage
))
692 SetConsoleCodePage();
696 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
> 0x60) && (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
< 0x7b))
699 GenericListKeyPress (LanguageList
, Ir
->Event
.KeyEvent
.uChar
.AsciiChar
);
710 * Number of the next page.
713 SetupStartPage(PINPUT_RECORD Ir
)
715 SYSTEM_DEVICE_INFORMATION Sdi
;
717 WCHAR FileNameBuffer
[MAX_PATH
];
722 PGENERIC_LIST_ENTRY ListEntry
;
724 CONSOLE_SetStatusText(MUIGetString(STRING_PLEASEWAIT
));
727 /* Check whether a harddisk is available */
728 Status
= NtQuerySystemInformation (SystemDeviceInformation
,
730 sizeof(SYSTEM_DEVICE_INFORMATION
),
733 if (!NT_SUCCESS (Status
))
735 CONSOLE_PrintTextXY(6, 15, "NtQuerySystemInformation() failed (Status 0x%08lx)", Status
);
736 MUIDisplayError(ERROR_DRIVE_INFORMATION
, Ir
, POPUP_WAIT_ENTER
);
740 if (Sdi
.NumberOfDisks
== 0)
742 MUIDisplayError(ERROR_NO_HDD
, Ir
, POPUP_WAIT_ENTER
);
746 /* Get the source path and source root path */
747 Status
= GetSourcePaths(&SourcePath
,
751 if (!NT_SUCCESS(Status
))
753 CONSOLE_PrintTextXY(6, 15, "GetSourcePaths() failed (Status 0x%08lx)", Status
);
754 MUIDisplayError(ERROR_NO_SOURCE_DRIVE
, Ir
, POPUP_WAIT_ENTER
);
760 CONSOLE_PrintTextXY(6, 15, "SourcePath: '%wZ'", &SourcePath
);
761 CONSOLE_PrintTextXY(6, 16, "SourceRootPath: '%wZ'", &SourceRootPath
);
762 CONSOLE_PrintTextXY(6, 17, "SourceRootDir: '%wZ'", &SourceRootDir
);
766 /* Load txtsetup.sif from install media. */
767 wcscpy(FileNameBuffer
, SourcePath
.Buffer
);
768 wcscat(FileNameBuffer
, L
"\\txtsetup.sif");
770 SetupInf
= SetupOpenInfFileW(FileNameBuffer
,
776 if (SetupInf
== INVALID_HANDLE_VALUE
)
778 MUIDisplayError(ERROR_LOAD_TXTSETUPSIF
, Ir
, POPUP_WAIT_ENTER
);
782 /* Open 'Version' section */
783 if (!SetupFindFirstLineW (SetupInf
, L
"Version", L
"Signature", &Context
))
785 MUIDisplayError(ERROR_CORRUPT_TXTSETUPSIF
, Ir
, POPUP_WAIT_ENTER
);
789 /* Get pointer 'Signature' key */
790 if (!INF_GetData (&Context
, NULL
, &Value
))
792 MUIDisplayError(ERROR_CORRUPT_TXTSETUPSIF
, Ir
, POPUP_WAIT_ENTER
);
796 /* Check 'Signature' string */
797 if (_wcsicmp(Value
, L
"$ReactOS$") != 0)
799 MUIDisplayError(ERROR_SIGNATURE_TXTSETUPSIF
, Ir
, POPUP_WAIT_ENTER
);
803 /* Start PnP thread */
804 if (hPnpThread
!= INVALID_HANDLE_VALUE
)
806 NtResumeThread(hPnpThread
, NULL
);
807 hPnpThread
= INVALID_HANDLE_VALUE
;
810 CheckUnattendedSetup();
812 if (IsUnattendedSetup
)
815 //read options from inf
816 ComputerList
= CreateComputerTypeList(SetupInf
);
817 DisplayList
= CreateDisplayDriverList(SetupInf
);
818 KeyboardList
= CreateKeyboardDriverList(SetupInf
);
819 LayoutList
= CreateKeyboardLayoutList(SetupInf
, DefaultKBLayout
);
820 LanguageList
= CreateLanguageList(SetupInf
, DefaultLanguage
);
824 wcscpy(SelectedLanguageId
,LocaleID
);
827 /* first we hack LanguageList */
828 ListEntry
= GetFirstListEntry(LanguageList
);
830 while (ListEntry
!= NULL
)
832 if (!wcscmp(LocaleID
, GetListEntryUserData(ListEntry
)))
834 DPRINT("found %S in LanguageList\n",GetListEntryUserData(ListEntry
));
835 SetCurrentListEntry(LanguageList
, ListEntry
);
839 ListEntry
= GetNextListEntry(ListEntry
);
842 ListEntry
= GetFirstListEntry(LayoutList
);
844 while (ListEntry
!= NULL
)
846 if (!wcscmp(LocaleID
, GetListEntryUserData(ListEntry
)))
848 DPRINT("found %S in LayoutList\n",GetListEntryUserData(ListEntry
));
849 SetCurrentListEntry(LayoutList
, ListEntry
);
853 ListEntry
= GetNextListEntry(ListEntry
);
855 SetConsoleCodePage();
857 return INSTALL_INTRO_PAGE
;
860 return LANGUAGE_PAGE
;
870 IntroPage(PINPUT_RECORD Ir
)
872 MUIDisplayPage(START_PAGE
);
876 CONSOLE_ConInKey(Ir
);
878 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
879 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
881 if (ConfirmQuit(Ir
) == TRUE
)
886 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
888 return INSTALL_INTRO_PAGE
;
891 else if (toupper(Ir
->Event
.KeyEvent
.uChar
.AsciiChar
) == 'R') /* R */
893 return REPAIR_INTRO_PAGE
;
896 else if (toupper(Ir
->Event
.KeyEvent
.uChar
.AsciiChar
) == 'L') /* R */
909 * Back to main setup page.
912 LicensePage(PINPUT_RECORD Ir
)
914 MUIDisplayPage(LICENSE_PAGE
);
918 CONSOLE_ConInKey(Ir
);
920 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
931 RepairIntroPage(PINPUT_RECORD Ir
)
933 MUIDisplayPage(REPAIR_INTRO_PAGE
);
937 CONSOLE_ConInKey(Ir
);
939 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
943 else if (toupper(Ir
->Event
.KeyEvent
.uChar
.AsciiChar
) == 'U') /* U */
945 RepairUpdateFlag
= TRUE
;
946 return INSTALL_INTRO_PAGE
;
948 else if (toupper(Ir
->Event
.KeyEvent
.uChar
.AsciiChar
) == 'R') /* R */
952 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
953 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
)) /* ESC */
959 return REPAIR_INTRO_PAGE
;
964 InstallIntroPage(PINPUT_RECORD Ir
)
966 MUIDisplayPage(INSTALL_INTRO_PAGE
);
968 if (RepairUpdateFlag
)
970 //return SELECT_PARTITION_PAGE;
971 return DEVICE_SETTINGS_PAGE
;
974 if (IsUnattendedSetup
)
976 return SELECT_PARTITION_PAGE
;
981 CONSOLE_ConInKey(Ir
);
983 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
984 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
986 if (ConfirmQuit(Ir
) == TRUE
)
991 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
993 return DEVICE_SETTINGS_PAGE
;
994 // return SCSI_CONTROLLER_PAGE;
998 return INSTALL_INTRO_PAGE
;
1004 ScsiControllerPage(PINPUT_RECORD Ir
)
1006 SetTextXY(6, 8, "Setup detected the following mass storage devices:");
1008 /* FIXME: print loaded mass storage driver descriptions */
1010 SetTextXY(8, 10, "TEST device");
1014 SetStatusText(" ENTER = Continue F3 = Quit");
1020 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1021 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1023 if (ConfirmQuit(Ir
) == TRUE
)
1028 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
1030 return DEVICE_SETTINGS_PAGE
;
1034 return SCSI_CONTROLLER_PAGE
;
1040 DeviceSettingsPage(PINPUT_RECORD Ir
)
1042 static ULONG Line
= 16;
1043 MUIDisplayPage(DEVICE_SETTINGS_PAGE
);
1045 /* Initialize the computer settings list */
1046 if (ComputerList
== NULL
)
1048 ComputerList
= CreateComputerTypeList(SetupInf
);
1049 if (ComputerList
== NULL
)
1051 MUIDisplayError(ERROR_LOAD_COMPUTER
, Ir
, POPUP_WAIT_ENTER
);
1056 /* Initialize the display settings list */
1057 if (DisplayList
== NULL
)
1059 DisplayList
= CreateDisplayDriverList(SetupInf
);
1060 if (DisplayList
== NULL
)
1062 MUIDisplayError(ERROR_LOAD_DISPLAY
, Ir
, POPUP_WAIT_ENTER
);
1067 /* Initialize the keyboard settings list */
1068 if (KeyboardList
== NULL
)
1070 KeyboardList
= CreateKeyboardDriverList(SetupInf
);
1071 if (KeyboardList
== NULL
)
1073 MUIDisplayError(ERROR_LOAD_KEYBOARD
, Ir
, POPUP_WAIT_ENTER
);
1078 /* Initialize the keyboard layout list */
1079 if (LayoutList
== NULL
)
1081 LayoutList
= CreateKeyboardLayoutList(SetupInf
, DefaultKBLayout
);
1082 if (LayoutList
== NULL
)
1084 /* FIXME: report error */
1085 MUIDisplayError(ERROR_LOAD_KBLAYOUT
, Ir
, POPUP_WAIT_ENTER
);
1090 MUIDisplayPage(DEVICE_SETTINGS_PAGE
);
1093 CONSOLE_SetTextXY(25, 11, GetListEntryText(GetCurrentListEntry((ComputerList
))));
1094 CONSOLE_SetTextXY(25, 12, GetListEntryText(GetCurrentListEntry((DisplayList
))));
1095 CONSOLE_SetTextXY(25, 13, GetListEntryText(GetCurrentListEntry((KeyboardList
))));
1096 CONSOLE_SetTextXY(25, 14, GetListEntryText(GetCurrentListEntry((LayoutList
))));
1098 CONSOLE_InvertTextXY(24, Line
, 48, 1);
1100 if (RepairUpdateFlag
)
1102 return SELECT_PARTITION_PAGE
;
1107 CONSOLE_ConInKey(Ir
);
1109 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1110 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
)) /* DOWN */
1112 CONSOLE_NormalTextXY(24, Line
, 48, 1);
1116 else if (Line
== 16)
1121 CONSOLE_InvertTextXY(24, Line
, 48, 1);
1123 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1124 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_UP
)) /* UP */
1126 CONSOLE_NormalTextXY(24, Line
, 48, 1);
1130 else if (Line
== 16)
1135 CONSOLE_InvertTextXY(24, Line
, 48, 1);
1137 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1138 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1140 if (ConfirmQuit(Ir
) == TRUE
)
1145 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
1148 return COMPUTER_SETTINGS_PAGE
;
1149 else if (Line
== 12)
1150 return DISPLAY_SETTINGS_PAGE
;
1151 else if (Line
== 13)
1152 return KEYBOARD_SETTINGS_PAGE
;
1153 else if (Line
== 14)
1154 return LAYOUT_SETTINGS_PAGE
;
1155 else if (Line
== 16)
1156 return SELECT_PARTITION_PAGE
;
1160 return DEVICE_SETTINGS_PAGE
;
1165 ComputerSettingsPage(PINPUT_RECORD Ir
)
1167 MUIDisplayPage(COMPUTER_SETTINGS_PAGE
);
1169 DrawGenericList(ComputerList
,
1175 SaveGenericListState(ComputerList
);
1179 CONSOLE_ConInKey(Ir
);
1181 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1182 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
)) /* DOWN */
1184 ScrollDownGenericList (ComputerList
);
1186 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1187 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_UP
)) /* UP */
1189 ScrollUpGenericList (ComputerList
);
1191 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1192 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1194 if (ConfirmQuit(Ir
) == TRUE
)
1199 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1200 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
)) /* ESC */
1202 RestoreGenericListState(ComputerList
);
1203 return DEVICE_SETTINGS_PAGE
;
1205 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
1207 return DEVICE_SETTINGS_PAGE
;
1211 return COMPUTER_SETTINGS_PAGE
;
1216 DisplaySettingsPage(PINPUT_RECORD Ir
)
1218 MUIDisplayPage(DISPLAY_SETTINGS_PAGE
);
1220 DrawGenericList(DisplayList
,
1226 SaveGenericListState(DisplayList
);
1230 CONSOLE_ConInKey(Ir
);
1232 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1233 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
)) /* DOWN */
1235 ScrollDownGenericList (DisplayList
);
1237 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1238 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_UP
)) /* UP */
1240 ScrollUpGenericList (DisplayList
);
1242 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1243 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1245 if (ConfirmQuit(Ir
) == TRUE
)
1252 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1253 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
)) /* ESC */
1255 RestoreGenericListState(DisplayList
);
1256 return DEVICE_SETTINGS_PAGE
;
1258 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
1260 return DEVICE_SETTINGS_PAGE
;
1264 return DISPLAY_SETTINGS_PAGE
;
1269 KeyboardSettingsPage(PINPUT_RECORD Ir
)
1271 MUIDisplayPage(KEYBOARD_SETTINGS_PAGE
);
1273 DrawGenericList(KeyboardList
,
1279 SaveGenericListState(KeyboardList
);
1283 CONSOLE_ConInKey(Ir
);
1285 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1286 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
)) /* DOWN */
1288 ScrollDownGenericList (KeyboardList
);
1290 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1291 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_UP
)) /* UP */
1293 ScrollUpGenericList (KeyboardList
);
1295 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1296 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1298 if (ConfirmQuit(Ir
) == TRUE
)
1303 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1304 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
)) /* ESC */
1306 RestoreGenericListState(KeyboardList
);
1307 return DEVICE_SETTINGS_PAGE
;
1309 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
1311 return DEVICE_SETTINGS_PAGE
;
1315 return DISPLAY_SETTINGS_PAGE
;
1320 LayoutSettingsPage(PINPUT_RECORD Ir
)
1322 MUIDisplayPage(LAYOUT_SETTINGS_PAGE
);
1324 DrawGenericList(LayoutList
,
1330 SaveGenericListState(LayoutList
);
1334 CONSOLE_ConInKey(Ir
);
1336 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1337 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
)) /* DOWN */
1339 ScrollDownGenericList (LayoutList
);
1341 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1342 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_UP
)) /* UP */
1344 ScrollUpGenericList (LayoutList
);
1346 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1347 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_NEXT
)) /* PAGE DOWN */
1349 ScrollPageDownGenericList (LayoutList
);
1351 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1352 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_PRIOR
)) /* PAGE UP */
1354 ScrollPageUpGenericList (LayoutList
);
1356 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1357 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1359 if (ConfirmQuit(Ir
) == TRUE
)
1364 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1365 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
)) /* ESC */
1367 RestoreGenericListState(LayoutList
);
1368 return DEVICE_SETTINGS_PAGE
;
1370 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
1372 return DEVICE_SETTINGS_PAGE
;
1374 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
> 0x60) && (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
< 0x7b))
1377 GenericListKeyPress (LayoutList
, Ir
->Event
.KeyEvent
.uChar
.AsciiChar
);
1381 return DISPLAY_SETTINGS_PAGE
;
1386 SelectPartitionPage(PINPUT_RECORD Ir
)
1388 MUIDisplayPage(SELECT_PARTITION_PAGE
);
1390 if (PartitionList
== NULL
)
1392 PartitionList
= CreatePartitionList (2,
1397 if (PartitionList
== NULL
)
1399 /* FIXME: show an error dialog */
1404 CheckActiveBootPartition (PartitionList
);
1406 DrawPartitionList (PartitionList
);
1408 /* Warn about partitions created by Linux Fdisk */
1409 if (WarnLinuxPartitions
== TRUE
&&
1410 CheckForLinuxFdiskPartitions(PartitionList
) == TRUE
)
1412 MUIDisplayError(ERROR_WARN_PARTITION
, NULL
, POPUP_WAIT_NONE
);
1416 CONSOLE_ConInKey(Ir
);
1418 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1419 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1423 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_RETURN
) /* ENTER */
1425 WarnLinuxPartitions
= FALSE
;
1426 return SELECT_PARTITION_PAGE
;
1431 if (IsUnattendedSetup
)
1433 if (!SelectPartition(PartitionList
, UnattendDestinationDiskNumber
, UnattendDestinationPartitionNumber
))
1437 PPARTENTRY PartEntry
= PartEntry
= PartitionList
->CurrentPartition
;
1438 ULONG MaxSize
= (PartEntry
->UnpartitionedLength
+ (1 << 19)) >> 20; /* in MBytes (rounded) */
1440 CreateNewPartition(PartitionList
,
1444 return (SELECT_FILE_SYSTEM_PAGE
);
1449 return(SELECT_FILE_SYSTEM_PAGE
);
1455 /* Update status text */
1456 if (PartitionList
->CurrentPartition
== NULL
||
1457 PartitionList
->CurrentPartition
->Unpartitioned
== TRUE
)
1459 CONSOLE_SetStatusText(MUIGetString(STRING_INSTALLCREATEPARTITION
));
1463 CONSOLE_SetStatusText(MUIGetString(STRING_INSTALLDELETEPARTITION
));
1466 CONSOLE_ConInKey(Ir
);
1468 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1469 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1471 if (ConfirmQuit(Ir
) == TRUE
)
1473 DestroyPartitionList (PartitionList
);
1474 PartitionList
= NULL
;
1480 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1481 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
)) /* DOWN */
1483 ScrollDownPartitionList (PartitionList
);
1485 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1486 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_UP
)) /* UP */
1488 ScrollUpPartitionList (PartitionList
);
1490 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_RETURN
) /* ENTER */
1492 if (PartitionList
->CurrentPartition
== NULL
||
1493 PartitionList
->CurrentPartition
->Unpartitioned
== TRUE
)
1495 CreateNewPartition (PartitionList
,
1500 return SELECT_FILE_SYSTEM_PAGE
;
1502 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== 'C') /* C */
1504 if (PartitionList
->CurrentPartition
->Unpartitioned
== FALSE
)
1506 MUIDisplayError(ERROR_NEW_PARTITION
, Ir
, POPUP_WAIT_ANY_KEY
);
1507 return SELECT_PARTITION_PAGE
;
1510 return CREATE_PARTITION_PAGE
;
1512 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== 'D') /* D */
1514 if (PartitionList
->CurrentPartition
->Unpartitioned
== TRUE
)
1516 MUIDisplayError(ERROR_DELETE_SPACE
, Ir
, POPUP_WAIT_ANY_KEY
);
1517 return SELECT_PARTITION_PAGE
;
1520 return DELETE_PARTITION_PAGE
;
1524 return SELECT_PARTITION_PAGE
;
1529 DrawInputField(ULONG FieldLength
,
1540 memset(buf
, '_', sizeof(buf
));
1541 buf
[FieldLength
- strlen(FieldContent
)] = 0;
1542 strcat(buf
, FieldContent
);
1544 WriteConsoleOutputCharacterA (StdOutput
,
1552 #define PARTITION_SIZE_INPUT_FIELD_LENGTH 6
1553 /* Restriction for MaxSize: pow(10, PARTITION_SIZE_INPUT_FIELD_LENGTH)-1 */
1554 #define PARTITION_MAXSIZE 999999
1557 ShowPartitionSizeInputBox(SHORT Left
,
1581 DrawBox(Left
, Top
, Right
- Left
+ 1, Bottom
- Top
+ 1);
1586 strcpy (Buffer
, MUIGetString(STRING_PARTITIONSIZE
));
1587 iLeft
= coPos
.X
+ strlen (Buffer
) + 1;
1590 WriteConsoleOutputCharacterA(StdOutput
,
1596 sprintf (Buffer
, MUIGetString(STRING_MAXSIZE
), MaxSize
);
1597 coPos
.X
= iLeft
+ PARTITION_SIZE_INPUT_FIELD_LENGTH
+ 1;
1599 WriteConsoleOutputCharacterA(StdOutput
,
1605 sprintf(Buffer
, "%lu", MaxSize
);
1606 Index
= strlen(Buffer
);
1607 DrawInputField (PARTITION_SIZE_INPUT_FIELD_LENGTH
,
1614 CONSOLE_ConInKey(&Ir
);
1616 if ((Ir
.Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1617 (Ir
.Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1625 else if (Ir
.Event
.KeyEvent
.wVirtualKeyCode
== VK_RETURN
) /* ENTER */
1629 else if (Ir
.Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
) /* ESCAPE */
1637 else if ((Ir
.Event
.KeyEvent
.wVirtualKeyCode
== VK_BACK
) && /* BACKSPACE */
1643 DrawInputField (PARTITION_SIZE_INPUT_FIELD_LENGTH
,
1648 else if ((Ir
.Event
.KeyEvent
.uChar
.AsciiChar
!= 0x00) &&
1649 (Index
< PARTITION_SIZE_INPUT_FIELD_LENGTH
))
1651 ch
= Ir
.Event
.KeyEvent
.uChar
.AsciiChar
;
1653 if ((ch
>= '0') && (ch
<= '9'))
1659 DrawInputField (PARTITION_SIZE_INPUT_FIELD_LENGTH
,
1667 strcpy (InputBuffer
, Buffer
);
1672 CreatePartitionPage (PINPUT_RECORD Ir
)
1674 PDISKENTRY DiskEntry
;
1675 PPARTENTRY PartEntry
;
1678 CHAR InputBuffer
[50];
1684 if (PartitionList
== NULL
||
1685 PartitionList
->CurrentDisk
== NULL
||
1686 PartitionList
->CurrentPartition
== NULL
)
1688 /* FIXME: show an error dialog */
1692 DiskEntry
= PartitionList
->CurrentDisk
;
1693 PartEntry
= PartitionList
->CurrentPartition
;
1695 CONSOLE_SetStatusText(MUIGetString(STRING_PLEASEWAIT
));
1697 CONSOLE_SetTextXY(6, 8, MUIGetString(STRING_CHOOSENEWPARTITION
));
1700 if (DiskEntry
->DiskSize
>= 0x280000000ULL
) /* 10 GB */
1702 DiskSize
= (DiskEntry
->DiskSize
+ (1 << 29)) >> 30;
1703 Unit
= MUIGetString(STRING_GB
);
1708 DiskSize
= (DiskEntry
->DiskSize
+ (1 << 19)) >> 20;
1713 Unit
= MUIGetString(STRING_MB
);
1716 if (DiskEntry
->DriverName
.Length
> 0)
1718 CONSOLE_PrintTextXY(6, 10,
1719 MUIGetString(STRING_HDINFOPARTCREATE
),
1722 DiskEntry
->DiskNumber
,
1726 &DiskEntry
->DriverName
);
1730 CONSOLE_PrintTextXY(6, 10,
1731 MUIGetString(STRING_HDDINFOUNK1
),
1734 DiskEntry
->DiskNumber
,
1740 CONSOLE_SetTextXY(6, 12, MUIGetString(STRING_HDDSIZE
));
1743 CONSOLE_PrintTextXY(8, 10, "Maximum size of the new partition is %I64u MB",
1744 PartitionList
->CurrentPartition
->UnpartitionedLength
/ (1024*1024));
1747 CONSOLE_SetStatusText(MUIGetString(STRING_CREATEPARTITION
));
1749 PartEntry
= PartitionList
->CurrentPartition
;
1752 MaxSize
= (PartEntry
->UnpartitionedLength
+ (1 << 19)) >> 20; /* in MBytes (rounded) */
1754 if (MaxSize
> PARTITION_MAXSIZE
) MaxSize
= PARTITION_MAXSIZE
;
1756 ShowPartitionSizeInputBox (12, 14, xScreen
- 12, 17, /* left, top, right, bottom */
1757 MaxSize
, InputBuffer
, &Quit
, &Cancel
);
1761 if (ConfirmQuit (Ir
) == TRUE
)
1766 else if (Cancel
== TRUE
)
1768 return SELECT_PARTITION_PAGE
;
1772 PartSize
= atoi(InputBuffer
);
1780 if (PartSize
> MaxSize
)
1786 /* Convert to bytes */
1787 if (PartSize
== MaxSize
)
1789 /* Use all of the unpartitioned disk space */
1790 PartSize
= PartEntry
->UnpartitionedLength
;
1794 /* Round-up by cylinder size */
1795 PartSize
= (PartSize
* 1024 * 1024 + DiskEntry
->CylinderSize
- 1) /
1796 DiskEntry
->CylinderSize
* DiskEntry
->CylinderSize
;
1798 /* But never get larger than the unpartitioned disk space */
1799 if (PartSize
> PartEntry
->UnpartitionedLength
)
1800 PartSize
= PartEntry
->UnpartitionedLength
;
1803 DPRINT ("Partition size: %I64u bytes\n", PartSize
);
1805 CreateNewPartition (PartitionList
,
1809 return SELECT_PARTITION_PAGE
;
1813 return CREATE_PARTITION_PAGE
;
1818 DeletePartitionPage (PINPUT_RECORD Ir
)
1820 PDISKENTRY DiskEntry
;
1821 PPARTENTRY PartEntry
;
1828 if (PartitionList
== NULL
||
1829 PartitionList
->CurrentDisk
== NULL
||
1830 PartitionList
->CurrentPartition
== NULL
)
1832 /* FIXME: show an error dialog */
1836 DiskEntry
= PartitionList
->CurrentDisk
;
1837 PartEntry
= PartitionList
->CurrentPartition
;
1838 PartNumber
= PartitionList
->CurrentPartitionNumber
;
1840 MUIDisplayPage(DELETE_PARTITION_PAGE
);
1842 /* Determine partition type */
1844 if (PartEntry
->New
== TRUE
)
1846 PartType
= MUIGetString(STRING_UNFORMATTED
);
1848 else if (PartEntry
->Unpartitioned
== FALSE
)
1850 if ((PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_FAT_12
) ||
1851 (PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_FAT_16
) ||
1852 (PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_HUGE
) ||
1853 (PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_XINT13
))
1857 else if ((PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_FAT32
) ||
1858 (PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_FAT32_XINT13
))
1862 else if (PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_EXT2
)
1866 else if (PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_IFS
)
1868 PartType
= "NTFS"; /* FIXME: Not quite correct! */
1873 if (PartEntry
->PartInfo
[PartNumber
].PartitionLength
.QuadPart
>= 0x280000000LL
) /* 10 GB */
1875 PartSize
= (PartEntry
->PartInfo
[PartNumber
].PartitionLength
.QuadPart
+ (1 << 29)) >> 30;
1876 Unit
= MUIGetString(STRING_GB
);
1880 if (PartEntry
->PartInfo
[PartNumber
].PartitionLength
.QuadPart
>= 0xA00000LL
) /* 10 MB */
1882 PartSize
= (PartEntry
->PartInfo
[PartNumber
].PartitionLength
.QuadPart
+ (1 << 19)) >> 20;
1883 Unit
= MUIGetString(STRING_MB
);
1887 PartSize
= (PartEntry
->PartInfo
[PartNumber
].PartitionLength
.QuadPart
+ (1 << 9)) >> 10;
1888 Unit
= MUIGetString(STRING_KB
);
1891 if (PartType
== NULL
)
1893 CONSOLE_PrintTextXY(6, 10,
1894 MUIGetString(STRING_HDDINFOUNK2
),
1895 (PartEntry
->DriveLetter
[PartNumber
] == 0) ? '-' : PartEntry
->DriveLetter
[PartNumber
],
1896 (PartEntry
->DriveLetter
[PartNumber
] == 0) ? '-' : ':',
1897 PartEntry
->PartInfo
[PartNumber
].PartitionType
,
1903 CONSOLE_PrintTextXY(6, 10,
1904 " %c%c %s %I64u %s",
1905 (PartEntry
->DriveLetter
[PartNumber
] == 0) ? '-' : PartEntry
->DriveLetter
[PartNumber
],
1906 (PartEntry
->DriveLetter
[PartNumber
] == 0) ? '-' : ':',
1913 if (DiskEntry
->DiskSize
>= 0x280000000ULL
) /* 10 GB */
1915 DiskSize
= (DiskEntry
->DiskSize
+ (1 << 29)) >> 30;
1916 Unit
= MUIGetString(STRING_GB
);
1921 DiskSize
= (DiskEntry
->DiskSize
+ (1 << 19)) >> 20;
1926 Unit
= MUIGetString(STRING_MB
);
1929 if (DiskEntry
->DriverName
.Length
> 0)
1931 CONSOLE_PrintTextXY(6, 12,
1932 MUIGetString(STRING_HDINFOPARTDELETE
),
1935 DiskEntry
->DiskNumber
,
1939 &DiskEntry
->DriverName
);
1943 CONSOLE_PrintTextXY(6, 12,
1944 MUIGetString(STRING_HDDINFOUNK3
),
1947 DiskEntry
->DiskNumber
,
1955 CONSOLE_ConInKey(Ir
);
1957 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1958 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1960 if (ConfirmQuit (Ir
) == TRUE
)
1967 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
) /* ESC */
1969 return SELECT_PARTITION_PAGE
;
1971 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== 'D') /* D */
1973 DeleteCurrentPartition (PartitionList
);
1975 return SELECT_PARTITION_PAGE
;
1979 return DELETE_PARTITION_PAGE
;
1984 SelectFileSystemPage (PINPUT_RECORD Ir
)
1986 PDISKENTRY DiskEntry
;
1987 PPARTENTRY PartEntry
;
1995 if (PartitionList
== NULL
||
1996 PartitionList
->CurrentDisk
== NULL
||
1997 PartitionList
->CurrentPartition
== NULL
)
1999 /* FIXME: show an error dialog */
2003 DiskEntry
= PartitionList
->CurrentDisk
;
2004 PartEntry
= PartitionList
->CurrentPartition
;
2005 PartNumber
= PartitionList
->CurrentPartitionNumber
;
2007 /* adjust disk size */
2008 if (DiskEntry
->DiskSize
>= 0x280000000ULL
) /* 10 GB */
2010 DiskSize
= (DiskEntry
->DiskSize
+ (1 << 29)) >> 30;
2011 DiskUnit
= MUIGetString(STRING_GB
);
2015 DiskSize
= (DiskEntry
->DiskSize
+ (1 << 19)) >> 20;
2016 DiskUnit
= MUIGetString(STRING_MB
);
2019 /* adjust partition size */
2020 if (PartEntry
->PartInfo
[PartNumber
].PartitionLength
.QuadPart
>= 0x280000000LL
) /* 10 GB */
2022 PartSize
= (PartEntry
->PartInfo
[PartNumber
].PartitionLength
.QuadPart
+ (1 << 29)) >> 30;
2023 PartUnit
= MUIGetString(STRING_GB
);
2027 PartSize
= (PartEntry
->PartInfo
[PartNumber
].PartitionLength
.QuadPart
+ (1 << 19)) >> 20;
2028 PartUnit
= MUIGetString(STRING_MB
);
2031 /* adjust partition type */
2032 if ((PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_FAT_12
) ||
2033 (PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_FAT_16
) ||
2034 (PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_HUGE
) ||
2035 (PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_XINT13
))
2039 else if ((PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_FAT32
) ||
2040 (PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_FAT32_XINT13
))
2044 else if (PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_EXT2
)
2048 else if (PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_IFS
)
2050 PartType
= "NTFS"; /* FIXME: Not quite correct! */
2052 else if (PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_ENTRY_UNUSED
)
2054 PartType
= MUIGetString(STRING_FORMATUNUSED
);
2058 PartType
= MUIGetString(STRING_FORMATUNKNOWN
);
2061 if (PartEntry
->AutoCreate
== TRUE
)
2063 CONSOLE_SetTextXY(6, 8, MUIGetString(STRING_NEWPARTITION
));
2066 CONSOLE_PrintTextXY(8, 10, "Partition %lu (%I64u %s) %s of",
2067 PartEntry
->PartInfo
[PartNumber
].PartitionNumber
,
2073 CONSOLE_PrintTextXY(8, 10, MUIGetString(STRING_HDINFOPARTZEROED
),
2074 DiskEntry
->DiskNumber
,
2080 &DiskEntry
->DriverName
);
2082 CONSOLE_SetTextXY(6, 12, MUIGetString(STRING_PARTFORMAT
));
2085 PartEntry
->AutoCreate
= FALSE
;
2087 else if (PartEntry
->New
== TRUE
)
2089 CONSOLE_SetTextXY(6, 8, MUIGetString(STRING_NONFORMATTEDPART
));
2090 CONSOLE_SetTextXY(6, 10, MUIGetString(STRING_PARTFORMAT
));
2094 CONSOLE_SetTextXY(6, 8, MUIGetString(STRING_INSTALLONPART
));
2096 if (PartType
== NULL
)
2098 CONSOLE_PrintTextXY(8, 10,
2099 MUIGetString(STRING_HDDINFOUNK4
),
2100 (PartEntry
->DriveLetter
[PartNumber
] == 0) ? '-' : PartEntry
->DriveLetter
[PartNumber
],
2101 (PartEntry
->DriveLetter
[PartNumber
] == 0) ? '-' : ':',
2102 PartEntry
->PartInfo
[PartNumber
].PartitionType
,
2108 CONSOLE_PrintTextXY(8, 10,
2110 (PartEntry
->DriveLetter
[PartNumber
] == 0) ? '-' : PartEntry
->DriveLetter
[PartNumber
],
2111 (PartEntry
->DriveLetter
[PartNumber
] == 0) ? '-' : ':',
2117 CONSOLE_PrintTextXY(6, 12, MUIGetString(STRING_HDINFOPARTEXISTS
),
2118 DiskEntry
->DiskNumber
,
2124 &DiskEntry
->DriverName
);
2127 MUIDisplayPage(SELECT_FILE_SYSTEM_PAGE
);
2129 if (FileSystemList
== NULL
)
2131 FileSystemList
= CreateFileSystemList (6, 26, PartEntry
->New
, L
"FAT");
2132 if (FileSystemList
== NULL
)
2134 /* FIXME: show an error dialog */
2138 /* FIXME: Add file systems to list */
2140 DrawFileSystemList (FileSystemList
);
2142 if (RepairUpdateFlag
)
2144 return CHECK_FILE_SYSTEM_PAGE
;
2145 //return SELECT_PARTITION_PAGE;
2148 if (IsUnattendedSetup
)
2150 if (UnattendFormatPartition
)
2152 return FORMAT_PARTITION_PAGE
;
2155 return(CHECK_FILE_SYSTEM_PAGE
);
2160 CONSOLE_ConInKey(Ir
);
2162 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
2163 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
2165 if (ConfirmQuit (Ir
) == TRUE
)
2172 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
2173 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
)) /* ESC */
2175 return SELECT_PARTITION_PAGE
;
2177 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
2178 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
)) /* DOWN */
2180 ScrollDownFileSystemList (FileSystemList
);
2182 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
2183 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_UP
)) /* UP */
2185 ScrollUpFileSystemList (FileSystemList
);
2187 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_RETURN
) /* ENTER */
2189 if (!FileSystemList
->Selected
->FormatFunc
)
2191 return CHECK_FILE_SYSTEM_PAGE
;
2195 return FORMAT_PARTITION_PAGE
;
2200 return SELECT_FILE_SYSTEM_PAGE
;
2205 FormatPartitionPage (PINPUT_RECORD Ir
)
2207 WCHAR PathBuffer
[MAX_PATH
];
2208 PDISKENTRY DiskEntry
;
2209 PPARTENTRY PartEntry
;
2219 MUIDisplayPage(FORMAT_PARTITION_PAGE
);
2221 if (PartitionList
== NULL
||
2222 PartitionList
->CurrentDisk
== NULL
||
2223 PartitionList
->CurrentPartition
== NULL
)
2225 /* FIXME: show an error dialog */
2229 DiskEntry
= PartitionList
->CurrentDisk
;
2230 PartEntry
= PartitionList
->CurrentPartition
;
2231 PartNum
= PartitionList
->CurrentPartitionNumber
;
2235 if (!IsUnattendedSetup
)
2237 CONSOLE_ConInKey(Ir
);
2240 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
2241 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
2243 if (ConfirmQuit (Ir
) == TRUE
)
2250 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_RETURN
|| IsUnattendedSetup
) /* ENTER */
2252 CONSOLE_SetStatusText(MUIGetString(STRING_PLEASEWAIT
));
2254 if (PartEntry
->PartInfo
[PartNum
].PartitionType
== PARTITION_ENTRY_UNUSED
)
2256 if (wcscmp(FileSystemList
->Selected
->FileSystem
, L
"FAT") == 0)
2258 if (PartEntry
->PartInfo
[PartNum
].PartitionLength
.QuadPart
< (4200LL * 1024LL))
2260 /* FAT12 CHS partition (disk is smaller than 4.1MB) */
2261 PartEntry
->PartInfo
[PartNum
].PartitionType
= PARTITION_FAT_12
;
2263 else if (PartEntry
->PartInfo
[PartNum
].StartingOffset
.QuadPart
< (1024LL * 255LL * 63LL * 512LL))
2265 /* Partition starts below the 8.4GB boundary ==> CHS partition */
2267 if (PartEntry
->PartInfo
[PartNum
].PartitionLength
.QuadPart
< (32LL * 1024LL * 1024LL))
2269 /* FAT16 CHS partition (partiton size < 32MB) */
2270 PartEntry
->PartInfo
[PartNum
].PartitionType
= PARTITION_FAT_16
;
2272 else if (PartEntry
->PartInfo
[PartNum
].PartitionLength
.QuadPart
< (512LL * 1024LL * 1024LL))
2274 /* FAT16 CHS partition (partition size < 512MB) */
2275 PartEntry
->PartInfo
[PartNum
].PartitionType
= PARTITION_HUGE
;
2279 /* FAT32 CHS partition (partition size >= 512MB) */
2280 PartEntry
->PartInfo
[PartNum
].PartitionType
= PARTITION_FAT32
;
2285 /* Partition starts above the 8.4GB boundary ==> LBA partition */
2287 if (PartEntry
->PartInfo
[PartNum
].PartitionLength
.QuadPart
< (512LL * 1024LL * 1024LL))
2289 /* FAT16 LBA partition (partition size < 512MB) */
2290 PartEntry
->PartInfo
[PartNum
].PartitionType
= PARTITION_XINT13
;
2294 /* FAT32 LBA partition (partition size >= 512MB) */
2295 PartEntry
->PartInfo
[PartNum
].PartitionType
= PARTITION_FAT32_XINT13
;
2299 else if (wcscmp(FileSystemList
->Selected
->FileSystem
, L
"EXT2") == 0)
2300 PartEntry
->PartInfo
[PartNum
].PartitionType
= PARTITION_EXT2
;
2301 else if (!FileSystemList
->Selected
->FormatFunc
)
2305 CheckActiveBootPartition (PartitionList
);
2308 CONSOLE_PrintTextXY(6, 12,
2309 "Disk: %I64u Cylinder: %I64u Track: %I64u",
2310 DiskEntry
->DiskSize
,
2311 DiskEntry
->CylinderSize
,
2312 DiskEntry
->TrackSize
);
2315 DiskEntry
= PartitionList
->CurrentDisk
;
2316 Entry
= DiskEntry
->PartListHead
.Flink
;
2318 while (Entry
!= &DiskEntry
->PartListHead
)
2320 PartEntry
= CONTAINING_RECORD(Entry
, PARTENTRY
, ListEntry
);
2322 if (PartEntry
->Unpartitioned
== FALSE
)
2324 for (i
= 0; i
< 4; i
++)
2326 CONSOLE_PrintTextXY(6, Line
,
2327 "%2u: %2u %c %12I64u %12I64u %2u %c",
2329 PartEntry
->PartInfo
[i
].PartitionNumber
,
2330 PartEntry
->PartInfo
[i
].BootIndicator
? 'A' : '-',
2331 PartEntry
->PartInfo
[i
].StartingOffset
.QuadPart
,
2332 PartEntry
->PartInfo
[i
].PartitionLength
.QuadPart
,
2333 PartEntry
->PartInfo
[i
].PartitionType
,
2334 PartEntry
->PartInfo
[i
].RewritePartition
? '*' : ' ');
2342 Entry
= Entry
->Flink
;
2345 /* Restore the old entry */
2346 PartEntry
= PartitionList
->CurrentPartition
;
2349 if (WritePartitionsToDisk (PartitionList
) == FALSE
)
2351 DPRINT ("WritePartitionsToDisk() failed\n");
2352 MUIDisplayError(ERROR_WRITE_PTABLE
, Ir
, POPUP_WAIT_ENTER
);
2356 /* Set DestinationRootPath */
2357 RtlFreeUnicodeString (&DestinationRootPath
);
2358 swprintf (PathBuffer
,
2359 L
"\\Device\\Harddisk%lu\\Partition%lu",
2360 PartitionList
->CurrentDisk
->DiskNumber
,
2361 PartitionList
->CurrentPartition
->PartInfo
[PartNum
].PartitionNumber
);
2362 RtlCreateUnicodeString (&DestinationRootPath
,
2364 DPRINT ("DestinationRootPath: %wZ\n", &DestinationRootPath
);
2367 /* Set SystemRootPath */
2368 RtlFreeUnicodeString (&SystemRootPath
);
2369 swprintf (PathBuffer
,
2370 L
"\\Device\\Harddisk%lu\\Partition%lu",
2371 PartitionList
->ActiveBootDisk
->DiskNumber
,
2372 PartitionList
->ActiveBootPartition
->
2373 PartInfo
[PartitionList
->ActiveBootPartitionNumber
].PartitionNumber
);
2374 RtlCreateUnicodeString (&SystemRootPath
,
2376 DPRINT ("SystemRootPath: %wZ\n", &SystemRootPath
);
2379 if (FileSystemList
->Selected
->FormatFunc
)
2381 Status
= FormatPartition(&DestinationRootPath
, FileSystemList
->Selected
);
2382 if (!NT_SUCCESS(Status
))
2384 DPRINT1("FormatPartition() failed with status 0x%08lx\n", Status
);
2385 /* FIXME: show an error dialog */
2389 PartEntry
->New
= FALSE
;
2391 CheckActiveBootPartition(PartitionList
);
2394 /* Install MBR if necessary */
2395 if (DiskEntry
->NoMbr
&&
2396 DiskEntry
->BiosDiskNumber
== 0)
2398 wcscpy(PathBuffer
, SourceRootPath
.Buffer
);
2399 wcscat(PathBuffer
, L
"\\loader\\dosmbr.bin");
2401 DPRINT("Install MBR bootcode: %S ==> %S\n",
2402 PathBuffer
, DestinationRootPath
.Buffer
);
2404 /* Install MBR bootcode */
2405 Status
= InstallMbrBootCodeToDisk(PathBuffer
, DestinationRootPath
.Buffer
);
2406 if (!NT_SUCCESS (Status
))
2408 DPRINT1("InstallMbrBootCodeToDisk() failed (Status %lx)\n",
2413 DiskEntry
->NoMbr
= FALSE
;
2416 if (wcscmp(FileSystemList
->Selected
->FileSystem
, L
"FAT") == 0)
2418 /* FIXME: Install boot code. This is a hack! */
2419 if ((PartEntry
->PartInfo
[PartNum
].PartitionType
== PARTITION_FAT32_XINT13
) ||
2420 (PartEntry
->PartInfo
[PartNum
].PartitionType
== PARTITION_FAT32
))
2422 wcscpy(PathBuffer
, SourceRootPath
.Buffer
);
2423 wcscat(PathBuffer
, L
"\\loader\\fat32.bin");
2425 DPRINT("Install FAT32 bootcode: %S ==> %S\n", PathBuffer
,
2426 DestinationRootPath
.Buffer
);
2427 Status
= InstallFat32BootCodeToDisk(PathBuffer
,
2428 DestinationRootPath
.Buffer
);
2430 if (!NT_SUCCESS(Status
))
2432 DPRINT1("InstallFat32BootCodeToDisk() failed with status 0x%08lx\n", Status
);
2433 /* FIXME: show an error dialog */
2434 DestroyFileSystemList(FileSystemList
);
2435 FileSystemList
= NULL
;
2441 wcscpy(PathBuffer
, SourceRootPath
.Buffer
);
2442 wcscat(PathBuffer
, L
"\\loader\\fat.bin");
2444 DPRINT("Install FAT bootcode: %S ==> %S\n", PathBuffer
,
2445 DestinationRootPath
.Buffer
);
2446 Status
= InstallFat16BootCodeToDisk(PathBuffer
,
2447 DestinationRootPath
.Buffer
);
2449 if (!NT_SUCCESS(Status
))
2451 DPRINT1("InstallFat16BootCodeToDisk() failed with status 0x%.08x\n", Status
);
2452 /* FIXME: show an error dialog */
2453 DestroyFileSystemList(FileSystemList
);
2454 FileSystemList
= NULL
;
2459 else if (wcscmp(FileSystemList
->Selected
->FileSystem
, L
"EXT2") == 0)
2461 wcscpy(PathBuffer
, SourceRootPath
.Buffer
);
2462 wcscat(PathBuffer
, L
"\\loader\\ext2.bin");
2464 DPRINT("Install EXT2 bootcode: %S ==> %S\n", PathBuffer
,
2465 DestinationRootPath
.Buffer
);
2466 Status
= InstallFat32BootCodeToDisk(PathBuffer
,
2467 DestinationRootPath
.Buffer
);
2469 if (!NT_SUCCESS(Status
))
2471 DPRINT1("InstallFat32BootCodeToDisk() failed with status 0x%08lx\n", Status
);
2472 /* FIXME: show an error dialog */
2473 DestroyFileSystemList(FileSystemList
);
2474 FileSystemList
= NULL
;
2478 else if (FileSystemList
->Selected
->FormatFunc
)
2480 DestroyFileSystemList(FileSystemList
);
2481 FileSystemList
= NULL
;
2486 CONSOLE_SetStatusText(" Done. Press any key ...");
2487 CONSOLE_ConInKey(Ir
);
2490 DestroyFileSystemList(FileSystemList
);
2491 FileSystemList
= NULL
;
2492 return INSTALL_DIRECTORY_PAGE
;
2496 return FORMAT_PARTITION_PAGE
;
2501 CheckFileSystemPage(PINPUT_RECORD Ir
)
2503 PFILE_SYSTEM_ITEM CurrentFileSystem
;
2504 WCHAR PathBuffer
[MAX_PATH
];
2505 CHAR Buffer
[MAX_PATH
];
2507 UCHAR PartNum
= PartitionList
->CurrentPartitionNumber
;
2509 /* FIXME: code duplicated in FormatPartitionPage */
2510 /* Set DestinationRootPath */
2511 RtlFreeUnicodeString(&DestinationRootPath
);
2512 swprintf(PathBuffer
,
2513 L
"\\Device\\Harddisk%lu\\Partition%lu",
2514 PartitionList
->CurrentDisk
->DiskNumber
,
2515 PartitionList
->CurrentPartition
->PartInfo
[PartNum
].PartitionNumber
);
2516 RtlCreateUnicodeString(&DestinationRootPath
, PathBuffer
);
2517 DPRINT("DestinationRootPath: %wZ\n", &DestinationRootPath
);
2519 /* Set SystemRootPath */
2520 RtlFreeUnicodeString(&SystemRootPath
);
2521 swprintf(PathBuffer
,
2522 L
"\\Device\\Harddisk%lu\\Partition%lu",
2523 PartitionList
->ActiveBootDisk
->DiskNumber
,
2524 PartitionList
->ActiveBootPartition
->PartInfo
[PartNum
].PartitionNumber
);
2525 RtlCreateUnicodeString(&SystemRootPath
, PathBuffer
);
2526 DPRINT("SystemRootPath: %wZ\n", &SystemRootPath
);
2528 CONSOLE_SetTextXY(6, 8, MUIGetString(STRING_CHECKINGPART
));
2530 CONSOLE_SetStatusText(MUIGetString(STRING_PLEASEWAIT
));
2532 /* WRONG: first filesystem is not necesseraly the one of the current partition! */
2533 CurrentFileSystem
= CONTAINING_RECORD(FileSystemList
->ListHead
.Flink
, FILE_SYSTEM_ITEM
, ListEntry
);
2535 if (!CurrentFileSystem
->ChkdskFunc
)
2538 "Setup is currently unable to check a partition formatted in %S.\n"
2540 " \x07 Press ENTER to continue Setup.\n"
2541 " \x07 Press F3 to quit Setup.",
2542 CurrentFileSystem
->FileSystem
);
2545 MUIGetString(STRING_QUITCONTINUE
),
2546 NULL
, POPUP_WAIT_NONE
);
2550 CONSOLE_ConInKey(Ir
);
2552 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00 &&
2553 Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
) /* F3 */
2555 if (ConfirmQuit(Ir
))
2558 return CHECK_FILE_SYSTEM_PAGE
;
2560 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== VK_RETURN
) /* ENTER */
2562 return INSTALL_DIRECTORY_PAGE
;
2568 Status
= ChkdskPartition(&DestinationRootPath
, CurrentFileSystem
);
2569 if (!NT_SUCCESS(Status
))
2571 DPRINT("ChkdskPartition() failed with status 0x%08lx\n", Status
);
2572 sprintf(Buffer
, "Setup failed to verify the selected partition.\n"
2573 "(Status 0x%08lx).\n", Status
);
2576 MUIGetString(STRING_REBOOTCOMPUTER
),
2577 Ir
, POPUP_WAIT_ENTER
);
2582 return INSTALL_DIRECTORY_PAGE
;
2588 InstallDirectoryPage1(PWCHAR InstallDir
, PDISKENTRY DiskEntry
, PPARTENTRY PartEntry
, UCHAR PartNum
)
2590 WCHAR PathBuffer
[MAX_PATH
];
2592 /* Create 'InstallPath' string */
2593 RtlFreeUnicodeString(&InstallPath
);
2594 RtlCreateUnicodeString(&InstallPath
,
2597 /* Create 'DestinationPath' string */
2598 RtlFreeUnicodeString(&DestinationPath
);
2599 wcscpy(PathBuffer
, DestinationRootPath
.Buffer
);
2601 if (InstallDir
[0] != L
'\\')
2602 wcscat(PathBuffer
, L
"\\");
2604 wcscat(PathBuffer
, InstallDir
);
2605 RtlCreateUnicodeString(&DestinationPath
, PathBuffer
);
2607 /* Create 'DestinationArcPath' */
2608 RtlFreeUnicodeString(&DestinationArcPath
);
2609 swprintf(PathBuffer
,
2610 L
"multi(0)disk(0)rdisk(%lu)partition(%lu)",
2611 DiskEntry
->BiosDiskNumber
,
2612 PartEntry
->PartInfo
[PartNum
].PartitionNumber
);
2614 if (InstallDir
[0] != L
'\\')
2615 wcscat(PathBuffer
, L
"\\");
2617 wcscat(PathBuffer
, InstallDir
);
2618 RtlCreateUnicodeString(&DestinationArcPath
, PathBuffer
);
2620 return(PREPARE_COPY_PAGE
);
2625 InstallDirectoryPage(PINPUT_RECORD Ir
)
2627 PDISKENTRY DiskEntry
;
2628 PPARTENTRY PartEntry
;
2629 WCHAR InstallDir
[51];
2634 if (PartitionList
== NULL
||
2635 PartitionList
->CurrentDisk
== NULL
||
2636 PartitionList
->CurrentPartition
== NULL
)
2638 /* FIXME: show an error dialog */
2642 DiskEntry
= PartitionList
->CurrentDisk
;
2643 PartEntry
= PartitionList
->CurrentPartition
;
2645 /* Search for 'DefaultPath' in the 'SetupData' section */
2646 if (!SetupFindFirstLineW (SetupInf
, L
"SetupData", L
"DefaultPath", &Context
))
2648 MUIDisplayError(ERROR_FIND_SETUPDATA
, Ir
, POPUP_WAIT_ENTER
);
2652 /* Read the 'DefaultPath' data */
2653 if (INF_GetData (&Context
, NULL
, &DefaultPath
))
2655 wcscpy(InstallDir
, DefaultPath
);
2659 wcscpy(InstallDir
, L
"\\ReactOS");
2662 Length
= wcslen(InstallDir
);
2663 CONSOLE_SetInputTextXY(8, 11, 51, InstallDir
);
2664 MUIDisplayPage(INSTALL_DIRECTORY_PAGE
);
2666 if (IsUnattendedSetup
)
2668 return(InstallDirectoryPage1 (InstallDir
, DiskEntry
, PartEntry
, PartitionList
->CurrentPartitionNumber
));
2673 CONSOLE_ConInKey(Ir
);
2675 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
2676 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
2678 if (ConfirmQuit(Ir
) == TRUE
)
2683 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2685 return (InstallDirectoryPage1 (InstallDir
, DiskEntry
, PartEntry
, PartitionList
->CurrentPartitionNumber
));
2687 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x08) /* BACKSPACE */
2692 InstallDir
[Length
] = 0;
2693 CONSOLE_SetInputTextXY(8, 11, 51, InstallDir
);
2696 else if (isprint(Ir
->Event
.KeyEvent
.uChar
.AsciiChar
))
2700 InstallDir
[Length
] = (WCHAR
)Ir
->Event
.KeyEvent
.uChar
.AsciiChar
;
2702 InstallDir
[Length
] = 0;
2703 CONSOLE_SetInputTextXY(8, 11, 51, InstallDir
);
2708 return(INSTALL_DIRECTORY_PAGE
);
2712 AddSectionToCopyQueueCab(HINF InfFile
,
2714 PWCHAR SourceCabinet
,
2715 PCUNICODE_STRING DestinationPath
,
2718 INFCONTEXT FilesContext
;
2719 INFCONTEXT DirContext
;
2721 PWCHAR FileKeyValue
;
2723 PWCHAR TargetFileName
;
2725 /* Search for the SectionName section */
2726 if (!SetupFindFirstLineW (InfFile
, SectionName
, NULL
, &FilesContext
))
2729 sprintf(Buffer
, MUIGetString(STRING_TXTSETUPFAILED
), SectionName
);
2730 PopupError(Buffer
, MUIGetString(STRING_REBOOTCOMPUTER
), Ir
, POPUP_WAIT_ENTER
);
2735 * Enumerate the files in the section
2736 * and add them to the file queue.
2740 /* Get source file name and target directory id */
2741 if (!INF_GetData (&FilesContext
, &FileKeyName
, &FileKeyValue
))
2743 /* FIXME: Handle error! */
2744 DPRINT1("INF_GetData() failed\n");
2748 /* Get optional target file name */
2749 if (!INF_GetDataField (&FilesContext
, 2, &TargetFileName
))
2750 TargetFileName
= NULL
;
2752 DPRINT ("FileKeyName: '%S' FileKeyValue: '%S'\n", FileKeyName
, FileKeyValue
);
2754 /* Lookup target directory */
2755 if (!SetupFindFirstLineW (InfFile
, L
"Directories", FileKeyValue
, &DirContext
))
2757 /* FIXME: Handle error! */
2758 DPRINT1("SetupFindFirstLine() failed\n");
2762 if (!INF_GetData (&DirContext
, NULL
, &DirKeyValue
))
2764 /* FIXME: Handle error! */
2765 DPRINT1("INF_GetData() failed\n");
2769 if (!SetupQueueCopy(SetupFileQueue
,
2771 SourceRootPath
.Buffer
,
2772 SourceRootDir
.Buffer
,
2777 /* FIXME: Handle error! */
2778 DPRINT1("SetupQueueCopy() failed\n");
2780 } while (SetupFindNextLine(&FilesContext
, &FilesContext
));
2786 AddSectionToCopyQueue(HINF InfFile
,
2788 PWCHAR SourceCabinet
,
2789 PCUNICODE_STRING DestinationPath
,
2792 INFCONTEXT FilesContext
;
2793 INFCONTEXT DirContext
;
2795 PWCHAR FileKeyValue
;
2797 PWCHAR TargetFileName
;
2800 return AddSectionToCopyQueueCab(InfFile
, L
"SourceFiles", SourceCabinet
, DestinationPath
, Ir
);
2802 /* Search for the SectionName section */
2803 if (!SetupFindFirstLineW (InfFile
, SectionName
, NULL
, &FilesContext
))
2806 sprintf(Buffer
, MUIGetString(STRING_TXTSETUPFAILED
), SectionName
);
2807 PopupError(Buffer
, MUIGetString(STRING_REBOOTCOMPUTER
), Ir
, POPUP_WAIT_ENTER
);
2812 * Enumerate the files in the section
2813 * and add them to the file queue.
2817 /* Get source file name and target directory id */
2818 if (!INF_GetData (&FilesContext
, &FileKeyName
, &FileKeyValue
))
2820 /* FIXME: Handle error! */
2821 DPRINT1("INF_GetData() failed\n");
2825 /* Get target directory id */
2826 if (!INF_GetDataField (&FilesContext
, 13, &FileKeyValue
))
2828 /* FIXME: Handle error! */
2829 DPRINT1("INF_GetData() failed\n");
2833 /* Get optional target file name */
2834 if (!INF_GetDataField (&FilesContext
, 11, &TargetFileName
))
2835 TargetFileName
= NULL
;
2836 else if (!*TargetFileName
)
2837 TargetFileName
= NULL
;
2839 DPRINT ("FileKeyName: '%S' FileKeyValue: '%S'\n", FileKeyName
, FileKeyValue
);
2841 /* Lookup target directory */
2842 if (!SetupFindFirstLineW (InfFile
, L
"Directories", FileKeyValue
, &DirContext
))
2844 /* FIXME: Handle error! */
2845 DPRINT1("SetupFindFirstLine() failed\n");
2849 if (!INF_GetData (&DirContext
, NULL
, &DirKeyValue
))
2851 /* FIXME: Handle error! */
2852 DPRINT1("INF_GetData() failed\n");
2856 if (!SetupQueueCopy(SetupFileQueue
,
2858 SourceRootPath
.Buffer
,
2859 SourceRootDir
.Buffer
,
2864 /* FIXME: Handle error! */
2865 DPRINT1("SetupQueueCopy() failed\n");
2867 } while (SetupFindNextLine(&FilesContext
, &FilesContext
));
2873 PrepareCopyPageInfFile(HINF InfFile
,
2874 PWCHAR SourceCabinet
,
2877 WCHAR PathBuffer
[MAX_PATH
];
2878 INFCONTEXT DirContext
;
2879 PWCHAR AdditionalSectionName
= NULL
;
2884 /* Add common files */
2885 if (!AddSectionToCopyQueue(InfFile
, L
"SourceDisksFiles", SourceCabinet
, &DestinationPath
, Ir
))
2888 /* Add specific files depending of computer type */
2889 if (SourceCabinet
== NULL
)
2891 if (!ProcessComputerFiles(InfFile
, ComputerList
, &AdditionalSectionName
))
2894 if (AdditionalSectionName
)
2896 if (!AddSectionToCopyQueue(InfFile
, AdditionalSectionName
, SourceCabinet
, &DestinationPath
, Ir
))
2901 /* Create directories */
2905 * Install directories like '\reactos\test' are not handled yet.
2908 /* Get destination path */
2909 wcscpy(PathBuffer
, DestinationPath
.Buffer
);
2911 /* Remove trailing backslash */
2912 Length
= wcslen(PathBuffer
);
2913 if ((Length
> 0) && (PathBuffer
[Length
- 1] == '\\'))
2915 PathBuffer
[Length
- 1] = 0;
2918 /* Create the install directory */
2919 Status
= SetupCreateDirectory(PathBuffer
);
2920 if (!NT_SUCCESS(Status
) && Status
!= STATUS_OBJECT_NAME_COLLISION
)
2922 DPRINT("Creating directory '%S' failed: Status = 0x%08lx", PathBuffer
, Status
);
2923 MUIDisplayError(ERROR_CREATE_INSTALL_DIR
, Ir
, POPUP_WAIT_ENTER
);
2927 /* Search for the 'Directories' section */
2928 if (!SetupFindFirstLineW(InfFile
, L
"Directories", NULL
, &DirContext
))
2932 MUIDisplayError(ERROR_CABINET_SECTION
, Ir
, POPUP_WAIT_ENTER
);
2936 MUIDisplayError(ERROR_TXTSETUP_SECTION
, Ir
, POPUP_WAIT_ENTER
);
2942 /* Enumerate the directory values and create the subdirectories */
2945 if (!INF_GetData (&DirContext
, NULL
, &KeyValue
))
2951 if (KeyValue
[0] == L
'\\' && KeyValue
[1] != 0)
2953 DPRINT("Absolute Path: '%S'\n", KeyValue
);
2955 wcscpy(PathBuffer
, DestinationRootPath
.Buffer
);
2956 wcscat(PathBuffer
, KeyValue
);
2958 DPRINT("FullPath: '%S'\n", PathBuffer
);
2960 else if (KeyValue
[0] != L
'\\')
2962 DPRINT("RelativePath: '%S'\n", KeyValue
);
2963 wcscpy(PathBuffer
, DestinationPath
.Buffer
);
2964 wcscat(PathBuffer
, L
"\\");
2965 wcscat(PathBuffer
, KeyValue
);
2967 DPRINT("FullPath: '%S'\n", PathBuffer
);
2969 Status
= SetupCreateDirectory(PathBuffer
);
2970 if (!NT_SUCCESS(Status
) && Status
!= STATUS_OBJECT_NAME_COLLISION
)
2972 DPRINT("Creating directory '%S' failed: Status = 0x%08lx", PathBuffer
, Status
);
2973 MUIDisplayError(ERROR_CREATE_DIR
, Ir
, POPUP_WAIT_ENTER
);
2977 } while (SetupFindNextLine (&DirContext
, &DirContext
));
2983 PrepareCopyPage(PINPUT_RECORD Ir
)
2986 WCHAR PathBuffer
[MAX_PATH
];
2987 INFCONTEXT CabinetsContext
;
2993 MUIDisplayPage(PREPARE_COPY_PAGE
);
2995 /* Create the file queue */
2996 SetupFileQueue
= SetupOpenFileQueue();
2997 if (SetupFileQueue
== NULL
)
2999 MUIDisplayError(ERROR_COPY_QUEUE
, Ir
, POPUP_WAIT_ENTER
);
3003 if (!PrepareCopyPageInfFile(SetupInf
, NULL
, Ir
))
3008 /* Search for the 'Cabinets' section */
3009 if (!SetupFindFirstLineW (SetupInf
, L
"Cabinets", NULL
, &CabinetsContext
))
3011 return FILE_COPY_PAGE
;
3015 * Enumerate the directory values in the 'Cabinets'
3016 * section and parse their inf files.
3020 if (!INF_GetData (&CabinetsContext
, NULL
, &KeyValue
))
3023 wcscpy(PathBuffer
, SourcePath
.Buffer
);
3024 wcscat(PathBuffer
, L
"\\");
3025 wcscat(PathBuffer
, KeyValue
);
3028 CabinetInitialize();
3029 CabinetSetEventHandlers(NULL
, NULL
, NULL
);
3030 CabinetSetCabinetName(PathBuffer
);
3032 if (CabinetOpen() == CAB_STATUS_SUCCESS
)
3034 DPRINT("Cabinet %S\n", CabinetGetCabinetName());
3036 InfFileData
= CabinetGetCabinetReservedArea(&InfFileSize
);
3037 if (InfFileData
== NULL
)
3039 MUIDisplayError(ERROR_CABINET_SCRIPT
, Ir
, POPUP_WAIT_ENTER
);
3045 DPRINT("Cannot open cabinet: %S.\n", CabinetGetCabinetName());
3046 MUIDisplayError(ERROR_CABINET_MISSING
, Ir
, POPUP_WAIT_ENTER
);
3050 InfHandle
= INF_OpenBufferedFileA((CHAR
*) InfFileData
,
3057 if (InfHandle
== INVALID_HANDLE_VALUE
)
3059 MUIDisplayError(ERROR_INVALID_CABINET_INF
, Ir
, POPUP_WAIT_ENTER
);
3065 if (!PrepareCopyPageInfFile(InfHandle
, KeyValue
, Ir
))
3070 } while (SetupFindNextLine (&CabinetsContext
, &CabinetsContext
));
3072 return FILE_COPY_PAGE
;
3077 SetupUpdateMemoryInfo(IN PCOPYCONTEXT CopyContext
,
3080 SYSTEM_PERFORMANCE_INFORMATION PerfInfo
;
3082 /* Get the memory information from the system */
3083 NtQuerySystemInformation(SystemPerformanceInformation
,
3088 /* Check if this is initial setup */
3091 /* Set maximum limits to be total RAM pages */
3092 ProgressSetStepCount(CopyContext
->MemoryBars
[0], PerfInfo
.CommitLimit
);
3093 ProgressSetStepCount(CopyContext
->MemoryBars
[1], PerfInfo
.CommitLimit
);
3094 ProgressSetStepCount(CopyContext
->MemoryBars
[2], PerfInfo
.CommitLimit
);
3097 /* Set current values */
3098 ProgressSetStep(CopyContext
->MemoryBars
[0], PerfInfo
.PagedPoolPages
+ PerfInfo
.NonPagedPoolPages
);
3099 ProgressSetStep(CopyContext
->MemoryBars
[1], PerfInfo
.ResidentSystemCachePage
);
3100 ProgressSetStep(CopyContext
->MemoryBars
[2], PerfInfo
.AvailablePages
);
3103 static UINT CALLBACK
3104 FileCopyCallback(PVOID Context
,
3109 PCOPYCONTEXT CopyContext
;
3111 CopyContext
= (PCOPYCONTEXT
)Context
;
3113 switch (Notification
)
3115 case SPFILENOTIFY_STARTSUBQUEUE
:
3116 CopyContext
->TotalOperations
= (ULONG
)Param2
;
3117 ProgressSetStepCount(CopyContext
->ProgressBar
,
3118 CopyContext
->TotalOperations
);
3119 SetupUpdateMemoryInfo(CopyContext
, TRUE
);
3122 case SPFILENOTIFY_STARTCOPY
:
3123 /* Display copy message */
3124 CONSOLE_SetStatusTextAutoFitX (45 , MUIGetString(STRING_COPYING
), (PWSTR
)Param1
);
3125 SetupUpdateMemoryInfo(CopyContext
, FALSE
);
3128 case SPFILENOTIFY_ENDCOPY
:
3129 CopyContext
->CompletedOperations
++;
3130 ProgressNextStep(CopyContext
->ProgressBar
);
3131 SetupUpdateMemoryInfo(CopyContext
, FALSE
);
3140 FileCopyPage(PINPUT_RECORD Ir
)
3142 COPYCONTEXT CopyContext
;
3143 unsigned int mem_bar_width
;
3145 MUIDisplayPage(FILE_COPY_PAGE
);
3147 /* Create context for the copy process */
3148 CopyContext
.DestinationRootPath
= DestinationRootPath
.Buffer
;
3149 CopyContext
.InstallPath
= InstallPath
.Buffer
;
3150 CopyContext
.TotalOperations
= 0;
3151 CopyContext
.CompletedOperations
= 0;
3153 /* Create the progress bar as well */
3154 CopyContext
.ProgressBar
= CreateProgressBar(13,
3161 MUIGetString(STRING_SETUPCOPYINGFILES
));
3163 // fit memory bars to screen width, distribute them uniform
3164 mem_bar_width
= (xScreen
- 26) / 5;
3165 mem_bar_width
-= mem_bar_width
% 2; // make even
3166 /* ATTENTION: The following progress bars are debug stuff, which should not be translated!! */
3167 /* Create the paged pool progress bar */
3168 CopyContext
.MemoryBars
[0] = CreateProgressBar(13,
3177 /* Create the non paged pool progress bar */
3178 CopyContext
.MemoryBars
[1] = CreateProgressBar((xScreen
/ 2)- (mem_bar_width
/ 2),
3180 (xScreen
/ 2) + (mem_bar_width
/ 2),
3182 (xScreen
/ 2)- (mem_bar_width
/ 2),
3187 /* Create the global memory progress bar */
3188 CopyContext
.MemoryBars
[2] = CreateProgressBar(xScreen
- 13 - mem_bar_width
,
3192 xScreen
- 13 - mem_bar_width
,
3197 /* Do the file copying */
3198 SetupCommitFileQueueW(NULL
,
3203 /* If we get here, we're done, so cleanup the queue and progress bar */
3204 SetupCloseFileQueue(SetupFileQueue
);
3205 DestroyProgressBar(CopyContext
.ProgressBar
);
3206 DestroyProgressBar(CopyContext
.MemoryBars
[0]);
3207 DestroyProgressBar(CopyContext
.MemoryBars
[1]);
3208 DestroyProgressBar(CopyContext
.MemoryBars
[2]);
3210 /* Go display the next page */
3211 return REGISTRY_PAGE
;
3215 RegistryPage(PINPUT_RECORD Ir
)
3217 INFCONTEXT InfContext
;
3224 MUIDisplayPage(REGISTRY_PAGE
);
3226 if (RepairUpdateFlag
)
3228 return SUCCESS_PAGE
;
3231 if (!SetInstallPathValue(&DestinationPath
))
3233 DPRINT("SetInstallPathValue() failed\n");
3234 MUIDisplayError(ERROR_INITIALIZE_REGISTRY
, Ir
, POPUP_WAIT_ENTER
);
3238 /* Create the default hives */
3240 Status
= NtInitializeRegistry(CM_BOOT_FLAG_SETUP
);
3241 if (!NT_SUCCESS(Status
))
3243 DPRINT("NtInitializeRegistry() failed (Status %lx)\n", Status
);
3244 MUIDisplayError(ERROR_CREATE_HIVE
, Ir
, POPUP_WAIT_ENTER
);
3248 RegInitializeRegistry();
3251 /* Update registry */
3252 CONSOLE_SetStatusText(MUIGetString(STRING_REGHIVEUPDATE
));
3254 if (!SetupFindFirstLineW(SetupInf
, L
"HiveInfs.Install", NULL
, &InfContext
))
3256 DPRINT1("SetupFindFirstLine() failed\n");
3257 MUIDisplayError(ERROR_FIND_REGISTRY
, Ir
, POPUP_WAIT_ENTER
);
3263 INF_GetDataField (&InfContext
, 0, &Action
);
3264 INF_GetDataField (&InfContext
, 1, &File
);
3265 INF_GetDataField (&InfContext
, 2, &Section
);
3267 DPRINT("Action: %S File: %S Section %S\n", Action
, File
, Section
);
3269 if (Action
== NULL
) break; // Hackfix
3271 if (!_wcsicmp (Action
, L
"AddReg"))
3275 else if (!_wcsicmp (Action
, L
"DelReg"))
3284 CONSOLE_SetStatusText(MUIGetString(STRING_IMPORTFILE
), File
);
3286 if (!ImportRegistryFile(File
, Section
, LanguageId
, Delete
))
3288 DPRINT("Importing %S failed\n", File
);
3290 MUIDisplayError(ERROR_IMPORT_HIVE
, Ir
, POPUP_WAIT_ENTER
);
3293 } while (SetupFindNextLine (&InfContext
, &InfContext
));
3295 /* Update display registry settings */
3296 CONSOLE_SetStatusText(MUIGetString(STRING_DISPLAYETTINGSUPDATE
));
3297 if (!ProcessDisplayRegistry(SetupInf
, DisplayList
))
3299 MUIDisplayError(ERROR_UPDATE_DISPLAY_SETTINGS
, Ir
, POPUP_WAIT_ENTER
);
3303 /* Set the locale */
3304 CONSOLE_SetStatusText(MUIGetString(STRING_LOCALESETTINGSUPDATE
));
3305 if (!ProcessLocaleRegistry(LanguageList
))
3307 MUIDisplayError(ERROR_UPDATE_LOCALESETTINGS
, Ir
, POPUP_WAIT_ENTER
);
3311 /* Add keyboard layouts */
3312 CONSOLE_SetStatusText(MUIGetString(STRING_ADDKBLAYOUTS
));
3313 if (!AddKeyboardLayouts())
3315 MUIDisplayError(ERROR_ADDING_KBLAYOUTS
, Ir
, POPUP_WAIT_ENTER
);
3321 if (!SetGeoID(MUIGetGeoID()))
3323 MUIDisplayError(ERROR_UPDATE_GEOID
, Ir
, POPUP_WAIT_ENTER
);
3327 if (!IsUnattendedSetup
){
3329 /* Update keyboard layout settings */
3330 CONSOLE_SetStatusText(MUIGetString(STRING_KEYBOARDSETTINGSUPDATE
));
3331 if (!ProcessKeyboardLayoutRegistry(LayoutList
))
3333 MUIDisplayError(ERROR_UPDATE_KBSETTINGS
, Ir
, POPUP_WAIT_ENTER
);
3337 /* Add codepage information to registry */
3338 CONSOLE_SetStatusText(MUIGetString(STRING_CODEPAGEINFOUPDATE
));
3341 MUIDisplayError(ERROR_ADDING_CODEPAGE
, Ir
, POPUP_WAIT_ENTER
);
3345 /* Update the mounted devices list */
3346 SetMountedDeviceValues(PartitionList
);
3348 CONSOLE_SetStatusText(MUIGetString(STRING_DONE
));
3350 return BOOT_LOADER_PAGE
;
3355 BootLoaderPage(PINPUT_RECORD Ir
)
3357 UCHAR PartitionType
;
3358 BOOLEAN InstallOnFloppy
;
3361 CONSOLE_SetStatusText(MUIGetString(STRING_PLEASEWAIT
));
3363 PartitionType
= PartitionList
->ActiveBootPartition
->
3364 PartInfo
[PartitionList
->ActiveBootPartitionNumber
].PartitionType
;
3366 if (IsUnattendedSetup
)
3368 if (UnattendMBRInstallType
== 0) /* skip MBR installation */
3370 return SUCCESS_PAGE
;
3372 else if (UnattendMBRInstallType
== 1) /* install on floppy */
3374 return BOOT_LOADER_FLOPPY_PAGE
;
3378 if (PartitionType
== PARTITION_ENTRY_UNUSED
)
3380 DPRINT("Error: active partition invalid (unused)\n");
3381 InstallOnFloppy
= TRUE
;
3383 else if (PartitionType
== 0x0A)
3385 /* OS/2 boot manager partition */
3386 DPRINT("Found OS/2 boot manager partition\n");
3387 InstallOnFloppy
= TRUE
;
3389 else if (PartitionType
== 0x83)
3391 /* Linux ext2 partition */
3392 DPRINT("Found Linux ext2 partition\n");
3393 InstallOnFloppy
= TRUE
;
3395 else if (PartitionType
== PARTITION_IFS
)
3397 /* NTFS partition */
3398 DPRINT("Found NTFS partition\n");
3399 InstallOnFloppy
= TRUE
;
3401 else if ((PartitionType
== PARTITION_FAT_12
) ||
3402 (PartitionType
== PARTITION_FAT_16
) ||
3403 (PartitionType
== PARTITION_HUGE
) ||
3404 (PartitionType
== PARTITION_XINT13
) ||
3405 (PartitionType
== PARTITION_FAT32
) ||
3406 (PartitionType
== PARTITION_FAT32_XINT13
))
3408 DPRINT("Found FAT partition\n");
3409 InstallOnFloppy
= FALSE
;
3413 /* Unknown partition */
3414 DPRINT("Unknown partition found\n");
3415 InstallOnFloppy
= TRUE
;
3418 if (InstallOnFloppy
== TRUE
)
3420 return BOOT_LOADER_FLOPPY_PAGE
;
3423 /* Unattended install on hdd? */
3424 if (IsUnattendedSetup
&& UnattendMBRInstallType
== 2)
3426 return BOOT_LOADER_HARDDISK_PAGE
;
3429 MUIDisplayPage(BOOT_LOADER_PAGE
);
3430 CONSOLE_InvertTextXY(8, Line
, 60, 1);
3434 CONSOLE_ConInKey(Ir
);
3436 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
3437 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
)) /* DOWN */
3439 CONSOLE_NormalTextXY(8, Line
, 60, 1);
3442 if (Line
<12) Line
=14;
3443 if (Line
>14) Line
=12;
3445 CONSOLE_InvertTextXY(8, Line
, 60, 1);
3447 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
3448 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_UP
)) /* UP */
3450 CONSOLE_NormalTextXY(8, Line
, 60, 1);
3453 if (Line
<12) Line
=14;
3454 if (Line
>14) Line
=12;
3456 CONSOLE_InvertTextXY(8, Line
, 60, 1);
3458 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
3459 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
3461 if (ConfirmQuit(Ir
) == TRUE
)
3466 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
3470 return BOOT_LOADER_HARDDISK_PAGE
;
3472 else if (Line
== 13)
3474 return BOOT_LOADER_FLOPPY_PAGE
;
3476 else if (Line
== 14)
3478 return SUCCESS_PAGE
;
3481 return BOOT_LOADER_PAGE
;
3485 return BOOT_LOADER_PAGE
;
3490 BootLoaderFloppyPage(PINPUT_RECORD Ir
)
3494 MUIDisplayPage(BOOT_LOADER_FLOPPY_PAGE
);
3496 // SetStatusText(" Please wait...");
3500 CONSOLE_ConInKey(Ir
);
3502 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
3503 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
3505 if (ConfirmQuit(Ir
) == TRUE
)
3510 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
3512 if (DoesFileExist(L
"\\Device\\Floppy0", L
"\\") == FALSE
)
3514 MUIDisplayError(ERROR_NO_FLOPPY
, Ir
, POPUP_WAIT_ENTER
);
3515 return BOOT_LOADER_FLOPPY_PAGE
;
3518 Status
= InstallFatBootcodeToFloppy(&SourceRootPath
, &DestinationArcPath
);
3519 if (!NT_SUCCESS(Status
))
3521 /* Print error message */
3522 return BOOT_LOADER_FLOPPY_PAGE
;
3525 return SUCCESS_PAGE
;
3529 return BOOT_LOADER_FLOPPY_PAGE
;
3534 BootLoaderHarddiskPage(PINPUT_RECORD Ir
)
3536 UCHAR PartitionType
;
3539 PartitionType
= PartitionList
->ActiveBootPartition
->
3540 PartInfo
[PartitionList
->ActiveBootPartitionNumber
].PartitionType
;
3541 if ((PartitionType
== PARTITION_FAT_12
) ||
3542 (PartitionType
== PARTITION_FAT_16
) ||
3543 (PartitionType
== PARTITION_HUGE
) ||
3544 (PartitionType
== PARTITION_XINT13
) ||
3545 (PartitionType
== PARTITION_FAT32
) ||
3546 (PartitionType
== PARTITION_FAT32_XINT13
))
3548 Status
= InstallFatBootcodeToPartition(&SystemRootPath
,
3550 &DestinationArcPath
,
3552 if (!NT_SUCCESS(Status
))
3554 MUIDisplayError(ERROR_INSTALL_BOOTCODE
, Ir
, POPUP_WAIT_ENTER
);
3558 return SUCCESS_PAGE
;
3562 MUIDisplayError(ERROR_WRITE_BOOT
, Ir
, POPUP_WAIT_ENTER
);
3566 return BOOT_LOADER_HARDDISK_PAGE
;
3571 QuitPage(PINPUT_RECORD Ir
)
3573 MUIDisplayPage(QUIT_PAGE
);
3575 /* Destroy partition list */
3576 if (PartitionList
!= NULL
)
3578 DestroyPartitionList (PartitionList
);
3579 PartitionList
= NULL
;
3582 /* Destroy filesystem list */
3583 if (FileSystemList
!= NULL
)
3585 DestroyFileSystemList (FileSystemList
);
3586 FileSystemList
= NULL
;
3589 /* Destroy computer settings list */
3590 if (ComputerList
!= NULL
)
3592 DestroyGenericList(ComputerList
, TRUE
);
3593 ComputerList
= NULL
;
3596 /* Destroy display settings list */
3597 if (DisplayList
!= NULL
)
3599 DestroyGenericList(DisplayList
, TRUE
);
3603 /* Destroy keyboard settings list */
3604 if (KeyboardList
!= NULL
)
3606 DestroyGenericList(KeyboardList
, TRUE
);
3607 KeyboardList
= NULL
;
3610 /* Destroy keyboard layout list */
3611 if (LayoutList
!= NULL
)
3613 DestroyGenericList(LayoutList
, TRUE
);
3617 if (LanguageList
!= NULL
)
3619 DestroyGenericList(LanguageList
, FALSE
);
3620 LanguageList
= NULL
;
3623 CONSOLE_SetStatusText(MUIGetString(STRING_REBOOTCOMPUTER2
));
3627 CONSOLE_ConInKey(Ir
);
3629 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
3638 SuccessPage(PINPUT_RECORD Ir
)
3640 MUIDisplayPage(SUCCESS_PAGE
);
3642 if (IsUnattendedSetup
)
3649 CONSOLE_ConInKey(Ir
);
3651 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
3660 FlushPage(PINPUT_RECORD Ir
)
3662 MUIDisplayPage(FLUSH_PAGE
);
3668 PnpEventThread(IN LPVOID lpParameter
);
3678 NtQuerySystemTime(&Time
);
3680 Status
= RtlCreateUserThread(NtCurrentProcess(), NULL
, TRUE
, 0, 0, 0, PnpEventThread
, &SetupInf
, &hPnpThread
, NULL
);
3681 if (!NT_SUCCESS(Status
))
3682 hPnpThread
= INVALID_HANDLE_VALUE
;
3684 if (!CONSOLE_Init())
3686 PrintString(MUIGetString(STRING_CONSOLEFAIL1
));
3687 PrintString(MUIGetString(STRING_CONSOLEFAIL2
));
3688 PrintString(MUIGetString(STRING_CONSOLEFAIL3
));
3690 /* Raise a hard error (crash the system/BSOD) */
3691 NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED
,
3695 /* Initialize global unicode strings */
3696 RtlInitUnicodeString(&SourcePath
, NULL
);
3697 RtlInitUnicodeString(&SourceRootPath
, NULL
);
3698 RtlInitUnicodeString(&SourceRootDir
, NULL
);
3699 RtlInitUnicodeString(&InstallPath
, NULL
);
3700 RtlInitUnicodeString(&DestinationPath
, NULL
);
3701 RtlInitUnicodeString(&DestinationArcPath
, NULL
);
3702 RtlInitUnicodeString(&DestinationRootPath
, NULL
);
3703 RtlInitUnicodeString(&SystemRootPath
, NULL
);
3705 /* Hide the cursor */
3706 CONSOLE_SetCursorType(TRUE
, FALSE
);
3709 while (Page
!= REBOOT_PAGE
)
3711 CONSOLE_ClearScreen();
3714 //CONSOLE_SetUnderlinedTextXY(4, 3, " ReactOS " KERNEL_VERSION_STR " Setup ");
3721 Page
= SetupStartPage(&Ir
);
3726 Page
= LanguagePage(&Ir
);
3731 Page
= LicensePage(&Ir
);
3736 Page
= IntroPage(&Ir
);
3740 case INSTALL_INTRO_PAGE
:
3741 Page
= InstallIntroPage(&Ir
);
3745 case SCSI_CONTROLLER_PAGE
:
3746 Page
= ScsiControllerPage(&Ir
);
3751 case OEM_DRIVER_PAGE
:
3752 Page
= OemDriverPage(&Ir
);
3756 case DEVICE_SETTINGS_PAGE
:
3757 Page
= DeviceSettingsPage(&Ir
);
3760 case COMPUTER_SETTINGS_PAGE
:
3761 Page
= ComputerSettingsPage(&Ir
);
3764 case DISPLAY_SETTINGS_PAGE
:
3765 Page
= DisplaySettingsPage(&Ir
);
3768 case KEYBOARD_SETTINGS_PAGE
:
3769 Page
= KeyboardSettingsPage(&Ir
);
3772 case LAYOUT_SETTINGS_PAGE
:
3773 Page
= LayoutSettingsPage(&Ir
);
3776 case SELECT_PARTITION_PAGE
:
3777 Page
= SelectPartitionPage(&Ir
);
3780 case CREATE_PARTITION_PAGE
:
3781 Page
= CreatePartitionPage(&Ir
);
3784 case DELETE_PARTITION_PAGE
:
3785 Page
= DeletePartitionPage(&Ir
);
3788 case SELECT_FILE_SYSTEM_PAGE
:
3789 Page
= SelectFileSystemPage(&Ir
);
3792 case FORMAT_PARTITION_PAGE
:
3793 Page
= (PAGE_NUMBER
) FormatPartitionPage(&Ir
);
3796 case CHECK_FILE_SYSTEM_PAGE
:
3797 Page
= (PAGE_NUMBER
) CheckFileSystemPage(&Ir
);
3800 case INSTALL_DIRECTORY_PAGE
:
3801 Page
= InstallDirectoryPage(&Ir
);
3804 case PREPARE_COPY_PAGE
:
3805 Page
= PrepareCopyPage(&Ir
);
3808 case FILE_COPY_PAGE
:
3809 Page
= FileCopyPage(&Ir
);
3813 Page
= RegistryPage(&Ir
);
3816 case BOOT_LOADER_PAGE
:
3817 Page
= BootLoaderPage(&Ir
);
3820 case BOOT_LOADER_FLOPPY_PAGE
:
3821 Page
= BootLoaderFloppyPage(&Ir
);
3824 case BOOT_LOADER_HARDDISK_PAGE
:
3825 Page
= BootLoaderHarddiskPage(&Ir
);
3829 case REPAIR_INTRO_PAGE
:
3830 Page
= RepairIntroPage(&Ir
);
3834 Page
= SuccessPage(&Ir
);
3838 Page
= FlushPage(&Ir
);
3842 Page
= QuitPage(&Ir
);
3852 /* Avoid bugcheck */
3853 Time
.QuadPart
+= 50000000;
3854 NtDelayExecution(FALSE
, &Time
);
3857 NtShutdownSystem(ShutdownReboot
);
3858 NtTerminateProcess(NtCurrentProcess(), 0);
3865 NtProcessStartup(PPEB Peb
)
3867 RtlNormalizeProcessParams(Peb
->ProcessParameters
);
3869 ProcessHeap
= Peb
->ProcessHeap
;
3870 INF_SetHeap(ProcessHeap
);
3873 #endif /* __REACTOS__ */