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 /* required free disk space in MB */
35 #define MINIMUMDISKSIZE 350
37 /* GLOBALS ******************************************************************/
40 UNICODE_STRING SourceRootPath
;
41 UNICODE_STRING SourceRootDir
;
42 UNICODE_STRING SourcePath
;
43 BOOLEAN IsUnattendedSetup
= FALSE
;
44 LONG UnattendDestinationDiskNumber
;
45 LONG UnattendDestinationPartitionNumber
;
46 LONG UnattendMBRInstallType
= -1;
47 LONG UnattendFormatPartition
= 0;
48 LONG AutoPartition
= 0;
49 WCHAR UnattendInstallationDirectory
[MAX_PATH
];
50 PWCHAR SelectedLanguageId
;
52 WCHAR DefaultLanguage
[20];
53 WCHAR DefaultKBLayout
[20];
54 BOOLEAN RepairUpdateFlag
= FALSE
;
55 HANDLE hPnpThread
= INVALID_HANDLE_VALUE
;
57 /* LOCALS *******************************************************************/
59 static PPARTLIST PartitionList
= NULL
;
61 static PFILE_SYSTEM_LIST FileSystemList
= NULL
;
63 static UNICODE_STRING InstallPath
;
65 /* Path to the install directory */
66 static UNICODE_STRING DestinationPath
;
67 static UNICODE_STRING DestinationArcPath
;
68 static UNICODE_STRING DestinationRootPath
;
70 /* Path to the active partition (boot manager) */
71 static UNICODE_STRING SystemRootPath
;
75 static HSPFILEQ SetupFileQueue
= NULL
;
77 static BOOLEAN WarnLinuxPartitions
= TRUE
;
79 static PGENERIC_LIST ComputerList
= NULL
;
80 static PGENERIC_LIST DisplayList
= NULL
;
81 static PGENERIC_LIST KeyboardList
= NULL
;
82 static PGENERIC_LIST LayoutList
= NULL
;
83 static PGENERIC_LIST LanguageList
= NULL
;
85 static LANGID LanguageId
= 0;
87 /* FUNCTIONS ****************************************************************/
90 PrintString(char* fmt
,...)
94 UNICODE_STRING UnicodeString
;
95 ANSI_STRING AnsiString
;
98 vsprintf(buffer
, fmt
, ap
);
101 RtlInitAnsiString(&AnsiString
, buffer
);
102 RtlAnsiStringToUnicodeString(&UnicodeString
, &AnsiString
, TRUE
);
103 NtDisplayString(&UnicodeString
);
104 RtlFreeUnicodeString(&UnicodeString
);
118 /* draw upper left corner */
121 FillConsoleOutputCharacterA(
128 /* draw upper edge */
131 FillConsoleOutputCharacterA(
138 /* draw upper right corner */
139 coPos
.X
= xLeft
+ Width
- 1;
141 FillConsoleOutputCharacterA(
148 /* Draw right edge, inner space and left edge */
149 for (coPos
.Y
= yTop
+ 1; coPos
.Y
< yTop
+ Height
- 1; coPos
.Y
++)
152 FillConsoleOutputCharacterA(
160 FillConsoleOutputCharacterA(
167 coPos
.X
= xLeft
+ Width
- 1;
168 FillConsoleOutputCharacterA(
176 /* draw lower left corner */
178 coPos
.Y
= yTop
+ Height
- 1;
179 FillConsoleOutputCharacterA(
186 /* draw lower edge */
188 coPos
.Y
= yTop
+ Height
- 1;
189 FillConsoleOutputCharacterA(
196 /* draw lower right corner */
197 coPos
.X
= xLeft
+ Width
- 1;
198 coPos
.Y
= yTop
+ Height
- 1;
199 FillConsoleOutputCharacterA(
208 PopupError(PCCH Text
,
226 /* Count text lines and longest line */
233 p
= strchr(pnext
, '\n');
237 Length
= strlen(pnext
);
242 Length
= (ULONG
)(p
- pnext
);
248 if (Length
> MaxLength
)
251 if (LastLine
== TRUE
)
257 /* Check length of status line */
260 Length
= strlen(Status
);
262 if (Length
> MaxLength
)
266 Width
= MaxLength
+ 4;
272 yTop
= (yScreen
- Height
) / 2;
273 xLeft
= (xScreen
- Width
) / 2;
276 /* Set screen attributes */
278 for (coPos
.Y
= yTop
; coPos
.Y
< yTop
+ Height
; coPos
.Y
++)
280 FillConsoleOutputAttribute(StdOutput
,
281 FOREGROUND_RED
| BACKGROUND_WHITE
,
287 DrawBox(xLeft
, yTop
, Width
, Height
);
289 /* Print message text */
294 p
= strchr(pnext
, '\n');
298 Length
= strlen(pnext
);
303 Length
= (ULONG
)(p
- pnext
);
310 WriteConsoleOutputCharacterA(StdOutput
,
317 if (LastLine
== TRUE
)
324 /* Print separator line and status text */
327 coPos
.Y
= yTop
+ Height
- 3;
329 FillConsoleOutputCharacterA(StdOutput
,
336 FillConsoleOutputCharacterA(StdOutput
,
342 coPos
.X
= xLeft
+ Width
- 1;
343 FillConsoleOutputCharacterA(StdOutput
,
351 WriteConsoleOutputCharacterA(StdOutput
,
353 min(strlen(Status
), (SIZE_T
)Width
- 4),
358 if (WaitEvent
== POPUP_WAIT_NONE
)
363 CONSOLE_ConInKey(Ir
);
365 if (WaitEvent
== POPUP_WAIT_ANY_KEY
||
366 Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D)
378 * FALSE: Don't quit setup.
381 ConfirmQuit(PINPUT_RECORD Ir
)
384 MUIDisplayError(ERROR_NOT_INSTALLED
, NULL
, POPUP_WAIT_NONE
);
388 CONSOLE_ConInKey(Ir
);
390 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
391 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
396 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
408 CheckUnattendedSetup(VOID
)
410 WCHAR UnattendInfPath
[MAX_PATH
];
417 if (DoesFileExist(SourcePath
.Buffer
, L
"unattend.inf") == FALSE
)
419 DPRINT("Does not exist: %S\\%S\n", SourcePath
.Buffer
, L
"unattend.inf");
423 wcscpy(UnattendInfPath
, SourcePath
.Buffer
);
424 wcscat(UnattendInfPath
, L
"\\unattend.inf");
426 /* Load 'unattend.inf' from install media. */
427 UnattendInf
= SetupOpenInfFileW(UnattendInfPath
,
433 if (UnattendInf
== INVALID_HANDLE_VALUE
)
435 DPRINT("SetupOpenInfFileW() failed\n");
439 /* Open 'Unattend' section */
440 if (!SetupFindFirstLineW(UnattendInf
, L
"Unattend", L
"Signature", &Context
))
442 DPRINT("SetupFindFirstLineW() failed for section 'Unattend'\n");
443 SetupCloseInfFile(UnattendInf
);
447 /* Get pointer 'Signature' key */
448 if (!INF_GetData(&Context
, NULL
, &Value
))
450 DPRINT("INF_GetData() failed for key 'Signature'\n");
451 SetupCloseInfFile(UnattendInf
);
455 /* Check 'Signature' string */
456 if (_wcsicmp(Value
, L
"$ReactOS$") != 0)
458 DPRINT("Signature not $ReactOS$\n");
459 SetupCloseInfFile(UnattendInf
);
463 /* Check if Unattend setup is enabled */
464 if (!SetupFindFirstLineW(UnattendInf
, L
"Unattend", L
"UnattendSetupEnabled", &Context
))
466 DPRINT("Can't find key 'UnattendSetupEnabled'\n");
467 SetupCloseInfFile(UnattendInf
);
471 if (!INF_GetData(&Context
, NULL
, &Value
))
473 DPRINT("Can't read key 'UnattendSetupEnabled'\n");
474 SetupCloseInfFile(UnattendInf
);
478 if (_wcsicmp(Value
, L
"yes") != 0)
480 DPRINT("Unattend setup is disabled by 'UnattendSetupEnabled' key!\n");
481 SetupCloseInfFile(UnattendInf
);
485 /* Search for 'DestinationDiskNumber' in the 'Unattend' section */
486 if (!SetupFindFirstLineW(UnattendInf
, L
"Unattend", L
"DestinationDiskNumber", &Context
))
488 DPRINT("SetupFindFirstLine() failed for key 'DestinationDiskNumber'\n");
489 SetupCloseInfFile(UnattendInf
);
493 if (!SetupGetIntField(&Context
, 1, &IntValue
))
495 DPRINT("SetupGetIntField() failed for key 'DestinationDiskNumber'\n");
496 SetupCloseInfFile(UnattendInf
);
500 UnattendDestinationDiskNumber
= (LONG
)IntValue
;
502 /* Search for 'DestinationPartitionNumber' in the 'Unattend' section */
503 if (!SetupFindFirstLineW(UnattendInf
, L
"Unattend", L
"DestinationPartitionNumber", &Context
))
505 DPRINT("SetupFindFirstLine() failed for key 'DestinationPartitionNumber'\n");
506 SetupCloseInfFile(UnattendInf
);
510 if (!SetupGetIntField(&Context
, 1, &IntValue
))
512 DPRINT("SetupGetIntField() failed for key 'DestinationPartitionNumber'\n");
513 SetupCloseInfFile(UnattendInf
);
517 UnattendDestinationPartitionNumber
= IntValue
;
519 /* Search for 'DestinationPartitionNumber' in the 'Unattend' section */
520 if (!SetupFindFirstLineW(UnattendInf
, L
"Unattend", L
"DestinationPartitionNumber", &Context
))
522 DPRINT("SetupFindFirstLine() failed for key 'DestinationPartitionNumber'\n");
523 SetupCloseInfFile(UnattendInf
);
527 /* Get pointer 'InstallationDirectory' key */
528 if (!INF_GetData(&Context
, NULL
, &Value
))
530 DPRINT("INF_GetData() failed for key 'InstallationDirectory'\n");
531 SetupCloseInfFile(UnattendInf
);
535 wcscpy(UnattendInstallationDirectory
, Value
);
537 IsUnattendedSetup
= TRUE
;
539 /* Search for 'MBRInstallType' in the 'Unattend' section */
540 if (SetupFindFirstLineW(UnattendInf
, L
"Unattend", L
"MBRInstallType", &Context
))
542 if (SetupGetIntField(&Context
, 1, &IntValue
))
544 UnattendMBRInstallType
= IntValue
;
548 /* Search for 'FormatPartition' in the 'Unattend' section */
549 if (SetupFindFirstLineW(UnattendInf
, L
"Unattend", L
"FormatPartition", &Context
))
551 if (SetupGetIntField(&Context
, 1, &IntValue
))
553 UnattendFormatPartition
= IntValue
;
557 if (SetupFindFirstLineW(UnattendInf
, L
"Unattend", L
"AutoPartition", &Context
))
559 if (SetupGetIntField(&Context
, 1, &IntValue
))
561 AutoPartition
= IntValue
;
565 /* search for LocaleID in the 'Unattend' section*/
566 if (SetupFindFirstLineW (UnattendInf
, L
"Unattend", L
"LocaleID", &Context
)){
567 if (INF_GetData (&Context
, NULL
, &Value
)){
568 LONG Id
= wcstol(Value
, NULL
, 16);
569 swprintf(LocaleID
,L
"%08lx", Id
);
573 SetupCloseInfFile(UnattendInf
);
575 DPRINT("Running unattended setup\n");
581 PGENERIC_LIST_ENTRY ListEntry
;
582 LPCWSTR pszNewLayout
;
584 pszNewLayout
= MUIDefaultKeyboardLayout();
586 if (LayoutList
== NULL
)
588 LayoutList
= CreateKeyboardLayoutList(SetupInf
, DefaultKBLayout
);
589 if (LayoutList
== NULL
)
591 /* FIXME: Handle error! */
596 ListEntry
= GetFirstListEntry(LayoutList
);
598 /* Search for default layout (if provided) */
599 if (pszNewLayout
!= NULL
)
601 while (ListEntry
!= NULL
)
603 if (!wcscmp(pszNewLayout
, GetListEntryUserData(ListEntry
)))
605 SetCurrentListEntry(LayoutList
, ListEntry
);
609 ListEntry
= GetNextListEntry(ListEntry
);
615 LanguagePage(PINPUT_RECORD Ir
)
617 /* Initialize the computer settings list */
618 if (LanguageList
== NULL
)
620 LanguageList
= CreateLanguageList(SetupInf
, DefaultLanguage
);
622 if (LanguageList
== NULL
)
624 PopupError("Setup failed to initialize available translations", NULL
, NULL
, POPUP_WAIT_NONE
);
629 DrawGenericList(LanguageList
,
635 ScrollToPositionGenericList (LanguageList
, GetDefaultLanguageIndex());
637 MUIDisplayPage(LANGUAGE_PAGE
);
641 CONSOLE_ConInKey(Ir
);
643 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
644 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
)) /* DOWN */
647 SelectedLanguageId
= (PWCHAR
)GetListEntryUserData(GetCurrentListEntry(LanguageList
));
649 /* Redraw language selection page in native language */
650 MUIDisplayPage(LANGUAGE_PAGE
);
653 ScrollDownGenericList (LanguageList
);
655 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
656 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_UP
)) /* UP */
659 SelectedLanguageId
= (PWCHAR
)GetListEntryUserData(GetCurrentListEntry(LanguageList
));
661 /* Redraw language selection page in native language */
662 MUIDisplayPage(LANGUAGE_PAGE
);
665 ScrollUpGenericList (LanguageList
);
667 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
668 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_NEXT
)) /* PAGE DOWN */
670 ScrollPageDownGenericList (LanguageList
);
672 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
673 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_PRIOR
)) /* PAGE UP */
675 ScrollPageUpGenericList (LanguageList
);
677 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
678 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
680 if (ConfirmQuit(Ir
) == TRUE
)
683 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
685 SelectedLanguageId
= (PWCHAR
)GetListEntryUserData(GetCurrentListEntry(LanguageList
));
687 LanguageId
= (LANGID
)(wcstol(SelectedLanguageId
, NULL
, 16) & 0xFFFF);
689 if (wcscmp(SelectedLanguageId
, DefaultLanguage
))
695 SetConsoleCodePage();
699 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
> 0x60) && (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
< 0x7b))
702 GenericListKeyPress (LanguageList
, Ir
->Event
.KeyEvent
.uChar
.AsciiChar
);
713 * Number of the next page.
716 SetupStartPage(PINPUT_RECORD Ir
)
718 SYSTEM_DEVICE_INFORMATION Sdi
;
720 WCHAR FileNameBuffer
[MAX_PATH
];
725 PGENERIC_LIST_ENTRY ListEntry
;
727 CONSOLE_SetStatusText(MUIGetString(STRING_PLEASEWAIT
));
730 /* Check whether a harddisk is available */
731 Status
= NtQuerySystemInformation (SystemDeviceInformation
,
733 sizeof(SYSTEM_DEVICE_INFORMATION
),
736 if (!NT_SUCCESS (Status
))
738 CONSOLE_PrintTextXY(6, 15, "NtQuerySystemInformation() failed (Status 0x%08lx)", Status
);
739 MUIDisplayError(ERROR_DRIVE_INFORMATION
, Ir
, POPUP_WAIT_ENTER
);
743 if (Sdi
.NumberOfDisks
== 0)
745 MUIDisplayError(ERROR_NO_HDD
, Ir
, POPUP_WAIT_ENTER
);
749 /* Get the source path and source root path */
750 Status
= GetSourcePaths(&SourcePath
,
754 if (!NT_SUCCESS(Status
))
756 CONSOLE_PrintTextXY(6, 15, "GetSourcePaths() failed (Status 0x%08lx)", Status
);
757 MUIDisplayError(ERROR_NO_SOURCE_DRIVE
, Ir
, POPUP_WAIT_ENTER
);
763 CONSOLE_PrintTextXY(6, 15, "SourcePath: '%wZ'", &SourcePath
);
764 CONSOLE_PrintTextXY(6, 16, "SourceRootPath: '%wZ'", &SourceRootPath
);
765 CONSOLE_PrintTextXY(6, 17, "SourceRootDir: '%wZ'", &SourceRootDir
);
769 /* Load txtsetup.sif from install media. */
770 wcscpy(FileNameBuffer
, SourcePath
.Buffer
);
771 wcscat(FileNameBuffer
, L
"\\txtsetup.sif");
773 SetupInf
= SetupOpenInfFileW(FileNameBuffer
,
779 if (SetupInf
== INVALID_HANDLE_VALUE
)
781 MUIDisplayError(ERROR_LOAD_TXTSETUPSIF
, Ir
, POPUP_WAIT_ENTER
);
785 /* Open 'Version' section */
786 if (!SetupFindFirstLineW (SetupInf
, L
"Version", L
"Signature", &Context
))
788 MUIDisplayError(ERROR_CORRUPT_TXTSETUPSIF
, Ir
, POPUP_WAIT_ENTER
);
792 /* Get pointer 'Signature' key */
793 if (!INF_GetData (&Context
, NULL
, &Value
))
795 MUIDisplayError(ERROR_CORRUPT_TXTSETUPSIF
, Ir
, POPUP_WAIT_ENTER
);
799 /* Check 'Signature' string */
800 if (_wcsicmp(Value
, L
"$ReactOS$") != 0)
802 MUIDisplayError(ERROR_SIGNATURE_TXTSETUPSIF
, Ir
, POPUP_WAIT_ENTER
);
806 /* Start PnP thread */
807 if (hPnpThread
!= INVALID_HANDLE_VALUE
)
809 NtResumeThread(hPnpThread
, NULL
);
810 hPnpThread
= INVALID_HANDLE_VALUE
;
813 CheckUnattendedSetup();
815 if (IsUnattendedSetup
)
818 //read options from inf
819 ComputerList
= CreateComputerTypeList(SetupInf
);
820 DisplayList
= CreateDisplayDriverList(SetupInf
);
821 KeyboardList
= CreateKeyboardDriverList(SetupInf
);
822 LayoutList
= CreateKeyboardLayoutList(SetupInf
, DefaultKBLayout
);
823 LanguageList
= CreateLanguageList(SetupInf
, DefaultLanguage
);
827 wcscpy(SelectedLanguageId
,LocaleID
);
830 /* first we hack LanguageList */
831 ListEntry
= GetFirstListEntry(LanguageList
);
833 while (ListEntry
!= NULL
)
835 if (!wcsicmp(LocaleID
, GetListEntryUserData(ListEntry
)))
837 DPRINT("found %S in LanguageList\n",GetListEntryUserData(ListEntry
));
838 SetCurrentListEntry(LanguageList
, ListEntry
);
842 ListEntry
= GetNextListEntry(ListEntry
);
845 ListEntry
= GetFirstListEntry(LayoutList
);
847 while (ListEntry
!= NULL
)
849 if (!wcsicmp(LocaleID
, GetListEntryUserData(ListEntry
)))
851 DPRINT("found %S in LayoutList\n",GetListEntryUserData(ListEntry
));
852 SetCurrentListEntry(LayoutList
, ListEntry
);
856 ListEntry
= GetNextListEntry(ListEntry
);
858 SetConsoleCodePage();
860 return INSTALL_INTRO_PAGE
;
863 return LANGUAGE_PAGE
;
873 IntroPage(PINPUT_RECORD Ir
)
875 MUIDisplayPage(START_PAGE
);
879 CONSOLE_ConInKey(Ir
);
881 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
882 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
884 if (ConfirmQuit(Ir
) == TRUE
)
889 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
891 return INSTALL_INTRO_PAGE
;
894 else if (toupper(Ir
->Event
.KeyEvent
.uChar
.AsciiChar
) == 'R') /* R */
896 return REPAIR_INTRO_PAGE
;
899 else if (toupper(Ir
->Event
.KeyEvent
.uChar
.AsciiChar
) == 'L') /* R */
912 * Back to main setup page.
915 LicensePage(PINPUT_RECORD Ir
)
917 MUIDisplayPage(LICENSE_PAGE
);
921 CONSOLE_ConInKey(Ir
);
923 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
934 RepairIntroPage(PINPUT_RECORD Ir
)
936 MUIDisplayPage(REPAIR_INTRO_PAGE
);
940 CONSOLE_ConInKey(Ir
);
942 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
946 else if (toupper(Ir
->Event
.KeyEvent
.uChar
.AsciiChar
) == 'U') /* U */
948 RepairUpdateFlag
= TRUE
;
949 return INSTALL_INTRO_PAGE
;
951 else if (toupper(Ir
->Event
.KeyEvent
.uChar
.AsciiChar
) == 'R') /* R */
955 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
956 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
)) /* ESC */
962 return REPAIR_INTRO_PAGE
;
967 InstallIntroPage(PINPUT_RECORD Ir
)
969 MUIDisplayPage(INSTALL_INTRO_PAGE
);
971 if (RepairUpdateFlag
)
973 //return SELECT_PARTITION_PAGE;
974 return DEVICE_SETTINGS_PAGE
;
977 if (IsUnattendedSetup
)
979 return SELECT_PARTITION_PAGE
;
984 CONSOLE_ConInKey(Ir
);
986 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
987 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
989 if (ConfirmQuit(Ir
) == TRUE
)
994 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
996 return DEVICE_SETTINGS_PAGE
;
997 // return SCSI_CONTROLLER_PAGE;
1001 return INSTALL_INTRO_PAGE
;
1007 ScsiControllerPage(PINPUT_RECORD Ir
)
1009 SetTextXY(6, 8, "Setup detected the following mass storage devices:");
1011 /* FIXME: print loaded mass storage driver descriptions */
1013 SetTextXY(8, 10, "TEST device");
1017 SetStatusText(" ENTER = Continue F3 = Quit");
1023 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1024 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1026 if (ConfirmQuit(Ir
) == TRUE
)
1031 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
1033 return DEVICE_SETTINGS_PAGE
;
1037 return SCSI_CONTROLLER_PAGE
;
1043 DeviceSettingsPage(PINPUT_RECORD Ir
)
1045 static ULONG Line
= 16;
1046 MUIDisplayPage(DEVICE_SETTINGS_PAGE
);
1048 /* Initialize the computer settings list */
1049 if (ComputerList
== NULL
)
1051 ComputerList
= CreateComputerTypeList(SetupInf
);
1052 if (ComputerList
== NULL
)
1054 MUIDisplayError(ERROR_LOAD_COMPUTER
, Ir
, POPUP_WAIT_ENTER
);
1059 /* Initialize the display settings list */
1060 if (DisplayList
== NULL
)
1062 DisplayList
= CreateDisplayDriverList(SetupInf
);
1063 if (DisplayList
== NULL
)
1065 MUIDisplayError(ERROR_LOAD_DISPLAY
, Ir
, POPUP_WAIT_ENTER
);
1070 /* Initialize the keyboard settings list */
1071 if (KeyboardList
== NULL
)
1073 KeyboardList
= CreateKeyboardDriverList(SetupInf
);
1074 if (KeyboardList
== NULL
)
1076 MUIDisplayError(ERROR_LOAD_KEYBOARD
, Ir
, POPUP_WAIT_ENTER
);
1081 /* Initialize the keyboard layout list */
1082 if (LayoutList
== NULL
)
1084 LayoutList
= CreateKeyboardLayoutList(SetupInf
, DefaultKBLayout
);
1085 if (LayoutList
== NULL
)
1087 /* FIXME: report error */
1088 MUIDisplayError(ERROR_LOAD_KBLAYOUT
, Ir
, POPUP_WAIT_ENTER
);
1093 MUIDisplayPage(DEVICE_SETTINGS_PAGE
);
1096 CONSOLE_SetTextXY(25, 11, GetListEntryText(GetCurrentListEntry((ComputerList
))));
1097 CONSOLE_SetTextXY(25, 12, GetListEntryText(GetCurrentListEntry((DisplayList
))));
1098 CONSOLE_SetTextXY(25, 13, GetListEntryText(GetCurrentListEntry((KeyboardList
))));
1099 CONSOLE_SetTextXY(25, 14, GetListEntryText(GetCurrentListEntry((LayoutList
))));
1101 CONSOLE_InvertTextXY(24, Line
, 48, 1);
1103 if (RepairUpdateFlag
)
1105 return SELECT_PARTITION_PAGE
;
1110 CONSOLE_ConInKey(Ir
);
1112 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1113 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
)) /* DOWN */
1115 CONSOLE_NormalTextXY(24, Line
, 48, 1);
1119 else if (Line
== 16)
1124 CONSOLE_InvertTextXY(24, Line
, 48, 1);
1126 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1127 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_UP
)) /* UP */
1129 CONSOLE_NormalTextXY(24, Line
, 48, 1);
1133 else if (Line
== 16)
1138 CONSOLE_InvertTextXY(24, Line
, 48, 1);
1140 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1141 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1143 if (ConfirmQuit(Ir
) == TRUE
)
1148 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
1151 return COMPUTER_SETTINGS_PAGE
;
1152 else if (Line
== 12)
1153 return DISPLAY_SETTINGS_PAGE
;
1154 else if (Line
== 13)
1155 return KEYBOARD_SETTINGS_PAGE
;
1156 else if (Line
== 14)
1157 return LAYOUT_SETTINGS_PAGE
;
1158 else if (Line
== 16)
1159 return SELECT_PARTITION_PAGE
;
1163 return DEVICE_SETTINGS_PAGE
;
1168 ComputerSettingsPage(PINPUT_RECORD Ir
)
1170 MUIDisplayPage(COMPUTER_SETTINGS_PAGE
);
1172 DrawGenericList(ComputerList
,
1178 SaveGenericListState(ComputerList
);
1182 CONSOLE_ConInKey(Ir
);
1184 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1185 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
)) /* DOWN */
1187 ScrollDownGenericList (ComputerList
);
1189 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1190 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_UP
)) /* UP */
1192 ScrollUpGenericList (ComputerList
);
1194 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1195 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1197 if (ConfirmQuit(Ir
) == TRUE
)
1202 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1203 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
)) /* ESC */
1205 RestoreGenericListState(ComputerList
);
1206 return DEVICE_SETTINGS_PAGE
;
1208 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
1210 return DEVICE_SETTINGS_PAGE
;
1214 return COMPUTER_SETTINGS_PAGE
;
1219 DisplaySettingsPage(PINPUT_RECORD Ir
)
1221 MUIDisplayPage(DISPLAY_SETTINGS_PAGE
);
1223 DrawGenericList(DisplayList
,
1229 SaveGenericListState(DisplayList
);
1233 CONSOLE_ConInKey(Ir
);
1235 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1236 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
)) /* DOWN */
1238 ScrollDownGenericList (DisplayList
);
1240 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1241 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_UP
)) /* UP */
1243 ScrollUpGenericList (DisplayList
);
1245 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1246 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1248 if (ConfirmQuit(Ir
) == TRUE
)
1255 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1256 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
)) /* ESC */
1258 RestoreGenericListState(DisplayList
);
1259 return DEVICE_SETTINGS_PAGE
;
1261 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
1263 return DEVICE_SETTINGS_PAGE
;
1267 return DISPLAY_SETTINGS_PAGE
;
1272 KeyboardSettingsPage(PINPUT_RECORD Ir
)
1274 MUIDisplayPage(KEYBOARD_SETTINGS_PAGE
);
1276 DrawGenericList(KeyboardList
,
1282 SaveGenericListState(KeyboardList
);
1286 CONSOLE_ConInKey(Ir
);
1288 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1289 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
)) /* DOWN */
1291 ScrollDownGenericList (KeyboardList
);
1293 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1294 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_UP
)) /* UP */
1296 ScrollUpGenericList (KeyboardList
);
1298 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1299 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1301 if (ConfirmQuit(Ir
) == TRUE
)
1306 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1307 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
)) /* ESC */
1309 RestoreGenericListState(KeyboardList
);
1310 return DEVICE_SETTINGS_PAGE
;
1312 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
1314 return DEVICE_SETTINGS_PAGE
;
1318 return DISPLAY_SETTINGS_PAGE
;
1323 LayoutSettingsPage(PINPUT_RECORD Ir
)
1325 MUIDisplayPage(LAYOUT_SETTINGS_PAGE
);
1327 DrawGenericList(LayoutList
,
1333 SaveGenericListState(LayoutList
);
1337 CONSOLE_ConInKey(Ir
);
1339 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1340 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
)) /* DOWN */
1342 ScrollDownGenericList (LayoutList
);
1344 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1345 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_UP
)) /* UP */
1347 ScrollUpGenericList (LayoutList
);
1349 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1350 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_NEXT
)) /* PAGE DOWN */
1352 ScrollPageDownGenericList (LayoutList
);
1354 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1355 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_PRIOR
)) /* PAGE UP */
1357 ScrollPageUpGenericList (LayoutList
);
1359 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1360 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1362 if (ConfirmQuit(Ir
) == TRUE
)
1367 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1368 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
)) /* ESC */
1370 RestoreGenericListState(LayoutList
);
1371 return DEVICE_SETTINGS_PAGE
;
1373 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
1375 return DEVICE_SETTINGS_PAGE
;
1377 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
> 0x60) && (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
< 0x7b))
1380 GenericListKeyPress (LayoutList
, Ir
->Event
.KeyEvent
.uChar
.AsciiChar
);
1384 return DISPLAY_SETTINGS_PAGE
;
1387 static BOOL
IsDiskSizeValid(PPARTENTRY PartEntry
)
1390 /* check for unpartitioned space */
1391 m
= PartEntry
->UnpartitionedLength
;
1392 m
= (m
+ (1 << 19)) >> 20; /* in MBytes (rounded) */
1393 if( m
> MINIMUMDISKSIZE
)
1398 // check for partitioned space
1399 m
= PartEntry
->PartInfo
[0].PartitionLength
.QuadPart
;
1400 m
= (m
+ (1 << 19)) >> 20; /* in MBytes (rounded) */
1401 if( m
< MINIMUMDISKSIZE
)
1403 /* partition is too small so ask for another partion */
1404 DPRINT1("Partition too small");
1414 SelectPartitionPage(PINPUT_RECORD Ir
)
1416 MUIDisplayPage(SELECT_PARTITION_PAGE
);
1418 if (PartitionList
== NULL
)
1420 PartitionList
= CreatePartitionList (2,
1425 if (PartitionList
== NULL
)
1427 /* FIXME: show an error dialog */
1432 CheckActiveBootPartition (PartitionList
);
1434 DrawPartitionList (PartitionList
);
1436 /* Warn about partitions created by Linux Fdisk */
1437 if (WarnLinuxPartitions
== TRUE
&&
1438 CheckForLinuxFdiskPartitions(PartitionList
) == TRUE
)
1440 MUIDisplayError(ERROR_WARN_PARTITION
, NULL
, POPUP_WAIT_NONE
);
1444 CONSOLE_ConInKey(Ir
);
1446 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1447 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1451 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_RETURN
) /* ENTER */
1453 WarnLinuxPartitions
= FALSE
;
1454 return SELECT_PARTITION_PAGE
;
1459 if (IsUnattendedSetup
)
1461 if (!SelectPartition(PartitionList
, UnattendDestinationDiskNumber
, UnattendDestinationPartitionNumber
))
1465 PPARTENTRY PartEntry
= PartitionList
->CurrentPartition
;
1466 ULONG MaxSize
= (PartEntry
->UnpartitionedLength
+ (1 << 19)) >> 20; /* in MBytes (rounded) */
1467 if(!IsDiskSizeValid(PartitionList
->CurrentPartition
))
1469 MUIDisplayError(ERROR_INSUFFICIENT_DISKSPACE
, Ir
, POPUP_WAIT_ANY_KEY
);
1470 return SELECT_PARTITION_PAGE
; /* let the user select another partition */
1472 CreateNewPartition(PartitionList
,
1476 return (SELECT_FILE_SYSTEM_PAGE
);
1481 if(!IsDiskSizeValid(PartitionList
->CurrentPartition
))
1483 MUIDisplayError(ERROR_INSUFFICIENT_DISKSPACE
, Ir
, POPUP_WAIT_ANY_KEY
);
1484 return SELECT_PARTITION_PAGE
; /* let the user select another partition */
1486 return(SELECT_FILE_SYSTEM_PAGE
);
1492 /* Update status text */
1493 if (PartitionList
->CurrentPartition
== NULL
||
1494 PartitionList
->CurrentPartition
->Unpartitioned
== TRUE
)
1496 CONSOLE_SetStatusText(MUIGetString(STRING_INSTALLCREATEPARTITION
));
1500 CONSOLE_SetStatusText(MUIGetString(STRING_INSTALLDELETEPARTITION
));
1503 CONSOLE_ConInKey(Ir
);
1505 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1506 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1508 if (ConfirmQuit(Ir
) == TRUE
)
1510 DestroyPartitionList (PartitionList
);
1511 PartitionList
= NULL
;
1517 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1518 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
)) /* DOWN */
1520 ScrollDownPartitionList (PartitionList
);
1522 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1523 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_UP
)) /* UP */
1525 ScrollUpPartitionList (PartitionList
);
1527 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_RETURN
) /* ENTER */
1529 if(!IsDiskSizeValid(PartitionList
->CurrentPartition
))
1531 MUIDisplayError(ERROR_INSUFFICIENT_DISKSPACE
, Ir
, POPUP_WAIT_ANY_KEY
);
1532 return SELECT_PARTITION_PAGE
; /* let the user select another partition */
1534 if (PartitionList
->CurrentPartition
== NULL
||
1535 PartitionList
->CurrentPartition
->Unpartitioned
== TRUE
)
1537 CreateNewPartition (PartitionList
,
1542 return SELECT_FILE_SYSTEM_PAGE
;
1544 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== 'C') /* C */
1546 if (PartitionList
->CurrentPartition
->Unpartitioned
== FALSE
)
1548 MUIDisplayError(ERROR_NEW_PARTITION
, Ir
, POPUP_WAIT_ANY_KEY
);
1549 return SELECT_PARTITION_PAGE
;
1552 return CREATE_PARTITION_PAGE
;
1554 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== 'D') /* D */
1556 if (PartitionList
->CurrentPartition
->Unpartitioned
== TRUE
)
1558 MUIDisplayError(ERROR_DELETE_SPACE
, Ir
, POPUP_WAIT_ANY_KEY
);
1559 return SELECT_PARTITION_PAGE
;
1562 return DELETE_PARTITION_PAGE
;
1566 return SELECT_PARTITION_PAGE
;
1571 DrawInputField(ULONG FieldLength
,
1582 memset(buf
, '_', sizeof(buf
));
1583 buf
[FieldLength
- strlen(FieldContent
)] = 0;
1584 strcat(buf
, FieldContent
);
1586 WriteConsoleOutputCharacterA (StdOutput
,
1594 #define PARTITION_SIZE_INPUT_FIELD_LENGTH 6
1595 /* Restriction for MaxSize: pow(10, PARTITION_SIZE_INPUT_FIELD_LENGTH)-1 */
1596 #define PARTITION_MAXSIZE 999999
1599 ShowPartitionSizeInputBox(SHORT Left
,
1623 DrawBox(Left
, Top
, Right
- Left
+ 1, Bottom
- Top
+ 1);
1628 strcpy (Buffer
, MUIGetString(STRING_PARTITIONSIZE
));
1629 iLeft
= coPos
.X
+ strlen (Buffer
) + 1;
1632 WriteConsoleOutputCharacterA(StdOutput
,
1638 sprintf (Buffer
, MUIGetString(STRING_MAXSIZE
), MaxSize
);
1639 coPos
.X
= iLeft
+ PARTITION_SIZE_INPUT_FIELD_LENGTH
+ 1;
1641 WriteConsoleOutputCharacterA(StdOutput
,
1647 sprintf(Buffer
, "%lu", MaxSize
);
1648 Index
= strlen(Buffer
);
1649 DrawInputField (PARTITION_SIZE_INPUT_FIELD_LENGTH
,
1656 CONSOLE_ConInKey(&Ir
);
1658 if ((Ir
.Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1659 (Ir
.Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1667 else if (Ir
.Event
.KeyEvent
.wVirtualKeyCode
== VK_RETURN
) /* ENTER */
1671 else if (Ir
.Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
) /* ESCAPE */
1679 else if ((Ir
.Event
.KeyEvent
.wVirtualKeyCode
== VK_BACK
) && /* BACKSPACE */
1685 DrawInputField (PARTITION_SIZE_INPUT_FIELD_LENGTH
,
1690 else if ((Ir
.Event
.KeyEvent
.uChar
.AsciiChar
!= 0x00) &&
1691 (Index
< PARTITION_SIZE_INPUT_FIELD_LENGTH
))
1693 ch
= Ir
.Event
.KeyEvent
.uChar
.AsciiChar
;
1695 if ((ch
>= '0') && (ch
<= '9'))
1701 DrawInputField (PARTITION_SIZE_INPUT_FIELD_LENGTH
,
1709 strcpy (InputBuffer
, Buffer
);
1714 CreatePartitionPage (PINPUT_RECORD Ir
)
1716 PDISKENTRY DiskEntry
;
1717 PPARTENTRY PartEntry
;
1720 CHAR InputBuffer
[50];
1726 if (PartitionList
== NULL
||
1727 PartitionList
->CurrentDisk
== NULL
||
1728 PartitionList
->CurrentPartition
== NULL
)
1730 /* FIXME: show an error dialog */
1734 DiskEntry
= PartitionList
->CurrentDisk
;
1735 PartEntry
= PartitionList
->CurrentPartition
;
1737 CONSOLE_SetStatusText(MUIGetString(STRING_PLEASEWAIT
));
1739 CONSOLE_SetTextXY(6, 8, MUIGetString(STRING_CHOOSENEWPARTITION
));
1742 if (DiskEntry
->DiskSize
>= 0x280000000ULL
) /* 10 GB */
1744 DiskSize
= (DiskEntry
->DiskSize
+ (1 << 29)) >> 30;
1745 Unit
= MUIGetString(STRING_GB
);
1750 DiskSize
= (DiskEntry
->DiskSize
+ (1 << 19)) >> 20;
1755 Unit
= MUIGetString(STRING_MB
);
1758 if (DiskEntry
->DriverName
.Length
> 0)
1760 CONSOLE_PrintTextXY(6, 10,
1761 MUIGetString(STRING_HDINFOPARTCREATE
),
1764 DiskEntry
->DiskNumber
,
1768 &DiskEntry
->DriverName
);
1772 CONSOLE_PrintTextXY(6, 10,
1773 MUIGetString(STRING_HDDINFOUNK1
),
1776 DiskEntry
->DiskNumber
,
1782 CONSOLE_SetTextXY(6, 12, MUIGetString(STRING_HDDSIZE
));
1785 CONSOLE_PrintTextXY(8, 10, "Maximum size of the new partition is %I64u MB",
1786 PartitionList
->CurrentPartition
->UnpartitionedLength
/ (1024*1024));
1789 CONSOLE_SetStatusText(MUIGetString(STRING_CREATEPARTITION
));
1791 PartEntry
= PartitionList
->CurrentPartition
;
1794 MaxSize
= (PartEntry
->UnpartitionedLength
+ (1 << 19)) >> 20; /* in MBytes (rounded) */
1796 if (MaxSize
> PARTITION_MAXSIZE
) MaxSize
= PARTITION_MAXSIZE
;
1798 ShowPartitionSizeInputBox (12, 14, xScreen
- 12, 17, /* left, top, right, bottom */
1799 MaxSize
, InputBuffer
, &Quit
, &Cancel
);
1803 if (ConfirmQuit (Ir
) == TRUE
)
1808 else if (Cancel
== TRUE
)
1810 return SELECT_PARTITION_PAGE
;
1814 PartSize
= atoi(InputBuffer
);
1822 if (PartSize
> MaxSize
)
1828 /* Convert to bytes */
1829 if (PartSize
== MaxSize
)
1831 /* Use all of the unpartitioned disk space */
1832 PartSize
= PartEntry
->UnpartitionedLength
;
1836 /* Round-up by cylinder size */
1837 PartSize
= (PartSize
* 1024 * 1024 + DiskEntry
->CylinderSize
- 1) /
1838 DiskEntry
->CylinderSize
* DiskEntry
->CylinderSize
;
1840 /* But never get larger than the unpartitioned disk space */
1841 if (PartSize
> PartEntry
->UnpartitionedLength
)
1842 PartSize
= PartEntry
->UnpartitionedLength
;
1845 DPRINT ("Partition size: %I64u bytes\n", PartSize
);
1847 CreateNewPartition (PartitionList
,
1851 return SELECT_PARTITION_PAGE
;
1855 return CREATE_PARTITION_PAGE
;
1860 DeletePartitionPage (PINPUT_RECORD Ir
)
1862 PDISKENTRY DiskEntry
;
1863 PPARTENTRY PartEntry
;
1870 if (PartitionList
== NULL
||
1871 PartitionList
->CurrentDisk
== NULL
||
1872 PartitionList
->CurrentPartition
== NULL
)
1874 /* FIXME: show an error dialog */
1878 DiskEntry
= PartitionList
->CurrentDisk
;
1879 PartEntry
= PartitionList
->CurrentPartition
;
1880 PartNumber
= PartitionList
->CurrentPartitionNumber
;
1882 MUIDisplayPage(DELETE_PARTITION_PAGE
);
1884 /* Determine partition type */
1886 if (PartEntry
->New
== TRUE
)
1888 PartType
= MUIGetString(STRING_UNFORMATTED
);
1890 else if (PartEntry
->Unpartitioned
== FALSE
)
1892 if ((PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_FAT_12
) ||
1893 (PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_FAT_16
) ||
1894 (PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_HUGE
) ||
1895 (PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_XINT13
))
1899 else if ((PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_FAT32
) ||
1900 (PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_FAT32_XINT13
))
1904 else if (PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_EXT2
)
1908 else if (PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_IFS
)
1910 PartType
= "NTFS"; /* FIXME: Not quite correct! */
1915 if (PartEntry
->PartInfo
[PartNumber
].PartitionLength
.QuadPart
>= 0x280000000LL
) /* 10 GB */
1917 PartSize
= (PartEntry
->PartInfo
[PartNumber
].PartitionLength
.QuadPart
+ (1 << 29)) >> 30;
1918 Unit
= MUIGetString(STRING_GB
);
1922 if (PartEntry
->PartInfo
[PartNumber
].PartitionLength
.QuadPart
>= 0xA00000LL
) /* 10 MB */
1924 PartSize
= (PartEntry
->PartInfo
[PartNumber
].PartitionLength
.QuadPart
+ (1 << 19)) >> 20;
1925 Unit
= MUIGetString(STRING_MB
);
1929 PartSize
= (PartEntry
->PartInfo
[PartNumber
].PartitionLength
.QuadPart
+ (1 << 9)) >> 10;
1930 Unit
= MUIGetString(STRING_KB
);
1933 if (PartType
== NULL
)
1935 CONSOLE_PrintTextXY(6, 10,
1936 MUIGetString(STRING_HDDINFOUNK2
),
1937 (PartEntry
->DriveLetter
[PartNumber
] == 0) ? '-' : PartEntry
->DriveLetter
[PartNumber
],
1938 (PartEntry
->DriveLetter
[PartNumber
] == 0) ? '-' : ':',
1939 PartEntry
->PartInfo
[PartNumber
].PartitionType
,
1945 CONSOLE_PrintTextXY(6, 10,
1946 " %c%c %s %I64u %s",
1947 (PartEntry
->DriveLetter
[PartNumber
] == 0) ? '-' : PartEntry
->DriveLetter
[PartNumber
],
1948 (PartEntry
->DriveLetter
[PartNumber
] == 0) ? '-' : ':',
1955 if (DiskEntry
->DiskSize
>= 0x280000000ULL
) /* 10 GB */
1957 DiskSize
= (DiskEntry
->DiskSize
+ (1 << 29)) >> 30;
1958 Unit
= MUIGetString(STRING_GB
);
1963 DiskSize
= (DiskEntry
->DiskSize
+ (1 << 19)) >> 20;
1968 Unit
= MUIGetString(STRING_MB
);
1971 if (DiskEntry
->DriverName
.Length
> 0)
1973 CONSOLE_PrintTextXY(6, 12,
1974 MUIGetString(STRING_HDINFOPARTDELETE
),
1977 DiskEntry
->DiskNumber
,
1981 &DiskEntry
->DriverName
);
1985 CONSOLE_PrintTextXY(6, 12,
1986 MUIGetString(STRING_HDDINFOUNK3
),
1989 DiskEntry
->DiskNumber
,
1997 CONSOLE_ConInKey(Ir
);
1999 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
2000 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
2002 if (ConfirmQuit (Ir
) == TRUE
)
2009 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
) /* ESC */
2011 return SELECT_PARTITION_PAGE
;
2013 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== 'D') /* D */
2015 DeleteCurrentPartition (PartitionList
);
2017 return SELECT_PARTITION_PAGE
;
2021 return DELETE_PARTITION_PAGE
;
2026 SelectFileSystemPage (PINPUT_RECORD Ir
)
2028 PDISKENTRY DiskEntry
;
2029 PPARTENTRY PartEntry
;
2037 if (PartitionList
== NULL
||
2038 PartitionList
->CurrentDisk
== NULL
||
2039 PartitionList
->CurrentPartition
== NULL
)
2041 /* FIXME: show an error dialog */
2045 DiskEntry
= PartitionList
->CurrentDisk
;
2046 PartEntry
= PartitionList
->CurrentPartition
;
2047 PartNumber
= PartitionList
->CurrentPartitionNumber
;
2049 /* adjust disk size */
2050 if (DiskEntry
->DiskSize
>= 0x280000000ULL
) /* 10 GB */
2052 DiskSize
= (DiskEntry
->DiskSize
+ (1 << 29)) >> 30;
2053 DiskUnit
= MUIGetString(STRING_GB
);
2057 DiskSize
= (DiskEntry
->DiskSize
+ (1 << 19)) >> 20;
2058 DiskUnit
= MUIGetString(STRING_MB
);
2061 /* adjust partition size */
2062 if (PartEntry
->PartInfo
[PartNumber
].PartitionLength
.QuadPart
>= 0x280000000LL
) /* 10 GB */
2064 PartSize
= (PartEntry
->PartInfo
[PartNumber
].PartitionLength
.QuadPart
+ (1 << 29)) >> 30;
2065 PartUnit
= MUIGetString(STRING_GB
);
2069 PartSize
= (PartEntry
->PartInfo
[PartNumber
].PartitionLength
.QuadPart
+ (1 << 19)) >> 20;
2070 PartUnit
= MUIGetString(STRING_MB
);
2073 /* adjust partition type */
2074 if ((PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_FAT_12
) ||
2075 (PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_FAT_16
) ||
2076 (PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_HUGE
) ||
2077 (PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_XINT13
))
2081 else if ((PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_FAT32
) ||
2082 (PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_FAT32_XINT13
))
2086 else if (PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_EXT2
)
2090 else if (PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_IFS
)
2092 PartType
= "NTFS"; /* FIXME: Not quite correct! */
2094 else if (PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_ENTRY_UNUSED
)
2096 PartType
= MUIGetString(STRING_FORMATUNUSED
);
2100 PartType
= MUIGetString(STRING_FORMATUNKNOWN
);
2103 if (PartEntry
->AutoCreate
== TRUE
)
2105 CONSOLE_SetTextXY(6, 8, MUIGetString(STRING_NEWPARTITION
));
2108 CONSOLE_PrintTextXY(8, 10, "Partition %lu (%I64u %s) %s of",
2109 PartEntry
->PartInfo
[PartNumber
].PartitionNumber
,
2115 CONSOLE_PrintTextXY(8, 10, MUIGetString(STRING_HDINFOPARTZEROED
),
2116 DiskEntry
->DiskNumber
,
2122 &DiskEntry
->DriverName
);
2124 CONSOLE_SetTextXY(6, 12, MUIGetString(STRING_PARTFORMAT
));
2127 PartEntry
->AutoCreate
= FALSE
;
2129 else if (PartEntry
->New
== TRUE
)
2131 CONSOLE_SetTextXY(6, 8, MUIGetString(STRING_NONFORMATTEDPART
));
2132 CONSOLE_SetTextXY(6, 10, MUIGetString(STRING_PARTFORMAT
));
2136 CONSOLE_SetTextXY(6, 8, MUIGetString(STRING_INSTALLONPART
));
2138 if (PartType
== NULL
)
2140 CONSOLE_PrintTextXY(8, 10,
2141 MUIGetString(STRING_HDDINFOUNK4
),
2142 (PartEntry
->DriveLetter
[PartNumber
] == 0) ? '-' : PartEntry
->DriveLetter
[PartNumber
],
2143 (PartEntry
->DriveLetter
[PartNumber
] == 0) ? '-' : ':',
2144 PartEntry
->PartInfo
[PartNumber
].PartitionType
,
2150 CONSOLE_PrintTextXY(8, 10,
2152 (PartEntry
->DriveLetter
[PartNumber
] == 0) ? '-' : PartEntry
->DriveLetter
[PartNumber
],
2153 (PartEntry
->DriveLetter
[PartNumber
] == 0) ? '-' : ':',
2159 CONSOLE_PrintTextXY(6, 12, MUIGetString(STRING_HDINFOPARTEXISTS
),
2160 DiskEntry
->DiskNumber
,
2166 &DiskEntry
->DriverName
);
2169 MUIDisplayPage(SELECT_FILE_SYSTEM_PAGE
);
2171 if (FileSystemList
== NULL
)
2173 FileSystemList
= CreateFileSystemList (6, 26, PartEntry
->New
, L
"FAT");
2174 if (FileSystemList
== NULL
)
2176 /* FIXME: show an error dialog */
2180 /* FIXME: Add file systems to list */
2182 DrawFileSystemList (FileSystemList
);
2184 if (RepairUpdateFlag
)
2186 return CHECK_FILE_SYSTEM_PAGE
;
2187 //return SELECT_PARTITION_PAGE;
2190 if (IsUnattendedSetup
)
2192 if (UnattendFormatPartition
)
2194 return FORMAT_PARTITION_PAGE
;
2197 return(CHECK_FILE_SYSTEM_PAGE
);
2202 CONSOLE_ConInKey(Ir
);
2204 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
2205 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
2207 if (ConfirmQuit (Ir
) == TRUE
)
2214 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
2215 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
)) /* ESC */
2217 return SELECT_PARTITION_PAGE
;
2219 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
2220 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
)) /* DOWN */
2222 ScrollDownFileSystemList (FileSystemList
);
2224 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
2225 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_UP
)) /* UP */
2227 ScrollUpFileSystemList (FileSystemList
);
2229 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_RETURN
) /* ENTER */
2231 if (!FileSystemList
->Selected
->FormatFunc
)
2233 return CHECK_FILE_SYSTEM_PAGE
;
2237 return FORMAT_PARTITION_PAGE
;
2242 return SELECT_FILE_SYSTEM_PAGE
;
2247 FormatPartitionPage (PINPUT_RECORD Ir
)
2249 WCHAR PathBuffer
[MAX_PATH
];
2250 PDISKENTRY DiskEntry
;
2251 PPARTENTRY PartEntry
;
2261 MUIDisplayPage(FORMAT_PARTITION_PAGE
);
2263 if (PartitionList
== NULL
||
2264 PartitionList
->CurrentDisk
== NULL
||
2265 PartitionList
->CurrentPartition
== NULL
)
2267 /* FIXME: show an error dialog */
2271 DiskEntry
= PartitionList
->CurrentDisk
;
2272 PartEntry
= PartitionList
->CurrentPartition
;
2273 PartNum
= PartitionList
->CurrentPartitionNumber
;
2277 if (!IsUnattendedSetup
)
2279 CONSOLE_ConInKey(Ir
);
2282 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
2283 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
2285 if (ConfirmQuit (Ir
) == TRUE
)
2292 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_RETURN
|| IsUnattendedSetup
) /* ENTER */
2294 CONSOLE_SetStatusText(MUIGetString(STRING_PLEASEWAIT
));
2296 if (PartEntry
->PartInfo
[PartNum
].PartitionType
== PARTITION_ENTRY_UNUSED
)
2298 if (wcscmp(FileSystemList
->Selected
->FileSystem
, L
"FAT") == 0)
2300 if (PartEntry
->PartInfo
[PartNum
].PartitionLength
.QuadPart
< (4200LL * 1024LL))
2302 /* FAT12 CHS partition (disk is smaller than 4.1MB) */
2303 PartEntry
->PartInfo
[PartNum
].PartitionType
= PARTITION_FAT_12
;
2305 else if (PartEntry
->PartInfo
[PartNum
].StartingOffset
.QuadPart
< (1024LL * 255LL * 63LL * 512LL))
2307 /* Partition starts below the 8.4GB boundary ==> CHS partition */
2309 if (PartEntry
->PartInfo
[PartNum
].PartitionLength
.QuadPart
< (32LL * 1024LL * 1024LL))
2311 /* FAT16 CHS partition (partiton size < 32MB) */
2312 PartEntry
->PartInfo
[PartNum
].PartitionType
= PARTITION_FAT_16
;
2314 else if (PartEntry
->PartInfo
[PartNum
].PartitionLength
.QuadPart
< (512LL * 1024LL * 1024LL))
2316 /* FAT16 CHS partition (partition size < 512MB) */
2317 PartEntry
->PartInfo
[PartNum
].PartitionType
= PARTITION_HUGE
;
2321 /* FAT32 CHS partition (partition size >= 512MB) */
2322 PartEntry
->PartInfo
[PartNum
].PartitionType
= PARTITION_FAT32
;
2327 /* Partition starts above the 8.4GB boundary ==> LBA partition */
2329 if (PartEntry
->PartInfo
[PartNum
].PartitionLength
.QuadPart
< (512LL * 1024LL * 1024LL))
2331 /* FAT16 LBA partition (partition size < 512MB) */
2332 PartEntry
->PartInfo
[PartNum
].PartitionType
= PARTITION_XINT13
;
2336 /* FAT32 LBA partition (partition size >= 512MB) */
2337 PartEntry
->PartInfo
[PartNum
].PartitionType
= PARTITION_FAT32_XINT13
;
2341 else if (wcscmp(FileSystemList
->Selected
->FileSystem
, L
"EXT2") == 0)
2342 PartEntry
->PartInfo
[PartNum
].PartitionType
= PARTITION_EXT2
;
2343 else if (!FileSystemList
->Selected
->FormatFunc
)
2347 CheckActiveBootPartition (PartitionList
);
2350 CONSOLE_PrintTextXY(6, 12,
2351 "Disk: %I64u Cylinder: %I64u Track: %I64u",
2352 DiskEntry
->DiskSize
,
2353 DiskEntry
->CylinderSize
,
2354 DiskEntry
->TrackSize
);
2357 DiskEntry
= PartitionList
->CurrentDisk
;
2358 Entry
= DiskEntry
->PartListHead
.Flink
;
2360 while (Entry
!= &DiskEntry
->PartListHead
)
2362 PartEntry
= CONTAINING_RECORD(Entry
, PARTENTRY
, ListEntry
);
2364 if (PartEntry
->Unpartitioned
== FALSE
)
2366 for (i
= 0; i
< 4; i
++)
2368 CONSOLE_PrintTextXY(6, Line
,
2369 "%2u: %2u %c %12I64u %12I64u %2u %c",
2371 PartEntry
->PartInfo
[i
].PartitionNumber
,
2372 PartEntry
->PartInfo
[i
].BootIndicator
? 'A' : '-',
2373 PartEntry
->PartInfo
[i
].StartingOffset
.QuadPart
,
2374 PartEntry
->PartInfo
[i
].PartitionLength
.QuadPart
,
2375 PartEntry
->PartInfo
[i
].PartitionType
,
2376 PartEntry
->PartInfo
[i
].RewritePartition
? '*' : ' ');
2384 Entry
= Entry
->Flink
;
2387 /* Restore the old entry */
2388 PartEntry
= PartitionList
->CurrentPartition
;
2391 if (WritePartitionsToDisk (PartitionList
) == FALSE
)
2393 DPRINT ("WritePartitionsToDisk() failed\n");
2394 MUIDisplayError(ERROR_WRITE_PTABLE
, Ir
, POPUP_WAIT_ENTER
);
2398 /* Set DestinationRootPath */
2399 RtlFreeUnicodeString (&DestinationRootPath
);
2400 swprintf (PathBuffer
,
2401 L
"\\Device\\Harddisk%lu\\Partition%lu",
2402 PartitionList
->CurrentDisk
->DiskNumber
,
2403 PartitionList
->CurrentPartition
->PartInfo
[PartNum
].PartitionNumber
);
2404 RtlCreateUnicodeString (&DestinationRootPath
,
2406 DPRINT ("DestinationRootPath: %wZ\n", &DestinationRootPath
);
2409 /* Set SystemRootPath */
2410 RtlFreeUnicodeString (&SystemRootPath
);
2411 swprintf (PathBuffer
,
2412 L
"\\Device\\Harddisk%lu\\Partition%lu",
2413 PartitionList
->ActiveBootDisk
->DiskNumber
,
2414 PartitionList
->ActiveBootPartition
->
2415 PartInfo
[PartitionList
->ActiveBootPartitionNumber
].PartitionNumber
);
2416 RtlCreateUnicodeString (&SystemRootPath
,
2418 DPRINT ("SystemRootPath: %wZ\n", &SystemRootPath
);
2421 if (FileSystemList
->Selected
->FormatFunc
)
2423 Status
= FormatPartition(&DestinationRootPath
, FileSystemList
->Selected
);
2424 if (!NT_SUCCESS(Status
))
2426 DPRINT1("FormatPartition() failed with status 0x%08lx\n", Status
);
2427 /* FIXME: show an error dialog */
2431 PartEntry
->New
= FALSE
;
2433 CheckActiveBootPartition(PartitionList
);
2436 /* Install MBR if necessary */
2437 if (DiskEntry
->NoMbr
&&
2438 DiskEntry
->BiosDiskNumber
== 0)
2440 wcscpy(PathBuffer
, SourceRootPath
.Buffer
);
2441 wcscat(PathBuffer
, L
"\\loader\\dosmbr.bin");
2443 DPRINT("Install MBR bootcode: %S ==> %S\n",
2444 PathBuffer
, DestinationRootPath
.Buffer
);
2446 /* Install MBR bootcode */
2447 Status
= InstallMbrBootCodeToDisk(PathBuffer
, DestinationRootPath
.Buffer
);
2448 if (!NT_SUCCESS (Status
))
2450 DPRINT1("InstallMbrBootCodeToDisk() failed (Status %lx)\n",
2455 DiskEntry
->NoMbr
= FALSE
;
2458 if (wcscmp(FileSystemList
->Selected
->FileSystem
, L
"FAT") == 0)
2460 /* FIXME: Install boot code. This is a hack! */
2461 if ((PartEntry
->PartInfo
[PartNum
].PartitionType
== PARTITION_FAT32_XINT13
) ||
2462 (PartEntry
->PartInfo
[PartNum
].PartitionType
== PARTITION_FAT32
))
2464 wcscpy(PathBuffer
, SourceRootPath
.Buffer
);
2465 wcscat(PathBuffer
, L
"\\loader\\fat32.bin");
2467 DPRINT("Install FAT32 bootcode: %S ==> %S\n", PathBuffer
,
2468 DestinationRootPath
.Buffer
);
2469 Status
= InstallFat32BootCodeToDisk(PathBuffer
,
2470 DestinationRootPath
.Buffer
);
2472 if (!NT_SUCCESS(Status
))
2474 DPRINT1("InstallFat32BootCodeToDisk() failed with status 0x%08lx\n", Status
);
2475 /* FIXME: show an error dialog */
2476 DestroyFileSystemList(FileSystemList
);
2477 FileSystemList
= NULL
;
2483 wcscpy(PathBuffer
, SourceRootPath
.Buffer
);
2484 wcscat(PathBuffer
, L
"\\loader\\fat.bin");
2486 DPRINT("Install FAT bootcode: %S ==> %S\n", PathBuffer
,
2487 DestinationRootPath
.Buffer
);
2488 Status
= InstallFat16BootCodeToDisk(PathBuffer
,
2489 DestinationRootPath
.Buffer
);
2491 if (!NT_SUCCESS(Status
))
2493 DPRINT1("InstallFat16BootCodeToDisk() failed with status 0x%.08x\n", Status
);
2494 /* FIXME: show an error dialog */
2495 DestroyFileSystemList(FileSystemList
);
2496 FileSystemList
= NULL
;
2501 else if (wcscmp(FileSystemList
->Selected
->FileSystem
, L
"EXT2") == 0)
2503 wcscpy(PathBuffer
, SourceRootPath
.Buffer
);
2504 wcscat(PathBuffer
, L
"\\loader\\ext2.bin");
2506 DPRINT("Install EXT2 bootcode: %S ==> %S\n", PathBuffer
,
2507 DestinationRootPath
.Buffer
);
2508 Status
= InstallFat32BootCodeToDisk(PathBuffer
,
2509 DestinationRootPath
.Buffer
);
2511 if (!NT_SUCCESS(Status
))
2513 DPRINT1("InstallFat32BootCodeToDisk() failed with status 0x%08lx\n", Status
);
2514 /* FIXME: show an error dialog */
2515 DestroyFileSystemList(FileSystemList
);
2516 FileSystemList
= NULL
;
2520 else if (FileSystemList
->Selected
->FormatFunc
)
2522 DestroyFileSystemList(FileSystemList
);
2523 FileSystemList
= NULL
;
2528 CONSOLE_SetStatusText(" Done. Press any key ...");
2529 CONSOLE_ConInKey(Ir
);
2532 DestroyFileSystemList(FileSystemList
);
2533 FileSystemList
= NULL
;
2534 return INSTALL_DIRECTORY_PAGE
;
2538 return FORMAT_PARTITION_PAGE
;
2543 CheckFileSystemPage(PINPUT_RECORD Ir
)
2545 PFILE_SYSTEM_ITEM CurrentFileSystem
;
2546 WCHAR PathBuffer
[MAX_PATH
];
2547 CHAR Buffer
[MAX_PATH
];
2549 UCHAR PartNum
= PartitionList
->CurrentPartitionNumber
;
2551 /* FIXME: code duplicated in FormatPartitionPage */
2552 /* Set DestinationRootPath */
2553 RtlFreeUnicodeString(&DestinationRootPath
);
2554 swprintf(PathBuffer
,
2555 L
"\\Device\\Harddisk%lu\\Partition%lu",
2556 PartitionList
->CurrentDisk
->DiskNumber
,
2557 PartitionList
->CurrentPartition
->PartInfo
[PartNum
].PartitionNumber
);
2558 RtlCreateUnicodeString(&DestinationRootPath
, PathBuffer
);
2559 DPRINT("DestinationRootPath: %wZ\n", &DestinationRootPath
);
2561 /* Set SystemRootPath */
2562 RtlFreeUnicodeString(&SystemRootPath
);
2563 swprintf(PathBuffer
,
2564 L
"\\Device\\Harddisk%lu\\Partition%lu",
2565 PartitionList
->ActiveBootDisk
->DiskNumber
,
2566 PartitionList
->ActiveBootPartition
->PartInfo
[PartNum
].PartitionNumber
);
2567 RtlCreateUnicodeString(&SystemRootPath
, PathBuffer
);
2568 DPRINT("SystemRootPath: %wZ\n", &SystemRootPath
);
2570 CONSOLE_SetTextXY(6, 8, MUIGetString(STRING_CHECKINGPART
));
2572 CONSOLE_SetStatusText(MUIGetString(STRING_PLEASEWAIT
));
2574 /* WRONG: first filesystem is not necesseraly the one of the current partition! */
2575 CurrentFileSystem
= CONTAINING_RECORD(FileSystemList
->ListHead
.Flink
, FILE_SYSTEM_ITEM
, ListEntry
);
2577 if (!CurrentFileSystem
->ChkdskFunc
)
2580 "Setup is currently unable to check a partition formatted in %S.\n"
2582 " \x07 Press ENTER to continue Setup.\n"
2583 " \x07 Press F3 to quit Setup.",
2584 CurrentFileSystem
->FileSystem
);
2587 MUIGetString(STRING_QUITCONTINUE
),
2588 NULL
, POPUP_WAIT_NONE
);
2592 CONSOLE_ConInKey(Ir
);
2594 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00 &&
2595 Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
) /* F3 */
2597 if (ConfirmQuit(Ir
))
2600 return CHECK_FILE_SYSTEM_PAGE
;
2602 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== VK_RETURN
) /* ENTER */
2604 return INSTALL_DIRECTORY_PAGE
;
2610 Status
= ChkdskPartition(&DestinationRootPath
, CurrentFileSystem
);
2611 if (!NT_SUCCESS(Status
))
2613 DPRINT("ChkdskPartition() failed with status 0x%08lx\n", Status
);
2614 sprintf(Buffer
, "Setup failed to verify the selected partition.\n"
2615 "(Status 0x%08lx).\n", Status
);
2618 MUIGetString(STRING_REBOOTCOMPUTER
),
2619 Ir
, POPUP_WAIT_ENTER
);
2624 return INSTALL_DIRECTORY_PAGE
;
2630 InstallDirectoryPage1(PWCHAR InstallDir
, PDISKENTRY DiskEntry
, PPARTENTRY PartEntry
, UCHAR PartNum
)
2632 WCHAR PathBuffer
[MAX_PATH
];
2634 /* Create 'InstallPath' string */
2635 RtlFreeUnicodeString(&InstallPath
);
2636 RtlCreateUnicodeString(&InstallPath
,
2639 /* Create 'DestinationPath' string */
2640 RtlFreeUnicodeString(&DestinationPath
);
2641 wcscpy(PathBuffer
, DestinationRootPath
.Buffer
);
2643 if (InstallDir
[0] != L
'\\')
2644 wcscat(PathBuffer
, L
"\\");
2646 wcscat(PathBuffer
, InstallDir
);
2647 RtlCreateUnicodeString(&DestinationPath
, PathBuffer
);
2649 /* Create 'DestinationArcPath' */
2650 RtlFreeUnicodeString(&DestinationArcPath
);
2651 swprintf(PathBuffer
,
2652 L
"multi(0)disk(0)rdisk(%lu)partition(%lu)",
2653 DiskEntry
->BiosDiskNumber
,
2654 PartEntry
->PartInfo
[PartNum
].PartitionNumber
);
2656 if (InstallDir
[0] != L
'\\')
2657 wcscat(PathBuffer
, L
"\\");
2659 wcscat(PathBuffer
, InstallDir
);
2660 RtlCreateUnicodeString(&DestinationArcPath
, PathBuffer
);
2662 return(PREPARE_COPY_PAGE
);
2667 InstallDirectoryPage(PINPUT_RECORD Ir
)
2669 PDISKENTRY DiskEntry
;
2670 PPARTENTRY PartEntry
;
2671 WCHAR InstallDir
[51];
2676 if (PartitionList
== NULL
||
2677 PartitionList
->CurrentDisk
== NULL
||
2678 PartitionList
->CurrentPartition
== NULL
)
2680 /* FIXME: show an error dialog */
2684 DiskEntry
= PartitionList
->CurrentDisk
;
2685 PartEntry
= PartitionList
->CurrentPartition
;
2687 /* Search for 'DefaultPath' in the 'SetupData' section */
2688 if (!SetupFindFirstLineW (SetupInf
, L
"SetupData", L
"DefaultPath", &Context
))
2690 MUIDisplayError(ERROR_FIND_SETUPDATA
, Ir
, POPUP_WAIT_ENTER
);
2694 /* Read the 'DefaultPath' data */
2695 if (INF_GetData (&Context
, NULL
, &DefaultPath
))
2697 wcscpy(InstallDir
, DefaultPath
);
2701 wcscpy(InstallDir
, L
"\\ReactOS");
2704 Length
= wcslen(InstallDir
);
2705 CONSOLE_SetInputTextXY(8, 11, 51, InstallDir
);
2706 MUIDisplayPage(INSTALL_DIRECTORY_PAGE
);
2708 if (IsUnattendedSetup
)
2710 return(InstallDirectoryPage1 (InstallDir
, DiskEntry
, PartEntry
, PartitionList
->CurrentPartitionNumber
));
2715 CONSOLE_ConInKey(Ir
);
2717 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
2718 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
2720 if (ConfirmQuit(Ir
) == TRUE
)
2725 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2727 return (InstallDirectoryPage1 (InstallDir
, DiskEntry
, PartEntry
, PartitionList
->CurrentPartitionNumber
));
2729 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x08) /* BACKSPACE */
2734 InstallDir
[Length
] = 0;
2735 CONSOLE_SetInputTextXY(8, 11, 51, InstallDir
);
2738 else if (isprint(Ir
->Event
.KeyEvent
.uChar
.AsciiChar
))
2742 InstallDir
[Length
] = (WCHAR
)Ir
->Event
.KeyEvent
.uChar
.AsciiChar
;
2744 InstallDir
[Length
] = 0;
2745 CONSOLE_SetInputTextXY(8, 11, 51, InstallDir
);
2750 return(INSTALL_DIRECTORY_PAGE
);
2754 AddSectionToCopyQueueCab(HINF InfFile
,
2756 PWCHAR SourceCabinet
,
2757 PCUNICODE_STRING DestinationPath
,
2760 INFCONTEXT FilesContext
;
2761 INFCONTEXT DirContext
;
2763 PWCHAR FileKeyValue
;
2765 PWCHAR TargetFileName
;
2767 /* Search for the SectionName section */
2768 if (!SetupFindFirstLineW (InfFile
, SectionName
, NULL
, &FilesContext
))
2771 sprintf(Buffer
, MUIGetString(STRING_TXTSETUPFAILED
), SectionName
);
2772 PopupError(Buffer
, MUIGetString(STRING_REBOOTCOMPUTER
), Ir
, POPUP_WAIT_ENTER
);
2777 * Enumerate the files in the section
2778 * and add them to the file queue.
2782 /* Get source file name and target directory id */
2783 if (!INF_GetData (&FilesContext
, &FileKeyName
, &FileKeyValue
))
2785 /* FIXME: Handle error! */
2786 DPRINT1("INF_GetData() failed\n");
2790 /* Get optional target file name */
2791 if (!INF_GetDataField (&FilesContext
, 2, &TargetFileName
))
2792 TargetFileName
= NULL
;
2794 DPRINT ("FileKeyName: '%S' FileKeyValue: '%S'\n", FileKeyName
, FileKeyValue
);
2796 /* Lookup target directory */
2797 if (!SetupFindFirstLineW (InfFile
, L
"Directories", FileKeyValue
, &DirContext
))
2799 /* FIXME: Handle error! */
2800 DPRINT1("SetupFindFirstLine() failed\n");
2804 if (!INF_GetData (&DirContext
, NULL
, &DirKeyValue
))
2806 /* FIXME: Handle error! */
2807 DPRINT1("INF_GetData() failed\n");
2811 if (!SetupQueueCopy(SetupFileQueue
,
2813 SourceRootPath
.Buffer
,
2814 SourceRootDir
.Buffer
,
2819 /* FIXME: Handle error! */
2820 DPRINT1("SetupQueueCopy() failed\n");
2822 } while (SetupFindNextLine(&FilesContext
, &FilesContext
));
2828 AddSectionToCopyQueue(HINF InfFile
,
2830 PWCHAR SourceCabinet
,
2831 PCUNICODE_STRING DestinationPath
,
2834 INFCONTEXT FilesContext
;
2835 INFCONTEXT DirContext
;
2837 PWCHAR FileKeyValue
;
2839 PWCHAR TargetFileName
;
2842 return AddSectionToCopyQueueCab(InfFile
, L
"SourceFiles", SourceCabinet
, DestinationPath
, Ir
);
2844 /* Search for the SectionName section */
2845 if (!SetupFindFirstLineW (InfFile
, SectionName
, NULL
, &FilesContext
))
2848 sprintf(Buffer
, MUIGetString(STRING_TXTSETUPFAILED
), SectionName
);
2849 PopupError(Buffer
, MUIGetString(STRING_REBOOTCOMPUTER
), Ir
, POPUP_WAIT_ENTER
);
2854 * Enumerate the files in the section
2855 * and add them to the file queue.
2859 /* Get source file name and target directory id */
2860 if (!INF_GetData (&FilesContext
, &FileKeyName
, &FileKeyValue
))
2862 /* FIXME: Handle error! */
2863 DPRINT1("INF_GetData() failed\n");
2867 /* Get target directory id */
2868 if (!INF_GetDataField (&FilesContext
, 13, &FileKeyValue
))
2870 /* FIXME: Handle error! */
2871 DPRINT1("INF_GetData() failed\n");
2875 /* Get optional target file name */
2876 if (!INF_GetDataField (&FilesContext
, 11, &TargetFileName
))
2877 TargetFileName
= NULL
;
2878 else if (!*TargetFileName
)
2879 TargetFileName
= NULL
;
2881 DPRINT ("FileKeyName: '%S' FileKeyValue: '%S'\n", FileKeyName
, FileKeyValue
);
2883 /* Lookup target directory */
2884 if (!SetupFindFirstLineW (InfFile
, L
"Directories", FileKeyValue
, &DirContext
))
2886 /* FIXME: Handle error! */
2887 DPRINT1("SetupFindFirstLine() failed\n");
2891 if (!INF_GetData (&DirContext
, NULL
, &DirKeyValue
))
2893 /* FIXME: Handle error! */
2894 DPRINT1("INF_GetData() failed\n");
2898 if (!SetupQueueCopy(SetupFileQueue
,
2900 SourceRootPath
.Buffer
,
2901 SourceRootDir
.Buffer
,
2906 /* FIXME: Handle error! */
2907 DPRINT1("SetupQueueCopy() failed\n");
2909 } while (SetupFindNextLine(&FilesContext
, &FilesContext
));
2915 PrepareCopyPageInfFile(HINF InfFile
,
2916 PWCHAR SourceCabinet
,
2919 WCHAR PathBuffer
[MAX_PATH
];
2920 INFCONTEXT DirContext
;
2921 PWCHAR AdditionalSectionName
= NULL
;
2926 /* Add common files */
2927 if (!AddSectionToCopyQueue(InfFile
, L
"SourceDisksFiles", SourceCabinet
, &DestinationPath
, Ir
))
2930 /* Add specific files depending of computer type */
2931 if (SourceCabinet
== NULL
)
2933 if (!ProcessComputerFiles(InfFile
, ComputerList
, &AdditionalSectionName
))
2936 if (AdditionalSectionName
)
2938 if (!AddSectionToCopyQueue(InfFile
, AdditionalSectionName
, SourceCabinet
, &DestinationPath
, Ir
))
2943 /* Create directories */
2947 * Install directories like '\reactos\test' are not handled yet.
2950 /* Get destination path */
2951 wcscpy(PathBuffer
, DestinationPath
.Buffer
);
2953 /* Remove trailing backslash */
2954 Length
= wcslen(PathBuffer
);
2955 if ((Length
> 0) && (PathBuffer
[Length
- 1] == '\\'))
2957 PathBuffer
[Length
- 1] = 0;
2960 /* Create the install directory */
2961 Status
= SetupCreateDirectory(PathBuffer
);
2962 if (!NT_SUCCESS(Status
) && Status
!= STATUS_OBJECT_NAME_COLLISION
)
2964 DPRINT("Creating directory '%S' failed: Status = 0x%08lx", PathBuffer
, Status
);
2965 MUIDisplayError(ERROR_CREATE_INSTALL_DIR
, Ir
, POPUP_WAIT_ENTER
);
2969 /* Search for the 'Directories' section */
2970 if (!SetupFindFirstLineW(InfFile
, L
"Directories", NULL
, &DirContext
))
2974 MUIDisplayError(ERROR_CABINET_SECTION
, Ir
, POPUP_WAIT_ENTER
);
2978 MUIDisplayError(ERROR_TXTSETUP_SECTION
, Ir
, POPUP_WAIT_ENTER
);
2984 /* Enumerate the directory values and create the subdirectories */
2987 if (!INF_GetData (&DirContext
, NULL
, &KeyValue
))
2993 if (KeyValue
[0] == L
'\\' && KeyValue
[1] != 0)
2995 DPRINT("Absolute Path: '%S'\n", KeyValue
);
2997 wcscpy(PathBuffer
, DestinationRootPath
.Buffer
);
2998 wcscat(PathBuffer
, KeyValue
);
3000 DPRINT("FullPath: '%S'\n", PathBuffer
);
3002 else if (KeyValue
[0] != L
'\\')
3004 DPRINT("RelativePath: '%S'\n", KeyValue
);
3005 wcscpy(PathBuffer
, DestinationPath
.Buffer
);
3006 wcscat(PathBuffer
, L
"\\");
3007 wcscat(PathBuffer
, KeyValue
);
3009 DPRINT("FullPath: '%S'\n", PathBuffer
);
3011 Status
= SetupCreateDirectory(PathBuffer
);
3012 if (!NT_SUCCESS(Status
) && Status
!= STATUS_OBJECT_NAME_COLLISION
)
3014 DPRINT("Creating directory '%S' failed: Status = 0x%08lx", PathBuffer
, Status
);
3015 MUIDisplayError(ERROR_CREATE_DIR
, Ir
, POPUP_WAIT_ENTER
);
3019 } while (SetupFindNextLine (&DirContext
, &DirContext
));
3025 PrepareCopyPage(PINPUT_RECORD Ir
)
3028 WCHAR PathBuffer
[MAX_PATH
];
3029 INFCONTEXT CabinetsContext
;
3035 MUIDisplayPage(PREPARE_COPY_PAGE
);
3037 /* Create the file queue */
3038 SetupFileQueue
= SetupOpenFileQueue();
3039 if (SetupFileQueue
== NULL
)
3041 MUIDisplayError(ERROR_COPY_QUEUE
, Ir
, POPUP_WAIT_ENTER
);
3045 if (!PrepareCopyPageInfFile(SetupInf
, NULL
, Ir
))
3050 /* Search for the 'Cabinets' section */
3051 if (!SetupFindFirstLineW (SetupInf
, L
"Cabinets", NULL
, &CabinetsContext
))
3053 return FILE_COPY_PAGE
;
3057 * Enumerate the directory values in the 'Cabinets'
3058 * section and parse their inf files.
3062 if (!INF_GetData (&CabinetsContext
, NULL
, &KeyValue
))
3065 wcscpy(PathBuffer
, SourcePath
.Buffer
);
3066 wcscat(PathBuffer
, L
"\\");
3067 wcscat(PathBuffer
, KeyValue
);
3070 CabinetInitialize();
3071 CabinetSetEventHandlers(NULL
, NULL
, NULL
);
3072 CabinetSetCabinetName(PathBuffer
);
3074 if (CabinetOpen() == CAB_STATUS_SUCCESS
)
3076 DPRINT("Cabinet %S\n", CabinetGetCabinetName());
3078 InfFileData
= CabinetGetCabinetReservedArea(&InfFileSize
);
3079 if (InfFileData
== NULL
)
3081 MUIDisplayError(ERROR_CABINET_SCRIPT
, Ir
, POPUP_WAIT_ENTER
);
3087 DPRINT("Cannot open cabinet: %S.\n", CabinetGetCabinetName());
3088 MUIDisplayError(ERROR_CABINET_MISSING
, Ir
, POPUP_WAIT_ENTER
);
3092 InfHandle
= INF_OpenBufferedFileA((CHAR
*) InfFileData
,
3099 if (InfHandle
== INVALID_HANDLE_VALUE
)
3101 MUIDisplayError(ERROR_INVALID_CABINET_INF
, Ir
, POPUP_WAIT_ENTER
);
3107 if (!PrepareCopyPageInfFile(InfHandle
, KeyValue
, Ir
))
3112 } while (SetupFindNextLine (&CabinetsContext
, &CabinetsContext
));
3114 return FILE_COPY_PAGE
;
3119 SetupUpdateMemoryInfo(IN PCOPYCONTEXT CopyContext
,
3122 SYSTEM_PERFORMANCE_INFORMATION PerfInfo
;
3124 /* Get the memory information from the system */
3125 NtQuerySystemInformation(SystemPerformanceInformation
,
3130 /* Check if this is initial setup */
3133 /* Set maximum limits to be total RAM pages */
3134 ProgressSetStepCount(CopyContext
->MemoryBars
[0], PerfInfo
.CommitLimit
);
3135 ProgressSetStepCount(CopyContext
->MemoryBars
[1], PerfInfo
.CommitLimit
);
3136 ProgressSetStepCount(CopyContext
->MemoryBars
[2], PerfInfo
.CommitLimit
);
3139 /* Set current values */
3140 ProgressSetStep(CopyContext
->MemoryBars
[0], PerfInfo
.PagedPoolPages
+ PerfInfo
.NonPagedPoolPages
);
3141 ProgressSetStep(CopyContext
->MemoryBars
[1], PerfInfo
.ResidentSystemCachePage
);
3142 ProgressSetStep(CopyContext
->MemoryBars
[2], PerfInfo
.AvailablePages
);
3145 static UINT CALLBACK
3146 FileCopyCallback(PVOID Context
,
3151 PCOPYCONTEXT CopyContext
;
3153 CopyContext
= (PCOPYCONTEXT
)Context
;
3155 switch (Notification
)
3157 case SPFILENOTIFY_STARTSUBQUEUE
:
3158 CopyContext
->TotalOperations
= (ULONG
)Param2
;
3159 ProgressSetStepCount(CopyContext
->ProgressBar
,
3160 CopyContext
->TotalOperations
);
3161 SetupUpdateMemoryInfo(CopyContext
, TRUE
);
3164 case SPFILENOTIFY_STARTCOPY
:
3165 /* Display copy message */
3166 CONSOLE_SetStatusTextAutoFitX (45 , MUIGetString(STRING_COPYING
), (PWSTR
)Param1
);
3167 SetupUpdateMemoryInfo(CopyContext
, FALSE
);
3170 case SPFILENOTIFY_ENDCOPY
:
3171 CopyContext
->CompletedOperations
++;
3172 ProgressNextStep(CopyContext
->ProgressBar
);
3173 SetupUpdateMemoryInfo(CopyContext
, FALSE
);
3182 FileCopyPage(PINPUT_RECORD Ir
)
3184 COPYCONTEXT CopyContext
;
3185 unsigned int mem_bar_width
;
3187 MUIDisplayPage(FILE_COPY_PAGE
);
3189 /* Create context for the copy process */
3190 CopyContext
.DestinationRootPath
= DestinationRootPath
.Buffer
;
3191 CopyContext
.InstallPath
= InstallPath
.Buffer
;
3192 CopyContext
.TotalOperations
= 0;
3193 CopyContext
.CompletedOperations
= 0;
3195 /* Create the progress bar as well */
3196 CopyContext
.ProgressBar
= CreateProgressBar(13,
3203 MUIGetString(STRING_SETUPCOPYINGFILES
));
3205 // fit memory bars to screen width, distribute them uniform
3206 mem_bar_width
= (xScreen
- 26) / 5;
3207 mem_bar_width
-= mem_bar_width
% 2; // make even
3208 /* ATTENTION: The following progress bars are debug stuff, which should not be translated!! */
3209 /* Create the paged pool progress bar */
3210 CopyContext
.MemoryBars
[0] = CreateProgressBar(13,
3219 /* Create the non paged pool progress bar */
3220 CopyContext
.MemoryBars
[1] = CreateProgressBar((xScreen
/ 2)- (mem_bar_width
/ 2),
3222 (xScreen
/ 2) + (mem_bar_width
/ 2),
3224 (xScreen
/ 2)- (mem_bar_width
/ 2),
3229 /* Create the global memory progress bar */
3230 CopyContext
.MemoryBars
[2] = CreateProgressBar(xScreen
- 13 - mem_bar_width
,
3234 xScreen
- 13 - mem_bar_width
,
3239 /* Do the file copying */
3240 SetupCommitFileQueueW(NULL
,
3245 /* If we get here, we're done, so cleanup the queue and progress bar */
3246 SetupCloseFileQueue(SetupFileQueue
);
3247 DestroyProgressBar(CopyContext
.ProgressBar
);
3248 DestroyProgressBar(CopyContext
.MemoryBars
[0]);
3249 DestroyProgressBar(CopyContext
.MemoryBars
[1]);
3250 DestroyProgressBar(CopyContext
.MemoryBars
[2]);
3252 /* Go display the next page */
3253 return REGISTRY_PAGE
;
3257 RegistryPage(PINPUT_RECORD Ir
)
3259 INFCONTEXT InfContext
;
3266 MUIDisplayPage(REGISTRY_PAGE
);
3268 if (RepairUpdateFlag
)
3270 return SUCCESS_PAGE
;
3273 if (!SetInstallPathValue(&DestinationPath
))
3275 DPRINT("SetInstallPathValue() failed\n");
3276 MUIDisplayError(ERROR_INITIALIZE_REGISTRY
, Ir
, POPUP_WAIT_ENTER
);
3280 /* Create the default hives */
3282 Status
= NtInitializeRegistry(CM_BOOT_FLAG_SETUP
);
3283 if (!NT_SUCCESS(Status
))
3285 DPRINT("NtInitializeRegistry() failed (Status %lx)\n", Status
);
3286 MUIDisplayError(ERROR_CREATE_HIVE
, Ir
, POPUP_WAIT_ENTER
);
3290 RegInitializeRegistry();
3293 /* Update registry */
3294 CONSOLE_SetStatusText(MUIGetString(STRING_REGHIVEUPDATE
));
3296 if (!SetupFindFirstLineW(SetupInf
, L
"HiveInfs.Install", NULL
, &InfContext
))
3298 DPRINT1("SetupFindFirstLine() failed\n");
3299 MUIDisplayError(ERROR_FIND_REGISTRY
, Ir
, POPUP_WAIT_ENTER
);
3305 INF_GetDataField (&InfContext
, 0, &Action
);
3306 INF_GetDataField (&InfContext
, 1, &File
);
3307 INF_GetDataField (&InfContext
, 2, &Section
);
3309 DPRINT("Action: %S File: %S Section %S\n", Action
, File
, Section
);
3311 if (Action
== NULL
) break; // Hackfix
3313 if (!_wcsicmp (Action
, L
"AddReg"))
3317 else if (!_wcsicmp (Action
, L
"DelReg"))
3326 CONSOLE_SetStatusText(MUIGetString(STRING_IMPORTFILE
), File
);
3328 if (!ImportRegistryFile(File
, Section
, LanguageId
, Delete
))
3330 DPRINT("Importing %S failed\n", File
);
3332 MUIDisplayError(ERROR_IMPORT_HIVE
, Ir
, POPUP_WAIT_ENTER
);
3335 } while (SetupFindNextLine (&InfContext
, &InfContext
));
3337 /* Update display registry settings */
3338 CONSOLE_SetStatusText(MUIGetString(STRING_DISPLAYETTINGSUPDATE
));
3339 if (!ProcessDisplayRegistry(SetupInf
, DisplayList
))
3341 MUIDisplayError(ERROR_UPDATE_DISPLAY_SETTINGS
, Ir
, POPUP_WAIT_ENTER
);
3345 /* Set the locale */
3346 CONSOLE_SetStatusText(MUIGetString(STRING_LOCALESETTINGSUPDATE
));
3347 if (!ProcessLocaleRegistry(LanguageList
))
3349 MUIDisplayError(ERROR_UPDATE_LOCALESETTINGS
, Ir
, POPUP_WAIT_ENTER
);
3353 /* Add keyboard layouts */
3354 CONSOLE_SetStatusText(MUIGetString(STRING_ADDKBLAYOUTS
));
3355 if (!AddKeyboardLayouts())
3357 MUIDisplayError(ERROR_ADDING_KBLAYOUTS
, Ir
, POPUP_WAIT_ENTER
);
3363 if (!SetGeoID(MUIGetGeoID()))
3365 MUIDisplayError(ERROR_UPDATE_GEOID
, Ir
, POPUP_WAIT_ENTER
);
3369 if (!IsUnattendedSetup
){
3371 /* Update keyboard layout settings */
3372 CONSOLE_SetStatusText(MUIGetString(STRING_KEYBOARDSETTINGSUPDATE
));
3373 if (!ProcessKeyboardLayoutRegistry(LayoutList
))
3375 MUIDisplayError(ERROR_UPDATE_KBSETTINGS
, Ir
, POPUP_WAIT_ENTER
);
3379 /* Add codepage information to registry */
3380 CONSOLE_SetStatusText(MUIGetString(STRING_CODEPAGEINFOUPDATE
));
3383 MUIDisplayError(ERROR_ADDING_CODEPAGE
, Ir
, POPUP_WAIT_ENTER
);
3387 /* Update the mounted devices list */
3388 SetMountedDeviceValues(PartitionList
);
3390 CONSOLE_SetStatusText(MUIGetString(STRING_DONE
));
3392 return BOOT_LOADER_PAGE
;
3397 BootLoaderPage(PINPUT_RECORD Ir
)
3399 UCHAR PartitionType
;
3400 BOOLEAN InstallOnFloppy
;
3403 CONSOLE_SetStatusText(MUIGetString(STRING_PLEASEWAIT
));
3405 PartitionType
= PartitionList
->ActiveBootPartition
->
3406 PartInfo
[PartitionList
->ActiveBootPartitionNumber
].PartitionType
;
3408 if (IsUnattendedSetup
)
3410 if (UnattendMBRInstallType
== 0) /* skip MBR installation */
3412 return SUCCESS_PAGE
;
3414 else if (UnattendMBRInstallType
== 1) /* install on floppy */
3416 return BOOT_LOADER_FLOPPY_PAGE
;
3420 if (PartitionType
== PARTITION_ENTRY_UNUSED
)
3422 DPRINT("Error: active partition invalid (unused)\n");
3423 InstallOnFloppy
= TRUE
;
3425 else if (PartitionType
== 0x0A)
3427 /* OS/2 boot manager partition */
3428 DPRINT("Found OS/2 boot manager partition\n");
3429 InstallOnFloppy
= TRUE
;
3431 else if (PartitionType
== 0x83)
3433 /* Linux ext2 partition */
3434 DPRINT("Found Linux ext2 partition\n");
3435 InstallOnFloppy
= TRUE
;
3437 else if (PartitionType
== PARTITION_IFS
)
3439 /* NTFS partition */
3440 DPRINT("Found NTFS partition\n");
3441 InstallOnFloppy
= TRUE
;
3443 else if ((PartitionType
== PARTITION_FAT_12
) ||
3444 (PartitionType
== PARTITION_FAT_16
) ||
3445 (PartitionType
== PARTITION_HUGE
) ||
3446 (PartitionType
== PARTITION_XINT13
) ||
3447 (PartitionType
== PARTITION_FAT32
) ||
3448 (PartitionType
== PARTITION_FAT32_XINT13
))
3450 DPRINT("Found FAT partition\n");
3451 InstallOnFloppy
= FALSE
;
3455 /* Unknown partition */
3456 DPRINT("Unknown partition found\n");
3457 InstallOnFloppy
= TRUE
;
3460 if (InstallOnFloppy
== TRUE
)
3462 return BOOT_LOADER_FLOPPY_PAGE
;
3465 /* Unattended install on hdd? */
3466 if (IsUnattendedSetup
&& UnattendMBRInstallType
== 2)
3468 return BOOT_LOADER_HARDDISK_PAGE
;
3471 MUIDisplayPage(BOOT_LOADER_PAGE
);
3472 CONSOLE_InvertTextXY(8, Line
, 60, 1);
3476 CONSOLE_ConInKey(Ir
);
3478 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
3479 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
)) /* DOWN */
3481 CONSOLE_NormalTextXY(8, Line
, 60, 1);
3484 if (Line
<12) Line
=14;
3485 if (Line
>14) Line
=12;
3487 CONSOLE_InvertTextXY(8, Line
, 60, 1);
3489 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
3490 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_UP
)) /* UP */
3492 CONSOLE_NormalTextXY(8, Line
, 60, 1);
3495 if (Line
<12) Line
=14;
3496 if (Line
>14) Line
=12;
3498 CONSOLE_InvertTextXY(8, Line
, 60, 1);
3500 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
3501 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
3503 if (ConfirmQuit(Ir
) == TRUE
)
3508 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
3512 return BOOT_LOADER_HARDDISK_PAGE
;
3514 else if (Line
== 13)
3516 return BOOT_LOADER_FLOPPY_PAGE
;
3518 else if (Line
== 14)
3520 return SUCCESS_PAGE
;
3523 return BOOT_LOADER_PAGE
;
3527 return BOOT_LOADER_PAGE
;
3532 BootLoaderFloppyPage(PINPUT_RECORD Ir
)
3536 MUIDisplayPage(BOOT_LOADER_FLOPPY_PAGE
);
3538 // SetStatusText(" Please wait...");
3542 CONSOLE_ConInKey(Ir
);
3544 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
3545 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
3547 if (ConfirmQuit(Ir
) == TRUE
)
3552 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
3554 if (DoesFileExist(L
"\\Device\\Floppy0", L
"\\") == FALSE
)
3556 MUIDisplayError(ERROR_NO_FLOPPY
, Ir
, POPUP_WAIT_ENTER
);
3557 return BOOT_LOADER_FLOPPY_PAGE
;
3560 Status
= InstallFatBootcodeToFloppy(&SourceRootPath
, &DestinationArcPath
);
3561 if (!NT_SUCCESS(Status
))
3563 /* Print error message */
3564 return BOOT_LOADER_FLOPPY_PAGE
;
3567 return SUCCESS_PAGE
;
3571 return BOOT_LOADER_FLOPPY_PAGE
;
3576 BootLoaderHarddiskPage(PINPUT_RECORD Ir
)
3578 UCHAR PartitionType
;
3581 PartitionType
= PartitionList
->ActiveBootPartition
->
3582 PartInfo
[PartitionList
->ActiveBootPartitionNumber
].PartitionType
;
3583 if ((PartitionType
== PARTITION_FAT_12
) ||
3584 (PartitionType
== PARTITION_FAT_16
) ||
3585 (PartitionType
== PARTITION_HUGE
) ||
3586 (PartitionType
== PARTITION_XINT13
) ||
3587 (PartitionType
== PARTITION_FAT32
) ||
3588 (PartitionType
== PARTITION_FAT32_XINT13
))
3590 Status
= InstallFatBootcodeToPartition(&SystemRootPath
,
3592 &DestinationArcPath
,
3594 if (!NT_SUCCESS(Status
))
3596 MUIDisplayError(ERROR_INSTALL_BOOTCODE
, Ir
, POPUP_WAIT_ENTER
);
3600 return SUCCESS_PAGE
;
3604 MUIDisplayError(ERROR_WRITE_BOOT
, Ir
, POPUP_WAIT_ENTER
);
3608 return BOOT_LOADER_HARDDISK_PAGE
;
3613 QuitPage(PINPUT_RECORD Ir
)
3615 MUIDisplayPage(QUIT_PAGE
);
3617 /* Destroy partition list */
3618 if (PartitionList
!= NULL
)
3620 DestroyPartitionList (PartitionList
);
3621 PartitionList
= NULL
;
3624 /* Destroy filesystem list */
3625 if (FileSystemList
!= NULL
)
3627 DestroyFileSystemList (FileSystemList
);
3628 FileSystemList
= NULL
;
3631 /* Destroy computer settings list */
3632 if (ComputerList
!= NULL
)
3634 DestroyGenericList(ComputerList
, TRUE
);
3635 ComputerList
= NULL
;
3638 /* Destroy display settings list */
3639 if (DisplayList
!= NULL
)
3641 DestroyGenericList(DisplayList
, TRUE
);
3645 /* Destroy keyboard settings list */
3646 if (KeyboardList
!= NULL
)
3648 DestroyGenericList(KeyboardList
, TRUE
);
3649 KeyboardList
= NULL
;
3652 /* Destroy keyboard layout list */
3653 if (LayoutList
!= NULL
)
3655 DestroyGenericList(LayoutList
, TRUE
);
3659 if (LanguageList
!= NULL
)
3661 DestroyGenericList(LanguageList
, FALSE
);
3662 LanguageList
= NULL
;
3665 CONSOLE_SetStatusText(MUIGetString(STRING_REBOOTCOMPUTER2
));
3669 CONSOLE_ConInKey(Ir
);
3671 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
3680 SuccessPage(PINPUT_RECORD Ir
)
3682 MUIDisplayPage(SUCCESS_PAGE
);
3684 if (IsUnattendedSetup
)
3691 CONSOLE_ConInKey(Ir
);
3693 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
3702 FlushPage(PINPUT_RECORD Ir
)
3704 MUIDisplayPage(FLUSH_PAGE
);
3710 PnpEventThread(IN LPVOID lpParameter
);
3720 NtQuerySystemTime(&Time
);
3722 Status
= RtlCreateUserThread(NtCurrentProcess(), NULL
, TRUE
, 0, 0, 0, PnpEventThread
, &SetupInf
, &hPnpThread
, NULL
);
3723 if (!NT_SUCCESS(Status
))
3724 hPnpThread
= INVALID_HANDLE_VALUE
;
3726 if (!CONSOLE_Init())
3728 PrintString(MUIGetString(STRING_CONSOLEFAIL1
));
3729 PrintString(MUIGetString(STRING_CONSOLEFAIL2
));
3730 PrintString(MUIGetString(STRING_CONSOLEFAIL3
));
3732 /* Raise a hard error (crash the system/BSOD) */
3733 NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED
,
3737 /* Initialize global unicode strings */
3738 RtlInitUnicodeString(&SourcePath
, NULL
);
3739 RtlInitUnicodeString(&SourceRootPath
, NULL
);
3740 RtlInitUnicodeString(&SourceRootDir
, NULL
);
3741 RtlInitUnicodeString(&InstallPath
, NULL
);
3742 RtlInitUnicodeString(&DestinationPath
, NULL
);
3743 RtlInitUnicodeString(&DestinationArcPath
, NULL
);
3744 RtlInitUnicodeString(&DestinationRootPath
, NULL
);
3745 RtlInitUnicodeString(&SystemRootPath
, NULL
);
3747 /* Hide the cursor */
3748 CONSOLE_SetCursorType(TRUE
, FALSE
);
3751 while (Page
!= REBOOT_PAGE
)
3753 CONSOLE_ClearScreen();
3756 //CONSOLE_SetUnderlinedTextXY(4, 3, " ReactOS " KERNEL_VERSION_STR " Setup ");
3763 Page
= SetupStartPage(&Ir
);
3768 Page
= LanguagePage(&Ir
);
3773 Page
= LicensePage(&Ir
);
3778 Page
= IntroPage(&Ir
);
3782 case INSTALL_INTRO_PAGE
:
3783 Page
= InstallIntroPage(&Ir
);
3787 case SCSI_CONTROLLER_PAGE
:
3788 Page
= ScsiControllerPage(&Ir
);
3793 case OEM_DRIVER_PAGE
:
3794 Page
= OemDriverPage(&Ir
);
3798 case DEVICE_SETTINGS_PAGE
:
3799 Page
= DeviceSettingsPage(&Ir
);
3802 case COMPUTER_SETTINGS_PAGE
:
3803 Page
= ComputerSettingsPage(&Ir
);
3806 case DISPLAY_SETTINGS_PAGE
:
3807 Page
= DisplaySettingsPage(&Ir
);
3810 case KEYBOARD_SETTINGS_PAGE
:
3811 Page
= KeyboardSettingsPage(&Ir
);
3814 case LAYOUT_SETTINGS_PAGE
:
3815 Page
= LayoutSettingsPage(&Ir
);
3818 case SELECT_PARTITION_PAGE
:
3819 Page
= SelectPartitionPage(&Ir
);
3822 case CREATE_PARTITION_PAGE
:
3823 Page
= CreatePartitionPage(&Ir
);
3826 case DELETE_PARTITION_PAGE
:
3827 Page
= DeletePartitionPage(&Ir
);
3830 case SELECT_FILE_SYSTEM_PAGE
:
3831 Page
= SelectFileSystemPage(&Ir
);
3834 case FORMAT_PARTITION_PAGE
:
3835 Page
= (PAGE_NUMBER
) FormatPartitionPage(&Ir
);
3838 case CHECK_FILE_SYSTEM_PAGE
:
3839 Page
= (PAGE_NUMBER
) CheckFileSystemPage(&Ir
);
3842 case INSTALL_DIRECTORY_PAGE
:
3843 Page
= InstallDirectoryPage(&Ir
);
3846 case PREPARE_COPY_PAGE
:
3847 Page
= PrepareCopyPage(&Ir
);
3850 case FILE_COPY_PAGE
:
3851 Page
= FileCopyPage(&Ir
);
3855 Page
= RegistryPage(&Ir
);
3858 case BOOT_LOADER_PAGE
:
3859 Page
= BootLoaderPage(&Ir
);
3862 case BOOT_LOADER_FLOPPY_PAGE
:
3863 Page
= BootLoaderFloppyPage(&Ir
);
3866 case BOOT_LOADER_HARDDISK_PAGE
:
3867 Page
= BootLoaderHarddiskPage(&Ir
);
3871 case REPAIR_INTRO_PAGE
:
3872 Page
= RepairIntroPage(&Ir
);
3876 Page
= SuccessPage(&Ir
);
3880 Page
= FlushPage(&Ir
);
3884 Page
= QuitPage(&Ir
);
3894 /* Avoid bugcheck */
3895 Time
.QuadPart
+= 50000000;
3896 NtDelayExecution(FALSE
, &Time
);
3899 NtShutdownSystem(ShutdownReboot
);
3900 NtTerminateProcess(NtCurrentProcess(), 0);
3907 NtProcessStartup(PPEB Peb
)
3909 RtlNormalizeProcessParams(Peb
->ProcessParameters
);
3911 ProcessHeap
= Peb
->ProcessHeap
;
3912 INF_SetHeap(ProcessHeap
);
3915 #endif /* __REACTOS__ */