3 * Copyright (C) 2002, 2003, 2004 ReactOS Team
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 * COPYRIGHT: See COPYING in the top level directory
21 * PROJECT: ReactOS text-mode setup
22 * FILE: subsys/system/usetup/usetup.c
23 * PURPOSE: Text-mode setup
24 * PROGRAMMER: Eric Kohl
25 * Casper S. Hornstrup (chorns@users.sourceforge.net)
26 * Hervé Poussineau (hpoussin@reactos.org)
35 /* GLOBALS ******************************************************************/
38 UNICODE_STRING SourceRootPath
;
39 UNICODE_STRING SourceRootDir
;
40 UNICODE_STRING SourcePath
;
41 BOOLEAN IsUnattendedSetup
= FALSE
;
42 LONG UnattendDestinationDiskNumber
;
43 LONG UnattendDestinationPartitionNumber
;
44 LONG UnattendMBRInstallType
= -1;
45 LONG UnattendFormatPartition
= 0;
46 LONG AutoPartition
= 0;
47 WCHAR UnattendInstallationDirectory
[MAX_PATH
];
48 PWCHAR SelectedLanguageId
;
50 WCHAR DefaultLanguage
[20];
51 WCHAR DefaultKBLayout
[20];
52 BOOLEAN RepairUpdateFlag
= FALSE
;
53 HANDLE hPnpThread
= INVALID_HANDLE_VALUE
;
54 PPARTLIST PartitionList
= NULL
;
56 /* LOCALS *******************************************************************/
58 static PFILE_SYSTEM_LIST FileSystemList
= NULL
;
60 static UNICODE_STRING InstallPath
;
62 /* Path to the install directory */
63 static UNICODE_STRING DestinationPath
;
64 static UNICODE_STRING DestinationArcPath
;
65 static UNICODE_STRING DestinationRootPath
;
67 /* Path to the active partition (boot manager) */
68 static UNICODE_STRING SystemRootPath
;
72 static HSPFILEQ SetupFileQueue
= NULL
;
74 static BOOLEAN WarnLinuxPartitions
= TRUE
;
76 static PGENERIC_LIST ComputerList
= NULL
;
77 static PGENERIC_LIST DisplayList
= NULL
;
78 static PGENERIC_LIST KeyboardList
= NULL
;
79 static PGENERIC_LIST LayoutList
= NULL
;
80 static PGENERIC_LIST LanguageList
= NULL
;
82 static LANGID LanguageId
= 0;
84 static ULONG RequiredPartitionDiskSpace
= ~0;
86 /* FUNCTIONS ****************************************************************/
89 PrintString(char* fmt
,...)
93 UNICODE_STRING UnicodeString
;
94 ANSI_STRING AnsiString
;
97 vsprintf(buffer
, fmt
, ap
);
100 RtlInitAnsiString(&AnsiString
, buffer
);
101 RtlAnsiStringToUnicodeString(&UnicodeString
, &AnsiString
, TRUE
);
102 NtDisplayString(&UnicodeString
);
103 RtlFreeUnicodeString(&UnicodeString
);
108 DrawBox(IN SHORT xLeft
,
116 /* draw upper left corner */
119 FillConsoleOutputCharacterA(StdOutput
,
125 /* draw upper edge */
128 FillConsoleOutputCharacterA(StdOutput
,
134 /* draw upper right corner */
135 coPos
.X
= xLeft
+ Width
- 1;
137 FillConsoleOutputCharacterA(StdOutput
,
143 /* Draw right edge, inner space and left edge */
144 for (coPos
.Y
= yTop
+ 1; coPos
.Y
< yTop
+ Height
- 1; coPos
.Y
++)
147 FillConsoleOutputCharacterA(StdOutput
,
154 FillConsoleOutputCharacterA(StdOutput
,
160 coPos
.X
= xLeft
+ Width
- 1;
161 FillConsoleOutputCharacterA(StdOutput
,
168 /* draw lower left corner */
170 coPos
.Y
= yTop
+ Height
- 1;
171 FillConsoleOutputCharacterA(StdOutput
,
177 /* draw lower edge */
179 coPos
.Y
= yTop
+ Height
- 1;
180 FillConsoleOutputCharacterA(StdOutput
,
186 /* draw lower right corner */
187 coPos
.X
= xLeft
+ Width
- 1;
188 coPos
.Y
= yTop
+ Height
- 1;
189 FillConsoleOutputCharacterA(StdOutput
,
198 PopupError(PCCH Text
,
216 /* Count text lines and longest line */
223 p
= strchr(pnext
, '\n');
227 Length
= strlen(pnext
);
232 Length
= (ULONG
)(p
- pnext
);
238 if (Length
> MaxLength
)
241 if (LastLine
== TRUE
)
247 /* Check length of status line */
250 Length
= strlen(Status
);
252 if (Length
> MaxLength
)
256 Width
= MaxLength
+ 4;
262 yTop
= (yScreen
- Height
) / 2;
263 xLeft
= (xScreen
- Width
) / 2;
266 /* Set screen attributes */
268 for (coPos
.Y
= yTop
; coPos
.Y
< yTop
+ Height
; coPos
.Y
++)
270 FillConsoleOutputAttribute(StdOutput
,
271 FOREGROUND_RED
| BACKGROUND_WHITE
,
277 DrawBox(xLeft
, yTop
, Width
, Height
);
279 /* Print message text */
284 p
= strchr(pnext
, '\n');
288 Length
= strlen(pnext
);
293 Length
= (ULONG
)(p
- pnext
);
300 WriteConsoleOutputCharacterA(StdOutput
,
307 if (LastLine
== TRUE
)
314 /* Print separator line and status text */
317 coPos
.Y
= yTop
+ Height
- 3;
319 FillConsoleOutputCharacterA(StdOutput
,
326 FillConsoleOutputCharacterA(StdOutput
,
332 coPos
.X
= xLeft
+ Width
- 1;
333 FillConsoleOutputCharacterA(StdOutput
,
341 WriteConsoleOutputCharacterA(StdOutput
,
343 min(strlen(Status
), (SIZE_T
)Width
- 4),
348 if (WaitEvent
== POPUP_WAIT_NONE
)
353 CONSOLE_ConInKey(Ir
);
355 if (WaitEvent
== POPUP_WAIT_ANY_KEY
||
356 Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D)
368 * FALSE: Don't quit setup.
371 ConfirmQuit(PINPUT_RECORD Ir
)
374 MUIDisplayError(ERROR_NOT_INSTALLED
, NULL
, POPUP_WAIT_NONE
);
378 CONSOLE_ConInKey(Ir
);
380 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
381 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
386 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
398 CheckUnattendedSetup(VOID
)
400 WCHAR UnattendInfPath
[MAX_PATH
];
407 if (DoesFileExist(SourcePath
.Buffer
, L
"unattend.inf") == FALSE
)
409 DPRINT("Does not exist: %S\\%S\n", SourcePath
.Buffer
, L
"unattend.inf");
413 wcscpy(UnattendInfPath
, SourcePath
.Buffer
);
414 wcscat(UnattendInfPath
, L
"\\unattend.inf");
416 /* Load 'unattend.inf' from install media. */
417 UnattendInf
= SetupOpenInfFileW(UnattendInfPath
,
423 if (UnattendInf
== INVALID_HANDLE_VALUE
)
425 DPRINT("SetupOpenInfFileW() failed\n");
429 /* Open 'Unattend' section */
430 if (!SetupFindFirstLineW(UnattendInf
, L
"Unattend", L
"Signature", &Context
))
432 DPRINT("SetupFindFirstLineW() failed for section 'Unattend'\n");
433 SetupCloseInfFile(UnattendInf
);
437 /* Get pointer 'Signature' key */
438 if (!INF_GetData(&Context
, NULL
, &Value
))
440 DPRINT("INF_GetData() failed for key 'Signature'\n");
441 SetupCloseInfFile(UnattendInf
);
445 /* Check 'Signature' string */
446 if (_wcsicmp(Value
, L
"$ReactOS$") != 0)
448 DPRINT("Signature not $ReactOS$\n");
449 SetupCloseInfFile(UnattendInf
);
453 /* Check if Unattend setup is enabled */
454 if (!SetupFindFirstLineW(UnattendInf
, L
"Unattend", L
"UnattendSetupEnabled", &Context
))
456 DPRINT("Can't find key 'UnattendSetupEnabled'\n");
457 SetupCloseInfFile(UnattendInf
);
461 if (!INF_GetData(&Context
, NULL
, &Value
))
463 DPRINT("Can't read key 'UnattendSetupEnabled'\n");
464 SetupCloseInfFile(UnattendInf
);
468 if (_wcsicmp(Value
, L
"yes") != 0)
470 DPRINT("Unattend setup is disabled by 'UnattendSetupEnabled' key!\n");
471 SetupCloseInfFile(UnattendInf
);
475 /* Search for 'DestinationDiskNumber' in the 'Unattend' section */
476 if (!SetupFindFirstLineW(UnattendInf
, L
"Unattend", L
"DestinationDiskNumber", &Context
))
478 DPRINT("SetupFindFirstLine() failed for key 'DestinationDiskNumber'\n");
479 SetupCloseInfFile(UnattendInf
);
483 if (!SetupGetIntField(&Context
, 1, &IntValue
))
485 DPRINT("SetupGetIntField() failed for key 'DestinationDiskNumber'\n");
486 SetupCloseInfFile(UnattendInf
);
490 UnattendDestinationDiskNumber
= (LONG
)IntValue
;
492 /* Search for 'DestinationPartitionNumber' in the 'Unattend' section */
493 if (!SetupFindFirstLineW(UnattendInf
, L
"Unattend", L
"DestinationPartitionNumber", &Context
))
495 DPRINT("SetupFindFirstLine() failed for key 'DestinationPartitionNumber'\n");
496 SetupCloseInfFile(UnattendInf
);
500 if (!SetupGetIntField(&Context
, 1, &IntValue
))
502 DPRINT("SetupGetIntField() failed for key 'DestinationPartitionNumber'\n");
503 SetupCloseInfFile(UnattendInf
);
507 UnattendDestinationPartitionNumber
= IntValue
;
509 /* Search for 'DestinationPartitionNumber' in the 'Unattend' section */
510 if (!SetupFindFirstLineW(UnattendInf
, L
"Unattend", L
"DestinationPartitionNumber", &Context
))
512 DPRINT("SetupFindFirstLine() failed for key 'DestinationPartitionNumber'\n");
513 SetupCloseInfFile(UnattendInf
);
517 /* Get pointer 'InstallationDirectory' key */
518 if (!INF_GetData(&Context
, NULL
, &Value
))
520 DPRINT("INF_GetData() failed for key 'InstallationDirectory'\n");
521 SetupCloseInfFile(UnattendInf
);
525 wcscpy(UnattendInstallationDirectory
, Value
);
527 IsUnattendedSetup
= TRUE
;
529 /* Search for 'MBRInstallType' in the 'Unattend' section */
530 if (SetupFindFirstLineW(UnattendInf
, L
"Unattend", L
"MBRInstallType", &Context
))
532 if (SetupGetIntField(&Context
, 1, &IntValue
))
534 UnattendMBRInstallType
= IntValue
;
538 /* Search for 'FormatPartition' in the 'Unattend' section */
539 if (SetupFindFirstLineW(UnattendInf
, L
"Unattend", L
"FormatPartition", &Context
))
541 if (SetupGetIntField(&Context
, 1, &IntValue
))
543 UnattendFormatPartition
= IntValue
;
547 if (SetupFindFirstLineW(UnattendInf
, L
"Unattend", L
"AutoPartition", &Context
))
549 if (SetupGetIntField(&Context
, 1, &IntValue
))
551 AutoPartition
= IntValue
;
555 /* search for LocaleID in the 'Unattend' section*/
556 if (SetupFindFirstLineW (UnattendInf
, L
"Unattend", L
"LocaleID", &Context
))
558 if (INF_GetData (&Context
, NULL
, &Value
))
560 LONG Id
= wcstol(Value
, NULL
, 16);
561 swprintf(LocaleID
,L
"%08lx", Id
);
565 SetupCloseInfFile(UnattendInf
);
567 DPRINT("Running unattended setup\n");
574 PGENERIC_LIST_ENTRY ListEntry
;
575 LPCWSTR pszNewLayout
;
577 pszNewLayout
= MUIDefaultKeyboardLayout();
579 if (LayoutList
== NULL
)
581 LayoutList
= CreateKeyboardLayoutList(SetupInf
, DefaultKBLayout
);
582 if (LayoutList
== NULL
)
584 /* FIXME: Handle error! */
589 ListEntry
= GetFirstListEntry(LayoutList
);
591 /* Search for default layout (if provided) */
592 if (pszNewLayout
!= NULL
)
594 while (ListEntry
!= NULL
)
596 if (!wcscmp(pszNewLayout
, GetListEntryUserData(ListEntry
)))
598 SetCurrentListEntry(LayoutList
, ListEntry
);
602 ListEntry
= GetNextListEntry(ListEntry
);
609 LanguagePage(PINPUT_RECORD Ir
)
611 /* Initialize the computer settings list */
612 if (LanguageList
== NULL
)
614 LanguageList
= CreateLanguageList(SetupInf
, DefaultLanguage
);
616 if (LanguageList
== NULL
)
618 PopupError("Setup failed to initialize available translations", NULL
, NULL
, POPUP_WAIT_NONE
);
623 DrawGenericList(LanguageList
,
629 ScrollToPositionGenericList (LanguageList
, GetDefaultLanguageIndex());
631 MUIDisplayPage(LANGUAGE_PAGE
);
635 CONSOLE_ConInKey(Ir
);
637 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
638 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
)) /* DOWN */
641 SelectedLanguageId
= (PWCHAR
)GetListEntryUserData(GetCurrentListEntry(LanguageList
));
643 /* Redraw language selection page in native language */
644 MUIDisplayPage(LANGUAGE_PAGE
);
647 ScrollDownGenericList (LanguageList
);
649 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
650 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_UP
)) /* UP */
653 SelectedLanguageId
= (PWCHAR
)GetListEntryUserData(GetCurrentListEntry(LanguageList
));
655 /* Redraw language selection page in native language */
656 MUIDisplayPage(LANGUAGE_PAGE
);
659 ScrollUpGenericList(LanguageList
);
661 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
662 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_NEXT
)) /* PAGE DOWN */
664 ScrollPageDownGenericList(LanguageList
);
666 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
667 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_PRIOR
)) /* PAGE UP */
669 ScrollPageUpGenericList(LanguageList
);
671 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
672 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
674 if (ConfirmQuit(Ir
) == TRUE
)
677 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
679 SelectedLanguageId
= (PWCHAR
)GetListEntryUserData(GetCurrentListEntry(LanguageList
));
681 LanguageId
= (LANGID
)(wcstol(SelectedLanguageId
, NULL
, 16) & 0xFFFF);
683 if (wcscmp(SelectedLanguageId
, DefaultLanguage
))
689 SetConsoleCodePage();
693 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
> 0x60) && (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
< 0x7b))
696 GenericListKeyPress (LanguageList
, Ir
->Event
.KeyEvent
.uChar
.AsciiChar
);
707 * Number of the next page.
710 SetupStartPage(PINPUT_RECORD Ir
)
712 SYSTEM_DEVICE_INFORMATION Sdi
;
714 WCHAR FileNameBuffer
[MAX_PATH
];
719 PGENERIC_LIST_ENTRY ListEntry
;
722 CONSOLE_SetStatusText(MUIGetString(STRING_PLEASEWAIT
));
725 /* Check whether a harddisk is available */
726 Status
= NtQuerySystemInformation(SystemDeviceInformation
,
728 sizeof(SYSTEM_DEVICE_INFORMATION
),
731 if (!NT_SUCCESS(Status
))
733 CONSOLE_PrintTextXY(6, 15, "NtQuerySystemInformation() failed (Status 0x%08lx)", Status
);
734 MUIDisplayError(ERROR_DRIVE_INFORMATION
, Ir
, POPUP_WAIT_ENTER
);
738 if (Sdi
.NumberOfDisks
== 0)
740 MUIDisplayError(ERROR_NO_HDD
, Ir
, POPUP_WAIT_ENTER
);
744 /* Get the source path and source root path */
745 Status
= GetSourcePaths(&SourcePath
,
749 if (!NT_SUCCESS(Status
))
751 CONSOLE_PrintTextXY(6, 15, "GetSourcePaths() failed (Status 0x%08lx)", Status
);
752 MUIDisplayError(ERROR_NO_SOURCE_DRIVE
, Ir
, POPUP_WAIT_ENTER
);
758 CONSOLE_PrintTextXY(6, 15, "SourcePath: '%wZ'", &SourcePath
);
759 CONSOLE_PrintTextXY(6, 16, "SourceRootPath: '%wZ'", &SourceRootPath
);
760 CONSOLE_PrintTextXY(6, 17, "SourceRootDir: '%wZ'", &SourceRootDir
);
764 /* Load txtsetup.sif from install media. */
765 wcscpy(FileNameBuffer
, SourcePath
.Buffer
);
766 wcscat(FileNameBuffer
, L
"\\txtsetup.sif");
768 SetupInf
= SetupOpenInfFileW(FileNameBuffer
,
774 if (SetupInf
== INVALID_HANDLE_VALUE
)
776 MUIDisplayError(ERROR_LOAD_TXTSETUPSIF
, Ir
, POPUP_WAIT_ENTER
);
780 /* Open 'Version' section */
781 if (!SetupFindFirstLineW(SetupInf
, L
"Version", L
"Signature", &Context
))
783 MUIDisplayError(ERROR_CORRUPT_TXTSETUPSIF
, Ir
, POPUP_WAIT_ENTER
);
787 /* Get pointer 'Signature' key */
788 if (!INF_GetData(&Context
, NULL
, &Value
))
790 MUIDisplayError(ERROR_CORRUPT_TXTSETUPSIF
, Ir
, POPUP_WAIT_ENTER
);
794 /* Check 'Signature' string */
795 if (_wcsicmp(Value
, L
"$ReactOS$") != 0)
797 MUIDisplayError(ERROR_SIGNATURE_TXTSETUPSIF
, Ir
, POPUP_WAIT_ENTER
);
801 /* Open 'DiskSpaceRequirements' section */
802 if (!SetupFindFirstLineW(SetupInf
, L
"DiskSpaceRequirements", L
"FreeSysPartDiskSpace", &Context
))
804 MUIDisplayError(ERROR_CORRUPT_TXTSETUPSIF
, Ir
, POPUP_WAIT_ENTER
);
808 /* Get the 'FreeSysPartDiskSpace' value */
809 if (!SetupGetIntField(&Context
, 1, &IntValue
))
811 MUIDisplayError(ERROR_CORRUPT_TXTSETUPSIF
, Ir
, POPUP_WAIT_ENTER
);
815 RequiredPartitionDiskSpace
= (ULONG
)IntValue
;
817 /* Start PnP thread */
818 if (hPnpThread
!= INVALID_HANDLE_VALUE
)
820 NtResumeThread(hPnpThread
, NULL
);
821 hPnpThread
= INVALID_HANDLE_VALUE
;
824 CheckUnattendedSetup();
826 if (IsUnattendedSetup
)
829 //read options from inf
830 ComputerList
= CreateComputerTypeList(SetupInf
);
831 DisplayList
= CreateDisplayDriverList(SetupInf
);
832 KeyboardList
= CreateKeyboardDriverList(SetupInf
);
833 LayoutList
= CreateKeyboardLayoutList(SetupInf
, DefaultKBLayout
);
834 LanguageList
= CreateLanguageList(SetupInf
, DefaultLanguage
);
837 wcscpy(SelectedLanguageId
,LocaleID
);
839 /* first we hack LanguageList */
840 ListEntry
= GetFirstListEntry(LanguageList
);
842 while (ListEntry
!= NULL
)
844 if (!wcsicmp(LocaleID
, GetListEntryUserData(ListEntry
)))
846 DPRINT("found %S in LanguageList\n",GetListEntryUserData(ListEntry
));
847 SetCurrentListEntry(LanguageList
, ListEntry
);
851 ListEntry
= GetNextListEntry(ListEntry
);
855 ListEntry
= GetFirstListEntry(LayoutList
);
857 while (ListEntry
!= NULL
)
859 if (!wcsicmp(LocaleID
, GetListEntryUserData(ListEntry
)))
861 DPRINT("found %S in LayoutList\n",GetListEntryUserData(ListEntry
));
862 SetCurrentListEntry(LayoutList
, ListEntry
);
866 ListEntry
= GetNextListEntry(ListEntry
);
869 SetConsoleCodePage();
871 return INSTALL_INTRO_PAGE
;
874 return LANGUAGE_PAGE
;
884 IntroPage(PINPUT_RECORD Ir
)
886 MUIDisplayPage(START_PAGE
);
890 CONSOLE_ConInKey(Ir
);
892 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
893 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
895 if (ConfirmQuit(Ir
) == TRUE
)
900 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
902 return INSTALL_INTRO_PAGE
;
905 else if (toupper(Ir
->Event
.KeyEvent
.uChar
.AsciiChar
) == 'R') /* R */
907 return REPAIR_INTRO_PAGE
;
910 else if (toupper(Ir
->Event
.KeyEvent
.uChar
.AsciiChar
) == 'L') /* R */
924 * Back to main setup page.
927 LicensePage(PINPUT_RECORD Ir
)
929 MUIDisplayPage(LICENSE_PAGE
);
933 CONSOLE_ConInKey(Ir
);
935 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
947 RepairIntroPage(PINPUT_RECORD Ir
)
949 MUIDisplayPage(REPAIR_INTRO_PAGE
);
953 CONSOLE_ConInKey(Ir
);
955 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
959 else if (toupper(Ir
->Event
.KeyEvent
.uChar
.AsciiChar
) == 'U') /* U */
961 RepairUpdateFlag
= TRUE
;
962 return INSTALL_INTRO_PAGE
;
964 else if (toupper(Ir
->Event
.KeyEvent
.uChar
.AsciiChar
) == 'R') /* R */
968 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
969 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
)) /* ESC */
975 return REPAIR_INTRO_PAGE
;
980 InstallIntroPage(PINPUT_RECORD Ir
)
982 MUIDisplayPage(INSTALL_INTRO_PAGE
);
984 if (RepairUpdateFlag
)
986 //return SELECT_PARTITION_PAGE;
987 return DEVICE_SETTINGS_PAGE
;
990 if (IsUnattendedSetup
)
992 return SELECT_PARTITION_PAGE
;
997 CONSOLE_ConInKey(Ir
);
999 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1000 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1002 if (ConfirmQuit(Ir
) == TRUE
)
1007 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
1009 return DEVICE_SETTINGS_PAGE
;
1010 // return SCSI_CONTROLLER_PAGE;
1014 return INSTALL_INTRO_PAGE
;
1020 ScsiControllerPage(PINPUT_RECORD Ir
)
1022 SetTextXY(6, 8, "Setup detected the following mass storage devices:");
1024 /* FIXME: print loaded mass storage driver descriptions */
1026 SetTextXY(8, 10, "TEST device");
1030 SetStatusText(" ENTER = Continue F3 = Quit");
1036 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1037 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1039 if (ConfirmQuit(Ir
) == TRUE
)
1044 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
1046 return DEVICE_SETTINGS_PAGE
;
1050 return SCSI_CONTROLLER_PAGE
;
1056 DeviceSettingsPage(PINPUT_RECORD Ir
)
1058 static ULONG Line
= 16;
1059 MUIDisplayPage(DEVICE_SETTINGS_PAGE
);
1061 /* Initialize the computer settings list */
1062 if (ComputerList
== NULL
)
1064 ComputerList
= CreateComputerTypeList(SetupInf
);
1065 if (ComputerList
== NULL
)
1067 MUIDisplayError(ERROR_LOAD_COMPUTER
, Ir
, POPUP_WAIT_ENTER
);
1072 /* Initialize the display settings list */
1073 if (DisplayList
== NULL
)
1075 DisplayList
= CreateDisplayDriverList(SetupInf
);
1076 if (DisplayList
== NULL
)
1078 MUIDisplayError(ERROR_LOAD_DISPLAY
, Ir
, POPUP_WAIT_ENTER
);
1083 /* Initialize the keyboard settings list */
1084 if (KeyboardList
== NULL
)
1086 KeyboardList
= CreateKeyboardDriverList(SetupInf
);
1087 if (KeyboardList
== NULL
)
1089 MUIDisplayError(ERROR_LOAD_KEYBOARD
, Ir
, POPUP_WAIT_ENTER
);
1094 /* Initialize the keyboard layout list */
1095 if (LayoutList
== NULL
)
1097 LayoutList
= CreateKeyboardLayoutList(SetupInf
, DefaultKBLayout
);
1098 if (LayoutList
== NULL
)
1100 /* FIXME: report error */
1101 MUIDisplayError(ERROR_LOAD_KBLAYOUT
, Ir
, POPUP_WAIT_ENTER
);
1106 MUIDisplayPage(DEVICE_SETTINGS_PAGE
);
1109 CONSOLE_SetTextXY(25, 11, GetListEntryText(GetCurrentListEntry((ComputerList
))));
1110 CONSOLE_SetTextXY(25, 12, GetListEntryText(GetCurrentListEntry((DisplayList
))));
1111 CONSOLE_SetTextXY(25, 13, GetListEntryText(GetCurrentListEntry((KeyboardList
))));
1112 CONSOLE_SetTextXY(25, 14, GetListEntryText(GetCurrentListEntry((LayoutList
))));
1114 CONSOLE_InvertTextXY(24, Line
, 48, 1);
1116 if (RepairUpdateFlag
)
1118 return SELECT_PARTITION_PAGE
;
1123 CONSOLE_ConInKey(Ir
);
1125 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1126 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
)) /* DOWN */
1128 CONSOLE_NormalTextXY(24, Line
, 48, 1);
1132 else if (Line
== 16)
1137 CONSOLE_InvertTextXY(24, Line
, 48, 1);
1139 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1140 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_UP
)) /* UP */
1142 CONSOLE_NormalTextXY(24, Line
, 48, 1);
1146 else if (Line
== 16)
1151 CONSOLE_InvertTextXY(24, Line
, 48, 1);
1153 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1154 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1156 if (ConfirmQuit(Ir
) == TRUE
)
1161 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
1164 return COMPUTER_SETTINGS_PAGE
;
1165 else if (Line
== 12)
1166 return DISPLAY_SETTINGS_PAGE
;
1167 else if (Line
== 13)
1168 return KEYBOARD_SETTINGS_PAGE
;
1169 else if (Line
== 14)
1170 return LAYOUT_SETTINGS_PAGE
;
1171 else if (Line
== 16)
1172 return SELECT_PARTITION_PAGE
;
1176 return DEVICE_SETTINGS_PAGE
;
1181 ComputerSettingsPage(PINPUT_RECORD Ir
)
1183 MUIDisplayPage(COMPUTER_SETTINGS_PAGE
);
1185 DrawGenericList(ComputerList
,
1191 SaveGenericListState(ComputerList
);
1195 CONSOLE_ConInKey(Ir
);
1197 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1198 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
)) /* DOWN */
1200 ScrollDownGenericList(ComputerList
);
1202 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1203 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_UP
)) /* UP */
1205 ScrollUpGenericList(ComputerList
);
1207 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1208 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1210 if (ConfirmQuit(Ir
) == TRUE
)
1215 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1216 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
)) /* ESC */
1218 RestoreGenericListState(ComputerList
);
1219 return DEVICE_SETTINGS_PAGE
;
1221 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
1223 return DEVICE_SETTINGS_PAGE
;
1227 return COMPUTER_SETTINGS_PAGE
;
1232 DisplaySettingsPage(PINPUT_RECORD Ir
)
1234 MUIDisplayPage(DISPLAY_SETTINGS_PAGE
);
1236 DrawGenericList(DisplayList
,
1242 SaveGenericListState(DisplayList
);
1246 CONSOLE_ConInKey(Ir
);
1248 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1249 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
)) /* DOWN */
1251 ScrollDownGenericList(DisplayList
);
1253 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1254 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_UP
)) /* UP */
1256 ScrollUpGenericList(DisplayList
);
1258 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1259 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1261 if (ConfirmQuit(Ir
) == TRUE
)
1268 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1269 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
)) /* ESC */
1271 RestoreGenericListState(DisplayList
);
1272 return DEVICE_SETTINGS_PAGE
;
1274 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
1276 return DEVICE_SETTINGS_PAGE
;
1280 return DISPLAY_SETTINGS_PAGE
;
1285 KeyboardSettingsPage(PINPUT_RECORD Ir
)
1287 MUIDisplayPage(KEYBOARD_SETTINGS_PAGE
);
1289 DrawGenericList(KeyboardList
,
1295 SaveGenericListState(KeyboardList
);
1299 CONSOLE_ConInKey(Ir
);
1301 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1302 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
)) /* DOWN */
1304 ScrollDownGenericList(KeyboardList
);
1306 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1307 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_UP
)) /* UP */
1309 ScrollUpGenericList(KeyboardList
);
1311 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1312 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1314 if (ConfirmQuit(Ir
) == TRUE
)
1319 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1320 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
)) /* ESC */
1322 RestoreGenericListState(KeyboardList
);
1323 return DEVICE_SETTINGS_PAGE
;
1325 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
1327 return DEVICE_SETTINGS_PAGE
;
1331 return DISPLAY_SETTINGS_PAGE
;
1336 LayoutSettingsPage(PINPUT_RECORD Ir
)
1338 MUIDisplayPage(LAYOUT_SETTINGS_PAGE
);
1340 DrawGenericList(LayoutList
,
1346 SaveGenericListState(LayoutList
);
1350 CONSOLE_ConInKey(Ir
);
1352 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1353 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
)) /* DOWN */
1355 ScrollDownGenericList(LayoutList
);
1357 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1358 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_UP
)) /* UP */
1360 ScrollUpGenericList(LayoutList
);
1362 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1363 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_NEXT
)) /* PAGE DOWN */
1365 ScrollPageDownGenericList(LayoutList
);
1367 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1368 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_PRIOR
)) /* PAGE UP */
1370 ScrollPageUpGenericList(LayoutList
);
1372 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1373 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1375 if (ConfirmQuit(Ir
) == TRUE
)
1380 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1381 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
)) /* ESC */
1383 RestoreGenericListState(LayoutList
);
1384 return DEVICE_SETTINGS_PAGE
;
1386 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
1388 return DEVICE_SETTINGS_PAGE
;
1390 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
> 0x60) && (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
< 0x7b))
1393 GenericListKeyPress(LayoutList
, Ir
->Event
.KeyEvent
.uChar
.AsciiChar
);
1397 return DISPLAY_SETTINGS_PAGE
;
1402 IsDiskSizeValid(PPARTENTRY PartEntry
)
1406 /* check for unpartitioned space */
1407 m
= PartEntry
->UnpartitionedLength
;
1408 m
= (m
+ (1 << 19)) >> 20; /* in MBytes (rounded) */
1409 if( m
> RequiredPartitionDiskSpace
)
1414 /* check for partitioned space */
1415 m
= PartEntry
->PartInfo
[0].PartitionLength
.QuadPart
;
1416 m
= (m
+ (1 << 19)) >> 20; /* in MBytes (rounded) */
1417 if (m
< RequiredPartitionDiskSpace
)
1419 /* partition is too small so ask for another partion */
1420 DPRINT1("Partition is too small, required disk space is %lu MB\n", RequiredPartitionDiskSpace
);
1431 SelectPartitionPage(PINPUT_RECORD Ir
)
1433 MUIDisplayPage(SELECT_PARTITION_PAGE
);
1435 if (PartitionList
== NULL
)
1437 PartitionList
= CreatePartitionList(2,
1441 if (PartitionList
== NULL
)
1443 /* FIXME: show an error dialog */
1448 CheckActiveBootPartition(PartitionList
);
1450 DrawPartitionList(PartitionList
);
1452 /* Warn about partitions created by Linux Fdisk */
1453 if (WarnLinuxPartitions
== TRUE
&&
1454 CheckForLinuxFdiskPartitions(PartitionList
) == TRUE
)
1456 MUIDisplayError(ERROR_WARN_PARTITION
, NULL
, POPUP_WAIT_NONE
);
1460 CONSOLE_ConInKey(Ir
);
1462 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1463 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1467 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_RETURN
) /* ENTER */
1469 WarnLinuxPartitions
= FALSE
;
1470 return SELECT_PARTITION_PAGE
;
1475 if (IsUnattendedSetup
)
1477 if (!SelectPartition(PartitionList
, UnattendDestinationDiskNumber
, UnattendDestinationPartitionNumber
))
1481 PPARTENTRY PartEntry
= PartitionList
->CurrentPartition
;
1482 ULONG MaxSize
= (PartEntry
->UnpartitionedLength
+ (1 << 19)) >> 20; /* in MBytes (rounded) */
1483 if(!IsDiskSizeValid(PartitionList
->CurrentPartition
))
1485 MUIDisplayError(ERROR_INSUFFICIENT_DISKSPACE
, Ir
, POPUP_WAIT_ANY_KEY
);
1486 return SELECT_PARTITION_PAGE
; /* let the user select another partition */
1489 CreateNewPartition(PartitionList
,
1493 return SELECT_FILE_SYSTEM_PAGE
;
1498 if(!IsDiskSizeValid(PartitionList
->CurrentPartition
))
1500 MUIDisplayError(ERROR_INSUFFICIENT_DISKSPACE
, Ir
, POPUP_WAIT_ANY_KEY
);
1501 return SELECT_PARTITION_PAGE
; /* let the user select another partition */
1504 return SELECT_FILE_SYSTEM_PAGE
;
1510 /* Update status text */
1511 if (PartitionList
->CurrentPartition
== NULL
||
1512 PartitionList
->CurrentPartition
->Unpartitioned
== TRUE
)
1514 CONSOLE_SetStatusText(MUIGetString(STRING_INSTALLCREATEPARTITION
));
1518 CONSOLE_SetStatusText(MUIGetString(STRING_INSTALLDELETEPARTITION
));
1521 CONSOLE_ConInKey(Ir
);
1523 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1524 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1526 if (ConfirmQuit(Ir
) == TRUE
)
1528 DestroyPartitionList(PartitionList
);
1529 PartitionList
= NULL
;
1535 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1536 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
)) /* DOWN */
1538 ScrollDownPartitionList(PartitionList
);
1540 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1541 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_UP
)) /* UP */
1543 ScrollUpPartitionList(PartitionList
);
1545 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_RETURN
) /* ENTER */
1547 if(!IsDiskSizeValid(PartitionList
->CurrentPartition
))
1549 MUIDisplayError(ERROR_INSUFFICIENT_DISKSPACE
, Ir
, POPUP_WAIT_ANY_KEY
);
1550 return SELECT_PARTITION_PAGE
; /* let the user select another partition */
1552 if (PartitionList
->CurrentPartition
== NULL
||
1553 PartitionList
->CurrentPartition
->Unpartitioned
== TRUE
)
1555 CreateNewPartition(PartitionList
,
1560 return SELECT_FILE_SYSTEM_PAGE
;
1562 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== 'C') /* C */
1564 if (PartitionList
->CurrentPartition
->Unpartitioned
== FALSE
)
1566 MUIDisplayError(ERROR_NEW_PARTITION
, Ir
, POPUP_WAIT_ANY_KEY
);
1567 return SELECT_PARTITION_PAGE
;
1570 return CREATE_PARTITION_PAGE
;
1572 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== 'D') /* D */
1574 if (PartitionList
->CurrentPartition
->Unpartitioned
== TRUE
)
1576 MUIDisplayError(ERROR_DELETE_SPACE
, Ir
, POPUP_WAIT_ANY_KEY
);
1577 return SELECT_PARTITION_PAGE
;
1580 return DELETE_PARTITION_PAGE
;
1584 return SELECT_PARTITION_PAGE
;
1589 DrawInputField(ULONG FieldLength
,
1600 memset(buf
, '_', sizeof(buf
));
1601 buf
[FieldLength
- strlen(FieldContent
)] = 0;
1602 strcat(buf
, FieldContent
);
1604 WriteConsoleOutputCharacterA(StdOutput
,
1612 #define PARTITION_SIZE_INPUT_FIELD_LENGTH 6
1613 /* Restriction for MaxSize: pow(10, PARTITION_SIZE_INPUT_FIELD_LENGTH)-1 */
1614 #define PARTITION_MAXSIZE 999999
1617 ShowPartitionSizeInputBox(SHORT Left
,
1641 DrawBox(Left
, Top
, Right
- Left
+ 1, Bottom
- Top
+ 1);
1646 strcpy(Buffer
, MUIGetString(STRING_PARTITIONSIZE
));
1647 iLeft
= coPos
.X
+ strlen(Buffer
) + 1;
1650 WriteConsoleOutputCharacterA(StdOutput
,
1656 sprintf(Buffer
, MUIGetString(STRING_MAXSIZE
), MaxSize
);
1657 coPos
.X
= iLeft
+ PARTITION_SIZE_INPUT_FIELD_LENGTH
+ 1;
1659 WriteConsoleOutputCharacterA(StdOutput
,
1665 sprintf(Buffer
, "%lu", MaxSize
);
1666 Index
= strlen(Buffer
);
1667 DrawInputField(PARTITION_SIZE_INPUT_FIELD_LENGTH
,
1674 CONSOLE_ConInKey(&Ir
);
1676 if ((Ir
.Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1677 (Ir
.Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1685 else if (Ir
.Event
.KeyEvent
.wVirtualKeyCode
== VK_RETURN
) /* ENTER */
1689 else if (Ir
.Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
) /* ESCAPE */
1697 else if ((Ir
.Event
.KeyEvent
.wVirtualKeyCode
== VK_BACK
) && /* BACKSPACE */
1703 DrawInputField(PARTITION_SIZE_INPUT_FIELD_LENGTH
,
1708 else if ((Ir
.Event
.KeyEvent
.uChar
.AsciiChar
!= 0x00) &&
1709 (Index
< PARTITION_SIZE_INPUT_FIELD_LENGTH
))
1711 ch
= Ir
.Event
.KeyEvent
.uChar
.AsciiChar
;
1713 if ((ch
>= '0') && (ch
<= '9'))
1719 DrawInputField(PARTITION_SIZE_INPUT_FIELD_LENGTH
,
1727 strcpy(InputBuffer
, Buffer
);
1732 CreatePartitionPage(PINPUT_RECORD Ir
)
1734 PDISKENTRY DiskEntry
;
1735 PPARTENTRY PartEntry
;
1738 CHAR InputBuffer
[50];
1744 if (PartitionList
== NULL
||
1745 PartitionList
->CurrentDisk
== NULL
||
1746 PartitionList
->CurrentPartition
== NULL
)
1748 /* FIXME: show an error dialog */
1752 DiskEntry
= PartitionList
->CurrentDisk
;
1753 PartEntry
= PartitionList
->CurrentPartition
;
1755 CONSOLE_SetStatusText(MUIGetString(STRING_PLEASEWAIT
));
1757 CONSOLE_SetTextXY(6, 8, MUIGetString(STRING_CHOOSENEWPARTITION
));
1760 if (DiskEntry
->DiskSize
>= 0x280000000ULL
) /* 10 GB */
1762 DiskSize
= (DiskEntry
->DiskSize
+ (1 << 29)) >> 30;
1763 Unit
= MUIGetString(STRING_GB
);
1768 DiskSize
= (DiskEntry
->DiskSize
+ (1 << 19)) >> 20;
1773 Unit
= MUIGetString(STRING_MB
);
1776 if (DiskEntry
->DriverName
.Length
> 0)
1778 CONSOLE_PrintTextXY(6, 10,
1779 MUIGetString(STRING_HDINFOPARTCREATE
),
1782 DiskEntry
->DiskNumber
,
1786 &DiskEntry
->DriverName
);
1790 CONSOLE_PrintTextXY(6, 10,
1791 MUIGetString(STRING_HDDINFOUNK1
),
1794 DiskEntry
->DiskNumber
,
1800 CONSOLE_SetTextXY(6, 12, MUIGetString(STRING_HDDSIZE
));
1803 CONSOLE_PrintTextXY(8, 10, "Maximum size of the new partition is %I64u MB",
1804 PartitionList
->CurrentPartition
->UnpartitionedLength
/ (1024*1024));
1807 CONSOLE_SetStatusText(MUIGetString(STRING_CREATEPARTITION
));
1809 PartEntry
= PartitionList
->CurrentPartition
;
1812 MaxSize
= (PartEntry
->UnpartitionedLength
+ (1 << 19)) >> 20; /* in MBytes (rounded) */
1814 if (MaxSize
> PARTITION_MAXSIZE
) MaxSize
= PARTITION_MAXSIZE
;
1816 ShowPartitionSizeInputBox(12, 14, xScreen
- 12, 17, /* left, top, right, bottom */
1817 MaxSize
, InputBuffer
, &Quit
, &Cancel
);
1821 if (ConfirmQuit (Ir
) == TRUE
)
1826 else if (Cancel
== TRUE
)
1828 return SELECT_PARTITION_PAGE
;
1832 PartSize
= atoi(InputBuffer
);
1840 if (PartSize
> MaxSize
)
1846 /* Convert to bytes */
1847 if (PartSize
== MaxSize
)
1849 /* Use all of the unpartitioned disk space */
1850 PartSize
= PartEntry
->UnpartitionedLength
;
1854 /* Round-up by cylinder size */
1855 PartSize
= (PartSize
* 1024 * 1024 + DiskEntry
->CylinderSize
- 1) /
1856 DiskEntry
->CylinderSize
* DiskEntry
->CylinderSize
;
1858 /* But never get larger than the unpartitioned disk space */
1859 if (PartSize
> PartEntry
->UnpartitionedLength
)
1860 PartSize
= PartEntry
->UnpartitionedLength
;
1863 DPRINT ("Partition size: %I64u bytes\n", PartSize
);
1865 CreateNewPartition(PartitionList
,
1869 return SELECT_PARTITION_PAGE
;
1873 return CREATE_PARTITION_PAGE
;
1878 DeletePartitionPage(PINPUT_RECORD Ir
)
1880 PDISKENTRY DiskEntry
;
1881 PPARTENTRY PartEntry
;
1888 if (PartitionList
== NULL
||
1889 PartitionList
->CurrentDisk
== NULL
||
1890 PartitionList
->CurrentPartition
== NULL
)
1892 /* FIXME: show an error dialog */
1896 DiskEntry
= PartitionList
->CurrentDisk
;
1897 PartEntry
= PartitionList
->CurrentPartition
;
1898 PartNumber
= PartitionList
->CurrentPartitionNumber
;
1900 MUIDisplayPage(DELETE_PARTITION_PAGE
);
1902 /* Determine partition type */
1904 if (PartEntry
->New
== TRUE
)
1906 PartType
= MUIGetString(STRING_UNFORMATTED
);
1908 else if (PartEntry
->Unpartitioned
== FALSE
)
1910 if ((PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_FAT_12
) ||
1911 (PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_FAT_16
) ||
1912 (PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_HUGE
) ||
1913 (PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_XINT13
))
1917 else if ((PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_FAT32
) ||
1918 (PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_FAT32_XINT13
))
1922 else if (PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_EXT2
)
1926 else if (PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_IFS
)
1928 PartType
= "NTFS"; /* FIXME: Not quite correct! */
1933 if (PartEntry
->PartInfo
[PartNumber
].PartitionLength
.QuadPart
>= 0x280000000LL
) /* 10 GB */
1935 PartSize
= (PartEntry
->PartInfo
[PartNumber
].PartitionLength
.QuadPart
+ (1 << 29)) >> 30;
1936 Unit
= MUIGetString(STRING_GB
);
1940 if (PartEntry
->PartInfo
[PartNumber
].PartitionLength
.QuadPart
>= 0xA00000LL
) /* 10 MB */
1942 PartSize
= (PartEntry
->PartInfo
[PartNumber
].PartitionLength
.QuadPart
+ (1 << 19)) >> 20;
1943 Unit
= MUIGetString(STRING_MB
);
1947 PartSize
= (PartEntry
->PartInfo
[PartNumber
].PartitionLength
.QuadPart
+ (1 << 9)) >> 10;
1948 Unit
= MUIGetString(STRING_KB
);
1951 if (PartType
== NULL
)
1953 CONSOLE_PrintTextXY(6, 10,
1954 MUIGetString(STRING_HDDINFOUNK2
),
1955 (PartEntry
->DriveLetter
[PartNumber
] == 0) ? '-' : PartEntry
->DriveLetter
[PartNumber
],
1956 (PartEntry
->DriveLetter
[PartNumber
] == 0) ? '-' : ':',
1957 PartEntry
->PartInfo
[PartNumber
].PartitionType
,
1963 CONSOLE_PrintTextXY(6, 10,
1964 " %c%c %s %I64u %s",
1965 (PartEntry
->DriveLetter
[PartNumber
] == 0) ? '-' : PartEntry
->DriveLetter
[PartNumber
],
1966 (PartEntry
->DriveLetter
[PartNumber
] == 0) ? '-' : ':',
1973 if (DiskEntry
->DiskSize
>= 0x280000000ULL
) /* 10 GB */
1975 DiskSize
= (DiskEntry
->DiskSize
+ (1 << 29)) >> 30;
1976 Unit
= MUIGetString(STRING_GB
);
1981 DiskSize
= (DiskEntry
->DiskSize
+ (1 << 19)) >> 20;
1986 Unit
= MUIGetString(STRING_MB
);
1989 if (DiskEntry
->DriverName
.Length
> 0)
1991 CONSOLE_PrintTextXY(6, 12,
1992 MUIGetString(STRING_HDINFOPARTDELETE
),
1995 DiskEntry
->DiskNumber
,
1999 &DiskEntry
->DriverName
);
2003 CONSOLE_PrintTextXY(6, 12,
2004 MUIGetString(STRING_HDDINFOUNK3
),
2007 DiskEntry
->DiskNumber
,
2015 CONSOLE_ConInKey(Ir
);
2017 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
2018 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
2020 if (ConfirmQuit(Ir
) == TRUE
)
2027 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
) /* ESC */
2029 return SELECT_PARTITION_PAGE
;
2031 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== 'D') /* D */
2033 DeleteCurrentPartition(PartitionList
);
2035 return SELECT_PARTITION_PAGE
;
2039 return DELETE_PARTITION_PAGE
;
2044 SelectFileSystemPage(PINPUT_RECORD Ir
)
2046 PDISKENTRY DiskEntry
;
2047 PPARTENTRY PartEntry
;
2055 if (PartitionList
== NULL
||
2056 PartitionList
->CurrentDisk
== NULL
||
2057 PartitionList
->CurrentPartition
== NULL
)
2059 /* FIXME: show an error dialog */
2063 DiskEntry
= PartitionList
->CurrentDisk
;
2064 PartEntry
= PartitionList
->CurrentPartition
;
2065 PartNumber
= PartitionList
->CurrentPartitionNumber
;
2067 /* adjust disk size */
2068 if (DiskEntry
->DiskSize
>= 0x280000000ULL
) /* 10 GB */
2070 DiskSize
= (DiskEntry
->DiskSize
+ (1 << 29)) >> 30;
2071 DiskUnit
= MUIGetString(STRING_GB
);
2075 DiskSize
= (DiskEntry
->DiskSize
+ (1 << 19)) >> 20;
2076 DiskUnit
= MUIGetString(STRING_MB
);
2079 /* adjust partition size */
2080 if (PartEntry
->PartInfo
[PartNumber
].PartitionLength
.QuadPart
>= 0x280000000LL
) /* 10 GB */
2082 PartSize
= (PartEntry
->PartInfo
[PartNumber
].PartitionLength
.QuadPart
+ (1 << 29)) >> 30;
2083 PartUnit
= MUIGetString(STRING_GB
);
2087 PartSize
= (PartEntry
->PartInfo
[PartNumber
].PartitionLength
.QuadPart
+ (1 << 19)) >> 20;
2088 PartUnit
= MUIGetString(STRING_MB
);
2091 /* adjust partition type */
2092 if ((PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_FAT_12
) ||
2093 (PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_FAT_16
) ||
2094 (PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_HUGE
) ||
2095 (PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_XINT13
))
2099 else if ((PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_FAT32
) ||
2100 (PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_FAT32_XINT13
))
2104 else if (PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_EXT2
)
2108 else if (PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_IFS
)
2110 PartType
= "NTFS"; /* FIXME: Not quite correct! */
2112 else if (PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_ENTRY_UNUSED
)
2114 PartType
= MUIGetString(STRING_FORMATUNUSED
);
2118 PartType
= MUIGetString(STRING_FORMATUNKNOWN
);
2121 if (PartEntry
->AutoCreate
== TRUE
)
2123 CONSOLE_SetTextXY(6, 8, MUIGetString(STRING_NEWPARTITION
));
2126 CONSOLE_PrintTextXY(8, 10, "Partition %lu (%I64u %s) %s of",
2127 PartEntry
->PartInfo
[PartNumber
].PartitionNumber
,
2133 CONSOLE_PrintTextXY(8, 10, MUIGetString(STRING_HDINFOPARTZEROED
),
2134 DiskEntry
->DiskNumber
,
2140 &DiskEntry
->DriverName
);
2142 CONSOLE_SetTextXY(6, 12, MUIGetString(STRING_PARTFORMAT
));
2145 PartEntry
->AutoCreate
= FALSE
;
2147 else if (PartEntry
->New
== TRUE
)
2149 CONSOLE_SetTextXY(6, 8, MUIGetString(STRING_NONFORMATTEDPART
));
2150 CONSOLE_SetTextXY(6, 10, MUIGetString(STRING_PARTFORMAT
));
2154 CONSOLE_SetTextXY(6, 8, MUIGetString(STRING_INSTALLONPART
));
2156 if (PartType
== NULL
)
2158 CONSOLE_PrintTextXY(8, 10,
2159 MUIGetString(STRING_HDDINFOUNK4
),
2160 (PartEntry
->DriveLetter
[PartNumber
] == 0) ? '-' : PartEntry
->DriveLetter
[PartNumber
],
2161 (PartEntry
->DriveLetter
[PartNumber
] == 0) ? '-' : ':',
2162 PartEntry
->PartInfo
[PartNumber
].PartitionType
,
2168 CONSOLE_PrintTextXY(8, 10,
2170 (PartEntry
->DriveLetter
[PartNumber
] == 0) ? '-' : PartEntry
->DriveLetter
[PartNumber
],
2171 (PartEntry
->DriveLetter
[PartNumber
] == 0) ? '-' : ':',
2177 CONSOLE_PrintTextXY(6, 12, MUIGetString(STRING_HDINFOPARTEXISTS
),
2178 DiskEntry
->DiskNumber
,
2184 &DiskEntry
->DriverName
);
2187 MUIDisplayPage(SELECT_FILE_SYSTEM_PAGE
);
2189 if (FileSystemList
== NULL
)
2191 FileSystemList
= CreateFileSystemList(6, 26, PartEntry
->New
, L
"FAT");
2192 if (FileSystemList
== NULL
)
2194 /* FIXME: show an error dialog */
2198 /* FIXME: Add file systems to list */
2200 DrawFileSystemList(FileSystemList
);
2202 if (RepairUpdateFlag
)
2204 return CHECK_FILE_SYSTEM_PAGE
;
2205 //return SELECT_PARTITION_PAGE;
2208 if (IsUnattendedSetup
)
2210 if (UnattendFormatPartition
)
2212 return FORMAT_PARTITION_PAGE
;
2215 return CHECK_FILE_SYSTEM_PAGE
;
2220 CONSOLE_ConInKey(Ir
);
2222 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
2223 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
2225 if (ConfirmQuit(Ir
) == TRUE
)
2232 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
2233 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
)) /* ESC */
2235 return SELECT_PARTITION_PAGE
;
2237 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
2238 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
)) /* DOWN */
2240 ScrollDownFileSystemList(FileSystemList
);
2242 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
2243 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_UP
)) /* UP */
2245 ScrollUpFileSystemList(FileSystemList
);
2247 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_RETURN
) /* ENTER */
2249 if (!FileSystemList
->Selected
->FormatFunc
)
2251 return CHECK_FILE_SYSTEM_PAGE
;
2255 return FORMAT_PARTITION_PAGE
;
2260 return SELECT_FILE_SYSTEM_PAGE
;
2265 FormatPartitionPage(PINPUT_RECORD Ir
)
2267 WCHAR PathBuffer
[MAX_PATH
];
2268 PDISKENTRY DiskEntry
;
2269 PPARTENTRY PartEntry
;
2279 MUIDisplayPage(FORMAT_PARTITION_PAGE
);
2281 if (PartitionList
== NULL
||
2282 PartitionList
->CurrentDisk
== NULL
||
2283 PartitionList
->CurrentPartition
== NULL
)
2285 /* FIXME: show an error dialog */
2289 DiskEntry
= PartitionList
->CurrentDisk
;
2290 PartEntry
= PartitionList
->CurrentPartition
;
2291 PartNum
= PartitionList
->CurrentPartitionNumber
;
2295 if (!IsUnattendedSetup
)
2297 CONSOLE_ConInKey(Ir
);
2300 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
2301 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
2303 if (ConfirmQuit(Ir
) == TRUE
)
2310 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_RETURN
|| IsUnattendedSetup
) /* ENTER */
2312 CONSOLE_SetStatusText(MUIGetString(STRING_PLEASEWAIT
));
2314 if (wcscmp(FileSystemList
->Selected
->FileSystem
, L
"FAT") == 0)
2316 if (PartEntry
->PartInfo
[PartNum
].PartitionLength
.QuadPart
< (4200LL * 1024LL))
2318 /* FAT12 CHS partition (disk is smaller than 4.1MB) */
2319 PartEntry
->PartInfo
[PartNum
].PartitionType
= PARTITION_FAT_12
;
2321 else if (PartEntry
->PartInfo
[PartNum
].StartingOffset
.QuadPart
< (1024LL * 255LL * 63LL * 512LL))
2323 /* Partition starts below the 8.4GB boundary ==> CHS partition */
2325 if (PartEntry
->PartInfo
[PartNum
].PartitionLength
.QuadPart
< (32LL * 1024LL * 1024LL))
2327 /* FAT16 CHS partition (partiton size < 32MB) */
2328 PartEntry
->PartInfo
[PartNum
].PartitionType
= PARTITION_FAT_16
;
2330 else if (PartEntry
->PartInfo
[PartNum
].PartitionLength
.QuadPart
< (512LL * 1024LL * 1024LL))
2332 /* FAT16 CHS partition (partition size < 512MB) */
2333 PartEntry
->PartInfo
[PartNum
].PartitionType
= PARTITION_HUGE
;
2337 /* FAT32 CHS partition (partition size >= 512MB) */
2338 PartEntry
->PartInfo
[PartNum
].PartitionType
= PARTITION_FAT32
;
2343 /* Partition starts above the 8.4GB boundary ==> LBA partition */
2345 if (PartEntry
->PartInfo
[PartNum
].PartitionLength
.QuadPart
< (512LL * 1024LL * 1024LL))
2347 /* FAT16 LBA partition (partition size < 512MB) */
2348 PartEntry
->PartInfo
[PartNum
].PartitionType
= PARTITION_XINT13
;
2352 /* FAT32 LBA partition (partition size >= 512MB) */
2353 PartEntry
->PartInfo
[PartNum
].PartitionType
= PARTITION_FAT32_XINT13
;
2357 else if (wcscmp(FileSystemList
->Selected
->FileSystem
, L
"EXT2") == 0)
2358 PartEntry
->PartInfo
[PartNum
].PartitionType
= PARTITION_EXT2
;
2359 else if (!FileSystemList
->Selected
->FormatFunc
)
2362 CheckActiveBootPartition(PartitionList
);
2365 CONSOLE_PrintTextXY(6, 12,
2366 "Disk: %I64u Cylinder: %I64u Track: %I64u",
2367 DiskEntry
->DiskSize
,
2368 DiskEntry
->CylinderSize
,
2369 DiskEntry
->TrackSize
);
2372 DiskEntry
= PartitionList
->CurrentDisk
;
2373 Entry
= DiskEntry
->PartListHead
.Flink
;
2375 while (Entry
!= &DiskEntry
->PartListHead
)
2377 PartEntry
= CONTAINING_RECORD(Entry
, PARTENTRY
, ListEntry
);
2379 if (PartEntry
->Unpartitioned
== FALSE
)
2381 for (i
= 0; i
< 4; i
++)
2383 CONSOLE_PrintTextXY(6, Line
,
2384 "%2u: %2u %c %12I64u %12I64u %2u %c",
2386 PartEntry
->PartInfo
[i
].PartitionNumber
,
2387 PartEntry
->PartInfo
[i
].BootIndicator
? 'A' : '-',
2388 PartEntry
->PartInfo
[i
].StartingOffset
.QuadPart
,
2389 PartEntry
->PartInfo
[i
].PartitionLength
.QuadPart
,
2390 PartEntry
->PartInfo
[i
].PartitionType
,
2391 PartEntry
->PartInfo
[i
].RewritePartition
? '*' : ' ');
2399 Entry
= Entry
->Flink
;
2402 /* Restore the old entry */
2403 PartEntry
= PartitionList
->CurrentPartition
;
2406 if (WritePartitionsToDisk(PartitionList
) == FALSE
)
2408 DPRINT("WritePartitionsToDisk() failed\n");
2409 MUIDisplayError(ERROR_WRITE_PTABLE
, Ir
, POPUP_WAIT_ENTER
);
2413 /* Set DestinationRootPath */
2414 RtlFreeUnicodeString(&DestinationRootPath
);
2415 swprintf(PathBuffer
,
2416 L
"\\Device\\Harddisk%lu\\Partition%lu",
2417 PartitionList
->CurrentDisk
->DiskNumber
,
2418 PartitionList
->CurrentPartition
->PartInfo
[PartNum
].PartitionNumber
);
2419 RtlCreateUnicodeString(&DestinationRootPath
,
2421 DPRINT("DestinationRootPath: %wZ\n", &DestinationRootPath
);
2424 /* Set SystemRootPath */
2425 RtlFreeUnicodeString(&SystemRootPath
);
2426 swprintf(PathBuffer
,
2427 L
"\\Device\\Harddisk%lu\\Partition%lu",
2428 PartitionList
->ActiveBootDisk
->DiskNumber
,
2429 PartitionList
->ActiveBootPartition
->
2430 PartInfo
[PartitionList
->ActiveBootPartitionNumber
].PartitionNumber
);
2431 RtlCreateUnicodeString(&SystemRootPath
,
2433 DPRINT("SystemRootPath: %wZ\n", &SystemRootPath
);
2436 if (FileSystemList
->Selected
->FormatFunc
)
2438 Status
= FormatPartition(&DestinationRootPath
,
2439 FileSystemList
->Selected
);
2440 if (!NT_SUCCESS(Status
))
2442 DPRINT1("FormatPartition() failed with status 0x%08lx\n", Status
);
2443 /* FIXME: show an error dialog */
2447 PartEntry
->New
= FALSE
;
2449 CheckActiveBootPartition(PartitionList
);
2452 if (wcscmp(FileSystemList
->Selected
->FileSystem
, L
"FAT") == 0)
2454 /* FIXME: Install boot code. This is a hack! */
2455 if ((PartEntry
->PartInfo
[PartNum
].PartitionType
== PARTITION_FAT32_XINT13
) ||
2456 (PartEntry
->PartInfo
[PartNum
].PartitionType
== PARTITION_FAT32
))
2458 wcscpy(PathBuffer
, SourceRootPath
.Buffer
);
2459 wcscat(PathBuffer
, L
"\\loader\\fat32.bin");
2461 DPRINT("Install FAT32 bootcode: %S ==> %S\n", PathBuffer
,
2462 DestinationRootPath
.Buffer
);
2464 Status
= InstallFat32BootCodeToDisk(PathBuffer
,
2465 DestinationRootPath
.Buffer
);
2466 if (!NT_SUCCESS(Status
))
2468 DPRINT1("InstallFat32BootCodeToDisk() failed with status 0x%08lx\n", Status
);
2469 /* FIXME: show an error dialog */
2470 DestroyFileSystemList(FileSystemList
);
2471 FileSystemList
= NULL
;
2477 wcscpy(PathBuffer
, SourceRootPath
.Buffer
);
2478 wcscat(PathBuffer
, L
"\\loader\\fat.bin");
2480 DPRINT("Install FAT bootcode: %S ==> %S\n", PathBuffer
,
2481 DestinationRootPath
.Buffer
);
2483 Status
= InstallFat16BootCodeToDisk(PathBuffer
,
2484 DestinationRootPath
.Buffer
);
2485 if (!NT_SUCCESS(Status
))
2487 DPRINT1("InstallFat16BootCodeToDisk() failed with status 0x%.08x\n", Status
);
2488 /* FIXME: show an error dialog */
2489 DestroyFileSystemList(FileSystemList
);
2490 FileSystemList
= NULL
;
2495 else if (wcscmp(FileSystemList
->Selected
->FileSystem
, L
"EXT2") == 0)
2497 wcscpy(PathBuffer
, SourceRootPath
.Buffer
);
2498 wcscat(PathBuffer
, L
"\\loader\\ext2.bin");
2500 DPRINT("Install EXT2 bootcode: %S ==> %S\n", PathBuffer
,
2501 DestinationRootPath
.Buffer
);
2503 Status
= InstallFat32BootCodeToDisk(PathBuffer
,
2504 DestinationRootPath
.Buffer
);
2505 if (!NT_SUCCESS(Status
))
2507 DPRINT1("InstallFat32BootCodeToDisk() failed with status 0x%08lx\n", Status
);
2508 /* FIXME: show an error dialog */
2509 DestroyFileSystemList(FileSystemList
);
2510 FileSystemList
= NULL
;
2514 else if (FileSystemList
->Selected
->FormatFunc
)
2516 DestroyFileSystemList(FileSystemList
);
2517 FileSystemList
= NULL
;
2522 CONSOLE_SetStatusText(" Done. Press any key ...");
2523 CONSOLE_ConInKey(Ir
);
2526 DestroyFileSystemList(FileSystemList
);
2527 FileSystemList
= NULL
;
2528 return INSTALL_DIRECTORY_PAGE
;
2532 return FORMAT_PARTITION_PAGE
;
2537 CheckFileSystemPage(PINPUT_RECORD Ir
)
2539 PFILE_SYSTEM_ITEM CurrentFileSystem
;
2540 WCHAR PathBuffer
[MAX_PATH
];
2541 CHAR Buffer
[MAX_PATH
];
2543 UCHAR PartNum
= PartitionList
->CurrentPartitionNumber
;
2545 /* FIXME: code duplicated in FormatPartitionPage */
2546 /* Set DestinationRootPath */
2547 RtlFreeUnicodeString(&DestinationRootPath
);
2548 swprintf(PathBuffer
,
2549 L
"\\Device\\Harddisk%lu\\Partition%lu",
2550 PartitionList
->CurrentDisk
->DiskNumber
,
2551 PartitionList
->CurrentPartition
->PartInfo
[PartNum
].PartitionNumber
);
2552 RtlCreateUnicodeString(&DestinationRootPath
, PathBuffer
);
2553 DPRINT("DestinationRootPath: %wZ\n", &DestinationRootPath
);
2555 /* Set SystemRootPath */
2556 RtlFreeUnicodeString(&SystemRootPath
);
2557 swprintf(PathBuffer
,
2558 L
"\\Device\\Harddisk%lu\\Partition%lu",
2559 PartitionList
->ActiveBootDisk
->DiskNumber
,
2560 PartitionList
->ActiveBootPartition
->PartInfo
[PartNum
].PartitionNumber
);
2561 RtlCreateUnicodeString(&SystemRootPath
, PathBuffer
);
2562 DPRINT("SystemRootPath: %wZ\n", &SystemRootPath
);
2564 CONSOLE_SetTextXY(6, 8, MUIGetString(STRING_CHECKINGPART
));
2566 CONSOLE_SetStatusText(MUIGetString(STRING_PLEASEWAIT
));
2568 /* WRONG: first filesystem is not necesseraly the one of the current partition! */
2569 CurrentFileSystem
= CONTAINING_RECORD(FileSystemList
->ListHead
.Flink
, FILE_SYSTEM_ITEM
, ListEntry
);
2571 if (!CurrentFileSystem
->ChkdskFunc
)
2574 "Setup is currently unable to check a partition formatted in %S.\n"
2576 " \x07 Press ENTER to continue Setup.\n"
2577 " \x07 Press F3 to quit Setup.",
2578 CurrentFileSystem
->FileSystem
);
2581 MUIGetString(STRING_QUITCONTINUE
),
2582 NULL
, POPUP_WAIT_NONE
);
2586 CONSOLE_ConInKey(Ir
);
2588 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00 &&
2589 Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
) /* F3 */
2591 if (ConfirmQuit(Ir
))
2594 return CHECK_FILE_SYSTEM_PAGE
;
2596 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== VK_RETURN
) /* ENTER */
2598 return INSTALL_DIRECTORY_PAGE
;
2604 Status
= ChkdskPartition(&DestinationRootPath
, CurrentFileSystem
);
2605 if (!NT_SUCCESS(Status
))
2607 DPRINT("ChkdskPartition() failed with status 0x%08lx\n", Status
);
2608 sprintf(Buffer
, "Setup failed to verify the selected partition.\n"
2609 "(Status 0x%08lx).\n", Status
);
2612 MUIGetString(STRING_REBOOTCOMPUTER
),
2613 Ir
, POPUP_WAIT_ENTER
);
2618 return INSTALL_DIRECTORY_PAGE
;
2624 InstallDirectoryPage1(PWCHAR InstallDir
,
2625 PDISKENTRY DiskEntry
,
2626 PPARTENTRY PartEntry
,
2629 WCHAR PathBuffer
[MAX_PATH
];
2631 /* Create 'InstallPath' string */
2632 RtlFreeUnicodeString(&InstallPath
);
2633 RtlCreateUnicodeString(&InstallPath
,
2636 /* Create 'DestinationPath' string */
2637 RtlFreeUnicodeString(&DestinationPath
);
2638 wcscpy(PathBuffer
, DestinationRootPath
.Buffer
);
2640 if (InstallDir
[0] != L
'\\')
2641 wcscat(PathBuffer
, L
"\\");
2643 wcscat(PathBuffer
, InstallDir
);
2644 RtlCreateUnicodeString(&DestinationPath
, PathBuffer
);
2646 /* Create 'DestinationArcPath' */
2647 RtlFreeUnicodeString(&DestinationArcPath
);
2648 swprintf(PathBuffer
,
2649 L
"multi(0)disk(0)rdisk(%lu)partition(%lu)",
2650 DiskEntry
->BiosDiskNumber
,
2651 PartEntry
->PartInfo
[PartNum
].PartitionNumber
);
2653 if (InstallDir
[0] != L
'\\')
2654 wcscat(PathBuffer
, L
"\\");
2656 wcscat(PathBuffer
, InstallDir
);
2657 RtlCreateUnicodeString(&DestinationArcPath
, PathBuffer
);
2659 return PREPARE_COPY_PAGE
;
2664 InstallDirectoryPage(PINPUT_RECORD Ir
)
2666 PDISKENTRY DiskEntry
;
2667 PPARTENTRY PartEntry
;
2668 WCHAR InstallDir
[51];
2673 if (PartitionList
== NULL
||
2674 PartitionList
->CurrentDisk
== NULL
||
2675 PartitionList
->CurrentPartition
== NULL
)
2677 /* FIXME: show an error dialog */
2681 DiskEntry
= PartitionList
->CurrentDisk
;
2682 PartEntry
= PartitionList
->CurrentPartition
;
2684 /* Search for 'DefaultPath' in the 'SetupData' section */
2685 if (!SetupFindFirstLineW(SetupInf
, L
"SetupData", L
"DefaultPath", &Context
))
2687 MUIDisplayError(ERROR_FIND_SETUPDATA
, Ir
, POPUP_WAIT_ENTER
);
2691 /* Read the 'DefaultPath' data */
2692 if (INF_GetData(&Context
, NULL
, &DefaultPath
))
2694 wcscpy(InstallDir
, DefaultPath
);
2698 wcscpy(InstallDir
, L
"\\ReactOS");
2701 Length
= wcslen(InstallDir
);
2702 CONSOLE_SetInputTextXY(8, 11, 51, InstallDir
);
2703 MUIDisplayPage(INSTALL_DIRECTORY_PAGE
);
2705 if (IsUnattendedSetup
)
2707 return InstallDirectoryPage1(InstallDir
,
2710 PartitionList
->CurrentPartitionNumber
);
2715 CONSOLE_ConInKey(Ir
);
2717 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
2718 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
2720 if (ConfirmQuit(Ir
) == TRUE
)
2725 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2727 return InstallDirectoryPage1(InstallDir
,
2730 PartitionList
->CurrentPartitionNumber
);
2732 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x08) /* BACKSPACE */
2737 InstallDir
[Length
] = 0;
2738 CONSOLE_SetInputTextXY(8, 11, 51, InstallDir
);
2741 else if (isprint(Ir
->Event
.KeyEvent
.uChar
.AsciiChar
))
2745 InstallDir
[Length
] = (WCHAR
)Ir
->Event
.KeyEvent
.uChar
.AsciiChar
;
2747 InstallDir
[Length
] = 0;
2748 CONSOLE_SetInputTextXY(8, 11, 51, InstallDir
);
2753 return INSTALL_DIRECTORY_PAGE
;
2758 AddSectionToCopyQueueCab(HINF InfFile
,
2760 PWCHAR SourceCabinet
,
2761 PCUNICODE_STRING DestinationPath
,
2764 INFCONTEXT FilesContext
;
2765 INFCONTEXT DirContext
;
2767 PWCHAR FileKeyValue
;
2769 PWCHAR TargetFileName
;
2771 /* Search for the SectionName section */
2772 if (!SetupFindFirstLineW(InfFile
, SectionName
, NULL
, &FilesContext
))
2775 sprintf(Buffer
, MUIGetString(STRING_TXTSETUPFAILED
), SectionName
);
2776 PopupError(Buffer
, MUIGetString(STRING_REBOOTCOMPUTER
), Ir
, POPUP_WAIT_ENTER
);
2781 * Enumerate the files in the section
2782 * and add them to the file queue.
2786 /* Get source file name and target directory id */
2787 if (!INF_GetData(&FilesContext
, &FileKeyName
, &FileKeyValue
))
2789 /* FIXME: Handle error! */
2790 DPRINT1("INF_GetData() failed\n");
2794 /* Get optional target file name */
2795 if (!INF_GetDataField(&FilesContext
, 2, &TargetFileName
))
2796 TargetFileName
= NULL
;
2798 DPRINT("FileKeyName: '%S' FileKeyValue: '%S'\n", FileKeyName
, FileKeyValue
);
2800 /* Lookup target directory */
2801 if (!SetupFindFirstLineW(InfFile
, L
"Directories", FileKeyValue
, &DirContext
))
2803 /* FIXME: Handle error! */
2804 DPRINT1("SetupFindFirstLine() failed\n");
2808 if (!INF_GetData(&DirContext
, NULL
, &DirKeyValue
))
2810 /* FIXME: Handle error! */
2811 DPRINT1("INF_GetData() failed\n");
2815 if (!SetupQueueCopy(SetupFileQueue
,
2817 SourceRootPath
.Buffer
,
2818 SourceRootDir
.Buffer
,
2823 /* FIXME: Handle error! */
2824 DPRINT1("SetupQueueCopy() failed\n");
2826 } while (SetupFindNextLine(&FilesContext
, &FilesContext
));
2833 AddSectionToCopyQueue(HINF InfFile
,
2835 PWCHAR SourceCabinet
,
2836 PCUNICODE_STRING DestinationPath
,
2839 INFCONTEXT FilesContext
;
2840 INFCONTEXT DirContext
;
2842 PWCHAR FileKeyValue
;
2844 PWCHAR TargetFileName
;
2847 return AddSectionToCopyQueueCab(InfFile
, L
"SourceFiles", SourceCabinet
, DestinationPath
, Ir
);
2849 /* Search for the SectionName section */
2850 if (!SetupFindFirstLineW(InfFile
, SectionName
, NULL
, &FilesContext
))
2853 sprintf(Buffer
, MUIGetString(STRING_TXTSETUPFAILED
), SectionName
);
2854 PopupError(Buffer
, MUIGetString(STRING_REBOOTCOMPUTER
), Ir
, POPUP_WAIT_ENTER
);
2859 * Enumerate the files in the section
2860 * and add them to the file queue.
2864 /* Get source file name and target directory id */
2865 if (!INF_GetData(&FilesContext
, &FileKeyName
, &FileKeyValue
))
2867 /* FIXME: Handle error! */
2868 DPRINT1("INF_GetData() failed\n");
2872 /* Get target directory id */
2873 if (!INF_GetDataField(&FilesContext
, 13, &FileKeyValue
))
2875 /* FIXME: Handle error! */
2876 DPRINT1("INF_GetData() failed\n");
2880 /* Get optional target file name */
2881 if (!INF_GetDataField(&FilesContext
, 11, &TargetFileName
))
2882 TargetFileName
= NULL
;
2883 else if (!*TargetFileName
)
2884 TargetFileName
= NULL
;
2886 DPRINT("FileKeyName: '%S' FileKeyValue: '%S'\n", FileKeyName
, FileKeyValue
);
2888 /* Lookup target directory */
2889 if (!SetupFindFirstLineW(InfFile
, L
"Directories", FileKeyValue
, &DirContext
))
2891 /* FIXME: Handle error! */
2892 DPRINT1("SetupFindFirstLine() failed\n");
2896 if (!INF_GetData(&DirContext
, NULL
, &DirKeyValue
))
2898 /* FIXME: Handle error! */
2899 DPRINT1("INF_GetData() failed\n");
2903 if (!SetupQueueCopy(SetupFileQueue
,
2905 SourceRootPath
.Buffer
,
2906 SourceRootDir
.Buffer
,
2911 /* FIXME: Handle error! */
2912 DPRINT1("SetupQueueCopy() failed\n");
2914 } while (SetupFindNextLine(&FilesContext
, &FilesContext
));
2921 PrepareCopyPageInfFile(HINF InfFile
,
2922 PWCHAR SourceCabinet
,
2925 WCHAR PathBuffer
[MAX_PATH
];
2926 INFCONTEXT DirContext
;
2927 PWCHAR AdditionalSectionName
= NULL
;
2932 /* Add common files */
2933 if (!AddSectionToCopyQueue(InfFile
, L
"SourceDisksFiles", SourceCabinet
, &DestinationPath
, Ir
))
2936 /* Add specific files depending of computer type */
2937 if (SourceCabinet
== NULL
)
2939 if (!ProcessComputerFiles(InfFile
, ComputerList
, &AdditionalSectionName
))
2942 if (AdditionalSectionName
)
2944 if (!AddSectionToCopyQueue(InfFile
, AdditionalSectionName
, SourceCabinet
, &DestinationPath
, Ir
))
2949 /* Create directories */
2953 * Install directories like '\reactos\test' are not handled yet.
2956 /* Get destination path */
2957 wcscpy(PathBuffer
, DestinationPath
.Buffer
);
2959 /* Remove trailing backslash */
2960 Length
= wcslen(PathBuffer
);
2961 if ((Length
> 0) && (PathBuffer
[Length
- 1] == '\\'))
2963 PathBuffer
[Length
- 1] = 0;
2966 /* Create the install directory */
2967 Status
= SetupCreateDirectory(PathBuffer
);
2968 if (!NT_SUCCESS(Status
) && Status
!= STATUS_OBJECT_NAME_COLLISION
)
2970 DPRINT("Creating directory '%S' failed: Status = 0x%08lx", PathBuffer
, Status
);
2971 MUIDisplayError(ERROR_CREATE_INSTALL_DIR
, Ir
, POPUP_WAIT_ENTER
);
2975 /* Search for the 'Directories' section */
2976 if (!SetupFindFirstLineW(InfFile
, L
"Directories", NULL
, &DirContext
))
2980 MUIDisplayError(ERROR_CABINET_SECTION
, Ir
, POPUP_WAIT_ENTER
);
2984 MUIDisplayError(ERROR_TXTSETUP_SECTION
, Ir
, POPUP_WAIT_ENTER
);
2990 /* Enumerate the directory values and create the subdirectories */
2993 if (!INF_GetData(&DirContext
, NULL
, &KeyValue
))
2999 if (KeyValue
[0] == L
'\\' && KeyValue
[1] != 0)
3001 DPRINT("Absolute Path: '%S'\n", KeyValue
);
3003 wcscpy(PathBuffer
, DestinationRootPath
.Buffer
);
3004 wcscat(PathBuffer
, KeyValue
);
3006 DPRINT("FullPath: '%S'\n", PathBuffer
);
3008 else if (KeyValue
[0] != L
'\\')
3010 DPRINT("RelativePath: '%S'\n", KeyValue
);
3011 wcscpy(PathBuffer
, DestinationPath
.Buffer
);
3012 wcscat(PathBuffer
, L
"\\");
3013 wcscat(PathBuffer
, KeyValue
);
3015 DPRINT("FullPath: '%S'\n", PathBuffer
);
3017 Status
= SetupCreateDirectory(PathBuffer
);
3018 if (!NT_SUCCESS(Status
) && Status
!= STATUS_OBJECT_NAME_COLLISION
)
3020 DPRINT("Creating directory '%S' failed: Status = 0x%08lx", PathBuffer
, Status
);
3021 MUIDisplayError(ERROR_CREATE_DIR
, Ir
, POPUP_WAIT_ENTER
);
3025 } while (SetupFindNextLine (&DirContext
, &DirContext
));
3032 PrepareCopyPage(PINPUT_RECORD Ir
)
3035 WCHAR PathBuffer
[MAX_PATH
];
3036 INFCONTEXT CabinetsContext
;
3042 MUIDisplayPage(PREPARE_COPY_PAGE
);
3044 /* Create the file queue */
3045 SetupFileQueue
= SetupOpenFileQueue();
3046 if (SetupFileQueue
== NULL
)
3048 MUIDisplayError(ERROR_COPY_QUEUE
, Ir
, POPUP_WAIT_ENTER
);
3052 if (!PrepareCopyPageInfFile(SetupInf
, NULL
, Ir
))
3057 /* Search for the 'Cabinets' section */
3058 if (!SetupFindFirstLineW(SetupInf
, L
"Cabinets", NULL
, &CabinetsContext
))
3060 return FILE_COPY_PAGE
;
3064 * Enumerate the directory values in the 'Cabinets'
3065 * section and parse their inf files.
3069 if (!INF_GetData(&CabinetsContext
, NULL
, &KeyValue
))
3072 wcscpy(PathBuffer
, SourcePath
.Buffer
);
3073 wcscat(PathBuffer
, L
"\\");
3074 wcscat(PathBuffer
, KeyValue
);
3077 CabinetInitialize();
3078 CabinetSetEventHandlers(NULL
, NULL
, NULL
);
3079 CabinetSetCabinetName(PathBuffer
);
3081 if (CabinetOpen() == CAB_STATUS_SUCCESS
)
3083 DPRINT("Cabinet %S\n", CabinetGetCabinetName());
3085 InfFileData
= CabinetGetCabinetReservedArea(&InfFileSize
);
3086 if (InfFileData
== NULL
)
3088 MUIDisplayError(ERROR_CABINET_SCRIPT
, Ir
, POPUP_WAIT_ENTER
);
3094 DPRINT("Cannot open cabinet: %S.\n", CabinetGetCabinetName());
3095 MUIDisplayError(ERROR_CABINET_MISSING
, Ir
, POPUP_WAIT_ENTER
);
3099 InfHandle
= INF_OpenBufferedFileA((CHAR
*) InfFileData
,
3106 if (InfHandle
== INVALID_HANDLE_VALUE
)
3108 MUIDisplayError(ERROR_INVALID_CABINET_INF
, Ir
, POPUP_WAIT_ENTER
);
3114 if (!PrepareCopyPageInfFile(InfHandle
, KeyValue
, Ir
))
3119 } while (SetupFindNextLine(&CabinetsContext
, &CabinetsContext
));
3121 return FILE_COPY_PAGE
;
3127 SetupUpdateMemoryInfo(IN PCOPYCONTEXT CopyContext
,
3130 SYSTEM_PERFORMANCE_INFORMATION PerfInfo
;
3132 /* Get the memory information from the system */
3133 NtQuerySystemInformation(SystemPerformanceInformation
,
3138 /* Check if this is initial setup */
3141 /* Set maximum limits to be total RAM pages */
3142 ProgressSetStepCount(CopyContext
->MemoryBars
[0], PerfInfo
.CommitLimit
);
3143 ProgressSetStepCount(CopyContext
->MemoryBars
[1], PerfInfo
.CommitLimit
);
3144 ProgressSetStepCount(CopyContext
->MemoryBars
[2], PerfInfo
.CommitLimit
);
3147 /* Set current values */
3148 ProgressSetStep(CopyContext
->MemoryBars
[0], PerfInfo
.PagedPoolPages
+ PerfInfo
.NonPagedPoolPages
);
3149 ProgressSetStep(CopyContext
->MemoryBars
[1], PerfInfo
.ResidentSystemCachePage
);
3150 ProgressSetStep(CopyContext
->MemoryBars
[2], PerfInfo
.AvailablePages
);
3156 FileCopyCallback(PVOID Context
,
3161 PCOPYCONTEXT CopyContext
;
3163 CopyContext
= (PCOPYCONTEXT
)Context
;
3165 switch (Notification
)
3167 case SPFILENOTIFY_STARTSUBQUEUE
:
3168 CopyContext
->TotalOperations
= (ULONG
)Param2
;
3169 ProgressSetStepCount(CopyContext
->ProgressBar
,
3170 CopyContext
->TotalOperations
);
3171 SetupUpdateMemoryInfo(CopyContext
, TRUE
);
3174 case SPFILENOTIFY_STARTCOPY
:
3175 /* Display copy message */
3176 CONSOLE_SetStatusText(MUIGetString(STRING_COPYING
), (PWSTR
)Param1
);
3177 SetupUpdateMemoryInfo(CopyContext
, FALSE
);
3180 case SPFILENOTIFY_ENDCOPY
:
3181 CopyContext
->CompletedOperations
++;
3182 ProgressNextStep(CopyContext
->ProgressBar
);
3183 SetupUpdateMemoryInfo(CopyContext
, FALSE
);
3193 FileCopyPage(PINPUT_RECORD Ir
)
3195 COPYCONTEXT CopyContext
;
3196 unsigned int mem_bar_width
;
3198 MUIDisplayPage(FILE_COPY_PAGE
);
3200 /* Create context for the copy process */
3201 CopyContext
.DestinationRootPath
= DestinationRootPath
.Buffer
;
3202 CopyContext
.InstallPath
= InstallPath
.Buffer
;
3203 CopyContext
.TotalOperations
= 0;
3204 CopyContext
.CompletedOperations
= 0;
3206 /* Create the progress bar as well */
3207 CopyContext
.ProgressBar
= CreateProgressBar(13,
3214 MUIGetString(STRING_SETUPCOPYINGFILES
));
3216 // fit memory bars to screen width, distribute them uniform
3217 mem_bar_width
= (xScreen
- 26) / 5;
3218 mem_bar_width
-= mem_bar_width
% 2; // make even
3219 /* ATTENTION: The following progress bars are debug stuff, which should not be translated!! */
3220 /* Create the paged pool progress bar */
3221 CopyContext
.MemoryBars
[0] = CreateProgressBar(13,
3230 /* Create the non paged pool progress bar */
3231 CopyContext
.MemoryBars
[1] = CreateProgressBar((xScreen
/ 2)- (mem_bar_width
/ 2),
3233 (xScreen
/ 2) + (mem_bar_width
/ 2),
3235 (xScreen
/ 2)- (mem_bar_width
/ 2),
3240 /* Create the global memory progress bar */
3241 CopyContext
.MemoryBars
[2] = CreateProgressBar(xScreen
- 13 - mem_bar_width
,
3245 xScreen
- 13 - mem_bar_width
,
3250 /* Do the file copying */
3251 SetupCommitFileQueueW(NULL
,
3256 /* If we get here, we're done, so cleanup the queue and progress bar */
3257 SetupCloseFileQueue(SetupFileQueue
);
3258 DestroyProgressBar(CopyContext
.ProgressBar
);
3259 DestroyProgressBar(CopyContext
.MemoryBars
[0]);
3260 DestroyProgressBar(CopyContext
.MemoryBars
[1]);
3261 DestroyProgressBar(CopyContext
.MemoryBars
[2]);
3263 /* Go display the next page */
3264 return REGISTRY_PAGE
;
3269 RegistryPage(PINPUT_RECORD Ir
)
3271 INFCONTEXT InfContext
;
3278 MUIDisplayPage(REGISTRY_PAGE
);
3280 if (RepairUpdateFlag
)
3282 return SUCCESS_PAGE
;
3285 if (!SetInstallPathValue(&DestinationPath
))
3287 DPRINT("SetInstallPathValue() failed\n");
3288 MUIDisplayError(ERROR_INITIALIZE_REGISTRY
, Ir
, POPUP_WAIT_ENTER
);
3292 /* Create the default hives */
3294 Status
= NtInitializeRegistry(CM_BOOT_FLAG_SETUP
);
3295 if (!NT_SUCCESS(Status
))
3297 DPRINT("NtInitializeRegistry() failed (Status %lx)\n", Status
);
3298 MUIDisplayError(ERROR_CREATE_HIVE
, Ir
, POPUP_WAIT_ENTER
);
3302 RegInitializeRegistry();
3305 /* Update registry */
3306 CONSOLE_SetStatusText(MUIGetString(STRING_REGHIVEUPDATE
));
3308 if (!SetupFindFirstLineW(SetupInf
, L
"HiveInfs.Install", NULL
, &InfContext
))
3310 DPRINT1("SetupFindFirstLine() failed\n");
3311 MUIDisplayError(ERROR_FIND_REGISTRY
, Ir
, POPUP_WAIT_ENTER
);
3317 INF_GetDataField (&InfContext
, 0, &Action
);
3318 INF_GetDataField (&InfContext
, 1, &File
);
3319 INF_GetDataField (&InfContext
, 2, &Section
);
3321 DPRINT("Action: %S File: %S Section %S\n", Action
, File
, Section
);
3326 if (!_wcsicmp (Action
, L
"AddReg"))
3330 else if (!_wcsicmp (Action
, L
"DelReg"))
3339 CONSOLE_SetStatusText(MUIGetString(STRING_IMPORTFILE
), File
);
3341 if (!ImportRegistryFile(File
, Section
, LanguageId
, Delete
))
3343 DPRINT("Importing %S failed\n", File
);
3345 MUIDisplayError(ERROR_IMPORT_HIVE
, Ir
, POPUP_WAIT_ENTER
);
3348 } while (SetupFindNextLine(&InfContext
, &InfContext
));
3350 /* Update display registry settings */
3351 CONSOLE_SetStatusText(MUIGetString(STRING_DISPLAYETTINGSUPDATE
));
3352 if (!ProcessDisplayRegistry(SetupInf
, DisplayList
))
3354 MUIDisplayError(ERROR_UPDATE_DISPLAY_SETTINGS
, Ir
, POPUP_WAIT_ENTER
);
3358 /* Set the locale */
3359 CONSOLE_SetStatusText(MUIGetString(STRING_LOCALESETTINGSUPDATE
));
3360 if (!ProcessLocaleRegistry(LanguageList
))
3362 MUIDisplayError(ERROR_UPDATE_LOCALESETTINGS
, Ir
, POPUP_WAIT_ENTER
);
3366 /* Add keyboard layouts */
3367 CONSOLE_SetStatusText(MUIGetString(STRING_ADDKBLAYOUTS
));
3368 if (!AddKeyboardLayouts())
3370 MUIDisplayError(ERROR_ADDING_KBLAYOUTS
, Ir
, POPUP_WAIT_ENTER
);
3376 if (!SetGeoID(MUIGetGeoID()))
3378 MUIDisplayError(ERROR_UPDATE_GEOID
, Ir
, POPUP_WAIT_ENTER
);
3382 if (!IsUnattendedSetup
)
3384 /* Update keyboard layout settings */
3385 CONSOLE_SetStatusText(MUIGetString(STRING_KEYBOARDSETTINGSUPDATE
));
3386 if (!ProcessKeyboardLayoutRegistry(LayoutList
))
3388 MUIDisplayError(ERROR_UPDATE_KBSETTINGS
, Ir
, POPUP_WAIT_ENTER
);
3393 /* Add codepage information to registry */
3394 CONSOLE_SetStatusText(MUIGetString(STRING_CODEPAGEINFOUPDATE
));
3397 MUIDisplayError(ERROR_ADDING_CODEPAGE
, Ir
, POPUP_WAIT_ENTER
);
3401 /* Update the mounted devices list */
3402 SetMountedDeviceValues(PartitionList
);
3404 CONSOLE_SetStatusText(MUIGetString(STRING_DONE
));
3406 return BOOT_LOADER_PAGE
;
3411 BootLoaderPage(PINPUT_RECORD Ir
)
3413 UCHAR PartitionType
;
3414 BOOLEAN InstallOnFloppy
;
3417 CONSOLE_SetStatusText(MUIGetString(STRING_PLEASEWAIT
));
3419 PartitionType
= PartitionList
->ActiveBootPartition
->
3420 PartInfo
[PartitionList
->ActiveBootPartitionNumber
].PartitionType
;
3422 if (IsUnattendedSetup
)
3424 if (UnattendMBRInstallType
== 0) /* skip MBR installation */
3426 return SUCCESS_PAGE
;
3428 else if (UnattendMBRInstallType
== 1) /* install on floppy */
3430 return BOOT_LOADER_FLOPPY_PAGE
;
3434 if (PartitionType
== PARTITION_ENTRY_UNUSED
)
3436 DPRINT("Error: active partition invalid (unused)\n");
3437 InstallOnFloppy
= TRUE
;
3439 else if (PartitionType
== 0x0A)
3441 /* OS/2 boot manager partition */
3442 DPRINT("Found OS/2 boot manager partition\n");
3443 InstallOnFloppy
= TRUE
;
3445 else if (PartitionType
== 0x83)
3447 /* Linux ext2 partition */
3448 DPRINT("Found Linux ext2 partition\n");
3449 InstallOnFloppy
= TRUE
;
3451 else if (PartitionType
== PARTITION_IFS
)
3453 /* NTFS partition */
3454 DPRINT("Found NTFS partition\n");
3455 InstallOnFloppy
= TRUE
;
3457 else if ((PartitionType
== PARTITION_FAT_12
) ||
3458 (PartitionType
== PARTITION_FAT_16
) ||
3459 (PartitionType
== PARTITION_HUGE
) ||
3460 (PartitionType
== PARTITION_XINT13
) ||
3461 (PartitionType
== PARTITION_FAT32
) ||
3462 (PartitionType
== PARTITION_FAT32_XINT13
))
3464 DPRINT("Found FAT partition\n");
3465 InstallOnFloppy
= FALSE
;
3469 /* Unknown partition */
3470 DPRINT("Unknown partition found\n");
3471 InstallOnFloppy
= TRUE
;
3474 if (InstallOnFloppy
== TRUE
)
3476 return BOOT_LOADER_FLOPPY_PAGE
;
3479 /* Unattended install on hdd? */
3480 if (IsUnattendedSetup
&& UnattendMBRInstallType
== 2)
3482 return BOOT_LOADER_HARDDISK_MBR_PAGE
;
3485 MUIDisplayPage(BOOT_LOADER_PAGE
);
3486 CONSOLE_InvertTextXY(8, Line
, 60, 1);
3490 CONSOLE_ConInKey(Ir
);
3492 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
3493 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
)) /* DOWN */
3495 CONSOLE_NormalTextXY(8, Line
, 60, 1);
3504 CONSOLE_InvertTextXY(8, Line
, 60, 1);
3506 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
3507 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_UP
)) /* UP */
3509 CONSOLE_NormalTextXY(8, Line
, 60, 1);
3518 CONSOLE_InvertTextXY(8, Line
, 60, 1);
3520 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
3521 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
3523 if (ConfirmQuit(Ir
) == TRUE
)
3528 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
3532 return BOOT_LOADER_HARDDISK_MBR_PAGE
;
3534 else if (Line
== 13)
3536 return BOOT_LOADER_HARDDISK_VBR_PAGE
;
3538 else if (Line
== 14)
3540 return BOOT_LOADER_FLOPPY_PAGE
;
3542 else if (Line
== 15)
3544 return SUCCESS_PAGE
;
3547 return BOOT_LOADER_PAGE
;
3551 return BOOT_LOADER_PAGE
;
3556 BootLoaderFloppyPage(PINPUT_RECORD Ir
)
3560 MUIDisplayPage(BOOT_LOADER_FLOPPY_PAGE
);
3562 // SetStatusText(" Please wait...");
3566 CONSOLE_ConInKey(Ir
);
3568 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
3569 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
3571 if (ConfirmQuit(Ir
) == TRUE
)
3576 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
3578 if (DoesFileExist(L
"\\Device\\Floppy0", L
"\\") == FALSE
)
3580 MUIDisplayError(ERROR_NO_FLOPPY
, Ir
, POPUP_WAIT_ENTER
);
3581 return BOOT_LOADER_FLOPPY_PAGE
;
3584 Status
= InstallFatBootcodeToFloppy(&SourceRootPath
, &DestinationArcPath
);
3585 if (!NT_SUCCESS(Status
))
3587 /* Print error message */
3588 return BOOT_LOADER_FLOPPY_PAGE
;
3591 return SUCCESS_PAGE
;
3595 return BOOT_LOADER_FLOPPY_PAGE
;
3599 BootLoaderHarddiskVbrPage(PINPUT_RECORD Ir
)
3601 UCHAR PartitionType
;
3604 PartitionType
= PartitionList
->ActiveBootPartition
->
3605 PartInfo
[PartitionList
->ActiveBootPartitionNumber
].PartitionType
;
3607 Status
= InstallVBRToPartition(&SystemRootPath
,
3609 &DestinationArcPath
,
3611 if (!NT_SUCCESS(Status
))
3613 MUIDisplayError(ERROR_WRITE_BOOT
, Ir
, POPUP_WAIT_ENTER
);
3617 return SUCCESS_PAGE
;
3621 BootLoaderHarddiskMbrPage(PINPUT_RECORD Ir
)
3623 UCHAR PartitionType
;
3625 WCHAR DestinationDevicePathBuffer
[MAX_PATH
];
3626 WCHAR SourceMbrPathBuffer
[MAX_PATH
];
3628 /* Step 1: Write the VBR */
3629 PartitionType
= PartitionList
->ActiveBootPartition
->
3630 PartInfo
[PartitionList
->ActiveBootPartitionNumber
].PartitionType
;
3632 Status
= InstallVBRToPartition(&SystemRootPath
,
3634 &DestinationArcPath
,
3636 if (!NT_SUCCESS(Status
))
3638 MUIDisplayError(ERROR_WRITE_BOOT
, Ir
, POPUP_WAIT_ENTER
);
3642 /* Step 2: Write the MBR */
3643 swprintf(DestinationDevicePathBuffer
,
3644 L
"\\Device\\Harddisk%d\\Partition0",
3645 PartitionList
->ActiveBootDisk
->DiskNumber
);
3647 wcscpy(SourceMbrPathBuffer
, SourceRootPath
.Buffer
);
3648 wcscat(SourceMbrPathBuffer
, L
"\\loader\\dosmbr.bin");
3650 DPRINT("Install MBR bootcode: %S ==> %S\n",
3651 SourceMbrPathBuffer
, DestinationDevicePathBuffer
);
3653 Status
= InstallMbrBootCodeToDisk(SourceMbrPathBuffer
,
3654 DestinationDevicePathBuffer
);
3655 if (!NT_SUCCESS (Status
))
3657 DPRINT1("InstallMbrBootCodeToDisk() failed (Status %lx)\n",
3659 MUIDisplayError(ERROR_INSTALL_BOOTCODE
, Ir
, POPUP_WAIT_ENTER
);
3663 return SUCCESS_PAGE
;
3668 QuitPage(PINPUT_RECORD Ir
)
3670 MUIDisplayPage(QUIT_PAGE
);
3672 /* Destroy partition list */
3673 if (PartitionList
!= NULL
)
3675 DestroyPartitionList (PartitionList
);
3676 PartitionList
= NULL
;
3679 /* Destroy filesystem list */
3680 if (FileSystemList
!= NULL
)
3682 DestroyFileSystemList (FileSystemList
);
3683 FileSystemList
= NULL
;
3686 /* Destroy computer settings list */
3687 if (ComputerList
!= NULL
)
3689 DestroyGenericList(ComputerList
, TRUE
);
3690 ComputerList
= NULL
;
3693 /* Destroy display settings list */
3694 if (DisplayList
!= NULL
)
3696 DestroyGenericList(DisplayList
, TRUE
);
3700 /* Destroy keyboard settings list */
3701 if (KeyboardList
!= NULL
)
3703 DestroyGenericList(KeyboardList
, TRUE
);
3704 KeyboardList
= NULL
;
3707 /* Destroy keyboard layout list */
3708 if (LayoutList
!= NULL
)
3710 DestroyGenericList(LayoutList
, TRUE
);
3714 if (LanguageList
!= NULL
)
3716 DestroyGenericList(LanguageList
, FALSE
);
3717 LanguageList
= NULL
;
3720 CONSOLE_SetStatusText(MUIGetString(STRING_REBOOTCOMPUTER2
));
3724 CONSOLE_ConInKey(Ir
);
3726 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
3735 SuccessPage(PINPUT_RECORD Ir
)
3737 MUIDisplayPage(SUCCESS_PAGE
);
3739 if (IsUnattendedSetup
)
3746 CONSOLE_ConInKey(Ir
);
3748 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
3757 FlushPage(PINPUT_RECORD Ir
)
3759 MUIDisplayPage(FLUSH_PAGE
);
3765 PnpEventThread(IN LPVOID lpParameter
);
3775 NtQuerySystemTime(&Time
);
3777 Status
= RtlCreateUserThread(NtCurrentProcess(),
3787 if (!NT_SUCCESS(Status
))
3788 hPnpThread
= INVALID_HANDLE_VALUE
;
3790 if (!CONSOLE_Init())
3792 PrintString(MUIGetString(STRING_CONSOLEFAIL1
));
3793 PrintString(MUIGetString(STRING_CONSOLEFAIL2
));
3794 PrintString(MUIGetString(STRING_CONSOLEFAIL3
));
3796 /* Raise a hard error (crash the system/BSOD) */
3797 NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED
,
3801 /* Initialize global unicode strings */
3802 RtlInitUnicodeString(&SourcePath
, NULL
);
3803 RtlInitUnicodeString(&SourceRootPath
, NULL
);
3804 RtlInitUnicodeString(&SourceRootDir
, NULL
);
3805 RtlInitUnicodeString(&InstallPath
, NULL
);
3806 RtlInitUnicodeString(&DestinationPath
, NULL
);
3807 RtlInitUnicodeString(&DestinationArcPath
, NULL
);
3808 RtlInitUnicodeString(&DestinationRootPath
, NULL
);
3809 RtlInitUnicodeString(&SystemRootPath
, NULL
);
3811 /* Hide the cursor */
3812 CONSOLE_SetCursorType(TRUE
, FALSE
);
3815 while (Page
!= REBOOT_PAGE
)
3817 CONSOLE_ClearScreen();
3820 //CONSOLE_SetUnderlinedTextXY(4, 3, " ReactOS " KERNEL_VERSION_STR " Setup ");
3827 Page
= SetupStartPage(&Ir
);
3832 Page
= LanguagePage(&Ir
);
3837 Page
= LicensePage(&Ir
);
3842 Page
= IntroPage(&Ir
);
3846 case INSTALL_INTRO_PAGE
:
3847 Page
= InstallIntroPage(&Ir
);
3851 case SCSI_CONTROLLER_PAGE
:
3852 Page
= ScsiControllerPage(&Ir
);
3857 case OEM_DRIVER_PAGE
:
3858 Page
= OemDriverPage(&Ir
);
3862 case DEVICE_SETTINGS_PAGE
:
3863 Page
= DeviceSettingsPage(&Ir
);
3866 case COMPUTER_SETTINGS_PAGE
:
3867 Page
= ComputerSettingsPage(&Ir
);
3870 case DISPLAY_SETTINGS_PAGE
:
3871 Page
= DisplaySettingsPage(&Ir
);
3874 case KEYBOARD_SETTINGS_PAGE
:
3875 Page
= KeyboardSettingsPage(&Ir
);
3878 case LAYOUT_SETTINGS_PAGE
:
3879 Page
= LayoutSettingsPage(&Ir
);
3882 case SELECT_PARTITION_PAGE
:
3883 Page
= SelectPartitionPage(&Ir
);
3886 case CREATE_PARTITION_PAGE
:
3887 Page
= CreatePartitionPage(&Ir
);
3890 case DELETE_PARTITION_PAGE
:
3891 Page
= DeletePartitionPage(&Ir
);
3894 case SELECT_FILE_SYSTEM_PAGE
:
3895 Page
= SelectFileSystemPage(&Ir
);
3898 case FORMAT_PARTITION_PAGE
:
3899 Page
= (PAGE_NUMBER
) FormatPartitionPage(&Ir
);
3902 case CHECK_FILE_SYSTEM_PAGE
:
3903 Page
= (PAGE_NUMBER
) CheckFileSystemPage(&Ir
);
3906 case INSTALL_DIRECTORY_PAGE
:
3907 Page
= InstallDirectoryPage(&Ir
);
3910 case PREPARE_COPY_PAGE
:
3911 Page
= PrepareCopyPage(&Ir
);
3914 case FILE_COPY_PAGE
:
3915 Page
= FileCopyPage(&Ir
);
3919 Page
= RegistryPage(&Ir
);
3922 case BOOT_LOADER_PAGE
:
3923 Page
= BootLoaderPage(&Ir
);
3926 case BOOT_LOADER_FLOPPY_PAGE
:
3927 Page
= BootLoaderFloppyPage(&Ir
);
3930 case BOOT_LOADER_HARDDISK_MBR_PAGE
:
3931 Page
= BootLoaderHarddiskMbrPage(&Ir
);
3934 case BOOT_LOADER_HARDDISK_VBR_PAGE
:
3935 Page
= BootLoaderHarddiskVbrPage(&Ir
);
3939 case REPAIR_INTRO_PAGE
:
3940 Page
= RepairIntroPage(&Ir
);
3944 Page
= SuccessPage(&Ir
);
3948 Page
= FlushPage(&Ir
);
3952 Page
= QuitPage(&Ir
);
3962 /* Avoid bugcheck */
3963 Time
.QuadPart
+= 50000000;
3964 NtDelayExecution(FALSE
, &Time
);
3967 NtShutdownSystem(ShutdownReboot
);
3968 NtTerminateProcess(NtCurrentProcess(), 0);
3975 NtProcessStartup(PPEB Peb
)
3977 RtlNormalizeProcessParams(Peb
->ProcessParameters
);
3979 ProcessHeap
= Peb
->ProcessHeap
;
3980 INF_SetHeap(ProcessHeap
);
3983 #endif /* __REACTOS__ */