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/interface/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
== TRUE
)
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
== TRUE
)
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 * Number of the next page.
636 LanguagePage(PINPUT_RECORD Ir
)
638 PWCHAR NewLanguageId
;
639 BOOL RefreshPage
= FALSE
;
641 /* Initialize the computer settings list */
642 if (LanguageList
== NULL
)
644 LanguageList
= CreateLanguageList(SetupInf
, DefaultLanguage
);
646 if (LanguageList
== NULL
)
648 PopupError("Setup failed to initialize available translations", NULL
, NULL
, POPUP_WAIT_NONE
);
654 SelectedLanguageId
= DefaultLanguage
;
655 SetConsoleCodePage();
658 /* If there's just a single language in the list skip
659 * the language selection process altogether! */
660 if (GenericListHasSingleEntry(LanguageList
))
663 DrawGenericList(LanguageList
,
669 ScrollToPositionGenericList(LanguageList
, GetDefaultLanguageIndex());
671 MUIDisplayPage(LANGUAGE_PAGE
);
675 CONSOLE_ConInKey(Ir
);
677 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
678 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
)) /* DOWN */
680 ScrollDownGenericList(LanguageList
);
683 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
684 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_UP
)) /* UP */
686 ScrollUpGenericList(LanguageList
);
689 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
690 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_NEXT
)) /* PAGE DOWN */
692 ScrollPageDownGenericList(LanguageList
);
695 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
696 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_PRIOR
)) /* PAGE UP */
698 ScrollPageUpGenericList(LanguageList
);
701 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
702 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
704 if (ConfirmQuit(Ir
) == TRUE
)
707 RedrawGenericList(LanguageList
);
709 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
711 SelectedLanguageId
= (PWCHAR
)GetListEntryUserData(GetCurrentListEntry(LanguageList
));
713 LanguageId
= (LANGID
)(wcstol(SelectedLanguageId
, NULL
, 16) & 0xFFFF);
715 if (wcscmp(SelectedLanguageId
, DefaultLanguage
))
721 SetConsoleCodePage();
725 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
> 0x60) && (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
< 0x7b))
728 GenericListKeyPress(LanguageList
, Ir
->Event
.KeyEvent
.uChar
.AsciiChar
);
734 NewLanguageId
= (PWCHAR
)GetListEntryUserData(GetCurrentListEntry(LanguageList
));
736 if (SelectedLanguageId
!= NewLanguageId
)
738 /* Clear the language page */
739 MUIClearPage(LANGUAGE_PAGE
);
741 SelectedLanguageId
= NewLanguageId
;
744 SetConsoleCodePage();
746 /* Redraw language selection page in native language */
747 MUIDisplayPage(LANGUAGE_PAGE
);
762 * LanguagePage (at once, default)
763 * InstallIntroPage (at once, if unattended)
769 * Init SourceRootPath
772 * Init RequiredPartitionDiskSpace
773 * Init IsUnattendedSetup
774 * If unattended, init *List and sets the Codepage
777 * Number of the next page.
780 SetupStartPage(PINPUT_RECORD Ir
)
782 //SYSTEM_DEVICE_INFORMATION Sdi;
784 WCHAR FileNameBuffer
[MAX_PATH
];
789 PGENERIC_LIST_ENTRY ListEntry
;
792 CONSOLE_SetStatusText(MUIGetString(STRING_PLEASEWAIT
));
795 /* Check whether a harddisk is available */
796 Status
= NtQuerySystemInformation(SystemDeviceInformation
,
798 sizeof(SYSTEM_DEVICE_INFORMATION
),
801 if (!NT_SUCCESS(Status
))
803 CONSOLE_PrintTextXY(6, 15, "NtQuerySystemInformation() failed (Status 0x%08lx)", Status
);
804 MUIDisplayError(ERROR_DRIVE_INFORMATION
, Ir
, POPUP_WAIT_ENTER
);
808 if (Sdi
.NumberOfDisks
== 0)
810 MUIDisplayError(ERROR_NO_HDD
, Ir
, POPUP_WAIT_ENTER
);
815 /* Get the source path and source root path */
816 Status
= GetSourcePaths(&SourcePath
,
820 if (!NT_SUCCESS(Status
))
822 CONSOLE_PrintTextXY(6, 15, "GetSourcePaths() failed (Status 0x%08lx)", Status
);
823 MUIDisplayError(ERROR_NO_SOURCE_DRIVE
, Ir
, POPUP_WAIT_ENTER
);
829 CONSOLE_PrintTextXY(6, 15, "SourcePath: '%wZ'", &SourcePath
);
830 CONSOLE_PrintTextXY(6, 16, "SourceRootPath: '%wZ'", &SourceRootPath
);
831 CONSOLE_PrintTextXY(6, 17, "SourceRootDir: '%wZ'", &SourceRootDir
);
835 /* Load txtsetup.sif from install media. */
836 wcscpy(FileNameBuffer
, SourcePath
.Buffer
);
837 wcscat(FileNameBuffer
, L
"\\txtsetup.sif");
839 SetupInf
= SetupOpenInfFileW(FileNameBuffer
,
845 if (SetupInf
== INVALID_HANDLE_VALUE
)
847 MUIDisplayError(ERROR_LOAD_TXTSETUPSIF
, Ir
, POPUP_WAIT_ENTER
);
851 /* Open 'Version' section */
852 if (!SetupFindFirstLineW(SetupInf
, L
"Version", L
"Signature", &Context
))
854 MUIDisplayError(ERROR_CORRUPT_TXTSETUPSIF
, Ir
, POPUP_WAIT_ENTER
);
858 /* Get pointer 'Signature' key */
859 if (!INF_GetData(&Context
, NULL
, &Value
))
861 MUIDisplayError(ERROR_CORRUPT_TXTSETUPSIF
, Ir
, POPUP_WAIT_ENTER
);
865 /* Check 'Signature' string */
866 if (_wcsicmp(Value
, L
"$ReactOS$") != 0)
868 MUIDisplayError(ERROR_SIGNATURE_TXTSETUPSIF
, Ir
, POPUP_WAIT_ENTER
);
872 /* Open 'DiskSpaceRequirements' section */
873 if (!SetupFindFirstLineW(SetupInf
, L
"DiskSpaceRequirements", L
"FreeSysPartDiskSpace", &Context
))
875 MUIDisplayError(ERROR_CORRUPT_TXTSETUPSIF
, Ir
, POPUP_WAIT_ENTER
);
879 /* Get the 'FreeSysPartDiskSpace' value */
880 if (!SetupGetIntField(&Context
, 1, &IntValue
))
882 MUIDisplayError(ERROR_CORRUPT_TXTSETUPSIF
, Ir
, POPUP_WAIT_ENTER
);
886 RequiredPartitionDiskSpace
= (ULONG
)IntValue
;
888 /* Start PnP thread */
889 if (hPnpThread
!= INVALID_HANDLE_VALUE
)
891 NtResumeThread(hPnpThread
, NULL
);
892 hPnpThread
= INVALID_HANDLE_VALUE
;
895 CheckUnattendedSetup();
897 if (IsUnattendedSetup
)
900 //read options from inf
901 ComputerList
= CreateComputerTypeList(SetupInf
);
902 DisplayList
= CreateDisplayDriverList(SetupInf
);
903 KeyboardList
= CreateKeyboardDriverList(SetupInf
);
904 LayoutList
= CreateKeyboardLayoutList(SetupInf
, DefaultKBLayout
);
905 LanguageList
= CreateLanguageList(SetupInf
, DefaultLanguage
);
908 wcscpy(SelectedLanguageId
,LocaleID
);
910 /* first we hack LanguageList */
911 ListEntry
= GetFirstListEntry(LanguageList
);
913 while (ListEntry
!= NULL
)
915 if (!wcsicmp(LocaleID
, GetListEntryUserData(ListEntry
)))
917 DPRINT("found %S in LanguageList\n",GetListEntryUserData(ListEntry
));
918 SetCurrentListEntry(LanguageList
, ListEntry
);
922 ListEntry
= GetNextListEntry(ListEntry
);
926 ListEntry
= GetFirstListEntry(LayoutList
);
928 while (ListEntry
!= NULL
)
930 if (!wcsicmp(LocaleID
, GetListEntryUserData(ListEntry
)))
932 DPRINT("found %S in LayoutList\n",GetListEntryUserData(ListEntry
));
933 SetCurrentListEntry(LayoutList
, ListEntry
);
937 ListEntry
= GetNextListEntry(ListEntry
);
940 SetConsoleCodePage();
942 return INSTALL_INTRO_PAGE
;
945 return LANGUAGE_PAGE
;
950 * Displays the IntroPage.
953 * InstallIntroPage (default)
959 * Number of the next page.
962 IntroPage(PINPUT_RECORD Ir
)
964 MUIDisplayPage(START_PAGE
);
968 CONSOLE_ConInKey(Ir
);
970 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
971 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
973 if (ConfirmQuit(Ir
) == TRUE
)
978 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
980 return INSTALL_INTRO_PAGE
;
982 else if (toupper(Ir
->Event
.KeyEvent
.uChar
.AsciiChar
) == 'R') /* R */
984 return REPAIR_INTRO_PAGE
;
986 else if (toupper(Ir
->Event
.KeyEvent
.uChar
.AsciiChar
) == 'L') /* R */
997 * Displays the License page.
1000 * IntroPage (default)
1003 * Number of the next page.
1006 LicensePage(PINPUT_RECORD Ir
)
1008 MUIDisplayPage(LICENSE_PAGE
);
1012 CONSOLE_ConInKey(Ir
);
1014 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
1020 return LICENSE_PAGE
;
1025 * Displays the RepairIntroPage.
1028 * RebootPage (default)
1034 * Number of the next page.
1037 RepairIntroPage(PINPUT_RECORD Ir
)
1039 MUIDisplayPage(REPAIR_INTRO_PAGE
);
1043 CONSOLE_ConInKey(Ir
);
1045 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
1049 else if (toupper(Ir
->Event
.KeyEvent
.uChar
.AsciiChar
) == 'U') /* U */
1051 RepairUpdateFlag
= TRUE
;
1052 return INSTALL_INTRO_PAGE
;
1054 else if (toupper(Ir
->Event
.KeyEvent
.uChar
.AsciiChar
) == 'R') /* R */
1056 return RECOVERY_PAGE
;
1058 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1059 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
)) /* ESC */
1065 return REPAIR_INTRO_PAGE
;
1069 * Displays the InstallIntroPage.
1072 * DeviceSettingsPage (At once if repair or update is selected)
1073 * SelectPartitionPage (At once if unattended setup)
1074 * DeviceSettingsPage (default)
1078 * Number of the next page.
1081 InstallIntroPage(PINPUT_RECORD Ir
)
1083 MUIDisplayPage(INSTALL_INTRO_PAGE
);
1085 if (RepairUpdateFlag
)
1087 //return SELECT_PARTITION_PAGE;
1088 return DEVICE_SETTINGS_PAGE
;
1091 if (IsUnattendedSetup
)
1093 return SELECT_PARTITION_PAGE
;
1098 CONSOLE_ConInKey(Ir
);
1100 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1101 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1103 if (ConfirmQuit(Ir
) == TRUE
)
1108 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
1110 return DEVICE_SETTINGS_PAGE
;
1111 // return SCSI_CONTROLLER_PAGE;
1115 return INSTALL_INTRO_PAGE
;
1121 ScsiControllerPage(PINPUT_RECORD Ir
)
1123 SetTextXY(6, 8, "Setup detected the following mass storage devices:");
1125 /* FIXME: print loaded mass storage driver descriptions */
1127 SetTextXY(8, 10, "TEST device");
1131 SetStatusText(" ENTER = Continue F3 = Quit");
1137 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1138 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1140 if (ConfirmQuit(Ir
) == TRUE
)
1145 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
1147 return DEVICE_SETTINGS_PAGE
;
1151 return SCSI_CONTROLLER_PAGE
;
1157 * Displays the DeviceSettingsPage.
1160 * SelectPartitionPage (At once if repair or update is selected)
1161 * ComputerSettingsPage
1162 * DisplaySettingsPage
1163 * KeyboardSettingsPage
1164 * LayoutsettingsPage
1165 * SelectPartitionPage
1175 * Number of the next page.
1178 DeviceSettingsPage(PINPUT_RECORD Ir
)
1180 static ULONG Line
= 16;
1181 MUIDisplayPage(DEVICE_SETTINGS_PAGE
);
1183 /* Initialize the computer settings list */
1184 if (ComputerList
== NULL
)
1186 ComputerList
= CreateComputerTypeList(SetupInf
);
1187 if (ComputerList
== NULL
)
1189 MUIDisplayError(ERROR_LOAD_COMPUTER
, Ir
, POPUP_WAIT_ENTER
);
1194 /* Initialize the display settings list */
1195 if (DisplayList
== NULL
)
1197 DisplayList
= CreateDisplayDriverList(SetupInf
);
1198 if (DisplayList
== NULL
)
1200 MUIDisplayError(ERROR_LOAD_DISPLAY
, Ir
, POPUP_WAIT_ENTER
);
1205 /* Initialize the keyboard settings list */
1206 if (KeyboardList
== NULL
)
1208 KeyboardList
= CreateKeyboardDriverList(SetupInf
);
1209 if (KeyboardList
== NULL
)
1211 MUIDisplayError(ERROR_LOAD_KEYBOARD
, Ir
, POPUP_WAIT_ENTER
);
1216 /* Initialize the keyboard layout list */
1217 if (LayoutList
== NULL
)
1219 LayoutList
= CreateKeyboardLayoutList(SetupInf
, DefaultKBLayout
);
1220 if (LayoutList
== NULL
)
1222 /* FIXME: report error */
1223 MUIDisplayError(ERROR_LOAD_KBLAYOUT
, Ir
, POPUP_WAIT_ENTER
);
1228 MUIDisplayPage(DEVICE_SETTINGS_PAGE
);
1231 CONSOLE_SetTextXY(25, 11, GetListEntryText(GetCurrentListEntry((ComputerList
))));
1232 CONSOLE_SetTextXY(25, 12, GetListEntryText(GetCurrentListEntry((DisplayList
))));
1233 CONSOLE_SetTextXY(25, 13, GetListEntryText(GetCurrentListEntry((KeyboardList
))));
1234 CONSOLE_SetTextXY(25, 14, GetListEntryText(GetCurrentListEntry((LayoutList
))));
1236 CONSOLE_InvertTextXY(24, Line
, 48, 1);
1238 if (RepairUpdateFlag
)
1240 return SELECT_PARTITION_PAGE
;
1245 CONSOLE_ConInKey(Ir
);
1247 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1248 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
)) /* DOWN */
1250 CONSOLE_NormalTextXY(24, Line
, 48, 1);
1254 else if (Line
== 16)
1259 CONSOLE_InvertTextXY(24, Line
, 48, 1);
1261 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1262 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_UP
)) /* UP */
1264 CONSOLE_NormalTextXY(24, Line
, 48, 1);
1268 else if (Line
== 16)
1273 CONSOLE_InvertTextXY(24, Line
, 48, 1);
1275 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1276 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1278 if (ConfirmQuit(Ir
) == TRUE
)
1283 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
1286 return COMPUTER_SETTINGS_PAGE
;
1287 else if (Line
== 12)
1288 return DISPLAY_SETTINGS_PAGE
;
1289 else if (Line
== 13)
1290 return KEYBOARD_SETTINGS_PAGE
;
1291 else if (Line
== 14)
1292 return LAYOUT_SETTINGS_PAGE
;
1293 else if (Line
== 16)
1294 return SELECT_PARTITION_PAGE
;
1298 return DEVICE_SETTINGS_PAGE
;
1303 * Handles generic selection lists.
1306 * GenericList: The list to handle.
1307 * nextPage: The page it needs to jump to after this page.
1308 * Ir: The PINPUT_RECORD
1311 HandleGenericList(PGENERIC_LIST GenericList
,
1312 PAGE_NUMBER nextPage
,
1317 CONSOLE_ConInKey(Ir
);
1319 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1320 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
)) /* DOWN */
1322 ScrollDownGenericList(GenericList
);
1324 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1325 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_UP
)) /* UP */
1327 ScrollUpGenericList(GenericList
);
1329 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1330 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_NEXT
)) /* PAGE DOWN */
1332 ScrollPageDownGenericList(GenericList
);
1334 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1335 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_PRIOR
)) /* PAGE UP */
1337 ScrollPageUpGenericList(GenericList
);
1339 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1340 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1342 if (ConfirmQuit(Ir
) == TRUE
)
1347 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1348 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
)) /* ESC */
1350 RestoreGenericListState(GenericList
);
1353 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
1357 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
> 0x60) && (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
< 0x7b))
1360 GenericListKeyPress(GenericList
, Ir
->Event
.KeyEvent
.uChar
.AsciiChar
);
1367 * Displays the ComputerSettingsPage.
1370 * DeviceSettingsPage
1374 * Number of the next page.
1377 ComputerSettingsPage(PINPUT_RECORD Ir
)
1379 MUIDisplayPage(COMPUTER_SETTINGS_PAGE
);
1381 DrawGenericList(ComputerList
,
1387 SaveGenericListState(ComputerList
);
1389 return HandleGenericList(ComputerList
, DEVICE_SETTINGS_PAGE
, Ir
);
1394 * Displays the DisplaySettingsPage.
1397 * DeviceSettingsPage
1401 * Number of the next page.
1404 DisplaySettingsPage(PINPUT_RECORD Ir
)
1406 MUIDisplayPage(DISPLAY_SETTINGS_PAGE
);
1408 DrawGenericList(DisplayList
,
1414 SaveGenericListState(DisplayList
);
1416 return HandleGenericList(DisplayList
, DEVICE_SETTINGS_PAGE
, Ir
);
1421 * Displays the KeyboardSettingsPage.
1424 * DeviceSettingsPage
1428 * Number of the next page.
1431 KeyboardSettingsPage(PINPUT_RECORD Ir
)
1433 MUIDisplayPage(KEYBOARD_SETTINGS_PAGE
);
1435 DrawGenericList(KeyboardList
,
1441 SaveGenericListState(KeyboardList
);
1443 return HandleGenericList(KeyboardList
, DEVICE_SETTINGS_PAGE
, Ir
);
1448 * Displays the LayoutSettingsPage.
1451 * DeviceSettingsPage
1455 * Number of the next page.
1458 LayoutSettingsPage(PINPUT_RECORD Ir
)
1460 MUIDisplayPage(LAYOUT_SETTINGS_PAGE
);
1462 DrawGenericList(LayoutList
,
1468 SaveGenericListState(LayoutList
);
1470 return HandleGenericList(LayoutList
, DEVICE_SETTINGS_PAGE
, Ir
);
1475 IsDiskSizeValid(PPARTENTRY PartEntry
)
1479 size
= PartEntry
->SectorCount
.QuadPart
* PartEntry
->DiskEntry
->BytesPerSector
;
1480 size
= (size
+ 524288) / 1048576; /* in MBytes */
1482 if (size
< RequiredPartitionDiskSpace
)
1484 /* partition is too small so ask for another partion */
1485 DPRINT1("Partition is too small (size: %I64u MB), required disk space is %lu MB\n", size
, RequiredPartitionDiskSpace
);
1496 * Displays the SelectPartitionPage.
1499 * SelectFileSystemPage (At once if unattended)
1500 * SelectFileSystemPage (Default if free space is selected)
1501 * CreatePrimaryPartitionPage
1502 * CreateExtendedPartitionPage
1503 * CreateLogicalPartitionPage
1504 * ConfirmDeleteSystemPartitionPage (if the selected partition is the system partition, aka with the boot flag set)
1505 * DeletePartitionPage
1509 * Init DestinationDriveLetter (only if unattended or not free space is selected)
1510 * Set InstallShortcut (only if not unattended + free space is selected)
1513 * Number of the next page.
1516 SelectPartitionPage(PINPUT_RECORD Ir
)
1520 MUIDisplayPage(SELECT_PARTITION_PAGE
);
1522 if (PartitionList
== NULL
)
1524 PartitionList
= CreatePartitionList(2,
1528 if (PartitionList
== NULL
)
1530 /* FIXME: show an error dialog */
1533 else if (IsListEmpty(&PartitionList
->DiskListHead
))
1535 MUIDisplayError(ERROR_NO_HDD
, Ir
, POPUP_WAIT_ENTER
);
1540 DrawPartitionList(PartitionList
);
1542 if (IsUnattendedSetup
)
1544 if (!SelectPartition(PartitionList
, UnattendDestinationDiskNumber
, UnattendDestinationPartitionNumber
))
1548 if (PartitionList
->CurrentPartition
->LogicalPartition
)
1550 CreateLogicalPartition(PartitionList
,
1551 PartitionList
->CurrentPartition
->SectorCount
.QuadPart
,
1556 CreatePrimaryPartition(PartitionList
,
1557 PartitionList
->CurrentPartition
->SectorCount
.QuadPart
,
1561 if (!IsDiskSizeValid(PartitionList
->CurrentPartition
))
1563 MUIDisplayError(ERROR_INSUFFICIENT_PARTITION_SIZE
, Ir
, POPUP_WAIT_ANY_KEY
,
1564 RequiredPartitionDiskSpace
);
1565 return SELECT_PARTITION_PAGE
; /* let the user select another partition */
1568 DestinationDriveLetter
= (WCHAR
)PartitionList
->CurrentPartition
->DriveLetter
;
1570 return SELECT_FILE_SYSTEM_PAGE
;
1575 if (!IsDiskSizeValid(PartitionList
->CurrentPartition
))
1577 MUIDisplayError(ERROR_INSUFFICIENT_PARTITION_SIZE
, Ir
, POPUP_WAIT_ANY_KEY
,
1578 RequiredPartitionDiskSpace
);
1579 return SELECT_PARTITION_PAGE
; /* let the user select another partition */
1582 DestinationDriveLetter
= (WCHAR
)PartitionList
->CurrentPartition
->DriveLetter
;
1584 return SELECT_FILE_SYSTEM_PAGE
;
1590 /* Update status text */
1591 if (PartitionList
->CurrentPartition
== NULL
)
1593 CONSOLE_SetStatusText(MUIGetString(STRING_INSTALLCREATEPARTITION
));
1595 else if (PartitionList
->CurrentPartition
->LogicalPartition
)
1597 if (PartitionList
->CurrentPartition
->IsPartitioned
)
1599 CONSOLE_SetStatusText(MUIGetString(STRING_DELETEPARTITION
));
1603 CONSOLE_SetStatusText(MUIGetString(STRING_INSTALLCREATELOGICAL
));
1608 if (PartitionList
->CurrentPartition
->IsPartitioned
)
1610 if (IsContainerPartition(PartitionList
->CurrentPartition
->PartitionType
))
1612 CONSOLE_SetStatusText(MUIGetString(STRING_DELETEPARTITION
));
1616 CONSOLE_SetStatusText(MUIGetString(STRING_INSTALLDELETEPARTITION
));
1621 CONSOLE_SetStatusText(MUIGetString(STRING_INSTALLCREATEPARTITION
));
1625 CONSOLE_ConInKey(Ir
);
1627 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1628 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1630 if (ConfirmQuit(Ir
) == TRUE
)
1632 DestroyPartitionList(PartitionList
);
1633 PartitionList
= NULL
;
1639 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1640 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
)) /* DOWN */
1642 if (ScrollDownPartitionList(PartitionList
))
1643 DrawPartitionList(PartitionList
);
1645 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1646 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_UP
)) /* UP */
1648 if (ScrollUpPartitionList(PartitionList
))
1649 DrawPartitionList(PartitionList
);
1651 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_RETURN
) /* ENTER */
1653 if (IsContainerPartition(PartitionList
->CurrentPartition
->PartitionType
))
1654 continue; //return SELECT_PARTITION_PAGE;
1656 if (PartitionList
->CurrentPartition
== NULL
||
1657 PartitionList
->CurrentPartition
->IsPartitioned
== FALSE
)
1659 if (PartitionList
->CurrentPartition
->LogicalPartition
)
1661 CreateLogicalPartition(PartitionList
,
1667 CreatePrimaryPartition(PartitionList
,
1673 if (!IsDiskSizeValid(PartitionList
->CurrentPartition
))
1675 MUIDisplayError(ERROR_INSUFFICIENT_PARTITION_SIZE
, Ir
, POPUP_WAIT_ANY_KEY
,
1676 RequiredPartitionDiskSpace
);
1677 return SELECT_PARTITION_PAGE
; /* let the user select another partition */
1680 DestinationDriveLetter
= (WCHAR
)PartitionList
->CurrentPartition
->DriveLetter
;
1682 return SELECT_FILE_SYSTEM_PAGE
;
1684 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== 'P') /* P */
1686 if (PartitionList
->CurrentPartition
->LogicalPartition
== FALSE
)
1688 Error
= PrimaryPartitionCreationChecks(PartitionList
);
1689 if (Error
!= NOT_AN_ERROR
)
1691 MUIDisplayError(Error
, Ir
, POPUP_WAIT_ANY_KEY
);
1692 return SELECT_PARTITION_PAGE
;
1695 return CREATE_PRIMARY_PARTITION_PAGE
;
1698 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== 'E') /* E */
1700 if (PartitionList
->CurrentPartition
->LogicalPartition
== FALSE
)
1702 Error
= ExtendedPartitionCreationChecks(PartitionList
);
1703 if (Error
!= NOT_AN_ERROR
)
1705 MUIDisplayError(Error
, Ir
, POPUP_WAIT_ANY_KEY
);
1706 return SELECT_PARTITION_PAGE
;
1709 return CREATE_EXTENDED_PARTITION_PAGE
;
1712 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== 'L') /* L */
1714 if (PartitionList
->CurrentPartition
->LogicalPartition
== TRUE
)
1716 Error
= LogicalPartitionCreationChecks(PartitionList
);
1717 if (Error
!= NOT_AN_ERROR
)
1719 MUIDisplayError(Error
, Ir
, POPUP_WAIT_ANY_KEY
);
1720 return SELECT_PARTITION_PAGE
;
1723 return CREATE_LOGICAL_PARTITION_PAGE
;
1726 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== 'D') /* D */
1728 if (PartitionList
->CurrentPartition
->IsPartitioned
== FALSE
)
1730 MUIDisplayError(ERROR_DELETE_SPACE
, Ir
, POPUP_WAIT_ANY_KEY
);
1731 return SELECT_PARTITION_PAGE
;
1734 if (PartitionList
->CurrentPartition
->BootIndicator
||
1735 PartitionList
->CurrentPartition
== PartitionList
->SystemPartition
)
1737 return CONFIRM_DELETE_SYSTEM_PARTITION_PAGE
;
1740 return DELETE_PARTITION_PAGE
;
1744 return SELECT_PARTITION_PAGE
;
1748 #define PARTITION_SIZE_INPUT_FIELD_LENGTH 6
1749 /* Restriction for MaxSize: pow(10, PARTITION_SIZE_INPUT_FIELD_LENGTH)-1 */
1750 #define PARTITION_MAXSIZE 999999
1753 ShowPartitionSizeInputBox(SHORT Left
,
1766 WCHAR PartitionSizeBuffer
[100];
1778 DrawBox(Left
, Top
, Right
- Left
+ 1, Bottom
- Top
+ 1);
1783 strcpy(Buffer
, MUIGetString(STRING_PARTITIONSIZE
));
1784 iLeft
= coPos
.X
+ strlen(Buffer
) + 1;
1787 WriteConsoleOutputCharacterA(StdOutput
,
1793 sprintf(Buffer
, MUIGetString(STRING_MAXSIZE
), MaxSize
);
1794 coPos
.X
= iLeft
+ PARTITION_SIZE_INPUT_FIELD_LENGTH
+ 1;
1796 WriteConsoleOutputCharacterA(StdOutput
,
1802 swprintf(PartitionSizeBuffer
, L
"%lu", MaxSize
);
1803 Index
= wcslen(PartitionSizeBuffer
);
1804 CONSOLE_SetInputTextXY(iLeft
,
1806 PARTITION_SIZE_INPUT_FIELD_LENGTH
,
1807 PartitionSizeBuffer
);
1811 CONSOLE_ConInKey(&Ir
);
1813 if ((Ir
.Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1814 (Ir
.Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1819 PartitionSizeBuffer
[0] = 0;
1822 else if (Ir
.Event
.KeyEvent
.wVirtualKeyCode
== VK_RETURN
) /* ENTER */
1826 else if (Ir
.Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
) /* ESCAPE */
1831 PartitionSizeBuffer
[0] = 0;
1834 else if ((Ir
.Event
.KeyEvent
.wVirtualKeyCode
== VK_BACK
) && /* BACKSPACE */
1838 PartitionSizeBuffer
[Index
] = 0;
1840 CONSOLE_SetInputTextXY(iLeft
,
1842 PARTITION_SIZE_INPUT_FIELD_LENGTH
,
1843 PartitionSizeBuffer
);
1845 else if ((Ir
.Event
.KeyEvent
.uChar
.AsciiChar
!= 0x00) &&
1846 (Index
< PARTITION_SIZE_INPUT_FIELD_LENGTH
))
1848 ch
= (WCHAR
)Ir
.Event
.KeyEvent
.uChar
.AsciiChar
;
1850 if ((ch
>= L
'0') && (ch
<= L
'9'))
1852 PartitionSizeBuffer
[Index
] = ch
;
1854 PartitionSizeBuffer
[Index
] = 0;
1856 CONSOLE_SetInputTextXY(iLeft
,
1858 PARTITION_SIZE_INPUT_FIELD_LENGTH
,
1859 PartitionSizeBuffer
);
1864 /* Convert UNICODE --> ANSI the poor man's way */
1865 sprintf(InputBuffer
, "%S", PartitionSizeBuffer
);
1870 * Displays the CreatePrimaryPartitionPage.
1873 * SelectPartitionPage
1874 * SelectFileSystemPage (default)
1878 * Number of the next page.
1881 CreatePrimaryPartitionPage(PINPUT_RECORD Ir
)
1883 PDISKENTRY DiskEntry
;
1884 PPARTENTRY PartEntry
;
1887 CHAR InputBuffer
[50];
1891 ULONGLONG SectorCount
;
1894 if (PartitionList
== NULL
||
1895 PartitionList
->CurrentDisk
== NULL
||
1896 PartitionList
->CurrentPartition
== NULL
)
1898 /* FIXME: show an error dialog */
1902 DiskEntry
= PartitionList
->CurrentDisk
;
1903 PartEntry
= PartitionList
->CurrentPartition
;
1905 CONSOLE_SetStatusText(MUIGetString(STRING_PLEASEWAIT
));
1907 CONSOLE_SetTextXY(6, 8, MUIGetString(STRING_CHOOSENEWPARTITION
));
1909 DiskSize
= DiskEntry
->SectorCount
.QuadPart
* DiskEntry
->BytesPerSector
;
1911 if (DiskSize
>= 10737418240) /* 10 GB */
1913 DiskSize
= DiskSize
/ 1073741824;
1914 Unit
= MUIGetString(STRING_GB
);
1919 DiskSize
= DiskSize
/ 1048576;
1923 Unit
= MUIGetString(STRING_MB
);
1926 if (DiskEntry
->DriverName
.Length
> 0)
1928 CONSOLE_PrintTextXY(6, 10,
1929 MUIGetString(STRING_HDINFOPARTCREATE
),
1932 DiskEntry
->DiskNumber
,
1936 &DiskEntry
->DriverName
);
1940 CONSOLE_PrintTextXY(6, 10,
1941 MUIGetString(STRING_HDDINFOUNK1
),
1944 DiskEntry
->DiskNumber
,
1950 CONSOLE_SetTextXY(6, 12, MUIGetString(STRING_HDDSIZE
));
1953 CONSOLE_PrintTextXY(8, 10, "Maximum size of the new partition is %I64u MB",
1954 PartitionList
->CurrentPartition
->SectorCount
* DiskEntry
->BytesPerSector
/ 1048576);
1957 CONSOLE_SetStatusText(MUIGetString(STRING_CREATEPARTITION
));
1959 PartEntry
= PartitionList
->CurrentPartition
;
1962 MaxSize
= (PartEntry
->SectorCount
.QuadPart
* DiskEntry
->BytesPerSector
) / 1048576; /* in MBytes (rounded) */
1964 if (MaxSize
> PARTITION_MAXSIZE
)
1965 MaxSize
= PARTITION_MAXSIZE
;
1967 ShowPartitionSizeInputBox(12, 14, xScreen
- 12, 17, /* left, top, right, bottom */
1968 MaxSize
, InputBuffer
, &Quit
, &Cancel
);
1972 if (ConfirmQuit(Ir
) == TRUE
)
1975 else if (Cancel
== TRUE
)
1977 return SELECT_PARTITION_PAGE
;
1981 PartSize
= atoi(InputBuffer
);
1989 if (PartSize
> MaxSize
)
1995 /* Convert to bytes */
1996 if (PartSize
== MaxSize
)
1998 /* Use all of the unpartitioned disk space */
1999 SectorCount
= PartEntry
->SectorCount
.QuadPart
;
2003 /* Calculate the sector count from the size in MB */
2004 SectorCount
= PartSize
* 1048576 / DiskEntry
->BytesPerSector
;
2006 /* But never get larger than the unpartitioned disk space */
2007 if (SectorCount
> PartEntry
->SectorCount
.QuadPart
)
2008 SectorCount
= PartEntry
->SectorCount
.QuadPart
;
2011 DPRINT ("Partition size: %I64u bytes\n", PartSize
);
2013 CreatePrimaryPartition(PartitionList
,
2017 return SELECT_PARTITION_PAGE
;
2021 return CREATE_PRIMARY_PARTITION_PAGE
;
2026 * Displays the CreateExtendedPartitionPage.
2029 * SelectPartitionPage (default)
2033 * Number of the next page.
2036 CreateExtendedPartitionPage(PINPUT_RECORD Ir
)
2038 PDISKENTRY DiskEntry
;
2039 PPARTENTRY PartEntry
;
2042 CHAR InputBuffer
[50];
2046 ULONGLONG SectorCount
;
2049 if (PartitionList
== NULL
||
2050 PartitionList
->CurrentDisk
== NULL
||
2051 PartitionList
->CurrentPartition
== NULL
)
2053 /* FIXME: show an error dialog */
2057 DiskEntry
= PartitionList
->CurrentDisk
;
2058 PartEntry
= PartitionList
->CurrentPartition
;
2060 CONSOLE_SetStatusText(MUIGetString(STRING_PLEASEWAIT
));
2062 CONSOLE_SetTextXY(6, 8, MUIGetString(STRING_CHOOSE_NEW_EXTENDED_PARTITION
));
2064 DiskSize
= DiskEntry
->SectorCount
.QuadPart
* DiskEntry
->BytesPerSector
;
2066 if (DiskSize
>= 10737418240) /* 10 GB */
2068 DiskSize
= DiskSize
/ 1073741824;
2069 Unit
= MUIGetString(STRING_GB
);
2074 DiskSize
= DiskSize
/ 1048576;
2078 Unit
= MUIGetString(STRING_MB
);
2081 if (DiskEntry
->DriverName
.Length
> 0)
2083 CONSOLE_PrintTextXY(6, 10,
2084 MUIGetString(STRING_HDINFOPARTCREATE
),
2087 DiskEntry
->DiskNumber
,
2091 &DiskEntry
->DriverName
);
2095 CONSOLE_PrintTextXY(6, 10,
2096 MUIGetString(STRING_HDDINFOUNK1
),
2099 DiskEntry
->DiskNumber
,
2105 CONSOLE_SetTextXY(6, 12, MUIGetString(STRING_HDDSIZE
));
2108 CONSOLE_PrintTextXY(8, 10, "Maximum size of the new partition is %I64u MB",
2109 PartitionList
->CurrentPartition
->SectorCount
* DiskEntry
->BytesPerSector
/ 1048576);
2112 CONSOLE_SetStatusText(MUIGetString(STRING_CREATEPARTITION
));
2114 PartEntry
= PartitionList
->CurrentPartition
;
2117 MaxSize
= (PartEntry
->SectorCount
.QuadPart
* DiskEntry
->BytesPerSector
) / 1048576; /* in MBytes (rounded) */
2119 if (MaxSize
> PARTITION_MAXSIZE
)
2120 MaxSize
= PARTITION_MAXSIZE
;
2122 ShowPartitionSizeInputBox(12, 14, xScreen
- 12, 17, /* left, top, right, bottom */
2123 MaxSize
, InputBuffer
, &Quit
, &Cancel
);
2127 if (ConfirmQuit(Ir
) == TRUE
)
2130 else if (Cancel
== TRUE
)
2132 return SELECT_PARTITION_PAGE
;
2136 PartSize
= atoi(InputBuffer
);
2144 if (PartSize
> MaxSize
)
2150 /* Convert to bytes */
2151 if (PartSize
== MaxSize
)
2153 /* Use all of the unpartitioned disk space */
2154 SectorCount
= PartEntry
->SectorCount
.QuadPart
;
2158 /* Calculate the sector count from the size in MB */
2159 SectorCount
= PartSize
* 1048576 / DiskEntry
->BytesPerSector
;
2161 /* But never get larger than the unpartitioned disk space */
2162 if (SectorCount
> PartEntry
->SectorCount
.QuadPart
)
2163 SectorCount
= PartEntry
->SectorCount
.QuadPart
;
2166 DPRINT ("Partition size: %I64u bytes\n", PartSize
);
2168 CreateExtendedPartition(PartitionList
,
2171 return SELECT_PARTITION_PAGE
;
2175 return CREATE_EXTENDED_PARTITION_PAGE
;
2180 * Displays the CreateLogicalPartitionPage.
2183 * SelectFileSystemPage (default)
2187 * Number of the next page.
2190 CreateLogicalPartitionPage(PINPUT_RECORD Ir
)
2192 PDISKENTRY DiskEntry
;
2193 PPARTENTRY PartEntry
;
2196 CHAR InputBuffer
[50];
2200 ULONGLONG SectorCount
;
2203 if (PartitionList
== NULL
||
2204 PartitionList
->CurrentDisk
== NULL
||
2205 PartitionList
->CurrentPartition
== NULL
)
2207 /* FIXME: show an error dialog */
2211 DiskEntry
= PartitionList
->CurrentDisk
;
2212 PartEntry
= PartitionList
->CurrentPartition
;
2214 CONSOLE_SetStatusText(MUIGetString(STRING_PLEASEWAIT
));
2216 CONSOLE_SetTextXY(6, 8, MUIGetString(STRING_CHOOSE_NEW_LOGICAL_PARTITION
));
2218 DiskSize
= DiskEntry
->SectorCount
.QuadPart
* DiskEntry
->BytesPerSector
;
2220 if (DiskSize
>= 10737418240) /* 10 GB */
2222 DiskSize
= DiskSize
/ 1073741824;
2223 Unit
= MUIGetString(STRING_GB
);
2228 DiskSize
= DiskSize
/ 1048576;
2232 Unit
= MUIGetString(STRING_MB
);
2235 if (DiskEntry
->DriverName
.Length
> 0)
2237 CONSOLE_PrintTextXY(6, 10,
2238 MUIGetString(STRING_HDINFOPARTCREATE
),
2241 DiskEntry
->DiskNumber
,
2245 &DiskEntry
->DriverName
);
2249 CONSOLE_PrintTextXY(6, 10,
2250 MUIGetString(STRING_HDDINFOUNK1
),
2253 DiskEntry
->DiskNumber
,
2259 CONSOLE_SetTextXY(6, 12, MUIGetString(STRING_HDDSIZE
));
2262 CONSOLE_PrintTextXY(8, 10, "Maximum size of the new partition is %I64u MB",
2263 PartitionList
->CurrentPartition
->SectorCount
* DiskEntry
->BytesPerSector
/ 1048576);
2266 CONSOLE_SetStatusText(MUIGetString(STRING_CREATEPARTITION
));
2268 PartEntry
= PartitionList
->CurrentPartition
;
2271 MaxSize
= (PartEntry
->SectorCount
.QuadPart
* DiskEntry
->BytesPerSector
) / 1048576; /* in MBytes (rounded) */
2273 if (MaxSize
> PARTITION_MAXSIZE
)
2274 MaxSize
= PARTITION_MAXSIZE
;
2276 ShowPartitionSizeInputBox(12, 14, xScreen
- 12, 17, /* left, top, right, bottom */
2277 MaxSize
, InputBuffer
, &Quit
, &Cancel
);
2281 if (ConfirmQuit(Ir
) == TRUE
)
2284 else if (Cancel
== TRUE
)
2286 return SELECT_PARTITION_PAGE
;
2290 PartSize
= atoi(InputBuffer
);
2298 if (PartSize
> MaxSize
)
2304 /* Convert to bytes */
2305 if (PartSize
== MaxSize
)
2307 /* Use all of the unpartitioned disk space */
2308 SectorCount
= PartEntry
->SectorCount
.QuadPart
;
2312 /* Calculate the sector count from the size in MB */
2313 SectorCount
= PartSize
* 1048576 / DiskEntry
->BytesPerSector
;
2315 /* But never get larger than the unpartitioned disk space */
2316 if (SectorCount
> PartEntry
->SectorCount
.QuadPart
)
2317 SectorCount
= PartEntry
->SectorCount
.QuadPart
;
2320 DPRINT("Partition size: %I64u bytes\n", PartSize
);
2322 CreateLogicalPartition(PartitionList
,
2326 return SELECT_PARTITION_PAGE
;
2330 return CREATE_LOGICAL_PARTITION_PAGE
;
2335 * Displays the ConfirmDeleteSystemPartitionPage.
2338 * DeletePartitionPage (default)
2339 * SelectPartitionPage
2342 * Number of the next page.
2345 ConfirmDeleteSystemPartitionPage(PINPUT_RECORD Ir
)
2347 MUIDisplayPage(CONFIRM_DELETE_SYSTEM_PARTITION_PAGE
);
2351 CONSOLE_ConInKey(Ir
);
2353 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
2354 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
2356 if (ConfirmQuit(Ir
) == TRUE
)
2361 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_RETURN
) /* ENTER */
2363 return DELETE_PARTITION_PAGE
;
2365 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
) /* ESC */
2367 return SELECT_PARTITION_PAGE
;
2371 return SELECT_PARTITION_PAGE
;
2376 * Displays the DeletePartitionPage.
2379 * SelectPartitionPage (default)
2383 * Number of the next page.
2386 DeletePartitionPage(PINPUT_RECORD Ir
)
2388 PDISKENTRY DiskEntry
;
2389 PPARTENTRY PartEntry
;
2395 if (PartitionList
== NULL
||
2396 PartitionList
->CurrentDisk
== NULL
||
2397 PartitionList
->CurrentPartition
== NULL
)
2399 /* FIXME: show an error dialog */
2403 DiskEntry
= PartitionList
->CurrentDisk
;
2404 PartEntry
= PartitionList
->CurrentPartition
;
2406 MUIDisplayPage(DELETE_PARTITION_PAGE
);
2408 GetPartTypeStringFromPartitionType(PartEntry
->PartitionType
, PartType
, 30);
2410 PartSize
= PartEntry
->SectorCount
.QuadPart
* DiskEntry
->BytesPerSector
;
2412 if (PartSize
>= 10737418240) /* 10 GB */
2414 PartSize
= PartSize
/ 1073741824;
2415 Unit
= MUIGetString(STRING_GB
);
2419 if (PartSize
>= 10485760) /* 10 MB */
2421 PartSize
= PartSize
/ 1048576;
2422 Unit
= MUIGetString(STRING_MB
);
2426 PartSize
= PartSize
/ 1024;
2427 Unit
= MUIGetString(STRING_KB
);
2430 if (PartType
== NULL
)
2432 CONSOLE_PrintTextXY(6, 10,
2433 MUIGetString(STRING_HDDINFOUNK2
),
2434 (PartEntry
->DriveLetter
== 0) ? '-' : PartEntry
->DriveLetter
,
2435 (PartEntry
->DriveLetter
== 0) ? '-' : ':',
2436 PartEntry
->PartitionType
,
2442 CONSOLE_PrintTextXY(6, 10,
2443 " %c%c %s %I64u %s",
2444 (PartEntry
->DriveLetter
== 0) ? '-' : PartEntry
->DriveLetter
,
2445 (PartEntry
->DriveLetter
== 0) ? '-' : ':',
2451 DiskSize
= DiskEntry
->SectorCount
.QuadPart
* DiskEntry
->BytesPerSector
;
2453 if (DiskSize
>= 10737418240) /* 10 GB */
2455 DiskSize
= DiskSize
/ 1073741824;
2456 Unit
= MUIGetString(STRING_GB
);
2461 DiskSize
= DiskSize
/ 1048576;
2465 Unit
= MUIGetString(STRING_MB
);
2468 if (DiskEntry
->DriverName
.Length
> 0)
2470 CONSOLE_PrintTextXY(6, 12,
2471 MUIGetString(STRING_HDINFOPARTDELETE
),
2474 DiskEntry
->DiskNumber
,
2478 &DiskEntry
->DriverName
);
2482 CONSOLE_PrintTextXY(6, 12,
2483 MUIGetString(STRING_HDDINFOUNK3
),
2486 DiskEntry
->DiskNumber
,
2494 CONSOLE_ConInKey(Ir
);
2496 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
2497 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
2499 if (ConfirmQuit(Ir
) == TRUE
)
2504 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
) /* ESC */
2506 return SELECT_PARTITION_PAGE
;
2508 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== 'D') /* D */
2510 DeleteCurrentPartition(PartitionList
);
2512 return SELECT_PARTITION_PAGE
;
2516 return DELETE_PARTITION_PAGE
;
2521 * Displays the SelectFileSystemPage.
2524 * CheckFileSystemPage (At once if RepairUpdate is selected)
2525 * CheckFileSystemPage (At once if Unattended and not UnattendFormatPartition)
2526 * FormatPartitionPage (At once if Unattended and UnattendFormatPartition)
2527 * SelectPartitionPage (If the user aborts)
2528 * FormatPartitionPage (Default)
2532 * Sets PartEntry->DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex].PartitionType (via UpdatePartitionType)
2533 * Calls CheckActiveSystemPartition()
2536 * Number of the next page.
2539 SelectFileSystemPage(PINPUT_RECORD Ir
)
2541 PDISKENTRY DiskEntry
;
2542 PPARTENTRY PartEntry
;
2547 CHAR PartTypeString
[32];
2549 DPRINT("SelectFileSystemPage()\n");
2551 if (PartitionList
== NULL
||
2552 PartitionList
->CurrentDisk
== NULL
||
2553 PartitionList
->CurrentPartition
== NULL
)
2555 /* FIXME: show an error dialog */
2560 if (FileSystemList
== NULL
)
2562 FileSystemList
= CreateFileSystemList(6, 26, PartitionList
->CurrentPartition
->New
, L
"FAT");
2563 if (FileSystemList
== NULL
)
2565 /* FIXME: show an error dialog */
2569 /* FIXME: Add file systems to list */
2572 /* Find or set the active system partition */
2573 CheckActiveSystemPartition(PartitionList
, FileSystemList
);
2575 if (PartitionList
->SystemDisk
== NULL
||
2576 PartitionList
->SystemPartition
== NULL
)
2578 /* FIXME: show an error dialog */
2582 switch (PartitionList
->FormatState
)
2585 if (PartitionList
->CurrentPartition
!= PartitionList
->SystemPartition
)
2587 PartitionList
->TempDisk
= PartitionList
->SystemDisk
;
2588 PartitionList
->TempPartition
= PartitionList
->SystemPartition
;
2589 PartitionList
->TempPartition
->NeedsCheck
= TRUE
;
2591 PartitionList
->FormatState
= FormatSystemPartition
;
2592 DPRINT1("FormatState: Start --> FormatSystemPartition\n");
2596 PartitionList
->TempDisk
= PartitionList
->CurrentDisk
;
2597 PartitionList
->TempPartition
= PartitionList
->CurrentPartition
;
2598 PartitionList
->TempPartition
->NeedsCheck
= TRUE
;
2600 PartitionList
->FormatState
= FormatInstallPartition
;
2601 DPRINT1("FormatState: Start --> FormatInstallPartition\n");
2605 case FormatSystemPartition
:
2606 PartitionList
->TempDisk
= PartitionList
->CurrentDisk
;
2607 PartitionList
->TempPartition
= PartitionList
->CurrentPartition
;
2608 PartitionList
->TempPartition
->NeedsCheck
= TRUE
;
2610 PartitionList
->FormatState
= FormatInstallPartition
;
2611 DPRINT1("FormatState: FormatSystemPartition --> FormatInstallPartition\n");
2614 case FormatInstallPartition
:
2615 if (GetNextUnformattedPartition(PartitionList
,
2616 &PartitionList
->TempDisk
,
2617 &PartitionList
->TempPartition
))
2619 PartitionList
->FormatState
= FormatOtherPartition
;
2620 PartitionList
->TempPartition
->NeedsCheck
= TRUE
;
2621 DPRINT1("FormatState: FormatInstallPartition --> FormatOtherPartition\n");
2625 PartitionList
->FormatState
= FormatDone
;
2626 DPRINT1("FormatState: FormatInstallPartition --> FormatDone\n");
2627 return CHECK_FILE_SYSTEM_PAGE
;
2631 case FormatOtherPartition
:
2632 if (GetNextUnformattedPartition(PartitionList
,
2633 &PartitionList
->TempDisk
,
2634 &PartitionList
->TempPartition
))
2636 PartitionList
->FormatState
= FormatOtherPartition
;
2637 PartitionList
->TempPartition
->NeedsCheck
= TRUE
;
2638 DPRINT1("FormatState: FormatOtherPartition --> FormatOtherPartition\n");
2642 PartitionList
->FormatState
= FormatDone
;
2643 DPRINT1("FormatState: FormatOtherPartition --> FormatDone\n");
2644 return CHECK_FILE_SYSTEM_PAGE
;
2649 DPRINT1("FormatState: Invalid value %ld\n", PartitionList
->FormatState
);
2650 /* FIXME: show an error dialog */
2654 DiskEntry
= PartitionList
->TempDisk
;
2655 PartEntry
= PartitionList
->TempPartition
;
2657 /* adjust disk size */
2658 DiskSize
= DiskEntry
->SectorCount
.QuadPart
* DiskEntry
->BytesPerSector
;
2659 if (DiskSize
>= 10737418240) /* 10 GB */
2661 DiskSize
= DiskSize
/ 1073741824;
2662 DiskUnit
= MUIGetString(STRING_GB
);
2666 DiskSize
= DiskSize
/ 1048576;
2667 DiskUnit
= MUIGetString(STRING_MB
);
2670 /* adjust partition size */
2671 PartSize
= PartEntry
->SectorCount
.QuadPart
* DiskEntry
->BytesPerSector
;
2672 if (PartSize
>= 10737418240) /* 10 GB */
2674 PartSize
= PartSize
/ 1073741824;
2675 PartUnit
= MUIGetString(STRING_GB
);
2679 PartSize
= PartSize
/ 1048576;
2680 PartUnit
= MUIGetString(STRING_MB
);
2683 /* adjust partition type */
2684 GetPartTypeStringFromPartitionType(PartEntry
->PartitionType
, PartTypeString
, 30);
2686 if (PartEntry
->AutoCreate
== TRUE
)
2688 CONSOLE_SetTextXY(6, 8, MUIGetString(STRING_NEWPARTITION
));
2691 CONSOLE_PrintTextXY(8, 10, "Partition %lu (%I64u %s) %s of",
2692 PartEntry
->PartitionNumber
,
2698 CONSOLE_PrintTextXY(8, 10, MUIGetString(STRING_HDINFOPARTZEROED
),
2699 DiskEntry
->DiskNumber
,
2705 &DiskEntry
->DriverName
);
2707 CONSOLE_SetTextXY(6, 12, MUIGetString(STRING_PARTFORMAT
));
2710 PartEntry
->AutoCreate
= FALSE
;
2712 else if (PartEntry
->New
== TRUE
)
2714 switch (PartitionList
->FormatState
)
2716 case FormatSystemPartition
:
2717 CONSOLE_SetTextXY(6, 8, MUIGetString(STRING_NONFORMATTEDSYSTEMPART
));
2720 case FormatInstallPartition
:
2721 CONSOLE_SetTextXY(6, 8, MUIGetString(STRING_NONFORMATTEDPART
));
2724 case FormatOtherPartition
:
2725 CONSOLE_SetTextXY(6, 8, MUIGetString(STRING_NONFORMATTEDOTHERPART
));
2732 CONSOLE_SetTextXY(6, 10, MUIGetString(STRING_PARTFORMAT
));
2736 CONSOLE_SetTextXY(6, 8, MUIGetString(STRING_INSTALLONPART
));
2738 if (PartTypeString
== NULL
)
2740 CONSOLE_PrintTextXY(8, 10,
2741 MUIGetString(STRING_HDDINFOUNK4
),
2742 (PartEntry
->DriveLetter
== 0) ? '-' : PartEntry
->DriveLetter
,
2743 (PartEntry
->DriveLetter
== 0) ? '-' : ':',
2744 PartEntry
->PartitionType
,
2750 CONSOLE_PrintTextXY(8, 10,
2752 (PartEntry
->DriveLetter
== 0) ? '-' : PartEntry
->DriveLetter
,
2753 (PartEntry
->DriveLetter
== 0) ? '-' : ':',
2759 CONSOLE_PrintTextXY(6, 12, MUIGetString(STRING_HDINFOPARTEXISTS
),
2760 DiskEntry
->DiskNumber
,
2766 &DiskEntry
->DriverName
);
2769 MUIDisplayPage(SELECT_FILE_SYSTEM_PAGE
);
2771 if (FileSystemList
== NULL
)
2773 FileSystemList
= CreateFileSystemList(6, 26, PartEntry
->New
, L
"FAT");
2774 if (FileSystemList
== NULL
)
2776 /* FIXME: show an error dialog */
2780 /* FIXME: Add file systems to list */
2783 DrawFileSystemList(FileSystemList
);
2785 if (RepairUpdateFlag
)
2787 return CHECK_FILE_SYSTEM_PAGE
;
2788 //return SELECT_PARTITION_PAGE;
2791 if (IsUnattendedSetup
)
2793 if (UnattendFormatPartition
)
2795 PartEntry
->FileSystem
= GetFileSystemByName(FileSystemList
, L
"FAT");
2796 return FORMAT_PARTITION_PAGE
;
2799 return CHECK_FILE_SYSTEM_PAGE
;
2804 CONSOLE_ConInKey(Ir
);
2806 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
2807 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
2809 if (ConfirmQuit(Ir
) == TRUE
)
2814 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
2815 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
)) /* ESC */
2817 return SELECT_PARTITION_PAGE
;
2819 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
2820 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
)) /* DOWN */
2822 ScrollDownFileSystemList(FileSystemList
);
2824 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
2825 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_UP
)) /* UP */
2827 ScrollUpFileSystemList(FileSystemList
);
2829 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_RETURN
) /* ENTER */
2831 if (!FileSystemList
->Selected
->FormatFunc
)
2833 return SELECT_FILE_SYSTEM_PAGE
;
2837 PartEntry
->FileSystem
= FileSystemList
->Selected
;
2838 return FORMAT_PARTITION_PAGE
;
2843 return SELECT_FILE_SYSTEM_PAGE
;
2848 * Displays the FormatPartitionPage.
2851 * InstallDirectoryPage (At once if IsUnattendedSetup or InstallShortcut)
2852 * SelectPartitionPage (At once)
2856 * Sets PartitionList->CurrentPartition->FormatState
2857 * Sets DestinationRootPath
2860 * Number of the next page.
2863 FormatPartitionPage(PINPUT_RECORD Ir
)
2865 UNICODE_STRING PartitionRootPath
;
2866 WCHAR PathBuffer
[MAX_PATH
];
2867 PDISKENTRY DiskEntry
;
2868 PPARTENTRY PartEntry
;
2877 DPRINT("FormatPartitionPage()\n");
2879 MUIDisplayPage(FORMAT_PARTITION_PAGE
);
2881 if (PartitionList
== NULL
||
2882 PartitionList
->TempDisk
== NULL
||
2883 PartitionList
->TempPartition
== NULL
)
2885 /* FIXME: show an error dialog */
2889 DiskEntry
= PartitionList
->TempDisk
;
2890 PartEntry
= PartitionList
->TempPartition
;
2894 if (!IsUnattendedSetup
)
2896 CONSOLE_ConInKey(Ir
);
2899 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
2900 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
2902 if (ConfirmQuit(Ir
) == TRUE
)
2907 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_RETURN
|| IsUnattendedSetup
) /* ENTER */
2909 CONSOLE_SetStatusText(MUIGetString(STRING_PLEASEWAIT
));
2911 if (wcscmp(PartEntry
->FileSystem
->FileSystemName
, L
"FAT") == 0)
2913 if (PartEntry
->SectorCount
.QuadPart
< 8192)
2915 /* FAT12 CHS partition (disk is smaller than 4.1MB) */
2916 PartEntry
->PartitionType
= PARTITION_FAT_12
;
2918 else if (PartEntry
->StartSector
.QuadPart
< 1450560)
2920 /* Partition starts below the 8.4GB boundary ==> CHS partition */
2922 if (PartEntry
->SectorCount
.QuadPart
< 65536)
2924 /* FAT16 CHS partition (partition size < 32MB) */
2925 PartEntry
->PartitionType
= PARTITION_FAT_16
;
2927 else if (PartEntry
->SectorCount
.QuadPart
< 1048576)
2929 /* FAT16 CHS partition (partition size < 512MB) */
2930 PartEntry
->PartitionType
= PARTITION_HUGE
;
2934 /* FAT32 CHS partition (partition size >= 512MB) */
2935 PartEntry
->PartitionType
= PARTITION_FAT32
;
2940 /* Partition starts above the 8.4GB boundary ==> LBA partition */
2942 if (PartEntry
->SectorCount
.QuadPart
< 1048576)
2944 /* FAT16 LBA partition (partition size < 512MB) */
2945 PartEntry
->PartitionType
= PARTITION_XINT13
;
2949 /* FAT32 LBA partition (partition size >= 512MB) */
2950 PartEntry
->PartitionType
= PARTITION_FAT32_XINT13
;
2954 DiskEntry
->Dirty
= TRUE
;
2955 DiskEntry
->LayoutBuffer
->PartitionEntry
[PartEntry
->PartitionIndex
].PartitionType
= PartEntry
->PartitionType
;
2956 DiskEntry
->LayoutBuffer
->PartitionEntry
[PartEntry
->PartitionIndex
].RewritePartition
= TRUE
;
2959 else if (wcscmp(PartEntry
->FileSystem
->FileSystemName
, L
"EXT2") == 0)
2961 PartEntry
->PartitionType
= PARTITION_EXT2
;
2963 DiskEntry
->Dirty
= TRUE
;
2964 DiskEntry
->LayoutBuffer
->PartitionEntry
[PartEntry
->PartitionIndex
].PartitionType
= PartEntry
->PartitionType
;
2965 DiskEntry
->LayoutBuffer
->PartitionEntry
[PartEntry
->PartitionIndex
].RewritePartition
= TRUE
;
2967 else if (wcscmp(PartEntry
->FileSystem
->FileSystemName
, L
"NTFS") == 0)
2969 PartEntry
->PartitionType
= PARTITION_IFS
;
2971 DiskEntry
->Dirty
= TRUE
;
2972 DiskEntry
->LayoutBuffer
->PartitionEntry
[PartEntry
->PartitionIndex
].PartitionType
= PartEntry
->PartitionType
;
2973 DiskEntry
->LayoutBuffer
->PartitionEntry
[PartEntry
->PartitionIndex
].RewritePartition
= TRUE
;
2976 else if (!PartEntry
->FileSystem
->FormatFunc
)
2978 /* FIXME: show an error dialog */
2983 CONSOLE_PrintTextXY(6, 12,
2984 "Disk: %I64u Cylinder: %I64u Track: %I64u",
2985 DiskEntry
->DiskSize
,
2986 DiskEntry
->CylinderSize
,
2987 DiskEntry
->TrackSize
);
2990 DiskEntry
= PartitionList
->TempDisk
;
2991 Entry
= DiskEntry
->PartListHead
.Flink
;
2993 while (Entry
!= &DiskEntry
->PrimaryPartListHead
)
2995 PartEntry
= CONTAINING_RECORD(Entry
, PARTENTRY
, ListEntry
);
2997 if (PartEntry
->IsPartitioned
== TRUE
)
2999 CONSOLE_PrintTextXY(6, Line
,
3000 "%2u: %2u %c %12I64u %12I64u %2u %c",
3002 PartEntry
->PartitionNumber
,
3003 PartEntry
->BootIndicator
? 'A' : '-',
3004 PartEntry
->StartSector
.QuadPart
,
3005 PartEntry
->SectorCount
.QuadPart
,
3006 PartEntry
->PartitionType
,
3007 PartEntry
->Dirty
? '*' : ' ');
3011 Entry
= Entry
->Flink
;
3014 /* Restore the old entry */
3015 PartEntry
= PartitionList
->TempPartition
;
3018 if (WritePartitionsToDisk(PartitionList
) == FALSE
)
3020 DPRINT("WritePartitionsToDisk() failed\n");
3021 MUIDisplayError(ERROR_WRITE_PTABLE
, Ir
, POPUP_WAIT_ENTER
);
3025 /* Set PartitionRootPath */
3026 swprintf(PathBuffer
,
3027 L
"\\Device\\Harddisk%lu\\Partition%lu",
3028 DiskEntry
->DiskNumber
,
3029 PartEntry
->PartitionNumber
);
3030 RtlInitUnicodeString(&PartitionRootPath
,
3032 DPRINT("PartitionRootPath: %wZ\n", &PartitionRootPath
);
3034 if (PartEntry
->FileSystem
->FormatFunc
)
3036 Status
= FormatPartition(&PartitionRootPath
,
3037 PartEntry
->FileSystem
);
3038 if (!NT_SUCCESS(Status
))
3040 DPRINT1("FormatPartition() failed with status 0x%08lx\n", Status
);
3041 MUIDisplayError(ERROR_FORMATTING_PARTITION
, Ir
, POPUP_WAIT_ANY_KEY
, PathBuffer
);
3045 PartEntry
->New
= FALSE
;
3049 CONSOLE_SetStatusText(" Done. Press any key ...");
3050 CONSOLE_ConInKey(Ir
);
3053 return SELECT_FILE_SYSTEM_PAGE
;
3057 return FORMAT_PARTITION_PAGE
;
3062 * Displays the CheckFileSystemPage.
3065 * InstallDirectoryPage (At once)
3069 * Inits or reloads FileSystemList
3072 * Number of the next page.
3075 CheckFileSystemPage(PINPUT_RECORD Ir
)
3077 PFILE_SYSTEM_ITEM CurrentFileSystem
;
3078 UNICODE_STRING PartitionRootPath
;
3079 WCHAR PathBuffer
[MAX_PATH
];
3080 CHAR Buffer
[MAX_PATH
];
3081 PDISKENTRY DiskEntry
;
3082 PPARTENTRY PartEntry
;
3085 if (PartitionList
== NULL
)
3087 /* FIXME: show an error dialog */
3091 if (!GetNextUncheckedPartition(PartitionList
, &DiskEntry
, &PartEntry
))
3093 return INSTALL_DIRECTORY_PAGE
;
3096 /* Set PartitionRootPath */
3097 swprintf(PathBuffer
,
3098 L
"\\Device\\Harddisk%lu\\Partition%lu",
3099 DiskEntry
->DiskNumber
,
3100 PartEntry
->PartitionNumber
);
3101 RtlInitUnicodeString(&PartitionRootPath
, PathBuffer
);
3102 DPRINT("PartitionRootPath: %wZ\n", &PartitionRootPath
);
3104 CONSOLE_SetTextXY(6, 8, MUIGetString(STRING_CHECKINGPART
));
3106 CONSOLE_SetStatusText(MUIGetString(STRING_PLEASEWAIT
));
3108 CurrentFileSystem
= GetFileSystem(FileSystemList
, PartEntry
);
3109 DPRINT1("CheckFileSystemPage -- PartitionType: 0x%02X ; FileSystemName: %S\n",
3110 PartEntry
->PartitionType
, (CurrentFileSystem
? CurrentFileSystem
->FileSystemName
: L
"n/a"));
3112 /* HACK: Do not try to check a partition with an unknown filesytem */
3113 if (CurrentFileSystem
== NULL
)
3115 PartEntry
->NeedsCheck
= FALSE
;
3116 return CHECK_FILE_SYSTEM_PAGE
;
3119 if (CurrentFileSystem
->ChkdskFunc
== NULL
)
3122 "Setup is currently unable to check a partition formatted in %S.\n"
3124 " \x07 Press ENTER to continue Setup.\n"
3125 " \x07 Press F3 to quit Setup.",
3126 CurrentFileSystem
->FileSystemName
);
3129 MUIGetString(STRING_QUITCONTINUE
),
3130 NULL
, POPUP_WAIT_NONE
);
3134 CONSOLE_ConInKey(Ir
);
3136 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00 &&
3137 Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
) /* F3 */
3139 if (ConfirmQuit(Ir
))
3142 return CHECK_FILE_SYSTEM_PAGE
;
3144 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== VK_RETURN
) /* ENTER */
3146 PartEntry
->NeedsCheck
= FALSE
;
3147 return CHECK_FILE_SYSTEM_PAGE
;
3153 Status
= ChkdskPartition(&PartitionRootPath
, CurrentFileSystem
);
3154 if (!NT_SUCCESS(Status
))
3156 DPRINT("ChkdskPartition() failed with status 0x%08lx\n", Status
);
3157 // sprintf(Buffer, "Setup failed to verify the selected partition.\n"
3158 sprintf(Buffer
, "ChkDsk detected some disk errors.\n"
3159 "(Status 0x%08lx).\n", Status
);
3161 // MUIGetString(STRING_REBOOTCOMPUTER),
3162 MUIGetString(STRING_CONTINUE
),
3163 Ir
, POPUP_WAIT_ENTER
);
3165 // return QUIT_PAGE;
3168 PartEntry
->NeedsCheck
= FALSE
;
3169 return CHECK_FILE_SYSTEM_PAGE
;
3175 * Displays the InstallDirectoryPage1.
3178 * PrepareCopyPage (At once)
3181 * Inits DestinationRootPath
3182 * Inits DestinationPath
3183 * Inits DestinationArcPath
3186 * Number of the next page.
3189 InstallDirectoryPage1(PWCHAR InstallDir
,
3190 PDISKENTRY DiskEntry
,
3191 PPARTENTRY PartEntry
)
3193 WCHAR PathBuffer
[MAX_PATH
];
3195 /* Create 'InstallPath' string */
3196 RtlFreeUnicodeString(&InstallPath
);
3197 RtlCreateUnicodeString(&InstallPath
, InstallDir
);
3199 /* Create 'DestinationRootPath' string */
3200 RtlFreeUnicodeString(&DestinationRootPath
);
3201 swprintf(PathBuffer
,
3202 L
"\\Device\\Harddisk%lu\\Partition%lu",
3203 DiskEntry
->DiskNumber
,
3204 PartEntry
->PartitionNumber
);
3205 RtlCreateUnicodeString(&DestinationRootPath
, PathBuffer
);
3206 DPRINT("DestinationRootPath: %wZ\n", &DestinationRootPath
);
3208 /* Create 'DestinationPath' string */
3209 RtlFreeUnicodeString(&DestinationPath
);
3210 wcscpy(PathBuffer
, DestinationRootPath
.Buffer
);
3212 if (InstallDir
[0] != L
'\\')
3213 wcscat(PathBuffer
, L
"\\");
3215 wcscat(PathBuffer
, InstallDir
);
3216 RtlCreateUnicodeString(&DestinationPath
, PathBuffer
);
3218 /* Create 'DestinationArcPath' */
3219 RtlFreeUnicodeString(&DestinationArcPath
);
3220 swprintf(PathBuffer
,
3221 L
"multi(0)disk(0)rdisk(%lu)partition(%lu)",
3222 DiskEntry
->BiosDiskNumber
,
3223 PartEntry
->PartitionNumber
);
3225 if (InstallDir
[0] != L
'\\')
3226 wcscat(PathBuffer
, L
"\\");
3228 wcscat(PathBuffer
, InstallDir
);
3229 RtlCreateUnicodeString(&DestinationArcPath
, PathBuffer
);
3231 return PREPARE_COPY_PAGE
;
3236 * Displays the InstallDirectoryPage.
3239 * PrepareCopyPage (As the direct result of InstallDirectoryPage1)
3243 * Number of the next page.
3246 InstallDirectoryPage(PINPUT_RECORD Ir
)
3248 PDISKENTRY DiskEntry
;
3249 PPARTENTRY PartEntry
;
3250 WCHAR InstallDir
[51];
3254 /* We do not need the filsystem list any more */
3255 DestroyFileSystemList(FileSystemList
);
3256 FileSystemList
= NULL
;
3258 if (PartitionList
== NULL
||
3259 PartitionList
->CurrentDisk
== NULL
||
3260 PartitionList
->CurrentPartition
== NULL
)
3262 /* FIXME: show an error dialog */
3266 DiskEntry
= PartitionList
->CurrentDisk
;
3267 PartEntry
= PartitionList
->CurrentPartition
;
3269 if (IsUnattendedSetup
)
3270 wcscpy(InstallDir
, UnattendInstallationDirectory
);
3272 wcscpy(InstallDir
, L
"\\ReactOS");
3274 Length
= wcslen(InstallDir
);
3275 CONSOLE_SetInputTextXY(8, 11, 51, InstallDir
);
3276 MUIDisplayPage(INSTALL_DIRECTORY_PAGE
);
3278 // FIXME: Check the validity of the InstallDir; however what to do
3279 // if it is invalid but we are in unattended setup? (case of somebody
3280 // specified an invalid installation directory in the unattended file).
3282 if (IsUnattendedSetup
)
3284 return InstallDirectoryPage1(InstallDir
,
3291 CONSOLE_ConInKey(Ir
);
3293 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
3294 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
3296 if (ConfirmQuit(Ir
) == TRUE
)
3301 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
3304 * Check for the validity of the installation directory and pop up
3305 * an error if it is not the case. Then the user can fix its input.
3307 if (!IsValidPath(InstallDir
, Length
))
3309 MUIDisplayError(ERROR_DIRECTORY_NAME
, Ir
, POPUP_WAIT_ENTER
);
3310 return INSTALL_DIRECTORY_PAGE
;
3312 return InstallDirectoryPage1(InstallDir
,
3316 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x08) /* BACKSPACE */
3321 InstallDir
[Length
] = 0;
3322 CONSOLE_SetInputTextXY(8, 11, 51, InstallDir
);
3325 else if (isprint(Ir
->Event
.KeyEvent
.uChar
.AsciiChar
))
3329 c
= (WCHAR
)Ir
->Event
.KeyEvent
.uChar
.AsciiChar
;
3330 if (iswalpha(c
) || iswdigit(c
) || c
== '.' || c
== '\\' || c
== '-' || c
== '_')
3332 InstallDir
[Length
] = c
;
3334 InstallDir
[Length
] = 0;
3335 CONSOLE_SetInputTextXY(8, 11, 51, InstallDir
);
3341 return INSTALL_DIRECTORY_PAGE
;
3346 AddSectionToCopyQueueCab(HINF InfFile
,
3348 PWCHAR SourceCabinet
,
3349 PCUNICODE_STRING DestinationPath
,
3352 INFCONTEXT FilesContext
;
3353 INFCONTEXT DirContext
;
3355 PWCHAR FileKeyValue
;
3357 PWCHAR TargetFileName
;
3359 /* Search for the SectionName section */
3360 if (!SetupFindFirstLineW(InfFile
, SectionName
, NULL
, &FilesContext
))
3363 sprintf(Buffer
, MUIGetString(STRING_TXTSETUPFAILED
), SectionName
);
3364 PopupError(Buffer
, MUIGetString(STRING_REBOOTCOMPUTER
), Ir
, POPUP_WAIT_ENTER
);
3369 * Enumerate the files in the section
3370 * and add them to the file queue.
3374 /* Get source file name and target directory id */
3375 if (!INF_GetData(&FilesContext
, &FileKeyName
, &FileKeyValue
))
3377 /* FIXME: Handle error! */
3378 DPRINT1("INF_GetData() failed\n");
3382 /* Get optional target file name */
3383 if (!INF_GetDataField(&FilesContext
, 2, &TargetFileName
))
3384 TargetFileName
= NULL
;
3386 DPRINT("FileKeyName: '%S' FileKeyValue: '%S'\n", FileKeyName
, FileKeyValue
);
3388 /* Lookup target directory */
3389 if (!SetupFindFirstLineW(InfFile
, L
"Directories", FileKeyValue
, &DirContext
))
3391 /* FIXME: Handle error! */
3392 DPRINT1("SetupFindFirstLine() failed\n");
3396 if (!INF_GetData(&DirContext
, NULL
, &DirKeyValue
))
3398 /* FIXME: Handle error! */
3399 DPRINT1("INF_GetData() failed\n");
3403 if (!SetupQueueCopy(SetupFileQueue
,
3405 SourceRootPath
.Buffer
,
3406 SourceRootDir
.Buffer
,
3411 /* FIXME: Handle error! */
3412 DPRINT1("SetupQueueCopy() failed\n");
3414 } while (SetupFindNextLine(&FilesContext
, &FilesContext
));
3421 AddSectionToCopyQueue(HINF InfFile
,
3423 PWCHAR SourceCabinet
,
3424 PCUNICODE_STRING DestinationPath
,
3427 INFCONTEXT FilesContext
;
3428 INFCONTEXT DirContext
;
3430 PWCHAR FileKeyValue
;
3432 PWCHAR TargetFileName
;
3434 WCHAR CompleteOrigDirName
[512];
3437 return AddSectionToCopyQueueCab(InfFile
, L
"SourceFiles", SourceCabinet
, DestinationPath
, Ir
);
3439 /* Search for the SectionName section */
3440 if (!SetupFindFirstLineW(InfFile
, SectionName
, NULL
, &FilesContext
))
3443 sprintf(Buffer
, MUIGetString(STRING_TXTSETUPFAILED
), SectionName
);
3444 PopupError(Buffer
, MUIGetString(STRING_REBOOTCOMPUTER
), Ir
, POPUP_WAIT_ENTER
);
3449 * Enumerate the files in the section
3450 * and add them to the file queue.
3454 /* Get source file name and target directory id */
3455 if (!INF_GetData(&FilesContext
, &FileKeyName
, &FileKeyValue
))
3457 /* FIXME: Handle error! */
3458 DPRINT1("INF_GetData() failed\n");
3462 /* Get target directory id */
3463 if (!INF_GetDataField(&FilesContext
, 13, &FileKeyValue
))
3465 /* FIXME: Handle error! */
3466 DPRINT1("INF_GetData() failed\n");
3470 /* Get optional target file name */
3471 if (!INF_GetDataField(&FilesContext
, 11, &TargetFileName
))
3472 TargetFileName
= NULL
;
3473 else if (!*TargetFileName
)
3474 TargetFileName
= NULL
;
3476 DPRINT("FileKeyName: '%S' FileKeyValue: '%S'\n", FileKeyName
, FileKeyValue
);
3478 /* Lookup target directory */
3479 if (!SetupFindFirstLineW(InfFile
, L
"Directories", FileKeyValue
, &DirContext
))
3481 /* FIXME: Handle error! */
3482 DPRINT1("SetupFindFirstLine() failed\n");
3486 if (!INF_GetData(&DirContext
, NULL
, &DirKeyValue
))
3488 /* FIXME: Handle error! */
3489 DPRINT1("INF_GetData() failed\n");
3493 if ((DirKeyValue
[0] == 0) || (DirKeyValue
[0] == L
'\\' && DirKeyValue
[1] == 0))
3495 /* Installation path */
3496 wcscpy(CompleteOrigDirName
, SourceRootDir
.Buffer
);
3498 else if (DirKeyValue
[0] == L
'\\')
3501 wcscpy(CompleteOrigDirName
, DirKeyValue
);
3503 else // if (DirKeyValue[0] != L'\\')
3505 /* Path relative to the installation path */
3506 wcscpy(CompleteOrigDirName
, SourceRootDir
.Buffer
);
3507 wcscat(CompleteOrigDirName
, L
"\\");
3508 wcscat(CompleteOrigDirName
, DirKeyValue
);
3511 /* Remove trailing backslash */
3512 Length
= wcslen(CompleteOrigDirName
);
3513 if ((Length
> 0) && (CompleteOrigDirName
[Length
- 1] == L
'\\'))
3515 CompleteOrigDirName
[Length
- 1] = 0;
3518 if (!SetupQueueCopy(SetupFileQueue
,
3520 SourceRootPath
.Buffer
,
3521 CompleteOrigDirName
,
3526 /* FIXME: Handle error! */
3527 DPRINT1("SetupQueueCopy() failed\n");
3529 } while (SetupFindNextLine(&FilesContext
, &FilesContext
));
3536 PrepareCopyPageInfFile(HINF InfFile
,
3537 PWCHAR SourceCabinet
,
3540 WCHAR PathBuffer
[MAX_PATH
];
3541 INFCONTEXT DirContext
;
3542 PWCHAR AdditionalSectionName
= NULL
;
3547 /* Add common files */
3548 if (!AddSectionToCopyQueue(InfFile
, L
"SourceDisksFiles", SourceCabinet
, &DestinationPath
, Ir
))
3551 /* Add specific files depending of computer type */
3552 if (SourceCabinet
== NULL
)
3554 if (!ProcessComputerFiles(InfFile
, ComputerList
, &AdditionalSectionName
))
3557 if (AdditionalSectionName
)
3559 if (!AddSectionToCopyQueue(InfFile
, AdditionalSectionName
, SourceCabinet
, &DestinationPath
, Ir
))
3564 /* Create directories */
3568 * - Install directories like '\reactos\test' are not handled yet.
3569 * - Copying files to DestinationRootPath should be done from within
3570 * the SystemPartitionFiles section.
3571 * At the moment we check whether we specify paths like '\foo' or '\\' for that.
3572 * For installing to DestinationPath specify just '\' .
3575 /* Get destination path */
3576 wcscpy(PathBuffer
, DestinationPath
.Buffer
);
3578 /* Remove trailing backslash */
3579 Length
= wcslen(PathBuffer
);
3580 if ((Length
> 0) && (PathBuffer
[Length
- 1] == L
'\\'))
3582 PathBuffer
[Length
- 1] = 0;
3585 /* Create the install directory */
3586 Status
= SetupCreateDirectory(PathBuffer
);
3587 if (!NT_SUCCESS(Status
) && Status
!= STATUS_OBJECT_NAME_COLLISION
)
3589 DPRINT("Creating directory '%S' failed: Status = 0x%08lx", PathBuffer
, Status
);
3590 MUIDisplayError(ERROR_CREATE_INSTALL_DIR
, Ir
, POPUP_WAIT_ENTER
);
3594 /* Search for the 'Directories' section */
3595 if (!SetupFindFirstLineW(InfFile
, L
"Directories", NULL
, &DirContext
))
3599 MUIDisplayError(ERROR_CABINET_SECTION
, Ir
, POPUP_WAIT_ENTER
);
3603 MUIDisplayError(ERROR_TXTSETUP_SECTION
, Ir
, POPUP_WAIT_ENTER
);
3609 /* Enumerate the directory values and create the subdirectories */
3612 if (!INF_GetData(&DirContext
, NULL
, &DirKeyValue
))
3618 if ((DirKeyValue
[0] == 0) || (DirKeyValue
[0] == L
'\\' && DirKeyValue
[1] == 0))
3620 /* Installation path */
3621 DPRINT("InstallationPath: '%S'\n", DirKeyValue
);
3623 wcscpy(PathBuffer
, DestinationPath
.Buffer
);
3625 DPRINT("FullPath: '%S'\n", PathBuffer
);
3627 else if (DirKeyValue
[0] == L
'\\')
3630 DPRINT("Absolute Path: '%S'\n", DirKeyValue
);
3632 wcscpy(PathBuffer
, DestinationRootPath
.Buffer
);
3633 wcscat(PathBuffer
, DirKeyValue
);
3635 /* Remove trailing backslash */
3636 Length
= wcslen(PathBuffer
);
3637 if ((Length
> 0) && (PathBuffer
[Length
- 1] == L
'\\'))
3639 PathBuffer
[Length
- 1] = 0;
3642 DPRINT("FullPath: '%S'\n", PathBuffer
);
3644 Status
= SetupCreateDirectory(PathBuffer
);
3645 if (!NT_SUCCESS(Status
) && Status
!= STATUS_OBJECT_NAME_COLLISION
)
3647 DPRINT("Creating directory '%S' failed: Status = 0x%08lx", PathBuffer
, Status
);
3648 MUIDisplayError(ERROR_CREATE_DIR
, Ir
, POPUP_WAIT_ENTER
);
3652 else // if (DirKeyValue[0] != L'\\')
3654 /* Path relative to the installation path */
3655 DPRINT("RelativePath: '%S'\n", DirKeyValue
);
3657 wcscpy(PathBuffer
, DestinationPath
.Buffer
);
3658 wcscat(PathBuffer
, L
"\\");
3659 wcscat(PathBuffer
, DirKeyValue
);
3661 /* Remove trailing backslash */
3662 Length
= wcslen(PathBuffer
);
3663 if ((Length
> 0) && (PathBuffer
[Length
- 1] == L
'\\'))
3665 PathBuffer
[Length
- 1] = 0;
3668 DPRINT("FullPath: '%S'\n", PathBuffer
);
3670 Status
= SetupCreateDirectory(PathBuffer
);
3671 if (!NT_SUCCESS(Status
) && Status
!= STATUS_OBJECT_NAME_COLLISION
)
3673 DPRINT("Creating directory '%S' failed: Status = 0x%08lx", PathBuffer
, Status
);
3674 MUIDisplayError(ERROR_CREATE_DIR
, Ir
, POPUP_WAIT_ENTER
);
3678 } while (SetupFindNextLine(&DirContext
, &DirContext
));
3685 * Displays the PrepareCopyPage.
3688 * FileCopyPage(At once)
3692 * Inits SetupFileQueue
3693 * Calls PrepareCopyPageInfFile
3696 * Number of the next page.
3699 PrepareCopyPage(PINPUT_RECORD Ir
)
3702 WCHAR PathBuffer
[MAX_PATH
];
3703 INFCONTEXT CabinetsContext
;
3709 MUIDisplayPage(PREPARE_COPY_PAGE
);
3711 /* Create the file queue */
3712 SetupFileQueue
= SetupOpenFileQueue();
3713 if (SetupFileQueue
== NULL
)
3715 MUIDisplayError(ERROR_COPY_QUEUE
, Ir
, POPUP_WAIT_ENTER
);
3719 if (!PrepareCopyPageInfFile(SetupInf
, NULL
, Ir
))
3721 /* FIXME: show an error dialog */
3725 /* Search for the 'Cabinets' section */
3726 if (!SetupFindFirstLineW(SetupInf
, L
"Cabinets", NULL
, &CabinetsContext
))
3728 return FILE_COPY_PAGE
;
3732 * Enumerate the directory values in the 'Cabinets'
3733 * section and parse their inf files.
3737 if (!INF_GetData(&CabinetsContext
, NULL
, &KeyValue
))
3740 wcscpy(PathBuffer
, SourcePath
.Buffer
);
3741 wcscat(PathBuffer
, L
"\\");
3742 wcscat(PathBuffer
, KeyValue
);
3745 CabinetInitialize();
3746 CabinetSetEventHandlers(NULL
, NULL
, NULL
);
3747 CabinetSetCabinetName(PathBuffer
);
3749 if (CabinetOpen() == CAB_STATUS_SUCCESS
)
3751 DPRINT("Cabinet %S\n", CabinetGetCabinetName());
3753 InfFileData
= CabinetGetCabinetReservedArea(&InfFileSize
);
3754 if (InfFileData
== NULL
)
3756 MUIDisplayError(ERROR_CABINET_SCRIPT
, Ir
, POPUP_WAIT_ENTER
);
3762 DPRINT("Cannot open cabinet: %S.\n", CabinetGetCabinetName());
3763 MUIDisplayError(ERROR_CABINET_MISSING
, Ir
, POPUP_WAIT_ENTER
);
3767 InfHandle
= INF_OpenBufferedFileA((CHAR
*) InfFileData
,
3774 if (InfHandle
== INVALID_HANDLE_VALUE
)
3776 MUIDisplayError(ERROR_INVALID_CABINET_INF
, Ir
, POPUP_WAIT_ENTER
);
3782 if (!PrepareCopyPageInfFile(InfHandle
, KeyValue
, Ir
))
3784 /* FIXME: show an error dialog */
3788 } while (SetupFindNextLine(&CabinetsContext
, &CabinetsContext
));
3790 return FILE_COPY_PAGE
;
3796 SetupUpdateMemoryInfo(IN PCOPYCONTEXT CopyContext
,
3799 SYSTEM_PERFORMANCE_INFORMATION PerfInfo
;
3801 /* Get the memory information from the system */
3802 NtQuerySystemInformation(SystemPerformanceInformation
,
3807 /* Check if this is initial setup */
3810 /* Set maximum limits to be total RAM pages */
3811 ProgressSetStepCount(CopyContext
->MemoryBars
[0], PerfInfo
.CommitLimit
);
3812 ProgressSetStepCount(CopyContext
->MemoryBars
[1], PerfInfo
.CommitLimit
);
3813 ProgressSetStepCount(CopyContext
->MemoryBars
[2], PerfInfo
.CommitLimit
);
3816 /* Set current values */
3817 ProgressSetStep(CopyContext
->MemoryBars
[0], PerfInfo
.PagedPoolPages
+ PerfInfo
.NonPagedPoolPages
);
3818 ProgressSetStep(CopyContext
->MemoryBars
[1], PerfInfo
.ResidentSystemCachePage
);
3819 ProgressSetStep(CopyContext
->MemoryBars
[2], PerfInfo
.AvailablePages
);
3825 FileCopyCallback(PVOID Context
,
3830 PCOPYCONTEXT CopyContext
;
3832 CopyContext
= (PCOPYCONTEXT
)Context
;
3834 switch (Notification
)
3836 case SPFILENOTIFY_STARTSUBQUEUE
:
3837 CopyContext
->TotalOperations
= (ULONG
)Param2
;
3838 ProgressSetStepCount(CopyContext
->ProgressBar
,
3839 CopyContext
->TotalOperations
);
3840 SetupUpdateMemoryInfo(CopyContext
, TRUE
);
3843 case SPFILENOTIFY_STARTCOPY
:
3844 /* Display copy message */
3845 CONSOLE_SetStatusText(MUIGetString(STRING_COPYING
), (PWSTR
)Param1
);
3846 SetupUpdateMemoryInfo(CopyContext
, FALSE
);
3849 case SPFILENOTIFY_ENDCOPY
:
3850 CopyContext
->CompletedOperations
++;
3852 /* SYSREG checkpoint */
3853 if (CopyContext
->TotalOperations
>> 1 == CopyContext
->CompletedOperations
)
3854 DPRINT1("CHECKPOINT:HALF_COPIED\n");
3856 ProgressNextStep(CopyContext
->ProgressBar
);
3857 SetupUpdateMemoryInfo(CopyContext
, FALSE
);
3866 * Displays the FileCopyPage.
3869 * RegistryPage(At once)
3872 * Calls SetupCommitFileQueueW
3873 * Calls SetupCloseFileQueue
3876 * Number of the next page.
3880 FileCopyPage(PINPUT_RECORD Ir
)
3882 COPYCONTEXT CopyContext
;
3883 unsigned int mem_bar_width
;
3885 MUIDisplayPage(FILE_COPY_PAGE
);
3887 /* Create context for the copy process */
3888 CopyContext
.DestinationRootPath
= DestinationRootPath
.Buffer
;
3889 CopyContext
.InstallPath
= InstallPath
.Buffer
;
3890 CopyContext
.TotalOperations
= 0;
3891 CopyContext
.CompletedOperations
= 0;
3893 /* Create the progress bar as well */
3894 CopyContext
.ProgressBar
= CreateProgressBar(13,
3901 MUIGetString(STRING_SETUPCOPYINGFILES
));
3903 // fit memory bars to screen width, distribute them uniform
3904 mem_bar_width
= (xScreen
- 26) / 5;
3905 mem_bar_width
-= mem_bar_width
% 2; // make even
3906 /* ATTENTION: The following progress bars are debug stuff, which should not be translated!! */
3907 /* Create the paged pool progress bar */
3908 CopyContext
.MemoryBars
[0] = CreateProgressBar(13,
3917 /* Create the non paged pool progress bar */
3918 CopyContext
.MemoryBars
[1] = CreateProgressBar((xScreen
/ 2)- (mem_bar_width
/ 2),
3920 (xScreen
/ 2) + (mem_bar_width
/ 2),
3922 (xScreen
/ 2)- (mem_bar_width
/ 2),
3927 /* Create the global memory progress bar */
3928 CopyContext
.MemoryBars
[2] = CreateProgressBar(xScreen
- 13 - mem_bar_width
,
3932 xScreen
- 13 - mem_bar_width
,
3937 /* Do the file copying */
3938 SetupCommitFileQueueW(NULL
,
3943 /* If we get here, we're done, so cleanup the queue and progress bar */
3944 SetupCloseFileQueue(SetupFileQueue
);
3945 DestroyProgressBar(CopyContext
.ProgressBar
);
3946 DestroyProgressBar(CopyContext
.MemoryBars
[0]);
3947 DestroyProgressBar(CopyContext
.MemoryBars
[1]);
3948 DestroyProgressBar(CopyContext
.MemoryBars
[2]);
3950 /* Go display the next page */
3951 return REGISTRY_PAGE
;
3956 * Displays the RegistryPage.
3959 * SuccessPage (if RepairUpdate)
3960 * BootLoaderPage (default)
3964 * Calls SetInstallPathValue
3965 * Calls NtInitializeRegistry
3966 * Calls ImportRegistryFile
3967 * Calls SetDefaultPagefile
3968 * Calls SetMountedDeviceValues
3971 * Number of the next page.
3974 RegistryPage(PINPUT_RECORD Ir
)
3976 INFCONTEXT InfContext
;
3983 MUIDisplayPage(REGISTRY_PAGE
);
3985 if (RepairUpdateFlag
)
3987 return SUCCESS_PAGE
;
3990 if (!SetInstallPathValue(&DestinationPath
))
3992 DPRINT1("SetInstallPathValue() failed\n");
3993 MUIDisplayError(ERROR_INITIALIZE_REGISTRY
, Ir
, POPUP_WAIT_ENTER
);
3997 /* Create the default hives */
3998 Status
= NtInitializeRegistry(CM_BOOT_FLAG_SETUP
);
3999 if (!NT_SUCCESS(Status
))
4001 DPRINT1("NtInitializeRegistry() failed (Status %lx)\n", Status
);
4002 MUIDisplayError(ERROR_CREATE_HIVE
, Ir
, POPUP_WAIT_ENTER
);
4006 /* Update registry */
4007 CONSOLE_SetStatusText(MUIGetString(STRING_REGHIVEUPDATE
));
4009 if (!SetupFindFirstLineW(SetupInf
, L
"HiveInfs.Install", NULL
, &InfContext
))
4011 DPRINT1("SetupFindFirstLine() failed\n");
4012 MUIDisplayError(ERROR_FIND_REGISTRY
, Ir
, POPUP_WAIT_ENTER
);
4018 INF_GetDataField(&InfContext
, 0, &Action
);
4019 INF_GetDataField(&InfContext
, 1, &File
);
4020 INF_GetDataField(&InfContext
, 2, &Section
);
4022 DPRINT("Action: %S File: %S Section %S\n", Action
, File
, Section
);
4027 if (!_wcsicmp(Action
, L
"AddReg"))
4031 else if (!_wcsicmp(Action
, L
"DelReg"))
4040 CONSOLE_SetStatusText(MUIGetString(STRING_IMPORTFILE
), File
);
4042 if (!ImportRegistryFile(File
, Section
, LanguageId
, Delete
))
4044 DPRINT1("Importing %S failed\n", File
);
4046 MUIDisplayError(ERROR_IMPORT_HIVE
, Ir
, POPUP_WAIT_ENTER
);
4049 } while (SetupFindNextLine(&InfContext
, &InfContext
));
4051 /* Update display registry settings */
4052 CONSOLE_SetStatusText(MUIGetString(STRING_DISPLAYETTINGSUPDATE
));
4053 if (!ProcessDisplayRegistry(SetupInf
, DisplayList
))
4055 MUIDisplayError(ERROR_UPDATE_DISPLAY_SETTINGS
, Ir
, POPUP_WAIT_ENTER
);
4059 /* Set the locale */
4060 CONSOLE_SetStatusText(MUIGetString(STRING_LOCALESETTINGSUPDATE
));
4061 if (!ProcessLocaleRegistry(LanguageList
))
4063 MUIDisplayError(ERROR_UPDATE_LOCALESETTINGS
, Ir
, POPUP_WAIT_ENTER
);
4067 /* Add keyboard layouts */
4068 CONSOLE_SetStatusText(MUIGetString(STRING_ADDKBLAYOUTS
));
4069 if (!AddKeyboardLayouts())
4071 MUIDisplayError(ERROR_ADDING_KBLAYOUTS
, Ir
, POPUP_WAIT_ENTER
);
4077 if (!SetGeoID(MUIGetGeoID()))
4079 MUIDisplayError(ERROR_UPDATE_GEOID
, Ir
, POPUP_WAIT_ENTER
);
4083 if (!IsUnattendedSetup
)
4085 /* Update keyboard layout settings */
4086 CONSOLE_SetStatusText(MUIGetString(STRING_KEYBOARDSETTINGSUPDATE
));
4087 if (!ProcessKeyboardLayoutRegistry(LayoutList
))
4089 MUIDisplayError(ERROR_UPDATE_KBSETTINGS
, Ir
, POPUP_WAIT_ENTER
);
4094 /* Add codepage information to registry */
4095 CONSOLE_SetStatusText(MUIGetString(STRING_CODEPAGEINFOUPDATE
));
4098 MUIDisplayError(ERROR_ADDING_CODEPAGE
, Ir
, POPUP_WAIT_ENTER
);
4102 /* Set the default pagefile entry */
4103 SetDefaultPagefile(DestinationDriveLetter
);
4105 /* Update the mounted devices list */
4106 SetMountedDeviceValues(PartitionList
);
4108 CONSOLE_SetStatusText(MUIGetString(STRING_DONE
));
4110 return BOOT_LOADER_PAGE
;
4115 * Displays the BootLoaderPage.
4118 * SuccessPage (if RepairUpdate)
4119 * BootLoaderHarddiskMbrPage
4120 * BootLoaderHarddiskVbrPage
4121 * BootLoaderFloppyPage
4126 * Calls SetInstallPathValue
4127 * Calls NtInitializeRegistry
4128 * Calls ImportRegistryFile
4129 * Calls SetDefaultPagefile
4130 * Calls SetMountedDeviceValues
4133 * Number of the next page.
4136 BootLoaderPage(PINPUT_RECORD Ir
)
4138 UCHAR PartitionType
;
4139 BOOLEAN InstallOnFloppy
;
4141 WCHAR PathBuffer
[MAX_PATH
];
4143 CONSOLE_SetStatusText(MUIGetString(STRING_PLEASEWAIT
));
4145 RtlFreeUnicodeString(&SystemRootPath
);
4146 swprintf(PathBuffer
,
4147 L
"\\Device\\Harddisk%lu\\Partition%lu",
4148 PartitionList
->SystemDisk
->DiskNumber
,
4149 PartitionList
->SystemPartition
->PartitionNumber
);
4150 RtlCreateUnicodeString(&SystemRootPath
, PathBuffer
);
4151 DPRINT1("SystemRootPath: %wZ\n", &SystemRootPath
);
4153 PartitionType
= PartitionList
->SystemPartition
->PartitionType
;
4155 if (IsUnattendedSetup
)
4157 if (UnattendMBRInstallType
== 0) /* skip MBR installation */
4159 return SUCCESS_PAGE
;
4161 else if (UnattendMBRInstallType
== 1) /* install on floppy */
4163 return BOOT_LOADER_FLOPPY_PAGE
;
4167 if (PartitionType
== PARTITION_ENTRY_UNUSED
)
4169 DPRINT("Error: system partition invalid (unused)\n");
4170 InstallOnFloppy
= TRUE
;
4172 else if (PartitionType
== PARTITION_OS2BOOTMGR
)
4174 /* OS/2 boot manager partition */
4175 DPRINT("Found OS/2 boot manager partition\n");
4176 InstallOnFloppy
= TRUE
;
4178 else if (PartitionType
== PARTITION_EXT2
)
4180 /* Linux EXT2 partition */
4181 DPRINT("Found Linux EXT2 partition\n");
4182 InstallOnFloppy
= FALSE
;
4184 else if (PartitionType
== PARTITION_IFS
)
4186 /* NTFS partition */
4187 DPRINT("Found NTFS partition\n");
4189 // FIXME: Make it FALSE when we'll support NTFS installation!
4190 InstallOnFloppy
= TRUE
;
4192 else if ((PartitionType
== PARTITION_FAT_12
) ||
4193 (PartitionType
== PARTITION_FAT_16
) ||
4194 (PartitionType
== PARTITION_HUGE
) ||
4195 (PartitionType
== PARTITION_XINT13
) ||
4196 (PartitionType
== PARTITION_FAT32
) ||
4197 (PartitionType
== PARTITION_FAT32_XINT13
))
4199 DPRINT("Found FAT partition\n");
4200 InstallOnFloppy
= FALSE
;
4204 /* Unknown partition */
4205 DPRINT("Unknown partition found\n");
4206 InstallOnFloppy
= TRUE
;
4209 if (InstallOnFloppy
== TRUE
)
4211 return BOOT_LOADER_FLOPPY_PAGE
;
4214 /* Unattended install on hdd? */
4215 if (IsUnattendedSetup
&& UnattendMBRInstallType
== 2)
4217 return BOOT_LOADER_HARDDISK_MBR_PAGE
;
4220 MUIDisplayPage(BOOT_LOADER_PAGE
);
4221 CONSOLE_InvertTextXY(8, Line
, 60, 1);
4225 CONSOLE_ConInKey(Ir
);
4227 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
4228 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
)) /* DOWN */
4230 CONSOLE_NormalTextXY(8, Line
, 60, 1);
4239 CONSOLE_InvertTextXY(8, Line
, 60, 1);
4241 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
4242 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_UP
)) /* UP */
4244 CONSOLE_NormalTextXY(8, Line
, 60, 1);
4253 CONSOLE_InvertTextXY(8, Line
, 60, 1);
4255 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
4256 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
4258 if (ConfirmQuit(Ir
) == TRUE
)
4263 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
4267 return BOOT_LOADER_HARDDISK_MBR_PAGE
;
4269 else if (Line
== 13)
4271 return BOOT_LOADER_HARDDISK_VBR_PAGE
;
4273 else if (Line
== 14)
4275 return BOOT_LOADER_FLOPPY_PAGE
;
4277 else if (Line
== 15)
4279 return SUCCESS_PAGE
;
4282 return BOOT_LOADER_PAGE
;
4286 return BOOT_LOADER_PAGE
;
4291 * Displays the BootLoaderFloppyPage.
4294 * SuccessPage (At once)
4298 * Calls InstallFatBootcodeToFloppy()
4301 * Number of the next page.
4304 BootLoaderFloppyPage(PINPUT_RECORD Ir
)
4308 MUIDisplayPage(BOOT_LOADER_FLOPPY_PAGE
);
4310 // SetStatusText(" Please wait...");
4314 CONSOLE_ConInKey(Ir
);
4316 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
4317 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
4319 if (ConfirmQuit(Ir
) == TRUE
)
4324 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
4326 if (DoesFileExist(L
"\\Device\\Floppy0", L
"\\") == FALSE
)
4328 MUIDisplayError(ERROR_NO_FLOPPY
, Ir
, POPUP_WAIT_ENTER
);
4329 return BOOT_LOADER_FLOPPY_PAGE
;
4332 Status
= InstallFatBootcodeToFloppy(&SourceRootPath
, &DestinationArcPath
);
4333 if (!NT_SUCCESS(Status
))
4335 /* Print error message */
4336 return BOOT_LOADER_FLOPPY_PAGE
;
4339 return SUCCESS_PAGE
;
4343 return BOOT_LOADER_FLOPPY_PAGE
;
4348 * Displays the BootLoaderHarddiskVbrPage.
4351 * SuccessPage (At once)
4355 * Calls InstallVBRToPartition()
4358 * Number of the next page.
4361 BootLoaderHarddiskVbrPage(PINPUT_RECORD Ir
)
4363 UCHAR PartitionType
;
4366 PartitionType
= PartitionList
->SystemPartition
->PartitionType
;
4368 Status
= InstallVBRToPartition(&SystemRootPath
,
4370 &DestinationArcPath
,
4372 if (!NT_SUCCESS(Status
))
4374 MUIDisplayError(ERROR_WRITE_BOOT
, Ir
, POPUP_WAIT_ENTER
);
4378 return SUCCESS_PAGE
;
4383 * Displays the BootLoaderHarddiskMbrPage.
4386 * SuccessPage (At once)
4390 * Calls InstallVBRToPartition()
4391 * CallsInstallMbrBootCodeToDisk()
4394 * Number of the next page.
4397 BootLoaderHarddiskMbrPage(PINPUT_RECORD Ir
)
4399 UCHAR PartitionType
;
4401 WCHAR DestinationDevicePathBuffer
[MAX_PATH
];
4402 WCHAR SourceMbrPathBuffer
[MAX_PATH
];
4403 WCHAR DstPath
[MAX_PATH
];
4405 /* Step 1: Write the VBR */
4406 PartitionType
= PartitionList
->SystemPartition
->PartitionType
;
4408 Status
= InstallVBRToPartition(&SystemRootPath
,
4410 &DestinationArcPath
,
4412 if (!NT_SUCCESS(Status
))
4414 MUIDisplayError(ERROR_WRITE_BOOT
, Ir
, POPUP_WAIT_ENTER
);
4418 /* Step 2: Write the MBR */
4419 swprintf(DestinationDevicePathBuffer
,
4420 L
"\\Device\\Harddisk%d\\Partition0",
4421 PartitionList
->SystemDisk
->DiskNumber
);
4423 wcscpy(SourceMbrPathBuffer
, SourceRootPath
.Buffer
);
4424 wcscat(SourceMbrPathBuffer
, L
"\\loader\\dosmbr.bin");
4426 DPRINT1("Install MBR bootcode: %S ==> %S\n",
4427 SourceMbrPathBuffer
, DestinationDevicePathBuffer
);
4429 if (IsThereAValidBootSector(DestinationDevicePathBuffer
))
4431 /* Save current MBR */
4432 wcscpy(DstPath
, SystemRootPath
.Buffer
);
4433 wcscat(DstPath
, L
"\\mbr.old");
4435 DPRINT1("Save MBR: %S ==> %S\n", DestinationDevicePathBuffer
, DstPath
);
4436 Status
= SaveBootSector(DestinationDevicePathBuffer
, DstPath
, sizeof(PARTITION_SECTOR
));
4437 if (!NT_SUCCESS(Status
))
4439 DPRINT1("SaveBootSector() failed (Status %lx)\n", Status
);
4440 // Don't care if we succeeded or not saving the old MBR, just go ahead.
4444 Status
= InstallMbrBootCodeToDisk(SourceMbrPathBuffer
,
4445 DestinationDevicePathBuffer
);
4446 if (!NT_SUCCESS(Status
))
4448 DPRINT1("InstallMbrBootCodeToDisk() failed (Status %lx)\n",
4450 MUIDisplayError(ERROR_INSTALL_BOOTCODE
, Ir
, POPUP_WAIT_ENTER
);
4454 return SUCCESS_PAGE
;
4459 * Displays the QuitPage.
4462 * FlushPage (At once)
4468 * Number of the next page.
4471 QuitPage(PINPUT_RECORD Ir
)
4473 MUIDisplayPage(QUIT_PAGE
);
4475 /* Destroy partition list */
4476 if (PartitionList
!= NULL
)
4478 DestroyPartitionList(PartitionList
);
4479 PartitionList
= NULL
;
4482 /* Destroy filesystem list */
4483 if (FileSystemList
!= NULL
)
4485 DestroyFileSystemList(FileSystemList
);
4486 FileSystemList
= NULL
;
4489 /* Destroy computer settings list */
4490 if (ComputerList
!= NULL
)
4492 DestroyGenericList(ComputerList
, TRUE
);
4493 ComputerList
= NULL
;
4496 /* Destroy display settings list */
4497 if (DisplayList
!= NULL
)
4499 DestroyGenericList(DisplayList
, TRUE
);
4503 /* Destroy keyboard settings list */
4504 if (KeyboardList
!= NULL
)
4506 DestroyGenericList(KeyboardList
, TRUE
);
4507 KeyboardList
= NULL
;
4510 /* Destroy keyboard layout list */
4511 if (LayoutList
!= NULL
)
4513 DestroyGenericList(LayoutList
, TRUE
);
4517 if (LanguageList
!= NULL
)
4519 DestroyGenericList(LanguageList
, FALSE
);
4520 LanguageList
= NULL
;
4523 CONSOLE_SetStatusText(MUIGetString(STRING_REBOOTCOMPUTER2
));
4527 CONSOLE_ConInKey(Ir
);
4529 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
4538 * Displays the SuccessPage.
4541 * FlushPage (At once)
4547 * Number of the next page.
4550 SuccessPage(PINPUT_RECORD Ir
)
4552 MUIDisplayPage(SUCCESS_PAGE
);
4554 if (IsUnattendedSetup
)
4561 CONSOLE_ConInKey(Ir
);
4563 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
4572 * Displays the FlushPage.
4575 * RebootPage (At once)
4578 * Number of the next page.
4581 FlushPage(PINPUT_RECORD Ir
)
4583 MUIDisplayPage(FLUSH_PAGE
);
4589 PnpEventThread(IN LPVOID lpParameter
);
4593 * The start routine and page management
4604 NtQuerySystemTime(&Time
);
4606 Status
= RtlCreateUserThread(NtCurrentProcess(),
4616 if (!NT_SUCCESS(Status
))
4617 hPnpThread
= INVALID_HANDLE_VALUE
;
4619 if (!CONSOLE_Init())
4621 PrintString(MUIGetString(STRING_CONSOLEFAIL1
));
4622 PrintString(MUIGetString(STRING_CONSOLEFAIL2
));
4623 PrintString(MUIGetString(STRING_CONSOLEFAIL3
));
4625 /* Raise a hard error (crash the system/BSOD) */
4626 NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED
,
4630 /* Initialize global unicode strings */
4631 RtlInitUnicodeString(&SourcePath
, NULL
);
4632 RtlInitUnicodeString(&SourceRootPath
, NULL
);
4633 RtlInitUnicodeString(&SourceRootDir
, NULL
);
4634 RtlInitUnicodeString(&InstallPath
, NULL
);
4635 RtlInitUnicodeString(&DestinationPath
, NULL
);
4636 RtlInitUnicodeString(&DestinationArcPath
, NULL
);
4637 RtlInitUnicodeString(&DestinationRootPath
, NULL
);
4638 RtlInitUnicodeString(&SystemRootPath
, NULL
);
4640 /* Hide the cursor */
4641 CONSOLE_SetCursorType(TRUE
, FALSE
);
4644 while (Page
!= REBOOT_PAGE
&& Page
!= RECOVERY_PAGE
)
4646 CONSOLE_ClearScreen();
4649 //CONSOLE_SetUnderlinedTextXY(4, 3, " ReactOS " KERNEL_VERSION_STR " Setup ");
4656 Page
= SetupStartPage(&Ir
);
4661 Page
= LanguagePage(&Ir
);
4666 Page
= LicensePage(&Ir
);
4671 Page
= IntroPage(&Ir
);
4675 case INSTALL_INTRO_PAGE
:
4676 Page
= InstallIntroPage(&Ir
);
4680 case SCSI_CONTROLLER_PAGE
:
4681 Page
= ScsiControllerPage(&Ir
);
4686 case OEM_DRIVER_PAGE
:
4687 Page
= OemDriverPage(&Ir
);
4691 case DEVICE_SETTINGS_PAGE
:
4692 Page
= DeviceSettingsPage(&Ir
);
4695 case COMPUTER_SETTINGS_PAGE
:
4696 Page
= ComputerSettingsPage(&Ir
);
4699 case DISPLAY_SETTINGS_PAGE
:
4700 Page
= DisplaySettingsPage(&Ir
);
4703 case KEYBOARD_SETTINGS_PAGE
:
4704 Page
= KeyboardSettingsPage(&Ir
);
4707 case LAYOUT_SETTINGS_PAGE
:
4708 Page
= LayoutSettingsPage(&Ir
);
4711 case SELECT_PARTITION_PAGE
:
4712 Page
= SelectPartitionPage(&Ir
);
4715 case CREATE_PRIMARY_PARTITION_PAGE
:
4716 Page
= CreatePrimaryPartitionPage(&Ir
);
4719 case CREATE_EXTENDED_PARTITION_PAGE
:
4720 Page
= CreateExtendedPartitionPage(&Ir
);
4723 case CREATE_LOGICAL_PARTITION_PAGE
:
4724 Page
= CreateLogicalPartitionPage(&Ir
);
4727 case CONFIRM_DELETE_SYSTEM_PARTITION_PAGE
:
4728 Page
= ConfirmDeleteSystemPartitionPage(&Ir
);
4731 case DELETE_PARTITION_PAGE
:
4732 Page
= DeletePartitionPage(&Ir
);
4735 case SELECT_FILE_SYSTEM_PAGE
:
4736 Page
= SelectFileSystemPage(&Ir
);
4739 case FORMAT_PARTITION_PAGE
:
4740 Page
= (PAGE_NUMBER
) FormatPartitionPage(&Ir
);
4743 case CHECK_FILE_SYSTEM_PAGE
:
4744 Page
= (PAGE_NUMBER
) CheckFileSystemPage(&Ir
);
4747 case INSTALL_DIRECTORY_PAGE
:
4748 Page
= InstallDirectoryPage(&Ir
);
4751 case PREPARE_COPY_PAGE
:
4752 Page
= PrepareCopyPage(&Ir
);
4755 case FILE_COPY_PAGE
:
4756 Page
= FileCopyPage(&Ir
);
4760 Page
= RegistryPage(&Ir
);
4763 case BOOT_LOADER_PAGE
:
4764 Page
= BootLoaderPage(&Ir
);
4767 case BOOT_LOADER_FLOPPY_PAGE
:
4768 Page
= BootLoaderFloppyPage(&Ir
);
4771 case BOOT_LOADER_HARDDISK_MBR_PAGE
:
4772 Page
= BootLoaderHarddiskMbrPage(&Ir
);
4775 case BOOT_LOADER_HARDDISK_VBR_PAGE
:
4776 Page
= BootLoaderHarddiskVbrPage(&Ir
);
4780 case REPAIR_INTRO_PAGE
:
4781 Page
= RepairIntroPage(&Ir
);
4785 Page
= SuccessPage(&Ir
);
4789 Page
= FlushPage(&Ir
);
4793 Page
= QuitPage(&Ir
);
4802 if (Page
== RECOVERY_PAGE
)
4807 /* Avoid bugcheck */
4808 Time
.QuadPart
+= 50000000;
4809 NtDelayExecution(FALSE
, &Time
);
4812 RtlAdjustPrivilege(SE_SHUTDOWN_PRIVILEGE
, TRUE
, FALSE
, &Old
);
4813 NtShutdownSystem(ShutdownReboot
);
4814 RtlAdjustPrivilege(SE_SHUTDOWN_PRIVILEGE
, Old
, FALSE
, &Old
);
4815 NtTerminateProcess(NtCurrentProcess(), 0);
4822 NtProcessStartup(PPEB Peb
)
4824 RtlNormalizeProcessParams(Peb
->ProcessParameters
);
4826 ProcessHeap
= Peb
->ProcessHeap
;
4827 InfSetHeap(ProcessHeap
);
4830 #endif /* __REACTOS__ */