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: base/setup/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)
42 /* GLOBALS ******************************************************************/
45 UNICODE_STRING SourceRootPath
;
46 UNICODE_STRING SourceRootDir
;
47 UNICODE_STRING SourcePath
;
48 BOOLEAN IsUnattendedSetup
= FALSE
;
49 LONG UnattendDestinationDiskNumber
;
50 LONG UnattendDestinationPartitionNumber
;
51 LONG UnattendMBRInstallType
= -1;
52 LONG UnattendFormatPartition
= 0;
53 LONG AutoPartition
= 0;
54 WCHAR UnattendInstallationDirectory
[MAX_PATH
];
55 PWCHAR SelectedLanguageId
;
57 WCHAR DefaultLanguage
[20];
58 WCHAR DefaultKBLayout
[20];
59 BOOLEAN RepairUpdateFlag
= FALSE
;
60 HANDLE hPnpThread
= INVALID_HANDLE_VALUE
;
61 PPARTLIST PartitionList
= NULL
;
63 /* LOCALS *******************************************************************/
65 static PFILE_SYSTEM_LIST FileSystemList
= NULL
;
67 static UNICODE_STRING InstallPath
;
70 * Path to the system partition, where the boot manager resides.
71 * On x86 PCs, this is usually the active partition.
72 * On ARC, (u)EFI, ... platforms, this is a dedicated partition.
74 * For more information, see:
75 * https://en.wikipedia.org/wiki/System_partition_and_boot_partition
76 * http://homepage.ntlworld.com/jonathan.deboynepollard/FGA/boot-and-system-volumes.html
77 * http://homepage.ntlworld.com/jonathan.deboynepollard/FGA/arc-boot-process.html
78 * http://homepage.ntlworld.com/jonathan.deboynepollard/FGA/efi-boot-process.html
79 * http://homepage.ntlworld.com/jonathan.deboynepollard/FGA/determining-system-volume.html
80 * http://homepage.ntlworld.com/jonathan.deboynepollard/FGA/determining-boot-volume.html
82 static UNICODE_STRING SystemRootPath
;
84 /* Path to the install directory inside the ReactOS boot partition */
85 static UNICODE_STRING DestinationPath
;
86 static UNICODE_STRING DestinationArcPath
;
87 static UNICODE_STRING DestinationRootPath
;
89 static WCHAR DestinationDriveLetter
;
93 static HSPFILEQ SetupFileQueue
= NULL
;
95 static PGENERIC_LIST ComputerList
= NULL
;
96 static PGENERIC_LIST DisplayList
= NULL
;
97 static PGENERIC_LIST KeyboardList
= NULL
;
98 static PGENERIC_LIST LayoutList
= NULL
;
99 static PGENERIC_LIST LanguageList
= NULL
;
101 static LANGID LanguageId
= 0;
103 static ULONG RequiredPartitionDiskSpace
= ~0;
105 /* FUNCTIONS ****************************************************************/
108 PrintString(char* fmt
,...)
112 UNICODE_STRING UnicodeString
;
113 ANSI_STRING AnsiString
;
116 vsprintf(buffer
, fmt
, ap
);
119 RtlInitAnsiString(&AnsiString
, buffer
);
120 RtlAnsiStringToUnicodeString(&UnicodeString
, &AnsiString
, TRUE
);
121 NtDisplayString(&UnicodeString
);
122 RtlFreeUnicodeString(&UnicodeString
);
127 DrawBox(IN SHORT xLeft
,
135 /* draw upper left corner */
138 FillConsoleOutputCharacterA(StdOutput
,
144 /* draw upper edge */
147 FillConsoleOutputCharacterA(StdOutput
,
153 /* draw upper right corner */
154 coPos
.X
= xLeft
+ Width
- 1;
156 FillConsoleOutputCharacterA(StdOutput
,
162 /* Draw right edge, inner space and left edge */
163 for (coPos
.Y
= yTop
+ 1; coPos
.Y
< yTop
+ Height
- 1; coPos
.Y
++)
166 FillConsoleOutputCharacterA(StdOutput
,
173 FillConsoleOutputCharacterA(StdOutput
,
179 coPos
.X
= xLeft
+ Width
- 1;
180 FillConsoleOutputCharacterA(StdOutput
,
187 /* draw lower left corner */
189 coPos
.Y
= yTop
+ Height
- 1;
190 FillConsoleOutputCharacterA(StdOutput
,
196 /* draw lower edge */
198 coPos
.Y
= yTop
+ Height
- 1;
199 FillConsoleOutputCharacterA(StdOutput
,
205 /* draw lower right corner */
206 coPos
.X
= xLeft
+ Width
- 1;
207 coPos
.Y
= yTop
+ Height
- 1;
208 FillConsoleOutputCharacterA(StdOutput
,
217 PopupError(PCCH Text
,
235 /* Count text lines and longest line */
242 p
= strchr(pnext
, '\n');
246 Length
= strlen(pnext
);
251 Length
= (ULONG
)(p
- pnext
);
257 if (Length
> MaxLength
)
260 if (LastLine
!= FALSE
)
266 /* Check length of status line */
269 Length
= strlen(Status
);
271 if (Length
> MaxLength
)
275 Width
= MaxLength
+ 4;
281 yTop
= (yScreen
- Height
) / 2;
282 xLeft
= (xScreen
- Width
) / 2;
285 /* Set screen attributes */
287 for (coPos
.Y
= yTop
; coPos
.Y
< yTop
+ Height
; coPos
.Y
++)
289 FillConsoleOutputAttribute(StdOutput
,
290 FOREGROUND_RED
| BACKGROUND_WHITE
,
296 DrawBox(xLeft
, yTop
, Width
, Height
);
298 /* Print message text */
303 p
= strchr(pnext
, '\n');
307 Length
= strlen(pnext
);
312 Length
= (ULONG
)(p
- pnext
);
319 WriteConsoleOutputCharacterA(StdOutput
,
326 if (LastLine
!= FALSE
)
333 /* Print separator line and status text */
336 coPos
.Y
= yTop
+ Height
- 3;
338 FillConsoleOutputCharacterA(StdOutput
,
345 FillConsoleOutputCharacterA(StdOutput
,
351 coPos
.X
= xLeft
+ Width
- 1;
352 FillConsoleOutputCharacterA(StdOutput
,
360 WriteConsoleOutputCharacterA(StdOutput
,
362 min(strlen(Status
), (SIZE_T
)Width
- 4),
367 if (WaitEvent
== POPUP_WAIT_NONE
)
372 CONSOLE_ConInKey(Ir
);
374 if (WaitEvent
== POPUP_WAIT_ANY_KEY
||
375 Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D)
387 * FALSE: Don't quit setup.
390 ConfirmQuit(PINPUT_RECORD Ir
)
393 MUIDisplayError(ERROR_NOT_INSTALLED
, NULL
, POPUP_WAIT_NONE
);
397 CONSOLE_ConInKey(Ir
);
399 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
400 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
405 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
417 CheckUnattendedSetup(VOID
)
419 WCHAR UnattendInfPath
[MAX_PATH
];
426 if (DoesFileExist(SourcePath
.Buffer
, L
"unattend.inf") == FALSE
)
428 DPRINT("Does not exist: %S\\%S\n", SourcePath
.Buffer
, L
"unattend.inf");
432 wcscpy(UnattendInfPath
, SourcePath
.Buffer
);
433 wcscat(UnattendInfPath
, L
"\\unattend.inf");
435 /* Load 'unattend.inf' from install media. */
436 UnattendInf
= SetupOpenInfFileW(UnattendInfPath
,
442 if (UnattendInf
== INVALID_HANDLE_VALUE
)
444 DPRINT("SetupOpenInfFileW() failed\n");
448 /* Open 'Unattend' section */
449 if (!SetupFindFirstLineW(UnattendInf
, L
"Unattend", L
"Signature", &Context
))
451 DPRINT("SetupFindFirstLineW() failed for section 'Unattend'\n");
452 SetupCloseInfFile(UnattendInf
);
456 /* Get pointer 'Signature' key */
457 if (!INF_GetData(&Context
, NULL
, &Value
))
459 DPRINT("INF_GetData() failed for key 'Signature'\n");
460 SetupCloseInfFile(UnattendInf
);
464 /* Check 'Signature' string */
465 if (_wcsicmp(Value
, L
"$ReactOS$") != 0)
467 DPRINT("Signature not $ReactOS$\n");
468 SetupCloseInfFile(UnattendInf
);
472 /* Check if Unattend setup is enabled */
473 if (!SetupFindFirstLineW(UnattendInf
, L
"Unattend", L
"UnattendSetupEnabled", &Context
))
475 DPRINT("Can't find key 'UnattendSetupEnabled'\n");
476 SetupCloseInfFile(UnattendInf
);
480 if (!INF_GetData(&Context
, NULL
, &Value
))
482 DPRINT("Can't read key 'UnattendSetupEnabled'\n");
483 SetupCloseInfFile(UnattendInf
);
487 if (_wcsicmp(Value
, L
"yes") != 0)
489 DPRINT("Unattend setup is disabled by 'UnattendSetupEnabled' key!\n");
490 SetupCloseInfFile(UnattendInf
);
494 /* Search for 'DestinationDiskNumber' in the 'Unattend' section */
495 if (!SetupFindFirstLineW(UnattendInf
, L
"Unattend", L
"DestinationDiskNumber", &Context
))
497 DPRINT("SetupFindFirstLine() failed for key 'DestinationDiskNumber'\n");
498 SetupCloseInfFile(UnattendInf
);
502 if (!SetupGetIntField(&Context
, 1, &IntValue
))
504 DPRINT("SetupGetIntField() failed for key 'DestinationDiskNumber'\n");
505 SetupCloseInfFile(UnattendInf
);
509 UnattendDestinationDiskNumber
= (LONG
)IntValue
;
511 /* Search for 'DestinationPartitionNumber' in the 'Unattend' section */
512 if (!SetupFindFirstLineW(UnattendInf
, L
"Unattend", L
"DestinationPartitionNumber", &Context
))
514 DPRINT("SetupFindFirstLine() failed for key 'DestinationPartitionNumber'\n");
515 SetupCloseInfFile(UnattendInf
);
519 if (!SetupGetIntField(&Context
, 1, &IntValue
))
521 DPRINT("SetupGetIntField() failed for key 'DestinationPartitionNumber'\n");
522 SetupCloseInfFile(UnattendInf
);
526 UnattendDestinationPartitionNumber
= IntValue
;
528 /* Search for 'InstallationDirectory' in the 'Unattend' section */
529 if (!SetupFindFirstLineW(UnattendInf
, L
"Unattend", L
"InstallationDirectory", &Context
))
531 DPRINT("SetupFindFirstLine() failed for key 'InstallationDirectory'\n");
532 SetupCloseInfFile(UnattendInf
);
536 /* Get pointer 'InstallationDirectory' key */
537 if (!INF_GetData(&Context
, NULL
, &Value
))
539 DPRINT("INF_GetData() failed for key 'InstallationDirectory'\n");
540 SetupCloseInfFile(UnattendInf
);
544 wcscpy(UnattendInstallationDirectory
, Value
);
546 IsUnattendedSetup
= TRUE
;
548 /* Search for 'MBRInstallType' in the 'Unattend' section */
549 if (SetupFindFirstLineW(UnattendInf
, L
"Unattend", L
"MBRInstallType", &Context
))
551 if (SetupGetIntField(&Context
, 1, &IntValue
))
553 UnattendMBRInstallType
= IntValue
;
557 /* Search for 'FormatPartition' in the 'Unattend' section */
558 if (SetupFindFirstLineW(UnattendInf
, L
"Unattend", L
"FormatPartition", &Context
))
560 if (SetupGetIntField(&Context
, 1, &IntValue
))
562 UnattendFormatPartition
= IntValue
;
566 if (SetupFindFirstLineW(UnattendInf
, L
"Unattend", L
"AutoPartition", &Context
))
568 if (SetupGetIntField(&Context
, 1, &IntValue
))
570 AutoPartition
= IntValue
;
574 /* search for LocaleID in the 'Unattend' section*/
575 if (SetupFindFirstLineW(UnattendInf
, L
"Unattend", L
"LocaleID", &Context
))
577 if (INF_GetData(&Context
, NULL
, &Value
))
579 LONG Id
= wcstol(Value
, NULL
, 16);
580 swprintf(LocaleID
,L
"%08lx", Id
);
584 SetupCloseInfFile(UnattendInf
);
586 DPRINT("Running unattended setup\n");
593 PGENERIC_LIST_ENTRY ListEntry
;
594 LPCWSTR pszNewLayout
;
596 pszNewLayout
= MUIDefaultKeyboardLayout();
598 if (LayoutList
== NULL
)
600 LayoutList
= CreateKeyboardLayoutList(SetupInf
, DefaultKBLayout
);
601 if (LayoutList
== NULL
)
603 /* FIXME: Handle error! */
608 ListEntry
= GetFirstListEntry(LayoutList
);
610 /* Search for default layout (if provided) */
611 if (pszNewLayout
!= NULL
)
613 while (ListEntry
!= NULL
)
615 if (!wcscmp(pszNewLayout
, GetListEntryUserData(ListEntry
)))
617 SetCurrentListEntry(LayoutList
, ListEntry
);
621 ListEntry
= GetNextListEntry(ListEntry
);
628 * Displays the LanguagePage.
630 * Next pages: IntroPage, QuitPage
633 * Init SelectedLanguageId
637 * Number of the next page.
640 LanguagePage(PINPUT_RECORD Ir
)
642 PWCHAR NewLanguageId
;
643 BOOL RefreshPage
= FALSE
;
645 /* Initialize the computer settings list */
646 if (LanguageList
== NULL
)
648 LanguageList
= CreateLanguageList(SetupInf
, DefaultLanguage
);
650 if (LanguageList
== NULL
)
652 PopupError("Setup failed to initialize available translations", NULL
, NULL
, POPUP_WAIT_NONE
);
658 SelectedLanguageId
= DefaultLanguage
;
659 SetConsoleCodePage();
662 /* If there's just a single language in the list skip
663 * the language selection process altogether! */
664 if (GenericListHasSingleEntry(LanguageList
))
666 LanguageId
= (LANGID
)(wcstol(SelectedLanguageId
, NULL
, 16) & 0xFFFF);
670 DrawGenericList(LanguageList
,
676 ScrollToPositionGenericList(LanguageList
, GetDefaultLanguageIndex());
678 MUIDisplayPage(LANGUAGE_PAGE
);
682 CONSOLE_ConInKey(Ir
);
684 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
685 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
)) /* DOWN */
687 ScrollDownGenericList(LanguageList
);
690 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
691 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_UP
)) /* UP */
693 ScrollUpGenericList(LanguageList
);
696 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
697 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_NEXT
)) /* PAGE DOWN */
699 ScrollPageDownGenericList(LanguageList
);
702 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
703 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_PRIOR
)) /* PAGE UP */
705 ScrollPageUpGenericList(LanguageList
);
708 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
709 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
711 if (ConfirmQuit(Ir
) != FALSE
)
714 RedrawGenericList(LanguageList
);
716 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
718 SelectedLanguageId
= (PWCHAR
)GetListEntryUserData(GetCurrentListEntry(LanguageList
));
720 LanguageId
= (LANGID
)(wcstol(SelectedLanguageId
, NULL
, 16) & 0xFFFF);
722 if (wcscmp(SelectedLanguageId
, DefaultLanguage
))
728 SetConsoleCodePage();
732 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
> 0x60) && (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
< 0x7b))
735 GenericListKeyPress(LanguageList
, Ir
->Event
.KeyEvent
.uChar
.AsciiChar
);
741 NewLanguageId
= (PWCHAR
)GetListEntryUserData(GetCurrentListEntry(LanguageList
));
743 if (SelectedLanguageId
!= NewLanguageId
)
745 /* Clear the language page */
746 MUIClearPage(LANGUAGE_PAGE
);
748 SelectedLanguageId
= NewLanguageId
;
751 SetConsoleCodePage();
753 /* Redraw language selection page in native language */
754 MUIDisplayPage(LANGUAGE_PAGE
);
769 * LanguagePage (at once, default)
770 * InstallIntroPage (at once, if unattended)
776 * Init SourceRootPath
779 * Init RequiredPartitionDiskSpace
780 * Init IsUnattendedSetup
781 * If unattended, init *List and sets the Codepage
782 * If unattended, init SelectedLanguageId
783 * If unattended, init LanguageId
786 * Number of the next page.
789 SetupStartPage(PINPUT_RECORD Ir
)
791 //SYSTEM_DEVICE_INFORMATION Sdi;
793 WCHAR FileNameBuffer
[MAX_PATH
];
798 PGENERIC_LIST_ENTRY ListEntry
;
801 CONSOLE_SetStatusText(MUIGetString(STRING_PLEASEWAIT
));
804 /* Check whether a harddisk is available */
805 Status
= NtQuerySystemInformation(SystemDeviceInformation
,
807 sizeof(SYSTEM_DEVICE_INFORMATION
),
810 if (!NT_SUCCESS(Status
))
812 CONSOLE_PrintTextXY(6, 15, "NtQuerySystemInformation() failed (Status 0x%08lx)", Status
);
813 MUIDisplayError(ERROR_DRIVE_INFORMATION
, Ir
, POPUP_WAIT_ENTER
);
817 if (Sdi
.NumberOfDisks
== 0)
819 MUIDisplayError(ERROR_NO_HDD
, Ir
, POPUP_WAIT_ENTER
);
824 /* Get the source path and source root path */
825 Status
= GetSourcePaths(&SourcePath
,
829 if (!NT_SUCCESS(Status
))
831 CONSOLE_PrintTextXY(6, 15, "GetSourcePaths() failed (Status 0x%08lx)", Status
);
832 MUIDisplayError(ERROR_NO_SOURCE_DRIVE
, Ir
, POPUP_WAIT_ENTER
);
838 CONSOLE_PrintTextXY(6, 15, "SourcePath: '%wZ'", &SourcePath
);
839 CONSOLE_PrintTextXY(6, 16, "SourceRootPath: '%wZ'", &SourceRootPath
);
840 CONSOLE_PrintTextXY(6, 17, "SourceRootDir: '%wZ'", &SourceRootDir
);
844 /* Load txtsetup.sif from install media. */
845 wcscpy(FileNameBuffer
, SourcePath
.Buffer
);
846 wcscat(FileNameBuffer
, L
"\\txtsetup.sif");
848 SetupInf
= SetupOpenInfFileW(FileNameBuffer
,
854 if (SetupInf
== INVALID_HANDLE_VALUE
)
856 MUIDisplayError(ERROR_LOAD_TXTSETUPSIF
, Ir
, POPUP_WAIT_ENTER
);
860 /* Open 'Version' section */
861 if (!SetupFindFirstLineW(SetupInf
, L
"Version", L
"Signature", &Context
))
863 MUIDisplayError(ERROR_CORRUPT_TXTSETUPSIF
, Ir
, POPUP_WAIT_ENTER
);
867 /* Get pointer 'Signature' key */
868 if (!INF_GetData(&Context
, NULL
, &Value
))
870 MUIDisplayError(ERROR_CORRUPT_TXTSETUPSIF
, Ir
, POPUP_WAIT_ENTER
);
874 /* Check 'Signature' string */
875 if (_wcsicmp(Value
, L
"$ReactOS$") != 0)
877 MUIDisplayError(ERROR_SIGNATURE_TXTSETUPSIF
, Ir
, POPUP_WAIT_ENTER
);
881 /* Open 'DiskSpaceRequirements' section */
882 if (!SetupFindFirstLineW(SetupInf
, L
"DiskSpaceRequirements", L
"FreeSysPartDiskSpace", &Context
))
884 MUIDisplayError(ERROR_CORRUPT_TXTSETUPSIF
, Ir
, POPUP_WAIT_ENTER
);
888 /* Get the 'FreeSysPartDiskSpace' value */
889 if (!SetupGetIntField(&Context
, 1, &IntValue
))
891 MUIDisplayError(ERROR_CORRUPT_TXTSETUPSIF
, Ir
, POPUP_WAIT_ENTER
);
895 RequiredPartitionDiskSpace
= (ULONG
)IntValue
;
897 /* Start PnP thread */
898 if (hPnpThread
!= INVALID_HANDLE_VALUE
)
900 NtResumeThread(hPnpThread
, NULL
);
901 hPnpThread
= INVALID_HANDLE_VALUE
;
904 CheckUnattendedSetup();
906 if (IsUnattendedSetup
)
909 //read options from inf
910 ComputerList
= CreateComputerTypeList(SetupInf
);
911 DisplayList
= CreateDisplayDriverList(SetupInf
);
912 KeyboardList
= CreateKeyboardDriverList(SetupInf
);
913 LayoutList
= CreateKeyboardLayoutList(SetupInf
, DefaultKBLayout
);
914 LanguageList
= CreateLanguageList(SetupInf
, DefaultLanguage
);
917 wcscpy(SelectedLanguageId
,LocaleID
);
918 LanguageId
= (LANGID
)(wcstol(SelectedLanguageId
, NULL
, 16) & 0xFFFF);
920 /* first we hack LanguageList */
921 ListEntry
= GetFirstListEntry(LanguageList
);
923 while (ListEntry
!= NULL
)
925 if (!wcsicmp(LocaleID
, GetListEntryUserData(ListEntry
)))
927 DPRINT("found %S in LanguageList\n",GetListEntryUserData(ListEntry
));
928 SetCurrentListEntry(LanguageList
, ListEntry
);
932 ListEntry
= GetNextListEntry(ListEntry
);
936 ListEntry
= GetFirstListEntry(LayoutList
);
938 while (ListEntry
!= NULL
)
940 if (!wcsicmp(LocaleID
, GetListEntryUserData(ListEntry
)))
942 DPRINT("found %S in LayoutList\n",GetListEntryUserData(ListEntry
));
943 SetCurrentListEntry(LayoutList
, ListEntry
);
947 ListEntry
= GetNextListEntry(ListEntry
);
950 SetConsoleCodePage();
952 return INSTALL_INTRO_PAGE
;
955 return LANGUAGE_PAGE
;
960 * Displays the IntroPage.
963 * InstallIntroPage (default)
969 * Number of the next page.
972 IntroPage(PINPUT_RECORD Ir
)
974 MUIDisplayPage(START_PAGE
);
978 CONSOLE_ConInKey(Ir
);
980 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
981 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
983 if (ConfirmQuit(Ir
) != FALSE
)
988 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
990 return INSTALL_INTRO_PAGE
;
992 else if (toupper(Ir
->Event
.KeyEvent
.uChar
.AsciiChar
) == 'R') /* R */
994 return REPAIR_INTRO_PAGE
;
996 else if (toupper(Ir
->Event
.KeyEvent
.uChar
.AsciiChar
) == 'L') /* R */
1007 * Displays the License page.
1010 * IntroPage (default)
1013 * Number of the next page.
1016 LicensePage(PINPUT_RECORD Ir
)
1018 MUIDisplayPage(LICENSE_PAGE
);
1022 CONSOLE_ConInKey(Ir
);
1024 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
1030 return LICENSE_PAGE
;
1035 * Displays the RepairIntroPage.
1038 * RebootPage (default)
1044 * Number of the next page.
1047 RepairIntroPage(PINPUT_RECORD Ir
)
1049 MUIDisplayPage(REPAIR_INTRO_PAGE
);
1053 CONSOLE_ConInKey(Ir
);
1055 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
1059 else if (toupper(Ir
->Event
.KeyEvent
.uChar
.AsciiChar
) == 'U') /* U */
1061 RepairUpdateFlag
= TRUE
;
1062 return INSTALL_INTRO_PAGE
;
1064 else if (toupper(Ir
->Event
.KeyEvent
.uChar
.AsciiChar
) == 'R') /* R */
1066 return RECOVERY_PAGE
;
1068 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1069 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
)) /* ESC */
1075 return REPAIR_INTRO_PAGE
;
1079 * Displays the InstallIntroPage.
1082 * DeviceSettingsPage (At once if repair or update is selected)
1083 * SelectPartitionPage (At once if unattended setup)
1084 * DeviceSettingsPage (default)
1088 * Number of the next page.
1091 InstallIntroPage(PINPUT_RECORD Ir
)
1093 MUIDisplayPage(INSTALL_INTRO_PAGE
);
1095 if (RepairUpdateFlag
)
1097 //return SELECT_PARTITION_PAGE;
1098 return DEVICE_SETTINGS_PAGE
;
1101 if (IsUnattendedSetup
)
1103 return SELECT_PARTITION_PAGE
;
1108 CONSOLE_ConInKey(Ir
);
1110 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1111 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1113 if (ConfirmQuit(Ir
) != FALSE
)
1118 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
1120 return DEVICE_SETTINGS_PAGE
;
1121 // return SCSI_CONTROLLER_PAGE;
1125 return INSTALL_INTRO_PAGE
;
1131 ScsiControllerPage(PINPUT_RECORD Ir
)
1133 SetTextXY(6, 8, "Setup detected the following mass storage devices:");
1135 /* FIXME: print loaded mass storage driver descriptions */
1137 SetTextXY(8, 10, "TEST device");
1141 SetStatusText(" ENTER = Continue F3 = Quit");
1147 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1148 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1150 if (ConfirmQuit(Ir
) != FALSE
)
1155 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
1157 return DEVICE_SETTINGS_PAGE
;
1161 return SCSI_CONTROLLER_PAGE
;
1167 * Displays the DeviceSettingsPage.
1170 * SelectPartitionPage (At once if repair or update is selected)
1171 * ComputerSettingsPage
1172 * DisplaySettingsPage
1173 * KeyboardSettingsPage
1174 * LayoutsettingsPage
1175 * SelectPartitionPage
1185 * Number of the next page.
1188 DeviceSettingsPage(PINPUT_RECORD Ir
)
1190 static ULONG Line
= 16;
1191 MUIDisplayPage(DEVICE_SETTINGS_PAGE
);
1193 /* Initialize the computer settings list */
1194 if (ComputerList
== NULL
)
1196 ComputerList
= CreateComputerTypeList(SetupInf
);
1197 if (ComputerList
== NULL
)
1199 MUIDisplayError(ERROR_LOAD_COMPUTER
, Ir
, POPUP_WAIT_ENTER
);
1204 /* Initialize the display settings list */
1205 if (DisplayList
== NULL
)
1207 DisplayList
= CreateDisplayDriverList(SetupInf
);
1208 if (DisplayList
== NULL
)
1210 MUIDisplayError(ERROR_LOAD_DISPLAY
, Ir
, POPUP_WAIT_ENTER
);
1215 /* Initialize the keyboard settings list */
1216 if (KeyboardList
== NULL
)
1218 KeyboardList
= CreateKeyboardDriverList(SetupInf
);
1219 if (KeyboardList
== NULL
)
1221 MUIDisplayError(ERROR_LOAD_KEYBOARD
, Ir
, POPUP_WAIT_ENTER
);
1226 /* Initialize the keyboard layout list */
1227 if (LayoutList
== NULL
)
1229 LayoutList
= CreateKeyboardLayoutList(SetupInf
, DefaultKBLayout
);
1230 if (LayoutList
== NULL
)
1232 /* FIXME: report error */
1233 MUIDisplayError(ERROR_LOAD_KBLAYOUT
, Ir
, POPUP_WAIT_ENTER
);
1238 MUIDisplayPage(DEVICE_SETTINGS_PAGE
);
1241 CONSOLE_SetTextXY(25, 11, GetListEntryText(GetCurrentListEntry((ComputerList
))));
1242 CONSOLE_SetTextXY(25, 12, GetListEntryText(GetCurrentListEntry((DisplayList
))));
1243 CONSOLE_SetTextXY(25, 13, GetListEntryText(GetCurrentListEntry((KeyboardList
))));
1244 CONSOLE_SetTextXY(25, 14, GetListEntryText(GetCurrentListEntry((LayoutList
))));
1246 CONSOLE_InvertTextXY(24, Line
, 48, 1);
1248 if (RepairUpdateFlag
)
1250 return SELECT_PARTITION_PAGE
;
1255 CONSOLE_ConInKey(Ir
);
1257 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1258 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
)) /* DOWN */
1260 CONSOLE_NormalTextXY(24, Line
, 48, 1);
1264 else if (Line
== 16)
1269 CONSOLE_InvertTextXY(24, Line
, 48, 1);
1271 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1272 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_UP
)) /* UP */
1274 CONSOLE_NormalTextXY(24, Line
, 48, 1);
1278 else if (Line
== 16)
1283 CONSOLE_InvertTextXY(24, Line
, 48, 1);
1285 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1286 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1288 if (ConfirmQuit(Ir
) != FALSE
)
1293 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
1296 return COMPUTER_SETTINGS_PAGE
;
1297 else if (Line
== 12)
1298 return DISPLAY_SETTINGS_PAGE
;
1299 else if (Line
== 13)
1300 return KEYBOARD_SETTINGS_PAGE
;
1301 else if (Line
== 14)
1302 return LAYOUT_SETTINGS_PAGE
;
1303 else if (Line
== 16)
1304 return SELECT_PARTITION_PAGE
;
1308 return DEVICE_SETTINGS_PAGE
;
1313 * Handles generic selection lists.
1316 * GenericList: The list to handle.
1317 * nextPage: The page it needs to jump to after this page.
1318 * Ir: The PINPUT_RECORD
1321 HandleGenericList(PGENERIC_LIST GenericList
,
1322 PAGE_NUMBER nextPage
,
1327 CONSOLE_ConInKey(Ir
);
1329 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1330 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
)) /* DOWN */
1332 ScrollDownGenericList(GenericList
);
1334 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1335 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_UP
)) /* UP */
1337 ScrollUpGenericList(GenericList
);
1339 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1340 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_NEXT
)) /* PAGE DOWN */
1342 ScrollPageDownGenericList(GenericList
);
1344 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1345 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_PRIOR
)) /* PAGE UP */
1347 ScrollPageUpGenericList(GenericList
);
1349 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1350 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1352 if (ConfirmQuit(Ir
) != FALSE
)
1357 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1358 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
)) /* ESC */
1360 RestoreGenericListState(GenericList
);
1363 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
1367 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
> 0x60) && (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
< 0x7b))
1370 GenericListKeyPress(GenericList
, Ir
->Event
.KeyEvent
.uChar
.AsciiChar
);
1377 * Displays the ComputerSettingsPage.
1380 * DeviceSettingsPage
1384 * Number of the next page.
1387 ComputerSettingsPage(PINPUT_RECORD Ir
)
1389 MUIDisplayPage(COMPUTER_SETTINGS_PAGE
);
1391 DrawGenericList(ComputerList
,
1397 SaveGenericListState(ComputerList
);
1399 return HandleGenericList(ComputerList
, DEVICE_SETTINGS_PAGE
, Ir
);
1404 * Displays the DisplaySettingsPage.
1407 * DeviceSettingsPage
1411 * Number of the next page.
1414 DisplaySettingsPage(PINPUT_RECORD Ir
)
1416 MUIDisplayPage(DISPLAY_SETTINGS_PAGE
);
1418 DrawGenericList(DisplayList
,
1424 SaveGenericListState(DisplayList
);
1426 return HandleGenericList(DisplayList
, DEVICE_SETTINGS_PAGE
, Ir
);
1431 * Displays the KeyboardSettingsPage.
1434 * DeviceSettingsPage
1438 * Number of the next page.
1441 KeyboardSettingsPage(PINPUT_RECORD Ir
)
1443 MUIDisplayPage(KEYBOARD_SETTINGS_PAGE
);
1445 DrawGenericList(KeyboardList
,
1451 SaveGenericListState(KeyboardList
);
1453 return HandleGenericList(KeyboardList
, DEVICE_SETTINGS_PAGE
, Ir
);
1458 * Displays the LayoutSettingsPage.
1461 * DeviceSettingsPage
1465 * Number of the next page.
1468 LayoutSettingsPage(PINPUT_RECORD Ir
)
1470 MUIDisplayPage(LAYOUT_SETTINGS_PAGE
);
1472 DrawGenericList(LayoutList
,
1478 SaveGenericListState(LayoutList
);
1480 return HandleGenericList(LayoutList
, DEVICE_SETTINGS_PAGE
, Ir
);
1485 IsDiskSizeValid(PPARTENTRY PartEntry
)
1489 size
= PartEntry
->SectorCount
.QuadPart
* PartEntry
->DiskEntry
->BytesPerSector
;
1490 size
= (size
+ 524288) / 1048576; /* in MBytes */
1492 if (size
< RequiredPartitionDiskSpace
)
1494 /* partition is too small so ask for another partition */
1495 DPRINT1("Partition is too small (size: %I64u MB), required disk space is %lu MB\n", size
, RequiredPartitionDiskSpace
);
1506 * Displays the SelectPartitionPage.
1509 * SelectFileSystemPage (At once if unattended)
1510 * SelectFileSystemPage (Default if free space is selected)
1511 * CreatePrimaryPartitionPage
1512 * CreateExtendedPartitionPage
1513 * CreateLogicalPartitionPage
1514 * ConfirmDeleteSystemPartitionPage (if the selected partition is the system partition, aka with the boot flag set)
1515 * DeletePartitionPage
1519 * Init DestinationDriveLetter (only if unattended or not free space is selected)
1520 * Set InstallShortcut (only if not unattended + free space is selected)
1523 * Number of the next page.
1526 SelectPartitionPage(PINPUT_RECORD Ir
)
1530 MUIDisplayPage(SELECT_PARTITION_PAGE
);
1532 if (PartitionList
== NULL
)
1534 PartitionList
= CreatePartitionList(2,
1538 if (PartitionList
== NULL
)
1540 /* FIXME: show an error dialog */
1543 else if (IsListEmpty(&PartitionList
->DiskListHead
))
1545 MUIDisplayError(ERROR_NO_HDD
, Ir
, POPUP_WAIT_ENTER
);
1550 DrawPartitionList(PartitionList
);
1552 if (IsUnattendedSetup
)
1554 if (!SelectPartition(PartitionList
, UnattendDestinationDiskNumber
, UnattendDestinationPartitionNumber
))
1558 if (PartitionList
->CurrentPartition
->LogicalPartition
)
1560 CreateLogicalPartition(PartitionList
,
1561 PartitionList
->CurrentPartition
->SectorCount
.QuadPart
,
1566 CreatePrimaryPartition(PartitionList
,
1567 PartitionList
->CurrentPartition
->SectorCount
.QuadPart
,
1571 if (!IsDiskSizeValid(PartitionList
->CurrentPartition
))
1573 MUIDisplayError(ERROR_INSUFFICIENT_PARTITION_SIZE
, Ir
, POPUP_WAIT_ANY_KEY
,
1574 RequiredPartitionDiskSpace
);
1575 return SELECT_PARTITION_PAGE
; /* let the user select another partition */
1578 DestinationDriveLetter
= (WCHAR
)PartitionList
->CurrentPartition
->DriveLetter
;
1580 return SELECT_FILE_SYSTEM_PAGE
;
1585 if (!IsDiskSizeValid(PartitionList
->CurrentPartition
))
1587 MUIDisplayError(ERROR_INSUFFICIENT_PARTITION_SIZE
, Ir
, POPUP_WAIT_ANY_KEY
,
1588 RequiredPartitionDiskSpace
);
1589 return SELECT_PARTITION_PAGE
; /* let the user select another partition */
1592 DestinationDriveLetter
= (WCHAR
)PartitionList
->CurrentPartition
->DriveLetter
;
1594 return SELECT_FILE_SYSTEM_PAGE
;
1600 /* Update status text */
1601 if (PartitionList
->CurrentPartition
== NULL
)
1603 CONSOLE_SetStatusText(MUIGetString(STRING_INSTALLCREATEPARTITION
));
1605 else if (PartitionList
->CurrentPartition
->LogicalPartition
)
1607 if (PartitionList
->CurrentPartition
->IsPartitioned
)
1609 CONSOLE_SetStatusText(MUIGetString(STRING_DELETEPARTITION
));
1613 CONSOLE_SetStatusText(MUIGetString(STRING_INSTALLCREATELOGICAL
));
1618 if (PartitionList
->CurrentPartition
->IsPartitioned
)
1620 if (IsContainerPartition(PartitionList
->CurrentPartition
->PartitionType
))
1622 CONSOLE_SetStatusText(MUIGetString(STRING_DELETEPARTITION
));
1626 CONSOLE_SetStatusText(MUIGetString(STRING_INSTALLDELETEPARTITION
));
1631 CONSOLE_SetStatusText(MUIGetString(STRING_INSTALLCREATEPARTITION
));
1635 CONSOLE_ConInKey(Ir
);
1637 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1638 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1640 if (ConfirmQuit(Ir
) != FALSE
)
1642 DestroyPartitionList(PartitionList
);
1643 PartitionList
= NULL
;
1649 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1650 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
)) /* DOWN */
1652 if (ScrollDownPartitionList(PartitionList
))
1653 DrawPartitionList(PartitionList
);
1655 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1656 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_UP
)) /* UP */
1658 if (ScrollUpPartitionList(PartitionList
))
1659 DrawPartitionList(PartitionList
);
1661 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_RETURN
) /* ENTER */
1663 if (IsContainerPartition(PartitionList
->CurrentPartition
->PartitionType
))
1664 continue; //return SELECT_PARTITION_PAGE;
1666 if (PartitionList
->CurrentPartition
== NULL
||
1667 PartitionList
->CurrentPartition
->IsPartitioned
== FALSE
)
1669 if (PartitionList
->CurrentPartition
->LogicalPartition
)
1671 CreateLogicalPartition(PartitionList
,
1677 CreatePrimaryPartition(PartitionList
,
1683 if (!IsDiskSizeValid(PartitionList
->CurrentPartition
))
1685 MUIDisplayError(ERROR_INSUFFICIENT_PARTITION_SIZE
, Ir
, POPUP_WAIT_ANY_KEY
,
1686 RequiredPartitionDiskSpace
);
1687 return SELECT_PARTITION_PAGE
; /* let the user select another partition */
1690 DestinationDriveLetter
= (WCHAR
)PartitionList
->CurrentPartition
->DriveLetter
;
1692 return SELECT_FILE_SYSTEM_PAGE
;
1694 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== 'P') /* P */
1696 if (PartitionList
->CurrentPartition
->LogicalPartition
== FALSE
)
1698 Error
= PrimaryPartitionCreationChecks(PartitionList
);
1699 if (Error
!= NOT_AN_ERROR
)
1701 MUIDisplayError(Error
, Ir
, POPUP_WAIT_ANY_KEY
);
1702 return SELECT_PARTITION_PAGE
;
1705 return CREATE_PRIMARY_PARTITION_PAGE
;
1708 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== 'E') /* E */
1710 if (PartitionList
->CurrentPartition
->LogicalPartition
== FALSE
)
1712 Error
= ExtendedPartitionCreationChecks(PartitionList
);
1713 if (Error
!= NOT_AN_ERROR
)
1715 MUIDisplayError(Error
, Ir
, POPUP_WAIT_ANY_KEY
);
1716 return SELECT_PARTITION_PAGE
;
1719 return CREATE_EXTENDED_PARTITION_PAGE
;
1722 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== 'L') /* L */
1724 if (PartitionList
->CurrentPartition
->LogicalPartition
!= FALSE
)
1726 Error
= LogicalPartitionCreationChecks(PartitionList
);
1727 if (Error
!= NOT_AN_ERROR
)
1729 MUIDisplayError(Error
, Ir
, POPUP_WAIT_ANY_KEY
);
1730 return SELECT_PARTITION_PAGE
;
1733 return CREATE_LOGICAL_PARTITION_PAGE
;
1736 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== 'D') /* D */
1738 if (PartitionList
->CurrentPartition
->IsPartitioned
== FALSE
)
1740 MUIDisplayError(ERROR_DELETE_SPACE
, Ir
, POPUP_WAIT_ANY_KEY
);
1741 return SELECT_PARTITION_PAGE
;
1744 if (PartitionList
->CurrentPartition
->BootIndicator
||
1745 PartitionList
->CurrentPartition
== PartitionList
->SystemPartition
)
1747 return CONFIRM_DELETE_SYSTEM_PARTITION_PAGE
;
1750 return DELETE_PARTITION_PAGE
;
1754 return SELECT_PARTITION_PAGE
;
1758 #define PARTITION_SIZE_INPUT_FIELD_LENGTH 6
1759 /* Restriction for MaxSize: pow(10, PARTITION_SIZE_INPUT_FIELD_LENGTH)-1 */
1760 #define PARTITION_MAXSIZE 999999
1763 ShowPartitionSizeInputBox(SHORT Left
,
1776 WCHAR PartitionSizeBuffer
[100];
1788 DrawBox(Left
, Top
, Right
- Left
+ 1, Bottom
- Top
+ 1);
1793 strcpy(Buffer
, MUIGetString(STRING_PARTITIONSIZE
));
1794 iLeft
= coPos
.X
+ strlen(Buffer
) + 1;
1797 WriteConsoleOutputCharacterA(StdOutput
,
1803 sprintf(Buffer
, MUIGetString(STRING_MAXSIZE
), MaxSize
);
1804 coPos
.X
= iLeft
+ PARTITION_SIZE_INPUT_FIELD_LENGTH
+ 1;
1806 WriteConsoleOutputCharacterA(StdOutput
,
1812 swprintf(PartitionSizeBuffer
, L
"%lu", MaxSize
);
1813 Length
= wcslen(PartitionSizeBuffer
);
1815 CONSOLE_SetInputTextXY(iLeft
,
1817 PARTITION_SIZE_INPUT_FIELD_LENGTH
,
1818 PartitionSizeBuffer
);
1819 CONSOLE_SetCursorXY(iLeft
+ Length
, iTop
);
1820 CONSOLE_SetCursorType(TRUE
, TRUE
);
1824 CONSOLE_ConInKey(&Ir
);
1826 if ((Ir
.Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1827 (Ir
.Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1832 PartitionSizeBuffer
[0] = UNICODE_NULL
;
1833 CONSOLE_SetCursorType(TRUE
, FALSE
);
1836 else if (Ir
.Event
.KeyEvent
.wVirtualKeyCode
== VK_RETURN
) /* ENTER */
1838 CONSOLE_SetCursorType(TRUE
, FALSE
);
1841 else if (Ir
.Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
) /* ESCAPE */
1846 PartitionSizeBuffer
[0] = UNICODE_NULL
;
1847 CONSOLE_SetCursorType(TRUE
, FALSE
);
1850 else if ((Ir
.Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1851 (Ir
.Event
.KeyEvent
.wVirtualKeyCode
== VK_HOME
)) /* HOME */
1854 CONSOLE_SetCursorXY(iLeft
+ Pos
, iTop
);
1856 else if ((Ir
.Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1857 (Ir
.Event
.KeyEvent
.wVirtualKeyCode
== VK_END
)) /* END */
1860 CONSOLE_SetCursorXY(iLeft
+ Pos
, iTop
);
1862 else if ((Ir
.Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1863 (Ir
.Event
.KeyEvent
.wVirtualKeyCode
== VK_LEFT
)) /* LEFT */
1868 CONSOLE_SetCursorXY(iLeft
+ Pos
, iTop
);
1871 else if ((Ir
.Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1872 (Ir
.Event
.KeyEvent
.wVirtualKeyCode
== VK_RIGHT
)) /* RIGHT */
1877 CONSOLE_SetCursorXY(iLeft
+ Pos
, iTop
);
1880 else if ((Ir
.Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1881 (Ir
.Event
.KeyEvent
.wVirtualKeyCode
== VK_DELETE
)) /* DEL */
1885 memmove(&PartitionSizeBuffer
[Pos
],
1886 &PartitionSizeBuffer
[Pos
+ 1],
1887 (Length
- Pos
- 1) * sizeof(WCHAR
));
1888 PartitionSizeBuffer
[Length
- 1] = UNICODE_NULL
;
1891 CONSOLE_SetInputTextXY(iLeft
,
1893 PARTITION_SIZE_INPUT_FIELD_LENGTH
,
1894 PartitionSizeBuffer
);
1895 CONSOLE_SetCursorXY(iLeft
+ Pos
, iTop
);
1898 else if (Ir
.Event
.KeyEvent
.wVirtualKeyCode
== VK_BACK
) /* BACKSPACE */
1903 memmove(&PartitionSizeBuffer
[Pos
- 1],
1904 &PartitionSizeBuffer
[Pos
],
1905 (Length
- Pos
) * sizeof(WCHAR
));
1906 PartitionSizeBuffer
[Length
- 1] = UNICODE_NULL
;
1910 CONSOLE_SetInputTextXY(iLeft
,
1912 PARTITION_SIZE_INPUT_FIELD_LENGTH
,
1913 PartitionSizeBuffer
);
1914 CONSOLE_SetCursorXY(iLeft
+ Pos
, iTop
);
1917 else if (Ir
.Event
.KeyEvent
.uChar
.AsciiChar
!= 0x00)
1919 if (Length
< PARTITION_SIZE_INPUT_FIELD_LENGTH
)
1921 ch
= (WCHAR
)Ir
.Event
.KeyEvent
.uChar
.AsciiChar
;
1923 if ((ch
>= L
'0') && (ch
<= L
'9'))
1926 memmove(&PartitionSizeBuffer
[Pos
+ 1],
1927 &PartitionSizeBuffer
[Pos
],
1928 (Length
- Pos
) * sizeof(WCHAR
));
1929 PartitionSizeBuffer
[Length
+ 1] = UNICODE_NULL
;
1930 PartitionSizeBuffer
[Pos
] = ch
;
1934 CONSOLE_SetInputTextXY(iLeft
,
1936 PARTITION_SIZE_INPUT_FIELD_LENGTH
,
1937 PartitionSizeBuffer
);
1938 CONSOLE_SetCursorXY(iLeft
+ Pos
, iTop
);
1944 /* Convert UNICODE --> ANSI the poor man's way */
1945 sprintf(InputBuffer
, "%S", PartitionSizeBuffer
);
1950 * Displays the CreatePrimaryPartitionPage.
1953 * SelectPartitionPage
1954 * SelectFileSystemPage (default)
1958 * Number of the next page.
1961 CreatePrimaryPartitionPage(PINPUT_RECORD Ir
)
1963 PDISKENTRY DiskEntry
;
1964 PPARTENTRY PartEntry
;
1967 CHAR InputBuffer
[50];
1971 ULONGLONG SectorCount
;
1974 if (PartitionList
== NULL
||
1975 PartitionList
->CurrentDisk
== NULL
||
1976 PartitionList
->CurrentPartition
== NULL
)
1978 /* FIXME: show an error dialog */
1982 DiskEntry
= PartitionList
->CurrentDisk
;
1983 PartEntry
= PartitionList
->CurrentPartition
;
1985 CONSOLE_SetStatusText(MUIGetString(STRING_PLEASEWAIT
));
1987 CONSOLE_SetTextXY(6, 8, MUIGetString(STRING_CHOOSENEWPARTITION
));
1989 DiskSize
= DiskEntry
->SectorCount
.QuadPart
* DiskEntry
->BytesPerSector
;
1991 if (DiskSize
>= 10737418240) /* 10 GB */
1993 DiskSize
= DiskSize
/ 1073741824;
1994 Unit
= MUIGetString(STRING_GB
);
1999 DiskSize
= DiskSize
/ 1048576;
2003 Unit
= MUIGetString(STRING_MB
);
2006 if (DiskEntry
->DriverName
.Length
> 0)
2008 CONSOLE_PrintTextXY(6, 10,
2009 MUIGetString(STRING_HDINFOPARTCREATE
),
2012 DiskEntry
->DiskNumber
,
2016 &DiskEntry
->DriverName
);
2020 CONSOLE_PrintTextXY(6, 10,
2021 MUIGetString(STRING_HDDINFOUNK1
),
2024 DiskEntry
->DiskNumber
,
2030 CONSOLE_SetTextXY(6, 12, MUIGetString(STRING_HDDSIZE
));
2033 CONSOLE_PrintTextXY(8, 10, "Maximum size of the new partition is %I64u MB",
2034 PartitionList
->CurrentPartition
->SectorCount
* DiskEntry
->BytesPerSector
/ 1048576);
2037 CONSOLE_SetStatusText(MUIGetString(STRING_CREATEPARTITION
));
2039 PartEntry
= PartitionList
->CurrentPartition
;
2042 MaxSize
= (PartEntry
->SectorCount
.QuadPart
* DiskEntry
->BytesPerSector
) / 1048576; /* in MBytes (rounded) */
2044 if (MaxSize
> PARTITION_MAXSIZE
)
2045 MaxSize
= PARTITION_MAXSIZE
;
2047 ShowPartitionSizeInputBox(12, 14, xScreen
- 12, 17, /* left, top, right, bottom */
2048 MaxSize
, InputBuffer
, &Quit
, &Cancel
);
2052 if (ConfirmQuit(Ir
) != FALSE
)
2057 else if (Cancel
!= FALSE
)
2059 return SELECT_PARTITION_PAGE
;
2063 PartSize
= atoi(InputBuffer
);
2071 if (PartSize
> MaxSize
)
2077 /* Convert to bytes */
2078 if (PartSize
== MaxSize
)
2080 /* Use all of the unpartitioned disk space */
2081 SectorCount
= PartEntry
->SectorCount
.QuadPart
;
2085 /* Calculate the sector count from the size in MB */
2086 SectorCount
= PartSize
* 1048576 / DiskEntry
->BytesPerSector
;
2088 /* But never get larger than the unpartitioned disk space */
2089 if (SectorCount
> PartEntry
->SectorCount
.QuadPart
)
2090 SectorCount
= PartEntry
->SectorCount
.QuadPart
;
2093 DPRINT ("Partition size: %I64u bytes\n", PartSize
);
2095 CreatePrimaryPartition(PartitionList
,
2099 return SELECT_PARTITION_PAGE
;
2103 return CREATE_PRIMARY_PARTITION_PAGE
;
2108 * Displays the CreateExtendedPartitionPage.
2111 * SelectPartitionPage (default)
2115 * Number of the next page.
2118 CreateExtendedPartitionPage(PINPUT_RECORD Ir
)
2120 PDISKENTRY DiskEntry
;
2121 PPARTENTRY PartEntry
;
2124 CHAR InputBuffer
[50];
2128 ULONGLONG SectorCount
;
2131 if (PartitionList
== NULL
||
2132 PartitionList
->CurrentDisk
== NULL
||
2133 PartitionList
->CurrentPartition
== NULL
)
2135 /* FIXME: show an error dialog */
2139 DiskEntry
= PartitionList
->CurrentDisk
;
2140 PartEntry
= PartitionList
->CurrentPartition
;
2142 CONSOLE_SetStatusText(MUIGetString(STRING_PLEASEWAIT
));
2144 CONSOLE_SetTextXY(6, 8, MUIGetString(STRING_CHOOSE_NEW_EXTENDED_PARTITION
));
2146 DiskSize
= DiskEntry
->SectorCount
.QuadPart
* DiskEntry
->BytesPerSector
;
2148 if (DiskSize
>= 10737418240) /* 10 GB */
2150 DiskSize
= DiskSize
/ 1073741824;
2151 Unit
= MUIGetString(STRING_GB
);
2156 DiskSize
= DiskSize
/ 1048576;
2160 Unit
= MUIGetString(STRING_MB
);
2163 if (DiskEntry
->DriverName
.Length
> 0)
2165 CONSOLE_PrintTextXY(6, 10,
2166 MUIGetString(STRING_HDINFOPARTCREATE
),
2169 DiskEntry
->DiskNumber
,
2173 &DiskEntry
->DriverName
);
2177 CONSOLE_PrintTextXY(6, 10,
2178 MUIGetString(STRING_HDDINFOUNK1
),
2181 DiskEntry
->DiskNumber
,
2187 CONSOLE_SetTextXY(6, 12, MUIGetString(STRING_HDDSIZE
));
2190 CONSOLE_PrintTextXY(8, 10, "Maximum size of the new partition is %I64u MB",
2191 PartitionList
->CurrentPartition
->SectorCount
* DiskEntry
->BytesPerSector
/ 1048576);
2194 CONSOLE_SetStatusText(MUIGetString(STRING_CREATEPARTITION
));
2196 PartEntry
= PartitionList
->CurrentPartition
;
2199 MaxSize
= (PartEntry
->SectorCount
.QuadPart
* DiskEntry
->BytesPerSector
) / 1048576; /* in MBytes (rounded) */
2201 if (MaxSize
> PARTITION_MAXSIZE
)
2202 MaxSize
= PARTITION_MAXSIZE
;
2204 ShowPartitionSizeInputBox(12, 14, xScreen
- 12, 17, /* left, top, right, bottom */
2205 MaxSize
, InputBuffer
, &Quit
, &Cancel
);
2209 if (ConfirmQuit(Ir
) != FALSE
)
2214 else if (Cancel
!= FALSE
)
2216 return SELECT_PARTITION_PAGE
;
2220 PartSize
= atoi(InputBuffer
);
2228 if (PartSize
> MaxSize
)
2234 /* Convert to bytes */
2235 if (PartSize
== MaxSize
)
2237 /* Use all of the unpartitioned disk space */
2238 SectorCount
= PartEntry
->SectorCount
.QuadPart
;
2242 /* Calculate the sector count from the size in MB */
2243 SectorCount
= PartSize
* 1048576 / DiskEntry
->BytesPerSector
;
2245 /* But never get larger than the unpartitioned disk space */
2246 if (SectorCount
> PartEntry
->SectorCount
.QuadPart
)
2247 SectorCount
= PartEntry
->SectorCount
.QuadPart
;
2250 DPRINT ("Partition size: %I64u bytes\n", PartSize
);
2252 CreateExtendedPartition(PartitionList
,
2255 return SELECT_PARTITION_PAGE
;
2259 return CREATE_EXTENDED_PARTITION_PAGE
;
2264 * Displays the CreateLogicalPartitionPage.
2267 * SelectFileSystemPage (default)
2271 * Number of the next page.
2274 CreateLogicalPartitionPage(PINPUT_RECORD Ir
)
2276 PDISKENTRY DiskEntry
;
2277 PPARTENTRY PartEntry
;
2280 CHAR InputBuffer
[50];
2284 ULONGLONG SectorCount
;
2287 if (PartitionList
== NULL
||
2288 PartitionList
->CurrentDisk
== NULL
||
2289 PartitionList
->CurrentPartition
== NULL
)
2291 /* FIXME: show an error dialog */
2295 DiskEntry
= PartitionList
->CurrentDisk
;
2296 PartEntry
= PartitionList
->CurrentPartition
;
2298 CONSOLE_SetStatusText(MUIGetString(STRING_PLEASEWAIT
));
2300 CONSOLE_SetTextXY(6, 8, MUIGetString(STRING_CHOOSE_NEW_LOGICAL_PARTITION
));
2302 DiskSize
= DiskEntry
->SectorCount
.QuadPart
* DiskEntry
->BytesPerSector
;
2304 if (DiskSize
>= 10737418240) /* 10 GB */
2306 DiskSize
= DiskSize
/ 1073741824;
2307 Unit
= MUIGetString(STRING_GB
);
2312 DiskSize
= DiskSize
/ 1048576;
2316 Unit
= MUIGetString(STRING_MB
);
2319 if (DiskEntry
->DriverName
.Length
> 0)
2321 CONSOLE_PrintTextXY(6, 10,
2322 MUIGetString(STRING_HDINFOPARTCREATE
),
2325 DiskEntry
->DiskNumber
,
2329 &DiskEntry
->DriverName
);
2333 CONSOLE_PrintTextXY(6, 10,
2334 MUIGetString(STRING_HDDINFOUNK1
),
2337 DiskEntry
->DiskNumber
,
2343 CONSOLE_SetTextXY(6, 12, MUIGetString(STRING_HDDSIZE
));
2346 CONSOLE_PrintTextXY(8, 10, "Maximum size of the new partition is %I64u MB",
2347 PartitionList
->CurrentPartition
->SectorCount
* DiskEntry
->BytesPerSector
/ 1048576);
2350 CONSOLE_SetStatusText(MUIGetString(STRING_CREATEPARTITION
));
2352 PartEntry
= PartitionList
->CurrentPartition
;
2355 MaxSize
= (PartEntry
->SectorCount
.QuadPart
* DiskEntry
->BytesPerSector
) / 1048576; /* in MBytes (rounded) */
2357 if (MaxSize
> PARTITION_MAXSIZE
)
2358 MaxSize
= PARTITION_MAXSIZE
;
2360 ShowPartitionSizeInputBox(12, 14, xScreen
- 12, 17, /* left, top, right, bottom */
2361 MaxSize
, InputBuffer
, &Quit
, &Cancel
);
2365 if (ConfirmQuit(Ir
) != FALSE
)
2370 else if (Cancel
!= FALSE
)
2372 return SELECT_PARTITION_PAGE
;
2376 PartSize
= atoi(InputBuffer
);
2384 if (PartSize
> MaxSize
)
2390 /* Convert to bytes */
2391 if (PartSize
== MaxSize
)
2393 /* Use all of the unpartitioned disk space */
2394 SectorCount
= PartEntry
->SectorCount
.QuadPart
;
2398 /* Calculate the sector count from the size in MB */
2399 SectorCount
= PartSize
* 1048576 / DiskEntry
->BytesPerSector
;
2401 /* But never get larger than the unpartitioned disk space */
2402 if (SectorCount
> PartEntry
->SectorCount
.QuadPart
)
2403 SectorCount
= PartEntry
->SectorCount
.QuadPart
;
2406 DPRINT("Partition size: %I64u bytes\n", PartSize
);
2408 CreateLogicalPartition(PartitionList
,
2412 return SELECT_PARTITION_PAGE
;
2416 return CREATE_LOGICAL_PARTITION_PAGE
;
2421 * Displays the ConfirmDeleteSystemPartitionPage.
2424 * DeletePartitionPage (default)
2425 * SelectPartitionPage
2428 * Number of the next page.
2431 ConfirmDeleteSystemPartitionPage(PINPUT_RECORD Ir
)
2433 MUIDisplayPage(CONFIRM_DELETE_SYSTEM_PARTITION_PAGE
);
2437 CONSOLE_ConInKey(Ir
);
2439 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
2440 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
2442 if (ConfirmQuit(Ir
) == TRUE
)
2447 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_RETURN
) /* ENTER */
2449 return DELETE_PARTITION_PAGE
;
2451 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
) /* ESC */
2453 return SELECT_PARTITION_PAGE
;
2457 return CONFIRM_DELETE_SYSTEM_PARTITION_PAGE
;
2462 * Displays the DeletePartitionPage.
2465 * SelectPartitionPage (default)
2469 * Number of the next page.
2472 DeletePartitionPage(PINPUT_RECORD Ir
)
2474 PDISKENTRY DiskEntry
;
2475 PPARTENTRY PartEntry
;
2479 CHAR PartTypeString
[32];
2481 if (PartitionList
== NULL
||
2482 PartitionList
->CurrentDisk
== NULL
||
2483 PartitionList
->CurrentPartition
== NULL
)
2485 /* FIXME: show an error dialog */
2489 DiskEntry
= PartitionList
->CurrentDisk
;
2490 PartEntry
= PartitionList
->CurrentPartition
;
2492 MUIDisplayPage(DELETE_PARTITION_PAGE
);
2494 GetPartTypeStringFromPartitionType(PartEntry
->PartitionType
,
2496 ARRAYSIZE(PartTypeString
));
2498 PartSize
= PartEntry
->SectorCount
.QuadPart
* DiskEntry
->BytesPerSector
;
2500 if (PartSize
>= 10737418240) /* 10 GB */
2502 PartSize
= PartSize
/ 1073741824;
2503 Unit
= MUIGetString(STRING_GB
);
2507 if (PartSize
>= 10485760) /* 10 MB */
2509 PartSize
= PartSize
/ 1048576;
2510 Unit
= MUIGetString(STRING_MB
);
2514 PartSize
= PartSize
/ 1024;
2515 Unit
= MUIGetString(STRING_KB
);
2518 if (*PartTypeString
== '\0') // STRING_FORMATUNKNOWN ??
2520 CONSOLE_PrintTextXY(6, 10,
2521 MUIGetString(STRING_HDDINFOUNK2
),
2522 (PartEntry
->DriveLetter
== 0) ? '-' : PartEntry
->DriveLetter
,
2523 (PartEntry
->DriveLetter
== 0) ? '-' : ':',
2524 PartEntry
->PartitionType
,
2530 CONSOLE_PrintTextXY(6, 10,
2531 " %c%c %s %I64u %s",
2532 (PartEntry
->DriveLetter
== 0) ? '-' : PartEntry
->DriveLetter
,
2533 (PartEntry
->DriveLetter
== 0) ? '-' : ':',
2539 DiskSize
= DiskEntry
->SectorCount
.QuadPart
* DiskEntry
->BytesPerSector
;
2541 if (DiskSize
>= 10737418240) /* 10 GB */
2543 DiskSize
= DiskSize
/ 1073741824;
2544 Unit
= MUIGetString(STRING_GB
);
2549 DiskSize
= DiskSize
/ 1048576;
2553 Unit
= MUIGetString(STRING_MB
);
2556 if (DiskEntry
->DriverName
.Length
> 0)
2558 CONSOLE_PrintTextXY(6, 12,
2559 MUIGetString(STRING_HDINFOPARTDELETE
),
2562 DiskEntry
->DiskNumber
,
2566 &DiskEntry
->DriverName
);
2570 CONSOLE_PrintTextXY(6, 12,
2571 MUIGetString(STRING_HDDINFOUNK3
),
2574 DiskEntry
->DiskNumber
,
2582 CONSOLE_ConInKey(Ir
);
2584 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
2585 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
2587 if (ConfirmQuit(Ir
) != FALSE
)
2592 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
) /* ESC */
2594 return SELECT_PARTITION_PAGE
;
2596 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== 'D') /* D */
2598 DeleteCurrentPartition(PartitionList
);
2600 return SELECT_PARTITION_PAGE
;
2604 return DELETE_PARTITION_PAGE
;
2609 * Displays the SelectFileSystemPage.
2612 * CheckFileSystemPage (At once if RepairUpdate is selected)
2613 * CheckFileSystemPage (At once if Unattended and not UnattendFormatPartition)
2614 * FormatPartitionPage (At once if Unattended and UnattendFormatPartition)
2615 * SelectPartitionPage (If the user aborts)
2616 * FormatPartitionPage (Default)
2620 * Sets PartEntry->DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex].PartitionType (via UpdatePartitionType)
2621 * Calls CheckActiveSystemPartition()
2624 * Number of the next page.
2627 SelectFileSystemPage(PINPUT_RECORD Ir
)
2629 PDISKENTRY DiskEntry
;
2630 PPARTENTRY PartEntry
;
2635 CHAR PartTypeString
[32];
2636 FORMATMACHINESTATE PreviousFormatState
;
2638 DPRINT("SelectFileSystemPage()\n");
2640 if (PartitionList
== NULL
||
2641 PartitionList
->CurrentDisk
== NULL
||
2642 PartitionList
->CurrentPartition
== NULL
)
2644 /* FIXME: show an error dialog */
2649 if (FileSystemList
== NULL
)
2651 FileSystemList
= CreateFileSystemList(6, 26, PartitionList
->CurrentPartition
->New
, L
"FAT");
2652 if (FileSystemList
== NULL
)
2654 /* FIXME: show an error dialog */
2658 /* FIXME: Add file systems to list */
2661 /* Find or set the active system partition */
2662 CheckActiveSystemPartition(PartitionList
, FileSystemList
);
2664 if (PartitionList
->SystemDisk
== NULL
||
2665 PartitionList
->SystemPartition
== NULL
)
2667 /* FIXME: show an error dialog */
2671 PreviousFormatState
= PartitionList
->FormatState
;
2672 switch (PartitionList
->FormatState
)
2675 if (PartitionList
->CurrentPartition
!= PartitionList
->SystemPartition
)
2677 PartitionList
->TempDisk
= PartitionList
->SystemDisk
;
2678 PartitionList
->TempPartition
= PartitionList
->SystemPartition
;
2679 PartitionList
->TempPartition
->NeedsCheck
= TRUE
;
2681 PartitionList
->FormatState
= FormatSystemPartition
;
2682 DPRINT1("FormatState: Start --> FormatSystemPartition\n");
2686 PartitionList
->TempDisk
= PartitionList
->CurrentDisk
;
2687 PartitionList
->TempPartition
= PartitionList
->CurrentPartition
;
2688 PartitionList
->TempPartition
->NeedsCheck
= TRUE
;
2690 PartitionList
->FormatState
= FormatInstallPartition
;
2691 DPRINT1("FormatState: Start --> FormatInstallPartition\n");
2695 case FormatSystemPartition
:
2696 PartitionList
->TempDisk
= PartitionList
->CurrentDisk
;
2697 PartitionList
->TempPartition
= PartitionList
->CurrentPartition
;
2698 PartitionList
->TempPartition
->NeedsCheck
= TRUE
;
2700 PartitionList
->FormatState
= FormatInstallPartition
;
2701 DPRINT1("FormatState: FormatSystemPartition --> FormatInstallPartition\n");
2704 case FormatInstallPartition
:
2705 if (GetNextUnformattedPartition(PartitionList
,
2706 &PartitionList
->TempDisk
,
2707 &PartitionList
->TempPartition
))
2709 PartitionList
->FormatState
= FormatOtherPartition
;
2710 PartitionList
->TempPartition
->NeedsCheck
= TRUE
;
2711 DPRINT1("FormatState: FormatInstallPartition --> FormatOtherPartition\n");
2715 PartitionList
->FormatState
= FormatDone
;
2716 DPRINT1("FormatState: FormatInstallPartition --> FormatDone\n");
2717 return CHECK_FILE_SYSTEM_PAGE
;
2721 case FormatOtherPartition
:
2722 if (GetNextUnformattedPartition(PartitionList
,
2723 &PartitionList
->TempDisk
,
2724 &PartitionList
->TempPartition
))
2726 PartitionList
->FormatState
= FormatOtherPartition
;
2727 PartitionList
->TempPartition
->NeedsCheck
= TRUE
;
2728 DPRINT1("FormatState: FormatOtherPartition --> FormatOtherPartition\n");
2732 PartitionList
->FormatState
= FormatDone
;
2733 DPRINT1("FormatState: FormatOtherPartition --> FormatDone\n");
2734 return CHECK_FILE_SYSTEM_PAGE
;
2739 DPRINT1("FormatState: Invalid value %ld\n", PartitionList
->FormatState
);
2740 /* FIXME: show an error dialog */
2744 DiskEntry
= PartitionList
->TempDisk
;
2745 PartEntry
= PartitionList
->TempPartition
;
2747 /* adjust disk size */
2748 DiskSize
= DiskEntry
->SectorCount
.QuadPart
* DiskEntry
->BytesPerSector
;
2749 if (DiskSize
>= 10737418240) /* 10 GB */
2751 DiskSize
= DiskSize
/ 1073741824;
2752 DiskUnit
= MUIGetString(STRING_GB
);
2756 DiskSize
= DiskSize
/ 1048576;
2757 DiskUnit
= MUIGetString(STRING_MB
);
2760 /* adjust partition size */
2761 PartSize
= PartEntry
->SectorCount
.QuadPart
* DiskEntry
->BytesPerSector
;
2762 if (PartSize
>= 10737418240) /* 10 GB */
2764 PartSize
= PartSize
/ 1073741824;
2765 PartUnit
= MUIGetString(STRING_GB
);
2769 PartSize
= PartSize
/ 1048576;
2770 PartUnit
= MUIGetString(STRING_MB
);
2773 /* adjust partition type */
2774 GetPartTypeStringFromPartitionType(PartEntry
->PartitionType
,
2776 ARRAYSIZE(PartTypeString
));
2778 if (PartEntry
->AutoCreate
!= FALSE
)
2780 CONSOLE_SetTextXY(6, 8, MUIGetString(STRING_NEWPARTITION
));
2783 CONSOLE_PrintTextXY(8, 10, "Partition %lu (%I64u %s) %s of",
2784 PartEntry
->PartitionNumber
,
2790 CONSOLE_PrintTextXY(8, 10, MUIGetString(STRING_HDINFOPARTZEROED
),
2791 DiskEntry
->DiskNumber
,
2797 &DiskEntry
->DriverName
);
2799 CONSOLE_SetTextXY(6, 12, MUIGetString(STRING_PARTFORMAT
));
2802 PartEntry
->AutoCreate
= FALSE
;
2804 else if (PartEntry
->New
!= FALSE
)
2806 switch (PartitionList
->FormatState
)
2808 case FormatSystemPartition
:
2809 CONSOLE_SetTextXY(6, 8, MUIGetString(STRING_NONFORMATTEDSYSTEMPART
));
2812 case FormatInstallPartition
:
2813 CONSOLE_SetTextXY(6, 8, MUIGetString(STRING_NONFORMATTEDPART
));
2816 case FormatOtherPartition
:
2817 CONSOLE_SetTextXY(6, 8, MUIGetString(STRING_NONFORMATTEDOTHERPART
));
2824 CONSOLE_SetTextXY(6, 10, MUIGetString(STRING_PARTFORMAT
));
2828 CONSOLE_SetTextXY(6, 8, MUIGetString(STRING_INSTALLONPART
));
2830 if (*PartTypeString
== '\0') // STRING_FORMATUNKNOWN ??
2832 CONSOLE_PrintTextXY(8, 10,
2833 MUIGetString(STRING_HDDINFOUNK4
),
2834 (PartEntry
->DriveLetter
== 0) ? '-' : PartEntry
->DriveLetter
,
2835 (PartEntry
->DriveLetter
== 0) ? '-' : ':',
2836 PartEntry
->PartitionType
,
2842 CONSOLE_PrintTextXY(8, 10,
2844 (PartEntry
->DriveLetter
== 0) ? '-' : PartEntry
->DriveLetter
,
2845 (PartEntry
->DriveLetter
== 0) ? '-' : ':',
2851 CONSOLE_PrintTextXY(6, 12, MUIGetString(STRING_HDINFOPARTEXISTS
),
2852 DiskEntry
->DiskNumber
,
2858 &DiskEntry
->DriverName
);
2861 MUIDisplayPage(SELECT_FILE_SYSTEM_PAGE
);
2863 if (FileSystemList
== NULL
)
2865 FileSystemList
= CreateFileSystemList(6, 26, PartEntry
->New
, L
"FAT");
2866 if (FileSystemList
== NULL
)
2868 /* FIXME: show an error dialog */
2872 /* FIXME: Add file systems to list */
2875 DrawFileSystemList(FileSystemList
);
2877 if (RepairUpdateFlag
)
2879 return CHECK_FILE_SYSTEM_PAGE
;
2880 //return SELECT_PARTITION_PAGE;
2883 if (IsUnattendedSetup
)
2885 if (UnattendFormatPartition
)
2887 PartEntry
->FileSystem
= GetFileSystemByName(FileSystemList
, L
"FAT");
2888 return FORMAT_PARTITION_PAGE
;
2891 return CHECK_FILE_SYSTEM_PAGE
;
2896 CONSOLE_ConInKey(Ir
);
2898 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
2899 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
2901 if (ConfirmQuit(Ir
) != FALSE
)
2906 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
2907 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
)) /* ESC */
2909 PartitionList
->FormatState
= Start
;
2910 return SELECT_PARTITION_PAGE
;
2912 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
2913 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
)) /* DOWN */
2915 ScrollDownFileSystemList(FileSystemList
);
2917 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
2918 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_UP
)) /* UP */
2920 ScrollUpFileSystemList(FileSystemList
);
2922 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_RETURN
) /* ENTER */
2924 if (!FileSystemList
->Selected
->FormatFunc
)
2926 return SELECT_FILE_SYSTEM_PAGE
;
2930 PartEntry
->FileSystem
= FileSystemList
->Selected
;
2931 return FORMAT_PARTITION_PAGE
;
2936 PartitionList
->FormatState
= PreviousFormatState
;
2938 return SELECT_FILE_SYSTEM_PAGE
;
2943 * Displays the FormatPartitionPage.
2946 * InstallDirectoryPage (At once if IsUnattendedSetup or InstallShortcut)
2947 * SelectPartitionPage (At once)
2951 * Sets PartitionList->CurrentPartition->FormatState
2952 * Sets DestinationRootPath
2955 * Number of the next page.
2958 FormatPartitionPage(PINPUT_RECORD Ir
)
2960 UNICODE_STRING PartitionRootPath
;
2961 WCHAR PathBuffer
[MAX_PATH
];
2962 PDISKENTRY DiskEntry
;
2963 PPARTENTRY PartEntry
;
2969 PPARTITION_INFORMATION PartitionInfo
;
2972 DPRINT("FormatPartitionPage()\n");
2974 MUIDisplayPage(FORMAT_PARTITION_PAGE
);
2976 if (PartitionList
== NULL
||
2977 PartitionList
->TempDisk
== NULL
||
2978 PartitionList
->TempPartition
== NULL
)
2980 /* FIXME: show an error dialog */
2984 DiskEntry
= PartitionList
->TempDisk
;
2985 PartEntry
= PartitionList
->TempPartition
;
2989 if (!IsUnattendedSetup
)
2991 CONSOLE_ConInKey(Ir
);
2994 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
2995 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
2997 if (ConfirmQuit(Ir
) != FALSE
)
3002 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_RETURN
|| IsUnattendedSetup
) /* ENTER */
3004 CONSOLE_SetStatusText(MUIGetString(STRING_PLEASEWAIT
));
3006 if (wcscmp(PartEntry
->FileSystem
->FileSystemName
, L
"FAT") == 0)
3008 if (PartEntry
->SectorCount
.QuadPart
< 8192)
3010 /* FAT12 CHS partition (disk is smaller than 4.1MB) */
3011 PartEntry
->PartitionType
= PARTITION_FAT_12
;
3013 else if (PartEntry
->StartSector
.QuadPart
< 1450560)
3015 /* Partition starts below the 8.4GB boundary ==> CHS partition */
3017 if (PartEntry
->SectorCount
.QuadPart
< 65536)
3019 /* FAT16 CHS partition (partition size < 32MB) */
3020 PartEntry
->PartitionType
= PARTITION_FAT_16
;
3022 else if (PartEntry
->SectorCount
.QuadPart
< 1048576)
3024 /* FAT16 CHS partition (partition size < 512MB) */
3025 PartEntry
->PartitionType
= PARTITION_HUGE
;
3029 /* FAT32 CHS partition (partition size >= 512MB) */
3030 PartEntry
->PartitionType
= PARTITION_FAT32
;
3035 /* Partition starts above the 8.4GB boundary ==> LBA partition */
3037 if (PartEntry
->SectorCount
.QuadPart
< 1048576)
3039 /* FAT16 LBA partition (partition size < 512MB) */
3040 PartEntry
->PartitionType
= PARTITION_XINT13
;
3044 /* FAT32 LBA partition (partition size >= 512MB) */
3045 PartEntry
->PartitionType
= PARTITION_FAT32_XINT13
;
3049 DiskEntry
->Dirty
= TRUE
;
3050 DiskEntry
->LayoutBuffer
->PartitionEntry
[PartEntry
->PartitionIndex
].PartitionType
= PartEntry
->PartitionType
;
3051 DiskEntry
->LayoutBuffer
->PartitionEntry
[PartEntry
->PartitionIndex
].RewritePartition
= TRUE
;
3054 else if (wcscmp(PartEntry
->FileSystem
->FileSystemName
, L
"EXT2") == 0)
3056 PartEntry
->PartitionType
= PARTITION_EXT2
;
3058 DiskEntry
->Dirty
= TRUE
;
3059 DiskEntry
->LayoutBuffer
->PartitionEntry
[PartEntry
->PartitionIndex
].PartitionType
= PartEntry
->PartitionType
;
3060 DiskEntry
->LayoutBuffer
->PartitionEntry
[PartEntry
->PartitionIndex
].RewritePartition
= TRUE
;
3062 else if (wcscmp(PartEntry
->FileSystem
->FileSystemName
, L
"NTFS") == 0)
3064 PartEntry
->PartitionType
= PARTITION_IFS
;
3066 DiskEntry
->Dirty
= TRUE
;
3067 DiskEntry
->LayoutBuffer
->PartitionEntry
[PartEntry
->PartitionIndex
].PartitionType
= PartEntry
->PartitionType
;
3068 DiskEntry
->LayoutBuffer
->PartitionEntry
[PartEntry
->PartitionIndex
].RewritePartition
= TRUE
;
3071 else if (!PartEntry
->FileSystem
->FormatFunc
)
3073 /* FIXME: show an error dialog */
3078 CONSOLE_PrintTextXY(6, 12,
3079 "Cylinders: %I64u Tracks/Cyl: %lu Sectors/Trk: %lu Bytes/Sec: %lu %c",
3080 DiskEntry
->Cylinders
,
3081 DiskEntry
->TracksPerCylinder
,
3082 DiskEntry
->SectorsPerTrack
,
3083 DiskEntry
->BytesPerSector
,
3084 DiskEntry
->Dirty
? '*' : ' ');
3088 for (i
= 0; i
< DiskEntry
->LayoutBuffer
->PartitionCount
; i
++)
3090 PartitionInfo
= &DiskEntry
->LayoutBuffer
->PartitionEntry
[i
];
3092 CONSOLE_PrintTextXY(6, Line
,
3093 "%2u: %2lu %c %12I64u %12I64u %02x",
3095 PartitionInfo
->PartitionNumber
,
3096 PartitionInfo
->BootIndicator
? 'A' : '-',
3097 PartitionInfo
->StartingOffset
.QuadPart
/ DiskEntry
->BytesPerSector
,
3098 PartitionInfo
->PartitionLength
.QuadPart
/ DiskEntry
->BytesPerSector
,
3099 PartitionInfo
->PartitionType
);
3104 if (WritePartitionsToDisk(PartitionList
) == FALSE
)
3106 DPRINT("WritePartitionsToDisk() failed\n");
3107 MUIDisplayError(ERROR_WRITE_PTABLE
, Ir
, POPUP_WAIT_ENTER
);
3111 /* Set PartitionRootPath */
3112 swprintf(PathBuffer
,
3113 L
"\\Device\\Harddisk%lu\\Partition%lu",
3114 DiskEntry
->DiskNumber
,
3115 PartEntry
->PartitionNumber
);
3116 RtlInitUnicodeString(&PartitionRootPath
,
3118 DPRINT("PartitionRootPath: %wZ\n", &PartitionRootPath
);
3120 if (PartEntry
->FileSystem
->FormatFunc
)
3122 Status
= FormatPartition(&PartitionRootPath
,
3123 PartEntry
->FileSystem
);
3124 if (!NT_SUCCESS(Status
))
3126 DPRINT1("FormatPartition() failed with status 0x%08lx\n", Status
);
3127 MUIDisplayError(ERROR_FORMATTING_PARTITION
, Ir
, POPUP_WAIT_ANY_KEY
, PathBuffer
);
3131 PartEntry
->New
= FALSE
;
3135 CONSOLE_SetStatusText(" Done. Press any key ...");
3136 CONSOLE_ConInKey(Ir
);
3139 return SELECT_FILE_SYSTEM_PAGE
;
3143 return FORMAT_PARTITION_PAGE
;
3148 * Displays the CheckFileSystemPage.
3151 * InstallDirectoryPage (At once)
3155 * Inits or reloads FileSystemList
3158 * Number of the next page.
3161 CheckFileSystemPage(PINPUT_RECORD Ir
)
3163 PFILE_SYSTEM_ITEM CurrentFileSystem
;
3164 UNICODE_STRING PartitionRootPath
;
3165 WCHAR PathBuffer
[MAX_PATH
];
3166 CHAR Buffer
[MAX_PATH
];
3167 PDISKENTRY DiskEntry
;
3168 PPARTENTRY PartEntry
;
3171 if (PartitionList
== NULL
)
3173 /* FIXME: show an error dialog */
3177 if (!GetNextUncheckedPartition(PartitionList
, &DiskEntry
, &PartEntry
))
3179 return INSTALL_DIRECTORY_PAGE
;
3182 /* Set PartitionRootPath */
3183 swprintf(PathBuffer
,
3184 L
"\\Device\\Harddisk%lu\\Partition%lu",
3185 DiskEntry
->DiskNumber
,
3186 PartEntry
->PartitionNumber
);
3187 RtlInitUnicodeString(&PartitionRootPath
, PathBuffer
);
3188 DPRINT("PartitionRootPath: %wZ\n", &PartitionRootPath
);
3190 CONSOLE_SetTextXY(6, 8, MUIGetString(STRING_CHECKINGPART
));
3192 CONSOLE_SetStatusText(MUIGetString(STRING_PLEASEWAIT
));
3194 CurrentFileSystem
= GetFileSystem(FileSystemList
, PartEntry
);
3195 DPRINT1("CheckFileSystemPage -- PartitionType: 0x%02X ; FileSystemName: %S\n",
3196 PartEntry
->PartitionType
, (CurrentFileSystem
? CurrentFileSystem
->FileSystemName
: L
"n/a"));
3198 /* HACK: Do not try to check a partition with an unknown filesystem */
3199 if (CurrentFileSystem
== NULL
)
3201 PartEntry
->NeedsCheck
= FALSE
;
3202 return CHECK_FILE_SYSTEM_PAGE
;
3205 if (CurrentFileSystem
->ChkdskFunc
== NULL
)
3208 "Setup is currently unable to check a partition formatted in %S.\n"
3210 " \x07 Press ENTER to continue Setup.\n"
3211 " \x07 Press F3 to quit Setup.",
3212 CurrentFileSystem
->FileSystemName
);
3215 MUIGetString(STRING_QUITCONTINUE
),
3216 NULL
, POPUP_WAIT_NONE
);
3220 CONSOLE_ConInKey(Ir
);
3222 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00 &&
3223 Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
) /* F3 */
3225 if (ConfirmQuit(Ir
))
3228 return CHECK_FILE_SYSTEM_PAGE
;
3230 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== VK_RETURN
) /* ENTER */
3232 PartEntry
->NeedsCheck
= FALSE
;
3233 return CHECK_FILE_SYSTEM_PAGE
;
3239 Status
= ChkdskPartition(&PartitionRootPath
, CurrentFileSystem
);
3240 if (!NT_SUCCESS(Status
))
3242 DPRINT("ChkdskPartition() failed with status 0x%08lx\n", Status
);
3243 // sprintf(Buffer, "Setup failed to verify the selected partition.\n"
3244 sprintf(Buffer
, "ChkDsk detected some disk errors.\n"
3245 "(Status 0x%08lx).\n", Status
);
3247 // MUIGetString(STRING_REBOOTCOMPUTER),
3248 MUIGetString(STRING_CONTINUE
),
3249 Ir
, POPUP_WAIT_ENTER
);
3251 // return QUIT_PAGE;
3254 PartEntry
->NeedsCheck
= FALSE
;
3255 return CHECK_FILE_SYSTEM_PAGE
;
3262 BuildInstallPaths(PWCHAR InstallDir
,
3263 PDISKENTRY DiskEntry
,
3264 PPARTENTRY PartEntry
)
3266 WCHAR PathBuffer
[MAX_PATH
];
3268 /* Create 'InstallPath' string */
3269 RtlFreeUnicodeString(&InstallPath
);
3270 RtlCreateUnicodeString(&InstallPath
, InstallDir
);
3272 /* Create 'DestinationRootPath' string */
3273 RtlFreeUnicodeString(&DestinationRootPath
);
3274 swprintf(PathBuffer
,
3275 L
"\\Device\\Harddisk%lu\\Partition%lu",
3276 DiskEntry
->DiskNumber
,
3277 PartEntry
->PartitionNumber
);
3278 RtlCreateUnicodeString(&DestinationRootPath
, PathBuffer
);
3279 DPRINT("DestinationRootPath: %wZ\n", &DestinationRootPath
);
3281 /* Create 'DestinationPath' string */
3282 RtlFreeUnicodeString(&DestinationPath
);
3283 wcscpy(PathBuffer
, DestinationRootPath
.Buffer
);
3285 if (InstallDir
[0] != L
'\\')
3286 wcscat(PathBuffer
, L
"\\");
3288 wcscat(PathBuffer
, InstallDir
);
3289 RtlCreateUnicodeString(&DestinationPath
, PathBuffer
);
3291 /* Create 'DestinationArcPath' */
3292 RtlFreeUnicodeString(&DestinationArcPath
);
3293 swprintf(PathBuffer
,
3294 L
"multi(0)disk(0)rdisk(%lu)partition(%lu)",
3295 DiskEntry
->BiosDiskNumber
,
3296 PartEntry
->PartitionNumber
);
3298 if (InstallDir
[0] != L
'\\')
3299 wcscat(PathBuffer
, L
"\\");
3301 wcscat(PathBuffer
, InstallDir
);
3302 RtlCreateUnicodeString(&DestinationArcPath
, PathBuffer
);
3307 * Displays the InstallDirectoryPage.
3310 * PrepareCopyPage (As the direct result of InstallDirectoryPage1)
3314 * Number of the next page.
3317 InstallDirectoryPage(PINPUT_RECORD Ir
)
3319 PDISKENTRY DiskEntry
;
3320 PPARTENTRY PartEntry
;
3321 WCHAR InstallDir
[51];
3325 /* We do not need the filesystem list any more */
3326 if (FileSystemList
!= NULL
)
3328 DestroyFileSystemList(FileSystemList
);
3329 FileSystemList
= NULL
;
3332 if (PartitionList
== NULL
||
3333 PartitionList
->CurrentDisk
== NULL
||
3334 PartitionList
->CurrentPartition
== NULL
)
3336 /* FIXME: show an error dialog */
3340 DiskEntry
= PartitionList
->CurrentDisk
;
3341 PartEntry
= PartitionList
->CurrentPartition
;
3343 if (IsUnattendedSetup
)
3345 if (!IsValidPath(UnattendInstallationDirectory
))
3347 /* FIXME: Log the error? */
3351 BuildInstallPaths(UnattendInstallationDirectory
,
3355 return PREPARE_COPY_PAGE
;
3358 wcscpy(InstallDir
, L
"\\ReactOS");
3360 Length
= wcslen(InstallDir
);
3362 CONSOLE_SetInputTextXY(8, 11, 51, InstallDir
);
3363 CONSOLE_SetCursorXY(8 + Pos
, 11);
3364 CONSOLE_SetCursorType(TRUE
, TRUE
);
3365 MUIDisplayPage(INSTALL_DIRECTORY_PAGE
);
3369 CONSOLE_ConInKey(Ir
);
3371 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
3372 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
3374 CONSOLE_SetCursorType(TRUE
, FALSE
);
3376 if (ConfirmQuit(Ir
) != FALSE
)
3379 CONSOLE_SetCursorType(TRUE
, TRUE
);
3382 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
3383 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DELETE
)) /* DEL */
3387 memmove(&InstallDir
[Pos
],
3388 &InstallDir
[Pos
+ 1],
3389 (Length
- Pos
- 1) * sizeof(WCHAR
));
3390 InstallDir
[Length
- 1] = UNICODE_NULL
;
3393 CONSOLE_SetInputTextXY(8, 11, 51, InstallDir
);
3394 CONSOLE_SetCursorXY(8 + Pos
, 11);
3397 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
3398 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_HOME
)) /* HOME */
3401 CONSOLE_SetCursorXY(8 + Pos
, 11);
3403 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
3404 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_END
)) /* END */
3407 CONSOLE_SetCursorXY(8 + Pos
, 11);
3409 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
3410 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_LEFT
)) /* LEFT */
3415 CONSOLE_SetCursorXY(8 + Pos
, 11);
3418 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
3419 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_RIGHT
)) /* RIGHT */
3424 CONSOLE_SetCursorXY(8 + Pos
, 11);
3427 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
3429 CONSOLE_SetCursorType(TRUE
, FALSE
);
3432 * Check for the validity of the installation directory and pop up
3433 * an error if it is not the case. Then the user can fix its input.
3435 if (!IsValidPath(InstallDir
))
3437 MUIDisplayError(ERROR_DIRECTORY_NAME
, Ir
, POPUP_WAIT_ENTER
);
3438 return INSTALL_DIRECTORY_PAGE
;
3441 BuildInstallPaths(InstallDir
,
3445 return PREPARE_COPY_PAGE
;
3447 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x08) /* BACKSPACE */
3452 memmove(&InstallDir
[Pos
- 1],
3454 (Length
- Pos
) * sizeof(WCHAR
));
3455 InstallDir
[Length
- 1] = UNICODE_NULL
;
3459 CONSOLE_SetInputTextXY(8, 11, 51, InstallDir
);
3460 CONSOLE_SetCursorXY(8 + Pos
, 11);
3463 else if (isprint(Ir
->Event
.KeyEvent
.uChar
.AsciiChar
))
3467 c
= (WCHAR
)Ir
->Event
.KeyEvent
.uChar
.AsciiChar
;
3468 if (iswalpha(c
) || iswdigit(c
) || c
== '.' || c
== '\\' || c
== '-' || c
== '_')
3471 memmove(&InstallDir
[Pos
+ 1],
3473 (Length
- Pos
) * sizeof(WCHAR
));
3474 InstallDir
[Length
+ 1] = UNICODE_NULL
;
3475 InstallDir
[Pos
] = c
;
3479 CONSOLE_SetInputTextXY(8, 11, 51, InstallDir
);
3480 CONSOLE_SetCursorXY(8 + Pos
, 11);
3486 return INSTALL_DIRECTORY_PAGE
;
3491 AddSectionToCopyQueueCab(HINF InfFile
,
3493 PWCHAR SourceCabinet
,
3494 PCUNICODE_STRING DestinationPath
,
3497 INFCONTEXT FilesContext
;
3498 INFCONTEXT DirContext
;
3500 PWCHAR FileKeyValue
;
3502 PWCHAR TargetFileName
;
3504 /* Search for the SectionName section */
3505 if (!SetupFindFirstLineW(InfFile
, SectionName
, NULL
, &FilesContext
))
3508 sprintf(Buffer
, MUIGetString(STRING_TXTSETUPFAILED
), SectionName
);
3509 PopupError(Buffer
, MUIGetString(STRING_REBOOTCOMPUTER
), Ir
, POPUP_WAIT_ENTER
);
3514 * Enumerate the files in the section
3515 * and add them to the file queue.
3519 /* Get source file name and target directory id */
3520 if (!INF_GetData(&FilesContext
, &FileKeyName
, &FileKeyValue
))
3522 /* FIXME: Handle error! */
3523 DPRINT1("INF_GetData() failed\n");
3527 /* Get optional target file name */
3528 if (!INF_GetDataField(&FilesContext
, 2, &TargetFileName
))
3529 TargetFileName
= NULL
;
3531 DPRINT("FileKeyName: '%S' FileKeyValue: '%S'\n", FileKeyName
, FileKeyValue
);
3533 /* Lookup target directory */
3534 if (!SetupFindFirstLineW(InfFile
, L
"Directories", FileKeyValue
, &DirContext
))
3536 /* FIXME: Handle error! */
3537 DPRINT1("SetupFindFirstLine() failed\n");
3541 if (!INF_GetData(&DirContext
, NULL
, &DirKeyValue
))
3543 /* FIXME: Handle error! */
3544 DPRINT1("INF_GetData() failed\n");
3548 if (!SetupQueueCopy(SetupFileQueue
,
3550 SourceRootPath
.Buffer
,
3551 SourceRootDir
.Buffer
,
3556 /* FIXME: Handle error! */
3557 DPRINT1("SetupQueueCopy() failed\n");
3559 } while (SetupFindNextLine(&FilesContext
, &FilesContext
));
3566 AddSectionToCopyQueue(HINF InfFile
,
3568 PWCHAR SourceCabinet
,
3569 PCUNICODE_STRING DestinationPath
,
3572 INFCONTEXT FilesContext
;
3573 INFCONTEXT DirContext
;
3575 PWCHAR FileKeyValue
;
3577 PWCHAR TargetFileName
;
3579 WCHAR CompleteOrigDirName
[512];
3582 return AddSectionToCopyQueueCab(InfFile
, L
"SourceFiles", SourceCabinet
, DestinationPath
, Ir
);
3584 /* Search for the SectionName section */
3585 if (!SetupFindFirstLineW(InfFile
, SectionName
, NULL
, &FilesContext
))
3588 sprintf(Buffer
, MUIGetString(STRING_TXTSETUPFAILED
), SectionName
);
3589 PopupError(Buffer
, MUIGetString(STRING_REBOOTCOMPUTER
), Ir
, POPUP_WAIT_ENTER
);
3594 * Enumerate the files in the section
3595 * and add them to the file queue.
3599 /* Get source file name and target directory id */
3600 if (!INF_GetData(&FilesContext
, &FileKeyName
, &FileKeyValue
))
3602 /* FIXME: Handle error! */
3603 DPRINT1("INF_GetData() failed\n");
3607 /* Get target directory id */
3608 if (!INF_GetDataField(&FilesContext
, 13, &FileKeyValue
))
3610 /* FIXME: Handle error! */
3611 DPRINT1("INF_GetData() failed\n");
3615 /* Get optional target file name */
3616 if (!INF_GetDataField(&FilesContext
, 11, &TargetFileName
))
3617 TargetFileName
= NULL
;
3618 else if (!*TargetFileName
)
3619 TargetFileName
= NULL
;
3621 DPRINT("FileKeyName: '%S' FileKeyValue: '%S'\n", FileKeyName
, FileKeyValue
);
3623 /* Lookup target directory */
3624 if (!SetupFindFirstLineW(InfFile
, L
"Directories", FileKeyValue
, &DirContext
))
3626 /* FIXME: Handle error! */
3627 DPRINT1("SetupFindFirstLine() failed\n");
3631 if (!INF_GetData(&DirContext
, NULL
, &DirKeyValue
))
3633 /* FIXME: Handle error! */
3634 DPRINT1("INF_GetData() failed\n");
3638 if ((DirKeyValue
[0] == 0) || (DirKeyValue
[0] == L
'\\' && DirKeyValue
[1] == 0))
3640 /* Installation path */
3641 wcscpy(CompleteOrigDirName
, SourceRootDir
.Buffer
);
3643 else if (DirKeyValue
[0] == L
'\\')
3646 wcscpy(CompleteOrigDirName
, DirKeyValue
);
3648 else // if (DirKeyValue[0] != L'\\')
3650 /* Path relative to the installation path */
3651 wcscpy(CompleteOrigDirName
, SourceRootDir
.Buffer
);
3652 wcscat(CompleteOrigDirName
, L
"\\");
3653 wcscat(CompleteOrigDirName
, DirKeyValue
);
3656 /* Remove trailing backslash */
3657 Length
= wcslen(CompleteOrigDirName
);
3658 if ((Length
> 0) && (CompleteOrigDirName
[Length
- 1] == L
'\\'))
3660 CompleteOrigDirName
[Length
- 1] = 0;
3663 if (!SetupQueueCopy(SetupFileQueue
,
3665 SourceRootPath
.Buffer
,
3666 CompleteOrigDirName
,
3671 /* FIXME: Handle error! */
3672 DPRINT1("SetupQueueCopy() failed\n");
3674 } while (SetupFindNextLine(&FilesContext
, &FilesContext
));
3681 PrepareCopyPageInfFile(HINF InfFile
,
3682 PWCHAR SourceCabinet
,
3685 WCHAR PathBuffer
[MAX_PATH
];
3686 INFCONTEXT DirContext
;
3687 PWCHAR AdditionalSectionName
= NULL
;
3692 /* Add common files */
3693 if (!AddSectionToCopyQueue(InfFile
, L
"SourceDisksFiles", SourceCabinet
, &DestinationPath
, Ir
))
3696 /* Add specific files depending of computer type */
3697 if (SourceCabinet
== NULL
)
3699 if (!ProcessComputerFiles(InfFile
, ComputerList
, &AdditionalSectionName
))
3702 if (AdditionalSectionName
)
3704 if (!AddSectionToCopyQueue(InfFile
, AdditionalSectionName
, SourceCabinet
, &DestinationPath
, Ir
))
3709 /* Create directories */
3713 * - Install directories like '\reactos\test' are not handled yet.
3714 * - Copying files to DestinationRootPath should be done from within
3715 * the SystemPartitionFiles section.
3716 * At the moment we check whether we specify paths like '\foo' or '\\' for that.
3717 * For installing to DestinationPath specify just '\' .
3720 /* Get destination path */
3721 wcscpy(PathBuffer
, DestinationPath
.Buffer
);
3723 /* Remove trailing backslash */
3724 Length
= wcslen(PathBuffer
);
3725 if ((Length
> 0) && (PathBuffer
[Length
- 1] == L
'\\'))
3727 PathBuffer
[Length
- 1] = 0;
3730 /* Create the install directory */
3731 Status
= SetupCreateDirectory(PathBuffer
);
3732 if (!NT_SUCCESS(Status
) && Status
!= STATUS_OBJECT_NAME_COLLISION
)
3734 DPRINT1("Creating directory '%S' failed: Status = 0x%08lx", PathBuffer
, Status
);
3735 MUIDisplayError(ERROR_CREATE_INSTALL_DIR
, Ir
, POPUP_WAIT_ENTER
);
3739 /* Search for the 'Directories' section */
3740 if (!SetupFindFirstLineW(InfFile
, L
"Directories", NULL
, &DirContext
))
3744 MUIDisplayError(ERROR_CABINET_SECTION
, Ir
, POPUP_WAIT_ENTER
);
3748 MUIDisplayError(ERROR_TXTSETUP_SECTION
, Ir
, POPUP_WAIT_ENTER
);
3754 /* Enumerate the directory values and create the subdirectories */
3757 if (!INF_GetData(&DirContext
, NULL
, &DirKeyValue
))
3763 if ((DirKeyValue
[0] == 0) || (DirKeyValue
[0] == L
'\\' && DirKeyValue
[1] == 0))
3765 /* Installation path */
3766 DPRINT("InstallationPath: '%S'\n", DirKeyValue
);
3768 wcscpy(PathBuffer
, DestinationPath
.Buffer
);
3770 DPRINT("FullPath: '%S'\n", PathBuffer
);
3772 else if (DirKeyValue
[0] == L
'\\')
3775 DPRINT("Absolute Path: '%S'\n", DirKeyValue
);
3777 wcscpy(PathBuffer
, DestinationRootPath
.Buffer
);
3778 wcscat(PathBuffer
, DirKeyValue
);
3780 /* Remove trailing backslash */
3781 Length
= wcslen(PathBuffer
);
3782 if ((Length
> 0) && (PathBuffer
[Length
- 1] == L
'\\'))
3784 PathBuffer
[Length
- 1] = 0;
3787 DPRINT("FullPath: '%S'\n", PathBuffer
);
3789 Status
= SetupCreateDirectory(PathBuffer
);
3790 if (!NT_SUCCESS(Status
) && Status
!= STATUS_OBJECT_NAME_COLLISION
)
3792 DPRINT("Creating directory '%S' failed: Status = 0x%08lx", PathBuffer
, Status
);
3793 MUIDisplayError(ERROR_CREATE_DIR
, Ir
, POPUP_WAIT_ENTER
);
3797 else // if (DirKeyValue[0] != L'\\')
3799 /* Path relative to the installation path */
3800 DPRINT("RelativePath: '%S'\n", DirKeyValue
);
3802 wcscpy(PathBuffer
, DestinationPath
.Buffer
);
3803 wcscat(PathBuffer
, L
"\\");
3804 wcscat(PathBuffer
, DirKeyValue
);
3806 /* Remove trailing backslash */
3807 Length
= wcslen(PathBuffer
);
3808 if ((Length
> 0) && (PathBuffer
[Length
- 1] == L
'\\'))
3810 PathBuffer
[Length
- 1] = 0;
3813 DPRINT("FullPath: '%S'\n", PathBuffer
);
3815 Status
= SetupCreateDirectory(PathBuffer
);
3816 if (!NT_SUCCESS(Status
) && Status
!= STATUS_OBJECT_NAME_COLLISION
)
3818 DPRINT("Creating directory '%S' failed: Status = 0x%08lx", PathBuffer
, Status
);
3819 MUIDisplayError(ERROR_CREATE_DIR
, Ir
, POPUP_WAIT_ENTER
);
3823 } while (SetupFindNextLine(&DirContext
, &DirContext
));
3830 * Displays the PrepareCopyPage.
3833 * FileCopyPage(At once)
3837 * Inits SetupFileQueue
3838 * Calls PrepareCopyPageInfFile
3841 * Number of the next page.
3844 PrepareCopyPage(PINPUT_RECORD Ir
)
3847 WCHAR PathBuffer
[MAX_PATH
];
3848 INFCONTEXT CabinetsContext
;
3854 MUIDisplayPage(PREPARE_COPY_PAGE
);
3856 /* Create the file queue */
3857 SetupFileQueue
= SetupOpenFileQueue();
3858 if (SetupFileQueue
== NULL
)
3860 MUIDisplayError(ERROR_COPY_QUEUE
, Ir
, POPUP_WAIT_ENTER
);
3864 if (!PrepareCopyPageInfFile(SetupInf
, NULL
, Ir
))
3866 /* FIXME: show an error dialog */
3870 /* Search for the 'Cabinets' section */
3871 if (!SetupFindFirstLineW(SetupInf
, L
"Cabinets", NULL
, &CabinetsContext
))
3873 return FILE_COPY_PAGE
;
3877 * Enumerate the directory values in the 'Cabinets'
3878 * section and parse their inf files.
3882 if (!INF_GetData(&CabinetsContext
, NULL
, &KeyValue
))
3885 wcscpy(PathBuffer
, SourcePath
.Buffer
);
3886 wcscat(PathBuffer
, L
"\\");
3887 wcscat(PathBuffer
, KeyValue
);
3889 CabinetInitialize();
3890 CabinetSetEventHandlers(NULL
, NULL
, NULL
);
3891 CabinetSetCabinetName(PathBuffer
);
3893 if (CabinetOpen() == CAB_STATUS_SUCCESS
)
3895 DPRINT("Cabinet %S\n", CabinetGetCabinetName());
3897 InfFileData
= CabinetGetCabinetReservedArea(&InfFileSize
);
3898 if (InfFileData
== NULL
)
3900 MUIDisplayError(ERROR_CABINET_SCRIPT
, Ir
, POPUP_WAIT_ENTER
);
3906 DPRINT("Cannot open cabinet: %S.\n", CabinetGetCabinetName());
3907 MUIDisplayError(ERROR_CABINET_MISSING
, Ir
, POPUP_WAIT_ENTER
);
3911 InfHandle
= INF_OpenBufferedFileA((CHAR
*) InfFileData
,
3918 if (InfHandle
== INVALID_HANDLE_VALUE
)
3920 MUIDisplayError(ERROR_INVALID_CABINET_INF
, Ir
, POPUP_WAIT_ENTER
);
3926 if (!PrepareCopyPageInfFile(InfHandle
, KeyValue
, Ir
))
3928 /* FIXME: show an error dialog */
3931 } while (SetupFindNextLine(&CabinetsContext
, &CabinetsContext
));
3933 return FILE_COPY_PAGE
;
3939 SetupUpdateMemoryInfo(IN PCOPYCONTEXT CopyContext
,
3942 SYSTEM_PERFORMANCE_INFORMATION PerfInfo
;
3944 /* Get the memory information from the system */
3945 NtQuerySystemInformation(SystemPerformanceInformation
,
3950 /* Check if this is initial setup */
3953 /* Set maximum limits to be total RAM pages */
3954 ProgressSetStepCount(CopyContext
->MemoryBars
[0], PerfInfo
.CommitLimit
);
3955 ProgressSetStepCount(CopyContext
->MemoryBars
[1], PerfInfo
.CommitLimit
);
3956 ProgressSetStepCount(CopyContext
->MemoryBars
[2], PerfInfo
.CommitLimit
);
3959 /* Set current values */
3960 ProgressSetStep(CopyContext
->MemoryBars
[0], PerfInfo
.PagedPoolPages
+ PerfInfo
.NonPagedPoolPages
);
3961 ProgressSetStep(CopyContext
->MemoryBars
[1], PerfInfo
.ResidentSystemCachePage
);
3962 ProgressSetStep(CopyContext
->MemoryBars
[2], PerfInfo
.AvailablePages
);
3968 FileCopyCallback(PVOID Context
,
3973 PCOPYCONTEXT CopyContext
;
3975 CopyContext
= (PCOPYCONTEXT
)Context
;
3977 switch (Notification
)
3979 case SPFILENOTIFY_STARTSUBQUEUE
:
3980 CopyContext
->TotalOperations
= (ULONG
)Param2
;
3981 ProgressSetStepCount(CopyContext
->ProgressBar
,
3982 CopyContext
->TotalOperations
);
3983 SetupUpdateMemoryInfo(CopyContext
, TRUE
);
3986 case SPFILENOTIFY_STARTCOPY
:
3987 /* Display copy message */
3988 CONSOLE_SetStatusText(MUIGetString(STRING_COPYING
), (PWSTR
)Param1
);
3989 SetupUpdateMemoryInfo(CopyContext
, FALSE
);
3992 case SPFILENOTIFY_ENDCOPY
:
3993 CopyContext
->CompletedOperations
++;
3995 /* SYSREG checkpoint */
3996 if (CopyContext
->TotalOperations
>> 1 == CopyContext
->CompletedOperations
)
3997 DPRINT1("CHECKPOINT:HALF_COPIED\n");
3999 ProgressNextStep(CopyContext
->ProgressBar
);
4000 SetupUpdateMemoryInfo(CopyContext
, FALSE
);
4009 * Displays the FileCopyPage.
4012 * RegistryPage(At once)
4015 * Calls SetupCommitFileQueueW
4016 * Calls SetupCloseFileQueue
4019 * Number of the next page.
4023 FileCopyPage(PINPUT_RECORD Ir
)
4025 COPYCONTEXT CopyContext
;
4026 unsigned int mem_bar_width
;
4028 MUIDisplayPage(FILE_COPY_PAGE
);
4030 /* Create context for the copy process */
4031 CopyContext
.DestinationRootPath
= DestinationRootPath
.Buffer
;
4032 CopyContext
.InstallPath
= InstallPath
.Buffer
;
4033 CopyContext
.TotalOperations
= 0;
4034 CopyContext
.CompletedOperations
= 0;
4036 /* Create the progress bar as well */
4037 CopyContext
.ProgressBar
= CreateProgressBar(13,
4044 MUIGetString(STRING_SETUPCOPYINGFILES
));
4046 // fit memory bars to screen width, distribute them uniform
4047 mem_bar_width
= (xScreen
- 26) / 5;
4048 mem_bar_width
-= mem_bar_width
% 2; // make even
4049 /* ATTENTION: The following progress bars are debug stuff, which should not be translated!! */
4050 /* Create the paged pool progress bar */
4051 CopyContext
.MemoryBars
[0] = CreateProgressBar(13,
4060 /* Create the non paged pool progress bar */
4061 CopyContext
.MemoryBars
[1] = CreateProgressBar((xScreen
/ 2)- (mem_bar_width
/ 2),
4063 (xScreen
/ 2) + (mem_bar_width
/ 2),
4065 (xScreen
/ 2)- (mem_bar_width
/ 2),
4070 /* Create the global memory progress bar */
4071 CopyContext
.MemoryBars
[2] = CreateProgressBar(xScreen
- 13 - mem_bar_width
,
4075 xScreen
- 13 - mem_bar_width
,
4080 /* Do the file copying */
4081 SetupCommitFileQueueW(NULL
,
4086 /* If we get here, we're done, so cleanup the queue and progress bar */
4087 SetupCloseFileQueue(SetupFileQueue
);
4088 DestroyProgressBar(CopyContext
.ProgressBar
);
4089 DestroyProgressBar(CopyContext
.MemoryBars
[0]);
4090 DestroyProgressBar(CopyContext
.MemoryBars
[1]);
4091 DestroyProgressBar(CopyContext
.MemoryBars
[2]);
4093 /* Go display the next page */
4094 return REGISTRY_PAGE
;
4099 * Displays the RegistryPage.
4102 * SuccessPage (if RepairUpdate)
4103 * BootLoaderPage (default)
4107 * Calls SetInstallPathValue
4108 * Calls NtInitializeRegistry
4109 * Calls ImportRegistryFile
4110 * Calls SetDefaultPagefile
4111 * Calls SetMountedDeviceValues
4114 * Number of the next page.
4117 RegistryPage(PINPUT_RECORD Ir
)
4119 INFCONTEXT InfContext
;
4126 MUIDisplayPage(REGISTRY_PAGE
);
4128 if (RepairUpdateFlag
)
4130 return SUCCESS_PAGE
;
4133 if (!SetInstallPathValue(&DestinationPath
))
4135 DPRINT1("SetInstallPathValue() failed\n");
4136 MUIDisplayError(ERROR_INITIALIZE_REGISTRY
, Ir
, POPUP_WAIT_ENTER
);
4140 /* Create the default hives */
4141 Status
= NtInitializeRegistry(CM_BOOT_FLAG_SETUP
);
4142 if (!NT_SUCCESS(Status
))
4144 DPRINT1("NtInitializeRegistry() failed (Status %lx)\n", Status
);
4145 MUIDisplayError(ERROR_CREATE_HIVE
, Ir
, POPUP_WAIT_ENTER
);
4149 /* Update registry */
4150 CONSOLE_SetStatusText(MUIGetString(STRING_REGHIVEUPDATE
));
4152 if (!SetupFindFirstLineW(SetupInf
, L
"HiveInfs.Install", NULL
, &InfContext
))
4154 DPRINT1("SetupFindFirstLine() failed\n");
4155 MUIDisplayError(ERROR_FIND_REGISTRY
, Ir
, POPUP_WAIT_ENTER
);
4161 INF_GetDataField(&InfContext
, 0, &Action
);
4162 INF_GetDataField(&InfContext
, 1, &File
);
4163 INF_GetDataField(&InfContext
, 2, &Section
);
4165 DPRINT("Action: %S File: %S Section %S\n", Action
, File
, Section
);
4170 if (!_wcsicmp(Action
, L
"AddReg"))
4174 else if (!_wcsicmp(Action
, L
"DelReg"))
4183 CONSOLE_SetStatusText(MUIGetString(STRING_IMPORTFILE
), File
);
4185 if (!ImportRegistryFile(File
, Section
, LanguageId
, Delete
))
4187 DPRINT1("Importing %S failed\n", File
);
4189 MUIDisplayError(ERROR_IMPORT_HIVE
, Ir
, POPUP_WAIT_ENTER
);
4192 } while (SetupFindNextLine(&InfContext
, &InfContext
));
4194 /* Update display registry settings */
4195 CONSOLE_SetStatusText(MUIGetString(STRING_DISPLAYETTINGSUPDATE
));
4196 if (!ProcessDisplayRegistry(SetupInf
, DisplayList
))
4198 MUIDisplayError(ERROR_UPDATE_DISPLAY_SETTINGS
, Ir
, POPUP_WAIT_ENTER
);
4202 /* Set the locale */
4203 CONSOLE_SetStatusText(MUIGetString(STRING_LOCALESETTINGSUPDATE
));
4204 if (!ProcessLocaleRegistry(LanguageList
))
4206 MUIDisplayError(ERROR_UPDATE_LOCALESETTINGS
, Ir
, POPUP_WAIT_ENTER
);
4210 /* Add keyboard layouts */
4211 CONSOLE_SetStatusText(MUIGetString(STRING_ADDKBLAYOUTS
));
4212 if (!AddKeyboardLayouts())
4214 MUIDisplayError(ERROR_ADDING_KBLAYOUTS
, Ir
, POPUP_WAIT_ENTER
);
4220 if (!SetGeoID(MUIGetGeoID()))
4222 MUIDisplayError(ERROR_UPDATE_GEOID
, Ir
, POPUP_WAIT_ENTER
);
4226 if (!IsUnattendedSetup
)
4228 /* Update keyboard layout settings */
4229 CONSOLE_SetStatusText(MUIGetString(STRING_KEYBOARDSETTINGSUPDATE
));
4230 if (!ProcessKeyboardLayoutRegistry(LayoutList
))
4232 MUIDisplayError(ERROR_UPDATE_KBSETTINGS
, Ir
, POPUP_WAIT_ENTER
);
4237 /* Add codepage information to registry */
4238 CONSOLE_SetStatusText(MUIGetString(STRING_CODEPAGEINFOUPDATE
));
4241 MUIDisplayError(ERROR_ADDING_CODEPAGE
, Ir
, POPUP_WAIT_ENTER
);
4245 /* Set the default pagefile entry */
4246 SetDefaultPagefile(DestinationDriveLetter
);
4248 /* Update the mounted devices list */
4249 SetMountedDeviceValues(PartitionList
);
4251 CONSOLE_SetStatusText(MUIGetString(STRING_DONE
));
4253 return BOOT_LOADER_PAGE
;
4258 * Displays the BootLoaderPage.
4261 * SuccessPage (if RepairUpdate)
4262 * BootLoaderHarddiskMbrPage
4263 * BootLoaderHarddiskVbrPage
4264 * BootLoaderFloppyPage
4269 * Calls SetInstallPathValue
4270 * Calls NtInitializeRegistry
4271 * Calls ImportRegistryFile
4272 * Calls SetDefaultPagefile
4273 * Calls SetMountedDeviceValues
4276 * Number of the next page.
4279 BootLoaderPage(PINPUT_RECORD Ir
)
4281 UCHAR PartitionType
;
4282 BOOLEAN InstallOnFloppy
;
4284 WCHAR PathBuffer
[MAX_PATH
];
4286 CONSOLE_SetStatusText(MUIGetString(STRING_PLEASEWAIT
));
4288 RtlFreeUnicodeString(&SystemRootPath
);
4289 swprintf(PathBuffer
,
4290 L
"\\Device\\Harddisk%lu\\Partition%lu",
4291 PartitionList
->SystemDisk
->DiskNumber
,
4292 PartitionList
->SystemPartition
->PartitionNumber
);
4293 RtlCreateUnicodeString(&SystemRootPath
, PathBuffer
);
4294 DPRINT1("SystemRootPath: %wZ\n", &SystemRootPath
);
4296 PartitionType
= PartitionList
->SystemPartition
->PartitionType
;
4298 if (IsUnattendedSetup
)
4300 if (UnattendMBRInstallType
== 0) /* skip MBR installation */
4302 return SUCCESS_PAGE
;
4304 else if (UnattendMBRInstallType
== 1) /* install on floppy */
4306 return BOOT_LOADER_FLOPPY_PAGE
;
4310 if (PartitionType
== PARTITION_ENTRY_UNUSED
)
4312 DPRINT("Error: system partition invalid (unused)\n");
4313 InstallOnFloppy
= TRUE
;
4315 else if (PartitionType
== PARTITION_OS2BOOTMGR
)
4317 /* OS/2 boot manager partition */
4318 DPRINT("Found OS/2 boot manager partition\n");
4319 InstallOnFloppy
= TRUE
;
4321 else if (PartitionType
== PARTITION_EXT2
)
4323 /* Linux EXT2 partition */
4324 DPRINT("Found Linux EXT2 partition\n");
4325 InstallOnFloppy
= FALSE
;
4327 else if (PartitionType
== PARTITION_IFS
)
4329 /* NTFS partition */
4330 DPRINT("Found NTFS partition\n");
4332 // FIXME: Make it FALSE when we'll support NTFS installation!
4333 InstallOnFloppy
= TRUE
;
4335 else if ((PartitionType
== PARTITION_FAT_12
) ||
4336 (PartitionType
== PARTITION_FAT_16
) ||
4337 (PartitionType
== PARTITION_HUGE
) ||
4338 (PartitionType
== PARTITION_XINT13
) ||
4339 (PartitionType
== PARTITION_FAT32
) ||
4340 (PartitionType
== PARTITION_FAT32_XINT13
))
4342 DPRINT("Found FAT partition\n");
4343 InstallOnFloppy
= FALSE
;
4347 /* Unknown partition */
4348 DPRINT("Unknown partition found\n");
4349 InstallOnFloppy
= TRUE
;
4352 if (InstallOnFloppy
!= FALSE
)
4354 return BOOT_LOADER_FLOPPY_PAGE
;
4357 /* Unattended install on hdd? */
4358 if (IsUnattendedSetup
&& UnattendMBRInstallType
== 2)
4360 return BOOT_LOADER_HARDDISK_MBR_PAGE
;
4363 MUIDisplayPage(BOOT_LOADER_PAGE
);
4364 CONSOLE_InvertTextXY(8, Line
, 60, 1);
4368 CONSOLE_ConInKey(Ir
);
4370 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
4371 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
)) /* DOWN */
4373 CONSOLE_NormalTextXY(8, Line
, 60, 1);
4382 CONSOLE_InvertTextXY(8, Line
, 60, 1);
4384 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
4385 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_UP
)) /* UP */
4387 CONSOLE_NormalTextXY(8, Line
, 60, 1);
4396 CONSOLE_InvertTextXY(8, Line
, 60, 1);
4398 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
4399 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
4401 if (ConfirmQuit(Ir
) != FALSE
)
4406 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
4410 return BOOT_LOADER_HARDDISK_MBR_PAGE
;
4412 else if (Line
== 13)
4414 return BOOT_LOADER_HARDDISK_VBR_PAGE
;
4416 else if (Line
== 14)
4418 return BOOT_LOADER_FLOPPY_PAGE
;
4420 else if (Line
== 15)
4422 return SUCCESS_PAGE
;
4425 return BOOT_LOADER_PAGE
;
4429 return BOOT_LOADER_PAGE
;
4434 * Displays the BootLoaderFloppyPage.
4437 * SuccessPage (At once)
4441 * Calls InstallFatBootcodeToFloppy()
4444 * Number of the next page.
4447 BootLoaderFloppyPage(PINPUT_RECORD Ir
)
4451 MUIDisplayPage(BOOT_LOADER_FLOPPY_PAGE
);
4453 // SetStatusText(" Please wait...");
4457 CONSOLE_ConInKey(Ir
);
4459 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
4460 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
4462 if (ConfirmQuit(Ir
) != FALSE
)
4467 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
4469 if (DoesFileExist(L
"\\Device\\Floppy0", L
"\\") == FALSE
)
4471 MUIDisplayError(ERROR_NO_FLOPPY
, Ir
, POPUP_WAIT_ENTER
);
4472 return BOOT_LOADER_FLOPPY_PAGE
;
4475 Status
= InstallFatBootcodeToFloppy(&SourceRootPath
, &DestinationArcPath
);
4476 if (!NT_SUCCESS(Status
))
4478 /* Print error message */
4479 return BOOT_LOADER_FLOPPY_PAGE
;
4482 return SUCCESS_PAGE
;
4486 return BOOT_LOADER_FLOPPY_PAGE
;
4491 * Displays the BootLoaderHarddiskVbrPage.
4494 * SuccessPage (At once)
4498 * Calls InstallVBRToPartition()
4501 * Number of the next page.
4504 BootLoaderHarddiskVbrPage(PINPUT_RECORD Ir
)
4506 UCHAR PartitionType
;
4509 PartitionType
= PartitionList
->SystemPartition
->PartitionType
;
4511 Status
= InstallVBRToPartition(&SystemRootPath
,
4513 &DestinationArcPath
,
4515 if (!NT_SUCCESS(Status
))
4517 MUIDisplayError(ERROR_WRITE_BOOT
, Ir
, POPUP_WAIT_ENTER
);
4521 return SUCCESS_PAGE
;
4526 * Displays the BootLoaderHarddiskMbrPage.
4529 * SuccessPage (At once)
4533 * Calls InstallVBRToPartition()
4534 * CallsInstallMbrBootCodeToDisk()
4537 * Number of the next page.
4540 BootLoaderHarddiskMbrPage(PINPUT_RECORD Ir
)
4542 UCHAR PartitionType
;
4544 WCHAR DestinationDevicePathBuffer
[MAX_PATH
];
4545 WCHAR SourceMbrPathBuffer
[MAX_PATH
];
4546 WCHAR DstPath
[MAX_PATH
];
4548 /* Step 1: Write the VBR */
4549 PartitionType
= PartitionList
->SystemPartition
->PartitionType
;
4551 Status
= InstallVBRToPartition(&SystemRootPath
,
4553 &DestinationArcPath
,
4555 if (!NT_SUCCESS(Status
))
4557 MUIDisplayError(ERROR_WRITE_BOOT
, Ir
, POPUP_WAIT_ENTER
);
4561 /* Step 2: Write the MBR */
4562 swprintf(DestinationDevicePathBuffer
,
4563 L
"\\Device\\Harddisk%d\\Partition0",
4564 PartitionList
->SystemDisk
->DiskNumber
);
4566 wcscpy(SourceMbrPathBuffer
, SourceRootPath
.Buffer
);
4567 wcscat(SourceMbrPathBuffer
, L
"\\loader\\dosmbr.bin");
4569 if (IsThereAValidBootSector(DestinationDevicePathBuffer
))
4571 /* Save current MBR */
4572 wcscpy(DstPath
, SystemRootPath
.Buffer
);
4573 wcscat(DstPath
, L
"\\mbr.old");
4575 DPRINT1("Save MBR: %S ==> %S\n", DestinationDevicePathBuffer
, DstPath
);
4576 Status
= SaveBootSector(DestinationDevicePathBuffer
, DstPath
, sizeof(PARTITION_SECTOR
));
4577 if (!NT_SUCCESS(Status
))
4579 DPRINT1("SaveBootSector() failed (Status %lx)\n", Status
);
4580 // Don't care if we succeeded or not saving the old MBR, just go ahead.
4584 DPRINT1("Install MBR bootcode: %S ==> %S\n",
4585 SourceMbrPathBuffer
, DestinationDevicePathBuffer
);
4586 Status
= InstallMbrBootCodeToDisk(SourceMbrPathBuffer
,
4587 DestinationDevicePathBuffer
);
4588 if (!NT_SUCCESS(Status
))
4590 DPRINT1("InstallMbrBootCodeToDisk() failed (Status %lx)\n",
4592 MUIDisplayError(ERROR_INSTALL_BOOTCODE
, Ir
, POPUP_WAIT_ENTER
);
4596 return SUCCESS_PAGE
;
4601 * Displays the QuitPage.
4604 * FlushPage (At once)
4610 * Number of the next page.
4613 QuitPage(PINPUT_RECORD Ir
)
4615 MUIDisplayPage(QUIT_PAGE
);
4617 /* Destroy partition list */
4618 if (PartitionList
!= NULL
)
4620 DestroyPartitionList(PartitionList
);
4621 PartitionList
= NULL
;
4624 /* Destroy filesystem list */
4625 if (FileSystemList
!= NULL
)
4627 DestroyFileSystemList(FileSystemList
);
4628 FileSystemList
= NULL
;
4631 /* Destroy computer settings list */
4632 if (ComputerList
!= NULL
)
4634 DestroyGenericList(ComputerList
, TRUE
);
4635 ComputerList
= NULL
;
4638 /* Destroy display settings list */
4639 if (DisplayList
!= NULL
)
4641 DestroyGenericList(DisplayList
, TRUE
);
4645 /* Destroy keyboard settings list */
4646 if (KeyboardList
!= NULL
)
4648 DestroyGenericList(KeyboardList
, TRUE
);
4649 KeyboardList
= NULL
;
4652 /* Destroy keyboard layout list */
4653 if (LayoutList
!= NULL
)
4655 DestroyGenericList(LayoutList
, TRUE
);
4659 if (LanguageList
!= NULL
)
4661 DestroyGenericList(LanguageList
, FALSE
);
4662 LanguageList
= NULL
;
4665 CONSOLE_SetStatusText(MUIGetString(STRING_REBOOTCOMPUTER2
));
4669 CONSOLE_ConInKey(Ir
);
4671 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
4680 * Displays the SuccessPage.
4683 * FlushPage (At once)
4689 * Number of the next page.
4692 SuccessPage(PINPUT_RECORD Ir
)
4694 MUIDisplayPage(SUCCESS_PAGE
);
4696 if (IsUnattendedSetup
)
4703 CONSOLE_ConInKey(Ir
);
4705 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
4714 * Displays the FlushPage.
4717 * RebootPage (At once)
4720 * Number of the next page.
4723 FlushPage(PINPUT_RECORD Ir
)
4725 MUIDisplayPage(FLUSH_PAGE
);
4731 PnpEventThread(IN LPVOID lpParameter
);
4735 * The start routine and page management
4746 NtQuerySystemTime(&Time
);
4748 Status
= RtlCreateUserThread(NtCurrentProcess(),
4758 if (!NT_SUCCESS(Status
))
4759 hPnpThread
= INVALID_HANDLE_VALUE
;
4761 if (!CONSOLE_Init())
4763 PrintString(MUIGetString(STRING_CONSOLEFAIL1
));
4764 PrintString(MUIGetString(STRING_CONSOLEFAIL2
));
4765 PrintString(MUIGetString(STRING_CONSOLEFAIL3
));
4767 /* Raise a hard error (crash the system/BSOD) */
4768 NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED
,
4772 /* Initialize global unicode strings */
4773 RtlInitUnicodeString(&SourcePath
, NULL
);
4774 RtlInitUnicodeString(&SourceRootPath
, NULL
);
4775 RtlInitUnicodeString(&SourceRootDir
, NULL
);
4776 RtlInitUnicodeString(&InstallPath
, NULL
);
4777 RtlInitUnicodeString(&DestinationPath
, NULL
);
4778 RtlInitUnicodeString(&DestinationArcPath
, NULL
);
4779 RtlInitUnicodeString(&DestinationRootPath
, NULL
);
4780 RtlInitUnicodeString(&SystemRootPath
, NULL
);
4782 /* Hide the cursor */
4783 CONSOLE_SetCursorType(TRUE
, FALSE
);
4786 while (Page
!= REBOOT_PAGE
&& Page
!= RECOVERY_PAGE
)
4788 CONSOLE_ClearScreen();
4791 //CONSOLE_SetUnderlinedTextXY(4, 3, " ReactOS " KERNEL_VERSION_STR " Setup ");
4798 Page
= SetupStartPage(&Ir
);
4803 Page
= LanguagePage(&Ir
);
4808 Page
= LicensePage(&Ir
);
4813 Page
= IntroPage(&Ir
);
4817 case INSTALL_INTRO_PAGE
:
4818 Page
= InstallIntroPage(&Ir
);
4822 case SCSI_CONTROLLER_PAGE
:
4823 Page
= ScsiControllerPage(&Ir
);
4828 case OEM_DRIVER_PAGE
:
4829 Page
= OemDriverPage(&Ir
);
4833 case DEVICE_SETTINGS_PAGE
:
4834 Page
= DeviceSettingsPage(&Ir
);
4837 case COMPUTER_SETTINGS_PAGE
:
4838 Page
= ComputerSettingsPage(&Ir
);
4841 case DISPLAY_SETTINGS_PAGE
:
4842 Page
= DisplaySettingsPage(&Ir
);
4845 case KEYBOARD_SETTINGS_PAGE
:
4846 Page
= KeyboardSettingsPage(&Ir
);
4849 case LAYOUT_SETTINGS_PAGE
:
4850 Page
= LayoutSettingsPage(&Ir
);
4853 case SELECT_PARTITION_PAGE
:
4854 Page
= SelectPartitionPage(&Ir
);
4857 case CREATE_PRIMARY_PARTITION_PAGE
:
4858 Page
= CreatePrimaryPartitionPage(&Ir
);
4861 case CREATE_EXTENDED_PARTITION_PAGE
:
4862 Page
= CreateExtendedPartitionPage(&Ir
);
4865 case CREATE_LOGICAL_PARTITION_PAGE
:
4866 Page
= CreateLogicalPartitionPage(&Ir
);
4869 case CONFIRM_DELETE_SYSTEM_PARTITION_PAGE
:
4870 Page
= ConfirmDeleteSystemPartitionPage(&Ir
);
4873 case DELETE_PARTITION_PAGE
:
4874 Page
= DeletePartitionPage(&Ir
);
4877 case SELECT_FILE_SYSTEM_PAGE
:
4878 Page
= SelectFileSystemPage(&Ir
);
4881 case FORMAT_PARTITION_PAGE
:
4882 Page
= (PAGE_NUMBER
) FormatPartitionPage(&Ir
);
4885 case CHECK_FILE_SYSTEM_PAGE
:
4886 Page
= (PAGE_NUMBER
) CheckFileSystemPage(&Ir
);
4889 case INSTALL_DIRECTORY_PAGE
:
4890 Page
= InstallDirectoryPage(&Ir
);
4893 case PREPARE_COPY_PAGE
:
4894 Page
= PrepareCopyPage(&Ir
);
4897 case FILE_COPY_PAGE
:
4898 Page
= FileCopyPage(&Ir
);
4902 Page
= RegistryPage(&Ir
);
4905 case BOOT_LOADER_PAGE
:
4906 Page
= BootLoaderPage(&Ir
);
4909 case BOOT_LOADER_FLOPPY_PAGE
:
4910 Page
= BootLoaderFloppyPage(&Ir
);
4913 case BOOT_LOADER_HARDDISK_MBR_PAGE
:
4914 Page
= BootLoaderHarddiskMbrPage(&Ir
);
4917 case BOOT_LOADER_HARDDISK_VBR_PAGE
:
4918 Page
= BootLoaderHarddiskVbrPage(&Ir
);
4922 case REPAIR_INTRO_PAGE
:
4923 Page
= RepairIntroPage(&Ir
);
4927 Page
= SuccessPage(&Ir
);
4931 Page
= FlushPage(&Ir
);
4935 Page
= QuitPage(&Ir
);
4944 if (Page
== RECOVERY_PAGE
)
4949 /* Avoid bugcheck */
4950 Time
.QuadPart
+= 50000000;
4951 NtDelayExecution(FALSE
, &Time
);
4954 RtlAdjustPrivilege(SE_SHUTDOWN_PRIVILEGE
, TRUE
, FALSE
, &Old
);
4955 NtShutdownSystem(ShutdownReboot
);
4956 RtlAdjustPrivilege(SE_SHUTDOWN_PRIVILEGE
, Old
, FALSE
, &Old
);
4957 NtTerminateProcess(NtCurrentProcess(), 0);
4962 NtProcessStartup(PPEB Peb
)
4964 RtlNormalizeProcessParams(Peb
->ProcessParameters
);
4966 ProcessHeap
= Peb
->ProcessHeap
;
4967 InfSetHeap(ProcessHeap
);