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)
41 /* GLOBALS ******************************************************************/
44 UNICODE_STRING SourceRootPath
;
45 UNICODE_STRING SourceRootDir
;
46 UNICODE_STRING SourcePath
;
47 BOOLEAN IsUnattendedSetup
= FALSE
;
48 LONG UnattendDestinationDiskNumber
;
49 LONG UnattendDestinationPartitionNumber
;
50 LONG UnattendMBRInstallType
= -1;
51 LONG UnattendFormatPartition
= 0;
52 LONG AutoPartition
= 0;
53 WCHAR UnattendInstallationDirectory
[MAX_PATH
];
54 PWCHAR SelectedLanguageId
;
56 WCHAR DefaultLanguage
[20];
57 WCHAR DefaultKBLayout
[20];
58 BOOLEAN RepairUpdateFlag
= FALSE
;
59 HANDLE hPnpThread
= INVALID_HANDLE_VALUE
;
60 PPARTLIST PartitionList
= NULL
;
62 /* LOCALS *******************************************************************/
64 static PFILE_SYSTEM_LIST FileSystemList
= NULL
;
66 static UNICODE_STRING InstallPath
;
68 /* Path to the install directory */
69 static UNICODE_STRING DestinationPath
;
70 static UNICODE_STRING DestinationArcPath
;
71 static UNICODE_STRING DestinationRootPath
;
73 static WCHAR DestinationDriveLetter
;
75 /* Path to the active partition (boot manager) */
76 static UNICODE_STRING SystemRootPath
;
80 static HSPFILEQ SetupFileQueue
= NULL
;
82 static BOOLEAN WarnLinuxPartitions
= TRUE
;
84 static PGENERIC_LIST ComputerList
= NULL
;
85 static PGENERIC_LIST DisplayList
= NULL
;
86 static PGENERIC_LIST KeyboardList
= NULL
;
87 static PGENERIC_LIST LayoutList
= NULL
;
88 static PGENERIC_LIST LanguageList
= NULL
;
90 static LANGID LanguageId
= 0;
92 static ULONG RequiredPartitionDiskSpace
= ~0;
94 /* FUNCTIONS ****************************************************************/
97 PrintString(char* fmt
,...)
101 UNICODE_STRING UnicodeString
;
102 ANSI_STRING AnsiString
;
105 vsprintf(buffer
, fmt
, ap
);
108 RtlInitAnsiString(&AnsiString
, buffer
);
109 RtlAnsiStringToUnicodeString(&UnicodeString
, &AnsiString
, TRUE
);
110 NtDisplayString(&UnicodeString
);
111 RtlFreeUnicodeString(&UnicodeString
);
116 DrawBox(IN SHORT xLeft
,
124 /* draw upper left corner */
127 FillConsoleOutputCharacterA(StdOutput
,
133 /* draw upper edge */
136 FillConsoleOutputCharacterA(StdOutput
,
142 /* draw upper right corner */
143 coPos
.X
= xLeft
+ Width
- 1;
145 FillConsoleOutputCharacterA(StdOutput
,
151 /* Draw right edge, inner space and left edge */
152 for (coPos
.Y
= yTop
+ 1; coPos
.Y
< yTop
+ Height
- 1; coPos
.Y
++)
155 FillConsoleOutputCharacterA(StdOutput
,
162 FillConsoleOutputCharacterA(StdOutput
,
168 coPos
.X
= xLeft
+ Width
- 1;
169 FillConsoleOutputCharacterA(StdOutput
,
176 /* draw lower left corner */
178 coPos
.Y
= yTop
+ Height
- 1;
179 FillConsoleOutputCharacterA(StdOutput
,
185 /* draw lower edge */
187 coPos
.Y
= yTop
+ Height
- 1;
188 FillConsoleOutputCharacterA(StdOutput
,
194 /* draw lower right corner */
195 coPos
.X
= xLeft
+ Width
- 1;
196 coPos
.Y
= yTop
+ Height
- 1;
197 FillConsoleOutputCharacterA(StdOutput
,
206 PopupError(PCCH Text
,
224 /* Count text lines and longest line */
231 p
= strchr(pnext
, '\n');
235 Length
= strlen(pnext
);
240 Length
= (ULONG
)(p
- pnext
);
246 if (Length
> MaxLength
)
249 if (LastLine
== TRUE
)
255 /* Check length of status line */
258 Length
= strlen(Status
);
260 if (Length
> MaxLength
)
264 Width
= MaxLength
+ 4;
270 yTop
= (yScreen
- Height
) / 2;
271 xLeft
= (xScreen
- Width
) / 2;
274 /* Set screen attributes */
276 for (coPos
.Y
= yTop
; coPos
.Y
< yTop
+ Height
; coPos
.Y
++)
278 FillConsoleOutputAttribute(StdOutput
,
279 FOREGROUND_RED
| BACKGROUND_WHITE
,
285 DrawBox(xLeft
, yTop
, Width
, Height
);
287 /* Print message text */
292 p
= strchr(pnext
, '\n');
296 Length
= strlen(pnext
);
301 Length
= (ULONG
)(p
- pnext
);
308 WriteConsoleOutputCharacterA(StdOutput
,
315 if (LastLine
== TRUE
)
322 /* Print separator line and status text */
325 coPos
.Y
= yTop
+ Height
- 3;
327 FillConsoleOutputCharacterA(StdOutput
,
334 FillConsoleOutputCharacterA(StdOutput
,
340 coPos
.X
= xLeft
+ Width
- 1;
341 FillConsoleOutputCharacterA(StdOutput
,
349 WriteConsoleOutputCharacterA(StdOutput
,
351 min(strlen(Status
), (SIZE_T
)Width
- 4),
356 if (WaitEvent
== POPUP_WAIT_NONE
)
361 CONSOLE_ConInKey(Ir
);
363 if (WaitEvent
== POPUP_WAIT_ANY_KEY
||
364 Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D)
376 * FALSE: Don't quit setup.
379 ConfirmQuit(PINPUT_RECORD Ir
)
382 MUIDisplayError(ERROR_NOT_INSTALLED
, NULL
, POPUP_WAIT_NONE
);
386 CONSOLE_ConInKey(Ir
);
388 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
389 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
394 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
406 CheckUnattendedSetup(VOID
)
408 WCHAR UnattendInfPath
[MAX_PATH
];
415 if (DoesFileExist(SourcePath
.Buffer
, L
"unattend.inf") == FALSE
)
417 DPRINT("Does not exist: %S\\%S\n", SourcePath
.Buffer
, L
"unattend.inf");
421 wcscpy(UnattendInfPath
, SourcePath
.Buffer
);
422 wcscat(UnattendInfPath
, L
"\\unattend.inf");
424 /* Load 'unattend.inf' from install media. */
425 UnattendInf
= SetupOpenInfFileW(UnattendInfPath
,
431 if (UnattendInf
== INVALID_HANDLE_VALUE
)
433 DPRINT("SetupOpenInfFileW() failed\n");
437 /* Open 'Unattend' section */
438 if (!SetupFindFirstLineW(UnattendInf
, L
"Unattend", L
"Signature", &Context
))
440 DPRINT("SetupFindFirstLineW() failed for section 'Unattend'\n");
441 SetupCloseInfFile(UnattendInf
);
445 /* Get pointer 'Signature' key */
446 if (!INF_GetData(&Context
, NULL
, &Value
))
448 DPRINT("INF_GetData() failed for key 'Signature'\n");
449 SetupCloseInfFile(UnattendInf
);
453 /* Check 'Signature' string */
454 if (_wcsicmp(Value
, L
"$ReactOS$") != 0)
456 DPRINT("Signature not $ReactOS$\n");
457 SetupCloseInfFile(UnattendInf
);
461 /* Check if Unattend setup is enabled */
462 if (!SetupFindFirstLineW(UnattendInf
, L
"Unattend", L
"UnattendSetupEnabled", &Context
))
464 DPRINT("Can't find key 'UnattendSetupEnabled'\n");
465 SetupCloseInfFile(UnattendInf
);
469 if (!INF_GetData(&Context
, NULL
, &Value
))
471 DPRINT("Can't read key 'UnattendSetupEnabled'\n");
472 SetupCloseInfFile(UnattendInf
);
476 if (_wcsicmp(Value
, L
"yes") != 0)
478 DPRINT("Unattend setup is disabled by 'UnattendSetupEnabled' key!\n");
479 SetupCloseInfFile(UnattendInf
);
483 /* Search for 'DestinationDiskNumber' in the 'Unattend' section */
484 if (!SetupFindFirstLineW(UnattendInf
, L
"Unattend", L
"DestinationDiskNumber", &Context
))
486 DPRINT("SetupFindFirstLine() failed for key 'DestinationDiskNumber'\n");
487 SetupCloseInfFile(UnattendInf
);
491 if (!SetupGetIntField(&Context
, 1, &IntValue
))
493 DPRINT("SetupGetIntField() failed for key 'DestinationDiskNumber'\n");
494 SetupCloseInfFile(UnattendInf
);
498 UnattendDestinationDiskNumber
= (LONG
)IntValue
;
500 /* Search for 'DestinationPartitionNumber' in the 'Unattend' section */
501 if (!SetupFindFirstLineW(UnattendInf
, L
"Unattend", L
"DestinationPartitionNumber", &Context
))
503 DPRINT("SetupFindFirstLine() failed for key 'DestinationPartitionNumber'\n");
504 SetupCloseInfFile(UnattendInf
);
508 if (!SetupGetIntField(&Context
, 1, &IntValue
))
510 DPRINT("SetupGetIntField() failed for key 'DestinationPartitionNumber'\n");
511 SetupCloseInfFile(UnattendInf
);
515 UnattendDestinationPartitionNumber
= IntValue
;
517 /* Search for 'InstallationDirectory' in the 'Unattend' section */
518 if (!SetupFindFirstLineW(UnattendInf
, L
"Unattend", L
"InstallationDirectory", &Context
))
520 DPRINT("SetupFindFirstLine() failed for key 'InstallationDirectory'\n");
521 SetupCloseInfFile(UnattendInf
);
525 /* Get pointer 'InstallationDirectory' key */
526 if (!INF_GetData(&Context
, NULL
, &Value
))
528 DPRINT("INF_GetData() failed for key 'InstallationDirectory'\n");
529 SetupCloseInfFile(UnattendInf
);
533 wcscpy(UnattendInstallationDirectory
, Value
);
535 IsUnattendedSetup
= TRUE
;
537 /* Search for 'MBRInstallType' in the 'Unattend' section */
538 if (SetupFindFirstLineW(UnattendInf
, L
"Unattend", L
"MBRInstallType", &Context
))
540 if (SetupGetIntField(&Context
, 1, &IntValue
))
542 UnattendMBRInstallType
= IntValue
;
546 /* Search for 'FormatPartition' in the 'Unattend' section */
547 if (SetupFindFirstLineW(UnattendInf
, L
"Unattend", L
"FormatPartition", &Context
))
549 if (SetupGetIntField(&Context
, 1, &IntValue
))
551 UnattendFormatPartition
= IntValue
;
555 if (SetupFindFirstLineW(UnattendInf
, L
"Unattend", L
"AutoPartition", &Context
))
557 if (SetupGetIntField(&Context
, 1, &IntValue
))
559 AutoPartition
= IntValue
;
563 /* search for LocaleID in the 'Unattend' section*/
564 if (SetupFindFirstLineW (UnattendInf
, L
"Unattend", L
"LocaleID", &Context
))
566 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");
582 PGENERIC_LIST_ENTRY ListEntry
;
583 LPCWSTR pszNewLayout
;
585 pszNewLayout
= MUIDefaultKeyboardLayout();
587 if (LayoutList
== NULL
)
589 LayoutList
= CreateKeyboardLayoutList(SetupInf
, DefaultKBLayout
);
590 if (LayoutList
== NULL
)
592 /* FIXME: Handle error! */
597 ListEntry
= GetFirstListEntry(LayoutList
);
599 /* Search for default layout (if provided) */
600 if (pszNewLayout
!= NULL
)
602 while (ListEntry
!= NULL
)
604 if (!wcscmp(pszNewLayout
, GetListEntryUserData(ListEntry
)))
606 SetCurrentListEntry(LayoutList
, ListEntry
);
610 ListEntry
= GetNextListEntry(ListEntry
);
617 LanguagePage(PINPUT_RECORD Ir
)
619 PWCHAR NewLanguageId
;
620 BOOL RefreshPage
= FALSE
;
622 /* Initialize the computer settings list */
623 if (LanguageList
== NULL
)
625 LanguageList
= CreateLanguageList(SetupInf
, DefaultLanguage
);
627 if (LanguageList
== NULL
)
629 PopupError("Setup failed to initialize available translations", NULL
, NULL
, POPUP_WAIT_NONE
);
635 SelectedLanguageId
= DefaultLanguage
;
636 SetConsoleCodePage();
638 DrawGenericList(LanguageList
,
644 ScrollToPositionGenericList (LanguageList
, GetDefaultLanguageIndex());
646 MUIDisplayPage(LANGUAGE_PAGE
);
650 CONSOLE_ConInKey(Ir
);
652 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
653 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
)) /* DOWN */
655 ScrollDownGenericList (LanguageList
);
658 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
659 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_UP
)) /* UP */
661 ScrollUpGenericList(LanguageList
);
664 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
665 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_NEXT
)) /* PAGE DOWN */
667 ScrollPageDownGenericList(LanguageList
);
670 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
671 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_PRIOR
)) /* PAGE UP */
673 ScrollPageUpGenericList(LanguageList
);
676 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
677 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
679 if (ConfirmQuit(Ir
) == TRUE
)
682 RedrawGenericList(LanguageList
);
684 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
686 SelectedLanguageId
= (PWCHAR
)GetListEntryUserData(GetCurrentListEntry(LanguageList
));
688 LanguageId
= (LANGID
)(wcstol(SelectedLanguageId
, NULL
, 16) & 0xFFFF);
690 if (wcscmp(SelectedLanguageId
, DefaultLanguage
))
696 SetConsoleCodePage();
700 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
> 0x60) && (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
< 0x7b))
703 GenericListKeyPress (LanguageList
, Ir
->Event
.KeyEvent
.uChar
.AsciiChar
);
709 NewLanguageId
= (PWCHAR
)GetListEntryUserData(GetCurrentListEntry(LanguageList
));
711 if (SelectedLanguageId
!= NewLanguageId
)
713 /* Clear the language page */
714 MUIClearPage(LANGUAGE_PAGE
);
716 SelectedLanguageId
= NewLanguageId
;
719 SetConsoleCodePage();
721 /* Redraw language selection page in native language */
722 MUIDisplayPage(LANGUAGE_PAGE
);
736 * Number of the next page.
739 SetupStartPage(PINPUT_RECORD Ir
)
741 //SYSTEM_DEVICE_INFORMATION Sdi;
743 WCHAR FileNameBuffer
[MAX_PATH
];
748 PGENERIC_LIST_ENTRY ListEntry
;
751 CONSOLE_SetStatusText(MUIGetString(STRING_PLEASEWAIT
));
754 /* Check whether a harddisk is available */
755 Status
= NtQuerySystemInformation(SystemDeviceInformation
,
757 sizeof(SYSTEM_DEVICE_INFORMATION
),
760 if (!NT_SUCCESS(Status
))
762 CONSOLE_PrintTextXY(6, 15, "NtQuerySystemInformation() failed (Status 0x%08lx)", Status
);
763 MUIDisplayError(ERROR_DRIVE_INFORMATION
, Ir
, POPUP_WAIT_ENTER
);
767 if (Sdi
.NumberOfDisks
== 0)
769 MUIDisplayError(ERROR_NO_HDD
, Ir
, POPUP_WAIT_ENTER
);
774 /* Get the source path and source root path */
775 Status
= GetSourcePaths(&SourcePath
,
779 if (!NT_SUCCESS(Status
))
781 CONSOLE_PrintTextXY(6, 15, "GetSourcePaths() failed (Status 0x%08lx)", Status
);
782 MUIDisplayError(ERROR_NO_SOURCE_DRIVE
, Ir
, POPUP_WAIT_ENTER
);
788 CONSOLE_PrintTextXY(6, 15, "SourcePath: '%wZ'", &SourcePath
);
789 CONSOLE_PrintTextXY(6, 16, "SourceRootPath: '%wZ'", &SourceRootPath
);
790 CONSOLE_PrintTextXY(6, 17, "SourceRootDir: '%wZ'", &SourceRootDir
);
794 /* Load txtsetup.sif from install media. */
795 wcscpy(FileNameBuffer
, SourcePath
.Buffer
);
796 wcscat(FileNameBuffer
, L
"\\txtsetup.sif");
798 SetupInf
= SetupOpenInfFileW(FileNameBuffer
,
804 if (SetupInf
== INVALID_HANDLE_VALUE
)
806 MUIDisplayError(ERROR_LOAD_TXTSETUPSIF
, Ir
, POPUP_WAIT_ENTER
);
810 /* Open 'Version' section */
811 if (!SetupFindFirstLineW(SetupInf
, L
"Version", L
"Signature", &Context
))
813 MUIDisplayError(ERROR_CORRUPT_TXTSETUPSIF
, Ir
, POPUP_WAIT_ENTER
);
817 /* Get pointer 'Signature' key */
818 if (!INF_GetData(&Context
, NULL
, &Value
))
820 MUIDisplayError(ERROR_CORRUPT_TXTSETUPSIF
, Ir
, POPUP_WAIT_ENTER
);
824 /* Check 'Signature' string */
825 if (_wcsicmp(Value
, L
"$ReactOS$") != 0)
827 MUIDisplayError(ERROR_SIGNATURE_TXTSETUPSIF
, Ir
, POPUP_WAIT_ENTER
);
831 /* Open 'DiskSpaceRequirements' section */
832 if (!SetupFindFirstLineW(SetupInf
, L
"DiskSpaceRequirements", L
"FreeSysPartDiskSpace", &Context
))
834 MUIDisplayError(ERROR_CORRUPT_TXTSETUPSIF
, Ir
, POPUP_WAIT_ENTER
);
838 /* Get the 'FreeSysPartDiskSpace' value */
839 if (!SetupGetIntField(&Context
, 1, &IntValue
))
841 MUIDisplayError(ERROR_CORRUPT_TXTSETUPSIF
, Ir
, POPUP_WAIT_ENTER
);
845 RequiredPartitionDiskSpace
= (ULONG
)IntValue
;
847 /* Start PnP thread */
848 if (hPnpThread
!= INVALID_HANDLE_VALUE
)
850 NtResumeThread(hPnpThread
, NULL
);
851 hPnpThread
= INVALID_HANDLE_VALUE
;
854 CheckUnattendedSetup();
856 if (IsUnattendedSetup
)
859 //read options from inf
860 ComputerList
= CreateComputerTypeList(SetupInf
);
861 DisplayList
= CreateDisplayDriverList(SetupInf
);
862 KeyboardList
= CreateKeyboardDriverList(SetupInf
);
863 LayoutList
= CreateKeyboardLayoutList(SetupInf
, DefaultKBLayout
);
864 LanguageList
= CreateLanguageList(SetupInf
, DefaultLanguage
);
867 wcscpy(SelectedLanguageId
,LocaleID
);
869 /* first we hack LanguageList */
870 ListEntry
= GetFirstListEntry(LanguageList
);
872 while (ListEntry
!= NULL
)
874 if (!wcsicmp(LocaleID
, GetListEntryUserData(ListEntry
)))
876 DPRINT("found %S in LanguageList\n",GetListEntryUserData(ListEntry
));
877 SetCurrentListEntry(LanguageList
, ListEntry
);
881 ListEntry
= GetNextListEntry(ListEntry
);
885 ListEntry
= GetFirstListEntry(LayoutList
);
887 while (ListEntry
!= NULL
)
889 if (!wcsicmp(LocaleID
, GetListEntryUserData(ListEntry
)))
891 DPRINT("found %S in LayoutList\n",GetListEntryUserData(ListEntry
));
892 SetCurrentListEntry(LayoutList
, ListEntry
);
896 ListEntry
= GetNextListEntry(ListEntry
);
899 SetConsoleCodePage();
901 return INSTALL_INTRO_PAGE
;
904 return LANGUAGE_PAGE
;
914 IntroPage(PINPUT_RECORD Ir
)
916 MUIDisplayPage(START_PAGE
);
920 CONSOLE_ConInKey(Ir
);
922 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
923 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
925 if (ConfirmQuit(Ir
) == TRUE
)
930 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
932 return INSTALL_INTRO_PAGE
;
935 else if (toupper(Ir
->Event
.KeyEvent
.uChar
.AsciiChar
) == 'R') /* R */
937 return REPAIR_INTRO_PAGE
;
940 else if (toupper(Ir
->Event
.KeyEvent
.uChar
.AsciiChar
) == 'L') /* R */
954 * Back to main setup page.
957 LicensePage(PINPUT_RECORD Ir
)
959 MUIDisplayPage(LICENSE_PAGE
);
963 CONSOLE_ConInKey(Ir
);
965 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
977 RepairIntroPage(PINPUT_RECORD Ir
)
979 MUIDisplayPage(REPAIR_INTRO_PAGE
);
983 CONSOLE_ConInKey(Ir
);
985 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
989 else if (toupper(Ir
->Event
.KeyEvent
.uChar
.AsciiChar
) == 'U') /* U */
991 RepairUpdateFlag
= TRUE
;
992 return INSTALL_INTRO_PAGE
;
994 else if (toupper(Ir
->Event
.KeyEvent
.uChar
.AsciiChar
) == 'R') /* R */
998 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
999 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
)) /* ESC */
1005 return REPAIR_INTRO_PAGE
;
1010 InstallIntroPage(PINPUT_RECORD Ir
)
1012 MUIDisplayPage(INSTALL_INTRO_PAGE
);
1014 if (RepairUpdateFlag
)
1016 //return SELECT_PARTITION_PAGE;
1017 return DEVICE_SETTINGS_PAGE
;
1020 if (IsUnattendedSetup
)
1022 return SELECT_PARTITION_PAGE
;
1027 CONSOLE_ConInKey(Ir
);
1029 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1030 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1032 if (ConfirmQuit(Ir
) == TRUE
)
1037 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
1039 return DEVICE_SETTINGS_PAGE
;
1040 // return SCSI_CONTROLLER_PAGE;
1044 return INSTALL_INTRO_PAGE
;
1050 ScsiControllerPage(PINPUT_RECORD Ir
)
1052 SetTextXY(6, 8, "Setup detected the following mass storage devices:");
1054 /* FIXME: print loaded mass storage driver descriptions */
1056 SetTextXY(8, 10, "TEST device");
1060 SetStatusText(" ENTER = Continue F3 = Quit");
1066 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1067 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1069 if (ConfirmQuit(Ir
) == TRUE
)
1074 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
1076 return DEVICE_SETTINGS_PAGE
;
1080 return SCSI_CONTROLLER_PAGE
;
1086 DeviceSettingsPage(PINPUT_RECORD Ir
)
1088 static ULONG Line
= 16;
1089 MUIDisplayPage(DEVICE_SETTINGS_PAGE
);
1091 /* Initialize the computer settings list */
1092 if (ComputerList
== NULL
)
1094 ComputerList
= CreateComputerTypeList(SetupInf
);
1095 if (ComputerList
== NULL
)
1097 MUIDisplayError(ERROR_LOAD_COMPUTER
, Ir
, POPUP_WAIT_ENTER
);
1102 /* Initialize the display settings list */
1103 if (DisplayList
== NULL
)
1105 DisplayList
= CreateDisplayDriverList(SetupInf
);
1106 if (DisplayList
== NULL
)
1108 MUIDisplayError(ERROR_LOAD_DISPLAY
, Ir
, POPUP_WAIT_ENTER
);
1113 /* Initialize the keyboard settings list */
1114 if (KeyboardList
== NULL
)
1116 KeyboardList
= CreateKeyboardDriverList(SetupInf
);
1117 if (KeyboardList
== NULL
)
1119 MUIDisplayError(ERROR_LOAD_KEYBOARD
, Ir
, POPUP_WAIT_ENTER
);
1124 /* Initialize the keyboard layout list */
1125 if (LayoutList
== NULL
)
1127 LayoutList
= CreateKeyboardLayoutList(SetupInf
, DefaultKBLayout
);
1128 if (LayoutList
== NULL
)
1130 /* FIXME: report error */
1131 MUIDisplayError(ERROR_LOAD_KBLAYOUT
, Ir
, POPUP_WAIT_ENTER
);
1136 MUIDisplayPage(DEVICE_SETTINGS_PAGE
);
1139 CONSOLE_SetTextXY(25, 11, GetListEntryText(GetCurrentListEntry((ComputerList
))));
1140 CONSOLE_SetTextXY(25, 12, GetListEntryText(GetCurrentListEntry((DisplayList
))));
1141 CONSOLE_SetTextXY(25, 13, GetListEntryText(GetCurrentListEntry((KeyboardList
))));
1142 CONSOLE_SetTextXY(25, 14, GetListEntryText(GetCurrentListEntry((LayoutList
))));
1144 CONSOLE_InvertTextXY(24, Line
, 48, 1);
1146 if (RepairUpdateFlag
)
1148 return SELECT_PARTITION_PAGE
;
1153 CONSOLE_ConInKey(Ir
);
1155 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1156 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
)) /* DOWN */
1158 CONSOLE_NormalTextXY(24, Line
, 48, 1);
1162 else if (Line
== 16)
1167 CONSOLE_InvertTextXY(24, Line
, 48, 1);
1169 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1170 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_UP
)) /* UP */
1172 CONSOLE_NormalTextXY(24, Line
, 48, 1);
1176 else if (Line
== 16)
1181 CONSOLE_InvertTextXY(24, Line
, 48, 1);
1183 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1184 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1186 if (ConfirmQuit(Ir
) == TRUE
)
1191 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
1194 return COMPUTER_SETTINGS_PAGE
;
1195 else if (Line
== 12)
1196 return DISPLAY_SETTINGS_PAGE
;
1197 else if (Line
== 13)
1198 return KEYBOARD_SETTINGS_PAGE
;
1199 else if (Line
== 14)
1200 return LAYOUT_SETTINGS_PAGE
;
1201 else if (Line
== 16)
1202 return SELECT_PARTITION_PAGE
;
1206 return DEVICE_SETTINGS_PAGE
;
1211 ComputerSettingsPage(PINPUT_RECORD Ir
)
1213 MUIDisplayPage(COMPUTER_SETTINGS_PAGE
);
1215 DrawGenericList(ComputerList
,
1221 SaveGenericListState(ComputerList
);
1225 CONSOLE_ConInKey(Ir
);
1227 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1228 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
)) /* DOWN */
1230 ScrollDownGenericList(ComputerList
);
1232 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1233 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_UP
)) /* UP */
1235 ScrollUpGenericList(ComputerList
);
1237 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1238 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1240 if (ConfirmQuit(Ir
) == TRUE
)
1245 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1246 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
)) /* ESC */
1248 RestoreGenericListState(ComputerList
);
1249 return DEVICE_SETTINGS_PAGE
;
1251 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
1253 return DEVICE_SETTINGS_PAGE
;
1257 return COMPUTER_SETTINGS_PAGE
;
1262 DisplaySettingsPage(PINPUT_RECORD Ir
)
1264 MUIDisplayPage(DISPLAY_SETTINGS_PAGE
);
1266 DrawGenericList(DisplayList
,
1272 SaveGenericListState(DisplayList
);
1276 CONSOLE_ConInKey(Ir
);
1278 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1279 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
)) /* DOWN */
1281 ScrollDownGenericList(DisplayList
);
1283 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1284 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_UP
)) /* UP */
1286 ScrollUpGenericList(DisplayList
);
1288 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1289 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1291 if (ConfirmQuit(Ir
) == TRUE
)
1298 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1299 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
)) /* ESC */
1301 RestoreGenericListState(DisplayList
);
1302 return DEVICE_SETTINGS_PAGE
;
1304 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
1306 return DEVICE_SETTINGS_PAGE
;
1310 return DISPLAY_SETTINGS_PAGE
;
1315 KeyboardSettingsPage(PINPUT_RECORD Ir
)
1317 MUIDisplayPage(KEYBOARD_SETTINGS_PAGE
);
1319 DrawGenericList(KeyboardList
,
1325 SaveGenericListState(KeyboardList
);
1329 CONSOLE_ConInKey(Ir
);
1331 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1332 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
)) /* DOWN */
1334 ScrollDownGenericList(KeyboardList
);
1336 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1337 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_UP
)) /* UP */
1339 ScrollUpGenericList(KeyboardList
);
1341 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1342 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1344 if (ConfirmQuit(Ir
) == TRUE
)
1349 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1350 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
)) /* ESC */
1352 RestoreGenericListState(KeyboardList
);
1353 return DEVICE_SETTINGS_PAGE
;
1355 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
1357 return DEVICE_SETTINGS_PAGE
;
1361 return KEYBOARD_SETTINGS_PAGE
;
1366 LayoutSettingsPage(PINPUT_RECORD Ir
)
1368 MUIDisplayPage(LAYOUT_SETTINGS_PAGE
);
1370 DrawGenericList(LayoutList
,
1376 SaveGenericListState(LayoutList
);
1380 CONSOLE_ConInKey(Ir
);
1382 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1383 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
)) /* DOWN */
1385 ScrollDownGenericList(LayoutList
);
1387 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1388 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_UP
)) /* UP */
1390 ScrollUpGenericList(LayoutList
);
1392 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1393 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_NEXT
)) /* PAGE DOWN */
1395 ScrollPageDownGenericList(LayoutList
);
1397 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1398 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_PRIOR
)) /* PAGE UP */
1400 ScrollPageUpGenericList(LayoutList
);
1402 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1403 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1405 if (ConfirmQuit(Ir
) == TRUE
)
1410 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1411 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
)) /* ESC */
1413 RestoreGenericListState(LayoutList
);
1414 return DEVICE_SETTINGS_PAGE
;
1416 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
1418 return DEVICE_SETTINGS_PAGE
;
1420 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
> 0x60) && (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
< 0x7b))
1423 GenericListKeyPress(LayoutList
, Ir
->Event
.KeyEvent
.uChar
.AsciiChar
);
1427 return LAYOUT_SETTINGS_PAGE
;
1432 IsDiskSizeValid(PPARTENTRY PartEntry
)
1436 /* check for unpartitioned space */
1437 m1
= PartEntry
->UnpartitionedLength
;
1438 m1
= (m1
+ (1 << 19)) >> 20; /* in MBytes (rounded) */
1440 if( m1
> RequiredPartitionDiskSpace
)
1445 /* check for partitioned space */
1446 m2
= PartEntry
->PartInfo
[0].PartitionLength
.QuadPart
;
1447 m2
= (m2
+ (1 << 19)) >> 20; /* in MBytes (rounded) */
1448 if (m2
< RequiredPartitionDiskSpace
)
1450 /* partition is too small so ask for another partion */
1451 DPRINT1("Partition is too small(unpartitioned: %I64u MB, partitioned: %I64u MB), required disk space is %lu MB\n", m1
, m2
, RequiredPartitionDiskSpace
);
1462 SelectPartitionPage(PINPUT_RECORD Ir
)
1464 MUIDisplayPage(SELECT_PARTITION_PAGE
);
1466 if (PartitionList
== NULL
)
1468 PartitionList
= CreatePartitionList(2,
1472 if (PartitionList
== NULL
)
1474 /* FIXME: show an error dialog */
1477 else if (IsListEmpty (&PartitionList
->DiskListHead
))
1479 MUIDisplayError(ERROR_NO_HDD
, Ir
, POPUP_WAIT_ENTER
);
1484 DrawPartitionList(PartitionList
);
1486 /* Warn about partitions created by Linux Fdisk */
1487 if (WarnLinuxPartitions
== TRUE
&&
1488 CheckForLinuxFdiskPartitions(PartitionList
) == TRUE
)
1490 MUIDisplayError(ERROR_WARN_PARTITION
, NULL
, POPUP_WAIT_NONE
);
1494 CONSOLE_ConInKey(Ir
);
1496 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1497 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1501 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_RETURN
) /* ENTER */
1503 WarnLinuxPartitions
= FALSE
;
1504 return SELECT_PARTITION_PAGE
;
1509 if (IsUnattendedSetup
)
1511 if (!SelectPartition(PartitionList
, UnattendDestinationDiskNumber
, UnattendDestinationPartitionNumber
))
1515 PPARTENTRY PartEntry
= PartitionList
->CurrentPartition
;
1516 ULONG MaxSize
= (PartEntry
->UnpartitionedLength
+ (1 << 19)) >> 20; /* in MBytes (rounded) */
1517 if(!IsDiskSizeValid(PartitionList
->CurrentPartition
))
1519 MUIDisplayError(ERROR_INSUFFICIENT_DISKSPACE
, Ir
, POPUP_WAIT_ANY_KEY
);
1520 return SELECT_PARTITION_PAGE
; /* let the user select another partition */
1523 CreateNewPartition(PartitionList
,
1527 DestinationDriveLetter
= (WCHAR
)PartitionList
->CurrentPartition
->DriveLetter
[0];
1529 return SELECT_FILE_SYSTEM_PAGE
;
1534 if(!IsDiskSizeValid(PartitionList
->CurrentPartition
))
1536 MUIDisplayError(ERROR_INSUFFICIENT_DISKSPACE
, Ir
, POPUP_WAIT_ANY_KEY
);
1537 return SELECT_PARTITION_PAGE
; /* let the user select another partition */
1540 DestinationDriveLetter
= (WCHAR
)PartitionList
->CurrentPartition
->DriveLetter
[0];
1542 return SELECT_FILE_SYSTEM_PAGE
;
1548 /* Update status text */
1549 if (PartitionList
->CurrentPartition
== NULL
||
1550 PartitionList
->CurrentPartition
->Unpartitioned
== TRUE
)
1552 CONSOLE_SetStatusText(MUIGetString(STRING_INSTALLCREATEPARTITION
));
1556 CONSOLE_SetStatusText(MUIGetString(STRING_INSTALLDELETEPARTITION
));
1559 CONSOLE_ConInKey(Ir
);
1561 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1562 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1564 if (ConfirmQuit(Ir
) == TRUE
)
1566 DestroyPartitionList(PartitionList
);
1567 PartitionList
= NULL
;
1573 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1574 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
)) /* DOWN */
1576 ScrollDownPartitionList(PartitionList
);
1578 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1579 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_UP
)) /* UP */
1581 ScrollUpPartitionList(PartitionList
);
1583 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_RETURN
) /* ENTER */
1585 if(!IsDiskSizeValid(PartitionList
->CurrentPartition
))
1587 MUIDisplayError(ERROR_INSUFFICIENT_DISKSPACE
, Ir
, POPUP_WAIT_ANY_KEY
);
1588 return SELECT_PARTITION_PAGE
; /* let the user select another partition */
1590 if (PartitionList
->CurrentPartition
== NULL
||
1591 PartitionList
->CurrentPartition
->Unpartitioned
== TRUE
)
1593 CreateNewPartition(PartitionList
,
1598 DestinationDriveLetter
= (WCHAR
)PartitionList
->CurrentPartition
->DriveLetter
[0];
1600 return SELECT_FILE_SYSTEM_PAGE
;
1602 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== 'C') /* C */
1604 if (PartitionList
->CurrentPartition
->Unpartitioned
== FALSE
)
1606 MUIDisplayError(ERROR_NEW_PARTITION
, Ir
, POPUP_WAIT_ANY_KEY
);
1607 return SELECT_PARTITION_PAGE
;
1610 return CREATE_PARTITION_PAGE
;
1612 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== 'D') /* D */
1614 if (PartitionList
->CurrentPartition
->Unpartitioned
== TRUE
)
1616 MUIDisplayError(ERROR_DELETE_SPACE
, Ir
, POPUP_WAIT_ANY_KEY
);
1617 return SELECT_PARTITION_PAGE
;
1620 return DELETE_PARTITION_PAGE
;
1624 return SELECT_PARTITION_PAGE
;
1629 DrawInputField(ULONG FieldLength
,
1640 memset(buf
, '_', sizeof(buf
));
1641 buf
[FieldLength
- strlen(FieldContent
)] = 0;
1642 strcat(buf
, FieldContent
);
1644 WriteConsoleOutputCharacterA(StdOutput
,
1652 #define PARTITION_SIZE_INPUT_FIELD_LENGTH 6
1653 /* Restriction for MaxSize: pow(10, PARTITION_SIZE_INPUT_FIELD_LENGTH)-1 */
1654 #define PARTITION_MAXSIZE 999999
1657 ShowPartitionSizeInputBox(SHORT Left
,
1681 DrawBox(Left
, Top
, Right
- Left
+ 1, Bottom
- Top
+ 1);
1686 strcpy(Buffer
, MUIGetString(STRING_PARTITIONSIZE
));
1687 iLeft
= coPos
.X
+ strlen(Buffer
) + 1;
1690 WriteConsoleOutputCharacterA(StdOutput
,
1696 sprintf(Buffer
, MUIGetString(STRING_MAXSIZE
), MaxSize
);
1697 coPos
.X
= iLeft
+ PARTITION_SIZE_INPUT_FIELD_LENGTH
+ 1;
1699 WriteConsoleOutputCharacterA(StdOutput
,
1705 sprintf(Buffer
, "%lu", MaxSize
);
1706 Index
= strlen(Buffer
);
1707 DrawInputField(PARTITION_SIZE_INPUT_FIELD_LENGTH
,
1714 CONSOLE_ConInKey(&Ir
);
1716 if ((Ir
.Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1717 (Ir
.Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1725 else if (Ir
.Event
.KeyEvent
.wVirtualKeyCode
== VK_RETURN
) /* ENTER */
1729 else if (Ir
.Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
) /* ESCAPE */
1737 else if ((Ir
.Event
.KeyEvent
.wVirtualKeyCode
== VK_BACK
) && /* BACKSPACE */
1743 DrawInputField(PARTITION_SIZE_INPUT_FIELD_LENGTH
,
1748 else if ((Ir
.Event
.KeyEvent
.uChar
.AsciiChar
!= 0x00) &&
1749 (Index
< PARTITION_SIZE_INPUT_FIELD_LENGTH
))
1751 ch
= Ir
.Event
.KeyEvent
.uChar
.AsciiChar
;
1753 if ((ch
>= '0') && (ch
<= '9'))
1759 DrawInputField(PARTITION_SIZE_INPUT_FIELD_LENGTH
,
1767 strcpy(InputBuffer
, Buffer
);
1772 CreatePartitionPage(PINPUT_RECORD Ir
)
1774 PDISKENTRY DiskEntry
;
1775 PPARTENTRY PartEntry
;
1778 CHAR InputBuffer
[50];
1784 if (PartitionList
== NULL
||
1785 PartitionList
->CurrentDisk
== NULL
||
1786 PartitionList
->CurrentPartition
== NULL
)
1788 /* FIXME: show an error dialog */
1792 DiskEntry
= PartitionList
->CurrentDisk
;
1793 PartEntry
= PartitionList
->CurrentPartition
;
1795 CONSOLE_SetStatusText(MUIGetString(STRING_PLEASEWAIT
));
1797 CONSOLE_SetTextXY(6, 8, MUIGetString(STRING_CHOOSENEWPARTITION
));
1800 if (DiskEntry
->DiskSize
>= 0x280000000ULL
) /* 10 GB */
1802 DiskSize
= (DiskEntry
->DiskSize
+ (1 << 29)) >> 30;
1803 Unit
= MUIGetString(STRING_GB
);
1808 DiskSize
= (DiskEntry
->DiskSize
+ (1 << 19)) >> 20;
1813 Unit
= MUIGetString(STRING_MB
);
1816 if (DiskEntry
->DriverName
.Length
> 0)
1818 CONSOLE_PrintTextXY(6, 10,
1819 MUIGetString(STRING_HDINFOPARTCREATE
),
1822 DiskEntry
->DiskNumber
,
1826 &DiskEntry
->DriverName
);
1830 CONSOLE_PrintTextXY(6, 10,
1831 MUIGetString(STRING_HDDINFOUNK1
),
1834 DiskEntry
->DiskNumber
,
1840 CONSOLE_SetTextXY(6, 12, MUIGetString(STRING_HDDSIZE
));
1843 CONSOLE_PrintTextXY(8, 10, "Maximum size of the new partition is %I64u MB",
1844 PartitionList
->CurrentPartition
->UnpartitionedLength
/ (1024*1024));
1847 CONSOLE_SetStatusText(MUIGetString(STRING_CREATEPARTITION
));
1849 PartEntry
= PartitionList
->CurrentPartition
;
1852 MaxSize
= (PartEntry
->UnpartitionedLength
+ (1 << 19)) >> 20; /* in MBytes (rounded) */
1854 if (MaxSize
> PARTITION_MAXSIZE
) MaxSize
= PARTITION_MAXSIZE
;
1856 ShowPartitionSizeInputBox(12, 14, xScreen
- 12, 17, /* left, top, right, bottom */
1857 MaxSize
, InputBuffer
, &Quit
, &Cancel
);
1861 if (ConfirmQuit (Ir
) == TRUE
)
1866 else if (Cancel
== TRUE
)
1868 return SELECT_PARTITION_PAGE
;
1872 PartSize
= atoi(InputBuffer
);
1880 if (PartSize
> MaxSize
)
1886 /* Convert to bytes */
1887 if (PartSize
== MaxSize
)
1889 /* Use all of the unpartitioned disk space */
1890 PartSize
= PartEntry
->UnpartitionedLength
;
1894 /* Round-up by cylinder size */
1895 PartSize
= (PartSize
* 1024 * 1024 + DiskEntry
->CylinderSize
- 1) /
1896 DiskEntry
->CylinderSize
* DiskEntry
->CylinderSize
;
1898 /* But never get larger than the unpartitioned disk space */
1899 if (PartSize
> PartEntry
->UnpartitionedLength
)
1900 PartSize
= PartEntry
->UnpartitionedLength
;
1903 DPRINT ("Partition size: %I64u bytes\n", PartSize
);
1905 CreateNewPartition(PartitionList
,
1909 return SELECT_PARTITION_PAGE
;
1913 return CREATE_PARTITION_PAGE
;
1918 DeletePartitionPage(PINPUT_RECORD Ir
)
1920 PDISKENTRY DiskEntry
;
1921 PPARTENTRY PartEntry
;
1928 if (PartitionList
== NULL
||
1929 PartitionList
->CurrentDisk
== NULL
||
1930 PartitionList
->CurrentPartition
== NULL
)
1932 /* FIXME: show an error dialog */
1936 DiskEntry
= PartitionList
->CurrentDisk
;
1937 PartEntry
= PartitionList
->CurrentPartition
;
1938 PartNumber
= PartitionList
->CurrentPartitionNumber
;
1940 MUIDisplayPage(DELETE_PARTITION_PAGE
);
1942 /* Determine partition type */
1944 if (PartEntry
->New
== TRUE
)
1946 PartType
= MUIGetString(STRING_UNFORMATTED
);
1948 else if (PartEntry
->Unpartitioned
== FALSE
)
1950 if ((PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_FAT_12
) ||
1951 (PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_FAT_16
) ||
1952 (PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_HUGE
) ||
1953 (PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_XINT13
))
1957 else if ((PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_FAT32
) ||
1958 (PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_FAT32_XINT13
))
1962 else if (PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_EXT2
)
1966 else if (PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_IFS
)
1968 PartType
= "NTFS"; /* FIXME: Not quite correct! */
1973 if (PartEntry
->PartInfo
[PartNumber
].PartitionLength
.QuadPart
>= 0x280000000LL
) /* 10 GB */
1975 PartSize
= (PartEntry
->PartInfo
[PartNumber
].PartitionLength
.QuadPart
+ (1 << 29)) >> 30;
1976 Unit
= MUIGetString(STRING_GB
);
1980 if (PartEntry
->PartInfo
[PartNumber
].PartitionLength
.QuadPart
>= 0xA00000LL
) /* 10 MB */
1982 PartSize
= (PartEntry
->PartInfo
[PartNumber
].PartitionLength
.QuadPart
+ (1 << 19)) >> 20;
1983 Unit
= MUIGetString(STRING_MB
);
1987 PartSize
= (PartEntry
->PartInfo
[PartNumber
].PartitionLength
.QuadPart
+ (1 << 9)) >> 10;
1988 Unit
= MUIGetString(STRING_KB
);
1991 if (PartType
== NULL
)
1993 CONSOLE_PrintTextXY(6, 10,
1994 MUIGetString(STRING_HDDINFOUNK2
),
1995 (PartEntry
->DriveLetter
[PartNumber
] == 0) ? '-' : PartEntry
->DriveLetter
[PartNumber
],
1996 (PartEntry
->DriveLetter
[PartNumber
] == 0) ? '-' : ':',
1997 PartEntry
->PartInfo
[PartNumber
].PartitionType
,
2003 CONSOLE_PrintTextXY(6, 10,
2004 " %c%c %s %I64u %s",
2005 (PartEntry
->DriveLetter
[PartNumber
] == 0) ? '-' : PartEntry
->DriveLetter
[PartNumber
],
2006 (PartEntry
->DriveLetter
[PartNumber
] == 0) ? '-' : ':',
2013 if (DiskEntry
->DiskSize
>= 0x280000000ULL
) /* 10 GB */
2015 DiskSize
= (DiskEntry
->DiskSize
+ (1 << 29)) >> 30;
2016 Unit
= MUIGetString(STRING_GB
);
2021 DiskSize
= (DiskEntry
->DiskSize
+ (1 << 19)) >> 20;
2026 Unit
= MUIGetString(STRING_MB
);
2029 if (DiskEntry
->DriverName
.Length
> 0)
2031 CONSOLE_PrintTextXY(6, 12,
2032 MUIGetString(STRING_HDINFOPARTDELETE
),
2035 DiskEntry
->DiskNumber
,
2039 &DiskEntry
->DriverName
);
2043 CONSOLE_PrintTextXY(6, 12,
2044 MUIGetString(STRING_HDDINFOUNK3
),
2047 DiskEntry
->DiskNumber
,
2055 CONSOLE_ConInKey(Ir
);
2057 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
2058 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
2060 if (ConfirmQuit(Ir
) == TRUE
)
2067 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
) /* ESC */
2069 return SELECT_PARTITION_PAGE
;
2071 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== 'D') /* D */
2073 DeleteCurrentPartition(PartitionList
);
2075 return SELECT_PARTITION_PAGE
;
2079 return DELETE_PARTITION_PAGE
;
2084 SelectFileSystemPage(PINPUT_RECORD Ir
)
2086 PDISKENTRY DiskEntry
;
2087 PPARTENTRY PartEntry
;
2095 if (PartitionList
== NULL
||
2096 PartitionList
->CurrentDisk
== NULL
||
2097 PartitionList
->CurrentPartition
== NULL
)
2099 /* FIXME: show an error dialog */
2103 DiskEntry
= PartitionList
->CurrentDisk
;
2104 PartEntry
= PartitionList
->CurrentPartition
;
2105 PartNumber
= PartitionList
->CurrentPartitionNumber
;
2107 /* adjust disk size */
2108 if (DiskEntry
->DiskSize
>= 0x280000000ULL
) /* 10 GB */
2110 DiskSize
= (DiskEntry
->DiskSize
+ (1 << 29)) >> 30;
2111 DiskUnit
= MUIGetString(STRING_GB
);
2115 DiskSize
= (DiskEntry
->DiskSize
+ (1 << 19)) >> 20;
2116 DiskUnit
= MUIGetString(STRING_MB
);
2119 /* adjust partition size */
2120 if (PartEntry
->PartInfo
[PartNumber
].PartitionLength
.QuadPart
>= 0x280000000LL
) /* 10 GB */
2122 PartSize
= (PartEntry
->PartInfo
[PartNumber
].PartitionLength
.QuadPart
+ (1 << 29)) >> 30;
2123 PartUnit
= MUIGetString(STRING_GB
);
2127 PartSize
= (PartEntry
->PartInfo
[PartNumber
].PartitionLength
.QuadPart
+ (1 << 19)) >> 20;
2128 PartUnit
= MUIGetString(STRING_MB
);
2131 /* adjust partition type */
2132 if ((PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_FAT_12
) ||
2133 (PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_FAT_16
) ||
2134 (PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_HUGE
) ||
2135 (PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_XINT13
))
2139 else if ((PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_FAT32
) ||
2140 (PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_FAT32_XINT13
))
2144 else if (PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_EXT2
)
2148 else if (PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_IFS
)
2150 PartType
= "NTFS"; /* FIXME: Not quite correct! */
2152 else if (PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_ENTRY_UNUSED
)
2154 PartType
= MUIGetString(STRING_FORMATUNUSED
);
2158 PartType
= MUIGetString(STRING_FORMATUNKNOWN
);
2161 if (PartEntry
->AutoCreate
== TRUE
)
2163 CONSOLE_SetTextXY(6, 8, MUIGetString(STRING_NEWPARTITION
));
2166 CONSOLE_PrintTextXY(8, 10, "Partition %lu (%I64u %s) %s of",
2167 PartEntry
->PartInfo
[PartNumber
].PartitionNumber
,
2173 CONSOLE_PrintTextXY(8, 10, MUIGetString(STRING_HDINFOPARTZEROED
),
2174 DiskEntry
->DiskNumber
,
2180 &DiskEntry
->DriverName
);
2182 CONSOLE_SetTextXY(6, 12, MUIGetString(STRING_PARTFORMAT
));
2185 PartEntry
->AutoCreate
= FALSE
;
2187 else if (PartEntry
->New
== TRUE
)
2189 CONSOLE_SetTextXY(6, 8, MUIGetString(STRING_NONFORMATTEDPART
));
2190 CONSOLE_SetTextXY(6, 10, MUIGetString(STRING_PARTFORMAT
));
2194 CONSOLE_SetTextXY(6, 8, MUIGetString(STRING_INSTALLONPART
));
2196 if (PartType
== NULL
)
2198 CONSOLE_PrintTextXY(8, 10,
2199 MUIGetString(STRING_HDDINFOUNK4
),
2200 (PartEntry
->DriveLetter
[PartNumber
] == 0) ? '-' : PartEntry
->DriveLetter
[PartNumber
],
2201 (PartEntry
->DriveLetter
[PartNumber
] == 0) ? '-' : ':',
2202 PartEntry
->PartInfo
[PartNumber
].PartitionType
,
2208 CONSOLE_PrintTextXY(8, 10,
2210 (PartEntry
->DriveLetter
[PartNumber
] == 0) ? '-' : PartEntry
->DriveLetter
[PartNumber
],
2211 (PartEntry
->DriveLetter
[PartNumber
] == 0) ? '-' : ':',
2217 CONSOLE_PrintTextXY(6, 12, MUIGetString(STRING_HDINFOPARTEXISTS
),
2218 DiskEntry
->DiskNumber
,
2224 &DiskEntry
->DriverName
);
2227 MUIDisplayPage(SELECT_FILE_SYSTEM_PAGE
);
2229 if (FileSystemList
== NULL
)
2231 FileSystemList
= CreateFileSystemList(6, 26, PartEntry
->New
, L
"FAT");
2232 if (FileSystemList
== NULL
)
2234 /* FIXME: show an error dialog */
2238 /* FIXME: Add file systems to list */
2240 DrawFileSystemList(FileSystemList
);
2242 if (RepairUpdateFlag
)
2244 return CHECK_FILE_SYSTEM_PAGE
;
2245 //return SELECT_PARTITION_PAGE;
2248 if (IsUnattendedSetup
)
2250 if (UnattendFormatPartition
)
2252 return FORMAT_PARTITION_PAGE
;
2255 return CHECK_FILE_SYSTEM_PAGE
;
2260 CONSOLE_ConInKey(Ir
);
2262 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
2263 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
2265 if (ConfirmQuit(Ir
) == TRUE
)
2272 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
2273 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
)) /* ESC */
2275 return SELECT_PARTITION_PAGE
;
2277 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
2278 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
)) /* DOWN */
2280 ScrollDownFileSystemList(FileSystemList
);
2282 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
2283 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_UP
)) /* UP */
2285 ScrollUpFileSystemList(FileSystemList
);
2287 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_RETURN
) /* ENTER */
2289 if (!FileSystemList
->Selected
->FormatFunc
)
2291 return CHECK_FILE_SYSTEM_PAGE
;
2295 return FORMAT_PARTITION_PAGE
;
2300 return SELECT_FILE_SYSTEM_PAGE
;
2305 FormatPartitionPage(PINPUT_RECORD Ir
)
2307 WCHAR PathBuffer
[MAX_PATH
];
2308 PPARTENTRY PartEntry
;
2313 PDISKENTRY DiskEntry
;
2319 MUIDisplayPage(FORMAT_PARTITION_PAGE
);
2321 if (PartitionList
== NULL
||
2322 PartitionList
->CurrentDisk
== NULL
||
2323 PartitionList
->CurrentPartition
== NULL
)
2325 /* FIXME: show an error dialog */
2330 DiskEntry
= PartitionList
->CurrentDisk
;
2332 PartEntry
= PartitionList
->CurrentPartition
;
2333 PartNum
= PartitionList
->CurrentPartitionNumber
;
2337 if (!IsUnattendedSetup
)
2339 CONSOLE_ConInKey(Ir
);
2342 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
2343 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
2345 if (ConfirmQuit(Ir
) == TRUE
)
2352 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_RETURN
|| IsUnattendedSetup
) /* ENTER */
2354 CONSOLE_SetStatusText(MUIGetString(STRING_PLEASEWAIT
));
2356 if (wcscmp(FileSystemList
->Selected
->FileSystem
, L
"FAT") == 0)
2358 if (PartEntry
->PartInfo
[PartNum
].PartitionLength
.QuadPart
< (4200LL * 1024LL))
2360 /* FAT12 CHS partition (disk is smaller than 4.1MB) */
2361 PartEntry
->PartInfo
[PartNum
].PartitionType
= PARTITION_FAT_12
;
2363 else if (PartEntry
->PartInfo
[PartNum
].StartingOffset
.QuadPart
< (1024LL * 255LL * 63LL * 512LL))
2365 /* Partition starts below the 8.4GB boundary ==> CHS partition */
2367 if (PartEntry
->PartInfo
[PartNum
].PartitionLength
.QuadPart
< (32LL * 1024LL * 1024LL))
2369 /* FAT16 CHS partition (partiton size < 32MB) */
2370 PartEntry
->PartInfo
[PartNum
].PartitionType
= PARTITION_FAT_16
;
2372 else if (PartEntry
->PartInfo
[PartNum
].PartitionLength
.QuadPart
< (512LL * 1024LL * 1024LL))
2374 /* FAT16 CHS partition (partition size < 512MB) */
2375 PartEntry
->PartInfo
[PartNum
].PartitionType
= PARTITION_HUGE
;
2379 /* FAT32 CHS partition (partition size >= 512MB) */
2380 PartEntry
->PartInfo
[PartNum
].PartitionType
= PARTITION_FAT32
;
2385 /* Partition starts above the 8.4GB boundary ==> LBA partition */
2387 if (PartEntry
->PartInfo
[PartNum
].PartitionLength
.QuadPart
< (512LL * 1024LL * 1024LL))
2389 /* FAT16 LBA partition (partition size < 512MB) */
2390 PartEntry
->PartInfo
[PartNum
].PartitionType
= PARTITION_XINT13
;
2394 /* FAT32 LBA partition (partition size >= 512MB) */
2395 PartEntry
->PartInfo
[PartNum
].PartitionType
= PARTITION_FAT32_XINT13
;
2400 else if (wcscmp(FileSystemList
->Selected
->FileSystem
, L
"EXT2") == 0)
2401 PartEntry
->PartInfo
[PartNum
].PartitionType
= PARTITION_EXT2
;
2403 else if (!FileSystemList
->Selected
->FormatFunc
)
2407 CONSOLE_PrintTextXY(6, 12,
2408 "Disk: %I64u Cylinder: %I64u Track: %I64u",
2409 DiskEntry
->DiskSize
,
2410 DiskEntry
->CylinderSize
,
2411 DiskEntry
->TrackSize
);
2414 DiskEntry
= PartitionList
->CurrentDisk
;
2415 Entry
= DiskEntry
->PartListHead
.Flink
;
2417 while (Entry
!= &DiskEntry
->PartListHead
)
2419 PartEntry
= CONTAINING_RECORD(Entry
, PARTENTRY
, ListEntry
);
2421 if (PartEntry
->Unpartitioned
== FALSE
)
2423 for (i
= 0; i
< 4; i
++)
2425 CONSOLE_PrintTextXY(6, Line
,
2426 "%2u: %2u %c %12I64u %12I64u %2u %c",
2428 PartEntry
->PartInfo
[i
].PartitionNumber
,
2429 PartEntry
->PartInfo
[i
].BootIndicator
? 'A' : '-',
2430 PartEntry
->PartInfo
[i
].StartingOffset
.QuadPart
,
2431 PartEntry
->PartInfo
[i
].PartitionLength
.QuadPart
,
2432 PartEntry
->PartInfo
[i
].PartitionType
,
2433 PartEntry
->PartInfo
[i
].RewritePartition
? '*' : ' ');
2441 Entry
= Entry
->Flink
;
2444 /* Restore the old entry */
2445 PartEntry
= PartitionList
->CurrentPartition
;
2448 if (WritePartitionsToDisk(PartitionList
) == FALSE
)
2450 DPRINT("WritePartitionsToDisk() failed\n");
2451 MUIDisplayError(ERROR_WRITE_PTABLE
, Ir
, POPUP_WAIT_ENTER
);
2455 /* Set DestinationRootPath */
2456 RtlFreeUnicodeString(&DestinationRootPath
);
2457 swprintf(PathBuffer
,
2458 L
"\\Device\\Harddisk%lu\\Partition%lu",
2459 PartitionList
->CurrentDisk
->DiskNumber
,
2460 PartitionList
->CurrentPartition
->PartInfo
[PartNum
].PartitionNumber
);
2461 RtlCreateUnicodeString(&DestinationRootPath
,
2463 DPRINT("DestinationRootPath: %wZ\n", &DestinationRootPath
);
2465 if (FileSystemList
->Selected
->FormatFunc
)
2467 Status
= FormatPartition(&DestinationRootPath
,
2468 FileSystemList
->Selected
);
2469 if (!NT_SUCCESS(Status
))
2471 DPRINT1("FormatPartition() failed with status 0x%08lx\n", Status
);
2472 /* FIXME: show an error dialog */
2476 PartEntry
->New
= FALSE
;
2478 CheckActiveBootPartition(PartitionList
);
2482 CONSOLE_SetStatusText(" Done. Press any key ...");
2483 CONSOLE_ConInKey(Ir
);
2486 DestroyFileSystemList(FileSystemList
);
2487 FileSystemList
= NULL
;
2488 return INSTALL_DIRECTORY_PAGE
;
2492 return FORMAT_PARTITION_PAGE
;
2497 CheckFileSystemPage(PINPUT_RECORD Ir
)
2499 PFILE_SYSTEM_ITEM CurrentFileSystem
;
2500 WCHAR PathBuffer
[MAX_PATH
];
2501 CHAR Buffer
[MAX_PATH
];
2503 UCHAR PartNum
= PartitionList
->CurrentPartitionNumber
;
2505 /* FIXME: code duplicated in FormatPartitionPage */
2506 /* Set DestinationRootPath */
2507 RtlFreeUnicodeString(&DestinationRootPath
);
2508 swprintf(PathBuffer
,
2509 L
"\\Device\\Harddisk%lu\\Partition%lu",
2510 PartitionList
->CurrentDisk
->DiskNumber
,
2511 PartitionList
->CurrentPartition
->PartInfo
[PartNum
].PartitionNumber
);
2512 RtlCreateUnicodeString(&DestinationRootPath
, PathBuffer
);
2513 DPRINT("DestinationRootPath: %wZ\n", &DestinationRootPath
);
2515 CONSOLE_SetTextXY(6, 8, MUIGetString(STRING_CHECKINGPART
));
2517 CONSOLE_SetStatusText(MUIGetString(STRING_PLEASEWAIT
));
2519 /* WRONG: first filesystem is not necesseraly the one of the current partition! */
2520 CurrentFileSystem
= CONTAINING_RECORD(FileSystemList
->ListHead
.Flink
, FILE_SYSTEM_ITEM
, ListEntry
);
2522 if (!CurrentFileSystem
->ChkdskFunc
)
2525 "Setup is currently unable to check a partition formatted in %S.\n"
2527 " \x07 Press ENTER to continue Setup.\n"
2528 " \x07 Press F3 to quit Setup.",
2529 CurrentFileSystem
->FileSystem
);
2532 MUIGetString(STRING_QUITCONTINUE
),
2533 NULL
, POPUP_WAIT_NONE
);
2537 CONSOLE_ConInKey(Ir
);
2539 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00 &&
2540 Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
) /* F3 */
2542 if (ConfirmQuit(Ir
))
2545 return CHECK_FILE_SYSTEM_PAGE
;
2547 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== VK_RETURN
) /* ENTER */
2549 return INSTALL_DIRECTORY_PAGE
;
2555 Status
= ChkdskPartition(&DestinationRootPath
, CurrentFileSystem
);
2556 if (!NT_SUCCESS(Status
))
2558 DPRINT("ChkdskPartition() failed with status 0x%08lx\n", Status
);
2559 sprintf(Buffer
, "Setup failed to verify the selected partition.\n"
2560 "(Status 0x%08lx).\n", Status
);
2563 MUIGetString(STRING_REBOOTCOMPUTER
),
2564 Ir
, POPUP_WAIT_ENTER
);
2569 return INSTALL_DIRECTORY_PAGE
;
2575 InstallDirectoryPage1(PWCHAR InstallDir
,
2576 PDISKENTRY DiskEntry
,
2577 PPARTENTRY PartEntry
,
2580 WCHAR PathBuffer
[MAX_PATH
];
2582 /* Create 'InstallPath' string */
2583 RtlFreeUnicodeString(&InstallPath
);
2584 RtlCreateUnicodeString(&InstallPath
,
2587 /* Create 'DestinationPath' string */
2588 RtlFreeUnicodeString(&DestinationPath
);
2589 wcscpy(PathBuffer
, DestinationRootPath
.Buffer
);
2591 if (InstallDir
[0] != L
'\\')
2592 wcscat(PathBuffer
, L
"\\");
2594 wcscat(PathBuffer
, InstallDir
);
2595 RtlCreateUnicodeString(&DestinationPath
, PathBuffer
);
2597 /* Create 'DestinationArcPath' */
2598 RtlFreeUnicodeString(&DestinationArcPath
);
2599 swprintf(PathBuffer
,
2600 L
"multi(0)disk(0)rdisk(%lu)partition(%lu)",
2601 DiskEntry
->BiosDiskNumber
,
2602 PartEntry
->PartInfo
[PartNum
].PartitionNumber
);
2604 if (InstallDir
[0] != L
'\\')
2605 wcscat(PathBuffer
, L
"\\");
2607 wcscat(PathBuffer
, InstallDir
);
2608 RtlCreateUnicodeString(&DestinationArcPath
, PathBuffer
);
2610 return PREPARE_COPY_PAGE
;
2615 InstallDirectoryPage(PINPUT_RECORD Ir
)
2617 PDISKENTRY DiskEntry
;
2618 PPARTENTRY PartEntry
;
2619 WCHAR InstallDir
[51];
2622 if (PartitionList
== NULL
||
2623 PartitionList
->CurrentDisk
== NULL
||
2624 PartitionList
->CurrentPartition
== NULL
)
2626 /* FIXME: show an error dialog */
2630 DiskEntry
= PartitionList
->CurrentDisk
;
2631 PartEntry
= PartitionList
->CurrentPartition
;
2633 if (IsUnattendedSetup
)
2634 wcscpy(InstallDir
, UnattendInstallationDirectory
);
2636 wcscpy(InstallDir
, L
"\\ReactOS");
2638 Length
= wcslen(InstallDir
);
2639 CONSOLE_SetInputTextXY(8, 11, 51, InstallDir
);
2640 MUIDisplayPage(INSTALL_DIRECTORY_PAGE
);
2642 if (IsUnattendedSetup
)
2644 return InstallDirectoryPage1(InstallDir
,
2647 PartitionList
->CurrentPartitionNumber
);
2652 CONSOLE_ConInKey(Ir
);
2654 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
2655 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
2657 if (ConfirmQuit(Ir
) == TRUE
)
2662 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2664 return InstallDirectoryPage1(InstallDir
,
2667 PartitionList
->CurrentPartitionNumber
);
2669 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x08) /* BACKSPACE */
2674 InstallDir
[Length
] = 0;
2675 CONSOLE_SetInputTextXY(8, 11, 51, InstallDir
);
2678 else if (isprint(Ir
->Event
.KeyEvent
.uChar
.AsciiChar
))
2682 InstallDir
[Length
] = (WCHAR
)Ir
->Event
.KeyEvent
.uChar
.AsciiChar
;
2684 InstallDir
[Length
] = 0;
2685 CONSOLE_SetInputTextXY(8, 11, 51, InstallDir
);
2690 return INSTALL_DIRECTORY_PAGE
;
2695 AddSectionToCopyQueueCab(HINF InfFile
,
2697 PWCHAR SourceCabinet
,
2698 PCUNICODE_STRING DestinationPath
,
2701 INFCONTEXT FilesContext
;
2702 INFCONTEXT DirContext
;
2704 PWCHAR FileKeyValue
;
2706 PWCHAR TargetFileName
;
2708 /* Search for the SectionName section */
2709 if (!SetupFindFirstLineW(InfFile
, SectionName
, NULL
, &FilesContext
))
2712 sprintf(Buffer
, MUIGetString(STRING_TXTSETUPFAILED
), SectionName
);
2713 PopupError(Buffer
, MUIGetString(STRING_REBOOTCOMPUTER
), Ir
, POPUP_WAIT_ENTER
);
2718 * Enumerate the files in the section
2719 * and add them to the file queue.
2723 /* Get source file name and target directory id */
2724 if (!INF_GetData(&FilesContext
, &FileKeyName
, &FileKeyValue
))
2726 /* FIXME: Handle error! */
2727 DPRINT1("INF_GetData() failed\n");
2731 /* Get optional target file name */
2732 if (!INF_GetDataField(&FilesContext
, 2, &TargetFileName
))
2733 TargetFileName
= NULL
;
2735 DPRINT("FileKeyName: '%S' FileKeyValue: '%S'\n", FileKeyName
, FileKeyValue
);
2737 /* Lookup target directory */
2738 if (!SetupFindFirstLineW(InfFile
, L
"Directories", FileKeyValue
, &DirContext
))
2740 /* FIXME: Handle error! */
2741 DPRINT1("SetupFindFirstLine() failed\n");
2745 if (!INF_GetData(&DirContext
, NULL
, &DirKeyValue
))
2747 /* FIXME: Handle error! */
2748 DPRINT1("INF_GetData() failed\n");
2752 if (!SetupQueueCopy(SetupFileQueue
,
2754 SourceRootPath
.Buffer
,
2755 SourceRootDir
.Buffer
,
2760 /* FIXME: Handle error! */
2761 DPRINT1("SetupQueueCopy() failed\n");
2763 } while (SetupFindNextLine(&FilesContext
, &FilesContext
));
2770 AddSectionToCopyQueue(HINF InfFile
,
2772 PWCHAR SourceCabinet
,
2773 PCUNICODE_STRING DestinationPath
,
2776 INFCONTEXT FilesContext
;
2777 INFCONTEXT DirContext
;
2779 PWCHAR FileKeyValue
;
2781 PWCHAR TargetFileName
;
2782 WCHAR CompleteOrigFileName
[512];
2785 return AddSectionToCopyQueueCab(InfFile
, L
"SourceFiles", SourceCabinet
, DestinationPath
, Ir
);
2787 /* Search for the SectionName section */
2788 if (!SetupFindFirstLineW(InfFile
, SectionName
, NULL
, &FilesContext
))
2791 sprintf(Buffer
, MUIGetString(STRING_TXTSETUPFAILED
), SectionName
);
2792 PopupError(Buffer
, MUIGetString(STRING_REBOOTCOMPUTER
), Ir
, POPUP_WAIT_ENTER
);
2797 * Enumerate the files in the section
2798 * and add them to the file queue.
2802 /* Get source file name and target directory id */
2803 if (!INF_GetData(&FilesContext
, &FileKeyName
, &FileKeyValue
))
2805 /* FIXME: Handle error! */
2806 DPRINT1("INF_GetData() failed\n");
2810 /* Get target directory id */
2811 if (!INF_GetDataField(&FilesContext
, 13, &FileKeyValue
))
2813 /* FIXME: Handle error! */
2814 DPRINT1("INF_GetData() failed\n");
2818 /* Get optional target file name */
2819 if (!INF_GetDataField(&FilesContext
, 11, &TargetFileName
))
2820 TargetFileName
= NULL
;
2821 else if (!*TargetFileName
)
2822 TargetFileName
= NULL
;
2824 DPRINT("FileKeyName: '%S' FileKeyValue: '%S'\n", FileKeyName
, FileKeyValue
);
2826 /* Lookup target directory */
2827 if (!SetupFindFirstLineW(InfFile
, L
"Directories", FileKeyValue
, &DirContext
))
2829 /* FIXME: Handle error! */
2830 DPRINT1("SetupFindFirstLine() failed\n");
2834 if (!INF_GetData(&DirContext
, NULL
, &DirKeyValue
))
2836 /* FIXME: Handle error! */
2837 DPRINT1("INF_GetData() failed\n");
2841 wcscpy(CompleteOrigFileName
, SourceRootDir
.Buffer
);
2842 wcscat(CompleteOrigFileName
, L
"\\");
2843 wcscat(CompleteOrigFileName
, DirKeyValue
);
2845 if (!SetupQueueCopy(SetupFileQueue
,
2847 SourceRootPath
.Buffer
,
2848 CompleteOrigFileName
,
2853 /* FIXME: Handle error! */
2854 DPRINT1("SetupQueueCopy() failed\n");
2856 } while (SetupFindNextLine(&FilesContext
, &FilesContext
));
2863 PrepareCopyPageInfFile(HINF InfFile
,
2864 PWCHAR SourceCabinet
,
2867 WCHAR PathBuffer
[MAX_PATH
];
2868 INFCONTEXT DirContext
;
2869 PWCHAR AdditionalSectionName
= NULL
;
2874 /* Add common files */
2875 if (!AddSectionToCopyQueue(InfFile
, L
"SourceDisksFiles", SourceCabinet
, &DestinationPath
, Ir
))
2878 /* Add specific files depending of computer type */
2879 if (SourceCabinet
== NULL
)
2881 if (!ProcessComputerFiles(InfFile
, ComputerList
, &AdditionalSectionName
))
2884 if (AdditionalSectionName
)
2886 if (!AddSectionToCopyQueue(InfFile
, AdditionalSectionName
, SourceCabinet
, &DestinationPath
, Ir
))
2891 /* Create directories */
2895 * Install directories like '\reactos\test' are not handled yet.
2898 /* Get destination path */
2899 wcscpy(PathBuffer
, DestinationPath
.Buffer
);
2901 /* Remove trailing backslash */
2902 Length
= wcslen(PathBuffer
);
2903 if ((Length
> 0) && (PathBuffer
[Length
- 1] == '\\'))
2905 PathBuffer
[Length
- 1] = 0;
2908 /* Create the install directory */
2909 Status
= SetupCreateDirectory(PathBuffer
);
2910 if (!NT_SUCCESS(Status
) && Status
!= STATUS_OBJECT_NAME_COLLISION
)
2912 DPRINT("Creating directory '%S' failed: Status = 0x%08lx", PathBuffer
, Status
);
2913 MUIDisplayError(ERROR_CREATE_INSTALL_DIR
, Ir
, POPUP_WAIT_ENTER
);
2917 /* Search for the 'Directories' section */
2918 if (!SetupFindFirstLineW(InfFile
, L
"Directories", NULL
, &DirContext
))
2922 MUIDisplayError(ERROR_CABINET_SECTION
, Ir
, POPUP_WAIT_ENTER
);
2926 MUIDisplayError(ERROR_TXTSETUP_SECTION
, Ir
, POPUP_WAIT_ENTER
);
2932 /* Enumerate the directory values and create the subdirectories */
2935 if (!INF_GetData(&DirContext
, NULL
, &KeyValue
))
2941 if (KeyValue
[0] == L
'\\' && KeyValue
[1] != 0)
2943 DPRINT("Absolute Path: '%S'\n", KeyValue
);
2945 wcscpy(PathBuffer
, DestinationRootPath
.Buffer
);
2946 wcscat(PathBuffer
, KeyValue
);
2948 DPRINT("FullPath: '%S'\n", PathBuffer
);
2950 else if (KeyValue
[0] != L
'\\')
2952 DPRINT("RelativePath: '%S'\n", KeyValue
);
2953 wcscpy(PathBuffer
, DestinationPath
.Buffer
);
2954 wcscat(PathBuffer
, L
"\\");
2955 wcscat(PathBuffer
, KeyValue
);
2957 DPRINT("FullPath: '%S'\n", PathBuffer
);
2959 Status
= SetupCreateDirectory(PathBuffer
);
2960 if (!NT_SUCCESS(Status
) && Status
!= STATUS_OBJECT_NAME_COLLISION
)
2962 DPRINT("Creating directory '%S' failed: Status = 0x%08lx", PathBuffer
, Status
);
2963 MUIDisplayError(ERROR_CREATE_DIR
, Ir
, POPUP_WAIT_ENTER
);
2967 } while (SetupFindNextLine (&DirContext
, &DirContext
));
2974 PrepareCopyPage(PINPUT_RECORD Ir
)
2977 WCHAR PathBuffer
[MAX_PATH
];
2978 INFCONTEXT CabinetsContext
;
2984 MUIDisplayPage(PREPARE_COPY_PAGE
);
2986 /* Create the file queue */
2987 SetupFileQueue
= SetupOpenFileQueue();
2988 if (SetupFileQueue
== NULL
)
2990 MUIDisplayError(ERROR_COPY_QUEUE
, Ir
, POPUP_WAIT_ENTER
);
2994 if (!PrepareCopyPageInfFile(SetupInf
, NULL
, Ir
))
2999 /* Search for the 'Cabinets' section */
3000 if (!SetupFindFirstLineW(SetupInf
, L
"Cabinets", NULL
, &CabinetsContext
))
3002 return FILE_COPY_PAGE
;
3006 * Enumerate the directory values in the 'Cabinets'
3007 * section and parse their inf files.
3011 if (!INF_GetData(&CabinetsContext
, NULL
, &KeyValue
))
3014 wcscpy(PathBuffer
, SourcePath
.Buffer
);
3015 wcscat(PathBuffer
, L
"\\");
3016 wcscat(PathBuffer
, KeyValue
);
3019 CabinetInitialize();
3020 CabinetSetEventHandlers(NULL
, NULL
, NULL
);
3021 CabinetSetCabinetName(PathBuffer
);
3023 if (CabinetOpen() == CAB_STATUS_SUCCESS
)
3025 DPRINT("Cabinet %S\n", CabinetGetCabinetName());
3027 InfFileData
= CabinetGetCabinetReservedArea(&InfFileSize
);
3028 if (InfFileData
== NULL
)
3030 MUIDisplayError(ERROR_CABINET_SCRIPT
, Ir
, POPUP_WAIT_ENTER
);
3036 DPRINT("Cannot open cabinet: %S.\n", CabinetGetCabinetName());
3037 MUIDisplayError(ERROR_CABINET_MISSING
, Ir
, POPUP_WAIT_ENTER
);
3041 InfHandle
= INF_OpenBufferedFileA((CHAR
*) InfFileData
,
3048 if (InfHandle
== INVALID_HANDLE_VALUE
)
3050 MUIDisplayError(ERROR_INVALID_CABINET_INF
, Ir
, POPUP_WAIT_ENTER
);
3056 if (!PrepareCopyPageInfFile(InfHandle
, KeyValue
, Ir
))
3061 } while (SetupFindNextLine(&CabinetsContext
, &CabinetsContext
));
3063 return FILE_COPY_PAGE
;
3069 SetupUpdateMemoryInfo(IN PCOPYCONTEXT CopyContext
,
3072 SYSTEM_PERFORMANCE_INFORMATION PerfInfo
;
3074 /* Get the memory information from the system */
3075 NtQuerySystemInformation(SystemPerformanceInformation
,
3080 /* Check if this is initial setup */
3083 /* Set maximum limits to be total RAM pages */
3084 ProgressSetStepCount(CopyContext
->MemoryBars
[0], PerfInfo
.CommitLimit
);
3085 ProgressSetStepCount(CopyContext
->MemoryBars
[1], PerfInfo
.CommitLimit
);
3086 ProgressSetStepCount(CopyContext
->MemoryBars
[2], PerfInfo
.CommitLimit
);
3089 /* Set current values */
3090 ProgressSetStep(CopyContext
->MemoryBars
[0], PerfInfo
.PagedPoolPages
+ PerfInfo
.NonPagedPoolPages
);
3091 ProgressSetStep(CopyContext
->MemoryBars
[1], PerfInfo
.ResidentSystemCachePage
);
3092 ProgressSetStep(CopyContext
->MemoryBars
[2], PerfInfo
.AvailablePages
);
3098 FileCopyCallback(PVOID Context
,
3103 PCOPYCONTEXT CopyContext
;
3105 CopyContext
= (PCOPYCONTEXT
)Context
;
3107 switch (Notification
)
3109 case SPFILENOTIFY_STARTSUBQUEUE
:
3110 CopyContext
->TotalOperations
= (ULONG
)Param2
;
3111 ProgressSetStepCount(CopyContext
->ProgressBar
,
3112 CopyContext
->TotalOperations
);
3113 SetupUpdateMemoryInfo(CopyContext
, TRUE
);
3116 case SPFILENOTIFY_STARTCOPY
:
3117 /* Display copy message */
3118 CONSOLE_SetStatusText(MUIGetString(STRING_COPYING
), (PWSTR
)Param1
);
3119 SetupUpdateMemoryInfo(CopyContext
, FALSE
);
3122 case SPFILENOTIFY_ENDCOPY
:
3123 CopyContext
->CompletedOperations
++;
3125 /* SYSREG checkpoint */
3126 if (CopyContext
->TotalOperations
>> 1 == CopyContext
->CompletedOperations
)
3127 DPRINT1("CHECKPOINT:HALF_COPIED\n");
3129 ProgressNextStep(CopyContext
->ProgressBar
);
3130 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
;
3216 RegistryPage(PINPUT_RECORD Ir
)
3218 INFCONTEXT InfContext
;
3225 MUIDisplayPage(REGISTRY_PAGE
);
3227 if (RepairUpdateFlag
)
3229 return SUCCESS_PAGE
;
3232 if (!SetInstallPathValue(&DestinationPath
))
3234 DPRINT("SetInstallPathValue() failed\n");
3235 MUIDisplayError(ERROR_INITIALIZE_REGISTRY
, Ir
, POPUP_WAIT_ENTER
);
3239 /* Create the default hives */
3241 Status
= NtInitializeRegistry(CM_BOOT_FLAG_SETUP
);
3242 if (!NT_SUCCESS(Status
))
3244 DPRINT("NtInitializeRegistry() failed (Status %lx)\n", Status
);
3245 MUIDisplayError(ERROR_CREATE_HIVE
, Ir
, POPUP_WAIT_ENTER
);
3249 RegInitializeRegistry();
3252 /* Update registry */
3253 CONSOLE_SetStatusText(MUIGetString(STRING_REGHIVEUPDATE
));
3255 if (!SetupFindFirstLineW(SetupInf
, L
"HiveInfs.Install", NULL
, &InfContext
))
3257 DPRINT1("SetupFindFirstLine() failed\n");
3258 MUIDisplayError(ERROR_FIND_REGISTRY
, Ir
, POPUP_WAIT_ENTER
);
3264 INF_GetDataField (&InfContext
, 0, &Action
);
3265 INF_GetDataField (&InfContext
, 1, &File
);
3266 INF_GetDataField (&InfContext
, 2, &Section
);
3268 DPRINT("Action: %S File: %S Section %S\n", Action
, File
, Section
);
3273 if (!_wcsicmp (Action
, L
"AddReg"))
3277 else if (!_wcsicmp (Action
, L
"DelReg"))
3286 CONSOLE_SetStatusText(MUIGetString(STRING_IMPORTFILE
), File
);
3288 if (!ImportRegistryFile(File
, Section
, LanguageId
, Delete
))
3290 DPRINT("Importing %S failed\n", File
);
3292 MUIDisplayError(ERROR_IMPORT_HIVE
, Ir
, POPUP_WAIT_ENTER
);
3295 } while (SetupFindNextLine(&InfContext
, &InfContext
));
3297 /* Update display registry settings */
3298 CONSOLE_SetStatusText(MUIGetString(STRING_DISPLAYETTINGSUPDATE
));
3299 if (!ProcessDisplayRegistry(SetupInf
, DisplayList
))
3301 MUIDisplayError(ERROR_UPDATE_DISPLAY_SETTINGS
, Ir
, POPUP_WAIT_ENTER
);
3305 /* Set the locale */
3306 CONSOLE_SetStatusText(MUIGetString(STRING_LOCALESETTINGSUPDATE
));
3307 if (!ProcessLocaleRegistry(LanguageList
))
3309 MUIDisplayError(ERROR_UPDATE_LOCALESETTINGS
, Ir
, POPUP_WAIT_ENTER
);
3313 /* Add keyboard layouts */
3314 CONSOLE_SetStatusText(MUIGetString(STRING_ADDKBLAYOUTS
));
3315 if (!AddKeyboardLayouts())
3317 MUIDisplayError(ERROR_ADDING_KBLAYOUTS
, Ir
, POPUP_WAIT_ENTER
);
3323 if (!SetGeoID(MUIGetGeoID()))
3325 MUIDisplayError(ERROR_UPDATE_GEOID
, Ir
, POPUP_WAIT_ENTER
);
3329 if (!IsUnattendedSetup
)
3331 /* Update keyboard layout settings */
3332 CONSOLE_SetStatusText(MUIGetString(STRING_KEYBOARDSETTINGSUPDATE
));
3333 if (!ProcessKeyboardLayoutRegistry(LayoutList
))
3335 MUIDisplayError(ERROR_UPDATE_KBSETTINGS
, Ir
, POPUP_WAIT_ENTER
);
3340 /* Add codepage information to registry */
3341 CONSOLE_SetStatusText(MUIGetString(STRING_CODEPAGEINFOUPDATE
));
3344 MUIDisplayError(ERROR_ADDING_CODEPAGE
, Ir
, POPUP_WAIT_ENTER
);
3348 /* Set the default pagefile entry */
3349 SetDefaultPagefile(DestinationDriveLetter
);
3351 /* Update the mounted devices list */
3352 SetMountedDeviceValues(PartitionList
);
3354 CONSOLE_SetStatusText(MUIGetString(STRING_DONE
));
3356 return BOOT_LOADER_PAGE
;
3361 BootLoaderPage(PINPUT_RECORD Ir
)
3363 UCHAR PartitionType
;
3364 BOOLEAN InstallOnFloppy
;
3366 WCHAR PathBuffer
[MAX_PATH
];
3368 CONSOLE_SetStatusText(MUIGetString(STRING_PLEASEWAIT
));
3370 /* Find or set the active partition */
3371 CheckActiveBootPartition(PartitionList
);
3373 /* Update the partition table because we may have changed the active partition */
3374 if (WritePartitionsToDisk(PartitionList
) == FALSE
)
3376 DPRINT("WritePartitionsToDisk() failed\n");
3377 MUIDisplayError(ERROR_WRITE_PTABLE
, Ir
, POPUP_WAIT_ENTER
);
3381 RtlFreeUnicodeString(&SystemRootPath
);
3382 swprintf(PathBuffer
,
3383 L
"\\Device\\Harddisk%lu\\Partition%lu",
3384 PartitionList
->ActiveBootDisk
->DiskNumber
,
3385 PartitionList
->ActiveBootPartition
->
3386 PartInfo
[PartitionList
->ActiveBootPartitionNumber
].PartitionNumber
);
3387 RtlCreateUnicodeString(&SystemRootPath
,
3389 DPRINT("SystemRootPath: %wZ\n", &SystemRootPath
);
3391 PartitionType
= PartitionList
->ActiveBootPartition
->
3392 PartInfo
[PartitionList
->ActiveBootPartitionNumber
].PartitionType
;
3394 if (IsUnattendedSetup
)
3396 if (UnattendMBRInstallType
== 0) /* skip MBR installation */
3398 return SUCCESS_PAGE
;
3400 else if (UnattendMBRInstallType
== 1) /* install on floppy */
3402 return BOOT_LOADER_FLOPPY_PAGE
;
3406 if (PartitionType
== PARTITION_ENTRY_UNUSED
)
3408 DPRINT("Error: active partition invalid (unused)\n");
3409 InstallOnFloppy
= TRUE
;
3411 else if (PartitionType
== 0x0A)
3413 /* OS/2 boot manager partition */
3414 DPRINT("Found OS/2 boot manager partition\n");
3415 InstallOnFloppy
= TRUE
;
3417 else if (PartitionType
== 0x83)
3419 /* Linux ext2 partition */
3420 DPRINT("Found Linux ext2 partition\n");
3421 InstallOnFloppy
= TRUE
;
3423 else if (PartitionType
== PARTITION_IFS
)
3425 /* NTFS partition */
3426 DPRINT("Found NTFS partition\n");
3427 InstallOnFloppy
= TRUE
;
3429 else if ((PartitionType
== PARTITION_FAT_12
) ||
3430 (PartitionType
== PARTITION_FAT_16
) ||
3431 (PartitionType
== PARTITION_HUGE
) ||
3432 (PartitionType
== PARTITION_XINT13
) ||
3433 (PartitionType
== PARTITION_FAT32
) ||
3434 (PartitionType
== PARTITION_FAT32_XINT13
))
3436 DPRINT("Found FAT partition\n");
3437 InstallOnFloppy
= FALSE
;
3441 /* Unknown partition */
3442 DPRINT("Unknown partition found\n");
3443 InstallOnFloppy
= TRUE
;
3446 if (InstallOnFloppy
== TRUE
)
3448 return BOOT_LOADER_FLOPPY_PAGE
;
3451 /* Unattended install on hdd? */
3452 if (IsUnattendedSetup
&& UnattendMBRInstallType
== 2)
3454 return BOOT_LOADER_HARDDISK_MBR_PAGE
;
3457 MUIDisplayPage(BOOT_LOADER_PAGE
);
3458 CONSOLE_InvertTextXY(8, Line
, 60, 1);
3462 CONSOLE_ConInKey(Ir
);
3464 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
3465 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
)) /* DOWN */
3467 CONSOLE_NormalTextXY(8, Line
, 60, 1);
3476 CONSOLE_InvertTextXY(8, Line
, 60, 1);
3478 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
3479 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_UP
)) /* UP */
3481 CONSOLE_NormalTextXY(8, Line
, 60, 1);
3490 CONSOLE_InvertTextXY(8, Line
, 60, 1);
3492 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
3493 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
3495 if (ConfirmQuit(Ir
) == TRUE
)
3500 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
3504 return BOOT_LOADER_HARDDISK_MBR_PAGE
;
3506 else if (Line
== 13)
3508 return BOOT_LOADER_HARDDISK_VBR_PAGE
;
3510 else if (Line
== 14)
3512 return BOOT_LOADER_FLOPPY_PAGE
;
3514 else if (Line
== 15)
3516 return SUCCESS_PAGE
;
3519 return BOOT_LOADER_PAGE
;
3523 return BOOT_LOADER_PAGE
;
3528 BootLoaderFloppyPage(PINPUT_RECORD Ir
)
3532 MUIDisplayPage(BOOT_LOADER_FLOPPY_PAGE
);
3534 // SetStatusText(" Please wait...");
3538 CONSOLE_ConInKey(Ir
);
3540 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
3541 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
3543 if (ConfirmQuit(Ir
) == TRUE
)
3548 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
3550 if (DoesFileExist(L
"\\Device\\Floppy0", L
"\\") == FALSE
)
3552 MUIDisplayError(ERROR_NO_FLOPPY
, Ir
, POPUP_WAIT_ENTER
);
3553 return BOOT_LOADER_FLOPPY_PAGE
;
3556 Status
= InstallFatBootcodeToFloppy(&SourceRootPath
, &DestinationArcPath
);
3557 if (!NT_SUCCESS(Status
))
3559 /* Print error message */
3560 return BOOT_LOADER_FLOPPY_PAGE
;
3563 return SUCCESS_PAGE
;
3567 return BOOT_LOADER_FLOPPY_PAGE
;
3571 BootLoaderHarddiskVbrPage(PINPUT_RECORD Ir
)
3573 UCHAR PartitionType
;
3576 PartitionType
= PartitionList
->ActiveBootPartition
->
3577 PartInfo
[PartitionList
->ActiveBootPartitionNumber
].PartitionType
;
3579 Status
= InstallVBRToPartition(&SystemRootPath
,
3581 &DestinationArcPath
,
3583 if (!NT_SUCCESS(Status
))
3585 MUIDisplayError(ERROR_WRITE_BOOT
, Ir
, POPUP_WAIT_ENTER
);
3589 return SUCCESS_PAGE
;
3593 BootLoaderHarddiskMbrPage(PINPUT_RECORD Ir
)
3595 UCHAR PartitionType
;
3597 WCHAR DestinationDevicePathBuffer
[MAX_PATH
];
3598 WCHAR SourceMbrPathBuffer
[MAX_PATH
];
3600 /* Step 1: Write the VBR */
3601 PartitionType
= PartitionList
->ActiveBootPartition
->
3602 PartInfo
[PartitionList
->ActiveBootPartitionNumber
].PartitionType
;
3604 Status
= InstallVBRToPartition(&SystemRootPath
,
3606 &DestinationArcPath
,
3608 if (!NT_SUCCESS(Status
))
3610 MUIDisplayError(ERROR_WRITE_BOOT
, Ir
, POPUP_WAIT_ENTER
);
3614 /* Step 2: Write the MBR */
3615 swprintf(DestinationDevicePathBuffer
,
3616 L
"\\Device\\Harddisk%d\\Partition0",
3617 PartitionList
->ActiveBootDisk
->DiskNumber
);
3619 wcscpy(SourceMbrPathBuffer
, SourceRootPath
.Buffer
);
3620 wcscat(SourceMbrPathBuffer
, L
"\\loader\\dosmbr.bin");
3622 DPRINT("Install MBR bootcode: %S ==> %S\n",
3623 SourceMbrPathBuffer
, DestinationDevicePathBuffer
);
3625 Status
= InstallMbrBootCodeToDisk(SourceMbrPathBuffer
,
3626 DestinationDevicePathBuffer
);
3627 if (!NT_SUCCESS (Status
))
3629 DPRINT1("InstallMbrBootCodeToDisk() failed (Status %lx)\n",
3631 MUIDisplayError(ERROR_INSTALL_BOOTCODE
, Ir
, POPUP_WAIT_ENTER
);
3635 return SUCCESS_PAGE
;
3640 QuitPage(PINPUT_RECORD Ir
)
3642 MUIDisplayPage(QUIT_PAGE
);
3644 /* Destroy partition list */
3645 if (PartitionList
!= NULL
)
3647 DestroyPartitionList (PartitionList
);
3648 PartitionList
= NULL
;
3651 /* Destroy filesystem list */
3652 if (FileSystemList
!= NULL
)
3654 DestroyFileSystemList (FileSystemList
);
3655 FileSystemList
= NULL
;
3658 /* Destroy computer settings list */
3659 if (ComputerList
!= NULL
)
3661 DestroyGenericList(ComputerList
, TRUE
);
3662 ComputerList
= NULL
;