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)
35 /* GLOBALS ******************************************************************/
38 UNICODE_STRING SourceRootPath
;
39 UNICODE_STRING SourceRootDir
;
40 UNICODE_STRING SourcePath
;
41 BOOLEAN IsUnattendedSetup
= FALSE
;
42 LONG UnattendDestinationDiskNumber
;
43 LONG UnattendDestinationPartitionNumber
;
44 LONG UnattendMBRInstallType
= -1;
45 LONG UnattendFormatPartition
= 0;
46 LONG AutoPartition
= 0;
47 WCHAR UnattendInstallationDirectory
[MAX_PATH
];
48 PWCHAR SelectedLanguageId
;
50 WCHAR DefaultLanguage
[20];
51 WCHAR DefaultKBLayout
[20];
52 BOOLEAN RepairUpdateFlag
= FALSE
;
53 HANDLE hPnpThread
= INVALID_HANDLE_VALUE
;
55 /* LOCALS *******************************************************************/
57 static PPARTLIST PartitionList
= NULL
;
59 static PFILE_SYSTEM_LIST FileSystemList
= NULL
;
61 static UNICODE_STRING InstallPath
;
63 /* Path to the install directory */
64 static UNICODE_STRING DestinationPath
;
65 static UNICODE_STRING DestinationArcPath
;
66 static UNICODE_STRING DestinationRootPath
;
68 /* Path to the active partition (boot manager) */
69 static UNICODE_STRING SystemRootPath
;
73 static HSPFILEQ SetupFileQueue
= NULL
;
75 static BOOLEAN WarnLinuxPartitions
= TRUE
;
77 static PGENERIC_LIST ComputerList
= NULL
;
78 static PGENERIC_LIST DisplayList
= NULL
;
79 static PGENERIC_LIST KeyboardList
= NULL
;
80 static PGENERIC_LIST LayoutList
= NULL
;
81 static PGENERIC_LIST LanguageList
= NULL
;
83 static LANGID LanguageId
= 0;
85 static ULONG RequiredPartitionDiskSpace
= ~0;
87 /* FUNCTIONS ****************************************************************/
90 PrintString(char* fmt
,...)
94 UNICODE_STRING UnicodeString
;
95 ANSI_STRING AnsiString
;
98 vsprintf(buffer
, fmt
, ap
);
101 RtlInitAnsiString(&AnsiString
, buffer
);
102 RtlAnsiStringToUnicodeString(&UnicodeString
, &AnsiString
, TRUE
);
103 NtDisplayString(&UnicodeString
);
104 RtlFreeUnicodeString(&UnicodeString
);
109 DrawBox(IN SHORT xLeft
,
117 /* draw upper left corner */
120 FillConsoleOutputCharacterA(StdOutput
,
126 /* draw upper edge */
129 FillConsoleOutputCharacterA(StdOutput
,
135 /* draw upper right corner */
136 coPos
.X
= xLeft
+ Width
- 1;
138 FillConsoleOutputCharacterA(StdOutput
,
144 /* Draw right edge, inner space and left edge */
145 for (coPos
.Y
= yTop
+ 1; coPos
.Y
< yTop
+ Height
- 1; coPos
.Y
++)
148 FillConsoleOutputCharacterA(StdOutput
,
155 FillConsoleOutputCharacterA(StdOutput
,
161 coPos
.X
= xLeft
+ Width
- 1;
162 FillConsoleOutputCharacterA(StdOutput
,
169 /* draw lower left corner */
171 coPos
.Y
= yTop
+ Height
- 1;
172 FillConsoleOutputCharacterA(StdOutput
,
178 /* draw lower edge */
180 coPos
.Y
= yTop
+ Height
- 1;
181 FillConsoleOutputCharacterA(StdOutput
,
187 /* draw lower right corner */
188 coPos
.X
= xLeft
+ Width
- 1;
189 coPos
.Y
= yTop
+ Height
- 1;
190 FillConsoleOutputCharacterA(StdOutput
,
199 PopupError(PCCH Text
,
217 /* Count text lines and longest line */
224 p
= strchr(pnext
, '\n');
228 Length
= strlen(pnext
);
233 Length
= (ULONG
)(p
- pnext
);
239 if (Length
> MaxLength
)
242 if (LastLine
== TRUE
)
248 /* Check length of status line */
251 Length
= strlen(Status
);
253 if (Length
> MaxLength
)
257 Width
= MaxLength
+ 4;
263 yTop
= (yScreen
- Height
) / 2;
264 xLeft
= (xScreen
- Width
) / 2;
267 /* Set screen attributes */
269 for (coPos
.Y
= yTop
; coPos
.Y
< yTop
+ Height
; coPos
.Y
++)
271 FillConsoleOutputAttribute(StdOutput
,
272 FOREGROUND_RED
| BACKGROUND_WHITE
,
278 DrawBox(xLeft
, yTop
, Width
, Height
);
280 /* Print message text */
285 p
= strchr(pnext
, '\n');
289 Length
= strlen(pnext
);
294 Length
= (ULONG
)(p
- pnext
);
301 WriteConsoleOutputCharacterA(StdOutput
,
308 if (LastLine
== TRUE
)
315 /* Print separator line and status text */
318 coPos
.Y
= yTop
+ Height
- 3;
320 FillConsoleOutputCharacterA(StdOutput
,
327 FillConsoleOutputCharacterA(StdOutput
,
333 coPos
.X
= xLeft
+ Width
- 1;
334 FillConsoleOutputCharacterA(StdOutput
,
342 WriteConsoleOutputCharacterA(StdOutput
,
344 min(strlen(Status
), (SIZE_T
)Width
- 4),
349 if (WaitEvent
== POPUP_WAIT_NONE
)
354 CONSOLE_ConInKey(Ir
);
356 if (WaitEvent
== POPUP_WAIT_ANY_KEY
||
357 Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D)
369 * FALSE: Don't quit setup.
372 ConfirmQuit(PINPUT_RECORD Ir
)
375 MUIDisplayError(ERROR_NOT_INSTALLED
, NULL
, POPUP_WAIT_NONE
);
379 CONSOLE_ConInKey(Ir
);
381 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
382 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
387 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
399 CheckUnattendedSetup(VOID
)
401 WCHAR UnattendInfPath
[MAX_PATH
];
408 if (DoesFileExist(SourcePath
.Buffer
, L
"unattend.inf") == FALSE
)
410 DPRINT("Does not exist: %S\\%S\n", SourcePath
.Buffer
, L
"unattend.inf");
414 wcscpy(UnattendInfPath
, SourcePath
.Buffer
);
415 wcscat(UnattendInfPath
, L
"\\unattend.inf");
417 /* Load 'unattend.inf' from install media. */
418 UnattendInf
= SetupOpenInfFileW(UnattendInfPath
,
424 if (UnattendInf
== INVALID_HANDLE_VALUE
)
426 DPRINT("SetupOpenInfFileW() failed\n");
430 /* Open 'Unattend' section */
431 if (!SetupFindFirstLineW(UnattendInf
, L
"Unattend", L
"Signature", &Context
))
433 DPRINT("SetupFindFirstLineW() failed for section 'Unattend'\n");
434 SetupCloseInfFile(UnattendInf
);
438 /* Get pointer 'Signature' key */
439 if (!INF_GetData(&Context
, NULL
, &Value
))
441 DPRINT("INF_GetData() failed for key 'Signature'\n");
442 SetupCloseInfFile(UnattendInf
);
446 /* Check 'Signature' string */
447 if (_wcsicmp(Value
, L
"$ReactOS$") != 0)
449 DPRINT("Signature not $ReactOS$\n");
450 SetupCloseInfFile(UnattendInf
);
454 /* Check if Unattend setup is enabled */
455 if (!SetupFindFirstLineW(UnattendInf
, L
"Unattend", L
"UnattendSetupEnabled", &Context
))
457 DPRINT("Can't find key 'UnattendSetupEnabled'\n");
458 SetupCloseInfFile(UnattendInf
);
462 if (!INF_GetData(&Context
, NULL
, &Value
))
464 DPRINT("Can't read key 'UnattendSetupEnabled'\n");
465 SetupCloseInfFile(UnattendInf
);
469 if (_wcsicmp(Value
, L
"yes") != 0)
471 DPRINT("Unattend setup is disabled by 'UnattendSetupEnabled' key!\n");
472 SetupCloseInfFile(UnattendInf
);
476 /* Search for 'DestinationDiskNumber' in the 'Unattend' section */
477 if (!SetupFindFirstLineW(UnattendInf
, L
"Unattend", L
"DestinationDiskNumber", &Context
))
479 DPRINT("SetupFindFirstLine() failed for key 'DestinationDiskNumber'\n");
480 SetupCloseInfFile(UnattendInf
);
484 if (!SetupGetIntField(&Context
, 1, &IntValue
))
486 DPRINT("SetupGetIntField() failed for key 'DestinationDiskNumber'\n");
487 SetupCloseInfFile(UnattendInf
);
491 UnattendDestinationDiskNumber
= (LONG
)IntValue
;
493 /* Search for 'DestinationPartitionNumber' in the 'Unattend' section */
494 if (!SetupFindFirstLineW(UnattendInf
, L
"Unattend", L
"DestinationPartitionNumber", &Context
))
496 DPRINT("SetupFindFirstLine() failed for key 'DestinationPartitionNumber'\n");
497 SetupCloseInfFile(UnattendInf
);
501 if (!SetupGetIntField(&Context
, 1, &IntValue
))
503 DPRINT("SetupGetIntField() failed for key 'DestinationPartitionNumber'\n");
504 SetupCloseInfFile(UnattendInf
);
508 UnattendDestinationPartitionNumber
= IntValue
;
510 /* Search for 'DestinationPartitionNumber' in the 'Unattend' section */
511 if (!SetupFindFirstLineW(UnattendInf
, L
"Unattend", L
"DestinationPartitionNumber", &Context
))
513 DPRINT("SetupFindFirstLine() failed for key 'DestinationPartitionNumber'\n");
514 SetupCloseInfFile(UnattendInf
);
518 /* Get pointer 'InstallationDirectory' key */
519 if (!INF_GetData(&Context
, NULL
, &Value
))
521 DPRINT("INF_GetData() failed for key 'InstallationDirectory'\n");
522 SetupCloseInfFile(UnattendInf
);
526 wcscpy(UnattendInstallationDirectory
, Value
);
528 IsUnattendedSetup
= TRUE
;
530 /* Search for 'MBRInstallType' in the 'Unattend' section */
531 if (SetupFindFirstLineW(UnattendInf
, L
"Unattend", L
"MBRInstallType", &Context
))
533 if (SetupGetIntField(&Context
, 1, &IntValue
))
535 UnattendMBRInstallType
= IntValue
;
539 /* Search for 'FormatPartition' in the 'Unattend' section */
540 if (SetupFindFirstLineW(UnattendInf
, L
"Unattend", L
"FormatPartition", &Context
))
542 if (SetupGetIntField(&Context
, 1, &IntValue
))
544 UnattendFormatPartition
= IntValue
;
548 if (SetupFindFirstLineW(UnattendInf
, L
"Unattend", L
"AutoPartition", &Context
))
550 if (SetupGetIntField(&Context
, 1, &IntValue
))
552 AutoPartition
= IntValue
;
556 /* search for LocaleID in the 'Unattend' section*/
557 if (SetupFindFirstLineW (UnattendInf
, L
"Unattend", L
"LocaleID", &Context
))
559 if (INF_GetData (&Context
, NULL
, &Value
))
561 LONG Id
= wcstol(Value
, NULL
, 16);
562 swprintf(LocaleID
,L
"%08lx", Id
);
566 SetupCloseInfFile(UnattendInf
);
568 DPRINT("Running unattended setup\n");
575 PGENERIC_LIST_ENTRY ListEntry
;
576 LPCWSTR pszNewLayout
;
578 pszNewLayout
= MUIDefaultKeyboardLayout();
580 if (LayoutList
== NULL
)
582 LayoutList
= CreateKeyboardLayoutList(SetupInf
, DefaultKBLayout
);
583 if (LayoutList
== NULL
)
585 /* FIXME: Handle error! */
590 ListEntry
= GetFirstListEntry(LayoutList
);
592 /* Search for default layout (if provided) */
593 if (pszNewLayout
!= NULL
)
595 while (ListEntry
!= NULL
)
597 if (!wcscmp(pszNewLayout
, GetListEntryUserData(ListEntry
)))
599 SetCurrentListEntry(LayoutList
, ListEntry
);
603 ListEntry
= GetNextListEntry(ListEntry
);
610 LanguagePage(PINPUT_RECORD Ir
)
612 /* Initialize the computer settings list */
613 if (LanguageList
== NULL
)
615 LanguageList
= CreateLanguageList(SetupInf
, DefaultLanguage
);
617 if (LanguageList
== NULL
)
619 PopupError("Setup failed to initialize available translations", NULL
, NULL
, POPUP_WAIT_NONE
);
624 DrawGenericList(LanguageList
,
630 ScrollToPositionGenericList (LanguageList
, GetDefaultLanguageIndex());
632 MUIDisplayPage(LANGUAGE_PAGE
);
636 CONSOLE_ConInKey(Ir
);
638 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
639 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
)) /* DOWN */
642 SelectedLanguageId
= (PWCHAR
)GetListEntryUserData(GetCurrentListEntry(LanguageList
));
644 /* Redraw language selection page in native language */
645 MUIDisplayPage(LANGUAGE_PAGE
);
648 ScrollDownGenericList (LanguageList
);
650 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
651 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_UP
)) /* UP */
654 SelectedLanguageId
= (PWCHAR
)GetListEntryUserData(GetCurrentListEntry(LanguageList
));
656 /* Redraw language selection page in native language */
657 MUIDisplayPage(LANGUAGE_PAGE
);
660 ScrollUpGenericList(LanguageList
);
662 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
663 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_NEXT
)) /* PAGE DOWN */
665 ScrollPageDownGenericList(LanguageList
);
667 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
668 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_PRIOR
)) /* PAGE UP */
670 ScrollPageUpGenericList(LanguageList
);
672 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
673 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
675 if (ConfirmQuit(Ir
) == TRUE
)
678 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
680 SelectedLanguageId
= (PWCHAR
)GetListEntryUserData(GetCurrentListEntry(LanguageList
));
682 LanguageId
= (LANGID
)(wcstol(SelectedLanguageId
, NULL
, 16) & 0xFFFF);
684 if (wcscmp(SelectedLanguageId
, DefaultLanguage
))
690 SetConsoleCodePage();
694 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
> 0x60) && (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
< 0x7b))
697 GenericListKeyPress (LanguageList
, Ir
->Event
.KeyEvent
.uChar
.AsciiChar
);
708 * Number of the next page.
711 SetupStartPage(PINPUT_RECORD Ir
)
713 SYSTEM_DEVICE_INFORMATION Sdi
;
715 WCHAR FileNameBuffer
[MAX_PATH
];
720 PGENERIC_LIST_ENTRY ListEntry
;
723 CONSOLE_SetStatusText(MUIGetString(STRING_PLEASEWAIT
));
726 /* Check whether a harddisk is available */
727 Status
= NtQuerySystemInformation(SystemDeviceInformation
,
729 sizeof(SYSTEM_DEVICE_INFORMATION
),
732 if (!NT_SUCCESS(Status
))
734 CONSOLE_PrintTextXY(6, 15, "NtQuerySystemInformation() failed (Status 0x%08lx)", Status
);
735 MUIDisplayError(ERROR_DRIVE_INFORMATION
, Ir
, POPUP_WAIT_ENTER
);
739 if (Sdi
.NumberOfDisks
== 0)
741 MUIDisplayError(ERROR_NO_HDD
, Ir
, POPUP_WAIT_ENTER
);
745 /* Get the source path and source root path */
746 Status
= GetSourcePaths(&SourcePath
,
750 if (!NT_SUCCESS(Status
))
752 CONSOLE_PrintTextXY(6, 15, "GetSourcePaths() failed (Status 0x%08lx)", Status
);
753 MUIDisplayError(ERROR_NO_SOURCE_DRIVE
, Ir
, POPUP_WAIT_ENTER
);
759 CONSOLE_PrintTextXY(6, 15, "SourcePath: '%wZ'", &SourcePath
);
760 CONSOLE_PrintTextXY(6, 16, "SourceRootPath: '%wZ'", &SourceRootPath
);
761 CONSOLE_PrintTextXY(6, 17, "SourceRootDir: '%wZ'", &SourceRootDir
);
765 /* Load txtsetup.sif from install media. */
766 wcscpy(FileNameBuffer
, SourcePath
.Buffer
);
767 wcscat(FileNameBuffer
, L
"\\txtsetup.sif");
769 SetupInf
= SetupOpenInfFileW(FileNameBuffer
,
775 if (SetupInf
== INVALID_HANDLE_VALUE
)
777 MUIDisplayError(ERROR_LOAD_TXTSETUPSIF
, Ir
, POPUP_WAIT_ENTER
);
781 /* Open 'Version' section */
782 if (!SetupFindFirstLineW(SetupInf
, L
"Version", L
"Signature", &Context
))
784 MUIDisplayError(ERROR_CORRUPT_TXTSETUPSIF
, Ir
, POPUP_WAIT_ENTER
);
788 /* Get pointer 'Signature' key */
789 if (!INF_GetData(&Context
, NULL
, &Value
))
791 MUIDisplayError(ERROR_CORRUPT_TXTSETUPSIF
, Ir
, POPUP_WAIT_ENTER
);
795 /* Check 'Signature' string */
796 if (_wcsicmp(Value
, L
"$ReactOS$") != 0)
798 MUIDisplayError(ERROR_SIGNATURE_TXTSETUPSIF
, Ir
, POPUP_WAIT_ENTER
);
802 /* Open 'DiskSpaceRequirements' section */
803 if (!SetupFindFirstLineW(SetupInf
, L
"DiskSpaceRequirements", L
"FreeSysPartDiskSpace", &Context
))
805 MUIDisplayError(ERROR_CORRUPT_TXTSETUPSIF
, Ir
, POPUP_WAIT_ENTER
);
809 /* Get the 'FreeSysPartDiskSpace' value */
810 if (!SetupGetIntField(&Context
, 1, &IntValue
))
812 MUIDisplayError(ERROR_CORRUPT_TXTSETUPSIF
, Ir
, POPUP_WAIT_ENTER
);
816 RequiredPartitionDiskSpace
= (ULONG
)IntValue
;
818 /* Start PnP thread */
819 if (hPnpThread
!= INVALID_HANDLE_VALUE
)
821 NtResumeThread(hPnpThread
, NULL
);
822 hPnpThread
= INVALID_HANDLE_VALUE
;
825 CheckUnattendedSetup();
827 if (IsUnattendedSetup
)
830 //read options from inf
831 ComputerList
= CreateComputerTypeList(SetupInf
);
832 DisplayList
= CreateDisplayDriverList(SetupInf
);
833 KeyboardList
= CreateKeyboardDriverList(SetupInf
);
834 LayoutList
= CreateKeyboardLayoutList(SetupInf
, DefaultKBLayout
);
835 LanguageList
= CreateLanguageList(SetupInf
, DefaultLanguage
);
838 wcscpy(SelectedLanguageId
,LocaleID
);
840 /* first we hack LanguageList */
841 ListEntry
= GetFirstListEntry(LanguageList
);
843 while (ListEntry
!= NULL
)
845 if (!wcsicmp(LocaleID
, GetListEntryUserData(ListEntry
)))
847 DPRINT("found %S in LanguageList\n",GetListEntryUserData(ListEntry
));
848 SetCurrentListEntry(LanguageList
, ListEntry
);
852 ListEntry
= GetNextListEntry(ListEntry
);
856 ListEntry
= GetFirstListEntry(LayoutList
);
858 while (ListEntry
!= NULL
)
860 if (!wcsicmp(LocaleID
, GetListEntryUserData(ListEntry
)))
862 DPRINT("found %S in LayoutList\n",GetListEntryUserData(ListEntry
));
863 SetCurrentListEntry(LayoutList
, ListEntry
);
867 ListEntry
= GetNextListEntry(ListEntry
);
870 SetConsoleCodePage();
872 return INSTALL_INTRO_PAGE
;
875 return LANGUAGE_PAGE
;
885 IntroPage(PINPUT_RECORD Ir
)
887 MUIDisplayPage(START_PAGE
);
891 CONSOLE_ConInKey(Ir
);
893 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
894 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
896 if (ConfirmQuit(Ir
) == TRUE
)
901 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
903 return INSTALL_INTRO_PAGE
;
906 else if (toupper(Ir
->Event
.KeyEvent
.uChar
.AsciiChar
) == 'R') /* R */
908 return REPAIR_INTRO_PAGE
;
911 else if (toupper(Ir
->Event
.KeyEvent
.uChar
.AsciiChar
) == 'L') /* R */
925 * Back to main setup page.
928 LicensePage(PINPUT_RECORD Ir
)
930 MUIDisplayPage(LICENSE_PAGE
);
934 CONSOLE_ConInKey(Ir
);
936 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
948 RepairIntroPage(PINPUT_RECORD Ir
)
950 MUIDisplayPage(REPAIR_INTRO_PAGE
);
954 CONSOLE_ConInKey(Ir
);
956 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
960 else if (toupper(Ir
->Event
.KeyEvent
.uChar
.AsciiChar
) == 'U') /* U */
962 RepairUpdateFlag
= TRUE
;
963 return INSTALL_INTRO_PAGE
;
965 else if (toupper(Ir
->Event
.KeyEvent
.uChar
.AsciiChar
) == 'R') /* R */
969 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
970 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
)) /* ESC */
976 return REPAIR_INTRO_PAGE
;
981 InstallIntroPage(PINPUT_RECORD Ir
)
983 MUIDisplayPage(INSTALL_INTRO_PAGE
);
985 if (RepairUpdateFlag
)
987 //return SELECT_PARTITION_PAGE;
988 return DEVICE_SETTINGS_PAGE
;
991 if (IsUnattendedSetup
)
993 return SELECT_PARTITION_PAGE
;
998 CONSOLE_ConInKey(Ir
);
1000 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1001 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1003 if (ConfirmQuit(Ir
) == TRUE
)
1008 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
1010 return DEVICE_SETTINGS_PAGE
;
1011 // return SCSI_CONTROLLER_PAGE;
1015 return INSTALL_INTRO_PAGE
;
1021 ScsiControllerPage(PINPUT_RECORD Ir
)
1023 SetTextXY(6, 8, "Setup detected the following mass storage devices:");
1025 /* FIXME: print loaded mass storage driver descriptions */
1027 SetTextXY(8, 10, "TEST device");
1031 SetStatusText(" ENTER = Continue F3 = Quit");
1037 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1038 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1040 if (ConfirmQuit(Ir
) == TRUE
)
1045 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
1047 return DEVICE_SETTINGS_PAGE
;
1051 return SCSI_CONTROLLER_PAGE
;
1057 DeviceSettingsPage(PINPUT_RECORD Ir
)
1059 static ULONG Line
= 16;
1060 MUIDisplayPage(DEVICE_SETTINGS_PAGE
);
1062 /* Initialize the computer settings list */
1063 if (ComputerList
== NULL
)
1065 ComputerList
= CreateComputerTypeList(SetupInf
);
1066 if (ComputerList
== NULL
)
1068 MUIDisplayError(ERROR_LOAD_COMPUTER
, Ir
, POPUP_WAIT_ENTER
);
1073 /* Initialize the display settings list */
1074 if (DisplayList
== NULL
)
1076 DisplayList
= CreateDisplayDriverList(SetupInf
);
1077 if (DisplayList
== NULL
)
1079 MUIDisplayError(ERROR_LOAD_DISPLAY
, Ir
, POPUP_WAIT_ENTER
);
1084 /* Initialize the keyboard settings list */
1085 if (KeyboardList
== NULL
)
1087 KeyboardList
= CreateKeyboardDriverList(SetupInf
);
1088 if (KeyboardList
== NULL
)
1090 MUIDisplayError(ERROR_LOAD_KEYBOARD
, Ir
, POPUP_WAIT_ENTER
);
1095 /* Initialize the keyboard layout list */
1096 if (LayoutList
== NULL
)
1098 LayoutList
= CreateKeyboardLayoutList(SetupInf
, DefaultKBLayout
);
1099 if (LayoutList
== NULL
)
1101 /* FIXME: report error */
1102 MUIDisplayError(ERROR_LOAD_KBLAYOUT
, Ir
, POPUP_WAIT_ENTER
);
1107 MUIDisplayPage(DEVICE_SETTINGS_PAGE
);
1110 CONSOLE_SetTextXY(25, 11, GetListEntryText(GetCurrentListEntry((ComputerList
))));
1111 CONSOLE_SetTextXY(25, 12, GetListEntryText(GetCurrentListEntry((DisplayList
))));
1112 CONSOLE_SetTextXY(25, 13, GetListEntryText(GetCurrentListEntry((KeyboardList
))));
1113 CONSOLE_SetTextXY(25, 14, GetListEntryText(GetCurrentListEntry((LayoutList
))));
1115 CONSOLE_InvertTextXY(24, Line
, 48, 1);
1117 if (RepairUpdateFlag
)
1119 return SELECT_PARTITION_PAGE
;
1124 CONSOLE_ConInKey(Ir
);
1126 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1127 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
)) /* DOWN */
1129 CONSOLE_NormalTextXY(24, Line
, 48, 1);
1133 else if (Line
== 16)
1138 CONSOLE_InvertTextXY(24, Line
, 48, 1);
1140 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1141 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_UP
)) /* UP */
1143 CONSOLE_NormalTextXY(24, Line
, 48, 1);
1147 else if (Line
== 16)
1152 CONSOLE_InvertTextXY(24, Line
, 48, 1);
1154 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1155 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1157 if (ConfirmQuit(Ir
) == TRUE
)
1162 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
1165 return COMPUTER_SETTINGS_PAGE
;
1166 else if (Line
== 12)
1167 return DISPLAY_SETTINGS_PAGE
;
1168 else if (Line
== 13)
1169 return KEYBOARD_SETTINGS_PAGE
;
1170 else if (Line
== 14)
1171 return LAYOUT_SETTINGS_PAGE
;
1172 else if (Line
== 16)
1173 return SELECT_PARTITION_PAGE
;
1177 return DEVICE_SETTINGS_PAGE
;
1182 ComputerSettingsPage(PINPUT_RECORD Ir
)
1184 MUIDisplayPage(COMPUTER_SETTINGS_PAGE
);
1186 DrawGenericList(ComputerList
,
1192 SaveGenericListState(ComputerList
);
1196 CONSOLE_ConInKey(Ir
);
1198 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1199 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
)) /* DOWN */
1201 ScrollDownGenericList(ComputerList
);
1203 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1204 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_UP
)) /* UP */
1206 ScrollUpGenericList(ComputerList
);
1208 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1209 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1211 if (ConfirmQuit(Ir
) == TRUE
)
1216 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1217 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
)) /* ESC */
1219 RestoreGenericListState(ComputerList
);
1220 return DEVICE_SETTINGS_PAGE
;
1222 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
1224 return DEVICE_SETTINGS_PAGE
;
1228 return COMPUTER_SETTINGS_PAGE
;
1233 DisplaySettingsPage(PINPUT_RECORD Ir
)
1235 MUIDisplayPage(DISPLAY_SETTINGS_PAGE
);
1237 DrawGenericList(DisplayList
,
1243 SaveGenericListState(DisplayList
);
1247 CONSOLE_ConInKey(Ir
);
1249 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1250 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
)) /* DOWN */
1252 ScrollDownGenericList(DisplayList
);
1254 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1255 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_UP
)) /* UP */
1257 ScrollUpGenericList(DisplayList
);
1259 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1260 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1262 if (ConfirmQuit(Ir
) == TRUE
)
1269 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1270 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
)) /* ESC */
1272 RestoreGenericListState(DisplayList
);
1273 return DEVICE_SETTINGS_PAGE
;
1275 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
1277 return DEVICE_SETTINGS_PAGE
;
1281 return DISPLAY_SETTINGS_PAGE
;
1286 KeyboardSettingsPage(PINPUT_RECORD Ir
)
1288 MUIDisplayPage(KEYBOARD_SETTINGS_PAGE
);
1290 DrawGenericList(KeyboardList
,
1296 SaveGenericListState(KeyboardList
);
1300 CONSOLE_ConInKey(Ir
);
1302 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1303 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
)) /* DOWN */
1305 ScrollDownGenericList(KeyboardList
);
1307 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1308 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_UP
)) /* UP */
1310 ScrollUpGenericList(KeyboardList
);
1312 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1313 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1315 if (ConfirmQuit(Ir
) == TRUE
)
1320 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1321 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
)) /* ESC */
1323 RestoreGenericListState(KeyboardList
);
1324 return DEVICE_SETTINGS_PAGE
;
1326 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
1328 return DEVICE_SETTINGS_PAGE
;
1332 return DISPLAY_SETTINGS_PAGE
;
1337 LayoutSettingsPage(PINPUT_RECORD Ir
)
1339 MUIDisplayPage(LAYOUT_SETTINGS_PAGE
);
1341 DrawGenericList(LayoutList
,
1347 SaveGenericListState(LayoutList
);
1351 CONSOLE_ConInKey(Ir
);
1353 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1354 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
)) /* DOWN */
1356 ScrollDownGenericList(LayoutList
);
1358 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1359 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_UP
)) /* UP */
1361 ScrollUpGenericList(LayoutList
);
1363 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1364 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_NEXT
)) /* PAGE DOWN */
1366 ScrollPageDownGenericList(LayoutList
);
1368 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1369 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_PRIOR
)) /* PAGE UP */
1371 ScrollPageUpGenericList(LayoutList
);
1373 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1374 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1376 if (ConfirmQuit(Ir
) == TRUE
)
1381 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1382 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
)) /* ESC */
1384 RestoreGenericListState(LayoutList
);
1385 return DEVICE_SETTINGS_PAGE
;
1387 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
1389 return DEVICE_SETTINGS_PAGE
;
1391 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
> 0x60) && (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
< 0x7b))
1394 GenericListKeyPress(LayoutList
, Ir
->Event
.KeyEvent
.uChar
.AsciiChar
);
1398 return DISPLAY_SETTINGS_PAGE
;
1403 IsDiskSizeValid(PPARTENTRY PartEntry
)
1407 /* check for unpartitioned space */
1408 m
= PartEntry
->UnpartitionedLength
;
1409 m
= (m
+ (1 << 19)) >> 20; /* in MBytes (rounded) */
1410 if( m
> RequiredPartitionDiskSpace
)
1415 /* check for partitioned space */
1416 m
= PartEntry
->PartInfo
[0].PartitionLength
.QuadPart
;
1417 m
= (m
+ (1 << 19)) >> 20; /* in MBytes (rounded) */
1418 if (m
< RequiredPartitionDiskSpace
)
1420 /* partition is too small so ask for another partion */
1421 DPRINT1("Partition is too small, required disk space is %lu MB\n", RequiredPartitionDiskSpace
);
1432 SelectPartitionPage(PINPUT_RECORD Ir
)
1434 MUIDisplayPage(SELECT_PARTITION_PAGE
);
1436 if (PartitionList
== NULL
)
1438 PartitionList
= CreatePartitionList(2,
1442 if (PartitionList
== NULL
)
1444 /* FIXME: show an error dialog */
1449 CheckActiveBootPartition(PartitionList
);
1451 DrawPartitionList(PartitionList
);
1453 /* Warn about partitions created by Linux Fdisk */
1454 if (WarnLinuxPartitions
== TRUE
&&
1455 CheckForLinuxFdiskPartitions(PartitionList
) == TRUE
)
1457 MUIDisplayError(ERROR_WARN_PARTITION
, NULL
, POPUP_WAIT_NONE
);
1461 CONSOLE_ConInKey(Ir
);
1463 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1464 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1468 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_RETURN
) /* ENTER */
1470 WarnLinuxPartitions
= FALSE
;
1471 return SELECT_PARTITION_PAGE
;
1476 if (IsUnattendedSetup
)
1478 if (!SelectPartition(PartitionList
, UnattendDestinationDiskNumber
, UnattendDestinationPartitionNumber
))
1482 PPARTENTRY PartEntry
= PartitionList
->CurrentPartition
;
1483 ULONG MaxSize
= (PartEntry
->UnpartitionedLength
+ (1 << 19)) >> 20; /* in MBytes (rounded) */
1484 if(!IsDiskSizeValid(PartitionList
->CurrentPartition
))
1486 MUIDisplayError(ERROR_INSUFFICIENT_DISKSPACE
, Ir
, POPUP_WAIT_ANY_KEY
);
1487 return SELECT_PARTITION_PAGE
; /* let the user select another partition */
1490 CreateNewPartition(PartitionList
,
1494 return SELECT_FILE_SYSTEM_PAGE
;
1499 if(!IsDiskSizeValid(PartitionList
->CurrentPartition
))
1501 MUIDisplayError(ERROR_INSUFFICIENT_DISKSPACE
, Ir
, POPUP_WAIT_ANY_KEY
);
1502 return SELECT_PARTITION_PAGE
; /* let the user select another partition */
1505 return SELECT_FILE_SYSTEM_PAGE
;
1511 /* Update status text */
1512 if (PartitionList
->CurrentPartition
== NULL
||
1513 PartitionList
->CurrentPartition
->Unpartitioned
== TRUE
)
1515 CONSOLE_SetStatusText(MUIGetString(STRING_INSTALLCREATEPARTITION
));
1519 CONSOLE_SetStatusText(MUIGetString(STRING_INSTALLDELETEPARTITION
));
1522 CONSOLE_ConInKey(Ir
);
1524 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1525 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1527 if (ConfirmQuit(Ir
) == TRUE
)
1529 DestroyPartitionList(PartitionList
);
1530 PartitionList
= NULL
;
1536 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1537 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
)) /* DOWN */
1539 ScrollDownPartitionList(PartitionList
);
1541 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1542 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_UP
)) /* UP */
1544 ScrollUpPartitionList(PartitionList
);
1546 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_RETURN
) /* ENTER */
1548 if(!IsDiskSizeValid(PartitionList
->CurrentPartition
))
1550 MUIDisplayError(ERROR_INSUFFICIENT_DISKSPACE
, Ir
, POPUP_WAIT_ANY_KEY
);
1551 return SELECT_PARTITION_PAGE
; /* let the user select another partition */
1553 if (PartitionList
->CurrentPartition
== NULL
||
1554 PartitionList
->CurrentPartition
->Unpartitioned
== TRUE
)
1556 CreateNewPartition(PartitionList
,
1561 return SELECT_FILE_SYSTEM_PAGE
;
1563 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== 'C') /* C */
1565 if (PartitionList
->CurrentPartition
->Unpartitioned
== FALSE
)
1567 MUIDisplayError(ERROR_NEW_PARTITION
, Ir
, POPUP_WAIT_ANY_KEY
);
1568 return SELECT_PARTITION_PAGE
;
1571 return CREATE_PARTITION_PAGE
;
1573 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== 'D') /* D */
1575 if (PartitionList
->CurrentPartition
->Unpartitioned
== TRUE
)
1577 MUIDisplayError(ERROR_DELETE_SPACE
, Ir
, POPUP_WAIT_ANY_KEY
);
1578 return SELECT_PARTITION_PAGE
;
1581 return DELETE_PARTITION_PAGE
;
1585 return SELECT_PARTITION_PAGE
;
1590 DrawInputField(ULONG FieldLength
,
1601 memset(buf
, '_', sizeof(buf
));
1602 buf
[FieldLength
- strlen(FieldContent
)] = 0;
1603 strcat(buf
, FieldContent
);
1605 WriteConsoleOutputCharacterA(StdOutput
,
1613 #define PARTITION_SIZE_INPUT_FIELD_LENGTH 6
1614 /* Restriction for MaxSize: pow(10, PARTITION_SIZE_INPUT_FIELD_LENGTH)-1 */
1615 #define PARTITION_MAXSIZE 999999
1618 ShowPartitionSizeInputBox(SHORT Left
,
1642 DrawBox(Left
, Top
, Right
- Left
+ 1, Bottom
- Top
+ 1);
1647 strcpy(Buffer
, MUIGetString(STRING_PARTITIONSIZE
));
1648 iLeft
= coPos
.X
+ strlen(Buffer
) + 1;
1651 WriteConsoleOutputCharacterA(StdOutput
,
1657 sprintf(Buffer
, MUIGetString(STRING_MAXSIZE
), MaxSize
);
1658 coPos
.X
= iLeft
+ PARTITION_SIZE_INPUT_FIELD_LENGTH
+ 1;
1660 WriteConsoleOutputCharacterA(StdOutput
,
1666 sprintf(Buffer
, "%lu", MaxSize
);
1667 Index
= strlen(Buffer
);
1668 DrawInputField(PARTITION_SIZE_INPUT_FIELD_LENGTH
,
1675 CONSOLE_ConInKey(&Ir
);
1677 if ((Ir
.Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1678 (Ir
.Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1686 else if (Ir
.Event
.KeyEvent
.wVirtualKeyCode
== VK_RETURN
) /* ENTER */
1690 else if (Ir
.Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
) /* ESCAPE */
1698 else if ((Ir
.Event
.KeyEvent
.wVirtualKeyCode
== VK_BACK
) && /* BACKSPACE */
1704 DrawInputField(PARTITION_SIZE_INPUT_FIELD_LENGTH
,
1709 else if ((Ir
.Event
.KeyEvent
.uChar
.AsciiChar
!= 0x00) &&
1710 (Index
< PARTITION_SIZE_INPUT_FIELD_LENGTH
))
1712 ch
= Ir
.Event
.KeyEvent
.uChar
.AsciiChar
;
1714 if ((ch
>= '0') && (ch
<= '9'))
1720 DrawInputField(PARTITION_SIZE_INPUT_FIELD_LENGTH
,
1728 strcpy(InputBuffer
, Buffer
);
1733 CreatePartitionPage(PINPUT_RECORD Ir
)
1735 PDISKENTRY DiskEntry
;
1736 PPARTENTRY PartEntry
;
1739 CHAR InputBuffer
[50];
1745 if (PartitionList
== NULL
||
1746 PartitionList
->CurrentDisk
== NULL
||
1747 PartitionList
->CurrentPartition
== NULL
)
1749 /* FIXME: show an error dialog */
1753 DiskEntry
= PartitionList
->CurrentDisk
;
1754 PartEntry
= PartitionList
->CurrentPartition
;
1756 CONSOLE_SetStatusText(MUIGetString(STRING_PLEASEWAIT
));
1758 CONSOLE_SetTextXY(6, 8, MUIGetString(STRING_CHOOSENEWPARTITION
));
1761 if (DiskEntry
->DiskSize
>= 0x280000000ULL
) /* 10 GB */
1763 DiskSize
= (DiskEntry
->DiskSize
+ (1 << 29)) >> 30;
1764 Unit
= MUIGetString(STRING_GB
);
1769 DiskSize
= (DiskEntry
->DiskSize
+ (1 << 19)) >> 20;
1774 Unit
= MUIGetString(STRING_MB
);
1777 if (DiskEntry
->DriverName
.Length
> 0)
1779 CONSOLE_PrintTextXY(6, 10,
1780 MUIGetString(STRING_HDINFOPARTCREATE
),
1783 DiskEntry
->DiskNumber
,
1787 &DiskEntry
->DriverName
);
1791 CONSOLE_PrintTextXY(6, 10,
1792 MUIGetString(STRING_HDDINFOUNK1
),
1795 DiskEntry
->DiskNumber
,
1801 CONSOLE_SetTextXY(6, 12, MUIGetString(STRING_HDDSIZE
));
1804 CONSOLE_PrintTextXY(8, 10, "Maximum size of the new partition is %I64u MB",
1805 PartitionList
->CurrentPartition
->UnpartitionedLength
/ (1024*1024));
1808 CONSOLE_SetStatusText(MUIGetString(STRING_CREATEPARTITION
));
1810 PartEntry
= PartitionList
->CurrentPartition
;
1813 MaxSize
= (PartEntry
->UnpartitionedLength
+ (1 << 19)) >> 20; /* in MBytes (rounded) */
1815 if (MaxSize
> PARTITION_MAXSIZE
) MaxSize
= PARTITION_MAXSIZE
;
1817 ShowPartitionSizeInputBox(12, 14, xScreen
- 12, 17, /* left, top, right, bottom */
1818 MaxSize
, InputBuffer
, &Quit
, &Cancel
);
1822 if (ConfirmQuit (Ir
) == TRUE
)
1827 else if (Cancel
== TRUE
)
1829 return SELECT_PARTITION_PAGE
;
1833 PartSize
= atoi(InputBuffer
);
1841 if (PartSize
> MaxSize
)
1847 /* Convert to bytes */
1848 if (PartSize
== MaxSize
)
1850 /* Use all of the unpartitioned disk space */
1851 PartSize
= PartEntry
->UnpartitionedLength
;
1855 /* Round-up by cylinder size */
1856 PartSize
= (PartSize
* 1024 * 1024 + DiskEntry
->CylinderSize
- 1) /
1857 DiskEntry
->CylinderSize
* DiskEntry
->CylinderSize
;
1859 /* But never get larger than the unpartitioned disk space */
1860 if (PartSize
> PartEntry
->UnpartitionedLength
)
1861 PartSize
= PartEntry
->UnpartitionedLength
;
1864 DPRINT ("Partition size: %I64u bytes\n", PartSize
);
1866 CreateNewPartition(PartitionList
,
1870 return SELECT_PARTITION_PAGE
;
1874 return CREATE_PARTITION_PAGE
;
1879 DeletePartitionPage(PINPUT_RECORD Ir
)
1881 PDISKENTRY DiskEntry
;
1882 PPARTENTRY PartEntry
;
1889 if (PartitionList
== NULL
||
1890 PartitionList
->CurrentDisk
== NULL
||
1891 PartitionList
->CurrentPartition
== NULL
)
1893 /* FIXME: show an error dialog */
1897 DiskEntry
= PartitionList
->CurrentDisk
;
1898 PartEntry
= PartitionList
->CurrentPartition
;
1899 PartNumber
= PartitionList
->CurrentPartitionNumber
;
1901 MUIDisplayPage(DELETE_PARTITION_PAGE
);
1903 /* Determine partition type */
1905 if (PartEntry
->New
== TRUE
)
1907 PartType
= MUIGetString(STRING_UNFORMATTED
);
1909 else if (PartEntry
->Unpartitioned
== FALSE
)
1911 if ((PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_FAT_12
) ||
1912 (PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_FAT_16
) ||
1913 (PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_HUGE
) ||
1914 (PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_XINT13
))
1918 else if ((PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_FAT32
) ||
1919 (PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_FAT32_XINT13
))
1923 else if (PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_EXT2
)
1927 else if (PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_IFS
)
1929 PartType
= "NTFS"; /* FIXME: Not quite correct! */
1934 if (PartEntry
->PartInfo
[PartNumber
].PartitionLength
.QuadPart
>= 0x280000000LL
) /* 10 GB */
1936 PartSize
= (PartEntry
->PartInfo
[PartNumber
].PartitionLength
.QuadPart
+ (1 << 29)) >> 30;
1937 Unit
= MUIGetString(STRING_GB
);
1941 if (PartEntry
->PartInfo
[PartNumber
].PartitionLength
.QuadPart
>= 0xA00000LL
) /* 10 MB */
1943 PartSize
= (PartEntry
->PartInfo
[PartNumber
].PartitionLength
.QuadPart
+ (1 << 19)) >> 20;
1944 Unit
= MUIGetString(STRING_MB
);
1948 PartSize
= (PartEntry
->PartInfo
[PartNumber
].PartitionLength
.QuadPart
+ (1 << 9)) >> 10;
1949 Unit
= MUIGetString(STRING_KB
);
1952 if (PartType
== NULL
)
1954 CONSOLE_PrintTextXY(6, 10,
1955 MUIGetString(STRING_HDDINFOUNK2
),
1956 (PartEntry
->DriveLetter
[PartNumber
] == 0) ? '-' : PartEntry
->DriveLetter
[PartNumber
],
1957 (PartEntry
->DriveLetter
[PartNumber
] == 0) ? '-' : ':',
1958 PartEntry
->PartInfo
[PartNumber
].PartitionType
,
1964 CONSOLE_PrintTextXY(6, 10,
1965 " %c%c %s %I64u %s",
1966 (PartEntry
->DriveLetter
[PartNumber
] == 0) ? '-' : PartEntry
->DriveLetter
[PartNumber
],
1967 (PartEntry
->DriveLetter
[PartNumber
] == 0) ? '-' : ':',
1974 if (DiskEntry
->DiskSize
>= 0x280000000ULL
) /* 10 GB */
1976 DiskSize
= (DiskEntry
->DiskSize
+ (1 << 29)) >> 30;
1977 Unit
= MUIGetString(STRING_GB
);
1982 DiskSize
= (DiskEntry
->DiskSize
+ (1 << 19)) >> 20;
1987 Unit
= MUIGetString(STRING_MB
);
1990 if (DiskEntry
->DriverName
.Length
> 0)
1992 CONSOLE_PrintTextXY(6, 12,
1993 MUIGetString(STRING_HDINFOPARTDELETE
),
1996 DiskEntry
->DiskNumber
,
2000 &DiskEntry
->DriverName
);
2004 CONSOLE_PrintTextXY(6, 12,
2005 MUIGetString(STRING_HDDINFOUNK3
),
2008 DiskEntry
->DiskNumber
,
2016 CONSOLE_ConInKey(Ir
);
2018 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
2019 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
2021 if (ConfirmQuit(Ir
) == TRUE
)
2028 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
) /* ESC */
2030 return SELECT_PARTITION_PAGE
;
2032 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== 'D') /* D */
2034 DeleteCurrentPartition(PartitionList
);
2036 return SELECT_PARTITION_PAGE
;
2040 return DELETE_PARTITION_PAGE
;
2045 SelectFileSystemPage(PINPUT_RECORD Ir
)
2047 PDISKENTRY DiskEntry
;
2048 PPARTENTRY PartEntry
;
2056 if (PartitionList
== NULL
||
2057 PartitionList
->CurrentDisk
== NULL
||
2058 PartitionList
->CurrentPartition
== NULL
)
2060 /* FIXME: show an error dialog */
2064 DiskEntry
= PartitionList
->CurrentDisk
;
2065 PartEntry
= PartitionList
->CurrentPartition
;
2066 PartNumber
= PartitionList
->CurrentPartitionNumber
;
2068 /* adjust disk size */
2069 if (DiskEntry
->DiskSize
>= 0x280000000ULL
) /* 10 GB */
2071 DiskSize
= (DiskEntry
->DiskSize
+ (1 << 29)) >> 30;
2072 DiskUnit
= MUIGetString(STRING_GB
);
2076 DiskSize
= (DiskEntry
->DiskSize
+ (1 << 19)) >> 20;
2077 DiskUnit
= MUIGetString(STRING_MB
);
2080 /* adjust partition size */
2081 if (PartEntry
->PartInfo
[PartNumber
].PartitionLength
.QuadPart
>= 0x280000000LL
) /* 10 GB */
2083 PartSize
= (PartEntry
->PartInfo
[PartNumber
].PartitionLength
.QuadPart
+ (1 << 29)) >> 30;
2084 PartUnit
= MUIGetString(STRING_GB
);
2088 PartSize
= (PartEntry
->PartInfo
[PartNumber
].PartitionLength
.QuadPart
+ (1 << 19)) >> 20;
2089 PartUnit
= MUIGetString(STRING_MB
);
2092 /* adjust partition type */
2093 if ((PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_FAT_12
) ||
2094 (PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_FAT_16
) ||
2095 (PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_HUGE
) ||
2096 (PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_XINT13
))
2100 else if ((PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_FAT32
) ||
2101 (PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_FAT32_XINT13
))
2105 else if (PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_EXT2
)
2109 else if (PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_IFS
)
2111 PartType
= "NTFS"; /* FIXME: Not quite correct! */
2113 else if (PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_ENTRY_UNUSED
)
2115 PartType
= MUIGetString(STRING_FORMATUNUSED
);
2119 PartType
= MUIGetString(STRING_FORMATUNKNOWN
);
2122 if (PartEntry
->AutoCreate
== TRUE
)
2124 CONSOLE_SetTextXY(6, 8, MUIGetString(STRING_NEWPARTITION
));
2127 CONSOLE_PrintTextXY(8, 10, "Partition %lu (%I64u %s) %s of",
2128 PartEntry
->PartInfo
[PartNumber
].PartitionNumber
,
2134 CONSOLE_PrintTextXY(8, 10, MUIGetString(STRING_HDINFOPARTZEROED
),
2135 DiskEntry
->DiskNumber
,
2141 &DiskEntry
->DriverName
);
2143 CONSOLE_SetTextXY(6, 12, MUIGetString(STRING_PARTFORMAT
));
2146 PartEntry
->AutoCreate
= FALSE
;
2148 else if (PartEntry
->New
== TRUE
)
2150 CONSOLE_SetTextXY(6, 8, MUIGetString(STRING_NONFORMATTEDPART
));
2151 CONSOLE_SetTextXY(6, 10, MUIGetString(STRING_PARTFORMAT
));
2155 CONSOLE_SetTextXY(6, 8, MUIGetString(STRING_INSTALLONPART
));
2157 if (PartType
== NULL
)
2159 CONSOLE_PrintTextXY(8, 10,
2160 MUIGetString(STRING_HDDINFOUNK4
),
2161 (PartEntry
->DriveLetter
[PartNumber
] == 0) ? '-' : PartEntry
->DriveLetter
[PartNumber
],
2162 (PartEntry
->DriveLetter
[PartNumber
] == 0) ? '-' : ':',
2163 PartEntry
->PartInfo
[PartNumber
].PartitionType
,
2169 CONSOLE_PrintTextXY(8, 10,
2171 (PartEntry
->DriveLetter
[PartNumber
] == 0) ? '-' : PartEntry
->DriveLetter
[PartNumber
],
2172 (PartEntry
->DriveLetter
[PartNumber
] == 0) ? '-' : ':',
2178 CONSOLE_PrintTextXY(6, 12, MUIGetString(STRING_HDINFOPARTEXISTS
),
2179 DiskEntry
->DiskNumber
,
2185 &DiskEntry
->DriverName
);
2188 MUIDisplayPage(SELECT_FILE_SYSTEM_PAGE
);
2190 if (FileSystemList
== NULL
)
2192 FileSystemList
= CreateFileSystemList(6, 26, PartEntry
->New
, L
"FAT");
2193 if (FileSystemList
== NULL
)
2195 /* FIXME: show an error dialog */
2199 /* FIXME: Add file systems to list */
2201 DrawFileSystemList(FileSystemList
);
2203 if (RepairUpdateFlag
)
2205 return CHECK_FILE_SYSTEM_PAGE
;
2206 //return SELECT_PARTITION_PAGE;
2209 if (IsUnattendedSetup
)
2211 if (UnattendFormatPartition
)
2213 return FORMAT_PARTITION_PAGE
;
2216 return CHECK_FILE_SYSTEM_PAGE
;
2221 CONSOLE_ConInKey(Ir
);
2223 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
2224 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
2226 if (ConfirmQuit(Ir
) == TRUE
)
2233 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
2234 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
)) /* ESC */
2236 return SELECT_PARTITION_PAGE
;
2238 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
2239 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
)) /* DOWN */
2241 ScrollDownFileSystemList(FileSystemList
);
2243 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
2244 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_UP
)) /* UP */
2246 ScrollUpFileSystemList(FileSystemList
);
2248 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_RETURN
) /* ENTER */
2250 if (!FileSystemList
->Selected
->FormatFunc
)
2252 return CHECK_FILE_SYSTEM_PAGE
;
2256 return FORMAT_PARTITION_PAGE
;
2261 return SELECT_FILE_SYSTEM_PAGE
;
2266 FormatPartitionPage(PINPUT_RECORD Ir
)
2268 WCHAR PathBuffer
[MAX_PATH
];
2269 PDISKENTRY DiskEntry
;
2270 PPARTENTRY PartEntry
;
2280 MUIDisplayPage(FORMAT_PARTITION_PAGE
);
2282 if (PartitionList
== NULL
||
2283 PartitionList
->CurrentDisk
== NULL
||
2284 PartitionList
->CurrentPartition
== NULL
)
2286 /* FIXME: show an error dialog */
2290 DiskEntry
= PartitionList
->CurrentDisk
;
2291 PartEntry
= PartitionList
->CurrentPartition
;
2292 PartNum
= PartitionList
->CurrentPartitionNumber
;
2296 if (!IsUnattendedSetup
)
2298 CONSOLE_ConInKey(Ir
);
2301 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
2302 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
2304 if (ConfirmQuit(Ir
) == TRUE
)
2311 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_RETURN
|| IsUnattendedSetup
) /* ENTER */
2313 CONSOLE_SetStatusText(MUIGetString(STRING_PLEASEWAIT
));
2315 if (wcscmp(FileSystemList
->Selected
->FileSystem
, L
"FAT") == 0)
2317 if (PartEntry
->PartInfo
[PartNum
].PartitionLength
.QuadPart
< (4200LL * 1024LL))
2319 /* FAT12 CHS partition (disk is smaller than 4.1MB) */
2320 PartEntry
->PartInfo
[PartNum
].PartitionType
= PARTITION_FAT_12
;
2322 else if (PartEntry
->PartInfo
[PartNum
].StartingOffset
.QuadPart
< (1024LL * 255LL * 63LL * 512LL))
2324 /* Partition starts below the 8.4GB boundary ==> CHS partition */
2326 if (PartEntry
->PartInfo
[PartNum
].PartitionLength
.QuadPart
< (32LL * 1024LL * 1024LL))
2328 /* FAT16 CHS partition (partiton size < 32MB) */
2329 PartEntry
->PartInfo
[PartNum
].PartitionType
= PARTITION_FAT_16
;
2331 else if (PartEntry
->PartInfo
[PartNum
].PartitionLength
.QuadPart
< (512LL * 1024LL * 1024LL))
2333 /* FAT16 CHS partition (partition size < 512MB) */
2334 PartEntry
->PartInfo
[PartNum
].PartitionType
= PARTITION_HUGE
;
2338 /* FAT32 CHS partition (partition size >= 512MB) */
2339 PartEntry
->PartInfo
[PartNum
].PartitionType
= PARTITION_FAT32
;
2344 /* Partition starts above the 8.4GB boundary ==> LBA partition */
2346 if (PartEntry
->PartInfo
[PartNum
].PartitionLength
.QuadPart
< (512LL * 1024LL * 1024LL))
2348 /* FAT16 LBA partition (partition size < 512MB) */
2349 PartEntry
->PartInfo
[PartNum
].PartitionType
= PARTITION_XINT13
;
2353 /* FAT32 LBA partition (partition size >= 512MB) */
2354 PartEntry
->PartInfo
[PartNum
].PartitionType
= PARTITION_FAT32_XINT13
;
2358 else if (wcscmp(FileSystemList
->Selected
->FileSystem
, L
"EXT2") == 0)
2359 PartEntry
->PartInfo
[PartNum
].PartitionType
= PARTITION_EXT2
;
2360 else if (!FileSystemList
->Selected
->FormatFunc
)
2363 CheckActiveBootPartition(PartitionList
);
2366 CONSOLE_PrintTextXY(6, 12,
2367 "Disk: %I64u Cylinder: %I64u Track: %I64u",
2368 DiskEntry
->DiskSize
,
2369 DiskEntry
->CylinderSize
,
2370 DiskEntry
->TrackSize
);
2373 DiskEntry
= PartitionList
->CurrentDisk
;
2374 Entry
= DiskEntry
->PartListHead
.Flink
;
2376 while (Entry
!= &DiskEntry
->PartListHead
)
2378 PartEntry
= CONTAINING_RECORD(Entry
, PARTENTRY
, ListEntry
);
2380 if (PartEntry
->Unpartitioned
== FALSE
)
2382 for (i
= 0; i
< 4; i
++)
2384 CONSOLE_PrintTextXY(6, Line
,
2385 "%2u: %2u %c %12I64u %12I64u %2u %c",
2387 PartEntry
->PartInfo
[i
].PartitionNumber
,
2388 PartEntry
->PartInfo
[i
].BootIndicator
? 'A' : '-',
2389 PartEntry
->PartInfo
[i
].StartingOffset
.QuadPart
,
2390 PartEntry
->PartInfo
[i
].PartitionLength
.QuadPart
,
2391 PartEntry
->PartInfo
[i
].PartitionType
,
2392 PartEntry
->PartInfo
[i
].RewritePartition
? '*' : ' ');
2400 Entry
= Entry
->Flink
;
2403 /* Restore the old entry */
2404 PartEntry
= PartitionList
->CurrentPartition
;
2407 if (WritePartitionsToDisk(PartitionList
) == FALSE
)
2409 DPRINT("WritePartitionsToDisk() failed\n");
2410 MUIDisplayError(ERROR_WRITE_PTABLE
, Ir
, POPUP_WAIT_ENTER
);
2414 /* Set DestinationRootPath */
2415 RtlFreeUnicodeString(&DestinationRootPath
);
2416 swprintf(PathBuffer
,
2417 L
"\\Device\\Harddisk%lu\\Partition%lu",
2418 PartitionList
->CurrentDisk
->DiskNumber
,
2419 PartitionList
->CurrentPartition
->PartInfo
[PartNum
].PartitionNumber
);
2420 RtlCreateUnicodeString(&DestinationRootPath
,
2422 DPRINT("DestinationRootPath: %wZ\n", &DestinationRootPath
);
2425 /* Set SystemRootPath */
2426 RtlFreeUnicodeString(&SystemRootPath
);
2427 swprintf(PathBuffer
,
2428 L
"\\Device\\Harddisk%lu\\Partition%lu",
2429 PartitionList
->ActiveBootDisk
->DiskNumber
,
2430 PartitionList
->ActiveBootPartition
->
2431 PartInfo
[PartitionList
->ActiveBootPartitionNumber
].PartitionNumber
);
2432 RtlCreateUnicodeString(&SystemRootPath
,
2434 DPRINT("SystemRootPath: %wZ\n", &SystemRootPath
);
2437 if (FileSystemList
->Selected
->FormatFunc
)
2439 Status
= FormatPartition(&DestinationRootPath
,
2440 FileSystemList
->Selected
);
2441 if (!NT_SUCCESS(Status
))
2443 DPRINT1("FormatPartition() failed with status 0x%08lx\n", Status
);
2444 /* FIXME: show an error dialog */
2448 PartEntry
->New
= FALSE
;
2450 CheckActiveBootPartition(PartitionList
);
2453 /* Install MBR if necessary */
2454 if (DiskEntry
->NoMbr
&&
2455 DiskEntry
->BiosDiskNumber
== 0)
2457 wcscpy(PathBuffer
, SourceRootPath
.Buffer
);
2458 wcscat(PathBuffer
, L
"\\loader\\dosmbr.bin");
2460 DPRINT("Install MBR bootcode: %S ==> %S\n",
2461 PathBuffer
, DestinationRootPath
.Buffer
);
2463 /* Install MBR bootcode */
2464 Status
= InstallMbrBootCodeToDisk(PathBuffer
,
2465 DestinationRootPath
.Buffer
);
2466 if (!NT_SUCCESS (Status
))
2468 DPRINT1("InstallMbrBootCodeToDisk() failed (Status %lx)\n",
2473 DiskEntry
->NoMbr
= FALSE
;
2476 if (wcscmp(FileSystemList
->Selected
->FileSystem
, L
"FAT") == 0)
2478 /* FIXME: Install boot code. This is a hack! */
2479 if ((PartEntry
->PartInfo
[PartNum
].PartitionType
== PARTITION_FAT32_XINT13
) ||
2480 (PartEntry
->PartInfo
[PartNum
].PartitionType
== PARTITION_FAT32
))
2482 wcscpy(PathBuffer
, SourceRootPath
.Buffer
);
2483 wcscat(PathBuffer
, L
"\\loader\\fat32.bin");
2485 DPRINT("Install FAT32 bootcode: %S ==> %S\n", PathBuffer
,
2486 DestinationRootPath
.Buffer
);
2488 Status
= InstallFat32BootCodeToDisk(PathBuffer
,
2489 DestinationRootPath
.Buffer
);
2490 if (!NT_SUCCESS(Status
))
2492 DPRINT1("InstallFat32BootCodeToDisk() failed with status 0x%08lx\n", Status
);
2493 /* FIXME: show an error dialog */
2494 DestroyFileSystemList(FileSystemList
);
2495 FileSystemList
= NULL
;
2501 wcscpy(PathBuffer
, SourceRootPath
.Buffer
);
2502 wcscat(PathBuffer
, L
"\\loader\\fat.bin");
2504 DPRINT("Install FAT bootcode: %S ==> %S\n", PathBuffer
,
2505 DestinationRootPath
.Buffer
);
2507 Status
= InstallFat16BootCodeToDisk(PathBuffer
,
2508 DestinationRootPath
.Buffer
);
2509 if (!NT_SUCCESS(Status
))
2511 DPRINT1("InstallFat16BootCodeToDisk() failed with status 0x%.08x\n", Status
);
2512 /* FIXME: show an error dialog */
2513 DestroyFileSystemList(FileSystemList
);
2514 FileSystemList
= NULL
;
2519 else if (wcscmp(FileSystemList
->Selected
->FileSystem
, L
"EXT2") == 0)
2521 wcscpy(PathBuffer
, SourceRootPath
.Buffer
);
2522 wcscat(PathBuffer
, L
"\\loader\\ext2.bin");
2524 DPRINT("Install EXT2 bootcode: %S ==> %S\n", PathBuffer
,
2525 DestinationRootPath
.Buffer
);
2527 Status
= InstallFat32BootCodeToDisk(PathBuffer
,
2528 DestinationRootPath
.Buffer
);
2529 if (!NT_SUCCESS(Status
))
2531 DPRINT1("InstallFat32BootCodeToDisk() failed with status 0x%08lx\n", Status
);
2532 /* FIXME: show an error dialog */
2533 DestroyFileSystemList(FileSystemList
);
2534 FileSystemList
= NULL
;
2538 else if (FileSystemList
->Selected
->FormatFunc
)
2540 DestroyFileSystemList(FileSystemList
);
2541 FileSystemList
= NULL
;
2546 CONSOLE_SetStatusText(" Done. Press any key ...");
2547 CONSOLE_ConInKey(Ir
);
2550 DestroyFileSystemList(FileSystemList
);
2551 FileSystemList
= NULL
;
2552 return INSTALL_DIRECTORY_PAGE
;
2556 return FORMAT_PARTITION_PAGE
;
2561 CheckFileSystemPage(PINPUT_RECORD Ir
)
2563 PFILE_SYSTEM_ITEM CurrentFileSystem
;
2564 WCHAR PathBuffer
[MAX_PATH
];
2565 CHAR Buffer
[MAX_PATH
];
2567 UCHAR PartNum
= PartitionList
->CurrentPartitionNumber
;
2569 /* FIXME: code duplicated in FormatPartitionPage */
2570 /* Set DestinationRootPath */
2571 RtlFreeUnicodeString(&DestinationRootPath
);
2572 swprintf(PathBuffer
,
2573 L
"\\Device\\Harddisk%lu\\Partition%lu",
2574 PartitionList
->CurrentDisk
->DiskNumber
,
2575 PartitionList
->CurrentPartition
->PartInfo
[PartNum
].PartitionNumber
);
2576 RtlCreateUnicodeString(&DestinationRootPath
, PathBuffer
);
2577 DPRINT("DestinationRootPath: %wZ\n", &DestinationRootPath
);
2579 /* Set SystemRootPath */
2580 RtlFreeUnicodeString(&SystemRootPath
);
2581 swprintf(PathBuffer
,
2582 L
"\\Device\\Harddisk%lu\\Partition%lu",
2583 PartitionList
->ActiveBootDisk
->DiskNumber
,
2584 PartitionList
->ActiveBootPartition
->PartInfo
[PartNum
].PartitionNumber
);
2585 RtlCreateUnicodeString(&SystemRootPath
, PathBuffer
);
2586 DPRINT("SystemRootPath: %wZ\n", &SystemRootPath
);
2588 CONSOLE_SetTextXY(6, 8, MUIGetString(STRING_CHECKINGPART
));
2590 CONSOLE_SetStatusText(MUIGetString(STRING_PLEASEWAIT
));
2592 /* WRONG: first filesystem is not necesseraly the one of the current partition! */
2593 CurrentFileSystem
= CONTAINING_RECORD(FileSystemList
->ListHead
.Flink
, FILE_SYSTEM_ITEM
, ListEntry
);
2595 if (!CurrentFileSystem
->ChkdskFunc
)
2598 "Setup is currently unable to check a partition formatted in %S.\n"
2600 " \x07 Press ENTER to continue Setup.\n"
2601 " \x07 Press F3 to quit Setup.",
2602 CurrentFileSystem
->FileSystem
);
2605 MUIGetString(STRING_QUITCONTINUE
),
2606 NULL
, POPUP_WAIT_NONE
);
2610 CONSOLE_ConInKey(Ir
);
2612 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00 &&
2613 Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
) /* F3 */
2615 if (ConfirmQuit(Ir
))
2618 return CHECK_FILE_SYSTEM_PAGE
;
2620 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== VK_RETURN
) /* ENTER */
2622 return INSTALL_DIRECTORY_PAGE
;
2628 Status
= ChkdskPartition(&DestinationRootPath
, CurrentFileSystem
);
2629 if (!NT_SUCCESS(Status
))
2631 DPRINT("ChkdskPartition() failed with status 0x%08lx\n", Status
);
2632 sprintf(Buffer
, "Setup failed to verify the selected partition.\n"
2633 "(Status 0x%08lx).\n", Status
);
2636 MUIGetString(STRING_REBOOTCOMPUTER
),
2637 Ir
, POPUP_WAIT_ENTER
);
2642 return INSTALL_DIRECTORY_PAGE
;
2648 InstallDirectoryPage1(PWCHAR InstallDir
,
2649 PDISKENTRY DiskEntry
,
2650 PPARTENTRY PartEntry
,
2653 WCHAR PathBuffer
[MAX_PATH
];
2655 /* Create 'InstallPath' string */
2656 RtlFreeUnicodeString(&InstallPath
);
2657 RtlCreateUnicodeString(&InstallPath
,
2660 /* Create 'DestinationPath' string */
2661 RtlFreeUnicodeString(&DestinationPath
);
2662 wcscpy(PathBuffer
, DestinationRootPath
.Buffer
);
2664 if (InstallDir
[0] != L
'\\')
2665 wcscat(PathBuffer
, L
"\\");
2667 wcscat(PathBuffer
, InstallDir
);
2668 RtlCreateUnicodeString(&DestinationPath
, PathBuffer
);
2670 /* Create 'DestinationArcPath' */
2671 RtlFreeUnicodeString(&DestinationArcPath
);
2672 swprintf(PathBuffer
,
2673 L
"multi(0)disk(0)rdisk(%lu)partition(%lu)",
2674 DiskEntry
->BiosDiskNumber
,
2675 PartEntry
->PartInfo
[PartNum
].PartitionNumber
);
2677 if (InstallDir
[0] != L
'\\')
2678 wcscat(PathBuffer
, L
"\\");
2680 wcscat(PathBuffer
, InstallDir
);
2681 RtlCreateUnicodeString(&DestinationArcPath
, PathBuffer
);
2683 return PREPARE_COPY_PAGE
;
2688 InstallDirectoryPage(PINPUT_RECORD Ir
)
2690 PDISKENTRY DiskEntry
;
2691 PPARTENTRY PartEntry
;
2692 WCHAR InstallDir
[51];
2697 if (PartitionList
== NULL
||
2698 PartitionList
->CurrentDisk
== NULL
||
2699 PartitionList
->CurrentPartition
== NULL
)
2701 /* FIXME: show an error dialog */
2705 DiskEntry
= PartitionList
->CurrentDisk
;
2706 PartEntry
= PartitionList
->CurrentPartition
;
2708 /* Search for 'DefaultPath' in the 'SetupData' section */
2709 if (!SetupFindFirstLineW(SetupInf
, L
"SetupData", L
"DefaultPath", &Context
))
2711 MUIDisplayError(ERROR_FIND_SETUPDATA
, Ir
, POPUP_WAIT_ENTER
);
2715 /* Read the 'DefaultPath' data */
2716 if (INF_GetData(&Context
, NULL
, &DefaultPath
))
2718 wcscpy(InstallDir
, DefaultPath
);
2722 wcscpy(InstallDir
, L
"\\ReactOS");
2725 Length
= wcslen(InstallDir
);
2726 CONSOLE_SetInputTextXY(8, 11, 51, InstallDir
);
2727 MUIDisplayPage(INSTALL_DIRECTORY_PAGE
);
2729 if (IsUnattendedSetup
)
2731 return InstallDirectoryPage1(InstallDir
,
2734 PartitionList
->CurrentPartitionNumber
);
2739 CONSOLE_ConInKey(Ir
);
2741 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
2742 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
2744 if (ConfirmQuit(Ir
) == TRUE
)
2749 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2751 return InstallDirectoryPage1(InstallDir
,
2754 PartitionList
->CurrentPartitionNumber
);
2756 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x08) /* BACKSPACE */
2761 InstallDir
[Length
] = 0;
2762 CONSOLE_SetInputTextXY(8, 11, 51, InstallDir
);
2765 else if (isprint(Ir
->Event
.KeyEvent
.uChar
.AsciiChar
))
2769 InstallDir
[Length
] = (WCHAR
)Ir
->Event
.KeyEvent
.uChar
.AsciiChar
;
2771 InstallDir
[Length
] = 0;
2772 CONSOLE_SetInputTextXY(8, 11, 51, InstallDir
);
2777 return INSTALL_DIRECTORY_PAGE
;
2782 AddSectionToCopyQueueCab(HINF InfFile
,
2784 PWCHAR SourceCabinet
,
2785 PCUNICODE_STRING DestinationPath
,
2788 INFCONTEXT FilesContext
;
2789 INFCONTEXT DirContext
;
2791 PWCHAR FileKeyValue
;
2793 PWCHAR TargetFileName
;
2795 /* Search for the SectionName section */
2796 if (!SetupFindFirstLineW(InfFile
, SectionName
, NULL
, &FilesContext
))
2799 sprintf(Buffer
, MUIGetString(STRING_TXTSETUPFAILED
), SectionName
);
2800 PopupError(Buffer
, MUIGetString(STRING_REBOOTCOMPUTER
), Ir
, POPUP_WAIT_ENTER
);
2805 * Enumerate the files in the section
2806 * and add them to the file queue.
2810 /* Get source file name and target directory id */
2811 if (!INF_GetData(&FilesContext
, &FileKeyName
, &FileKeyValue
))
2813 /* FIXME: Handle error! */
2814 DPRINT1("INF_GetData() failed\n");
2818 /* Get optional target file name */
2819 if (!INF_GetDataField(&FilesContext
, 2, &TargetFileName
))
2820 TargetFileName
= NULL
;
2822 DPRINT("FileKeyName: '%S' FileKeyValue: '%S'\n", FileKeyName
, FileKeyValue
);
2824 /* Lookup target directory */
2825 if (!SetupFindFirstLineW(InfFile
, L
"Directories", FileKeyValue
, &DirContext
))
2827 /* FIXME: Handle error! */
2828 DPRINT1("SetupFindFirstLine() failed\n");
2832 if (!INF_GetData(&DirContext
, NULL
, &DirKeyValue
))
2834 /* FIXME: Handle error! */
2835 DPRINT1("INF_GetData() failed\n");
2839 if (!SetupQueueCopy(SetupFileQueue
,
2841 SourceRootPath
.Buffer
,
2842 SourceRootDir
.Buffer
,
2847 /* FIXME: Handle error! */
2848 DPRINT1("SetupQueueCopy() failed\n");
2850 } while (SetupFindNextLine(&FilesContext
, &FilesContext
));
2857 AddSectionToCopyQueue(HINF InfFile
,
2859 PWCHAR SourceCabinet
,
2860 PCUNICODE_STRING DestinationPath
,
2863 INFCONTEXT FilesContext
;
2864 INFCONTEXT DirContext
;
2866 PWCHAR FileKeyValue
;
2868 PWCHAR TargetFileName
;
2871 return AddSectionToCopyQueueCab(InfFile
, L
"SourceFiles", SourceCabinet
, DestinationPath
, Ir
);
2873 /* Search for the SectionName section */
2874 if (!SetupFindFirstLineW(InfFile
, SectionName
, NULL
, &FilesContext
))
2877 sprintf(Buffer
, MUIGetString(STRING_TXTSETUPFAILED
), SectionName
);
2878 PopupError(Buffer
, MUIGetString(STRING_REBOOTCOMPUTER
), Ir
, POPUP_WAIT_ENTER
);
2883 * Enumerate the files in the section
2884 * and add them to the file queue.
2888 /* Get source file name and target directory id */
2889 if (!INF_GetData(&FilesContext
, &FileKeyName
, &FileKeyValue
))
2891 /* FIXME: Handle error! */
2892 DPRINT1("INF_GetData() failed\n");
2896 /* Get target directory id */
2897 if (!INF_GetDataField(&FilesContext
, 13, &FileKeyValue
))
2899 /* FIXME: Handle error! */
2900 DPRINT1("INF_GetData() failed\n");
2904 /* Get optional target file name */
2905 if (!INF_GetDataField(&FilesContext
, 11, &TargetFileName
))
2906 TargetFileName
= NULL
;
2907 else if (!*TargetFileName
)
2908 TargetFileName
= NULL
;
2910 DPRINT("FileKeyName: '%S' FileKeyValue: '%S'\n", FileKeyName
, FileKeyValue
);
2912 /* Lookup target directory */
2913 if (!SetupFindFirstLineW(InfFile
, L
"Directories", FileKeyValue
, &DirContext
))
2915 /* FIXME: Handle error! */
2916 DPRINT1("SetupFindFirstLine() failed\n");
2920 if (!INF_GetData(&DirContext
, NULL
, &DirKeyValue
))
2922 /* FIXME: Handle error! */
2923 DPRINT1("INF_GetData() failed\n");
2927 if (!SetupQueueCopy(SetupFileQueue
,
2929 SourceRootPath
.Buffer
,
2930 SourceRootDir
.Buffer
,
2935 /* FIXME: Handle error! */
2936 DPRINT1("SetupQueueCopy() failed\n");
2938 } while (SetupFindNextLine(&FilesContext
, &FilesContext
));
2945 PrepareCopyPageInfFile(HINF InfFile
,
2946 PWCHAR SourceCabinet
,
2949 WCHAR PathBuffer
[MAX_PATH
];
2950 INFCONTEXT DirContext
;
2951 PWCHAR AdditionalSectionName
= NULL
;
2956 /* Add common files */
2957 if (!AddSectionToCopyQueue(InfFile
, L
"SourceDisksFiles", SourceCabinet
, &DestinationPath
, Ir
))
2960 /* Add specific files depending of computer type */
2961 if (SourceCabinet
== NULL
)
2963 if (!ProcessComputerFiles(InfFile
, ComputerList
, &AdditionalSectionName
))
2966 if (AdditionalSectionName
)
2968 if (!AddSectionToCopyQueue(InfFile
, AdditionalSectionName
, SourceCabinet
, &DestinationPath
, Ir
))
2973 /* Create directories */
2977 * Install directories like '\reactos\test' are not handled yet.
2980 /* Get destination path */
2981 wcscpy(PathBuffer
, DestinationPath
.Buffer
);
2983 /* Remove trailing backslash */
2984 Length
= wcslen(PathBuffer
);
2985 if ((Length
> 0) && (PathBuffer
[Length
- 1] == '\\'))
2987 PathBuffer
[Length
- 1] = 0;
2990 /* Create the install directory */
2991 Status
= SetupCreateDirectory(PathBuffer
);
2992 if (!NT_SUCCESS(Status
) && Status
!= STATUS_OBJECT_NAME_COLLISION
)
2994 DPRINT("Creating directory '%S' failed: Status = 0x%08lx", PathBuffer
, Status
);
2995 MUIDisplayError(ERROR_CREATE_INSTALL_DIR
, Ir
, POPUP_WAIT_ENTER
);
2999 /* Search for the 'Directories' section */
3000 if (!SetupFindFirstLineW(InfFile
, L
"Directories", NULL
, &DirContext
))
3004 MUIDisplayError(ERROR_CABINET_SECTION
, Ir
, POPUP_WAIT_ENTER
);
3008 MUIDisplayError(ERROR_TXTSETUP_SECTION
, Ir
, POPUP_WAIT_ENTER
);
3014 /* Enumerate the directory values and create the subdirectories */
3017 if (!INF_GetData(&DirContext
, NULL
, &KeyValue
))
3023 if (KeyValue
[0] == L
'\\' && KeyValue
[1] != 0)
3025 DPRINT("Absolute Path: '%S'\n", KeyValue
);
3027 wcscpy(PathBuffer
, DestinationRootPath
.Buffer
);
3028 wcscat(PathBuffer
, KeyValue
);
3030 DPRINT("FullPath: '%S'\n", PathBuffer
);
3032 else if (KeyValue
[0] != L
'\\')
3034 DPRINT("RelativePath: '%S'\n", KeyValue
);
3035 wcscpy(PathBuffer
, DestinationPath
.Buffer
);
3036 wcscat(PathBuffer
, L
"\\");
3037 wcscat(PathBuffer
, KeyValue
);
3039 DPRINT("FullPath: '%S'\n", PathBuffer
);
3041 Status
= SetupCreateDirectory(PathBuffer
);
3042 if (!NT_SUCCESS(Status
) && Status
!= STATUS_OBJECT_NAME_COLLISION
)
3044 DPRINT("Creating directory '%S' failed: Status = 0x%08lx", PathBuffer
, Status
);
3045 MUIDisplayError(ERROR_CREATE_DIR
, Ir
, POPUP_WAIT_ENTER
);
3049 } while (SetupFindNextLine (&DirContext
, &DirContext
));
3056 PrepareCopyPage(PINPUT_RECORD Ir
)
3059 WCHAR PathBuffer
[MAX_PATH
];
3060 INFCONTEXT CabinetsContext
;
3066 MUIDisplayPage(PREPARE_COPY_PAGE
);
3068 /* Create the file queue */
3069 SetupFileQueue
= SetupOpenFileQueue();
3070 if (SetupFileQueue
== NULL
)
3072 MUIDisplayError(ERROR_COPY_QUEUE
, Ir
, POPUP_WAIT_ENTER
);
3076 if (!PrepareCopyPageInfFile(SetupInf
, NULL
, Ir
))
3081 /* Search for the 'Cabinets' section */
3082 if (!SetupFindFirstLineW(SetupInf
, L
"Cabinets", NULL
, &CabinetsContext
))
3084 return FILE_COPY_PAGE
;
3088 * Enumerate the directory values in the 'Cabinets'
3089 * section and parse their inf files.
3093 if (!INF_GetData(&CabinetsContext
, NULL
, &KeyValue
))
3096 wcscpy(PathBuffer
, SourcePath
.Buffer
);
3097 wcscat(PathBuffer
, L
"\\");
3098 wcscat(PathBuffer
, KeyValue
);
3101 CabinetInitialize();
3102 CabinetSetEventHandlers(NULL
, NULL
, NULL
);
3103 CabinetSetCabinetName(PathBuffer
);
3105 if (CabinetOpen() == CAB_STATUS_SUCCESS
)
3107 DPRINT("Cabinet %S\n", CabinetGetCabinetName());
3109 InfFileData
= CabinetGetCabinetReservedArea(&InfFileSize
);
3110 if (InfFileData
== NULL
)
3112 MUIDisplayError(ERROR_CABINET_SCRIPT
, Ir
, POPUP_WAIT_ENTER
);
3118 DPRINT("Cannot open cabinet: %S.\n", CabinetGetCabinetName());
3119 MUIDisplayError(ERROR_CABINET_MISSING
, Ir
, POPUP_WAIT_ENTER
);
3123 InfHandle
= INF_OpenBufferedFileA((CHAR
*) InfFileData
,
3130 if (InfHandle
== INVALID_HANDLE_VALUE
)
3132 MUIDisplayError(ERROR_INVALID_CABINET_INF
, Ir
, POPUP_WAIT_ENTER
);
3138 if (!PrepareCopyPageInfFile(InfHandle
, KeyValue
, Ir
))
3143 } while (SetupFindNextLine(&CabinetsContext
, &CabinetsContext
));
3145 return FILE_COPY_PAGE
;
3151 SetupUpdateMemoryInfo(IN PCOPYCONTEXT CopyContext
,
3154 SYSTEM_PERFORMANCE_INFORMATION PerfInfo
;
3156 /* Get the memory information from the system */
3157 NtQuerySystemInformation(SystemPerformanceInformation
,
3162 /* Check if this is initial setup */
3165 /* Set maximum limits to be total RAM pages */
3166 ProgressSetStepCount(CopyContext
->MemoryBars
[0], PerfInfo
.CommitLimit
);
3167 ProgressSetStepCount(CopyContext
->MemoryBars
[1], PerfInfo
.CommitLimit
);
3168 ProgressSetStepCount(CopyContext
->MemoryBars
[2], PerfInfo
.CommitLimit
);
3171 /* Set current values */
3172 ProgressSetStep(CopyContext
->MemoryBars
[0], PerfInfo
.PagedPoolPages
+ PerfInfo
.NonPagedPoolPages
);
3173 ProgressSetStep(CopyContext
->MemoryBars
[1], PerfInfo
.ResidentSystemCachePage
);
3174 ProgressSetStep(CopyContext
->MemoryBars
[2], PerfInfo
.AvailablePages
);
3180 FileCopyCallback(PVOID Context
,
3185 PCOPYCONTEXT CopyContext
;
3187 CopyContext
= (PCOPYCONTEXT
)Context
;
3189 switch (Notification
)
3191 case SPFILENOTIFY_STARTSUBQUEUE
:
3192 CopyContext
->TotalOperations
= (ULONG
)Param2
;
3193 ProgressSetStepCount(CopyContext
->ProgressBar
,
3194 CopyContext
->TotalOperations
);
3195 SetupUpdateMemoryInfo(CopyContext
, TRUE
);
3198 case SPFILENOTIFY_STARTCOPY
:
3199 /* Display copy message */
3200 CONSOLE_SetStatusText(MUIGetString(STRING_COPYING
), (PWSTR
)Param1
);
3201 SetupUpdateMemoryInfo(CopyContext
, FALSE
);
3204 case SPFILENOTIFY_ENDCOPY
:
3205 CopyContext
->CompletedOperations
++;
3206 ProgressNextStep(CopyContext
->ProgressBar
);
3207 SetupUpdateMemoryInfo(CopyContext
, FALSE
);
3217 FileCopyPage(PINPUT_RECORD Ir
)
3219 COPYCONTEXT CopyContext
;
3220 unsigned int mem_bar_width
;
3222 MUIDisplayPage(FILE_COPY_PAGE
);
3224 /* Create context for the copy process */
3225 CopyContext
.DestinationRootPath
= DestinationRootPath
.Buffer
;
3226 CopyContext
.InstallPath
= InstallPath
.Buffer
;
3227 CopyContext
.TotalOperations
= 0;
3228 CopyContext
.CompletedOperations
= 0;
3230 /* Create the progress bar as well */
3231 CopyContext
.ProgressBar
= CreateProgressBar(13,
3238 MUIGetString(STRING_SETUPCOPYINGFILES
));
3240 // fit memory bars to screen width, distribute them uniform
3241 mem_bar_width
= (xScreen
- 26) / 5;
3242 mem_bar_width
-= mem_bar_width
% 2; // make even
3243 /* ATTENTION: The following progress bars are debug stuff, which should not be translated!! */
3244 /* Create the paged pool progress bar */
3245 CopyContext
.MemoryBars
[0] = CreateProgressBar(13,
3254 /* Create the non paged pool progress bar */
3255 CopyContext
.MemoryBars
[1] = CreateProgressBar((xScreen
/ 2)- (mem_bar_width
/ 2),
3257 (xScreen
/ 2) + (mem_bar_width
/ 2),
3259 (xScreen
/ 2)- (mem_bar_width
/ 2),
3264 /* Create the global memory progress bar */
3265 CopyContext
.MemoryBars
[2] = CreateProgressBar(xScreen
- 13 - mem_bar_width
,
3269 xScreen
- 13 - mem_bar_width
,
3274 /* Do the file copying */
3275 SetupCommitFileQueueW(NULL
,
3280 /* If we get here, we're done, so cleanup the queue and progress bar */
3281 SetupCloseFileQueue(SetupFileQueue
);
3282 DestroyProgressBar(CopyContext
.ProgressBar
);
3283 DestroyProgressBar(CopyContext
.MemoryBars
[0]);
3284 DestroyProgressBar(CopyContext
.MemoryBars
[1]);
3285 DestroyProgressBar(CopyContext
.MemoryBars
[2]);
3287 /* Go display the next page */
3288 return REGISTRY_PAGE
;
3293 RegistryPage(PINPUT_RECORD Ir
)
3295 INFCONTEXT InfContext
;
3302 MUIDisplayPage(REGISTRY_PAGE
);
3304 if (RepairUpdateFlag
)
3306 return SUCCESS_PAGE
;
3309 if (!SetInstallPathValue(&DestinationPath
))
3311 DPRINT("SetInstallPathValue() failed\n");
3312 MUIDisplayError(ERROR_INITIALIZE_REGISTRY
, Ir
, POPUP_WAIT_ENTER
);
3316 /* Create the default hives */
3318 Status
= NtInitializeRegistry(CM_BOOT_FLAG_SETUP
);
3319 if (!NT_SUCCESS(Status
))
3321 DPRINT("NtInitializeRegistry() failed (Status %lx)\n", Status
);
3322 MUIDisplayError(ERROR_CREATE_HIVE
, Ir
, POPUP_WAIT_ENTER
);
3326 RegInitializeRegistry();
3329 /* Update registry */
3330 CONSOLE_SetStatusText(MUIGetString(STRING_REGHIVEUPDATE
));
3332 if (!SetupFindFirstLineW(SetupInf
, L
"HiveInfs.Install", NULL
, &InfContext
))
3334 DPRINT1("SetupFindFirstLine() failed\n");
3335 MUIDisplayError(ERROR_FIND_REGISTRY
, Ir
, POPUP_WAIT_ENTER
);
3341 INF_GetDataField (&InfContext
, 0, &Action
);
3342 INF_GetDataField (&InfContext
, 1, &File
);
3343 INF_GetDataField (&InfContext
, 2, &Section
);
3345 DPRINT("Action: %S File: %S Section %S\n", Action
, File
, Section
);
3350 if (!_wcsicmp (Action
, L
"AddReg"))
3354 else if (!_wcsicmp (Action
, L
"DelReg"))
3363 CONSOLE_SetStatusText(MUIGetString(STRING_IMPORTFILE
), File
);
3365 if (!ImportRegistryFile(File
, Section
, LanguageId
, Delete
))
3367 DPRINT("Importing %S failed\n", File
);
3369 MUIDisplayError(ERROR_IMPORT_HIVE
, Ir
, POPUP_WAIT_ENTER
);
3372 } while (SetupFindNextLine(&InfContext
, &InfContext
));
3374 /* Update display registry settings */
3375 CONSOLE_SetStatusText(MUIGetString(STRING_DISPLAYETTINGSUPDATE
));
3376 if (!ProcessDisplayRegistry(SetupInf
, DisplayList
))
3378 MUIDisplayError(ERROR_UPDATE_DISPLAY_SETTINGS
, Ir
, POPUP_WAIT_ENTER
);
3382 /* Set the locale */
3383 CONSOLE_SetStatusText(MUIGetString(STRING_LOCALESETTINGSUPDATE
));
3384 if (!ProcessLocaleRegistry(LanguageList
))
3386 MUIDisplayError(ERROR_UPDATE_LOCALESETTINGS
, Ir
, POPUP_WAIT_ENTER
);
3390 /* Add keyboard layouts */
3391 CONSOLE_SetStatusText(MUIGetString(STRING_ADDKBLAYOUTS
));
3392 if (!AddKeyboardLayouts())
3394 MUIDisplayError(ERROR_ADDING_KBLAYOUTS
, Ir
, POPUP_WAIT_ENTER
);
3400 if (!SetGeoID(MUIGetGeoID()))
3402 MUIDisplayError(ERROR_UPDATE_GEOID
, Ir
, POPUP_WAIT_ENTER
);
3406 if (!IsUnattendedSetup
)
3408 /* Update keyboard layout settings */
3409 CONSOLE_SetStatusText(MUIGetString(STRING_KEYBOARDSETTINGSUPDATE
));
3410 if (!ProcessKeyboardLayoutRegistry(LayoutList
))
3412 MUIDisplayError(ERROR_UPDATE_KBSETTINGS
, Ir
, POPUP_WAIT_ENTER
);
3417 /* Add codepage information to registry */
3418 CONSOLE_SetStatusText(MUIGetString(STRING_CODEPAGEINFOUPDATE
));
3421 MUIDisplayError(ERROR_ADDING_CODEPAGE
, Ir
, POPUP_WAIT_ENTER
);
3425 /* Update the mounted devices list */
3426 SetMountedDeviceValues(PartitionList
);
3428 CONSOLE_SetStatusText(MUIGetString(STRING_DONE
));
3430 return BOOT_LOADER_PAGE
;
3435 BootLoaderPage(PINPUT_RECORD Ir
)
3437 UCHAR PartitionType
;
3438 BOOLEAN InstallOnFloppy
;
3441 CONSOLE_SetStatusText(MUIGetString(STRING_PLEASEWAIT
));
3443 PartitionType
= PartitionList
->ActiveBootPartition
->
3444 PartInfo
[PartitionList
->ActiveBootPartitionNumber
].PartitionType
;
3446 if (IsUnattendedSetup
)
3448 if (UnattendMBRInstallType
== 0) /* skip MBR installation */
3450 return SUCCESS_PAGE
;
3452 else if (UnattendMBRInstallType
== 1) /* install on floppy */
3454 return BOOT_LOADER_FLOPPY_PAGE
;
3458 if (PartitionType
== PARTITION_ENTRY_UNUSED
)
3460 DPRINT("Error: active partition invalid (unused)\n");
3461 InstallOnFloppy
= TRUE
;
3463 else if (PartitionType
== 0x0A)
3465 /* OS/2 boot manager partition */
3466 DPRINT("Found OS/2 boot manager partition\n");
3467 InstallOnFloppy
= TRUE
;
3469 else if (PartitionType
== 0x83)
3471 /* Linux ext2 partition */
3472 DPRINT("Found Linux ext2 partition\n");
3473 InstallOnFloppy
= TRUE
;
3475 else if (PartitionType
== PARTITION_IFS
)
3477 /* NTFS partition */
3478 DPRINT("Found NTFS partition\n");
3479 InstallOnFloppy
= TRUE
;
3481 else if ((PartitionType
== PARTITION_FAT_12
) ||
3482 (PartitionType
== PARTITION_FAT_16
) ||
3483 (PartitionType
== PARTITION_HUGE
) ||
3484 (PartitionType
== PARTITION_XINT13
) ||
3485 (PartitionType
== PARTITION_FAT32
) ||
3486 (PartitionType
== PARTITION_FAT32_XINT13
))
3488 DPRINT("Found FAT partition\n");
3489 InstallOnFloppy
= FALSE
;
3493 /* Unknown partition */
3494 DPRINT("Unknown partition found\n");
3495 InstallOnFloppy
= TRUE
;
3498 if (InstallOnFloppy
== TRUE
)
3500 return BOOT_LOADER_FLOPPY_PAGE
;
3503 /* Unattended install on hdd? */
3504 if (IsUnattendedSetup
&& UnattendMBRInstallType
== 2)
3506 return BOOT_LOADER_HARDDISK_PAGE
;
3509 MUIDisplayPage(BOOT_LOADER_PAGE
);
3510 CONSOLE_InvertTextXY(8, Line
, 60, 1);
3514 CONSOLE_ConInKey(Ir
);
3516 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
3517 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
)) /* DOWN */
3519 CONSOLE_NormalTextXY(8, Line
, 60, 1);
3528 CONSOLE_InvertTextXY(8, Line
, 60, 1);
3530 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
3531 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_UP
)) /* UP */
3533 CONSOLE_NormalTextXY(8, Line
, 60, 1);
3542 CONSOLE_InvertTextXY(8, Line
, 60, 1);
3544 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
3545 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
3547 if (ConfirmQuit(Ir
) == TRUE
)
3552 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
3556 return BOOT_LOADER_HARDDISK_PAGE
;
3558 else if (Line
== 13)
3560 return BOOT_LOADER_FLOPPY_PAGE
;
3562 else if (Line
== 14)
3564 return SUCCESS_PAGE
;
3567 return BOOT_LOADER_PAGE
;
3571 return BOOT_LOADER_PAGE
;
3576 BootLoaderFloppyPage(PINPUT_RECORD Ir
)
3580 MUIDisplayPage(BOOT_LOADER_FLOPPY_PAGE
);
3582 // SetStatusText(" Please wait...");
3586 CONSOLE_ConInKey(Ir
);
3588 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
3589 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
3591 if (ConfirmQuit(Ir
) == TRUE
)
3596 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
3598 if (DoesFileExist(L
"\\Device\\Floppy0", L
"\\") == FALSE
)
3600 MUIDisplayError(ERROR_NO_FLOPPY
, Ir
, POPUP_WAIT_ENTER
);
3601 return BOOT_LOADER_FLOPPY_PAGE
;
3604 Status
= InstallFatBootcodeToFloppy(&SourceRootPath
, &DestinationArcPath
);
3605 if (!NT_SUCCESS(Status
))
3607 /* Print error message */
3608 return BOOT_LOADER_FLOPPY_PAGE
;
3611 return SUCCESS_PAGE
;
3615 return BOOT_LOADER_FLOPPY_PAGE
;
3620 BootLoaderHarddiskPage(PINPUT_RECORD Ir
)
3622 UCHAR PartitionType
;
3625 PartitionType
= PartitionList
->ActiveBootPartition
->
3626 PartInfo
[PartitionList
->ActiveBootPartitionNumber
].PartitionType
;
3627 if ((PartitionType
== PARTITION_FAT_12
) ||
3628 (PartitionType
== PARTITION_FAT_16
) ||
3629 (PartitionType
== PARTITION_HUGE
) ||
3630 (PartitionType
== PARTITION_XINT13
) ||
3631 (PartitionType
== PARTITION_FAT32
) ||
3632 (PartitionType
== PARTITION_FAT32_XINT13
))
3634 Status
= InstallFatBootcodeToPartition(&SystemRootPath
,
3636 &DestinationArcPath
,
3638 if (!NT_SUCCESS(Status
))
3640 MUIDisplayError(ERROR_INSTALL_BOOTCODE
, Ir
, POPUP_WAIT_ENTER
);
3644 return SUCCESS_PAGE
;
3648 MUIDisplayError(ERROR_WRITE_BOOT
, Ir
, POPUP_WAIT_ENTER
);
3652 return BOOT_LOADER_HARDDISK_PAGE
;
3657 QuitPage(PINPUT_RECORD Ir
)
3659 MUIDisplayPage(QUIT_PAGE
);
3661 /* Destroy partition list */
3662 if (PartitionList
!= NULL
)
3664 DestroyPartitionList (PartitionList
);
3665 PartitionList
= NULL
;
3668 /* Destroy filesystem list */
3669 if (FileSystemList
!= NULL
)
3671 DestroyFileSystemList (FileSystemList
);
3672 FileSystemList
= NULL
;
3675 /* Destroy computer settings list */
3676 if (ComputerList
!= NULL
)
3678 DestroyGenericList(ComputerList
, TRUE
);
3679 ComputerList
= NULL
;
3682 /* Destroy display settings list */
3683 if (DisplayList
!= NULL
)
3685 DestroyGenericList(DisplayList
, TRUE
);
3689 /* Destroy keyboard settings list */
3690 if (KeyboardList
!= NULL
)
3692 DestroyGenericList(KeyboardList
, TRUE
);
3693 KeyboardList
= NULL
;
3696 /* Destroy keyboard layout list */
3697 if (LayoutList
!= NULL
)
3699 DestroyGenericList(LayoutList
, TRUE
);
3703 if (LanguageList
!= NULL
)
3705 DestroyGenericList(LanguageList
, FALSE
);
3706 LanguageList
= NULL
;
3709 CONSOLE_SetStatusText(MUIGetString(STRING_REBOOTCOMPUTER2
));
3713 CONSOLE_ConInKey(Ir
);
3715 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
3724 SuccessPage(PINPUT_RECORD Ir
)
3726 MUIDisplayPage(SUCCESS_PAGE
);
3728 if (IsUnattendedSetup
)
3735 CONSOLE_ConInKey(Ir
);
3737 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
3746 FlushPage(PINPUT_RECORD Ir
)
3748 MUIDisplayPage(FLUSH_PAGE
);
3754 PnpEventThread(IN LPVOID lpParameter
);
3764 NtQuerySystemTime(&Time
);
3766 Status
= RtlCreateUserThread(NtCurrentProcess(),
3776 if (!NT_SUCCESS(Status
))
3777 hPnpThread
= INVALID_HANDLE_VALUE
;
3779 if (!CONSOLE_Init())
3781 PrintString(MUIGetString(STRING_CONSOLEFAIL1
));
3782 PrintString(MUIGetString(STRING_CONSOLEFAIL2
));
3783 PrintString(MUIGetString(STRING_CONSOLEFAIL3
));
3785 /* Raise a hard error (crash the system/BSOD) */
3786 NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED
,
3790 /* Initialize global unicode strings */
3791 RtlInitUnicodeString(&SourcePath
, NULL
);
3792 RtlInitUnicodeString(&SourceRootPath
, NULL
);
3793 RtlInitUnicodeString(&SourceRootDir
, NULL
);
3794 RtlInitUnicodeString(&InstallPath
, NULL
);
3795 RtlInitUnicodeString(&DestinationPath
, NULL
);
3796 RtlInitUnicodeString(&DestinationArcPath
, NULL
);
3797 RtlInitUnicodeString(&DestinationRootPath
, NULL
);
3798 RtlInitUnicodeString(&SystemRootPath
, NULL
);
3800 /* Hide the cursor */
3801 CONSOLE_SetCursorType(TRUE
, FALSE
);
3804 while (Page
!= REBOOT_PAGE
)
3806 CONSOLE_ClearScreen();
3809 //CONSOLE_SetUnderlinedTextXY(4, 3, " ReactOS " KERNEL_VERSION_STR " Setup ");
3816 Page
= SetupStartPage(&Ir
);
3821 Page
= LanguagePage(&Ir
);
3826 Page
= LicensePage(&Ir
);
3831 Page
= IntroPage(&Ir
);
3835 case INSTALL_INTRO_PAGE
:
3836 Page
= InstallIntroPage(&Ir
);
3840 case SCSI_CONTROLLER_PAGE
:
3841 Page
= ScsiControllerPage(&Ir
);
3846 case OEM_DRIVER_PAGE
:
3847 Page
= OemDriverPage(&Ir
);
3851 case DEVICE_SETTINGS_PAGE
:
3852 Page
= DeviceSettingsPage(&Ir
);
3855 case COMPUTER_SETTINGS_PAGE
:
3856 Page
= ComputerSettingsPage(&Ir
);
3859 case DISPLAY_SETTINGS_PAGE
:
3860 Page
= DisplaySettingsPage(&Ir
);
3863 case KEYBOARD_SETTINGS_PAGE
:
3864 Page
= KeyboardSettingsPage(&Ir
);
3867 case LAYOUT_SETTINGS_PAGE
:
3868 Page
= LayoutSettingsPage(&Ir
);
3871 case SELECT_PARTITION_PAGE
:
3872 Page
= SelectPartitionPage(&Ir
);
3875 case CREATE_PARTITION_PAGE
:
3876 Page
= CreatePartitionPage(&Ir
);
3879 case DELETE_PARTITION_PAGE
:
3880 Page
= DeletePartitionPage(&Ir
);
3883 case SELECT_FILE_SYSTEM_PAGE
:
3884 Page
= SelectFileSystemPage(&Ir
);
3887 case FORMAT_PARTITION_PAGE
:
3888 Page
= (PAGE_NUMBER
) FormatPartitionPage(&Ir
);
3891 case CHECK_FILE_SYSTEM_PAGE
:
3892 Page
= (PAGE_NUMBER
) CheckFileSystemPage(&Ir
);
3895 case INSTALL_DIRECTORY_PAGE
:
3896 Page
= InstallDirectoryPage(&Ir
);
3899 case PREPARE_COPY_PAGE
:
3900 Page
= PrepareCopyPage(&Ir
);
3903 case FILE_COPY_PAGE
:
3904 Page
= FileCopyPage(&Ir
);
3908 Page
= RegistryPage(&Ir
);
3911 case BOOT_LOADER_PAGE
:
3912 Page
= BootLoaderPage(&Ir
);
3915 case BOOT_LOADER_FLOPPY_PAGE
:
3916 Page
= BootLoaderFloppyPage(&Ir
);
3919 case BOOT_LOADER_HARDDISK_PAGE
:
3920 Page
= BootLoaderHarddiskPage(&Ir
);
3924 case REPAIR_INTRO_PAGE
:
3925 Page
= RepairIntroPage(&Ir
);
3929 Page
= SuccessPage(&Ir
);
3933 Page
= FlushPage(&Ir
);
3937 Page
= QuitPage(&Ir
);
3947 /* Avoid bugcheck */
3948 Time
.QuadPart
+= 50000000;
3949 NtDelayExecution(FALSE
, &Time
);
3952 NtShutdownSystem(ShutdownReboot
);
3953 NtTerminateProcess(NtCurrentProcess(), 0);
3960 NtProcessStartup(PPEB Peb
)
3962 RtlNormalizeProcessParams(Peb
->ProcessParameters
);
3964 ProcessHeap
= Peb
->ProcessHeap
;
3965 INF_SetHeap(ProcessHeap
);
3968 #endif /* __REACTOS__ */