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
;
1433 IsDiskSizeValid(PPARTENTRY PartEntry
)
1437 /* check for unpartitioned space */
1438 m1
= PartEntry
->UnpartitionedLength
;
1439 m1
= (m1
+ (1 << 19)) >> 20; /* in MBytes (rounded) */
1441 if( m1
> RequiredPartitionDiskSpace
)
1446 /* check for partitioned space */
1447 m2
= PartEntry
->PartInfo
[0].PartitionLength
.QuadPart
;
1448 m2
= (m2
+ (1 << 19)) >> 20; /* in MBytes (rounded) */
1449 if (m2
< RequiredPartitionDiskSpace
)
1451 /* partition is too small so ask for another partion */
1452 DPRINT1("Partition is too small(unpartitioned: %I64u MB, partitioned: %I64u MB), required disk space is %lu MB\n", m1
, m2
, RequiredPartitionDiskSpace
);
1464 SelectPartitionPage(PINPUT_RECORD Ir
)
1466 MUIDisplayPage(SELECT_PARTITION_PAGE
);
1468 if (PartitionList
== NULL
)
1470 PartitionList
= CreatePartitionList(2,
1474 if (PartitionList
== NULL
)
1476 /* FIXME: show an error dialog */
1479 else if (IsListEmpty (&PartitionList
->DiskListHead
))
1481 MUIDisplayError(ERROR_NO_HDD
, Ir
, POPUP_WAIT_ENTER
);
1486 DrawPartitionList(PartitionList
);
1488 /* Warn about partitions created by Linux Fdisk */
1489 if (WarnLinuxPartitions
== TRUE
&&
1490 CheckForLinuxFdiskPartitions(PartitionList
) == TRUE
)
1492 MUIDisplayError(ERROR_WARN_PARTITION
, NULL
, POPUP_WAIT_NONE
);
1496 CONSOLE_ConInKey(Ir
);
1498 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1499 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1503 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_RETURN
) /* ENTER */
1505 WarnLinuxPartitions
= FALSE
;
1506 return SELECT_PARTITION_PAGE
;
1511 if (IsUnattendedSetup
)
1513 if (!SelectPartition(PartitionList
, UnattendDestinationDiskNumber
, UnattendDestinationPartitionNumber
))
1518 if (!IsDiskSizeValid(PartitionList
->CurrentPartition
))
1520 MUIDisplayError(ERROR_INSUFFICIENT_DISKSPACE
, Ir
, POPUP_WAIT_ANY_KEY
);
1521 return SELECT_PARTITION_PAGE
; /* let the user select another partition */
1524 CreateNewPartition(PartitionList
,
1525 PartitionList
->CurrentPartition
->SectorCount
.QuadPart
,
1528 DestinationDriveLetter
= (WCHAR
)PartitionList
->CurrentPartition
->DriveLetter
;
1530 return SELECT_FILE_SYSTEM_PAGE
;
1536 if (!IsDiskSizeValid(PartitionList
->CurrentPartition
))
1538 MUIDisplayError(ERROR_INSUFFICIENT_DISKSPACE
, Ir
, POPUP_WAIT_ANY_KEY
);
1539 return SELECT_PARTITION_PAGE
; /* let the user select another partition */
1542 DestinationDriveLetter
= (WCHAR
)PartitionList
->CurrentPartition
->DriveLetter
;
1544 return SELECT_FILE_SYSTEM_PAGE
;
1550 /* Update status text */
1551 if (PartitionList
->CurrentPartition
== NULL
||
1552 PartitionList
->CurrentPartition
->IsPartitioned
== FALSE
)
1554 CONSOLE_SetStatusText(MUIGetString(STRING_INSTALLCREATEPARTITION
));
1558 CONSOLE_SetStatusText(MUIGetString(STRING_INSTALLDELETEPARTITION
));
1561 CONSOLE_ConInKey(Ir
);
1563 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1564 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1566 if (ConfirmQuit(Ir
) == TRUE
)
1568 DestroyPartitionList(PartitionList
);
1569 PartitionList
= NULL
;
1575 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1576 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
)) /* DOWN */
1578 ScrollDownPartitionList(PartitionList
);
1580 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1581 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_UP
)) /* UP */
1583 ScrollUpPartitionList(PartitionList
);
1585 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_RETURN
) /* ENTER */
1588 if (!IsDiskSizeValid(PartitionList
->CurrentPartition
))
1590 MUIDisplayError(ERROR_INSUFFICIENT_DISKSPACE
, Ir
, POPUP_WAIT_ANY_KEY
);
1591 return SELECT_PARTITION_PAGE
; /* let the user select another partition */
1594 if (PartitionList
->CurrentPartition
== NULL
||
1595 PartitionList
->CurrentPartition
->IsPartitioned
== FALSE
)
1597 CreateNewPartition(PartitionList
,
1602 DestinationDriveLetter
= (WCHAR
)PartitionList
->CurrentPartition
->DriveLetter
;
1604 return SELECT_FILE_SYSTEM_PAGE
;
1606 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== 'C') /* C */
1608 if (PartitionList
->CurrentPartition
->IsPartitioned
== TRUE
)
1610 MUIDisplayError(ERROR_NEW_PARTITION
, Ir
, POPUP_WAIT_ANY_KEY
);
1611 return SELECT_PARTITION_PAGE
;
1614 return CREATE_PARTITION_PAGE
;
1616 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== 'D') /* D */
1618 if (PartitionList
->CurrentPartition
->IsPartitioned
== FALSE
)
1620 MUIDisplayError(ERROR_DELETE_SPACE
, Ir
, POPUP_WAIT_ANY_KEY
);
1621 return SELECT_PARTITION_PAGE
;
1624 return DELETE_PARTITION_PAGE
;
1628 return SELECT_PARTITION_PAGE
;
1633 DrawInputField(ULONG FieldLength
,
1644 memset(buf
, '_', sizeof(buf
));
1645 buf
[FieldLength
- strlen(FieldContent
)] = 0;
1646 strcat(buf
, FieldContent
);
1648 WriteConsoleOutputCharacterA(StdOutput
,
1656 #define PARTITION_SIZE_INPUT_FIELD_LENGTH 6
1657 /* Restriction for MaxSize: pow(10, PARTITION_SIZE_INPUT_FIELD_LENGTH)-1 */
1658 #define PARTITION_MAXSIZE 999999
1661 ShowPartitionSizeInputBox(SHORT Left
,
1685 DrawBox(Left
, Top
, Right
- Left
+ 1, Bottom
- Top
+ 1);
1690 strcpy(Buffer
, MUIGetString(STRING_PARTITIONSIZE
));
1691 iLeft
= coPos
.X
+ strlen(Buffer
) + 1;
1694 WriteConsoleOutputCharacterA(StdOutput
,
1700 sprintf(Buffer
, MUIGetString(STRING_MAXSIZE
), MaxSize
);
1701 coPos
.X
= iLeft
+ PARTITION_SIZE_INPUT_FIELD_LENGTH
+ 1;
1703 WriteConsoleOutputCharacterA(StdOutput
,
1709 sprintf(Buffer
, "%lu", MaxSize
);
1710 Index
= strlen(Buffer
);
1711 DrawInputField(PARTITION_SIZE_INPUT_FIELD_LENGTH
,
1718 CONSOLE_ConInKey(&Ir
);
1720 if ((Ir
.Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1721 (Ir
.Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1729 else if (Ir
.Event
.KeyEvent
.wVirtualKeyCode
== VK_RETURN
) /* ENTER */
1733 else if (Ir
.Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
) /* ESCAPE */
1741 else if ((Ir
.Event
.KeyEvent
.wVirtualKeyCode
== VK_BACK
) && /* BACKSPACE */
1747 DrawInputField(PARTITION_SIZE_INPUT_FIELD_LENGTH
,
1752 else if ((Ir
.Event
.KeyEvent
.uChar
.AsciiChar
!= 0x00) &&
1753 (Index
< PARTITION_SIZE_INPUT_FIELD_LENGTH
))
1755 ch
= Ir
.Event
.KeyEvent
.uChar
.AsciiChar
;
1757 if ((ch
>= '0') && (ch
<= '9'))
1763 DrawInputField(PARTITION_SIZE_INPUT_FIELD_LENGTH
,
1771 strcpy(InputBuffer
, Buffer
);
1776 CreatePartitionPage(PINPUT_RECORD Ir
)
1778 PDISKENTRY DiskEntry
;
1779 PPARTENTRY PartEntry
;
1782 CHAR InputBuffer
[50];
1786 ULONGLONG SectorCount
;
1789 if (PartitionList
== NULL
||
1790 PartitionList
->CurrentDisk
== NULL
||
1791 PartitionList
->CurrentPartition
== NULL
)
1793 /* FIXME: show an error dialog */
1797 DiskEntry
= PartitionList
->CurrentDisk
;
1798 PartEntry
= PartitionList
->CurrentPartition
;
1800 CONSOLE_SetStatusText(MUIGetString(STRING_PLEASEWAIT
));
1802 CONSOLE_SetTextXY(6, 8, MUIGetString(STRING_CHOOSENEWPARTITION
));
1804 DiskSize
= DiskEntry
->SectorCount
.QuadPart
* DiskEntry
->BytesPerSector
;
1806 if (DiskSize
>= 10737418240) /* 10 GB */
1808 DiskSize
= DiskSize
/ 1073741824;
1809 Unit
= MUIGetString(STRING_GB
);
1814 DiskSize
= DiskSize
/ 1048576;
1818 Unit
= MUIGetString(STRING_MB
);
1821 if (DiskEntry
->DriverName
.Length
> 0)
1823 CONSOLE_PrintTextXY(6, 10,
1824 MUIGetString(STRING_HDINFOPARTCREATE
),
1827 DiskEntry
->DiskNumber
,
1831 &DiskEntry
->DriverName
);
1835 CONSOLE_PrintTextXY(6, 10,
1836 MUIGetString(STRING_HDDINFOUNK1
),
1839 DiskEntry
->DiskNumber
,
1845 CONSOLE_SetTextXY(6, 12, MUIGetString(STRING_HDDSIZE
));
1848 CONSOLE_PrintTextXY(8, 10, "Maximum size of the new partition is %I64u MB",
1849 PartitionList
->CurrentPartition
->SectorCount
* DiskEntry
->BytesPerSector
/ 1048576);
1852 CONSOLE_SetStatusText(MUIGetString(STRING_CREATEPARTITION
));
1854 PartEntry
= PartitionList
->CurrentPartition
;
1857 MaxSize
= (PartEntry
->SectorCount
.QuadPart
* DiskEntry
->BytesPerSector
) / 1048576; /* in MBytes (rounded) */
1859 if (MaxSize
> PARTITION_MAXSIZE
)
1860 MaxSize
= PARTITION_MAXSIZE
;
1862 ShowPartitionSizeInputBox(12, 14, xScreen
- 12, 17, /* left, top, right, bottom */
1863 MaxSize
, InputBuffer
, &Quit
, &Cancel
);
1867 if (ConfirmQuit (Ir
) == TRUE
)
1872 else if (Cancel
== TRUE
)
1874 return SELECT_PARTITION_PAGE
;
1878 PartSize
= atoi(InputBuffer
);
1886 if (PartSize
> MaxSize
)
1892 /* Convert to bytes */
1893 if (PartSize
== MaxSize
)
1895 /* Use all of the unpartitioned disk space */
1896 SectorCount
= PartEntry
->SectorCount
.QuadPart
;
1900 /* Calculate the sector count from the size in MB */
1901 SectorCount
= PartSize
* 1048576 / DiskEntry
->BytesPerSector
;
1903 /* But never get larger than the unpartitioned disk space */
1904 if (SectorCount
> PartEntry
->SectorCount
.QuadPart
)
1905 SectorCount
= PartEntry
->SectorCount
.QuadPart
;
1908 DPRINT ("Partition size: %I64u bytes\n", PartSize
);
1910 CreateNewPartition(PartitionList
,
1914 return SELECT_PARTITION_PAGE
;
1918 return CREATE_PARTITION_PAGE
;
1923 DeletePartitionPage(PINPUT_RECORD Ir
)
1925 PDISKENTRY DiskEntry
;
1926 PPARTENTRY PartEntry
;
1932 if (PartitionList
== NULL
||
1933 PartitionList
->CurrentDisk
== NULL
||
1934 PartitionList
->CurrentPartition
== NULL
)
1936 /* FIXME: show an error dialog */
1940 DiskEntry
= PartitionList
->CurrentDisk
;
1941 PartEntry
= PartitionList
->CurrentPartition
;
1943 MUIDisplayPage(DELETE_PARTITION_PAGE
);
1945 /* Determine partition type */
1947 if (PartEntry
->New
== TRUE
)
1949 PartType
= MUIGetString(STRING_UNFORMATTED
);
1951 else if (PartEntry
->IsPartitioned
== TRUE
)
1953 if ((PartEntry
->PartitionType
== PARTITION_FAT_12
) ||
1954 (PartEntry
->PartitionType
== PARTITION_FAT_16
) ||
1955 (PartEntry
->PartitionType
== PARTITION_HUGE
) ||
1956 (PartEntry
->PartitionType
== PARTITION_XINT13
))
1960 else if ((PartEntry
->PartitionType
== PARTITION_FAT32
) ||
1961 (PartEntry
->PartitionType
== PARTITION_FAT32_XINT13
))
1965 else if (PartEntry
->PartitionType
== PARTITION_EXT2
)
1969 else if (PartEntry
->PartitionType
== PARTITION_IFS
)
1971 PartType
= "NTFS"; /* FIXME: Not quite correct! */
1975 PartSize
= PartEntry
->SectorCount
.QuadPart
* DiskEntry
->BytesPerSector
;
1977 if (PartSize
>= 10737418240) /* 10 GB */
1979 PartSize
= PartSize
/ 1073741824;
1980 Unit
= MUIGetString(STRING_GB
);
1984 if (PartSize
>= 10485760) /* 10 MB */
1986 PartSize
= PartSize
/ 1048576;
1987 Unit
= MUIGetString(STRING_MB
);
1991 PartSize
= PartSize
/ 1024;
1992 Unit
= MUIGetString(STRING_KB
);
1995 if (PartType
== NULL
)
1997 CONSOLE_PrintTextXY(6, 10,
1998 MUIGetString(STRING_HDDINFOUNK2
),
1999 (PartEntry
->DriveLetter
== 0) ? '-' : PartEntry
->DriveLetter
,
2000 (PartEntry
->DriveLetter
== 0) ? '-' : ':',
2001 PartEntry
->PartitionType
,
2007 CONSOLE_PrintTextXY(6, 10,
2008 " %c%c %s %I64u %s",
2009 (PartEntry
->DriveLetter
== 0) ? '-' : PartEntry
->DriveLetter
,
2010 (PartEntry
->DriveLetter
== 0) ? '-' : ':',
2016 DiskSize
= DiskEntry
->SectorCount
.QuadPart
* DiskEntry
->BytesPerSector
;
2018 if (DiskSize
>= 10737418240) /* 10 GB */
2020 DiskSize
= DiskSize
/ 1073741824;
2021 Unit
= MUIGetString(STRING_GB
);
2026 DiskSize
= DiskSize
/ 1048576;
2030 Unit
= MUIGetString(STRING_MB
);
2033 if (DiskEntry
->DriverName
.Length
> 0)
2035 CONSOLE_PrintTextXY(6, 12,
2036 MUIGetString(STRING_HDINFOPARTDELETE
),
2039 DiskEntry
->DiskNumber
,
2043 &DiskEntry
->DriverName
);
2047 CONSOLE_PrintTextXY(6, 12,
2048 MUIGetString(STRING_HDDINFOUNK3
),
2051 DiskEntry
->DiskNumber
,
2059 CONSOLE_ConInKey(Ir
);
2061 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
2062 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
2064 if (ConfirmQuit(Ir
) == TRUE
)
2071 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
) /* ESC */
2073 return SELECT_PARTITION_PAGE
;
2075 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== 'D') /* D */
2077 DeleteCurrentPartition(PartitionList
);
2079 return SELECT_PARTITION_PAGE
;
2083 return DELETE_PARTITION_PAGE
;
2088 SelectFileSystemPage(PINPUT_RECORD Ir
)
2090 PDISKENTRY DiskEntry
;
2091 PPARTENTRY PartEntry
;
2098 if (PartitionList
== NULL
||
2099 PartitionList
->CurrentDisk
== NULL
||
2100 PartitionList
->CurrentPartition
== NULL
)
2102 /* FIXME: show an error dialog */
2106 DiskEntry
= PartitionList
->CurrentDisk
;
2107 PartEntry
= PartitionList
->CurrentPartition
;
2109 /* adjust disk size */
2110 DiskSize
= DiskEntry
->SectorCount
.QuadPart
* DiskEntry
->BytesPerSector
;
2111 if (DiskSize
>= 10737418240) /* 10 GB */
2113 DiskSize
= DiskSize
/ 1073741824;
2114 DiskUnit
= MUIGetString(STRING_GB
);
2118 DiskSize
= DiskSize
/ 1048576;
2119 DiskUnit
= MUIGetString(STRING_MB
);
2122 /* adjust partition size */
2123 PartSize
= PartEntry
->SectorCount
.QuadPart
* DiskEntry
->BytesPerSector
;
2124 if (PartSize
>= 10737418240) /* 10 GB */
2126 PartSize
= PartSize
/ 1073741824;
2127 PartUnit
= MUIGetString(STRING_GB
);
2131 PartSize
= PartSize
/ 1048576;
2132 PartUnit
= MUIGetString(STRING_MB
);
2135 /* adjust partition type */
2136 if ((PartEntry
->PartitionType
== PARTITION_FAT_12
) ||
2137 (PartEntry
->PartitionType
== PARTITION_FAT_16
) ||
2138 (PartEntry
->PartitionType
== PARTITION_HUGE
) ||
2139 (PartEntry
->PartitionType
== PARTITION_XINT13
))
2143 else if ((PartEntry
->PartitionType
== PARTITION_FAT32
) ||
2144 (PartEntry
->PartitionType
== PARTITION_FAT32_XINT13
))
2148 else if (PartEntry
->PartitionType
== PARTITION_EXT2
)
2152 else if (PartEntry
->PartitionType
== PARTITION_IFS
)
2154 PartType
= "NTFS"; /* FIXME: Not quite correct! */
2156 else if (PartEntry
->PartitionType
== PARTITION_ENTRY_UNUSED
)
2158 PartType
= MUIGetString(STRING_FORMATUNUSED
);
2162 PartType
= MUIGetString(STRING_FORMATUNKNOWN
);
2165 if (PartEntry
->AutoCreate
== TRUE
)
2167 CONSOLE_SetTextXY(6, 8, MUIGetString(STRING_NEWPARTITION
));
2170 CONSOLE_PrintTextXY(8, 10, "Partition %lu (%I64u %s) %s of",
2171 PartEntry
->PartitionNumber
,
2177 CONSOLE_PrintTextXY(8, 10, MUIGetString(STRING_HDINFOPARTZEROED
),
2178 DiskEntry
->DiskNumber
,
2184 &DiskEntry
->DriverName
);
2186 CONSOLE_SetTextXY(6, 12, MUIGetString(STRING_PARTFORMAT
));
2189 PartEntry
->AutoCreate
= FALSE
;
2191 else if (PartEntry
->New
== TRUE
)
2193 CONSOLE_SetTextXY(6, 8, MUIGetString(STRING_NONFORMATTEDPART
));
2194 CONSOLE_SetTextXY(6, 10, MUIGetString(STRING_PARTFORMAT
));
2198 CONSOLE_SetTextXY(6, 8, MUIGetString(STRING_INSTALLONPART
));
2200 if (PartType
== NULL
)
2202 CONSOLE_PrintTextXY(8, 10,
2203 MUIGetString(STRING_HDDINFOUNK4
),
2204 (PartEntry
->DriveLetter
== 0) ? '-' : PartEntry
->DriveLetter
,
2205 (PartEntry
->DriveLetter
== 0) ? '-' : ':',
2206 PartEntry
->PartitionType
,
2212 CONSOLE_PrintTextXY(8, 10,
2214 (PartEntry
->DriveLetter
== 0) ? '-' : PartEntry
->DriveLetter
,
2215 (PartEntry
->DriveLetter
== 0) ? '-' : ':',
2221 CONSOLE_PrintTextXY(6, 12, MUIGetString(STRING_HDINFOPARTEXISTS
),
2222 DiskEntry
->DiskNumber
,
2228 &DiskEntry
->DriverName
);
2231 MUIDisplayPage(SELECT_FILE_SYSTEM_PAGE
);
2233 if (FileSystemList
== NULL
)
2235 FileSystemList
= CreateFileSystemList(6, 26, PartEntry
->New
, L
"FAT");
2236 if (FileSystemList
== NULL
)
2238 /* FIXME: show an error dialog */
2242 /* FIXME: Add file systems to list */
2245 DrawFileSystemList(FileSystemList
);
2247 if (RepairUpdateFlag
)
2249 return CHECK_FILE_SYSTEM_PAGE
;
2250 //return SELECT_PARTITION_PAGE;
2253 if (IsUnattendedSetup
)
2255 if (UnattendFormatPartition
)
2257 return FORMAT_PARTITION_PAGE
;
2260 return CHECK_FILE_SYSTEM_PAGE
;
2265 CONSOLE_ConInKey(Ir
);
2267 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
2268 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
2270 if (ConfirmQuit(Ir
) == TRUE
)
2277 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
2278 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
)) /* ESC */
2280 return SELECT_PARTITION_PAGE
;
2282 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
2283 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
)) /* DOWN */
2285 ScrollDownFileSystemList(FileSystemList
);
2287 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
2288 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_UP
)) /* UP */
2290 ScrollUpFileSystemList(FileSystemList
);
2292 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_RETURN
) /* ENTER */
2294 if (!FileSystemList
->Selected
->FormatFunc
)
2296 return CHECK_FILE_SYSTEM_PAGE
;
2300 return FORMAT_PARTITION_PAGE
;
2305 return SELECT_FILE_SYSTEM_PAGE
;
2310 FormatPartitionPage(PINPUT_RECORD Ir
)
2312 WCHAR PathBuffer
[MAX_PATH
];
2313 PDISKENTRY DiskEntry
;
2314 PPARTENTRY PartEntry
;
2323 MUIDisplayPage(FORMAT_PARTITION_PAGE
);
2325 if (PartitionList
== NULL
||
2326 PartitionList
->CurrentDisk
== NULL
||
2327 PartitionList
->CurrentPartition
== NULL
)
2329 /* FIXME: show an error dialog */
2333 DiskEntry
= PartitionList
->CurrentDisk
;
2334 PartEntry
= PartitionList
->CurrentPartition
;
2338 if (!IsUnattendedSetup
)
2340 CONSOLE_ConInKey(Ir
);
2343 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
2344 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
2346 if (ConfirmQuit(Ir
) == TRUE
)
2353 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_RETURN
|| IsUnattendedSetup
) /* ENTER */
2355 CONSOLE_SetStatusText(MUIGetString(STRING_PLEASEWAIT
));
2357 if (wcscmp(FileSystemList
->Selected
->FileSystem
, L
"FAT") == 0)
2359 if (PartEntry
->SectorCount
.QuadPart
< 8192)
2361 /* FAT12 CHS partition (disk is smaller than 4.1MB) */
2362 PartEntry
->PartitionType
= PARTITION_FAT_12
;
2364 else if (PartEntry
->StartSector
.QuadPart
< 1450560)
2366 /* Partition starts below the 8.4GB boundary ==> CHS partition */
2368 if (PartEntry
->SectorCount
.QuadPart
< 65536)
2370 /* FAT16 CHS partition (partiton size < 32MB) */
2371 PartEntry
->PartitionType
= PARTITION_FAT_16
;
2373 else if (PartEntry
->SectorCount
.QuadPart
< 1048576)
2375 /* FAT16 CHS partition (partition size < 512MB) */
2376 PartEntry
->PartitionType
= PARTITION_HUGE
;
2380 /* FAT32 CHS partition (partition size >= 512MB) */
2381 PartEntry
->PartitionType
= PARTITION_FAT32
;
2386 /* Partition starts above the 8.4GB boundary ==> LBA partition */
2388 if (PartEntry
->SectorCount
.QuadPart
< 1048576)
2390 /* FAT16 LBA partition (partition size < 512MB) */
2391 PartEntry
->PartitionType
= PARTITION_XINT13
;
2395 /* FAT32 LBA partition (partition size >= 512MB) */
2396 PartEntry
->PartitionType
= PARTITION_FAT32_XINT13
;
2400 DiskEntry
->LayoutBuffer
->PartitionEntry
[PartEntry
->PartitionIndex
].PartitionType
= PartEntry
->PartitionType
;
2403 else if (wcscmp(FileSystemList
->Selected
->FileSystem
, L
"EXT2") == 0)
2405 PartEntry
->PartInfo
[PartNum
].PartitionType
= PARTITION_EXT2
;
2406 DiskEntry
->LayoutBuffer
->PartitionEntry
[PartEntry
->PartitionIndex
].PartitionType
= PartEntry
->PartitionType
;
2409 else if (!FileSystemList
->Selected
->FormatFunc
)
2413 CONSOLE_PrintTextXY(6, 12,
2414 "Disk: %I64u Cylinder: %I64u Track: %I64u",
2415 DiskEntry
->DiskSize
,
2416 DiskEntry
->CylinderSize
,
2417 DiskEntry
->TrackSize
);
2420 DiskEntry
= PartitionList
->CurrentDisk
;
2421 Entry
= DiskEntry
->PartListHead
.Flink
;
2423 while (Entry
!= &DiskEntry
->PrimaryPartListHead
)
2425 PartEntry
= CONTAINING_RECORD(Entry
, PARTENTRY
, ListEntry
);
2427 if (PartEntry
->IsPartitioned
== TRUE
)
2429 CONSOLE_PrintTextXY(6, Line
,
2430 "%2u: %2u %c %12I64u %12I64u %2u %c",
2432 PartEntry
->PartitionNumber
,
2433 PartEntry
->BootIndicator
? 'A' : '-',
2434 PartEntry
->StartSector
.QuadPart
,
2435 PartEntry
->SectorCount
.QuadPart
,
2436 PartEntry
->PartitionType
,
2437 PartEntry
->Dirty
? '*' : ' ');
2441 Entry
= Entry
->Flink
;
2444 /* Restore the old entry */
2445 PartEntry
= PartitionList
->CurrentPartition
;
2448 CheckActiveBootPartition(PartitionList
);
2450 if (WritePartitionsToDisk(PartitionList
) == FALSE
)
2452 DPRINT("WritePartitionsToDisk() failed\n");
2453 MUIDisplayError(ERROR_WRITE_PTABLE
, Ir
, POPUP_WAIT_ENTER
);
2457 /* Set DestinationRootPath */
2458 RtlFreeUnicodeString(&DestinationRootPath
);
2459 swprintf(PathBuffer
,
2460 L
"\\Device\\Harddisk%lu\\Partition%lu",
2461 PartitionList
->CurrentDisk
->DiskNumber
,
2462 PartitionList
->CurrentPartition
->PartitionNumber
);
2463 RtlCreateUnicodeString(&DestinationRootPath
,
2465 DPRINT("DestinationRootPath: %wZ\n", &DestinationRootPath
);
2467 if (FileSystemList
->Selected
->FormatFunc
)
2469 Status
= FormatPartition(&DestinationRootPath
,
2470 FileSystemList
->Selected
);
2471 if (!NT_SUCCESS(Status
))
2473 DPRINT1("FormatPartition() failed with status 0x%08lx\n", Status
);
2474 /* FIXME: show an error dialog */
2478 PartEntry
->New
= FALSE
;
2483 CONSOLE_SetStatusText(" Done. Press any key ...");
2484 CONSOLE_ConInKey(Ir
);
2487 DestroyFileSystemList(FileSystemList
);
2488 FileSystemList
= NULL
;
2489 return INSTALL_DIRECTORY_PAGE
;
2493 return FORMAT_PARTITION_PAGE
;
2498 CheckFileSystemPage(PINPUT_RECORD Ir
)
2500 PFILE_SYSTEM_ITEM CurrentFileSystem
;
2501 WCHAR PathBuffer
[MAX_PATH
];
2502 CHAR Buffer
[MAX_PATH
];
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
->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
)
2579 WCHAR PathBuffer
[MAX_PATH
];
2581 /* Create 'InstallPath' string */
2582 RtlFreeUnicodeString(&InstallPath
);
2583 RtlCreateUnicodeString(&InstallPath
,
2586 /* Create 'DestinationPath' string */
2587 RtlFreeUnicodeString(&DestinationPath
);
2588 wcscpy(PathBuffer
, DestinationRootPath
.Buffer
);
2590 if (InstallDir
[0] != L
'\\')
2591 wcscat(PathBuffer
, L
"\\");
2593 wcscat(PathBuffer
, InstallDir
);
2594 RtlCreateUnicodeString(&DestinationPath
, PathBuffer
);
2596 /* Create 'DestinationArcPath' */
2597 RtlFreeUnicodeString(&DestinationArcPath
);
2598 swprintf(PathBuffer
,
2599 L
"multi(0)disk(0)rdisk(%lu)partition(%lu)",
2600 DiskEntry
->BiosDiskNumber
,
2601 PartEntry
->PartitionNumber
);
2603 if (InstallDir
[0] != L
'\\')
2604 wcscat(PathBuffer
, L
"\\");
2606 wcscat(PathBuffer
, InstallDir
);
2607 RtlCreateUnicodeString(&DestinationArcPath
, PathBuffer
);
2609 return PREPARE_COPY_PAGE
;
2614 InstallDirectoryPage(PINPUT_RECORD Ir
)
2616 PDISKENTRY DiskEntry
;
2617 PPARTENTRY PartEntry
;
2618 WCHAR InstallDir
[51];
2621 if (PartitionList
== NULL
||
2622 PartitionList
->CurrentDisk
== NULL
||
2623 PartitionList
->CurrentPartition
== NULL
)
2625 /* FIXME: show an error dialog */
2629 DiskEntry
= PartitionList
->CurrentDisk
;
2630 PartEntry
= PartitionList
->CurrentPartition
;
2632 if (IsUnattendedSetup
)
2633 wcscpy(InstallDir
, UnattendInstallationDirectory
);
2635 wcscpy(InstallDir
, L
"\\ReactOS");
2637 Length
= wcslen(InstallDir
);
2638 CONSOLE_SetInputTextXY(8, 11, 51, InstallDir
);
2639 MUIDisplayPage(INSTALL_DIRECTORY_PAGE
);
2641 if (IsUnattendedSetup
)
2643 return InstallDirectoryPage1(InstallDir
,
2650 CONSOLE_ConInKey(Ir
);
2652 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
2653 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
2655 if (ConfirmQuit(Ir
) == TRUE
)
2660 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2662 return InstallDirectoryPage1(InstallDir
,
2666 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x08) /* BACKSPACE */
2671 InstallDir
[Length
] = 0;
2672 CONSOLE_SetInputTextXY(8, 11, 51, InstallDir
);
2675 else if (isprint(Ir
->Event
.KeyEvent
.uChar
.AsciiChar
))
2679 InstallDir
[Length
] = (WCHAR
)Ir
->Event
.KeyEvent
.uChar
.AsciiChar
;
2681 InstallDir
[Length
] = 0;
2682 CONSOLE_SetInputTextXY(8, 11, 51, InstallDir
);
2687 return INSTALL_DIRECTORY_PAGE
;
2692 AddSectionToCopyQueueCab(HINF InfFile
,
2694 PWCHAR SourceCabinet
,
2695 PCUNICODE_STRING DestinationPath
,
2698 INFCONTEXT FilesContext
;
2699 INFCONTEXT DirContext
;
2701 PWCHAR FileKeyValue
;
2703 PWCHAR TargetFileName
;
2705 /* Search for the SectionName section */
2706 if (!SetupFindFirstLineW(InfFile
, SectionName
, NULL
, &FilesContext
))
2709 sprintf(Buffer
, MUIGetString(STRING_TXTSETUPFAILED
), SectionName
);
2710 PopupError(Buffer
, MUIGetString(STRING_REBOOTCOMPUTER
), Ir
, POPUP_WAIT_ENTER
);
2715 * Enumerate the files in the section
2716 * and add them to the file queue.
2720 /* Get source file name and target directory id */
2721 if (!INF_GetData(&FilesContext
, &FileKeyName
, &FileKeyValue
))
2723 /* FIXME: Handle error! */
2724 DPRINT1("INF_GetData() failed\n");
2728 /* Get optional target file name */
2729 if (!INF_GetDataField(&FilesContext
, 2, &TargetFileName
))
2730 TargetFileName
= NULL
;
2732 DPRINT("FileKeyName: '%S' FileKeyValue: '%S'\n", FileKeyName
, FileKeyValue
);
2734 /* Lookup target directory */
2735 if (!SetupFindFirstLineW(InfFile
, L
"Directories", FileKeyValue
, &DirContext
))
2737 /* FIXME: Handle error! */
2738 DPRINT1("SetupFindFirstLine() failed\n");
2742 if (!INF_GetData(&DirContext
, NULL
, &DirKeyValue
))
2744 /* FIXME: Handle error! */
2745 DPRINT1("INF_GetData() failed\n");
2749 if (!SetupQueueCopy(SetupFileQueue
,
2751 SourceRootPath
.Buffer
,
2752 SourceRootDir
.Buffer
,
2757 /* FIXME: Handle error! */
2758 DPRINT1("SetupQueueCopy() failed\n");
2760 } while (SetupFindNextLine(&FilesContext
, &FilesContext
));
2767 AddSectionToCopyQueue(HINF InfFile
,
2769 PWCHAR SourceCabinet
,
2770 PCUNICODE_STRING DestinationPath
,
2773 INFCONTEXT FilesContext
;
2774 INFCONTEXT DirContext
;
2776 PWCHAR FileKeyValue
;
2778 PWCHAR TargetFileName
;
2779 WCHAR CompleteOrigFileName
[512];
2782 return AddSectionToCopyQueueCab(InfFile
, L
"SourceFiles", SourceCabinet
, DestinationPath
, Ir
);
2784 /* Search for the SectionName section */
2785 if (!SetupFindFirstLineW(InfFile
, SectionName
, NULL
, &FilesContext
))
2788 sprintf(Buffer
, MUIGetString(STRING_TXTSETUPFAILED
), SectionName
);
2789 PopupError(Buffer
, MUIGetString(STRING_REBOOTCOMPUTER
), Ir
, POPUP_WAIT_ENTER
);
2794 * Enumerate the files in the section
2795 * and add them to the file queue.
2799 /* Get source file name and target directory id */
2800 if (!INF_GetData(&FilesContext
, &FileKeyName
, &FileKeyValue
))
2802 /* FIXME: Handle error! */
2803 DPRINT1("INF_GetData() failed\n");
2807 /* Get target directory id */
2808 if (!INF_GetDataField(&FilesContext
, 13, &FileKeyValue
))
2810 /* FIXME: Handle error! */
2811 DPRINT1("INF_GetData() failed\n");
2815 /* Get optional target file name */
2816 if (!INF_GetDataField(&FilesContext
, 11, &TargetFileName
))
2817 TargetFileName
= NULL
;
2818 else if (!*TargetFileName
)
2819 TargetFileName
= NULL
;
2821 DPRINT("FileKeyName: '%S' FileKeyValue: '%S'\n", FileKeyName
, FileKeyValue
);
2823 /* Lookup target directory */
2824 if (!SetupFindFirstLineW(InfFile
, L
"Directories", FileKeyValue
, &DirContext
))
2826 /* FIXME: Handle error! */
2827 DPRINT1("SetupFindFirstLine() failed\n");
2831 if (!INF_GetData(&DirContext
, NULL
, &DirKeyValue
))
2833 /* FIXME: Handle error! */
2834 DPRINT1("INF_GetData() failed\n");
2838 wcscpy(CompleteOrigFileName
, SourceRootDir
.Buffer
);
2839 wcscat(CompleteOrigFileName
, L
"\\");
2840 wcscat(CompleteOrigFileName
, DirKeyValue
);
2842 if (!SetupQueueCopy(SetupFileQueue
,
2844 SourceRootPath
.Buffer
,
2845 CompleteOrigFileName
,
2850 /* FIXME: Handle error! */
2851 DPRINT1("SetupQueueCopy() failed\n");
2853 } while (SetupFindNextLine(&FilesContext
, &FilesContext
));
2860 PrepareCopyPageInfFile(HINF InfFile
,
2861 PWCHAR SourceCabinet
,
2864 WCHAR PathBuffer
[MAX_PATH
];
2865 INFCONTEXT DirContext
;
2866 PWCHAR AdditionalSectionName
= NULL
;
2871 /* Add common files */
2872 if (!AddSectionToCopyQueue(InfFile
, L
"SourceDisksFiles", SourceCabinet
, &DestinationPath
, Ir
))
2875 /* Add specific files depending of computer type */
2876 if (SourceCabinet
== NULL
)
2878 if (!ProcessComputerFiles(InfFile
, ComputerList
, &AdditionalSectionName
))
2881 if (AdditionalSectionName
)
2883 if (!AddSectionToCopyQueue(InfFile
, AdditionalSectionName
, SourceCabinet
, &DestinationPath
, Ir
))
2888 /* Create directories */
2892 * Install directories like '\reactos\test' are not handled yet.
2895 /* Get destination path */
2896 wcscpy(PathBuffer
, DestinationPath
.Buffer
);
2898 /* Remove trailing backslash */
2899 Length
= wcslen(PathBuffer
);
2900 if ((Length
> 0) && (PathBuffer
[Length
- 1] == '\\'))
2902 PathBuffer
[Length
- 1] = 0;
2905 /* Create the install directory */
2906 Status
= SetupCreateDirectory(PathBuffer
);
2907 if (!NT_SUCCESS(Status
) && Status
!= STATUS_OBJECT_NAME_COLLISION
)
2909 DPRINT("Creating directory '%S' failed: Status = 0x%08lx", PathBuffer
, Status
);
2910 MUIDisplayError(ERROR_CREATE_INSTALL_DIR
, Ir
, POPUP_WAIT_ENTER
);
2914 /* Search for the 'Directories' section */
2915 if (!SetupFindFirstLineW(InfFile
, L
"Directories", NULL
, &DirContext
))
2919 MUIDisplayError(ERROR_CABINET_SECTION
, Ir
, POPUP_WAIT_ENTER
);
2923 MUIDisplayError(ERROR_TXTSETUP_SECTION
, Ir
, POPUP_WAIT_ENTER
);
2929 /* Enumerate the directory values and create the subdirectories */
2932 if (!INF_GetData(&DirContext
, NULL
, &KeyValue
))
2938 if (KeyValue
[0] == L
'\\' && KeyValue
[1] != 0)
2940 DPRINT("Absolute Path: '%S'\n", KeyValue
);
2942 wcscpy(PathBuffer
, DestinationRootPath
.Buffer
);
2943 wcscat(PathBuffer
, KeyValue
);
2945 DPRINT("FullPath: '%S'\n", PathBuffer
);
2947 else if (KeyValue
[0] != L
'\\')
2949 DPRINT("RelativePath: '%S'\n", KeyValue
);
2950 wcscpy(PathBuffer
, DestinationPath
.Buffer
);
2951 wcscat(PathBuffer
, L
"\\");
2952 wcscat(PathBuffer
, KeyValue
);
2954 DPRINT("FullPath: '%S'\n", PathBuffer
);
2956 Status
= SetupCreateDirectory(PathBuffer
);
2957 if (!NT_SUCCESS(Status
) && Status
!= STATUS_OBJECT_NAME_COLLISION
)
2959 DPRINT("Creating directory '%S' failed: Status = 0x%08lx", PathBuffer
, Status
);
2960 MUIDisplayError(ERROR_CREATE_DIR
, Ir
, POPUP_WAIT_ENTER
);
2964 } while (SetupFindNextLine (&DirContext
, &DirContext
));
2971 PrepareCopyPage(PINPUT_RECORD Ir
)
2974 WCHAR PathBuffer
[MAX_PATH
];
2975 INFCONTEXT CabinetsContext
;
2981 MUIDisplayPage(PREPARE_COPY_PAGE
);
2983 /* Create the file queue */
2984 SetupFileQueue
= SetupOpenFileQueue();
2985 if (SetupFileQueue
== NULL
)
2987 MUIDisplayError(ERROR_COPY_QUEUE
, Ir
, POPUP_WAIT_ENTER
);
2991 if (!PrepareCopyPageInfFile(SetupInf
, NULL
, Ir
))
2996 /* Search for the 'Cabinets' section */
2997 if (!SetupFindFirstLineW(SetupInf
, L
"Cabinets", NULL
, &CabinetsContext
))
2999 return FILE_COPY_PAGE
;
3003 * Enumerate the directory values in the 'Cabinets'
3004 * section and parse their inf files.
3008 if (!INF_GetData(&CabinetsContext
, NULL
, &KeyValue
))
3011 wcscpy(PathBuffer
, SourcePath
.Buffer
);
3012 wcscat(PathBuffer
, L
"\\");
3013 wcscat(PathBuffer
, KeyValue
);
3016 CabinetInitialize();
3017 CabinetSetEventHandlers(NULL
, NULL
, NULL
);
3018 CabinetSetCabinetName(PathBuffer
);
3020 if (CabinetOpen() == CAB_STATUS_SUCCESS
)
3022 DPRINT("Cabinet %S\n", CabinetGetCabinetName());
3024 InfFileData
= CabinetGetCabinetReservedArea(&InfFileSize
);
3025 if (InfFileData
== NULL
)
3027 MUIDisplayError(ERROR_CABINET_SCRIPT
, Ir
, POPUP_WAIT_ENTER
);
3033 DPRINT("Cannot open cabinet: %S.\n", CabinetGetCabinetName());
3034 MUIDisplayError(ERROR_CABINET_MISSING
, Ir
, POPUP_WAIT_ENTER
);
3038 InfHandle
= INF_OpenBufferedFileA((CHAR
*) InfFileData
,
3045 if (InfHandle
== INVALID_HANDLE_VALUE
)
3047 MUIDisplayError(ERROR_INVALID_CABINET_INF
, Ir
, POPUP_WAIT_ENTER
);
3053 if (!PrepareCopyPageInfFile(InfHandle
, KeyValue
, Ir
))
3058 } while (SetupFindNextLine(&CabinetsContext
, &CabinetsContext
));
3060 return FILE_COPY_PAGE
;
3066 SetupUpdateMemoryInfo(IN PCOPYCONTEXT CopyContext
,
3069 SYSTEM_PERFORMANCE_INFORMATION PerfInfo
;
3071 /* Get the memory information from the system */
3072 NtQuerySystemInformation(SystemPerformanceInformation
,
3077 /* Check if this is initial setup */
3080 /* Set maximum limits to be total RAM pages */
3081 ProgressSetStepCount(CopyContext
->MemoryBars
[0], PerfInfo
.CommitLimit
);
3082 ProgressSetStepCount(CopyContext
->MemoryBars
[1], PerfInfo
.CommitLimit
);
3083 ProgressSetStepCount(CopyContext
->MemoryBars
[2], PerfInfo
.CommitLimit
);
3086 /* Set current values */
3087 ProgressSetStep(CopyContext
->MemoryBars
[0], PerfInfo
.PagedPoolPages
+ PerfInfo
.NonPagedPoolPages
);
3088 ProgressSetStep(CopyContext
->MemoryBars
[1], PerfInfo
.ResidentSystemCachePage
);
3089 ProgressSetStep(CopyContext
->MemoryBars
[2], PerfInfo
.AvailablePages
);
3095 FileCopyCallback(PVOID Context
,
3100 PCOPYCONTEXT CopyContext
;
3102 CopyContext
= (PCOPYCONTEXT
)Context
;
3104 switch (Notification
)
3106 case SPFILENOTIFY_STARTSUBQUEUE
:
3107 CopyContext
->TotalOperations
= (ULONG
)Param2
;
3108 ProgressSetStepCount(CopyContext
->ProgressBar
,
3109 CopyContext
->TotalOperations
);
3110 SetupUpdateMemoryInfo(CopyContext
, TRUE
);
3113 case SPFILENOTIFY_STARTCOPY
:
3114 /* Display copy message */
3115 CONSOLE_SetStatusText(MUIGetString(STRING_COPYING
), (PWSTR
)Param1
);
3116 SetupUpdateMemoryInfo(CopyContext
, FALSE
);
3119 case SPFILENOTIFY_ENDCOPY
:
3120 CopyContext
->CompletedOperations
++;
3122 /* SYSREG checkpoint */
3123 if (CopyContext
->TotalOperations
>> 1 == CopyContext
->CompletedOperations
)
3124 DPRINT1("CHECKPOINT:HALF_COPIED\n");
3126 ProgressNextStep(CopyContext
->ProgressBar
);
3127 SetupUpdateMemoryInfo(CopyContext
, FALSE
);
3137 FileCopyPage(PINPUT_RECORD Ir
)
3139 COPYCONTEXT CopyContext
;
3140 unsigned int mem_bar_width
;
3142 MUIDisplayPage(FILE_COPY_PAGE
);
3144 /* Create context for the copy process */
3145 CopyContext
.DestinationRootPath
= DestinationRootPath
.Buffer
;
3146 CopyContext
.InstallPath
= InstallPath
.Buffer
;
3147 CopyContext
.TotalOperations
= 0;
3148 CopyContext
.CompletedOperations
= 0;
3150 /* Create the progress bar as well */
3151 CopyContext
.ProgressBar
= CreateProgressBar(13,
3158 MUIGetString(STRING_SETUPCOPYINGFILES
));
3160 // fit memory bars to screen width, distribute them uniform
3161 mem_bar_width
= (xScreen
- 26) / 5;
3162 mem_bar_width
-= mem_bar_width
% 2; // make even
3163 /* ATTENTION: The following progress bars are debug stuff, which should not be translated!! */
3164 /* Create the paged pool progress bar */
3165 CopyContext
.MemoryBars
[0] = CreateProgressBar(13,
3174 /* Create the non paged pool progress bar */
3175 CopyContext
.MemoryBars
[1] = CreateProgressBar((xScreen
/ 2)- (mem_bar_width
/ 2),
3177 (xScreen
/ 2) + (mem_bar_width
/ 2),
3179 (xScreen
/ 2)- (mem_bar_width
/ 2),
3184 /* Create the global memory progress bar */
3185 CopyContext
.MemoryBars
[2] = CreateProgressBar(xScreen
- 13 - mem_bar_width
,
3189 xScreen
- 13 - mem_bar_width
,
3194 /* Do the file copying */
3195 SetupCommitFileQueueW(NULL
,
3200 /* If we get here, we're done, so cleanup the queue and progress bar */
3201 SetupCloseFileQueue(SetupFileQueue
);
3202 DestroyProgressBar(CopyContext
.ProgressBar
);
3203 DestroyProgressBar(CopyContext
.MemoryBars
[0]);
3204 DestroyProgressBar(CopyContext
.MemoryBars
[1]);
3205 DestroyProgressBar(CopyContext
.MemoryBars
[2]);
3207 /* Go display the next page */
3208 return REGISTRY_PAGE
;
3213 RegistryPage(PINPUT_RECORD Ir
)
3215 INFCONTEXT InfContext
;
3222 MUIDisplayPage(REGISTRY_PAGE
);
3224 if (RepairUpdateFlag
)
3226 return SUCCESS_PAGE
;
3229 if (!SetInstallPathValue(&DestinationPath
))
3231 DPRINT("SetInstallPathValue() failed\n");
3232 MUIDisplayError(ERROR_INITIALIZE_REGISTRY
, Ir
, POPUP_WAIT_ENTER
);
3236 /* Create the default hives */
3238 Status
= NtInitializeRegistry(CM_BOOT_FLAG_SETUP
);
3239 if (!NT_SUCCESS(Status
))
3241 DPRINT("NtInitializeRegistry() failed (Status %lx)\n", Status
);
3242 MUIDisplayError(ERROR_CREATE_HIVE
, Ir
, POPUP_WAIT_ENTER
);
3246 RegInitializeRegistry();
3249 /* Update registry */
3250 CONSOLE_SetStatusText(MUIGetString(STRING_REGHIVEUPDATE
));
3252 if (!SetupFindFirstLineW(SetupInf
, L
"HiveInfs.Install", NULL
, &InfContext
))
3254 DPRINT1("SetupFindFirstLine() failed\n");
3255 MUIDisplayError(ERROR_FIND_REGISTRY
, Ir
, POPUP_WAIT_ENTER
);
3261 INF_GetDataField (&InfContext
, 0, &Action
);
3262 INF_GetDataField (&InfContext
, 1, &File
);
3263 INF_GetDataField (&InfContext
, 2, &Section
);
3265 DPRINT("Action: %S File: %S Section %S\n", Action
, File
, Section
);
3270 if (!_wcsicmp (Action
, L
"AddReg"))
3274 else if (!_wcsicmp (Action
, L
"DelReg"))
3283 CONSOLE_SetStatusText(MUIGetString(STRING_IMPORTFILE
), File
);
3285 if (!ImportRegistryFile(File
, Section
, LanguageId
, Delete
))
3287 DPRINT("Importing %S failed\n", File
);
3289 MUIDisplayError(ERROR_IMPORT_HIVE
, Ir
, POPUP_WAIT_ENTER
);
3292 } while (SetupFindNextLine(&InfContext
, &InfContext
));
3294 /* Update display registry settings */
3295 CONSOLE_SetStatusText(MUIGetString(STRING_DISPLAYETTINGSUPDATE
));
3296 if (!ProcessDisplayRegistry(SetupInf
, DisplayList
))
3298 MUIDisplayError(ERROR_UPDATE_DISPLAY_SETTINGS
, Ir
, POPUP_WAIT_ENTER
);
3302 /* Set the locale */
3303 CONSOLE_SetStatusText(MUIGetString(STRING_LOCALESETTINGSUPDATE
));
3304 if (!ProcessLocaleRegistry(LanguageList
))
3306 MUIDisplayError(ERROR_UPDATE_LOCALESETTINGS
, Ir
, POPUP_WAIT_ENTER
);
3310 /* Add keyboard layouts */
3311 CONSOLE_SetStatusText(MUIGetString(STRING_ADDKBLAYOUTS
));
3312 if (!AddKeyboardLayouts())
3314 MUIDisplayError(ERROR_ADDING_KBLAYOUTS
, Ir
, POPUP_WAIT_ENTER
);
3320 if (!SetGeoID(MUIGetGeoID()))
3322 MUIDisplayError(ERROR_UPDATE_GEOID
, Ir
, POPUP_WAIT_ENTER
);
3326 if (!IsUnattendedSetup
)
3328 /* Update keyboard layout settings */
3329 CONSOLE_SetStatusText(MUIGetString(STRING_KEYBOARDSETTINGSUPDATE
));
3330 if (!ProcessKeyboardLayoutRegistry(LayoutList
))
3332 MUIDisplayError(ERROR_UPDATE_KBSETTINGS
, Ir
, POPUP_WAIT_ENTER
);
3337 /* Add codepage information to registry */
3338 CONSOLE_SetStatusText(MUIGetString(STRING_CODEPAGEINFOUPDATE
));
3341 MUIDisplayError(ERROR_ADDING_CODEPAGE
, Ir
, POPUP_WAIT_ENTER
);
3345 /* Set the default pagefile entry */
3346 SetDefaultPagefile(DestinationDriveLetter
);
3348 /* Update the mounted devices list */
3349 SetMountedDeviceValues(PartitionList
);
3351 CONSOLE_SetStatusText(MUIGetString(STRING_DONE
));
3353 return BOOT_LOADER_PAGE
;
3358 BootLoaderPage(PINPUT_RECORD Ir
)
3360 UCHAR PartitionType
;
3361 BOOLEAN InstallOnFloppy
;
3363 WCHAR PathBuffer
[MAX_PATH
];
3365 CONSOLE_SetStatusText(MUIGetString(STRING_PLEASEWAIT
));
3367 /* Find or set the active partition */
3368 CheckActiveBootPartition(PartitionList
);
3370 /* Update the partition table because we may have changed the active partition */
3371 if (WritePartitionsToDisk(PartitionList
) == FALSE
)
3373 DPRINT("WritePartitionsToDisk() failed\n");
3374 MUIDisplayError(ERROR_WRITE_PTABLE
, Ir
, POPUP_WAIT_ENTER
);
3378 RtlFreeUnicodeString(&SystemRootPath
);
3379 swprintf(PathBuffer
,
3380 L
"\\Device\\Harddisk%lu\\Partition%lu",
3381 PartitionList
->ActiveBootDisk
->DiskNumber
,
3382 PartitionList
->ActiveBootPartition
->PartitionNumber
);
3383 RtlCreateUnicodeString(&SystemRootPath
,
3385 DPRINT("SystemRootPath: %wZ\n", &SystemRootPath
);
3387 PartitionType
= PartitionList
->ActiveBootPartition
->PartitionType
;
3389 if (IsUnattendedSetup
)
3391 if (UnattendMBRInstallType
== 0) /* skip MBR installation */
3393 return SUCCESS_PAGE
;
3395 else if (UnattendMBRInstallType
== 1) /* install on floppy */
3397 return BOOT_LOADER_FLOPPY_PAGE
;
3401 if (PartitionType
== PARTITION_ENTRY_UNUSED
)
3403 DPRINT("Error: active partition invalid (unused)\n");
3404 InstallOnFloppy
= TRUE
;
3406 else if (PartitionType
== 0x0A)
3408 /* OS/2 boot manager partition */
3409 DPRINT("Found OS/2 boot manager partition\n");
3410 InstallOnFloppy
= TRUE
;
3412 else if (PartitionType
== 0x83)
3414 /* Linux ext2 partition */
3415 DPRINT("Found Linux ext2 partition\n");
3416 InstallOnFloppy
= TRUE
;
3418 else if (PartitionType
== PARTITION_IFS
)
3420 /* NTFS partition */
3421 DPRINT("Found NTFS partition\n");
3422 InstallOnFloppy
= TRUE
;
3424 else if ((PartitionType
== PARTITION_FAT_12
) ||
3425 (PartitionType
== PARTITION_FAT_16
) ||
3426 (PartitionType
== PARTITION_HUGE
) ||
3427 (PartitionType
== PARTITION_XINT13
) ||
3428 (PartitionType
== PARTITION_FAT32
) ||
3429 (PartitionType
== PARTITION_FAT32_XINT13
))
3431 DPRINT("Found FAT partition\n");
3432 InstallOnFloppy
= FALSE
;
3436 /* Unknown partition */
3437 DPRINT("Unknown partition found\n");
3438 InstallOnFloppy
= TRUE
;
3441 if (InstallOnFloppy
== TRUE
)
3443 return BOOT_LOADER_FLOPPY_PAGE
;
3446 /* Unattended install on hdd? */
3447 if (IsUnattendedSetup
&& UnattendMBRInstallType
== 2)
3449 return BOOT_LOADER_HARDDISK_MBR_PAGE
;
3452 MUIDisplayPage(BOOT_LOADER_PAGE
);
3453 CONSOLE_InvertTextXY(8, Line
, 60, 1);
3457 CONSOLE_ConInKey(Ir
);
3459 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
3460 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
)) /* DOWN */
3462 CONSOLE_NormalTextXY(8, Line
, 60, 1);
3471 CONSOLE_InvertTextXY(8, Line
, 60, 1);
3473 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
3474 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_UP
)) /* UP */
3476 CONSOLE_NormalTextXY(8, Line
, 60, 1);
3485 CONSOLE_InvertTextXY(8, Line
, 60, 1);
3487 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
3488 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
3490 if (ConfirmQuit(Ir
) == TRUE
)
3495 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
3499 return BOOT_LOADER_HARDDISK_MBR_PAGE
;
3501 else if (Line
== 13)
3503 return BOOT_LOADER_HARDDISK_VBR_PAGE
;
3505 else if (Line
== 14)
3507 return BOOT_LOADER_FLOPPY_PAGE
;
3509 else if (Line
== 15)
3511 return SUCCESS_PAGE
;
3514 return BOOT_LOADER_PAGE
;
3518 return BOOT_LOADER_PAGE
;
3523 BootLoaderFloppyPage(PINPUT_RECORD Ir
)
3527 MUIDisplayPage(BOOT_LOADER_FLOPPY_PAGE
);
3529 // SetStatusText(" Please wait...");
3533 CONSOLE_ConInKey(Ir
);
3535 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
3536 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
3538 if (ConfirmQuit(Ir
) == TRUE
)
3543 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
3545 if (DoesFileExist(L
"\\Device\\Floppy0", L
"\\") == FALSE
)
3547 MUIDisplayError(ERROR_NO_FLOPPY
, Ir
, POPUP_WAIT_ENTER
);
3548 return BOOT_LOADER_FLOPPY_PAGE
;
3551 Status
= InstallFatBootcodeToFloppy(&SourceRootPath
, &DestinationArcPath
);
3552 if (!NT_SUCCESS(Status
))
3554 /* Print error message */
3555 return BOOT_LOADER_FLOPPY_PAGE
;
3558 return SUCCESS_PAGE
;
3562 return BOOT_LOADER_FLOPPY_PAGE
;
3566 BootLoaderHarddiskVbrPage(PINPUT_RECORD Ir
)
3568 UCHAR PartitionType
;
3571 PartitionType
= PartitionList
->ActiveBootPartition
->PartitionType
;
3573 Status
= InstallVBRToPartition(&SystemRootPath
,
3575 &DestinationArcPath
,
3577 if (!NT_SUCCESS(Status
))
3579 MUIDisplayError(ERROR_WRITE_BOOT
, Ir
, POPUP_WAIT_ENTER
);
3583 return SUCCESS_PAGE
;
3587 BootLoaderHarddiskMbrPage(PINPUT_RECORD Ir
)
3589 UCHAR PartitionType
;
3591 WCHAR DestinationDevicePathBuffer
[MAX_PATH
];
3592 WCHAR SourceMbrPathBuffer
[MAX_PATH
];
3594 /* Step 1: Write the VBR */
3595 PartitionType
= PartitionList
->ActiveBootPartition
->PartitionType
;
3597 Status
= InstallVBRToPartition(&SystemRootPath
,
3599 &DestinationArcPath
,
3601 if (!NT_SUCCESS(Status
))
3603 MUIDisplayError(ERROR_WRITE_BOOT
, Ir
, POPUP_WAIT_ENTER
);
3607 /* Step 2: Write the MBR */
3608 swprintf(DestinationDevicePathBuffer
,
3609 L
"\\Device\\Harddisk%d\\Partition0",
3610 PartitionList
->ActiveBootDisk
->DiskNumber
);
3612 wcscpy(SourceMbrPathBuffer
, SourceRootPath
.Buffer
);
3613 wcscat(SourceMbrPathBuffer
, L
"\\loader\\dosmbr.bin");
3615 DPRINT("Install MBR bootcode: %S ==> %S\n",
3616 SourceMbrPathBuffer
, DestinationDevicePathBuffer
);
3618 Status
= InstallMbrBootCodeToDisk(SourceMbrPathBuffer
,
3619 DestinationDevicePathBuffer
);
3620 if (!NT_SUCCESS (Status
))
3622 DPRINT1("InstallMbrBootCodeToDisk() failed (Status %lx)\n",
3624 MUIDisplayError(ERROR_INSTALL_BOOTCODE
, Ir
, POPUP_WAIT_ENTER
);
3628 return SUCCESS_PAGE
;
3633 QuitPage(PINPUT_RECORD Ir
)
3635 MUIDisplayPage(QUIT_PAGE
);
3637 /* Destroy partition list */
3638 if (PartitionList
!= NULL
)
3640 DestroyPartitionList (PartitionList
);
3641 PartitionList
= NULL
;
3644 /* Destroy filesystem list */
3645 if (FileSystemList
!= NULL
)
3647 DestroyFileSystemList (FileSystemList
);
3648 FileSystemList
= NULL
;
3651 /* Destroy computer settings list */
3652 if (ComputerList
!= NULL
)
3654 DestroyGenericList(ComputerList
, TRUE
);
3655 ComputerList
= NULL
;
3658 /* Destroy display settings list */
3659 if (DisplayList
!= NULL
)
3661 DestroyGenericList(DisplayList
, TRUE
);
3665 /* Destroy keyboard settings list */
3666 if (KeyboardList
!= NULL
)
3668 DestroyGenericList(KeyboardList
, TRUE
);
3669 KeyboardList
= NULL
;
3672 /* Destroy keyboard layout list */
3673 if (LayoutList
!= NULL
)
3675 DestroyGenericList(LayoutList
, TRUE
);
3679 if (LanguageList
!= NULL
)
3681 DestroyGenericList(LanguageList
, FALSE
);
3682 LanguageList
= NULL
;
3685 CONSOLE_SetStatusText(MUIGetString(STRING_REBOOTCOMPUTER2
));
3689 CONSOLE_ConInKey(Ir
);
3691 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
3700 SuccessPage(PINPUT_RECORD Ir
)
3702 MUIDisplayPage(SUCCESS_PAGE
);
3704 if (IsUnattendedSetup
)
3711 CONSOLE_ConInKey(Ir
);
3713 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
3722 FlushPage(PINPUT_RECORD Ir
)
3724 MUIDisplayPage(FLUSH_PAGE
);
3730 PnpEventThread(IN LPVOID lpParameter
);
3740 NtQuerySystemTime(&Time
);
3742 Status
= RtlCreateUserThread(NtCurrentProcess(),
3752 if (!NT_SUCCESS(Status
))
3753 hPnpThread
= INVALID_HANDLE_VALUE
;
3755 if (!CONSOLE_Init())
3757 PrintString(MUIGetString(STRING_CONSOLEFAIL1
));
3758 PrintString(MUIGetString(STRING_CONSOLEFAIL2
));
3759 PrintString(MUIGetString(STRING_CONSOLEFAIL3
));
3761 /* Raise a hard error (crash the system/BSOD) */
3762 NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED
,
3766 /* Initialize global unicode strings */
3767 RtlInitUnicodeString(&SourcePath
, NULL
);
3768 RtlInitUnicodeString(&SourceRootPath
, NULL
);
3769 RtlInitUnicodeString(&SourceRootDir
, NULL
);
3770 RtlInitUnicodeString(&InstallPath
, NULL
);
3771 RtlInitUnicodeString(&DestinationPath
, NULL
);
3772 RtlInitUnicodeString(&DestinationArcPath
, NULL
);
3773 RtlInitUnicodeString(&DestinationRootPath
, NULL
);
3774 RtlInitUnicodeString(&SystemRootPath
, NULL
);
3776 /* Hide the cursor */
3777 CONSOLE_SetCursorType(TRUE
, FALSE
);
3780 while (Page
!= REBOOT_PAGE
)
3782 CONSOLE_ClearScreen();
3785 //CONSOLE_SetUnderlinedTextXY(4, 3, " ReactOS " KERNEL_VERSION_STR " Setup ");
3792 Page
= SetupStartPage(&Ir
);
3797 Page
= LanguagePage(&Ir
);
3802 Page
= LicensePage(&Ir
);
3807 Page
= IntroPage(&Ir
);
3811 case INSTALL_INTRO_PAGE
:
3812 Page
= InstallIntroPage(&Ir
);
3816 case SCSI_CONTROLLER_PAGE
:
3817 Page
= ScsiControllerPage(&Ir
);
3822 case OEM_DRIVER_PAGE
:
3823 Page
= OemDriverPage(&Ir
);
3827 case DEVICE_SETTINGS_PAGE
:
3828 Page
= DeviceSettingsPage(&Ir
);
3831 case COMPUTER_SETTINGS_PAGE
:
3832 Page
= ComputerSettingsPage(&Ir
);
3835 case DISPLAY_SETTINGS_PAGE
:
3836 Page
= DisplaySettingsPage(&Ir
);
3839 case KEYBOARD_SETTINGS_PAGE
:
3840 Page
= KeyboardSettingsPage(&Ir
);
3843 case LAYOUT_SETTINGS_PAGE
:
3844 Page
= LayoutSettingsPage(&Ir
);
3847 case SELECT_PARTITION_PAGE
:
3848 Page
= SelectPartitionPage(&Ir
);
3851 case CREATE_PARTITION_PAGE
:
3852 Page
= CreatePartitionPage(&Ir
);
3855 case DELETE_PARTITION_PAGE
:
3856 Page
= DeletePartitionPage(&Ir
);
3859 case SELECT_FILE_SYSTEM_PAGE
:
3860 Page
= SelectFileSystemPage(&Ir
);
3863 case FORMAT_PARTITION_PAGE
:
3864 Page
= (PAGE_NUMBER
) FormatPartitionPage(&Ir
);
3867 case CHECK_FILE_SYSTEM_PAGE
:
3868 Page
= (PAGE_NUMBER
) CheckFileSystemPage(&Ir
);
3871 case INSTALL_DIRECTORY_PAGE
:
3872 Page
= InstallDirectoryPage(&Ir
);
3875 case PREPARE_COPY_PAGE
:
3876 Page
= PrepareCopyPage(&Ir
);
3879 case FILE_COPY_PAGE
:
3880 Page
= FileCopyPage(&Ir
);
3884 Page
= RegistryPage(&Ir
);
3887 case BOOT_LOADER_PAGE
:
3888 Page
= BootLoaderPage(&Ir
);
3891 case BOOT_LOADER_FLOPPY_PAGE
:
3892 Page
= BootLoaderFloppyPage(&Ir
);
3895 case BOOT_LOADER_HARDDISK_MBR_PAGE
:
3896 Page
= BootLoaderHarddiskMbrPage(&Ir
);
3899 case BOOT_LOADER_HARDDISK_VBR_PAGE
:
3900 Page
= BootLoaderHarddiskVbrPage(&Ir
);
3904 case REPAIR_INTRO_PAGE
:
3905 Page
= RepairIntroPage(&Ir
);
3909 Page
= SuccessPage(&Ir
);
3913 Page
= FlushPage(&Ir
);
3917 Page
= QuitPage(&Ir
);
3927 /* Avoid bugcheck */
3928 Time
.QuadPart
+= 50000000;
3929 NtDelayExecution(FALSE
, &Time
);
3932 NtShutdownSystem(ShutdownReboot
);
3933 NtTerminateProcess(NtCurrentProcess(), 0);
3940 NtProcessStartup(PPEB Peb
)
3942 RtlNormalizeProcessParams(Peb
->ProcessParameters
);
3944 ProcessHeap
= Peb
->ProcessHeap
;
3945 InfSetHeap(ProcessHeap
);
3948 #endif /* __REACTOS__ */