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
;
69 /* Path to the install directory */
70 static UNICODE_STRING DestinationPath
;
71 static UNICODE_STRING DestinationArcPath
;
72 static UNICODE_STRING DestinationRootPath
;
74 static WCHAR DestinationDriveLetter
;
76 /* Path to the active partition (boot manager) */
77 static UNICODE_STRING SystemRootPath
;
81 static HSPFILEQ SetupFileQueue
= NULL
;
83 static PGENERIC_LIST ComputerList
= NULL
;
84 static PGENERIC_LIST DisplayList
= NULL
;
85 static PGENERIC_LIST KeyboardList
= NULL
;
86 static PGENERIC_LIST LayoutList
= NULL
;
87 static PGENERIC_LIST LanguageList
= NULL
;
89 static LANGID LanguageId
= 0;
91 static ULONG RequiredPartitionDiskSpace
= ~0;
93 /* FUNCTIONS ****************************************************************/
96 PrintString(char* fmt
,...)
100 UNICODE_STRING UnicodeString
;
101 ANSI_STRING AnsiString
;
104 vsprintf(buffer
, fmt
, ap
);
107 RtlInitAnsiString(&AnsiString
, buffer
);
108 RtlAnsiStringToUnicodeString(&UnicodeString
, &AnsiString
, TRUE
);
109 NtDisplayString(&UnicodeString
);
110 RtlFreeUnicodeString(&UnicodeString
);
115 DrawBox(IN SHORT xLeft
,
123 /* draw upper left corner */
126 FillConsoleOutputCharacterA(StdOutput
,
132 /* draw upper edge */
135 FillConsoleOutputCharacterA(StdOutput
,
141 /* draw upper right corner */
142 coPos
.X
= xLeft
+ Width
- 1;
144 FillConsoleOutputCharacterA(StdOutput
,
150 /* Draw right edge, inner space and left edge */
151 for (coPos
.Y
= yTop
+ 1; coPos
.Y
< yTop
+ Height
- 1; coPos
.Y
++)
154 FillConsoleOutputCharacterA(StdOutput
,
161 FillConsoleOutputCharacterA(StdOutput
,
167 coPos
.X
= xLeft
+ Width
- 1;
168 FillConsoleOutputCharacterA(StdOutput
,
175 /* draw lower left corner */
177 coPos
.Y
= yTop
+ Height
- 1;
178 FillConsoleOutputCharacterA(StdOutput
,
184 /* draw lower edge */
186 coPos
.Y
= yTop
+ Height
- 1;
187 FillConsoleOutputCharacterA(StdOutput
,
193 /* draw lower right corner */
194 coPos
.X
= xLeft
+ Width
- 1;
195 coPos
.Y
= yTop
+ Height
- 1;
196 FillConsoleOutputCharacterA(StdOutput
,
205 PopupError(PCCH Text
,
223 /* Count text lines and longest line */
230 p
= strchr(pnext
, '\n');
234 Length
= strlen(pnext
);
239 Length
= (ULONG
)(p
- pnext
);
245 if (Length
> MaxLength
)
248 if (LastLine
== TRUE
)
254 /* Check length of status line */
257 Length
= strlen(Status
);
259 if (Length
> MaxLength
)
263 Width
= MaxLength
+ 4;
269 yTop
= (yScreen
- Height
) / 2;
270 xLeft
= (xScreen
- Width
) / 2;
273 /* Set screen attributes */
275 for (coPos
.Y
= yTop
; coPos
.Y
< yTop
+ Height
; coPos
.Y
++)
277 FillConsoleOutputAttribute(StdOutput
,
278 FOREGROUND_RED
| BACKGROUND_WHITE
,
284 DrawBox(xLeft
, yTop
, Width
, Height
);
286 /* Print message text */
291 p
= strchr(pnext
, '\n');
295 Length
= strlen(pnext
);
300 Length
= (ULONG
)(p
- pnext
);
307 WriteConsoleOutputCharacterA(StdOutput
,
314 if (LastLine
== TRUE
)
321 /* Print separator line and status text */
324 coPos
.Y
= yTop
+ Height
- 3;
326 FillConsoleOutputCharacterA(StdOutput
,
333 FillConsoleOutputCharacterA(StdOutput
,
339 coPos
.X
= xLeft
+ Width
- 1;
340 FillConsoleOutputCharacterA(StdOutput
,
348 WriteConsoleOutputCharacterA(StdOutput
,
350 min(strlen(Status
), (SIZE_T
)Width
- 4),
355 if (WaitEvent
== POPUP_WAIT_NONE
)
360 CONSOLE_ConInKey(Ir
);
362 if (WaitEvent
== POPUP_WAIT_ANY_KEY
||
363 Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D)
375 * FALSE: Don't quit setup.
378 ConfirmQuit(PINPUT_RECORD Ir
)
381 MUIDisplayError(ERROR_NOT_INSTALLED
, NULL
, POPUP_WAIT_NONE
);
385 CONSOLE_ConInKey(Ir
);
387 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
388 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
393 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
405 CheckUnattendedSetup(VOID
)
407 WCHAR UnattendInfPath
[MAX_PATH
];
414 if (DoesFileExist(SourcePath
.Buffer
, L
"unattend.inf") == FALSE
)
416 DPRINT("Does not exist: %S\\%S\n", SourcePath
.Buffer
, L
"unattend.inf");
420 wcscpy(UnattendInfPath
, SourcePath
.Buffer
);
421 wcscat(UnattendInfPath
, L
"\\unattend.inf");
423 /* Load 'unattend.inf' from install media. */
424 UnattendInf
= SetupOpenInfFileW(UnattendInfPath
,
430 if (UnattendInf
== INVALID_HANDLE_VALUE
)
432 DPRINT("SetupOpenInfFileW() failed\n");
436 /* Open 'Unattend' section */
437 if (!SetupFindFirstLineW(UnattendInf
, L
"Unattend", L
"Signature", &Context
))
439 DPRINT("SetupFindFirstLineW() failed for section 'Unattend'\n");
440 SetupCloseInfFile(UnattendInf
);
444 /* Get pointer 'Signature' key */
445 if (!INF_GetData(&Context
, NULL
, &Value
))
447 DPRINT("INF_GetData() failed for key 'Signature'\n");
448 SetupCloseInfFile(UnattendInf
);
452 /* Check 'Signature' string */
453 if (_wcsicmp(Value
, L
"$ReactOS$") != 0)
455 DPRINT("Signature not $ReactOS$\n");
456 SetupCloseInfFile(UnattendInf
);
460 /* Check if Unattend setup is enabled */
461 if (!SetupFindFirstLineW(UnattendInf
, L
"Unattend", L
"UnattendSetupEnabled", &Context
))
463 DPRINT("Can't find key 'UnattendSetupEnabled'\n");
464 SetupCloseInfFile(UnattendInf
);
468 if (!INF_GetData(&Context
, NULL
, &Value
))
470 DPRINT("Can't read key 'UnattendSetupEnabled'\n");
471 SetupCloseInfFile(UnattendInf
);
475 if (_wcsicmp(Value
, L
"yes") != 0)
477 DPRINT("Unattend setup is disabled by 'UnattendSetupEnabled' key!\n");
478 SetupCloseInfFile(UnattendInf
);
482 /* Search for 'DestinationDiskNumber' in the 'Unattend' section */
483 if (!SetupFindFirstLineW(UnattendInf
, L
"Unattend", L
"DestinationDiskNumber", &Context
))
485 DPRINT("SetupFindFirstLine() failed for key 'DestinationDiskNumber'\n");
486 SetupCloseInfFile(UnattendInf
);
490 if (!SetupGetIntField(&Context
, 1, &IntValue
))
492 DPRINT("SetupGetIntField() failed for key 'DestinationDiskNumber'\n");
493 SetupCloseInfFile(UnattendInf
);
497 UnattendDestinationDiskNumber
= (LONG
)IntValue
;
499 /* Search for 'DestinationPartitionNumber' in the 'Unattend' section */
500 if (!SetupFindFirstLineW(UnattendInf
, L
"Unattend", L
"DestinationPartitionNumber", &Context
))
502 DPRINT("SetupFindFirstLine() failed for key 'DestinationPartitionNumber'\n");
503 SetupCloseInfFile(UnattendInf
);
507 if (!SetupGetIntField(&Context
, 1, &IntValue
))
509 DPRINT("SetupGetIntField() failed for key 'DestinationPartitionNumber'\n");
510 SetupCloseInfFile(UnattendInf
);
514 UnattendDestinationPartitionNumber
= IntValue
;
516 /* Search for 'InstallationDirectory' in the 'Unattend' section */
517 if (!SetupFindFirstLineW(UnattendInf
, L
"Unattend", L
"InstallationDirectory", &Context
))
519 DPRINT("SetupFindFirstLine() failed for key 'InstallationDirectory'\n");
520 SetupCloseInfFile(UnattendInf
);
524 /* Get pointer 'InstallationDirectory' key */
525 if (!INF_GetData(&Context
, NULL
, &Value
))
527 DPRINT("INF_GetData() failed for key 'InstallationDirectory'\n");
528 SetupCloseInfFile(UnattendInf
);
532 wcscpy(UnattendInstallationDirectory
, Value
);
534 IsUnattendedSetup
= TRUE
;
536 /* Search for 'MBRInstallType' in the 'Unattend' section */
537 if (SetupFindFirstLineW(UnattendInf
, L
"Unattend", L
"MBRInstallType", &Context
))
539 if (SetupGetIntField(&Context
, 1, &IntValue
))
541 UnattendMBRInstallType
= IntValue
;
545 /* Search for 'FormatPartition' in the 'Unattend' section */
546 if (SetupFindFirstLineW(UnattendInf
, L
"Unattend", L
"FormatPartition", &Context
))
548 if (SetupGetIntField(&Context
, 1, &IntValue
))
550 UnattendFormatPartition
= IntValue
;
554 if (SetupFindFirstLineW(UnattendInf
, L
"Unattend", L
"AutoPartition", &Context
))
556 if (SetupGetIntField(&Context
, 1, &IntValue
))
558 AutoPartition
= IntValue
;
562 /* search for LocaleID in the 'Unattend' section*/
563 if (SetupFindFirstLineW (UnattendInf
, L
"Unattend", L
"LocaleID", &Context
))
565 if (INF_GetData (&Context
, NULL
, &Value
))
567 LONG Id
= wcstol(Value
, NULL
, 16);
568 swprintf(LocaleID
,L
"%08lx", Id
);
572 SetupCloseInfFile(UnattendInf
);
574 DPRINT("Running unattended setup\n");
581 PGENERIC_LIST_ENTRY ListEntry
;
582 LPCWSTR pszNewLayout
;
584 pszNewLayout
= MUIDefaultKeyboardLayout();
586 if (LayoutList
== NULL
)
588 LayoutList
= CreateKeyboardLayoutList(SetupInf
, DefaultKBLayout
);
589 if (LayoutList
== NULL
)
591 /* FIXME: Handle error! */
596 ListEntry
= GetFirstListEntry(LayoutList
);
598 /* Search for default layout (if provided) */
599 if (pszNewLayout
!= NULL
)
601 while (ListEntry
!= NULL
)
603 if (!wcscmp(pszNewLayout
, GetListEntryUserData(ListEntry
)))
605 SetCurrentListEntry(LayoutList
, ListEntry
);
609 ListEntry
= GetNextListEntry(ListEntry
);
616 * Displays the LanguagePage.
618 * Next pages: IntroPage, QuitPage
621 * Number of the next page.
624 LanguagePage(PINPUT_RECORD Ir
)
626 PWCHAR NewLanguageId
;
627 BOOL RefreshPage
= FALSE
;
629 /* Initialize the computer settings list */
630 if (LanguageList
== NULL
)
632 LanguageList
= CreateLanguageList(SetupInf
, DefaultLanguage
);
634 if (LanguageList
== NULL
)
636 PopupError("Setup failed to initialize available translations", NULL
, NULL
, POPUP_WAIT_NONE
);
642 SelectedLanguageId
= DefaultLanguage
;
643 SetConsoleCodePage();
646 /* If there's just a single language in the list skip
647 * the language selection process altogether! */
648 if (GenericListHasSingleEntry(LanguageList
))
651 DrawGenericList(LanguageList
,
657 ScrollToPositionGenericList (LanguageList
, GetDefaultLanguageIndex());
659 MUIDisplayPage(LANGUAGE_PAGE
);
663 CONSOLE_ConInKey(Ir
);
665 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
666 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
)) /* DOWN */
668 ScrollDownGenericList (LanguageList
);
671 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
672 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_UP
)) /* UP */
674 ScrollUpGenericList(LanguageList
);
677 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
678 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_NEXT
)) /* PAGE DOWN */
680 ScrollPageDownGenericList(LanguageList
);
683 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
684 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_PRIOR
)) /* PAGE UP */
686 ScrollPageUpGenericList(LanguageList
);
689 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
690 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
692 if (ConfirmQuit(Ir
) == TRUE
)
695 RedrawGenericList(LanguageList
);
697 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
699 SelectedLanguageId
= (PWCHAR
)GetListEntryUserData(GetCurrentListEntry(LanguageList
));
701 LanguageId
= (LANGID
)(wcstol(SelectedLanguageId
, NULL
, 16) & 0xFFFF);
703 if (wcscmp(SelectedLanguageId
, DefaultLanguage
))
709 SetConsoleCodePage();
713 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
> 0x60) && (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
< 0x7b))
716 GenericListKeyPress(LanguageList
, Ir
->Event
.KeyEvent
.uChar
.AsciiChar
);
722 NewLanguageId
= (PWCHAR
)GetListEntryUserData(GetCurrentListEntry(LanguageList
));
724 if (SelectedLanguageId
!= NewLanguageId
)
726 /* Clear the language page */
727 MUIClearPage(LANGUAGE_PAGE
);
729 SelectedLanguageId
= NewLanguageId
;
732 SetConsoleCodePage();
734 /* Redraw language selection page in native language */
735 MUIDisplayPage(LANGUAGE_PAGE
);
750 * LanguagePage (at once, default)
751 * InstallIntroPage (at once, if unattended)
757 * Init SourceRootPath
760 * Init RequiredPartitionDiskSpace
761 * Init IsUnattendedSetup
762 * If unattended, init *List and sets the Codepage
765 * Number of the next page.
768 SetupStartPage(PINPUT_RECORD Ir
)
770 //SYSTEM_DEVICE_INFORMATION Sdi;
772 WCHAR FileNameBuffer
[MAX_PATH
];
777 PGENERIC_LIST_ENTRY ListEntry
;
780 CONSOLE_SetStatusText(MUIGetString(STRING_PLEASEWAIT
));
783 /* Check whether a harddisk is available */
784 Status
= NtQuerySystemInformation(SystemDeviceInformation
,
786 sizeof(SYSTEM_DEVICE_INFORMATION
),
789 if (!NT_SUCCESS(Status
))
791 CONSOLE_PrintTextXY(6, 15, "NtQuerySystemInformation() failed (Status 0x%08lx)", Status
);
792 MUIDisplayError(ERROR_DRIVE_INFORMATION
, Ir
, POPUP_WAIT_ENTER
);
796 if (Sdi
.NumberOfDisks
== 0)
798 MUIDisplayError(ERROR_NO_HDD
, Ir
, POPUP_WAIT_ENTER
);
803 /* Get the source path and source root path */
804 Status
= GetSourcePaths(&SourcePath
,
808 if (!NT_SUCCESS(Status
))
810 CONSOLE_PrintTextXY(6, 15, "GetSourcePaths() failed (Status 0x%08lx)", Status
);
811 MUIDisplayError(ERROR_NO_SOURCE_DRIVE
, Ir
, POPUP_WAIT_ENTER
);
817 CONSOLE_PrintTextXY(6, 15, "SourcePath: '%wZ'", &SourcePath
);
818 CONSOLE_PrintTextXY(6, 16, "SourceRootPath: '%wZ'", &SourceRootPath
);
819 CONSOLE_PrintTextXY(6, 17, "SourceRootDir: '%wZ'", &SourceRootDir
);
823 /* Load txtsetup.sif from install media. */
824 wcscpy(FileNameBuffer
, SourcePath
.Buffer
);
825 wcscat(FileNameBuffer
, L
"\\txtsetup.sif");
827 SetupInf
= SetupOpenInfFileW(FileNameBuffer
,
833 if (SetupInf
== INVALID_HANDLE_VALUE
)
835 MUIDisplayError(ERROR_LOAD_TXTSETUPSIF
, Ir
, POPUP_WAIT_ENTER
);
839 /* Open 'Version' section */
840 if (!SetupFindFirstLineW(SetupInf
, L
"Version", L
"Signature", &Context
))
842 MUIDisplayError(ERROR_CORRUPT_TXTSETUPSIF
, Ir
, POPUP_WAIT_ENTER
);
846 /* Get pointer 'Signature' key */
847 if (!INF_GetData(&Context
, NULL
, &Value
))
849 MUIDisplayError(ERROR_CORRUPT_TXTSETUPSIF
, Ir
, POPUP_WAIT_ENTER
);
853 /* Check 'Signature' string */
854 if (_wcsicmp(Value
, L
"$ReactOS$") != 0)
856 MUIDisplayError(ERROR_SIGNATURE_TXTSETUPSIF
, Ir
, POPUP_WAIT_ENTER
);
860 /* Open 'DiskSpaceRequirements' section */
861 if (!SetupFindFirstLineW(SetupInf
, L
"DiskSpaceRequirements", L
"FreeSysPartDiskSpace", &Context
))
863 MUIDisplayError(ERROR_CORRUPT_TXTSETUPSIF
, Ir
, POPUP_WAIT_ENTER
);
867 /* Get the 'FreeSysPartDiskSpace' value */
868 if (!SetupGetIntField(&Context
, 1, &IntValue
))
870 MUIDisplayError(ERROR_CORRUPT_TXTSETUPSIF
, Ir
, POPUP_WAIT_ENTER
);
874 RequiredPartitionDiskSpace
= (ULONG
)IntValue
;
876 /* Start PnP thread */
877 if (hPnpThread
!= INVALID_HANDLE_VALUE
)
879 NtResumeThread(hPnpThread
, NULL
);
880 hPnpThread
= INVALID_HANDLE_VALUE
;
883 CheckUnattendedSetup();
885 if (IsUnattendedSetup
)
888 //read options from inf
889 ComputerList
= CreateComputerTypeList(SetupInf
);
890 DisplayList
= CreateDisplayDriverList(SetupInf
);
891 KeyboardList
= CreateKeyboardDriverList(SetupInf
);
892 LayoutList
= CreateKeyboardLayoutList(SetupInf
, DefaultKBLayout
);
893 LanguageList
= CreateLanguageList(SetupInf
, DefaultLanguage
);
896 wcscpy(SelectedLanguageId
,LocaleID
);
898 /* first we hack LanguageList */
899 ListEntry
= GetFirstListEntry(LanguageList
);
901 while (ListEntry
!= NULL
)
903 if (!wcsicmp(LocaleID
, GetListEntryUserData(ListEntry
)))
905 DPRINT("found %S in LanguageList\n",GetListEntryUserData(ListEntry
));
906 SetCurrentListEntry(LanguageList
, ListEntry
);
910 ListEntry
= GetNextListEntry(ListEntry
);
914 ListEntry
= GetFirstListEntry(LayoutList
);
916 while (ListEntry
!= NULL
)
918 if (!wcsicmp(LocaleID
, GetListEntryUserData(ListEntry
)))
920 DPRINT("found %S in LayoutList\n",GetListEntryUserData(ListEntry
));
921 SetCurrentListEntry(LayoutList
, ListEntry
);
925 ListEntry
= GetNextListEntry(ListEntry
);
928 SetConsoleCodePage();
930 return INSTALL_INTRO_PAGE
;
933 return LANGUAGE_PAGE
;
938 * Displays the IntroPage.
941 * InstallIntroPage (default)
947 * Number of the next page.
950 IntroPage(PINPUT_RECORD Ir
)
952 MUIDisplayPage(START_PAGE
);
956 CONSOLE_ConInKey(Ir
);
958 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
959 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
961 if (ConfirmQuit(Ir
) == TRUE
)
966 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
968 return INSTALL_INTRO_PAGE
;
970 else if (toupper(Ir
->Event
.KeyEvent
.uChar
.AsciiChar
) == 'R') /* R */
972 return REPAIR_INTRO_PAGE
;
974 else if (toupper(Ir
->Event
.KeyEvent
.uChar
.AsciiChar
) == 'L') /* R */
985 * Displays the License page.
988 * IntroPage (default)
991 * Number of the next page.
994 LicensePage(PINPUT_RECORD Ir
)
996 MUIDisplayPage(LICENSE_PAGE
);
1000 CONSOLE_ConInKey(Ir
);
1002 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
1008 return LICENSE_PAGE
;
1013 * Displays the RepairIntroPage.
1016 * RebootPage (default)
1022 * Number of the next page.
1025 RepairIntroPage(PINPUT_RECORD Ir
)
1027 MUIDisplayPage(REPAIR_INTRO_PAGE
);
1031 CONSOLE_ConInKey(Ir
);
1033 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
1037 else if (toupper(Ir
->Event
.KeyEvent
.uChar
.AsciiChar
) == 'U') /* U */
1039 RepairUpdateFlag
= TRUE
;
1040 return INSTALL_INTRO_PAGE
;
1042 else if (toupper(Ir
->Event
.KeyEvent
.uChar
.AsciiChar
) == 'R') /* R */
1044 return RECOVERY_PAGE
;
1046 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1047 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
)) /* ESC */
1053 return REPAIR_INTRO_PAGE
;
1057 * Displays the InstallIntroPage.
1060 * DeviceSettingsPage (At once if repair or update is selected)
1061 * SelectPartitionPage (At once if unattended setup)
1062 * DeviceSettingsPage (default)
1066 * Number of the next page.
1069 InstallIntroPage(PINPUT_RECORD Ir
)
1071 MUIDisplayPage(INSTALL_INTRO_PAGE
);
1073 if (RepairUpdateFlag
)
1075 //return SELECT_PARTITION_PAGE;
1076 return DEVICE_SETTINGS_PAGE
;
1079 if (IsUnattendedSetup
)
1081 return SELECT_PARTITION_PAGE
;
1086 CONSOLE_ConInKey(Ir
);
1088 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1089 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1091 if (ConfirmQuit(Ir
) == TRUE
)
1096 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
1098 return DEVICE_SETTINGS_PAGE
;
1099 // return SCSI_CONTROLLER_PAGE;
1103 return INSTALL_INTRO_PAGE
;
1109 ScsiControllerPage(PINPUT_RECORD Ir
)
1111 SetTextXY(6, 8, "Setup detected the following mass storage devices:");
1113 /* FIXME: print loaded mass storage driver descriptions */
1115 SetTextXY(8, 10, "TEST device");
1119 SetStatusText(" ENTER = Continue F3 = Quit");
1125 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1126 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1128 if (ConfirmQuit(Ir
) == TRUE
)
1133 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
1135 return DEVICE_SETTINGS_PAGE
;
1139 return SCSI_CONTROLLER_PAGE
;
1145 * Displays the DeviceSettingsPage.
1148 * SelectPartitionPage (At once if repair or update is selected)
1149 * ComputerSettingsPage
1150 * DisplaySettingsPage
1151 * KeyboardSettingsPage
1152 * LayoutsettingsPage
1153 * SelectPartitionPage
1163 * Number of the next page.
1166 DeviceSettingsPage(PINPUT_RECORD Ir
)
1168 static ULONG Line
= 16;
1169 MUIDisplayPage(DEVICE_SETTINGS_PAGE
);
1171 /* Initialize the computer settings list */
1172 if (ComputerList
== NULL
)
1174 ComputerList
= CreateComputerTypeList(SetupInf
);
1175 if (ComputerList
== NULL
)
1177 MUIDisplayError(ERROR_LOAD_COMPUTER
, Ir
, POPUP_WAIT_ENTER
);
1182 /* Initialize the display settings list */
1183 if (DisplayList
== NULL
)
1185 DisplayList
= CreateDisplayDriverList(SetupInf
);
1186 if (DisplayList
== NULL
)
1188 MUIDisplayError(ERROR_LOAD_DISPLAY
, Ir
, POPUP_WAIT_ENTER
);
1193 /* Initialize the keyboard settings list */
1194 if (KeyboardList
== NULL
)
1196 KeyboardList
= CreateKeyboardDriverList(SetupInf
);
1197 if (KeyboardList
== NULL
)
1199 MUIDisplayError(ERROR_LOAD_KEYBOARD
, Ir
, POPUP_WAIT_ENTER
);
1204 /* Initialize the keyboard layout list */
1205 if (LayoutList
== NULL
)
1207 LayoutList
= CreateKeyboardLayoutList(SetupInf
, DefaultKBLayout
);
1208 if (LayoutList
== NULL
)
1210 /* FIXME: report error */
1211 MUIDisplayError(ERROR_LOAD_KBLAYOUT
, Ir
, POPUP_WAIT_ENTER
);
1216 MUIDisplayPage(DEVICE_SETTINGS_PAGE
);
1219 CONSOLE_SetTextXY(25, 11, GetListEntryText(GetCurrentListEntry((ComputerList
))));
1220 CONSOLE_SetTextXY(25, 12, GetListEntryText(GetCurrentListEntry((DisplayList
))));
1221 CONSOLE_SetTextXY(25, 13, GetListEntryText(GetCurrentListEntry((KeyboardList
))));
1222 CONSOLE_SetTextXY(25, 14, GetListEntryText(GetCurrentListEntry((LayoutList
))));
1224 CONSOLE_InvertTextXY(24, Line
, 48, 1);
1226 if (RepairUpdateFlag
)
1228 return SELECT_PARTITION_PAGE
;
1233 CONSOLE_ConInKey(Ir
);
1235 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1236 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
)) /* DOWN */
1238 CONSOLE_NormalTextXY(24, Line
, 48, 1);
1242 else if (Line
== 16)
1247 CONSOLE_InvertTextXY(24, Line
, 48, 1);
1249 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1250 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_UP
)) /* UP */
1252 CONSOLE_NormalTextXY(24, Line
, 48, 1);
1256 else if (Line
== 16)
1261 CONSOLE_InvertTextXY(24, Line
, 48, 1);
1263 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1264 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1266 if (ConfirmQuit(Ir
) == TRUE
)
1271 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
1274 return COMPUTER_SETTINGS_PAGE
;
1275 else if (Line
== 12)
1276 return DISPLAY_SETTINGS_PAGE
;
1277 else if (Line
== 13)
1278 return KEYBOARD_SETTINGS_PAGE
;
1279 else if (Line
== 14)
1280 return LAYOUT_SETTINGS_PAGE
;
1281 else if (Line
== 16)
1282 return SELECT_PARTITION_PAGE
;
1286 return DEVICE_SETTINGS_PAGE
;
1291 * Handles generic selection lists.
1294 * GenericList: The list to handle.
1295 * nextPage: The page it needs to jump to after this page.
1296 * Ir: The PINPUT_RECORD
1299 HandleGenericList(PGENERIC_LIST GenericList
,
1300 PAGE_NUMBER nextPage
,
1305 CONSOLE_ConInKey(Ir
);
1307 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1308 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
)) /* DOWN */
1310 ScrollDownGenericList(GenericList
);
1312 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1313 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_UP
)) /* UP */
1315 ScrollUpGenericList(GenericList
);
1317 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1318 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_NEXT
)) /* PAGE DOWN */
1320 ScrollPageDownGenericList(GenericList
);
1322 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1323 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_PRIOR
)) /* PAGE UP */
1325 ScrollPageUpGenericList(GenericList
);
1327 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1328 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1330 if (ConfirmQuit(Ir
) == TRUE
)
1335 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1336 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
)) /* ESC */
1338 RestoreGenericListState(GenericList
);
1341 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
1345 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
> 0x60) && (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
< 0x7b))
1348 GenericListKeyPress(GenericList
, Ir
->Event
.KeyEvent
.uChar
.AsciiChar
);
1355 * Displays the ComputerSettingsPage.
1358 * DeviceSettingsPage
1362 * Number of the next page.
1365 ComputerSettingsPage(PINPUT_RECORD Ir
)
1367 MUIDisplayPage(COMPUTER_SETTINGS_PAGE
);
1369 DrawGenericList(ComputerList
,
1375 SaveGenericListState(ComputerList
);
1377 return HandleGenericList(ComputerList
, DEVICE_SETTINGS_PAGE
, Ir
);
1382 * Displays the DisplaySettingsPage.
1385 * DeviceSettingsPage
1389 * Number of the next page.
1392 DisplaySettingsPage(PINPUT_RECORD Ir
)
1394 MUIDisplayPage(DISPLAY_SETTINGS_PAGE
);
1396 DrawGenericList(DisplayList
,
1402 SaveGenericListState(DisplayList
);
1404 return HandleGenericList(DisplayList
, DEVICE_SETTINGS_PAGE
, Ir
);
1409 * Displays the KeyboardSettingsPage.
1412 * DeviceSettingsPage
1416 * Number of the next page.
1419 KeyboardSettingsPage(PINPUT_RECORD Ir
)
1421 MUIDisplayPage(KEYBOARD_SETTINGS_PAGE
);
1423 DrawGenericList(KeyboardList
,
1429 SaveGenericListState(KeyboardList
);
1431 return HandleGenericList(KeyboardList
, DEVICE_SETTINGS_PAGE
, Ir
);
1436 * Displays the LayoutSettingsPage.
1439 * DeviceSettingsPage
1443 * Number of the next page.
1446 LayoutSettingsPage(PINPUT_RECORD Ir
)
1448 MUIDisplayPage(LAYOUT_SETTINGS_PAGE
);
1450 DrawGenericList(LayoutList
,
1456 SaveGenericListState(LayoutList
);
1458 return HandleGenericList(LayoutList
, DEVICE_SETTINGS_PAGE
, Ir
);
1463 IsDiskSizeValid(PPARTENTRY PartEntry
)
1467 size
= PartEntry
->SectorCount
.QuadPart
* PartEntry
->DiskEntry
->BytesPerSector
;
1468 size
= (size
+ 524288) / 1048576; /* in MBytes */
1470 if (size
< RequiredPartitionDiskSpace
)
1472 /* partition is too small so ask for another partion */
1473 DPRINT1("Partition is too small (size: %I64u MB), required disk space is %lu MB\n", size
, RequiredPartitionDiskSpace
);
1484 * Displays the SelectPartitionPage.
1487 * SelectFileSystemPage (At once if unattended)
1488 * SelectFileSystemPage (Default if free space is selected)
1489 * CreatePrimaryPartitionPage
1490 * CreateExtendedPartitionPage
1491 * CreateLogicalPartitionPage
1492 * ConfirmDeleteSystemPartitionPage (if the selected partition is the system partition, aka with the boot flag set)
1493 * DeletePartitionPage
1497 * Init DestinationDriveLetter (only if unattended or not free space is selected)
1498 * Set InstallShortcut (only if not unattended + free space is selected)
1501 * Number of the next page.
1504 SelectPartitionPage(PINPUT_RECORD Ir
)
1508 MUIDisplayPage(SELECT_PARTITION_PAGE
);
1510 if (PartitionList
== NULL
)
1512 PartitionList
= CreatePartitionList(2,
1516 if (PartitionList
== NULL
)
1518 /* FIXME: show an error dialog */
1521 else if (IsListEmpty (&PartitionList
->DiskListHead
))
1523 MUIDisplayError(ERROR_NO_HDD
, Ir
, POPUP_WAIT_ENTER
);
1528 DrawPartitionList(PartitionList
);
1530 if (IsUnattendedSetup
)
1532 if (!SelectPartition(PartitionList
, UnattendDestinationDiskNumber
, UnattendDestinationPartitionNumber
))
1536 if (PartitionList
->CurrentPartition
->LogicalPartition
)
1538 CreateLogicalPartition(PartitionList
,
1539 PartitionList
->CurrentPartition
->SectorCount
.QuadPart
,
1544 CreatePrimaryPartition(PartitionList
,
1545 PartitionList
->CurrentPartition
->SectorCount
.QuadPart
,
1549 if (!IsDiskSizeValid(PartitionList
->CurrentPartition
))
1551 MUIDisplayError(ERROR_INSUFFICIENT_PARTITION_SIZE
, Ir
, POPUP_WAIT_ANY_KEY
,
1552 RequiredPartitionDiskSpace
);
1553 return SELECT_PARTITION_PAGE
; /* let the user select another partition */
1556 DestinationDriveLetter
= (WCHAR
)PartitionList
->CurrentPartition
->DriveLetter
;
1558 return SELECT_FILE_SYSTEM_PAGE
;
1563 if (!IsDiskSizeValid(PartitionList
->CurrentPartition
))
1565 MUIDisplayError(ERROR_INSUFFICIENT_PARTITION_SIZE
, Ir
, POPUP_WAIT_ANY_KEY
,
1566 RequiredPartitionDiskSpace
);
1567 return SELECT_PARTITION_PAGE
; /* let the user select another partition */
1570 DestinationDriveLetter
= (WCHAR
)PartitionList
->CurrentPartition
->DriveLetter
;
1572 return SELECT_FILE_SYSTEM_PAGE
;
1578 /* Update status text */
1579 if (PartitionList
->CurrentPartition
== NULL
)
1581 CONSOLE_SetStatusText(MUIGetString(STRING_INSTALLCREATEPARTITION
));
1583 else if (PartitionList
->CurrentPartition
->LogicalPartition
)
1585 if (PartitionList
->CurrentPartition
->IsPartitioned
)
1587 CONSOLE_SetStatusText(MUIGetString(STRING_DELETEPARTITION
));
1591 CONSOLE_SetStatusText(MUIGetString(STRING_INSTALLCREATELOGICAL
));
1596 if (PartitionList
->CurrentPartition
->IsPartitioned
)
1598 if (IsContainerPartition(PartitionList
->CurrentPartition
->PartitionType
))
1600 CONSOLE_SetStatusText(MUIGetString(STRING_DELETEPARTITION
));
1604 CONSOLE_SetStatusText(MUIGetString(STRING_INSTALLDELETEPARTITION
));
1609 CONSOLE_SetStatusText(MUIGetString(STRING_INSTALLCREATEPARTITION
));
1613 CONSOLE_ConInKey(Ir
);
1615 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1616 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1618 if (ConfirmQuit(Ir
) == TRUE
)
1620 DestroyPartitionList(PartitionList
);
1621 PartitionList
= NULL
;
1627 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1628 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
)) /* DOWN */
1630 if (ScrollDownPartitionList(PartitionList
))
1631 DrawPartitionList(PartitionList
);
1633 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1634 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_UP
)) /* UP */
1636 if (ScrollUpPartitionList(PartitionList
))
1637 DrawPartitionList(PartitionList
);
1639 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_RETURN
) /* ENTER */
1641 if (IsContainerPartition(PartitionList
->CurrentPartition
->PartitionType
))
1642 continue; //return SELECT_PARTITION_PAGE;
1644 if (PartitionList
->CurrentPartition
== NULL
||
1645 PartitionList
->CurrentPartition
->IsPartitioned
== FALSE
)
1647 if (PartitionList
->CurrentPartition
->LogicalPartition
)
1649 CreateLogicalPartition(PartitionList
,
1655 CreatePrimaryPartition(PartitionList
,
1661 if (!IsDiskSizeValid(PartitionList
->CurrentPartition
))
1663 MUIDisplayError(ERROR_INSUFFICIENT_PARTITION_SIZE
, Ir
, POPUP_WAIT_ANY_KEY
,
1664 RequiredPartitionDiskSpace
);
1665 return SELECT_PARTITION_PAGE
; /* let the user select another partition */
1668 DestinationDriveLetter
= (WCHAR
)PartitionList
->CurrentPartition
->DriveLetter
;
1670 return SELECT_FILE_SYSTEM_PAGE
;
1672 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== 'P') /* P */
1674 if (PartitionList
->CurrentPartition
->LogicalPartition
== FALSE
)
1676 Error
= PrimaryPartitionCreationChecks(PartitionList
);
1677 if (Error
!= NOT_AN_ERROR
)
1679 MUIDisplayError(Error
, Ir
, POPUP_WAIT_ANY_KEY
);
1680 return SELECT_PARTITION_PAGE
;
1683 return CREATE_PRIMARY_PARTITION_PAGE
;
1686 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== 'E') /* E */
1688 if (PartitionList
->CurrentPartition
->LogicalPartition
== FALSE
)
1690 Error
= ExtendedPartitionCreationChecks(PartitionList
);
1691 if (Error
!= NOT_AN_ERROR
)
1693 MUIDisplayError(Error
, Ir
, POPUP_WAIT_ANY_KEY
);
1694 return SELECT_PARTITION_PAGE
;
1697 return CREATE_EXTENDED_PARTITION_PAGE
;
1700 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== 'L') /* L */
1702 if (PartitionList
->CurrentPartition
->LogicalPartition
== TRUE
)
1704 Error
= LogicalPartitionCreationChecks(PartitionList
);
1705 if (Error
!= NOT_AN_ERROR
)
1707 MUIDisplayError(Error
, Ir
, POPUP_WAIT_ANY_KEY
);
1708 return SELECT_PARTITION_PAGE
;
1711 return CREATE_LOGICAL_PARTITION_PAGE
;
1714 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== 'D') /* D */
1716 if (PartitionList
->CurrentPartition
->IsPartitioned
== FALSE
)
1718 MUIDisplayError(ERROR_DELETE_SPACE
, Ir
, POPUP_WAIT_ANY_KEY
);
1719 return SELECT_PARTITION_PAGE
;
1722 if (PartitionList
->CurrentPartition
->BootIndicator
)
1723 return CONFIRM_DELETE_SYSTEM_PARTITION_PAGE
;
1725 return DELETE_PARTITION_PAGE
;
1729 return SELECT_PARTITION_PAGE
;
1733 #define PARTITION_SIZE_INPUT_FIELD_LENGTH 6
1734 /* Restriction for MaxSize: pow(10, PARTITION_SIZE_INPUT_FIELD_LENGTH)-1 */
1735 #define PARTITION_MAXSIZE 999999
1738 ShowPartitionSizeInputBox(SHORT Left
,
1751 WCHAR PartitionSizeBuffer
[100];
1763 DrawBox(Left
, Top
, Right
- Left
+ 1, Bottom
- Top
+ 1);
1768 strcpy(Buffer
, MUIGetString(STRING_PARTITIONSIZE
));
1769 iLeft
= coPos
.X
+ strlen(Buffer
) + 1;
1772 WriteConsoleOutputCharacterA(StdOutput
,
1778 sprintf(Buffer
, MUIGetString(STRING_MAXSIZE
), MaxSize
);
1779 coPos
.X
= iLeft
+ PARTITION_SIZE_INPUT_FIELD_LENGTH
+ 1;
1781 WriteConsoleOutputCharacterA(StdOutput
,
1787 swprintf(PartitionSizeBuffer
, L
"%lu", MaxSize
);
1788 Index
= wcslen(PartitionSizeBuffer
);
1789 CONSOLE_SetInputTextXY(iLeft
,
1791 PARTITION_SIZE_INPUT_FIELD_LENGTH
,
1792 PartitionSizeBuffer
);
1796 CONSOLE_ConInKey(&Ir
);
1798 if ((Ir
.Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1799 (Ir
.Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1804 PartitionSizeBuffer
[0] = 0;
1807 else if (Ir
.Event
.KeyEvent
.wVirtualKeyCode
== VK_RETURN
) /* ENTER */
1811 else if (Ir
.Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
) /* ESCAPE */
1816 PartitionSizeBuffer
[0] = 0;
1819 else if ((Ir
.Event
.KeyEvent
.wVirtualKeyCode
== VK_BACK
) && /* BACKSPACE */
1823 PartitionSizeBuffer
[Index
] = 0;
1825 CONSOLE_SetInputTextXY(iLeft
,
1827 PARTITION_SIZE_INPUT_FIELD_LENGTH
,
1828 PartitionSizeBuffer
);
1830 else if ((Ir
.Event
.KeyEvent
.uChar
.AsciiChar
!= 0x00) &&
1831 (Index
< PARTITION_SIZE_INPUT_FIELD_LENGTH
))
1833 ch
= (WCHAR
)Ir
.Event
.KeyEvent
.uChar
.AsciiChar
;
1835 if ((ch
>= L
'0') && (ch
<= L
'9'))
1837 PartitionSizeBuffer
[Index
] = ch
;
1839 PartitionSizeBuffer
[Index
] = 0;
1841 CONSOLE_SetInputTextXY(iLeft
,
1843 PARTITION_SIZE_INPUT_FIELD_LENGTH
,
1844 PartitionSizeBuffer
);
1849 /* Convert UNICODE --> ANSI the poor man's way */
1850 sprintf(InputBuffer
, "%S", PartitionSizeBuffer
);
1855 * Displays the CreatePrimaryPartitionPage.
1858 * SelectPartitionPage
1859 * SelectFileSystemPage (default)
1863 * Number of the next page.
1866 CreatePrimaryPartitionPage(PINPUT_RECORD Ir
)
1868 PDISKENTRY DiskEntry
;
1869 PPARTENTRY PartEntry
;
1872 CHAR InputBuffer
[50];
1876 ULONGLONG SectorCount
;
1879 if (PartitionList
== NULL
||
1880 PartitionList
->CurrentDisk
== NULL
||
1881 PartitionList
->CurrentPartition
== NULL
)
1883 /* FIXME: show an error dialog */
1887 DiskEntry
= PartitionList
->CurrentDisk
;
1888 PartEntry
= PartitionList
->CurrentPartition
;
1890 CONSOLE_SetStatusText(MUIGetString(STRING_PLEASEWAIT
));
1892 CONSOLE_SetTextXY(6, 8, MUIGetString(STRING_CHOOSENEWPARTITION
));
1894 DiskSize
= DiskEntry
->SectorCount
.QuadPart
* DiskEntry
->BytesPerSector
;
1896 if (DiskSize
>= 10737418240) /* 10 GB */
1898 DiskSize
= DiskSize
/ 1073741824;
1899 Unit
= MUIGetString(STRING_GB
);
1904 DiskSize
= DiskSize
/ 1048576;
1908 Unit
= MUIGetString(STRING_MB
);
1911 if (DiskEntry
->DriverName
.Length
> 0)
1913 CONSOLE_PrintTextXY(6, 10,
1914 MUIGetString(STRING_HDINFOPARTCREATE
),
1917 DiskEntry
->DiskNumber
,
1921 &DiskEntry
->DriverName
);
1925 CONSOLE_PrintTextXY(6, 10,
1926 MUIGetString(STRING_HDDINFOUNK1
),
1929 DiskEntry
->DiskNumber
,
1935 CONSOLE_SetTextXY(6, 12, MUIGetString(STRING_HDDSIZE
));
1938 CONSOLE_PrintTextXY(8, 10, "Maximum size of the new partition is %I64u MB",
1939 PartitionList
->CurrentPartition
->SectorCount
* DiskEntry
->BytesPerSector
/ 1048576);
1942 CONSOLE_SetStatusText(MUIGetString(STRING_CREATEPARTITION
));
1944 PartEntry
= PartitionList
->CurrentPartition
;
1947 MaxSize
= (PartEntry
->SectorCount
.QuadPart
* DiskEntry
->BytesPerSector
) / 1048576; /* in MBytes (rounded) */
1949 if (MaxSize
> PARTITION_MAXSIZE
)
1950 MaxSize
= PARTITION_MAXSIZE
;
1952 ShowPartitionSizeInputBox(12, 14, xScreen
- 12, 17, /* left, top, right, bottom */
1953 MaxSize
, InputBuffer
, &Quit
, &Cancel
);
1957 if (ConfirmQuit (Ir
) == TRUE
)
1962 else if (Cancel
== TRUE
)
1964 return SELECT_PARTITION_PAGE
;
1968 PartSize
= atoi(InputBuffer
);
1976 if (PartSize
> MaxSize
)
1982 /* Convert to bytes */
1983 if (PartSize
== MaxSize
)
1985 /* Use all of the unpartitioned disk space */
1986 SectorCount
= PartEntry
->SectorCount
.QuadPart
;
1990 /* Calculate the sector count from the size in MB */
1991 SectorCount
= PartSize
* 1048576 / DiskEntry
->BytesPerSector
;
1993 /* But never get larger than the unpartitioned disk space */
1994 if (SectorCount
> PartEntry
->SectorCount
.QuadPart
)
1995 SectorCount
= PartEntry
->SectorCount
.QuadPart
;
1998 DPRINT ("Partition size: %I64u bytes\n", PartSize
);
2000 CreatePrimaryPartition(PartitionList
,
2004 return SELECT_PARTITION_PAGE
;
2008 return CREATE_PRIMARY_PARTITION_PAGE
;
2013 * Displays the CreateExtendedPartitionPage.
2016 * SelectPartitionPage (default)
2020 * Number of the next page.
2023 CreateExtendedPartitionPage(PINPUT_RECORD Ir
)
2025 PDISKENTRY DiskEntry
;
2026 PPARTENTRY PartEntry
;
2029 CHAR InputBuffer
[50];
2033 ULONGLONG SectorCount
;
2036 if (PartitionList
== NULL
||
2037 PartitionList
->CurrentDisk
== NULL
||
2038 PartitionList
->CurrentPartition
== NULL
)
2040 /* FIXME: show an error dialog */
2044 DiskEntry
= PartitionList
->CurrentDisk
;
2045 PartEntry
= PartitionList
->CurrentPartition
;
2047 CONSOLE_SetStatusText(MUIGetString(STRING_PLEASEWAIT
));
2049 CONSOLE_SetTextXY(6, 8, MUIGetString(STRING_CHOOSE_NEW_EXTENDED_PARTITION
));
2051 DiskSize
= DiskEntry
->SectorCount
.QuadPart
* DiskEntry
->BytesPerSector
;
2053 if (DiskSize
>= 10737418240) /* 10 GB */
2055 DiskSize
= DiskSize
/ 1073741824;
2056 Unit
= MUIGetString(STRING_GB
);
2061 DiskSize
= DiskSize
/ 1048576;
2065 Unit
= MUIGetString(STRING_MB
);
2068 if (DiskEntry
->DriverName
.Length
> 0)
2070 CONSOLE_PrintTextXY(6, 10,
2071 MUIGetString(STRING_HDINFOPARTCREATE
),
2074 DiskEntry
->DiskNumber
,
2078 &DiskEntry
->DriverName
);
2082 CONSOLE_PrintTextXY(6, 10,
2083 MUIGetString(STRING_HDDINFOUNK1
),
2086 DiskEntry
->DiskNumber
,
2092 CONSOLE_SetTextXY(6, 12, MUIGetString(STRING_HDDSIZE
));
2095 CONSOLE_PrintTextXY(8, 10, "Maximum size of the new partition is %I64u MB",
2096 PartitionList
->CurrentPartition
->SectorCount
* DiskEntry
->BytesPerSector
/ 1048576);
2099 CONSOLE_SetStatusText(MUIGetString(STRING_CREATEPARTITION
));
2101 PartEntry
= PartitionList
->CurrentPartition
;
2104 MaxSize
= (PartEntry
->SectorCount
.QuadPart
* DiskEntry
->BytesPerSector
) / 1048576; /* in MBytes (rounded) */
2106 if (MaxSize
> PARTITION_MAXSIZE
)
2107 MaxSize
= PARTITION_MAXSIZE
;
2109 ShowPartitionSizeInputBox(12, 14, xScreen
- 12, 17, /* left, top, right, bottom */
2110 MaxSize
, InputBuffer
, &Quit
, &Cancel
);
2114 if (ConfirmQuit (Ir
) == TRUE
)
2119 else if (Cancel
== TRUE
)
2121 return SELECT_PARTITION_PAGE
;
2125 PartSize
= atoi(InputBuffer
);
2133 if (PartSize
> MaxSize
)
2139 /* Convert to bytes */
2140 if (PartSize
== MaxSize
)
2142 /* Use all of the unpartitioned disk space */
2143 SectorCount
= PartEntry
->SectorCount
.QuadPart
;
2147 /* Calculate the sector count from the size in MB */
2148 SectorCount
= PartSize
* 1048576 / DiskEntry
->BytesPerSector
;
2150 /* But never get larger than the unpartitioned disk space */
2151 if (SectorCount
> PartEntry
->SectorCount
.QuadPart
)
2152 SectorCount
= PartEntry
->SectorCount
.QuadPart
;
2155 DPRINT ("Partition size: %I64u bytes\n", PartSize
);
2157 CreateExtendedPartition(PartitionList
,
2160 return SELECT_PARTITION_PAGE
;
2164 return CREATE_EXTENDED_PARTITION_PAGE
;
2169 * Displays the CreateLogicalPartitionPage.
2172 * SelectFileSystemPage (default)
2176 * Number of the next page.
2179 CreateLogicalPartitionPage(PINPUT_RECORD Ir
)
2181 PDISKENTRY DiskEntry
;
2182 PPARTENTRY PartEntry
;
2185 CHAR InputBuffer
[50];
2189 ULONGLONG SectorCount
;
2192 if (PartitionList
== NULL
||
2193 PartitionList
->CurrentDisk
== NULL
||
2194 PartitionList
->CurrentPartition
== NULL
)
2196 /* FIXME: show an error dialog */
2200 DiskEntry
= PartitionList
->CurrentDisk
;
2201 PartEntry
= PartitionList
->CurrentPartition
;
2203 CONSOLE_SetStatusText(MUIGetString(STRING_PLEASEWAIT
));
2205 CONSOLE_SetTextXY(6, 8, MUIGetString(STRING_CHOOSE_NEW_LOGICAL_PARTITION
));
2207 DiskSize
= DiskEntry
->SectorCount
.QuadPart
* DiskEntry
->BytesPerSector
;
2209 if (DiskSize
>= 10737418240) /* 10 GB */
2211 DiskSize
= DiskSize
/ 1073741824;
2212 Unit
= MUIGetString(STRING_GB
);
2217 DiskSize
= DiskSize
/ 1048576;
2221 Unit
= MUIGetString(STRING_MB
);
2224 if (DiskEntry
->DriverName
.Length
> 0)
2226 CONSOLE_PrintTextXY(6, 10,
2227 MUIGetString(STRING_HDINFOPARTCREATE
),
2230 DiskEntry
->DiskNumber
,
2234 &DiskEntry
->DriverName
);
2238 CONSOLE_PrintTextXY(6, 10,
2239 MUIGetString(STRING_HDDINFOUNK1
),
2242 DiskEntry
->DiskNumber
,
2248 CONSOLE_SetTextXY(6, 12, MUIGetString(STRING_HDDSIZE
));
2251 CONSOLE_PrintTextXY(8, 10, "Maximum size of the new partition is %I64u MB",
2252 PartitionList
->CurrentPartition
->SectorCount
* DiskEntry
->BytesPerSector
/ 1048576);
2255 CONSOLE_SetStatusText(MUIGetString(STRING_CREATEPARTITION
));
2257 PartEntry
= PartitionList
->CurrentPartition
;
2260 MaxSize
= (PartEntry
->SectorCount
.QuadPart
* DiskEntry
->BytesPerSector
) / 1048576; /* in MBytes (rounded) */
2262 if (MaxSize
> PARTITION_MAXSIZE
)
2263 MaxSize
= PARTITION_MAXSIZE
;
2265 ShowPartitionSizeInputBox(12, 14, xScreen
- 12, 17, /* left, top, right, bottom */
2266 MaxSize
, InputBuffer
, &Quit
, &Cancel
);
2270 if (ConfirmQuit (Ir
) == TRUE
)
2275 else if (Cancel
== TRUE
)
2277 return SELECT_PARTITION_PAGE
;
2281 PartSize
= atoi(InputBuffer
);
2289 if (PartSize
> MaxSize
)
2295 /* Convert to bytes */
2296 if (PartSize
== MaxSize
)
2298 /* Use all of the unpartitioned disk space */
2299 SectorCount
= PartEntry
->SectorCount
.QuadPart
;
2303 /* Calculate the sector count from the size in MB */
2304 SectorCount
= PartSize
* 1048576 / DiskEntry
->BytesPerSector
;
2306 /* But never get larger than the unpartitioned disk space */
2307 if (SectorCount
> PartEntry
->SectorCount
.QuadPart
)
2308 SectorCount
= PartEntry
->SectorCount
.QuadPart
;
2311 DPRINT("Partition size: %I64u bytes\n", PartSize
);
2313 CreateLogicalPartition(PartitionList
,
2317 return SELECT_PARTITION_PAGE
;
2321 return CREATE_LOGICAL_PARTITION_PAGE
;
2326 * Displays the ConfirmDeleteSystemPartitionPage.
2329 * DeletePartitionPage (default)
2330 * SelectPartitionPage
2333 * Number of the next page.
2336 ConfirmDeleteSystemPartitionPage(PINPUT_RECORD Ir
)
2338 MUIDisplayPage(CONFIRM_DELETE_SYSTEM_PARTITION_PAGE
);
2342 CONSOLE_ConInKey(Ir
);
2344 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
2345 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
2347 if (ConfirmQuit(Ir
) == TRUE
)
2354 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_RETURN
) /* ENTER */
2356 return DELETE_PARTITION_PAGE
;
2358 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
) /* ESC */
2360 return SELECT_PARTITION_PAGE
;
2364 return SELECT_PARTITION_PAGE
;
2369 * Displays the DeletePartitionPage.
2372 * SelectPartitionPage (default)
2376 * Number of the next page.
2379 DeletePartitionPage(PINPUT_RECORD Ir
)
2381 PDISKENTRY DiskEntry
;
2382 PPARTENTRY PartEntry
;
2388 if (PartitionList
== NULL
||
2389 PartitionList
->CurrentDisk
== NULL
||
2390 PartitionList
->CurrentPartition
== NULL
)
2392 /* FIXME: show an error dialog */
2396 DiskEntry
= PartitionList
->CurrentDisk
;
2397 PartEntry
= PartitionList
->CurrentPartition
;
2399 MUIDisplayPage(DELETE_PARTITION_PAGE
);
2401 GetPartTypeStringFromPartitionTypeA(PartEntry
->PartitionType
,
2405 PartSize
= PartEntry
->SectorCount
.QuadPart
* DiskEntry
->BytesPerSector
;
2407 if (PartSize
>= 10737418240) /* 10 GB */
2409 PartSize
= PartSize
/ 1073741824;
2410 Unit
= MUIGetString(STRING_GB
);
2414 if (PartSize
>= 10485760) /* 10 MB */
2416 PartSize
= PartSize
/ 1048576;
2417 Unit
= MUIGetString(STRING_MB
);
2421 PartSize
= PartSize
/ 1024;
2422 Unit
= MUIGetString(STRING_KB
);
2425 if (PartType
== NULL
)
2427 CONSOLE_PrintTextXY(6, 10,
2428 MUIGetString(STRING_HDDINFOUNK2
),
2429 (PartEntry
->DriveLetter
== 0) ? '-' : PartEntry
->DriveLetter
,
2430 (PartEntry
->DriveLetter
== 0) ? '-' : ':',
2431 PartEntry
->PartitionType
,
2437 CONSOLE_PrintTextXY(6, 10,
2438 " %c%c %s %I64u %s",
2439 (PartEntry
->DriveLetter
== 0) ? '-' : PartEntry
->DriveLetter
,
2440 (PartEntry
->DriveLetter
== 0) ? '-' : ':',
2446 DiskSize
= DiskEntry
->SectorCount
.QuadPart
* DiskEntry
->BytesPerSector
;
2448 if (DiskSize
>= 10737418240) /* 10 GB */
2450 DiskSize
= DiskSize
/ 1073741824;
2451 Unit
= MUIGetString(STRING_GB
);
2456 DiskSize
= DiskSize
/ 1048576;
2460 Unit
= MUIGetString(STRING_MB
);
2463 if (DiskEntry
->DriverName
.Length
> 0)
2465 CONSOLE_PrintTextXY(6, 12,
2466 MUIGetString(STRING_HDINFOPARTDELETE
),
2469 DiskEntry
->DiskNumber
,
2473 &DiskEntry
->DriverName
);
2477 CONSOLE_PrintTextXY(6, 12,
2478 MUIGetString(STRING_HDDINFOUNK3
),
2481 DiskEntry
->DiskNumber
,
2489 CONSOLE_ConInKey(Ir
);
2491 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
2492 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
2494 if (ConfirmQuit(Ir
) == TRUE
)
2501 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
) /* ESC */
2503 return SELECT_PARTITION_PAGE
;
2505 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== 'D') /* D */
2507 DeleteCurrentPartition(PartitionList
);
2509 return SELECT_PARTITION_PAGE
;
2513 return DELETE_PARTITION_PAGE
;
2518 * Displays the SelectFileSystemPage.
2521 * CheckFileSystemPage (At once if RepairUpdate is selected)
2522 * CheckFileSystemPage (At once if Unattended and not UnattendFormatPartition)
2523 * FormatPartitionPage (At once if Unattended and UnattendFormatPartition)
2524 * SelectPartitionPage (If the user aborts)
2525 * FormatPartitionPage (Default)
2529 * Sets PartEntry->DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex].PartitionType (via UpdatePartitionType)
2530 * Calls CheckActiveBootPartition()
2533 * Number of the next page.
2536 SelectFileSystemPage(PINPUT_RECORD Ir
)
2538 PDISKENTRY DiskEntry
;
2539 PPARTENTRY PartEntry
;
2544 CHAR PartTypeString
[32];
2546 DPRINT("SelectFileSystemPage()\n");
2548 if (PartitionList
== NULL
||
2549 PartitionList
->CurrentDisk
== NULL
||
2550 PartitionList
->CurrentPartition
== NULL
)
2552 /* FIXME: show an error dialog */
2556 /* Find or set the active partition */
2557 CheckActiveBootPartition(PartitionList
);
2559 if (PartitionList
->BootDisk
== NULL
||
2560 PartitionList
->BootPartition
== NULL
)
2562 /* FIXME: show an error dialog */
2566 switch (PartitionList
->FormatState
)
2569 if (PartitionList
->CurrentPartition
!= PartitionList
->BootPartition
)
2571 PartitionList
->TempDisk
= PartitionList
->BootDisk
;
2572 PartitionList
->TempPartition
= PartitionList
->BootPartition
;
2573 PartitionList
->TempPartition
->NeedsCheck
= TRUE
;
2575 PartitionList
->FormatState
= FormatSystemPartition
;
2576 DPRINT1("FormatState: Start --> FormatSystemPartition\n");
2580 PartitionList
->TempDisk
= PartitionList
->CurrentDisk
;
2581 PartitionList
->TempPartition
= PartitionList
->CurrentPartition
;
2582 PartitionList
->TempPartition
->NeedsCheck
= TRUE
;
2584 PartitionList
->FormatState
= FormatInstallPartition
;
2585 DPRINT1("FormatState: Start --> FormatInstallPartition\n");
2589 case FormatSystemPartition
:
2590 PartitionList
->TempDisk
= PartitionList
->CurrentDisk
;
2591 PartitionList
->TempPartition
= PartitionList
->CurrentPartition
;
2592 PartitionList
->TempPartition
->NeedsCheck
= TRUE
;
2594 PartitionList
->FormatState
= FormatInstallPartition
;
2595 DPRINT1("FormatState: FormatSystemPartition --> FormatInstallPartition\n");
2598 case FormatInstallPartition
:
2599 if (GetNextUnformattedPartition(PartitionList
,
2600 &PartitionList
->TempDisk
,
2601 &PartitionList
->TempPartition
))
2603 PartitionList
->FormatState
= FormatOtherPartition
;
2604 PartitionList
->TempPartition
->NeedsCheck
= TRUE
;
2605 DPRINT1("FormatState: FormatInstallPartition --> FormatOtherPartition\n");
2609 PartitionList
->FormatState
= FormatDone
;
2610 DPRINT1("FormatState: FormatInstallPartition --> FormatDone\n");
2611 return CHECK_FILE_SYSTEM_PAGE
;
2615 case FormatOtherPartition
:
2616 if (GetNextUnformattedPartition(PartitionList
,
2617 &PartitionList
->TempDisk
,
2618 &PartitionList
->TempPartition
))
2620 PartitionList
->FormatState
= FormatOtherPartition
;
2621 PartitionList
->TempPartition
->NeedsCheck
= TRUE
;
2622 DPRINT1("FormatState: FormatOtherPartition --> FormatOtherPartition\n");
2626 PartitionList
->FormatState
= FormatDone
;
2627 DPRINT1("FormatState: FormatOtherPartition --> FormatDone\n");
2628 return CHECK_FILE_SYSTEM_PAGE
;
2633 DPRINT1("FormatState: Invalid value %ld\n", PartitionList
->FormatState
);
2634 /* FIXME: show an error dialog */
2638 DiskEntry
= PartitionList
->TempDisk
;
2639 PartEntry
= PartitionList
->TempPartition
;
2641 /* adjust disk size */
2642 DiskSize
= DiskEntry
->SectorCount
.QuadPart
* DiskEntry
->BytesPerSector
;
2643 if (DiskSize
>= 10737418240) /* 10 GB */
2645 DiskSize
= DiskSize
/ 1073741824;
2646 DiskUnit
= MUIGetString(STRING_GB
);
2650 DiskSize
= DiskSize
/ 1048576;
2651 DiskUnit
= MUIGetString(STRING_MB
);
2654 /* adjust partition size */
2655 PartSize
= PartEntry
->SectorCount
.QuadPart
* DiskEntry
->BytesPerSector
;
2656 if (PartSize
>= 10737418240) /* 10 GB */
2658 PartSize
= PartSize
/ 1073741824;
2659 PartUnit
= MUIGetString(STRING_GB
);
2663 PartSize
= PartSize
/ 1048576;
2664 PartUnit
= MUIGetString(STRING_MB
);
2667 /* adjust partition type */
2668 GetPartTypeStringFromPartitionTypeA(PartEntry
->PartitionType
,
2672 if (PartEntry
->AutoCreate
== TRUE
)
2674 CONSOLE_SetTextXY(6, 8, MUIGetString(STRING_NEWPARTITION
));
2677 CONSOLE_PrintTextXY(8, 10, "Partition %lu (%I64u %s) %s of",
2678 PartEntry
->PartitionNumber
,
2684 CONSOLE_PrintTextXY(8, 10, MUIGetString(STRING_HDINFOPARTZEROED
),
2685 DiskEntry
->DiskNumber
,
2691 &DiskEntry
->DriverName
);
2693 CONSOLE_SetTextXY(6, 12, MUIGetString(STRING_PARTFORMAT
));
2696 PartEntry
->AutoCreate
= FALSE
;
2698 else if (PartEntry
->New
== TRUE
)
2700 switch (PartitionList
->FormatState
)
2702 case FormatSystemPartition
:
2703 CONSOLE_SetTextXY(6, 8, MUIGetString(STRING_NONFORMATTEDSYSTEMPART
));
2706 case FormatInstallPartition
:
2707 CONSOLE_SetTextXY(6, 8, MUIGetString(STRING_NONFORMATTEDPART
));
2710 case FormatOtherPartition
:
2711 CONSOLE_SetTextXY(6, 8, MUIGetString(STRING_NONFORMATTEDOTHERPART
));
2718 CONSOLE_SetTextXY(6, 10, MUIGetString(STRING_PARTFORMAT
));
2722 CONSOLE_SetTextXY(6, 8, MUIGetString(STRING_INSTALLONPART
));
2724 if (PartTypeString
== NULL
)
2726 CONSOLE_PrintTextXY(8, 10,
2727 MUIGetString(STRING_HDDINFOUNK4
),
2728 (PartEntry
->DriveLetter
== 0) ? '-' : PartEntry
->DriveLetter
,
2729 (PartEntry
->DriveLetter
== 0) ? '-' : ':',
2730 PartEntry
->PartitionType
,
2736 CONSOLE_PrintTextXY(8, 10,
2738 (PartEntry
->DriveLetter
== 0) ? '-' : PartEntry
->DriveLetter
,
2739 (PartEntry
->DriveLetter
== 0) ? '-' : ':',
2745 CONSOLE_PrintTextXY(6, 12, MUIGetString(STRING_HDINFOPARTEXISTS
),
2746 DiskEntry
->DiskNumber
,
2752 &DiskEntry
->DriverName
);
2755 MUIDisplayPage(SELECT_FILE_SYSTEM_PAGE
);
2757 if (FileSystemList
== NULL
)
2759 FileSystemList
= CreateFileSystemList(6, 26, PartEntry
->New
, L
"FAT");
2760 if (FileSystemList
== NULL
)
2762 /* FIXME: show an error dialog */
2766 /* FIXME: Add file systems to list */
2769 DrawFileSystemList(FileSystemList
);
2771 if (RepairUpdateFlag
)
2773 return CHECK_FILE_SYSTEM_PAGE
;
2774 //return SELECT_PARTITION_PAGE;
2777 if (IsUnattendedSetup
)
2779 if (UnattendFormatPartition
)
2781 PartEntry
->FileSystem
= GetFileSystemByName(FileSystemList
,
2783 return FORMAT_PARTITION_PAGE
;
2786 return CHECK_FILE_SYSTEM_PAGE
;
2791 CONSOLE_ConInKey(Ir
);
2793 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
2794 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
2796 if (ConfirmQuit(Ir
) == TRUE
)
2803 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
2804 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
)) /* ESC */
2806 return SELECT_PARTITION_PAGE
;
2808 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
2809 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
)) /* DOWN */
2811 ScrollDownFileSystemList(FileSystemList
);
2813 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
2814 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_UP
)) /* UP */
2816 ScrollUpFileSystemList(FileSystemList
);
2818 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_RETURN
) /* ENTER */
2820 if (!FileSystemList
->Selected
->FormatFunc
)
2822 return SELECT_FILE_SYSTEM_PAGE
;
2826 PartEntry
->FileSystem
= FileSystemList
->Selected
;
2827 return FORMAT_PARTITION_PAGE
;
2832 return SELECT_FILE_SYSTEM_PAGE
;
2837 * Displays the FormatPartitionPage.
2840 * InstallDirectoryPage (At once if IsUnattendedSetup or InstallShortcut)
2841 * SelectPartitionPage (At once)
2845 * Sets PartitionList->CurrentPartition->FormatState
2846 * Sets DestinationRootPath
2849 * Number of the next page.
2852 FormatPartitionPage(PINPUT_RECORD Ir
)
2854 UNICODE_STRING PartitionRootPath
;
2855 WCHAR PathBuffer
[MAX_PATH
];
2856 PDISKENTRY DiskEntry
;
2857 PPARTENTRY PartEntry
;
2866 DPRINT("FormatPartitionPage()\n");
2868 MUIDisplayPage(FORMAT_PARTITION_PAGE
);
2870 if (PartitionList
== NULL
||
2871 PartitionList
->TempDisk
== NULL
||
2872 PartitionList
->TempPartition
== NULL
)
2874 /* FIXME: show an error dialog */
2878 DiskEntry
= PartitionList
->TempDisk
;
2879 PartEntry
= PartitionList
->TempPartition
;
2883 if (!IsUnattendedSetup
)
2885 CONSOLE_ConInKey(Ir
);
2888 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
2889 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
2891 if (ConfirmQuit(Ir
) == TRUE
)
2898 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_RETURN
|| IsUnattendedSetup
) /* ENTER */
2900 CONSOLE_SetStatusText(MUIGetString(STRING_PLEASEWAIT
));
2902 if (wcscmp(PartEntry
->FileSystem
->FileSystemName
, L
"FAT") == 0)
2904 if (PartEntry
->SectorCount
.QuadPart
< 8192)
2906 /* FAT12 CHS partition (disk is smaller than 4.1MB) */
2907 PartEntry
->PartitionType
= PARTITION_FAT_12
;
2909 else if (PartEntry
->StartSector
.QuadPart
< 1450560)
2911 /* Partition starts below the 8.4GB boundary ==> CHS partition */
2913 if (PartEntry
->SectorCount
.QuadPart
< 65536)
2915 /* FAT16 CHS partition (partiton size < 32MB) */
2916 PartEntry
->PartitionType
= PARTITION_FAT_16
;
2918 else if (PartEntry
->SectorCount
.QuadPart
< 1048576)
2920 /* FAT16 CHS partition (partition size < 512MB) */
2921 PartEntry
->PartitionType
= PARTITION_HUGE
;
2925 /* FAT32 CHS partition (partition size >= 512MB) */
2926 PartEntry
->PartitionType
= PARTITION_FAT32
;
2931 /* Partition starts above the 8.4GB boundary ==> LBA partition */
2933 if (PartEntry
->SectorCount
.QuadPart
< 1048576)
2935 /* FAT16 LBA partition (partition size < 512MB) */
2936 PartEntry
->PartitionType
= PARTITION_XINT13
;
2940 /* FAT32 LBA partition (partition size >= 512MB) */
2941 PartEntry
->PartitionType
= PARTITION_FAT32_XINT13
;
2945 DiskEntry
->Dirty
= TRUE
;
2946 DiskEntry
->LayoutBuffer
->PartitionEntry
[PartEntry
->PartitionIndex
].PartitionType
= PartEntry
->PartitionType
;
2947 DiskEntry
->LayoutBuffer
->PartitionEntry
[PartEntry
->PartitionIndex
].RewritePartition
= TRUE
;
2950 else if (wcscmp(PartEntry
->FileSystem
->FileSystemName
, L
"EXT2") == 0)
2952 PartEntry
->PartitionType
= PARTITION_EXT2
;
2954 DiskEntry
->Dirty
= TRUE
;
2955 DiskEntry
->LayoutBuffer
->PartitionEntry
[PartEntry
->PartitionIndex
].PartitionType
= PartEntry
->PartitionType
;
2956 DiskEntry
->LayoutBuffer
->PartitionEntry
[PartEntry
->PartitionIndex
].RewritePartition
= TRUE
;
2958 else if (wcscmp(PartEntry
->FileSystem
->FileSystemName
, L
"NTFS") == 0)
2960 PartEntry
->PartitionType
= PARTITION_IFS
;
2962 DiskEntry
->Dirty
= TRUE
;
2963 DiskEntry
->LayoutBuffer
->PartitionEntry
[PartEntry
->PartitionIndex
].PartitionType
= PartEntry
->PartitionType
;
2964 DiskEntry
->LayoutBuffer
->PartitionEntry
[PartEntry
->PartitionIndex
].RewritePartition
= TRUE
;
2967 else if (!PartEntry
->FileSystem
->FormatFunc
)
2973 CONSOLE_PrintTextXY(6, 12,
2974 "Disk: %I64u Cylinder: %I64u Track: %I64u",
2975 DiskEntry
->DiskSize
,
2976 DiskEntry
->CylinderSize
,
2977 DiskEntry
->TrackSize
);
2980 DiskEntry
= PartitionList
->TempDisk
;
2981 Entry
= DiskEntry
->PartListHead
.Flink
;
2983 while (Entry
!= &DiskEntry
->PrimaryPartListHead
)
2985 PartEntry
= CONTAINING_RECORD(Entry
, PARTENTRY
, ListEntry
);
2987 if (PartEntry
->IsPartitioned
== TRUE
)
2989 CONSOLE_PrintTextXY(6, Line
,
2990 "%2u: %2u %c %12I64u %12I64u %2u %c",
2992 PartEntry
->PartitionNumber
,
2993 PartEntry
->BootIndicator
? 'A' : '-',
2994 PartEntry
->StartSector
.QuadPart
,
2995 PartEntry
->SectorCount
.QuadPart
,
2996 PartEntry
->PartitionType
,
2997 PartEntry
->Dirty
? '*' : ' ');
3001 Entry
= Entry
->Flink
;
3004 /* Restore the old entry */
3005 PartEntry
= PartitionList
->TempPartition
;
3008 if (WritePartitionsToDisk(PartitionList
) == FALSE
)
3010 DPRINT("WritePartitionsToDisk() failed\n");
3011 MUIDisplayError(ERROR_WRITE_PTABLE
, Ir
, POPUP_WAIT_ENTER
);
3015 /* Set PartitionRootPath */
3016 swprintf(PathBuffer
,
3017 L
"\\Device\\Harddisk%lu\\Partition%lu",
3018 DiskEntry
->DiskNumber
,
3019 PartEntry
->PartitionNumber
);
3020 RtlInitUnicodeString(&PartitionRootPath
,
3022 DPRINT("PartitionRootPath: %wZ\n", &PartitionRootPath
);
3024 if (PartEntry
->FileSystem
->FormatFunc
)
3026 Status
= FormatPartition(&PartitionRootPath
,
3027 PartEntry
->FileSystem
);
3028 if (!NT_SUCCESS(Status
))
3030 DPRINT1("FormatPartition() failed with status 0x%08lx\n", Status
);
3031 MUIDisplayError(ERROR_FORMATTING_PARTITION
, Ir
, POPUP_WAIT_ANY_KEY
, PathBuffer
);
3035 PartEntry
->New
= FALSE
;
3039 CONSOLE_SetStatusText(" Done. Press any key ...");
3040 CONSOLE_ConInKey(Ir
);
3043 return SELECT_FILE_SYSTEM_PAGE
;
3047 return FORMAT_PARTITION_PAGE
;
3052 * Displays the CheckFileSystemPage.
3055 * InstallDirectoryPage (At once)
3059 * Inits or reloads FileSystemList
3062 * Number of the next page.
3065 CheckFileSystemPage(PINPUT_RECORD Ir
)
3067 PFILE_SYSTEM_ITEM CurrentFileSystem
;
3068 UNICODE_STRING PartitionRootPath
;
3069 WCHAR PathBuffer
[MAX_PATH
];
3070 CHAR Buffer
[MAX_PATH
];
3071 WCHAR PartTypeString
[32];
3072 PDISKENTRY DiskEntry
;
3073 PPARTENTRY PartEntry
;
3076 if (PartitionList
== NULL
)
3078 /* FIXME: show an error dialog */
3082 if (!GetNextUncheckedPartition(PartitionList
,
3086 return INSTALL_DIRECTORY_PAGE
;
3089 /* Set PartitionRootPath */
3090 swprintf(PathBuffer
,
3091 L
"\\Device\\Harddisk%lu\\Partition%lu",
3092 DiskEntry
->DiskNumber
,
3093 PartEntry
->PartitionNumber
);
3094 RtlInitUnicodeString(&PartitionRootPath
, PathBuffer
);
3095 DPRINT("PartitionRootPath: %wZ\n", &PartitionRootPath
);
3097 CONSOLE_SetTextXY(6, 8, MUIGetString(STRING_CHECKINGPART
));
3099 CONSOLE_SetStatusText(MUIGetString(STRING_PLEASEWAIT
));
3101 CurrentFileSystem
= PartEntry
->FileSystem
;
3102 if (CurrentFileSystem
== NULL
|| CurrentFileSystem
->FileSystemName
== NULL
)
3104 GetPartTypeStringFromPartitionTypeW(PartEntry
->PartitionType
, PartTypeString
, 30);
3106 DPRINT("PartTypeString: %S\n", PartTypeString
);
3108 if (PartTypeString
!= NULL
)
3109 CurrentFileSystem
= GetFileSystemByName(FileSystemList
,
3113 /* HACK: Do not try to check a partition with an unknown filesytem */
3114 if (CurrentFileSystem
== NULL
)
3116 PartEntry
->NeedsCheck
= FALSE
;
3117 return CHECK_FILE_SYSTEM_PAGE
;
3120 if (CurrentFileSystem
->ChkdskFunc
== NULL
)
3123 "Setup is currently unable to check a partition formatted in %S.\n"
3125 " \x07 Press ENTER to continue Setup.\n"
3126 " \x07 Press F3 to quit Setup.",
3127 CurrentFileSystem
->FileSystemName
);
3130 MUIGetString(STRING_QUITCONTINUE
),
3131 NULL
, POPUP_WAIT_NONE
);
3135 CONSOLE_ConInKey(Ir
);
3137 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00 &&
3138 Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
) /* F3 */
3140 if (ConfirmQuit(Ir
))
3143 return CHECK_FILE_SYSTEM_PAGE
;
3145 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== VK_RETURN
) /* ENTER */
3147 PartEntry
->NeedsCheck
= FALSE
;
3148 return CHECK_FILE_SYSTEM_PAGE
;
3154 Status
= ChkdskPartition(&PartitionRootPath
, CurrentFileSystem
);
3155 if (!NT_SUCCESS(Status
))
3157 DPRINT("ChkdskPartition() failed with status 0x%08lx\n", Status
);
3158 sprintf(Buffer
, "Setup failed to verify the selected partition.\n"
3159 "(Status 0x%08lx).\n", Status
);
3161 MUIGetString(STRING_REBOOTCOMPUTER
),
3162 Ir
, POPUP_WAIT_ENTER
);
3167 PartEntry
->NeedsCheck
= FALSE
;
3168 return CHECK_FILE_SYSTEM_PAGE
;
3174 * Displays the InstallDirectoryPage1.
3177 * PrepareCopyPage (At once)
3180 * Inits DestinationRootPath
3181 * Inits DestinationPath
3182 * Inits DestinationArcPath
3185 * Number of the next page.
3188 InstallDirectoryPage1(PWCHAR InstallDir
,
3189 PDISKENTRY DiskEntry
,
3190 PPARTENTRY PartEntry
)
3192 WCHAR PathBuffer
[MAX_PATH
];
3194 /* Create 'InstallPath' string */
3195 RtlFreeUnicodeString(&InstallPath
);
3196 RtlCreateUnicodeString(&InstallPath
,
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
))
3724 /* Search for the 'Cabinets' section */
3725 if (!SetupFindFirstLineW(SetupInf
, L
"Cabinets", NULL
, &CabinetsContext
))
3727 return FILE_COPY_PAGE
;
3731 * Enumerate the directory values in the 'Cabinets'
3732 * section and parse their inf files.
3736 if (!INF_GetData(&CabinetsContext
, NULL
, &KeyValue
))
3739 wcscpy(PathBuffer
, SourcePath
.Buffer
);
3740 wcscat(PathBuffer
, L
"\\");
3741 wcscat(PathBuffer
, KeyValue
);
3744 CabinetInitialize();
3745 CabinetSetEventHandlers(NULL
, NULL
, NULL
);
3746 CabinetSetCabinetName(PathBuffer
);
3748 if (CabinetOpen() == CAB_STATUS_SUCCESS
)
3750 DPRINT("Cabinet %S\n", CabinetGetCabinetName());
3752 InfFileData
= CabinetGetCabinetReservedArea(&InfFileSize
);
3753 if (InfFileData
== NULL
)
3755 MUIDisplayError(ERROR_CABINET_SCRIPT
, Ir
, POPUP_WAIT_ENTER
);
3761 DPRINT("Cannot open cabinet: %S.\n", CabinetGetCabinetName());
3762 MUIDisplayError(ERROR_CABINET_MISSING
, Ir
, POPUP_WAIT_ENTER
);
3766 InfHandle
= INF_OpenBufferedFileA((CHAR
*) InfFileData
,
3773 if (InfHandle
== INVALID_HANDLE_VALUE
)
3775 MUIDisplayError(ERROR_INVALID_CABINET_INF
, Ir
, POPUP_WAIT_ENTER
);
3781 if (!PrepareCopyPageInfFile(InfHandle
, KeyValue
, Ir
))
3786 } while (SetupFindNextLine(&CabinetsContext
, &CabinetsContext
));
3788 return FILE_COPY_PAGE
;
3794 SetupUpdateMemoryInfo(IN PCOPYCONTEXT CopyContext
,
3797 SYSTEM_PERFORMANCE_INFORMATION PerfInfo
;
3799 /* Get the memory information from the system */
3800 NtQuerySystemInformation(SystemPerformanceInformation
,
3805 /* Check if this is initial setup */
3808 /* Set maximum limits to be total RAM pages */
3809 ProgressSetStepCount(CopyContext
->MemoryBars
[0], PerfInfo
.CommitLimit
);
3810 ProgressSetStepCount(CopyContext
->MemoryBars
[1], PerfInfo
.CommitLimit
);
3811 ProgressSetStepCount(CopyContext
->MemoryBars
[2], PerfInfo
.CommitLimit
);
3814 /* Set current values */
3815 ProgressSetStep(CopyContext
->MemoryBars
[0], PerfInfo
.PagedPoolPages
+ PerfInfo
.NonPagedPoolPages
);
3816 ProgressSetStep(CopyContext
->MemoryBars
[1], PerfInfo
.ResidentSystemCachePage
);
3817 ProgressSetStep(CopyContext
->MemoryBars
[2], PerfInfo
.AvailablePages
);
3823 FileCopyCallback(PVOID Context
,
3828 PCOPYCONTEXT CopyContext
;
3830 CopyContext
= (PCOPYCONTEXT
)Context
;
3832 switch (Notification
)
3834 case SPFILENOTIFY_STARTSUBQUEUE
:
3835 CopyContext
->TotalOperations
= (ULONG
)Param2
;
3836 ProgressSetStepCount(CopyContext
->ProgressBar
,
3837 CopyContext
->TotalOperations
);
3838 SetupUpdateMemoryInfo(CopyContext
, TRUE
);
3841 case SPFILENOTIFY_STARTCOPY
:
3842 /* Display copy message */
3843 CONSOLE_SetStatusText(MUIGetString(STRING_COPYING
), (PWSTR
)Param1
);
3844 SetupUpdateMemoryInfo(CopyContext
, FALSE
);
3847 case SPFILENOTIFY_ENDCOPY
:
3848 CopyContext
->CompletedOperations
++;
3850 /* SYSREG checkpoint */
3851 if (CopyContext
->TotalOperations
>> 1 == CopyContext
->CompletedOperations
)
3852 DPRINT1("CHECKPOINT:HALF_COPIED\n");
3854 ProgressNextStep(CopyContext
->ProgressBar
);
3855 SetupUpdateMemoryInfo(CopyContext
, FALSE
);
3864 * Displays the FileCopyPage.
3867 * RegistryPage(At once)
3870 * Calls SetupCommitFileQueueW
3871 * Calls SetupCloseFileQueue
3874 * Number of the next page.
3878 FileCopyPage(PINPUT_RECORD Ir
)
3880 COPYCONTEXT CopyContext
;
3881 unsigned int mem_bar_width
;
3883 MUIDisplayPage(FILE_COPY_PAGE
);
3885 /* Create context for the copy process */
3886 CopyContext
.DestinationRootPath
= DestinationRootPath
.Buffer
;
3887 CopyContext
.InstallPath
= InstallPath
.Buffer
;
3888 CopyContext
.TotalOperations
= 0;
3889 CopyContext
.CompletedOperations
= 0;
3891 /* Create the progress bar as well */
3892 CopyContext
.ProgressBar
= CreateProgressBar(13,
3899 MUIGetString(STRING_SETUPCOPYINGFILES
));
3901 // fit memory bars to screen width, distribute them uniform
3902 mem_bar_width
= (xScreen
- 26) / 5;
3903 mem_bar_width
-= mem_bar_width
% 2; // make even
3904 /* ATTENTION: The following progress bars are debug stuff, which should not be translated!! */
3905 /* Create the paged pool progress bar */
3906 CopyContext
.MemoryBars
[0] = CreateProgressBar(13,
3915 /* Create the non paged pool progress bar */
3916 CopyContext
.MemoryBars
[1] = CreateProgressBar((xScreen
/ 2)- (mem_bar_width
/ 2),
3918 (xScreen
/ 2) + (mem_bar_width
/ 2),
3920 (xScreen
/ 2)- (mem_bar_width
/ 2),
3925 /* Create the global memory progress bar */
3926 CopyContext
.MemoryBars
[2] = CreateProgressBar(xScreen
- 13 - mem_bar_width
,
3930 xScreen
- 13 - mem_bar_width
,
3935 /* Do the file copying */
3936 SetupCommitFileQueueW(NULL
,
3941 /* If we get here, we're done, so cleanup the queue and progress bar */
3942 SetupCloseFileQueue(SetupFileQueue
);
3943 DestroyProgressBar(CopyContext
.ProgressBar
);
3944 DestroyProgressBar(CopyContext
.MemoryBars
[0]);
3945 DestroyProgressBar(CopyContext
.MemoryBars
[1]);
3946 DestroyProgressBar(CopyContext
.MemoryBars
[2]);
3948 /* Go display the next page */
3949 return REGISTRY_PAGE
;
3954 * Displays the RegistryPage.
3957 * SuccessPage (if RepairUpdate)
3958 * BootLoaderPage (default)
3962 * Calls SetInstallPathValue
3963 * Calls NtInitializeRegistry
3964 * Calls ImportRegistryFile
3965 * Calls SetDefaultPagefile
3966 * Calls SetMountedDeviceValues
3969 * Number of the next page.
3972 RegistryPage(PINPUT_RECORD Ir
)
3974 INFCONTEXT InfContext
;
3981 MUIDisplayPage(REGISTRY_PAGE
);
3983 if (RepairUpdateFlag
)
3985 return SUCCESS_PAGE
;
3988 if (!SetInstallPathValue(&DestinationPath
))
3990 DPRINT1("SetInstallPathValue() failed\n");
3991 MUIDisplayError(ERROR_INITIALIZE_REGISTRY
, Ir
, POPUP_WAIT_ENTER
);
3995 /* Create the default hives */
3996 Status
= NtInitializeRegistry(CM_BOOT_FLAG_SETUP
);
3997 if (!NT_SUCCESS(Status
))
3999 DPRINT1("NtInitializeRegistry() failed (Status %lx)\n", Status
);
4000 MUIDisplayError(ERROR_CREATE_HIVE
, Ir
, POPUP_WAIT_ENTER
);
4004 /* Update registry */
4005 CONSOLE_SetStatusText(MUIGetString(STRING_REGHIVEUPDATE
));
4007 if (!SetupFindFirstLineW(SetupInf
, L
"HiveInfs.Install", NULL
, &InfContext
))
4009 DPRINT1("SetupFindFirstLine() failed\n");
4010 MUIDisplayError(ERROR_FIND_REGISTRY
, Ir
, POPUP_WAIT_ENTER
);
4016 INF_GetDataField (&InfContext
, 0, &Action
);
4017 INF_GetDataField (&InfContext
, 1, &File
);
4018 INF_GetDataField (&InfContext
, 2, &Section
);
4020 DPRINT("Action: %S File: %S Section %S\n", Action
, File
, Section
);
4025 if (!_wcsicmp (Action
, L
"AddReg"))
4029 else if (!_wcsicmp (Action
, L
"DelReg"))
4038 CONSOLE_SetStatusText(MUIGetString(STRING_IMPORTFILE
), File
);
4040 if (!ImportRegistryFile(File
, Section
, LanguageId
, Delete
))
4042 DPRINT1("Importing %S failed\n", File
);
4044 MUIDisplayError(ERROR_IMPORT_HIVE
, Ir
, POPUP_WAIT_ENTER
);
4047 } while (SetupFindNextLine(&InfContext
, &InfContext
));
4049 /* Update display registry settings */
4050 CONSOLE_SetStatusText(MUIGetString(STRING_DISPLAYETTINGSUPDATE
));
4051 if (!ProcessDisplayRegistry(SetupInf
, DisplayList
))
4053 MUIDisplayError(ERROR_UPDATE_DISPLAY_SETTINGS
, Ir
, POPUP_WAIT_ENTER
);
4057 /* Set the locale */
4058 CONSOLE_SetStatusText(MUIGetString(STRING_LOCALESETTINGSUPDATE
));
4059 if (!ProcessLocaleRegistry(LanguageList
))
4061 MUIDisplayError(ERROR_UPDATE_LOCALESETTINGS
, Ir
, POPUP_WAIT_ENTER
);
4065 /* Add keyboard layouts */
4066 CONSOLE_SetStatusText(MUIGetString(STRING_ADDKBLAYOUTS
));
4067 if (!AddKeyboardLayouts())
4069 MUIDisplayError(ERROR_ADDING_KBLAYOUTS
, Ir
, POPUP_WAIT_ENTER
);
4075 if (!SetGeoID(MUIGetGeoID()))
4077 MUIDisplayError(ERROR_UPDATE_GEOID
, Ir
, POPUP_WAIT_ENTER
);
4081 if (!IsUnattendedSetup
)
4083 /* Update keyboard layout settings */
4084 CONSOLE_SetStatusText(MUIGetString(STRING_KEYBOARDSETTINGSUPDATE
));
4085 if (!ProcessKeyboardLayoutRegistry(LayoutList
))
4087 MUIDisplayError(ERROR_UPDATE_KBSETTINGS
, Ir
, POPUP_WAIT_ENTER
);
4092 /* Add codepage information to registry */
4093 CONSOLE_SetStatusText(MUIGetString(STRING_CODEPAGEINFOUPDATE
));
4096 MUIDisplayError(ERROR_ADDING_CODEPAGE
, Ir
, POPUP_WAIT_ENTER
);
4100 /* Set the default pagefile entry */
4101 SetDefaultPagefile(DestinationDriveLetter
);
4103 /* Update the mounted devices list */
4104 SetMountedDeviceValues(PartitionList
);
4106 CONSOLE_SetStatusText(MUIGetString(STRING_DONE
));
4108 return BOOT_LOADER_PAGE
;
4113 * Displays the BootLoaderPage.
4116 * SuccessPage (if RepairUpdate)
4117 * BootLoaderHarddiskMbrPage
4118 * BootLoaderHarddiskVbrPage
4119 * BootLoaderFloppyPage
4124 * Calls SetInstallPathValue
4125 * Calls NtInitializeRegistry
4126 * Calls ImportRegistryFile
4127 * Calls SetDefaultPagefile
4128 * Calls SetMountedDeviceValues
4131 * Number of the next page.
4134 BootLoaderPage(PINPUT_RECORD Ir
)
4136 UCHAR PartitionType
;
4137 BOOLEAN InstallOnFloppy
;
4139 WCHAR PathBuffer
[MAX_PATH
];
4141 CONSOLE_SetStatusText(MUIGetString(STRING_PLEASEWAIT
));
4143 RtlFreeUnicodeString(&SystemRootPath
);
4144 swprintf(PathBuffer
,
4145 L
"\\Device\\Harddisk%lu\\Partition%lu",
4146 PartitionList
->BootDisk
->DiskNumber
,
4147 PartitionList
->BootPartition
->PartitionNumber
);
4148 RtlCreateUnicodeString(&SystemRootPath
,
4150 DPRINT("SystemRootPath: %wZ\n", &SystemRootPath
);
4152 PartitionType
= PartitionList
->BootPartition
->PartitionType
;
4154 if (IsUnattendedSetup
)
4156 if (UnattendMBRInstallType
== 0) /* skip MBR installation */
4158 return SUCCESS_PAGE
;
4160 else if (UnattendMBRInstallType
== 1) /* install on floppy */
4162 return BOOT_LOADER_FLOPPY_PAGE
;
4166 if (PartitionType
== PARTITION_ENTRY_UNUSED
)
4168 DPRINT("Error: active partition invalid (unused)\n");
4169 InstallOnFloppy
= TRUE
;
4171 else if (PartitionType
== PARTITION_OS2BOOTMGR
)
4173 /* OS/2 boot manager partition */
4174 DPRINT("Found OS/2 boot manager partition\n");
4175 InstallOnFloppy
= TRUE
;
4177 else if (PartitionType
== PARTITION_EXT2
)
4179 /* Linux ext2 partition */
4180 DPRINT("Found Linux ext2 partition\n");
4181 InstallOnFloppy
= FALSE
;
4183 else if (PartitionType
== PARTITION_IFS
)
4185 /* NTFS partition */
4186 DPRINT("Found NTFS partition\n");
4188 // FIXME: Make it FALSE when we'll support NTFS installation!
4189 InstallOnFloppy
= TRUE
;
4191 else if ((PartitionType
== PARTITION_FAT_12
) ||
4192 (PartitionType
== PARTITION_FAT_16
) ||
4193 (PartitionType
== PARTITION_HUGE
) ||
4194 (PartitionType
== PARTITION_XINT13
) ||
4195 (PartitionType
== PARTITION_FAT32
) ||
4196 (PartitionType
== PARTITION_FAT32_XINT13
))
4198 DPRINT("Found FAT partition\n");
4199 InstallOnFloppy
= FALSE
;
4203 /* Unknown partition */
4204 DPRINT("Unknown partition found\n");
4205 InstallOnFloppy
= TRUE
;
4208 if (InstallOnFloppy
== TRUE
)
4210 return BOOT_LOADER_FLOPPY_PAGE
;
4213 /* Unattended install on hdd? */
4214 if (IsUnattendedSetup
&& UnattendMBRInstallType
== 2)
4216 return BOOT_LOADER_HARDDISK_MBR_PAGE
;
4219 MUIDisplayPage(BOOT_LOADER_PAGE
);
4220 CONSOLE_InvertTextXY(8, Line
, 60, 1);
4224 CONSOLE_ConInKey(Ir
);
4226 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
4227 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
)) /* DOWN */
4229 CONSOLE_NormalTextXY(8, Line
, 60, 1);
4238 CONSOLE_InvertTextXY(8, Line
, 60, 1);
4240 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
4241 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_UP
)) /* UP */
4243 CONSOLE_NormalTextXY(8, Line
, 60, 1);
4252 CONSOLE_InvertTextXY(8, Line
, 60, 1);
4254 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
4255 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
4257 if (ConfirmQuit(Ir
) == TRUE
)
4262 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
4266 return BOOT_LOADER_HARDDISK_MBR_PAGE
;
4268 else if (Line
== 13)
4270 return BOOT_LOADER_HARDDISK_VBR_PAGE
;
4272 else if (Line
== 14)
4274 return BOOT_LOADER_FLOPPY_PAGE
;
4276 else if (Line
== 15)
4278 return SUCCESS_PAGE
;
4281 return BOOT_LOADER_PAGE
;
4285 return BOOT_LOADER_PAGE
;
4290 * Displays the BootLoaderFloppyPage.
4293 * SuccessPage (At once)
4297 * Calls InstallFatBootcodeToFloppy()
4300 * Number of the next page.
4303 BootLoaderFloppyPage(PINPUT_RECORD Ir
)
4307 MUIDisplayPage(BOOT_LOADER_FLOPPY_PAGE
);
4309 // SetStatusText(" Please wait...");
4313 CONSOLE_ConInKey(Ir
);
4315 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
4316 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
4318 if (ConfirmQuit(Ir
) == TRUE
)
4323 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
4325 if (DoesFileExist(L
"\\Device\\Floppy0", L
"\\") == FALSE
)
4327 MUIDisplayError(ERROR_NO_FLOPPY
, Ir
, POPUP_WAIT_ENTER
);
4328 return BOOT_LOADER_FLOPPY_PAGE
;
4331 Status
= InstallFatBootcodeToFloppy(&SourceRootPath
, &DestinationArcPath
);
4332 if (!NT_SUCCESS(Status
))
4334 /* Print error message */
4335 return BOOT_LOADER_FLOPPY_PAGE
;
4338 return SUCCESS_PAGE
;
4342 return BOOT_LOADER_FLOPPY_PAGE
;
4347 * Displays the BootLoaderHarddiskVbrPage.
4350 * SuccessPage (At once)
4354 * Calls InstallVBRToPartition()
4357 * Number of the next page.
4360 BootLoaderHarddiskVbrPage(PINPUT_RECORD Ir
)
4362 UCHAR PartitionType
;
4365 PartitionType
= PartitionList
->BootPartition
->PartitionType
;
4367 Status
= InstallVBRToPartition(&SystemRootPath
,
4369 &DestinationArcPath
,
4371 if (!NT_SUCCESS(Status
))
4373 MUIDisplayError(ERROR_WRITE_BOOT
, Ir
, POPUP_WAIT_ENTER
);
4377 return SUCCESS_PAGE
;
4382 * Displays the BootLoaderHarddiskMbrPage.
4385 * SuccessPage (At once)
4389 * Calls InstallVBRToPartition()
4390 * CallsInstallMbrBootCodeToDisk()
4393 * Number of the next page.
4396 BootLoaderHarddiskMbrPage(PINPUT_RECORD Ir
)
4398 UCHAR PartitionType
;
4400 WCHAR DestinationDevicePathBuffer
[MAX_PATH
];
4401 WCHAR SourceMbrPathBuffer
[MAX_PATH
];
4403 /* Step 1: Write the VBR */
4404 PartitionType
= PartitionList
->BootPartition
->PartitionType
;
4406 Status
= InstallVBRToPartition(&SystemRootPath
,
4408 &DestinationArcPath
,
4410 if (!NT_SUCCESS(Status
))
4412 MUIDisplayError(ERROR_WRITE_BOOT
, Ir
, POPUP_WAIT_ENTER
);
4416 /* Step 2: Write the MBR */
4417 swprintf(DestinationDevicePathBuffer
,
4418 L
"\\Device\\Harddisk%d\\Partition0",
4419 PartitionList
->BootDisk
->DiskNumber
);
4421 wcscpy(SourceMbrPathBuffer
, SourceRootPath
.Buffer
);
4422 wcscat(SourceMbrPathBuffer
, L
"\\loader\\dosmbr.bin");
4424 DPRINT("Install MBR bootcode: %S ==> %S\n",
4425 SourceMbrPathBuffer
, DestinationDevicePathBuffer
);
4427 Status
= InstallMbrBootCodeToDisk(SourceMbrPathBuffer
,
4428 DestinationDevicePathBuffer
);
4429 if (!NT_SUCCESS (Status
))
4431 DPRINT1("InstallMbrBootCodeToDisk() failed (Status %lx)\n",
4433 MUIDisplayError(ERROR_INSTALL_BOOTCODE
, Ir
, POPUP_WAIT_ENTER
);
4437 return SUCCESS_PAGE
;
4442 * Displays the QuitPage.
4445 * FlushPage (At once)
4451 * Number of the next page.
4454 QuitPage(PINPUT_RECORD Ir
)
4456 MUIDisplayPage(QUIT_PAGE
);
4458 /* Destroy partition list */
4459 if (PartitionList
!= NULL
)
4461 DestroyPartitionList (PartitionList
);
4462 PartitionList
= NULL
;
4465 /* Destroy filesystem list */
4466 if (FileSystemList
!= NULL
)
4468 DestroyFileSystemList (FileSystemList
);
4469 FileSystemList
= NULL
;
4472 /* Destroy computer settings list */
4473 if (ComputerList
!= NULL
)
4475 DestroyGenericList(ComputerList
, TRUE
);
4476 ComputerList
= NULL
;
4479 /* Destroy display settings list */
4480 if (DisplayList
!= NULL
)
4482 DestroyGenericList(DisplayList
, TRUE
);
4486 /* Destroy keyboard settings list */
4487 if (KeyboardList
!= NULL
)
4489 DestroyGenericList(KeyboardList
, TRUE
);
4490 KeyboardList
= NULL
;
4493 /* Destroy keyboard layout list */
4494 if (LayoutList
!= NULL
)
4496 DestroyGenericList(LayoutList
, TRUE
);
4500 if (LanguageList
!= NULL
)
4502 DestroyGenericList(LanguageList
, FALSE
);
4503 LanguageList
= NULL
;
4506 CONSOLE_SetStatusText(MUIGetString(STRING_REBOOTCOMPUTER2
));
4510 CONSOLE_ConInKey(Ir
);
4512 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
4521 * Displays the SuccessPage.
4524 * FlushPage (At once)
4530 * Number of the next page.
4533 SuccessPage(PINPUT_RECORD Ir
)
4535 MUIDisplayPage(SUCCESS_PAGE
);
4537 if (IsUnattendedSetup
)
4544 CONSOLE_ConInKey(Ir
);
4546 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
4555 * Displays the FlushPage.
4558 * RebootPage (At once)
4561 * Number of the next page.
4564 FlushPage(PINPUT_RECORD Ir
)
4566 MUIDisplayPage(FLUSH_PAGE
);
4572 PnpEventThread(IN LPVOID lpParameter
);
4576 * The start routine and page management
4587 NtQuerySystemTime(&Time
);
4589 Status
= RtlCreateUserThread(NtCurrentProcess(),
4599 if (!NT_SUCCESS(Status
))
4600 hPnpThread
= INVALID_HANDLE_VALUE
;
4602 if (!CONSOLE_Init())
4604 PrintString(MUIGetString(STRING_CONSOLEFAIL1
));
4605 PrintString(MUIGetString(STRING_CONSOLEFAIL2
));
4606 PrintString(MUIGetString(STRING_CONSOLEFAIL3
));
4608 /* Raise a hard error (crash the system/BSOD) */
4609 NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED
,
4613 /* Initialize global unicode strings */
4614 RtlInitUnicodeString(&SourcePath
, NULL
);
4615 RtlInitUnicodeString(&SourceRootPath
, NULL
);
4616 RtlInitUnicodeString(&SourceRootDir
, NULL
);
4617 RtlInitUnicodeString(&InstallPath
, NULL
);
4618 RtlInitUnicodeString(&DestinationPath
, NULL
);
4619 RtlInitUnicodeString(&DestinationArcPath
, NULL
);
4620 RtlInitUnicodeString(&DestinationRootPath
, NULL
);
4621 RtlInitUnicodeString(&SystemRootPath
, NULL
);
4623 /* Hide the cursor */
4624 CONSOLE_SetCursorType(TRUE
, FALSE
);
4627 while (Page
!= REBOOT_PAGE
&& Page
!= RECOVERY_PAGE
)
4629 CONSOLE_ClearScreen();
4632 //CONSOLE_SetUnderlinedTextXY(4, 3, " ReactOS " KERNEL_VERSION_STR " Setup ");
4639 Page
= SetupStartPage(&Ir
);
4644 Page
= LanguagePage(&Ir
);
4649 Page
= LicensePage(&Ir
);
4654 Page
= IntroPage(&Ir
);
4658 case INSTALL_INTRO_PAGE
:
4659 Page
= InstallIntroPage(&Ir
);
4663 case SCSI_CONTROLLER_PAGE
:
4664 Page
= ScsiControllerPage(&Ir
);
4669 case OEM_DRIVER_PAGE
:
4670 Page
= OemDriverPage(&Ir
);
4674 case DEVICE_SETTINGS_PAGE
:
4675 Page
= DeviceSettingsPage(&Ir
);
4678 case COMPUTER_SETTINGS_PAGE
:
4679 Page
= ComputerSettingsPage(&Ir
);
4682 case DISPLAY_SETTINGS_PAGE
:
4683 Page
= DisplaySettingsPage(&Ir
);
4686 case KEYBOARD_SETTINGS_PAGE
:
4687 Page
= KeyboardSettingsPage(&Ir
);
4690 case LAYOUT_SETTINGS_PAGE
:
4691 Page
= LayoutSettingsPage(&Ir
);
4694 case SELECT_PARTITION_PAGE
:
4695 Page
= SelectPartitionPage(&Ir
);
4698 case CREATE_PRIMARY_PARTITION_PAGE
:
4699 Page
= CreatePrimaryPartitionPage(&Ir
);
4702 case CREATE_EXTENDED_PARTITION_PAGE
:
4703 Page
= CreateExtendedPartitionPage(&Ir
);
4706 case CREATE_LOGICAL_PARTITION_PAGE
:
4707 Page
= CreateLogicalPartitionPage(&Ir
);
4710 case CONFIRM_DELETE_SYSTEM_PARTITION_PAGE
:
4711 Page
= ConfirmDeleteSystemPartitionPage(&Ir
);
4714 case DELETE_PARTITION_PAGE
:
4715 Page
= DeletePartitionPage(&Ir
);
4718 case SELECT_FILE_SYSTEM_PAGE
:
4719 Page
= SelectFileSystemPage(&Ir
);
4722 case FORMAT_PARTITION_PAGE
:
4723 Page
= (PAGE_NUMBER
) FormatPartitionPage(&Ir
);
4726 case CHECK_FILE_SYSTEM_PAGE
:
4727 Page
= (PAGE_NUMBER
) CheckFileSystemPage(&Ir
);
4730 case INSTALL_DIRECTORY_PAGE
:
4731 Page
= InstallDirectoryPage(&Ir
);
4734 case PREPARE_COPY_PAGE
:
4735 Page
= PrepareCopyPage(&Ir
);
4738 case FILE_COPY_PAGE
:
4739 Page
= FileCopyPage(&Ir
);
4743 Page
= RegistryPage(&Ir
);
4746 case BOOT_LOADER_PAGE
:
4747 Page
= BootLoaderPage(&Ir
);
4750 case BOOT_LOADER_FLOPPY_PAGE
:
4751 Page
= BootLoaderFloppyPage(&Ir
);
4754 case BOOT_LOADER_HARDDISK_MBR_PAGE
:
4755 Page
= BootLoaderHarddiskMbrPage(&Ir
);
4758 case BOOT_LOADER_HARDDISK_VBR_PAGE
:
4759 Page
= BootLoaderHarddiskVbrPage(&Ir
);
4763 case REPAIR_INTRO_PAGE
:
4764 Page
= RepairIntroPage(&Ir
);
4768 Page
= SuccessPage(&Ir
);
4772 Page
= FlushPage(&Ir
);
4776 Page
= QuitPage(&Ir
);
4785 if (Page
== RECOVERY_PAGE
)
4790 /* Avoid bugcheck */
4791 Time
.QuadPart
+= 50000000;
4792 NtDelayExecution(FALSE
, &Time
);
4795 RtlAdjustPrivilege(SE_SHUTDOWN_PRIVILEGE
, TRUE
, FALSE
, &Old
);
4796 NtShutdownSystem(ShutdownReboot
);
4797 RtlAdjustPrivilege(SE_SHUTDOWN_PRIVILEGE
, Old
, FALSE
, &Old
);
4798 NtTerminateProcess(NtCurrentProcess(), 0);
4805 NtProcessStartup(PPEB Peb
)
4807 RtlNormalizeProcessParams(Peb
->ProcessParameters
);
4809 ProcessHeap
= Peb
->ProcessHeap
;
4810 InfSetHeap(ProcessHeap
);
4813 #endif /* __REACTOS__ */