3 * Copyright (C) 2002, 2003, 2004 ReactOS Team
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 * COPYRIGHT: See COPYING in the top level directory
21 * PROJECT: ReactOS text-mode setup
22 * FILE: subsys/system/usetup/usetup.c
23 * PURPOSE: Text-mode setup
24 * PROGRAMMER: Eric Kohl
25 * Casper S. Hornstrup (chorns@users.sourceforge.net)
26 * Hervé Poussineau (hpoussin@reactos.org)
35 /* GLOBALS ******************************************************************/
38 UNICODE_STRING SourceRootPath
;
39 UNICODE_STRING SourceRootDir
;
40 UNICODE_STRING SourcePath
;
41 BOOLEAN IsUnattendedSetup
= FALSE
;
42 LONG UnattendDestinationDiskNumber
;
43 LONG UnattendDestinationPartitionNumber
;
44 LONG UnattendMBRInstallType
= -1;
45 LONG UnattendFormatPartition
= 0;
46 LONG AutoPartition
= 0;
47 WCHAR UnattendInstallationDirectory
[MAX_PATH
];
48 PWCHAR SelectedLanguageId
;
50 WCHAR DefaultLanguage
[20];
51 WCHAR DefaultKBLayout
[20];
52 BOOLEAN RepairUpdateFlag
= FALSE
;
53 HANDLE hPnpThread
= INVALID_HANDLE_VALUE
;
55 /* LOCALS *******************************************************************/
57 static PPARTLIST PartitionList
= NULL
;
59 static PFILE_SYSTEM_LIST FileSystemList
= NULL
;
61 static UNICODE_STRING InstallPath
;
63 /* Path to the install directory */
64 static UNICODE_STRING DestinationPath
;
65 static UNICODE_STRING DestinationArcPath
;
66 static UNICODE_STRING DestinationRootPath
;
68 /* Path to the active partition (boot manager) */
69 static UNICODE_STRING SystemRootPath
;
73 static HSPFILEQ SetupFileQueue
= NULL
;
75 static BOOLEAN WarnLinuxPartitions
= TRUE
;
77 static PGENERIC_LIST ComputerList
= NULL
;
78 static PGENERIC_LIST DisplayList
= NULL
;
79 static PGENERIC_LIST KeyboardList
= NULL
;
80 static PGENERIC_LIST LayoutList
= NULL
;
81 static PGENERIC_LIST LanguageList
= NULL
;
83 static LANGID LanguageId
= 0;
85 static ULONG RequiredPartitionDiskSpace
= ~0;
87 /* FUNCTIONS ****************************************************************/
90 PrintString(char* fmt
,...)
94 UNICODE_STRING UnicodeString
;
95 ANSI_STRING AnsiString
;
98 vsprintf(buffer
, fmt
, ap
);
101 RtlInitAnsiString(&AnsiString
, buffer
);
102 RtlAnsiStringToUnicodeString(&UnicodeString
, &AnsiString
, TRUE
);
103 NtDisplayString(&UnicodeString
);
104 RtlFreeUnicodeString(&UnicodeString
);
118 /* draw upper left corner */
121 FillConsoleOutputCharacterA(
128 /* draw upper edge */
131 FillConsoleOutputCharacterA(
138 /* draw upper right corner */
139 coPos
.X
= xLeft
+ Width
- 1;
141 FillConsoleOutputCharacterA(
148 /* Draw right edge, inner space and left edge */
149 for (coPos
.Y
= yTop
+ 1; coPos
.Y
< yTop
+ Height
- 1; coPos
.Y
++)
152 FillConsoleOutputCharacterA(
160 FillConsoleOutputCharacterA(
167 coPos
.X
= xLeft
+ Width
- 1;
168 FillConsoleOutputCharacterA(
176 /* draw lower left corner */
178 coPos
.Y
= yTop
+ Height
- 1;
179 FillConsoleOutputCharacterA(
186 /* draw lower edge */
188 coPos
.Y
= yTop
+ Height
- 1;
189 FillConsoleOutputCharacterA(
196 /* draw lower right corner */
197 coPos
.X
= xLeft
+ Width
- 1;
198 coPos
.Y
= yTop
+ Height
- 1;
199 FillConsoleOutputCharacterA(
208 PopupError(PCCH Text
,
226 /* Count text lines and longest line */
233 p
= strchr(pnext
, '\n');
237 Length
= strlen(pnext
);
242 Length
= (ULONG
)(p
- pnext
);
248 if (Length
> MaxLength
)
251 if (LastLine
== TRUE
)
257 /* Check length of status line */
260 Length
= strlen(Status
);
262 if (Length
> MaxLength
)
266 Width
= MaxLength
+ 4;
272 yTop
= (yScreen
- Height
) / 2;
273 xLeft
= (xScreen
- Width
) / 2;
276 /* Set screen attributes */
278 for (coPos
.Y
= yTop
; coPos
.Y
< yTop
+ Height
; coPos
.Y
++)
280 FillConsoleOutputAttribute(StdOutput
,
281 FOREGROUND_RED
| BACKGROUND_WHITE
,
287 DrawBox(xLeft
, yTop
, Width
, Height
);
289 /* Print message text */
294 p
= strchr(pnext
, '\n');
298 Length
= strlen(pnext
);
303 Length
= (ULONG
)(p
- pnext
);
310 WriteConsoleOutputCharacterA(StdOutput
,
317 if (LastLine
== TRUE
)
324 /* Print separator line and status text */
327 coPos
.Y
= yTop
+ Height
- 3;
329 FillConsoleOutputCharacterA(StdOutput
,
336 FillConsoleOutputCharacterA(StdOutput
,
342 coPos
.X
= xLeft
+ Width
- 1;
343 FillConsoleOutputCharacterA(StdOutput
,
351 WriteConsoleOutputCharacterA(StdOutput
,
353 min(strlen(Status
), (SIZE_T
)Width
- 4),
358 if (WaitEvent
== POPUP_WAIT_NONE
)
363 CONSOLE_ConInKey(Ir
);
365 if (WaitEvent
== POPUP_WAIT_ANY_KEY
||
366 Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D)
378 * FALSE: Don't quit setup.
381 ConfirmQuit(PINPUT_RECORD Ir
)
384 MUIDisplayError(ERROR_NOT_INSTALLED
, NULL
, POPUP_WAIT_NONE
);
388 CONSOLE_ConInKey(Ir
);
390 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
391 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
396 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
408 CheckUnattendedSetup(VOID
)
410 WCHAR UnattendInfPath
[MAX_PATH
];
417 if (DoesFileExist(SourcePath
.Buffer
, L
"unattend.inf") == FALSE
)
419 DPRINT("Does not exist: %S\\%S\n", SourcePath
.Buffer
, L
"unattend.inf");
423 wcscpy(UnattendInfPath
, SourcePath
.Buffer
);
424 wcscat(UnattendInfPath
, L
"\\unattend.inf");
426 /* Load 'unattend.inf' from install media. */
427 UnattendInf
= SetupOpenInfFileW(UnattendInfPath
,
433 if (UnattendInf
== INVALID_HANDLE_VALUE
)
435 DPRINT("SetupOpenInfFileW() failed\n");
439 /* Open 'Unattend' section */
440 if (!SetupFindFirstLineW(UnattendInf
, L
"Unattend", L
"Signature", &Context
))
442 DPRINT("SetupFindFirstLineW() failed for section 'Unattend'\n");
443 SetupCloseInfFile(UnattendInf
);
447 /* Get pointer 'Signature' key */
448 if (!INF_GetData(&Context
, NULL
, &Value
))
450 DPRINT("INF_GetData() failed for key 'Signature'\n");
451 SetupCloseInfFile(UnattendInf
);
455 /* Check 'Signature' string */
456 if (_wcsicmp(Value
, L
"$ReactOS$") != 0)
458 DPRINT("Signature not $ReactOS$\n");
459 SetupCloseInfFile(UnattendInf
);
463 /* Check if Unattend setup is enabled */
464 if (!SetupFindFirstLineW(UnattendInf
, L
"Unattend", L
"UnattendSetupEnabled", &Context
))
466 DPRINT("Can't find key 'UnattendSetupEnabled'\n");
467 SetupCloseInfFile(UnattendInf
);
471 if (!INF_GetData(&Context
, NULL
, &Value
))
473 DPRINT("Can't read key 'UnattendSetupEnabled'\n");
474 SetupCloseInfFile(UnattendInf
);
478 if (_wcsicmp(Value
, L
"yes") != 0)
480 DPRINT("Unattend setup is disabled by 'UnattendSetupEnabled' key!\n");
481 SetupCloseInfFile(UnattendInf
);
485 /* Search for 'DestinationDiskNumber' in the 'Unattend' section */
486 if (!SetupFindFirstLineW(UnattendInf
, L
"Unattend", L
"DestinationDiskNumber", &Context
))
488 DPRINT("SetupFindFirstLine() failed for key 'DestinationDiskNumber'\n");
489 SetupCloseInfFile(UnattendInf
);
493 if (!SetupGetIntField(&Context
, 1, &IntValue
))
495 DPRINT("SetupGetIntField() failed for key 'DestinationDiskNumber'\n");
496 SetupCloseInfFile(UnattendInf
);
500 UnattendDestinationDiskNumber
= (LONG
)IntValue
;
502 /* Search for 'DestinationPartitionNumber' in the 'Unattend' section */
503 if (!SetupFindFirstLineW(UnattendInf
, L
"Unattend", L
"DestinationPartitionNumber", &Context
))
505 DPRINT("SetupFindFirstLine() failed for key 'DestinationPartitionNumber'\n");
506 SetupCloseInfFile(UnattendInf
);
510 if (!SetupGetIntField(&Context
, 1, &IntValue
))
512 DPRINT("SetupGetIntField() failed for key 'DestinationPartitionNumber'\n");
513 SetupCloseInfFile(UnattendInf
);
517 UnattendDestinationPartitionNumber
= IntValue
;
519 /* Search for 'DestinationPartitionNumber' in the 'Unattend' section */
520 if (!SetupFindFirstLineW(UnattendInf
, L
"Unattend", L
"DestinationPartitionNumber", &Context
))
522 DPRINT("SetupFindFirstLine() failed for key 'DestinationPartitionNumber'\n");
523 SetupCloseInfFile(UnattendInf
);
527 /* Get pointer 'InstallationDirectory' key */
528 if (!INF_GetData(&Context
, NULL
, &Value
))
530 DPRINT("INF_GetData() failed for key 'InstallationDirectory'\n");
531 SetupCloseInfFile(UnattendInf
);
535 wcscpy(UnattendInstallationDirectory
, Value
);
537 IsUnattendedSetup
= TRUE
;
539 /* Search for 'MBRInstallType' in the 'Unattend' section */
540 if (SetupFindFirstLineW(UnattendInf
, L
"Unattend", L
"MBRInstallType", &Context
))
542 if (SetupGetIntField(&Context
, 1, &IntValue
))
544 UnattendMBRInstallType
= IntValue
;
548 /* Search for 'FormatPartition' in the 'Unattend' section */
549 if (SetupFindFirstLineW(UnattendInf
, L
"Unattend", L
"FormatPartition", &Context
))
551 if (SetupGetIntField(&Context
, 1, &IntValue
))
553 UnattendFormatPartition
= IntValue
;
557 if (SetupFindFirstLineW(UnattendInf
, L
"Unattend", L
"AutoPartition", &Context
))
559 if (SetupGetIntField(&Context
, 1, &IntValue
))
561 AutoPartition
= IntValue
;
565 /* search for LocaleID in the 'Unattend' section*/
566 if (SetupFindFirstLineW (UnattendInf
, L
"Unattend", L
"LocaleID", &Context
)){
567 if (INF_GetData (&Context
, NULL
, &Value
)){
568 LONG Id
= wcstol(Value
, NULL
, 16);
569 swprintf(LocaleID
,L
"%08lx", Id
);
573 SetupCloseInfFile(UnattendInf
);
575 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
);
615 LanguagePage(PINPUT_RECORD Ir
)
617 /* Initialize the computer settings list */
618 if (LanguageList
== NULL
)
620 LanguageList
= CreateLanguageList(SetupInf
, DefaultLanguage
);
622 if (LanguageList
== NULL
)
624 PopupError("Setup failed to initialize available translations", NULL
, NULL
, POPUP_WAIT_NONE
);
629 DrawGenericList(LanguageList
,
635 ScrollToPositionGenericList (LanguageList
, GetDefaultLanguageIndex());
637 MUIDisplayPage(LANGUAGE_PAGE
);
641 CONSOLE_ConInKey(Ir
);
643 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
644 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
)) /* DOWN */
647 SelectedLanguageId
= (PWCHAR
)GetListEntryUserData(GetCurrentListEntry(LanguageList
));
649 /* Redraw language selection page in native language */
650 MUIDisplayPage(LANGUAGE_PAGE
);
653 ScrollDownGenericList (LanguageList
);
655 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
656 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_UP
)) /* UP */
659 SelectedLanguageId
= (PWCHAR
)GetListEntryUserData(GetCurrentListEntry(LanguageList
));
661 /* Redraw language selection page in native language */
662 MUIDisplayPage(LANGUAGE_PAGE
);
665 ScrollUpGenericList (LanguageList
);
667 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
668 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_NEXT
)) /* PAGE DOWN */
670 ScrollPageDownGenericList (LanguageList
);
672 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
673 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_PRIOR
)) /* PAGE UP */
675 ScrollPageUpGenericList (LanguageList
);
677 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
678 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
680 if (ConfirmQuit(Ir
) == TRUE
)
683 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
685 SelectedLanguageId
= (PWCHAR
)GetListEntryUserData(GetCurrentListEntry(LanguageList
));
687 LanguageId
= (LANGID
)(wcstol(SelectedLanguageId
, NULL
, 16) & 0xFFFF);
689 if (wcscmp(SelectedLanguageId
, DefaultLanguage
))
695 SetConsoleCodePage();
699 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
> 0x60) && (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
< 0x7b))
702 GenericListKeyPress (LanguageList
, Ir
->Event
.KeyEvent
.uChar
.AsciiChar
);
713 * Number of the next page.
716 SetupStartPage(PINPUT_RECORD Ir
)
718 SYSTEM_DEVICE_INFORMATION Sdi
;
720 WCHAR FileNameBuffer
[MAX_PATH
];
725 PGENERIC_LIST_ENTRY ListEntry
;
728 CONSOLE_SetStatusText(MUIGetString(STRING_PLEASEWAIT
));
731 /* Check whether a harddisk is available */
732 Status
= NtQuerySystemInformation (SystemDeviceInformation
,
734 sizeof(SYSTEM_DEVICE_INFORMATION
),
737 if (!NT_SUCCESS (Status
))
739 CONSOLE_PrintTextXY(6, 15, "NtQuerySystemInformation() failed (Status 0x%08lx)", Status
);
740 MUIDisplayError(ERROR_DRIVE_INFORMATION
, Ir
, POPUP_WAIT_ENTER
);
744 if (Sdi
.NumberOfDisks
== 0)
746 MUIDisplayError(ERROR_NO_HDD
, Ir
, POPUP_WAIT_ENTER
);
750 /* Get the source path and source root path */
751 Status
= GetSourcePaths(&SourcePath
,
755 if (!NT_SUCCESS(Status
))
757 CONSOLE_PrintTextXY(6, 15, "GetSourcePaths() failed (Status 0x%08lx)", Status
);
758 MUIDisplayError(ERROR_NO_SOURCE_DRIVE
, Ir
, POPUP_WAIT_ENTER
);
764 CONSOLE_PrintTextXY(6, 15, "SourcePath: '%wZ'", &SourcePath
);
765 CONSOLE_PrintTextXY(6, 16, "SourceRootPath: '%wZ'", &SourceRootPath
);
766 CONSOLE_PrintTextXY(6, 17, "SourceRootDir: '%wZ'", &SourceRootDir
);
770 /* Load txtsetup.sif from install media. */
771 wcscpy(FileNameBuffer
, SourcePath
.Buffer
);
772 wcscat(FileNameBuffer
, L
"\\txtsetup.sif");
774 SetupInf
= SetupOpenInfFileW(FileNameBuffer
,
780 if (SetupInf
== INVALID_HANDLE_VALUE
)
782 MUIDisplayError(ERROR_LOAD_TXTSETUPSIF
, Ir
, POPUP_WAIT_ENTER
);
786 /* Open 'Version' section */
787 if (!SetupFindFirstLineW (SetupInf
, L
"Version", L
"Signature", &Context
))
789 MUIDisplayError(ERROR_CORRUPT_TXTSETUPSIF
, Ir
, POPUP_WAIT_ENTER
);
793 /* Get pointer 'Signature' key */
794 if (!INF_GetData (&Context
, NULL
, &Value
))
796 MUIDisplayError(ERROR_CORRUPT_TXTSETUPSIF
, Ir
, POPUP_WAIT_ENTER
);
800 /* Check 'Signature' string */
801 if (_wcsicmp(Value
, L
"$ReactOS$") != 0)
803 MUIDisplayError(ERROR_SIGNATURE_TXTSETUPSIF
, Ir
, POPUP_WAIT_ENTER
);
807 /* Open 'DiskSpaceRequirements' section */
808 if (!SetupFindFirstLineW(SetupInf
, L
"DiskSpaceRequirements", L
"FreeSysPartDiskSpace", &Context
))
810 MUIDisplayError(ERROR_CORRUPT_TXTSETUPSIF
, Ir
, POPUP_WAIT_ENTER
);
814 /* Get the 'FreeSysPartDiskSpace' value */
815 if (!SetupGetIntField(&Context
, 1, &IntValue
))
817 MUIDisplayError(ERROR_CORRUPT_TXTSETUPSIF
, Ir
, POPUP_WAIT_ENTER
);
821 RequiredPartitionDiskSpace
= (ULONG
)IntValue
;
823 /* Start PnP thread */
824 if (hPnpThread
!= INVALID_HANDLE_VALUE
)
826 NtResumeThread(hPnpThread
, NULL
);
827 hPnpThread
= INVALID_HANDLE_VALUE
;
830 CheckUnattendedSetup();
832 if (IsUnattendedSetup
)
835 //read options from inf
836 ComputerList
= CreateComputerTypeList(SetupInf
);
837 DisplayList
= CreateDisplayDriverList(SetupInf
);
838 KeyboardList
= CreateKeyboardDriverList(SetupInf
);
839 LayoutList
= CreateKeyboardLayoutList(SetupInf
, DefaultKBLayout
);
840 LanguageList
= CreateLanguageList(SetupInf
, DefaultLanguage
);
844 wcscpy(SelectedLanguageId
,LocaleID
);
847 /* first we hack LanguageList */
848 ListEntry
= GetFirstListEntry(LanguageList
);
850 while (ListEntry
!= NULL
)
852 if (!wcsicmp(LocaleID
, GetListEntryUserData(ListEntry
)))
854 DPRINT("found %S in LanguageList\n",GetListEntryUserData(ListEntry
));
855 SetCurrentListEntry(LanguageList
, ListEntry
);
859 ListEntry
= GetNextListEntry(ListEntry
);
862 ListEntry
= GetFirstListEntry(LayoutList
);
864 while (ListEntry
!= NULL
)
866 if (!wcsicmp(LocaleID
, GetListEntryUserData(ListEntry
)))
868 DPRINT("found %S in LayoutList\n",GetListEntryUserData(ListEntry
));
869 SetCurrentListEntry(LayoutList
, ListEntry
);
873 ListEntry
= GetNextListEntry(ListEntry
);
875 SetConsoleCodePage();
877 return INSTALL_INTRO_PAGE
;
880 return LANGUAGE_PAGE
;
890 IntroPage(PINPUT_RECORD Ir
)
892 MUIDisplayPage(START_PAGE
);
896 CONSOLE_ConInKey(Ir
);
898 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
899 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
901 if (ConfirmQuit(Ir
) == TRUE
)
906 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
908 return INSTALL_INTRO_PAGE
;
911 else if (toupper(Ir
->Event
.KeyEvent
.uChar
.AsciiChar
) == 'R') /* R */
913 return REPAIR_INTRO_PAGE
;
916 else if (toupper(Ir
->Event
.KeyEvent
.uChar
.AsciiChar
) == 'L') /* R */
929 * Back to main setup page.
932 LicensePage(PINPUT_RECORD Ir
)
934 MUIDisplayPage(LICENSE_PAGE
);
938 CONSOLE_ConInKey(Ir
);
940 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
951 RepairIntroPage(PINPUT_RECORD Ir
)
953 MUIDisplayPage(REPAIR_INTRO_PAGE
);
957 CONSOLE_ConInKey(Ir
);
959 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
963 else if (toupper(Ir
->Event
.KeyEvent
.uChar
.AsciiChar
) == 'U') /* U */
965 RepairUpdateFlag
= TRUE
;
966 return INSTALL_INTRO_PAGE
;
968 else if (toupper(Ir
->Event
.KeyEvent
.uChar
.AsciiChar
) == 'R') /* R */
972 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
973 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
)) /* ESC */
979 return REPAIR_INTRO_PAGE
;
984 InstallIntroPage(PINPUT_RECORD Ir
)
986 MUIDisplayPage(INSTALL_INTRO_PAGE
);
988 if (RepairUpdateFlag
)
990 //return SELECT_PARTITION_PAGE;
991 return DEVICE_SETTINGS_PAGE
;
994 if (IsUnattendedSetup
)
996 return SELECT_PARTITION_PAGE
;
1001 CONSOLE_ConInKey(Ir
);
1003 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1004 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1006 if (ConfirmQuit(Ir
) == TRUE
)
1011 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
1013 return DEVICE_SETTINGS_PAGE
;
1014 // return SCSI_CONTROLLER_PAGE;
1018 return INSTALL_INTRO_PAGE
;
1024 ScsiControllerPage(PINPUT_RECORD Ir
)
1026 SetTextXY(6, 8, "Setup detected the following mass storage devices:");
1028 /* FIXME: print loaded mass storage driver descriptions */
1030 SetTextXY(8, 10, "TEST device");
1034 SetStatusText(" ENTER = Continue F3 = Quit");
1040 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1041 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1043 if (ConfirmQuit(Ir
) == TRUE
)
1048 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
1050 return DEVICE_SETTINGS_PAGE
;
1054 return SCSI_CONTROLLER_PAGE
;
1060 DeviceSettingsPage(PINPUT_RECORD Ir
)
1062 static ULONG Line
= 16;
1063 MUIDisplayPage(DEVICE_SETTINGS_PAGE
);
1065 /* Initialize the computer settings list */
1066 if (ComputerList
== NULL
)
1068 ComputerList
= CreateComputerTypeList(SetupInf
);
1069 if (ComputerList
== NULL
)
1071 MUIDisplayError(ERROR_LOAD_COMPUTER
, Ir
, POPUP_WAIT_ENTER
);
1076 /* Initialize the display settings list */
1077 if (DisplayList
== NULL
)
1079 DisplayList
= CreateDisplayDriverList(SetupInf
);
1080 if (DisplayList
== NULL
)
1082 MUIDisplayError(ERROR_LOAD_DISPLAY
, Ir
, POPUP_WAIT_ENTER
);
1087 /* Initialize the keyboard settings list */
1088 if (KeyboardList
== NULL
)
1090 KeyboardList
= CreateKeyboardDriverList(SetupInf
);
1091 if (KeyboardList
== NULL
)
1093 MUIDisplayError(ERROR_LOAD_KEYBOARD
, Ir
, POPUP_WAIT_ENTER
);
1098 /* Initialize the keyboard layout list */
1099 if (LayoutList
== NULL
)
1101 LayoutList
= CreateKeyboardLayoutList(SetupInf
, DefaultKBLayout
);
1102 if (LayoutList
== NULL
)
1104 /* FIXME: report error */
1105 MUIDisplayError(ERROR_LOAD_KBLAYOUT
, Ir
, POPUP_WAIT_ENTER
);
1110 MUIDisplayPage(DEVICE_SETTINGS_PAGE
);
1113 CONSOLE_SetTextXY(25, 11, GetListEntryText(GetCurrentListEntry((ComputerList
))));
1114 CONSOLE_SetTextXY(25, 12, GetListEntryText(GetCurrentListEntry((DisplayList
))));
1115 CONSOLE_SetTextXY(25, 13, GetListEntryText(GetCurrentListEntry((KeyboardList
))));
1116 CONSOLE_SetTextXY(25, 14, GetListEntryText(GetCurrentListEntry((LayoutList
))));
1118 CONSOLE_InvertTextXY(24, Line
, 48, 1);
1120 if (RepairUpdateFlag
)
1122 return SELECT_PARTITION_PAGE
;
1127 CONSOLE_ConInKey(Ir
);
1129 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1130 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
)) /* DOWN */
1132 CONSOLE_NormalTextXY(24, Line
, 48, 1);
1136 else if (Line
== 16)
1141 CONSOLE_InvertTextXY(24, Line
, 48, 1);
1143 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1144 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_UP
)) /* UP */
1146 CONSOLE_NormalTextXY(24, Line
, 48, 1);
1150 else if (Line
== 16)
1155 CONSOLE_InvertTextXY(24, Line
, 48, 1);
1157 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1158 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1160 if (ConfirmQuit(Ir
) == TRUE
)
1165 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
1168 return COMPUTER_SETTINGS_PAGE
;
1169 else if (Line
== 12)
1170 return DISPLAY_SETTINGS_PAGE
;
1171 else if (Line
== 13)
1172 return KEYBOARD_SETTINGS_PAGE
;
1173 else if (Line
== 14)
1174 return LAYOUT_SETTINGS_PAGE
;
1175 else if (Line
== 16)
1176 return SELECT_PARTITION_PAGE
;
1180 return DEVICE_SETTINGS_PAGE
;
1185 ComputerSettingsPage(PINPUT_RECORD Ir
)
1187 MUIDisplayPage(COMPUTER_SETTINGS_PAGE
);
1189 DrawGenericList(ComputerList
,
1195 SaveGenericListState(ComputerList
);
1199 CONSOLE_ConInKey(Ir
);
1201 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1202 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
)) /* DOWN */
1204 ScrollDownGenericList (ComputerList
);
1206 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1207 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_UP
)) /* UP */
1209 ScrollUpGenericList (ComputerList
);
1211 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1212 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1214 if (ConfirmQuit(Ir
) == TRUE
)
1219 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1220 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
)) /* ESC */
1222 RestoreGenericListState(ComputerList
);
1223 return DEVICE_SETTINGS_PAGE
;
1225 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
1227 return DEVICE_SETTINGS_PAGE
;
1231 return COMPUTER_SETTINGS_PAGE
;
1236 DisplaySettingsPage(PINPUT_RECORD Ir
)
1238 MUIDisplayPage(DISPLAY_SETTINGS_PAGE
);
1240 DrawGenericList(DisplayList
,
1246 SaveGenericListState(DisplayList
);
1250 CONSOLE_ConInKey(Ir
);
1252 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1253 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
)) /* DOWN */
1255 ScrollDownGenericList (DisplayList
);
1257 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1258 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_UP
)) /* UP */
1260 ScrollUpGenericList (DisplayList
);
1262 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1263 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1265 if (ConfirmQuit(Ir
) == TRUE
)
1272 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1273 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
)) /* ESC */
1275 RestoreGenericListState(DisplayList
);
1276 return DEVICE_SETTINGS_PAGE
;
1278 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
1280 return DEVICE_SETTINGS_PAGE
;
1284 return DISPLAY_SETTINGS_PAGE
;
1289 KeyboardSettingsPage(PINPUT_RECORD Ir
)
1291 MUIDisplayPage(KEYBOARD_SETTINGS_PAGE
);
1293 DrawGenericList(KeyboardList
,
1299 SaveGenericListState(KeyboardList
);
1303 CONSOLE_ConInKey(Ir
);
1305 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1306 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
)) /* DOWN */
1308 ScrollDownGenericList (KeyboardList
);
1310 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1311 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_UP
)) /* UP */
1313 ScrollUpGenericList (KeyboardList
);
1315 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1316 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1318 if (ConfirmQuit(Ir
) == TRUE
)
1323 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1324 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
)) /* ESC */
1326 RestoreGenericListState(KeyboardList
);
1327 return DEVICE_SETTINGS_PAGE
;
1329 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
1331 return DEVICE_SETTINGS_PAGE
;
1335 return DISPLAY_SETTINGS_PAGE
;
1340 LayoutSettingsPage(PINPUT_RECORD Ir
)
1342 MUIDisplayPage(LAYOUT_SETTINGS_PAGE
);
1344 DrawGenericList(LayoutList
,
1350 SaveGenericListState(LayoutList
);
1354 CONSOLE_ConInKey(Ir
);
1356 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1357 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
)) /* DOWN */
1359 ScrollDownGenericList (LayoutList
);
1361 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1362 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_UP
)) /* UP */
1364 ScrollUpGenericList (LayoutList
);
1366 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1367 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_NEXT
)) /* PAGE DOWN */
1369 ScrollPageDownGenericList (LayoutList
);
1371 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1372 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_PRIOR
)) /* PAGE UP */
1374 ScrollPageUpGenericList (LayoutList
);
1376 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1377 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1379 if (ConfirmQuit(Ir
) == TRUE
)
1384 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1385 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
)) /* ESC */
1387 RestoreGenericListState(LayoutList
);
1388 return DEVICE_SETTINGS_PAGE
;
1390 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
1392 return DEVICE_SETTINGS_PAGE
;
1394 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
> 0x60) && (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
< 0x7b))
1397 GenericListKeyPress (LayoutList
, Ir
->Event
.KeyEvent
.uChar
.AsciiChar
);
1401 return DISPLAY_SETTINGS_PAGE
;
1404 static BOOL
IsDiskSizeValid(PPARTENTRY PartEntry
)
1407 /* check for unpartitioned space */
1408 m
= PartEntry
->UnpartitionedLength
;
1409 m
= (m
+ (1 << 19)) >> 20; /* in MBytes (rounded) */
1410 if( m
> RequiredPartitionDiskSpace
)
1415 // check for partitioned space
1416 m
= PartEntry
->PartInfo
[0].PartitionLength
.QuadPart
;
1417 m
= (m
+ (1 << 19)) >> 20; /* in MBytes (rounded) */
1418 if( m
< RequiredPartitionDiskSpace
)
1420 /* partition is too small so ask for another partion */
1421 DPRINT1("Partition too small");
1431 SelectPartitionPage(PINPUT_RECORD Ir
)
1433 MUIDisplayPage(SELECT_PARTITION_PAGE
);
1435 if (PartitionList
== NULL
)
1437 PartitionList
= CreatePartitionList (2,
1442 if (PartitionList
== NULL
)
1444 /* FIXME: show an error dialog */
1449 CheckActiveBootPartition (PartitionList
);
1451 DrawPartitionList (PartitionList
);
1453 /* Warn about partitions created by Linux Fdisk */
1454 if (WarnLinuxPartitions
== TRUE
&&
1455 CheckForLinuxFdiskPartitions(PartitionList
) == TRUE
)
1457 MUIDisplayError(ERROR_WARN_PARTITION
, NULL
, POPUP_WAIT_NONE
);
1461 CONSOLE_ConInKey(Ir
);
1463 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1464 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1468 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_RETURN
) /* ENTER */
1470 WarnLinuxPartitions
= FALSE
;
1471 return SELECT_PARTITION_PAGE
;
1476 if (IsUnattendedSetup
)
1478 if (!SelectPartition(PartitionList
, UnattendDestinationDiskNumber
, UnattendDestinationPartitionNumber
))
1482 PPARTENTRY PartEntry
= PartitionList
->CurrentPartition
;
1483 ULONG MaxSize
= (PartEntry
->UnpartitionedLength
+ (1 << 19)) >> 20; /* in MBytes (rounded) */
1484 if(!IsDiskSizeValid(PartitionList
->CurrentPartition
))
1486 MUIDisplayError(ERROR_INSUFFICIENT_DISKSPACE
, Ir
, POPUP_WAIT_ANY_KEY
);
1487 return SELECT_PARTITION_PAGE
; /* let the user select another partition */
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 */
1503 return(SELECT_FILE_SYSTEM_PAGE
);
1509 /* Update status text */
1510 if (PartitionList
->CurrentPartition
== NULL
||
1511 PartitionList
->CurrentPartition
->Unpartitioned
== TRUE
)
1513 CONSOLE_SetStatusText(MUIGetString(STRING_INSTALLCREATEPARTITION
));
1517 CONSOLE_SetStatusText(MUIGetString(STRING_INSTALLDELETEPARTITION
));
1520 CONSOLE_ConInKey(Ir
);
1522 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1523 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1525 if (ConfirmQuit(Ir
) == TRUE
)
1527 DestroyPartitionList (PartitionList
);
1528 PartitionList
= NULL
;
1534 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1535 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
)) /* DOWN */
1537 ScrollDownPartitionList (PartitionList
);
1539 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1540 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_UP
)) /* UP */
1542 ScrollUpPartitionList (PartitionList
);
1544 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_RETURN
) /* ENTER */
1546 if(!IsDiskSizeValid(PartitionList
->CurrentPartition
))
1548 MUIDisplayError(ERROR_INSUFFICIENT_DISKSPACE
, Ir
, POPUP_WAIT_ANY_KEY
);
1549 return SELECT_PARTITION_PAGE
; /* let the user select another partition */
1551 if (PartitionList
->CurrentPartition
== NULL
||
1552 PartitionList
->CurrentPartition
->Unpartitioned
== TRUE
)
1554 CreateNewPartition (PartitionList
,
1559 return SELECT_FILE_SYSTEM_PAGE
;
1561 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== 'C') /* C */
1563 if (PartitionList
->CurrentPartition
->Unpartitioned
== FALSE
)
1565 MUIDisplayError(ERROR_NEW_PARTITION
, Ir
, POPUP_WAIT_ANY_KEY
);
1566 return SELECT_PARTITION_PAGE
;
1569 return CREATE_PARTITION_PAGE
;
1571 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== 'D') /* D */
1573 if (PartitionList
->CurrentPartition
->Unpartitioned
== TRUE
)
1575 MUIDisplayError(ERROR_DELETE_SPACE
, Ir
, POPUP_WAIT_ANY_KEY
);
1576 return SELECT_PARTITION_PAGE
;
1579 return DELETE_PARTITION_PAGE
;
1583 return SELECT_PARTITION_PAGE
;
1588 DrawInputField(ULONG FieldLength
,
1599 memset(buf
, '_', sizeof(buf
));
1600 buf
[FieldLength
- strlen(FieldContent
)] = 0;
1601 strcat(buf
, FieldContent
);
1603 WriteConsoleOutputCharacterA (StdOutput
,
1611 #define PARTITION_SIZE_INPUT_FIELD_LENGTH 6
1612 /* Restriction for MaxSize: pow(10, PARTITION_SIZE_INPUT_FIELD_LENGTH)-1 */
1613 #define PARTITION_MAXSIZE 999999
1616 ShowPartitionSizeInputBox(SHORT Left
,
1640 DrawBox(Left
, Top
, Right
- Left
+ 1, Bottom
- Top
+ 1);
1645 strcpy (Buffer
, MUIGetString(STRING_PARTITIONSIZE
));
1646 iLeft
= coPos
.X
+ strlen (Buffer
) + 1;
1649 WriteConsoleOutputCharacterA(StdOutput
,
1655 sprintf (Buffer
, MUIGetString(STRING_MAXSIZE
), MaxSize
);
1656 coPos
.X
= iLeft
+ PARTITION_SIZE_INPUT_FIELD_LENGTH
+ 1;
1658 WriteConsoleOutputCharacterA(StdOutput
,
1664 sprintf(Buffer
, "%lu", MaxSize
);
1665 Index
= strlen(Buffer
);
1666 DrawInputField (PARTITION_SIZE_INPUT_FIELD_LENGTH
,
1673 CONSOLE_ConInKey(&Ir
);
1675 if ((Ir
.Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1676 (Ir
.Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1684 else if (Ir
.Event
.KeyEvent
.wVirtualKeyCode
== VK_RETURN
) /* ENTER */
1688 else if (Ir
.Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
) /* ESCAPE */
1696 else if ((Ir
.Event
.KeyEvent
.wVirtualKeyCode
== VK_BACK
) && /* BACKSPACE */
1702 DrawInputField (PARTITION_SIZE_INPUT_FIELD_LENGTH
,
1707 else if ((Ir
.Event
.KeyEvent
.uChar
.AsciiChar
!= 0x00) &&
1708 (Index
< PARTITION_SIZE_INPUT_FIELD_LENGTH
))
1710 ch
= Ir
.Event
.KeyEvent
.uChar
.AsciiChar
;
1712 if ((ch
>= '0') && (ch
<= '9'))
1718 DrawInputField (PARTITION_SIZE_INPUT_FIELD_LENGTH
,
1726 strcpy (InputBuffer
, Buffer
);
1731 CreatePartitionPage (PINPUT_RECORD Ir
)
1733 PDISKENTRY DiskEntry
;
1734 PPARTENTRY PartEntry
;
1737 CHAR InputBuffer
[50];
1743 if (PartitionList
== NULL
||
1744 PartitionList
->CurrentDisk
== NULL
||
1745 PartitionList
->CurrentPartition
== NULL
)
1747 /* FIXME: show an error dialog */
1751 DiskEntry
= PartitionList
->CurrentDisk
;
1752 PartEntry
= PartitionList
->CurrentPartition
;
1754 CONSOLE_SetStatusText(MUIGetString(STRING_PLEASEWAIT
));
1756 CONSOLE_SetTextXY(6, 8, MUIGetString(STRING_CHOOSENEWPARTITION
));
1759 if (DiskEntry
->DiskSize
>= 0x280000000ULL
) /* 10 GB */
1761 DiskSize
= (DiskEntry
->DiskSize
+ (1 << 29)) >> 30;
1762 Unit
= MUIGetString(STRING_GB
);
1767 DiskSize
= (DiskEntry
->DiskSize
+ (1 << 19)) >> 20;
1772 Unit
= MUIGetString(STRING_MB
);
1775 if (DiskEntry
->DriverName
.Length
> 0)
1777 CONSOLE_PrintTextXY(6, 10,
1778 MUIGetString(STRING_HDINFOPARTCREATE
),
1781 DiskEntry
->DiskNumber
,
1785 &DiskEntry
->DriverName
);
1789 CONSOLE_PrintTextXY(6, 10,
1790 MUIGetString(STRING_HDDINFOUNK1
),
1793 DiskEntry
->DiskNumber
,
1799 CONSOLE_SetTextXY(6, 12, MUIGetString(STRING_HDDSIZE
));
1802 CONSOLE_PrintTextXY(8, 10, "Maximum size of the new partition is %I64u MB",
1803 PartitionList
->CurrentPartition
->UnpartitionedLength
/ (1024*1024));
1806 CONSOLE_SetStatusText(MUIGetString(STRING_CREATEPARTITION
));
1808 PartEntry
= PartitionList
->CurrentPartition
;
1811 MaxSize
= (PartEntry
->UnpartitionedLength
+ (1 << 19)) >> 20; /* in MBytes (rounded) */
1813 if (MaxSize
> PARTITION_MAXSIZE
) MaxSize
= PARTITION_MAXSIZE
;
1815 ShowPartitionSizeInputBox (12, 14, xScreen
- 12, 17, /* left, top, right, bottom */
1816 MaxSize
, InputBuffer
, &Quit
, &Cancel
);
1820 if (ConfirmQuit (Ir
) == TRUE
)
1825 else if (Cancel
== TRUE
)
1827 return SELECT_PARTITION_PAGE
;
1831 PartSize
= atoi(InputBuffer
);
1839 if (PartSize
> MaxSize
)
1845 /* Convert to bytes */
1846 if (PartSize
== MaxSize
)
1848 /* Use all of the unpartitioned disk space */
1849 PartSize
= PartEntry
->UnpartitionedLength
;
1853 /* Round-up by cylinder size */
1854 PartSize
= (PartSize
* 1024 * 1024 + DiskEntry
->CylinderSize
- 1) /
1855 DiskEntry
->CylinderSize
* DiskEntry
->CylinderSize
;
1857 /* But never get larger than the unpartitioned disk space */
1858 if (PartSize
> PartEntry
->UnpartitionedLength
)
1859 PartSize
= PartEntry
->UnpartitionedLength
;
1862 DPRINT ("Partition size: %I64u bytes\n", PartSize
);
1864 CreateNewPartition (PartitionList
,
1868 return SELECT_PARTITION_PAGE
;
1872 return CREATE_PARTITION_PAGE
;
1877 DeletePartitionPage (PINPUT_RECORD Ir
)
1879 PDISKENTRY DiskEntry
;
1880 PPARTENTRY PartEntry
;
1887 if (PartitionList
== NULL
||
1888 PartitionList
->CurrentDisk
== NULL
||
1889 PartitionList
->CurrentPartition
== NULL
)
1891 /* FIXME: show an error dialog */
1895 DiskEntry
= PartitionList
->CurrentDisk
;
1896 PartEntry
= PartitionList
->CurrentPartition
;
1897 PartNumber
= PartitionList
->CurrentPartitionNumber
;
1899 MUIDisplayPage(DELETE_PARTITION_PAGE
);
1901 /* Determine partition type */
1903 if (PartEntry
->New
== TRUE
)
1905 PartType
= MUIGetString(STRING_UNFORMATTED
);
1907 else if (PartEntry
->Unpartitioned
== FALSE
)
1909 if ((PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_FAT_12
) ||
1910 (PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_FAT_16
) ||
1911 (PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_HUGE
) ||
1912 (PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_XINT13
))
1916 else if ((PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_FAT32
) ||
1917 (PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_FAT32_XINT13
))
1921 else if (PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_EXT2
)
1925 else if (PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_IFS
)
1927 PartType
= "NTFS"; /* FIXME: Not quite correct! */
1932 if (PartEntry
->PartInfo
[PartNumber
].PartitionLength
.QuadPart
>= 0x280000000LL
) /* 10 GB */
1934 PartSize
= (PartEntry
->PartInfo
[PartNumber
].PartitionLength
.QuadPart
+ (1 << 29)) >> 30;
1935 Unit
= MUIGetString(STRING_GB
);
1939 if (PartEntry
->PartInfo
[PartNumber
].PartitionLength
.QuadPart
>= 0xA00000LL
) /* 10 MB */
1941 PartSize
= (PartEntry
->PartInfo
[PartNumber
].PartitionLength
.QuadPart
+ (1 << 19)) >> 20;
1942 Unit
= MUIGetString(STRING_MB
);
1946 PartSize
= (PartEntry
->PartInfo
[PartNumber
].PartitionLength
.QuadPart
+ (1 << 9)) >> 10;
1947 Unit
= MUIGetString(STRING_KB
);
1950 if (PartType
== NULL
)
1952 CONSOLE_PrintTextXY(6, 10,
1953 MUIGetString(STRING_HDDINFOUNK2
),
1954 (PartEntry
->DriveLetter
[PartNumber
] == 0) ? '-' : PartEntry
->DriveLetter
[PartNumber
],
1955 (PartEntry
->DriveLetter
[PartNumber
] == 0) ? '-' : ':',
1956 PartEntry
->PartInfo
[PartNumber
].PartitionType
,
1962 CONSOLE_PrintTextXY(6, 10,
1963 " %c%c %s %I64u %s",
1964 (PartEntry
->DriveLetter
[PartNumber
] == 0) ? '-' : PartEntry
->DriveLetter
[PartNumber
],
1965 (PartEntry
->DriveLetter
[PartNumber
] == 0) ? '-' : ':',
1972 if (DiskEntry
->DiskSize
>= 0x280000000ULL
) /* 10 GB */
1974 DiskSize
= (DiskEntry
->DiskSize
+ (1 << 29)) >> 30;
1975 Unit
= MUIGetString(STRING_GB
);
1980 DiskSize
= (DiskEntry
->DiskSize
+ (1 << 19)) >> 20;
1985 Unit
= MUIGetString(STRING_MB
);
1988 if (DiskEntry
->DriverName
.Length
> 0)
1990 CONSOLE_PrintTextXY(6, 12,
1991 MUIGetString(STRING_HDINFOPARTDELETE
),
1994 DiskEntry
->DiskNumber
,
1998 &DiskEntry
->DriverName
);
2002 CONSOLE_PrintTextXY(6, 12,
2003 MUIGetString(STRING_HDDINFOUNK3
),
2006 DiskEntry
->DiskNumber
,
2014 CONSOLE_ConInKey(Ir
);
2016 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
2017 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
2019 if (ConfirmQuit (Ir
) == TRUE
)
2026 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
) /* ESC */
2028 return SELECT_PARTITION_PAGE
;
2030 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== 'D') /* D */
2032 DeleteCurrentPartition (PartitionList
);
2034 return SELECT_PARTITION_PAGE
;
2038 return DELETE_PARTITION_PAGE
;
2043 SelectFileSystemPage (PINPUT_RECORD Ir
)
2045 PDISKENTRY DiskEntry
;
2046 PPARTENTRY PartEntry
;
2054 if (PartitionList
== NULL
||
2055 PartitionList
->CurrentDisk
== NULL
||
2056 PartitionList
->CurrentPartition
== NULL
)
2058 /* FIXME: show an error dialog */
2062 DiskEntry
= PartitionList
->CurrentDisk
;
2063 PartEntry
= PartitionList
->CurrentPartition
;
2064 PartNumber
= PartitionList
->CurrentPartitionNumber
;
2066 /* adjust disk size */
2067 if (DiskEntry
->DiskSize
>= 0x280000000ULL
) /* 10 GB */
2069 DiskSize
= (DiskEntry
->DiskSize
+ (1 << 29)) >> 30;
2070 DiskUnit
= MUIGetString(STRING_GB
);
2074 DiskSize
= (DiskEntry
->DiskSize
+ (1 << 19)) >> 20;
2075 DiskUnit
= MUIGetString(STRING_MB
);
2078 /* adjust partition size */
2079 if (PartEntry
->PartInfo
[PartNumber
].PartitionLength
.QuadPart
>= 0x280000000LL
) /* 10 GB */
2081 PartSize
= (PartEntry
->PartInfo
[PartNumber
].PartitionLength
.QuadPart
+ (1 << 29)) >> 30;
2082 PartUnit
= MUIGetString(STRING_GB
);
2086 PartSize
= (PartEntry
->PartInfo
[PartNumber
].PartitionLength
.QuadPart
+ (1 << 19)) >> 20;
2087 PartUnit
= MUIGetString(STRING_MB
);
2090 /* adjust partition type */
2091 if ((PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_FAT_12
) ||
2092 (PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_FAT_16
) ||
2093 (PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_HUGE
) ||
2094 (PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_XINT13
))
2098 else if ((PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_FAT32
) ||
2099 (PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_FAT32_XINT13
))
2103 else if (PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_EXT2
)
2107 else if (PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_IFS
)
2109 PartType
= "NTFS"; /* FIXME: Not quite correct! */
2111 else if (PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_ENTRY_UNUSED
)
2113 PartType
= MUIGetString(STRING_FORMATUNUSED
);
2117 PartType
= MUIGetString(STRING_FORMATUNKNOWN
);
2120 if (PartEntry
->AutoCreate
== TRUE
)
2122 CONSOLE_SetTextXY(6, 8, MUIGetString(STRING_NEWPARTITION
));
2125 CONSOLE_PrintTextXY(8, 10, "Partition %lu (%I64u %s) %s of",
2126 PartEntry
->PartInfo
[PartNumber
].PartitionNumber
,
2132 CONSOLE_PrintTextXY(8, 10, MUIGetString(STRING_HDINFOPARTZEROED
),
2133 DiskEntry
->DiskNumber
,
2139 &DiskEntry
->DriverName
);
2141 CONSOLE_SetTextXY(6, 12, MUIGetString(STRING_PARTFORMAT
));
2144 PartEntry
->AutoCreate
= FALSE
;
2146 else if (PartEntry
->New
== TRUE
)
2148 CONSOLE_SetTextXY(6, 8, MUIGetString(STRING_NONFORMATTEDPART
));
2149 CONSOLE_SetTextXY(6, 10, MUIGetString(STRING_PARTFORMAT
));
2153 CONSOLE_SetTextXY(6, 8, MUIGetString(STRING_INSTALLONPART
));
2155 if (PartType
== NULL
)
2157 CONSOLE_PrintTextXY(8, 10,
2158 MUIGetString(STRING_HDDINFOUNK4
),
2159 (PartEntry
->DriveLetter
[PartNumber
] == 0) ? '-' : PartEntry
->DriveLetter
[PartNumber
],
2160 (PartEntry
->DriveLetter
[PartNumber
] == 0) ? '-' : ':',
2161 PartEntry
->PartInfo
[PartNumber
].PartitionType
,
2167 CONSOLE_PrintTextXY(8, 10,
2169 (PartEntry
->DriveLetter
[PartNumber
] == 0) ? '-' : PartEntry
->DriveLetter
[PartNumber
],
2170 (PartEntry
->DriveLetter
[PartNumber
] == 0) ? '-' : ':',
2176 CONSOLE_PrintTextXY(6, 12, MUIGetString(STRING_HDINFOPARTEXISTS
),
2177 DiskEntry
->DiskNumber
,
2183 &DiskEntry
->DriverName
);
2186 MUIDisplayPage(SELECT_FILE_SYSTEM_PAGE
);
2188 if (FileSystemList
== NULL
)
2190 FileSystemList
= CreateFileSystemList (6, 26, PartEntry
->New
, L
"FAT");
2191 if (FileSystemList
== NULL
)
2193 /* FIXME: show an error dialog */
2197 /* FIXME: Add file systems to list */
2199 DrawFileSystemList (FileSystemList
);
2201 if (RepairUpdateFlag
)
2203 return CHECK_FILE_SYSTEM_PAGE
;
2204 //return SELECT_PARTITION_PAGE;
2207 if (IsUnattendedSetup
)
2209 if (UnattendFormatPartition
)
2211 return FORMAT_PARTITION_PAGE
;
2214 return(CHECK_FILE_SYSTEM_PAGE
);
2219 CONSOLE_ConInKey(Ir
);
2221 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
2222 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
2224 if (ConfirmQuit (Ir
) == TRUE
)
2231 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
2232 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
)) /* ESC */
2234 return SELECT_PARTITION_PAGE
;
2236 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
2237 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
)) /* DOWN */
2239 ScrollDownFileSystemList (FileSystemList
);
2241 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
2242 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_UP
)) /* UP */
2244 ScrollUpFileSystemList (FileSystemList
);
2246 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_RETURN
) /* ENTER */
2248 if (!FileSystemList
->Selected
->FormatFunc
)
2250 return CHECK_FILE_SYSTEM_PAGE
;
2254 return FORMAT_PARTITION_PAGE
;
2259 return SELECT_FILE_SYSTEM_PAGE
;
2264 FormatPartitionPage (PINPUT_RECORD Ir
)
2266 WCHAR PathBuffer
[MAX_PATH
];
2267 PDISKENTRY DiskEntry
;
2268 PPARTENTRY PartEntry
;
2278 MUIDisplayPage(FORMAT_PARTITION_PAGE
);
2280 if (PartitionList
== NULL
||
2281 PartitionList
->CurrentDisk
== NULL
||
2282 PartitionList
->CurrentPartition
== NULL
)
2284 /* FIXME: show an error dialog */
2288 DiskEntry
= PartitionList
->CurrentDisk
;
2289 PartEntry
= PartitionList
->CurrentPartition
;
2290 PartNum
= PartitionList
->CurrentPartitionNumber
;
2294 if (!IsUnattendedSetup
)
2296 CONSOLE_ConInKey(Ir
);
2299 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
2300 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
2302 if (ConfirmQuit (Ir
) == TRUE
)
2309 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_RETURN
|| IsUnattendedSetup
) /* ENTER */
2311 CONSOLE_SetStatusText(MUIGetString(STRING_PLEASEWAIT
));
2313 if (PartEntry
->PartInfo
[PartNum
].PartitionType
== PARTITION_ENTRY_UNUSED
)
2315 if (wcscmp(FileSystemList
->Selected
->FileSystem
, L
"FAT") == 0)
2317 if (PartEntry
->PartInfo
[PartNum
].PartitionLength
.QuadPart
< (4200LL * 1024LL))
2319 /* FAT12 CHS partition (disk is smaller than 4.1MB) */
2320 PartEntry
->PartInfo
[PartNum
].PartitionType
= PARTITION_FAT_12
;
2322 else if (PartEntry
->PartInfo
[PartNum
].StartingOffset
.QuadPart
< (1024LL * 255LL * 63LL * 512LL))
2324 /* Partition starts below the 8.4GB boundary ==> CHS partition */
2326 if (PartEntry
->PartInfo
[PartNum
].PartitionLength
.QuadPart
< (32LL * 1024LL * 1024LL))
2328 /* FAT16 CHS partition (partiton size < 32MB) */
2329 PartEntry
->PartInfo
[PartNum
].PartitionType
= PARTITION_FAT_16
;
2331 else if (PartEntry
->PartInfo
[PartNum
].PartitionLength
.QuadPart
< (512LL * 1024LL * 1024LL))
2333 /* FAT16 CHS partition (partition size < 512MB) */
2334 PartEntry
->PartInfo
[PartNum
].PartitionType
= PARTITION_HUGE
;
2338 /* FAT32 CHS partition (partition size >= 512MB) */
2339 PartEntry
->PartInfo
[PartNum
].PartitionType
= PARTITION_FAT32
;
2344 /* Partition starts above the 8.4GB boundary ==> LBA partition */
2346 if (PartEntry
->PartInfo
[PartNum
].PartitionLength
.QuadPart
< (512LL * 1024LL * 1024LL))
2348 /* FAT16 LBA partition (partition size < 512MB) */
2349 PartEntry
->PartInfo
[PartNum
].PartitionType
= PARTITION_XINT13
;
2353 /* FAT32 LBA partition (partition size >= 512MB) */
2354 PartEntry
->PartInfo
[PartNum
].PartitionType
= PARTITION_FAT32_XINT13
;
2358 else if (wcscmp(FileSystemList
->Selected
->FileSystem
, L
"EXT2") == 0)
2359 PartEntry
->PartInfo
[PartNum
].PartitionType
= PARTITION_EXT2
;
2360 else if (!FileSystemList
->Selected
->FormatFunc
)
2364 CheckActiveBootPartition (PartitionList
);
2367 CONSOLE_PrintTextXY(6, 12,
2368 "Disk: %I64u Cylinder: %I64u Track: %I64u",
2369 DiskEntry
->DiskSize
,
2370 DiskEntry
->CylinderSize
,
2371 DiskEntry
->TrackSize
);
2374 DiskEntry
= PartitionList
->CurrentDisk
;
2375 Entry
= DiskEntry
->PartListHead
.Flink
;
2377 while (Entry
!= &DiskEntry
->PartListHead
)
2379 PartEntry
= CONTAINING_RECORD(Entry
, PARTENTRY
, ListEntry
);
2381 if (PartEntry
->Unpartitioned
== FALSE
)
2383 for (i
= 0; i
< 4; i
++)
2385 CONSOLE_PrintTextXY(6, Line
,
2386 "%2u: %2u %c %12I64u %12I64u %2u %c",
2388 PartEntry
->PartInfo
[i
].PartitionNumber
,
2389 PartEntry
->PartInfo
[i
].BootIndicator
? 'A' : '-',
2390 PartEntry
->PartInfo
[i
].StartingOffset
.QuadPart
,
2391 PartEntry
->PartInfo
[i
].PartitionLength
.QuadPart
,
2392 PartEntry
->PartInfo
[i
].PartitionType
,
2393 PartEntry
->PartInfo
[i
].RewritePartition
? '*' : ' ');
2401 Entry
= Entry
->Flink
;
2404 /* Restore the old entry */
2405 PartEntry
= PartitionList
->CurrentPartition
;
2408 if (WritePartitionsToDisk (PartitionList
) == FALSE
)
2410 DPRINT ("WritePartitionsToDisk() failed\n");
2411 MUIDisplayError(ERROR_WRITE_PTABLE
, Ir
, POPUP_WAIT_ENTER
);
2415 /* Set DestinationRootPath */
2416 RtlFreeUnicodeString (&DestinationRootPath
);
2417 swprintf (PathBuffer
,
2418 L
"\\Device\\Harddisk%lu\\Partition%lu",
2419 PartitionList
->CurrentDisk
->DiskNumber
,
2420 PartitionList
->CurrentPartition
->PartInfo
[PartNum
].PartitionNumber
);
2421 RtlCreateUnicodeString (&DestinationRootPath
,
2423 DPRINT ("DestinationRootPath: %wZ\n", &DestinationRootPath
);
2426 /* Set SystemRootPath */
2427 RtlFreeUnicodeString (&SystemRootPath
);
2428 swprintf (PathBuffer
,
2429 L
"\\Device\\Harddisk%lu\\Partition%lu",
2430 PartitionList
->ActiveBootDisk
->DiskNumber
,
2431 PartitionList
->ActiveBootPartition
->
2432 PartInfo
[PartitionList
->ActiveBootPartitionNumber
].PartitionNumber
);
2433 RtlCreateUnicodeString (&SystemRootPath
,
2435 DPRINT ("SystemRootPath: %wZ\n", &SystemRootPath
);
2438 if (FileSystemList
->Selected
->FormatFunc
)
2440 Status
= FormatPartition(&DestinationRootPath
, FileSystemList
->Selected
);
2441 if (!NT_SUCCESS(Status
))
2443 DPRINT1("FormatPartition() failed with status 0x%08lx\n", Status
);
2444 /* FIXME: show an error dialog */
2448 PartEntry
->New
= FALSE
;
2450 CheckActiveBootPartition(PartitionList
);
2453 /* Install MBR if necessary */
2454 if (DiskEntry
->NoMbr
&&
2455 DiskEntry
->BiosDiskNumber
== 0)
2457 wcscpy(PathBuffer
, SourceRootPath
.Buffer
);
2458 wcscat(PathBuffer
, L
"\\loader\\dosmbr.bin");
2460 DPRINT("Install MBR bootcode: %S ==> %S\n",
2461 PathBuffer
, DestinationRootPath
.Buffer
);
2463 /* Install MBR bootcode */
2464 Status
= InstallMbrBootCodeToDisk(PathBuffer
, DestinationRootPath
.Buffer
);
2465 if (!NT_SUCCESS (Status
))
2467 DPRINT1("InstallMbrBootCodeToDisk() failed (Status %lx)\n",
2472 DiskEntry
->NoMbr
= FALSE
;
2475 if (wcscmp(FileSystemList
->Selected
->FileSystem
, L
"FAT") == 0)
2477 /* FIXME: Install boot code. This is a hack! */
2478 if ((PartEntry
->PartInfo
[PartNum
].PartitionType
== PARTITION_FAT32_XINT13
) ||
2479 (PartEntry
->PartInfo
[PartNum
].PartitionType
== PARTITION_FAT32
))
2481 wcscpy(PathBuffer
, SourceRootPath
.Buffer
);
2482 wcscat(PathBuffer
, L
"\\loader\\fat32.bin");
2484 DPRINT("Install FAT32 bootcode: %S ==> %S\n", PathBuffer
,
2485 DestinationRootPath
.Buffer
);
2486 Status
= InstallFat32BootCodeToDisk(PathBuffer
,
2487 DestinationRootPath
.Buffer
);
2489 if (!NT_SUCCESS(Status
))
2491 DPRINT1("InstallFat32BootCodeToDisk() failed with status 0x%08lx\n", Status
);
2492 /* FIXME: show an error dialog */
2493 DestroyFileSystemList(FileSystemList
);
2494 FileSystemList
= NULL
;
2500 wcscpy(PathBuffer
, SourceRootPath
.Buffer
);
2501 wcscat(PathBuffer
, L
"\\loader\\fat.bin");
2503 DPRINT("Install FAT bootcode: %S ==> %S\n", PathBuffer
,
2504 DestinationRootPath
.Buffer
);
2505 Status
= InstallFat16BootCodeToDisk(PathBuffer
,
2506 DestinationRootPath
.Buffer
);
2508 if (!NT_SUCCESS(Status
))
2510 DPRINT1("InstallFat16BootCodeToDisk() failed with status 0x%.08x\n", Status
);
2511 /* FIXME: show an error dialog */
2512 DestroyFileSystemList(FileSystemList
);
2513 FileSystemList
= NULL
;
2518 else if (wcscmp(FileSystemList
->Selected
->FileSystem
, L
"EXT2") == 0)
2520 wcscpy(PathBuffer
, SourceRootPath
.Buffer
);
2521 wcscat(PathBuffer
, L
"\\loader\\ext2.bin");
2523 DPRINT("Install EXT2 bootcode: %S ==> %S\n", PathBuffer
,
2524 DestinationRootPath
.Buffer
);
2525 Status
= InstallFat32BootCodeToDisk(PathBuffer
,
2526 DestinationRootPath
.Buffer
);
2528 if (!NT_SUCCESS(Status
))
2530 DPRINT1("InstallFat32BootCodeToDisk() failed with status 0x%08lx\n", Status
);
2531 /* FIXME: show an error dialog */
2532 DestroyFileSystemList(FileSystemList
);
2533 FileSystemList
= NULL
;
2537 else if (FileSystemList
->Selected
->FormatFunc
)
2539 DestroyFileSystemList(FileSystemList
);
2540 FileSystemList
= NULL
;
2545 CONSOLE_SetStatusText(" Done. Press any key ...");
2546 CONSOLE_ConInKey(Ir
);
2549 DestroyFileSystemList(FileSystemList
);
2550 FileSystemList
= NULL
;
2551 return INSTALL_DIRECTORY_PAGE
;
2555 return FORMAT_PARTITION_PAGE
;
2560 CheckFileSystemPage(PINPUT_RECORD Ir
)
2562 PFILE_SYSTEM_ITEM CurrentFileSystem
;
2563 WCHAR PathBuffer
[MAX_PATH
];
2564 CHAR Buffer
[MAX_PATH
];
2566 UCHAR PartNum
= PartitionList
->CurrentPartitionNumber
;
2568 /* FIXME: code duplicated in FormatPartitionPage */
2569 /* Set DestinationRootPath */
2570 RtlFreeUnicodeString(&DestinationRootPath
);
2571 swprintf(PathBuffer
,
2572 L
"\\Device\\Harddisk%lu\\Partition%lu",
2573 PartitionList
->CurrentDisk
->DiskNumber
,
2574 PartitionList
->CurrentPartition
->PartInfo
[PartNum
].PartitionNumber
);
2575 RtlCreateUnicodeString(&DestinationRootPath
, PathBuffer
);
2576 DPRINT("DestinationRootPath: %wZ\n", &DestinationRootPath
);
2578 /* Set SystemRootPath */
2579 RtlFreeUnicodeString(&SystemRootPath
);
2580 swprintf(PathBuffer
,
2581 L
"\\Device\\Harddisk%lu\\Partition%lu",
2582 PartitionList
->ActiveBootDisk
->DiskNumber
,
2583 PartitionList
->ActiveBootPartition
->PartInfo
[PartNum
].PartitionNumber
);
2584 RtlCreateUnicodeString(&SystemRootPath
, PathBuffer
);
2585 DPRINT("SystemRootPath: %wZ\n", &SystemRootPath
);
2587 CONSOLE_SetTextXY(6, 8, MUIGetString(STRING_CHECKINGPART
));
2589 CONSOLE_SetStatusText(MUIGetString(STRING_PLEASEWAIT
));
2591 /* WRONG: first filesystem is not necesseraly the one of the current partition! */
2592 CurrentFileSystem
= CONTAINING_RECORD(FileSystemList
->ListHead
.Flink
, FILE_SYSTEM_ITEM
, ListEntry
);
2594 if (!CurrentFileSystem
->ChkdskFunc
)
2597 "Setup is currently unable to check a partition formatted in %S.\n"
2599 " \x07 Press ENTER to continue Setup.\n"
2600 " \x07 Press F3 to quit Setup.",
2601 CurrentFileSystem
->FileSystem
);
2604 MUIGetString(STRING_QUITCONTINUE
),
2605 NULL
, POPUP_WAIT_NONE
);
2609 CONSOLE_ConInKey(Ir
);
2611 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00 &&
2612 Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
) /* F3 */
2614 if (ConfirmQuit(Ir
))
2617 return CHECK_FILE_SYSTEM_PAGE
;
2619 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== VK_RETURN
) /* ENTER */
2621 return INSTALL_DIRECTORY_PAGE
;
2627 Status
= ChkdskPartition(&DestinationRootPath
, CurrentFileSystem
);
2628 if (!NT_SUCCESS(Status
))
2630 DPRINT("ChkdskPartition() failed with status 0x%08lx\n", Status
);
2631 sprintf(Buffer
, "Setup failed to verify the selected partition.\n"
2632 "(Status 0x%08lx).\n", Status
);
2635 MUIGetString(STRING_REBOOTCOMPUTER
),
2636 Ir
, POPUP_WAIT_ENTER
);
2641 return INSTALL_DIRECTORY_PAGE
;
2647 InstallDirectoryPage1(PWCHAR InstallDir
, PDISKENTRY DiskEntry
, PPARTENTRY PartEntry
, UCHAR PartNum
)
2649 WCHAR PathBuffer
[MAX_PATH
];
2651 /* Create 'InstallPath' string */
2652 RtlFreeUnicodeString(&InstallPath
);
2653 RtlCreateUnicodeString(&InstallPath
,
2656 /* Create 'DestinationPath' string */
2657 RtlFreeUnicodeString(&DestinationPath
);
2658 wcscpy(PathBuffer
, DestinationRootPath
.Buffer
);
2660 if (InstallDir
[0] != L
'\\')
2661 wcscat(PathBuffer
, L
"\\");
2663 wcscat(PathBuffer
, InstallDir
);
2664 RtlCreateUnicodeString(&DestinationPath
, PathBuffer
);
2666 /* Create 'DestinationArcPath' */
2667 RtlFreeUnicodeString(&DestinationArcPath
);
2668 swprintf(PathBuffer
,
2669 L
"multi(0)disk(0)rdisk(%lu)partition(%lu)",
2670 DiskEntry
->BiosDiskNumber
,
2671 PartEntry
->PartInfo
[PartNum
].PartitionNumber
);
2673 if (InstallDir
[0] != L
'\\')
2674 wcscat(PathBuffer
, L
"\\");
2676 wcscat(PathBuffer
, InstallDir
);
2677 RtlCreateUnicodeString(&DestinationArcPath
, PathBuffer
);
2679 return(PREPARE_COPY_PAGE
);
2684 InstallDirectoryPage(PINPUT_RECORD Ir
)
2686 PDISKENTRY DiskEntry
;
2687 PPARTENTRY PartEntry
;
2688 WCHAR InstallDir
[51];
2693 if (PartitionList
== NULL
||
2694 PartitionList
->CurrentDisk
== NULL
||
2695 PartitionList
->CurrentPartition
== NULL
)
2697 /* FIXME: show an error dialog */
2701 DiskEntry
= PartitionList
->CurrentDisk
;
2702 PartEntry
= PartitionList
->CurrentPartition
;
2704 /* Search for 'DefaultPath' in the 'SetupData' section */
2705 if (!SetupFindFirstLineW (SetupInf
, L
"SetupData", L
"DefaultPath", &Context
))
2707 MUIDisplayError(ERROR_FIND_SETUPDATA
, Ir
, POPUP_WAIT_ENTER
);
2711 /* Read the 'DefaultPath' data */
2712 if (INF_GetData (&Context
, NULL
, &DefaultPath
))
2714 wcscpy(InstallDir
, DefaultPath
);
2718 wcscpy(InstallDir
, L
"\\ReactOS");
2721 Length
= wcslen(InstallDir
);
2722 CONSOLE_SetInputTextXY(8, 11, 51, InstallDir
);
2723 MUIDisplayPage(INSTALL_DIRECTORY_PAGE
);
2725 if (IsUnattendedSetup
)
2727 return(InstallDirectoryPage1 (InstallDir
, DiskEntry
, PartEntry
, PartitionList
->CurrentPartitionNumber
));
2732 CONSOLE_ConInKey(Ir
);
2734 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
2735 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
2737 if (ConfirmQuit(Ir
) == TRUE
)
2742 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2744 return (InstallDirectoryPage1 (InstallDir
, DiskEntry
, PartEntry
, PartitionList
->CurrentPartitionNumber
));
2746 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x08) /* BACKSPACE */
2751 InstallDir
[Length
] = 0;
2752 CONSOLE_SetInputTextXY(8, 11, 51, InstallDir
);
2755 else if (isprint(Ir
->Event
.KeyEvent
.uChar
.AsciiChar
))
2759 InstallDir
[Length
] = (WCHAR
)Ir
->Event
.KeyEvent
.uChar
.AsciiChar
;
2761 InstallDir
[Length
] = 0;
2762 CONSOLE_SetInputTextXY(8, 11, 51, InstallDir
);
2767 return(INSTALL_DIRECTORY_PAGE
);
2771 AddSectionToCopyQueueCab(HINF InfFile
,
2773 PWCHAR SourceCabinet
,
2774 PCUNICODE_STRING DestinationPath
,
2777 INFCONTEXT FilesContext
;
2778 INFCONTEXT DirContext
;
2780 PWCHAR FileKeyValue
;
2782 PWCHAR TargetFileName
;
2784 /* Search for the SectionName section */
2785 if (!SetupFindFirstLineW (InfFile
, SectionName
, NULL
, &FilesContext
))
2788 sprintf(Buffer
, MUIGetString(STRING_TXTSETUPFAILED
), SectionName
);
2789 PopupError(Buffer
, MUIGetString(STRING_REBOOTCOMPUTER
), Ir
, POPUP_WAIT_ENTER
);
2794 * Enumerate the files in the section
2795 * and add them to the file queue.
2799 /* Get source file name and target directory id */
2800 if (!INF_GetData (&FilesContext
, &FileKeyName
, &FileKeyValue
))
2802 /* FIXME: Handle error! */
2803 DPRINT1("INF_GetData() failed\n");
2807 /* Get optional target file name */
2808 if (!INF_GetDataField (&FilesContext
, 2, &TargetFileName
))
2809 TargetFileName
= NULL
;
2811 DPRINT ("FileKeyName: '%S' FileKeyValue: '%S'\n", FileKeyName
, FileKeyValue
);
2813 /* Lookup target directory */
2814 if (!SetupFindFirstLineW (InfFile
, L
"Directories", FileKeyValue
, &DirContext
))
2816 /* FIXME: Handle error! */
2817 DPRINT1("SetupFindFirstLine() failed\n");
2821 if (!INF_GetData (&DirContext
, NULL
, &DirKeyValue
))
2823 /* FIXME: Handle error! */
2824 DPRINT1("INF_GetData() failed\n");
2828 if (!SetupQueueCopy(SetupFileQueue
,
2830 SourceRootPath
.Buffer
,
2831 SourceRootDir
.Buffer
,
2836 /* FIXME: Handle error! */
2837 DPRINT1("SetupQueueCopy() failed\n");
2839 } while (SetupFindNextLine(&FilesContext
, &FilesContext
));
2845 AddSectionToCopyQueue(HINF InfFile
,
2847 PWCHAR SourceCabinet
,
2848 PCUNICODE_STRING DestinationPath
,
2851 INFCONTEXT FilesContext
;
2852 INFCONTEXT DirContext
;
2854 PWCHAR FileKeyValue
;
2856 PWCHAR TargetFileName
;
2859 return AddSectionToCopyQueueCab(InfFile
, L
"SourceFiles", SourceCabinet
, DestinationPath
, Ir
);
2861 /* Search for the SectionName section */
2862 if (!SetupFindFirstLineW (InfFile
, SectionName
, NULL
, &FilesContext
))
2865 sprintf(Buffer
, MUIGetString(STRING_TXTSETUPFAILED
), SectionName
);
2866 PopupError(Buffer
, MUIGetString(STRING_REBOOTCOMPUTER
), Ir
, POPUP_WAIT_ENTER
);
2871 * Enumerate the files in the section
2872 * and add them to the file queue.
2876 /* Get source file name and target directory id */
2877 if (!INF_GetData (&FilesContext
, &FileKeyName
, &FileKeyValue
))
2879 /* FIXME: Handle error! */
2880 DPRINT1("INF_GetData() failed\n");
2884 /* Get target directory id */
2885 if (!INF_GetDataField (&FilesContext
, 13, &FileKeyValue
))
2887 /* FIXME: Handle error! */
2888 DPRINT1("INF_GetData() failed\n");
2892 /* Get optional target file name */
2893 if (!INF_GetDataField (&FilesContext
, 11, &TargetFileName
))
2894 TargetFileName
= NULL
;
2895 else if (!*TargetFileName
)
2896 TargetFileName
= NULL
;
2898 DPRINT ("FileKeyName: '%S' FileKeyValue: '%S'\n", FileKeyName
, FileKeyValue
);
2900 /* Lookup target directory */
2901 if (!SetupFindFirstLineW (InfFile
, L
"Directories", FileKeyValue
, &DirContext
))
2903 /* FIXME: Handle error! */
2904 DPRINT1("SetupFindFirstLine() failed\n");
2908 if (!INF_GetData (&DirContext
, NULL
, &DirKeyValue
))
2910 /* FIXME: Handle error! */
2911 DPRINT1("INF_GetData() failed\n");
2915 if (!SetupQueueCopy(SetupFileQueue
,
2917 SourceRootPath
.Buffer
,
2918 SourceRootDir
.Buffer
,
2923 /* FIXME: Handle error! */
2924 DPRINT1("SetupQueueCopy() failed\n");
2926 } while (SetupFindNextLine(&FilesContext
, &FilesContext
));
2932 PrepareCopyPageInfFile(HINF InfFile
,
2933 PWCHAR SourceCabinet
,
2936 WCHAR PathBuffer
[MAX_PATH
];
2937 INFCONTEXT DirContext
;
2938 PWCHAR AdditionalSectionName
= NULL
;
2943 /* Add common files */
2944 if (!AddSectionToCopyQueue(InfFile
, L
"SourceDisksFiles", SourceCabinet
, &DestinationPath
, Ir
))
2947 /* Add specific files depending of computer type */
2948 if (SourceCabinet
== NULL
)
2950 if (!ProcessComputerFiles(InfFile
, ComputerList
, &AdditionalSectionName
))
2953 if (AdditionalSectionName
)
2955 if (!AddSectionToCopyQueue(InfFile
, AdditionalSectionName
, SourceCabinet
, &DestinationPath
, Ir
))
2960 /* Create directories */
2964 * Install directories like '\reactos\test' are not handled yet.
2967 /* Get destination path */
2968 wcscpy(PathBuffer
, DestinationPath
.Buffer
);
2970 /* Remove trailing backslash */
2971 Length
= wcslen(PathBuffer
);
2972 if ((Length
> 0) && (PathBuffer
[Length
- 1] == '\\'))
2974 PathBuffer
[Length
- 1] = 0;
2977 /* Create the install directory */
2978 Status
= SetupCreateDirectory(PathBuffer
);
2979 if (!NT_SUCCESS(Status
) && Status
!= STATUS_OBJECT_NAME_COLLISION
)
2981 DPRINT("Creating directory '%S' failed: Status = 0x%08lx", PathBuffer
, Status
);
2982 MUIDisplayError(ERROR_CREATE_INSTALL_DIR
, Ir
, POPUP_WAIT_ENTER
);
2986 /* Search for the 'Directories' section */
2987 if (!SetupFindFirstLineW(InfFile
, L
"Directories", NULL
, &DirContext
))
2991 MUIDisplayError(ERROR_CABINET_SECTION
, Ir
, POPUP_WAIT_ENTER
);
2995 MUIDisplayError(ERROR_TXTSETUP_SECTION
, Ir
, POPUP_WAIT_ENTER
);
3001 /* Enumerate the directory values and create the subdirectories */
3004 if (!INF_GetData (&DirContext
, NULL
, &KeyValue
))
3010 if (KeyValue
[0] == L
'\\' && KeyValue
[1] != 0)
3012 DPRINT("Absolute Path: '%S'\n", KeyValue
);
3014 wcscpy(PathBuffer
, DestinationRootPath
.Buffer
);
3015 wcscat(PathBuffer
, KeyValue
);
3017 DPRINT("FullPath: '%S'\n", PathBuffer
);
3019 else if (KeyValue
[0] != L
'\\')
3021 DPRINT("RelativePath: '%S'\n", KeyValue
);
3022 wcscpy(PathBuffer
, DestinationPath
.Buffer
);
3023 wcscat(PathBuffer
, L
"\\");
3024 wcscat(PathBuffer
, KeyValue
);
3026 DPRINT("FullPath: '%S'\n", PathBuffer
);
3028 Status
= SetupCreateDirectory(PathBuffer
);
3029 if (!NT_SUCCESS(Status
) && Status
!= STATUS_OBJECT_NAME_COLLISION
)
3031 DPRINT("Creating directory '%S' failed: Status = 0x%08lx", PathBuffer
, Status
);
3032 MUIDisplayError(ERROR_CREATE_DIR
, Ir
, POPUP_WAIT_ENTER
);
3036 } while (SetupFindNextLine (&DirContext
, &DirContext
));
3042 PrepareCopyPage(PINPUT_RECORD Ir
)
3045 WCHAR PathBuffer
[MAX_PATH
];
3046 INFCONTEXT CabinetsContext
;
3052 MUIDisplayPage(PREPARE_COPY_PAGE
);
3054 /* Create the file queue */
3055 SetupFileQueue
= SetupOpenFileQueue();
3056 if (SetupFileQueue
== NULL
)
3058 MUIDisplayError(ERROR_COPY_QUEUE
, Ir
, POPUP_WAIT_ENTER
);
3062 if (!PrepareCopyPageInfFile(SetupInf
, NULL
, Ir
))
3067 /* Search for the 'Cabinets' section */
3068 if (!SetupFindFirstLineW (SetupInf
, L
"Cabinets", NULL
, &CabinetsContext
))
3070 return FILE_COPY_PAGE
;
3074 * Enumerate the directory values in the 'Cabinets'
3075 * section and parse their inf files.
3079 if (!INF_GetData (&CabinetsContext
, NULL
, &KeyValue
))
3082 wcscpy(PathBuffer
, SourcePath
.Buffer
);
3083 wcscat(PathBuffer
, L
"\\");
3084 wcscat(PathBuffer
, KeyValue
);
3087 CabinetInitialize();
3088 CabinetSetEventHandlers(NULL
, NULL
, NULL
);
3089 CabinetSetCabinetName(PathBuffer
);
3091 if (CabinetOpen() == CAB_STATUS_SUCCESS
)
3093 DPRINT("Cabinet %S\n", CabinetGetCabinetName());
3095 InfFileData
= CabinetGetCabinetReservedArea(&InfFileSize
);
3096 if (InfFileData
== NULL
)
3098 MUIDisplayError(ERROR_CABINET_SCRIPT
, Ir
, POPUP_WAIT_ENTER
);
3104 DPRINT("Cannot open cabinet: %S.\n", CabinetGetCabinetName());
3105 MUIDisplayError(ERROR_CABINET_MISSING
, Ir
, POPUP_WAIT_ENTER
);
3109 InfHandle
= INF_OpenBufferedFileA((CHAR
*) InfFileData
,
3116 if (InfHandle
== INVALID_HANDLE_VALUE
)
3118 MUIDisplayError(ERROR_INVALID_CABINET_INF
, Ir
, POPUP_WAIT_ENTER
);
3124 if (!PrepareCopyPageInfFile(InfHandle
, KeyValue
, Ir
))
3129 } while (SetupFindNextLine (&CabinetsContext
, &CabinetsContext
));
3131 return FILE_COPY_PAGE
;
3136 SetupUpdateMemoryInfo(IN PCOPYCONTEXT CopyContext
,
3139 SYSTEM_PERFORMANCE_INFORMATION PerfInfo
;
3141 /* Get the memory information from the system */
3142 NtQuerySystemInformation(SystemPerformanceInformation
,
3147 /* Check if this is initial setup */
3150 /* Set maximum limits to be total RAM pages */
3151 ProgressSetStepCount(CopyContext
->MemoryBars
[0], PerfInfo
.CommitLimit
);
3152 ProgressSetStepCount(CopyContext
->MemoryBars
[1], PerfInfo
.CommitLimit
);
3153 ProgressSetStepCount(CopyContext
->MemoryBars
[2], PerfInfo
.CommitLimit
);
3156 /* Set current values */
3157 ProgressSetStep(CopyContext
->MemoryBars
[0], PerfInfo
.PagedPoolPages
+ PerfInfo
.NonPagedPoolPages
);
3158 ProgressSetStep(CopyContext
->MemoryBars
[1], PerfInfo
.ResidentSystemCachePage
);
3159 ProgressSetStep(CopyContext
->MemoryBars
[2], PerfInfo
.AvailablePages
);
3162 static UINT CALLBACK
3163 FileCopyCallback(PVOID Context
,
3168 PCOPYCONTEXT CopyContext
;
3170 CopyContext
= (PCOPYCONTEXT
)Context
;
3172 switch (Notification
)
3174 case SPFILENOTIFY_STARTSUBQUEUE
:
3175 CopyContext
->TotalOperations
= (ULONG
)Param2
;
3176 ProgressSetStepCount(CopyContext
->ProgressBar
,
3177 CopyContext
->TotalOperations
);
3178 SetupUpdateMemoryInfo(CopyContext
, TRUE
);
3181 case SPFILENOTIFY_STARTCOPY
:
3182 /* Display copy message */
3183 CONSOLE_SetStatusText(MUIGetString(STRING_COPYING
), (PWSTR
)Param1
);
3184 SetupUpdateMemoryInfo(CopyContext
, FALSE
);
3187 case SPFILENOTIFY_ENDCOPY
:
3188 CopyContext
->CompletedOperations
++;
3189 ProgressNextStep(CopyContext
->ProgressBar
);
3190 SetupUpdateMemoryInfo(CopyContext
, FALSE
);
3199 FileCopyPage(PINPUT_RECORD Ir
)
3201 COPYCONTEXT CopyContext
;
3202 unsigned int mem_bar_width
;
3204 MUIDisplayPage(FILE_COPY_PAGE
);
3206 /* Create context for the copy process */
3207 CopyContext
.DestinationRootPath
= DestinationRootPath
.Buffer
;
3208 CopyContext
.InstallPath
= InstallPath
.Buffer
;
3209 CopyContext
.TotalOperations
= 0;
3210 CopyContext
.CompletedOperations
= 0;
3212 /* Create the progress bar as well */
3213 CopyContext
.ProgressBar
= CreateProgressBar(13,
3220 MUIGetString(STRING_SETUPCOPYINGFILES
));
3222 // fit memory bars to screen width, distribute them uniform
3223 mem_bar_width
= (xScreen
- 26) / 5;
3224 mem_bar_width
-= mem_bar_width
% 2; // make even
3225 /* ATTENTION: The following progress bars are debug stuff, which should not be translated!! */
3226 /* Create the paged pool progress bar */
3227 CopyContext
.MemoryBars
[0] = CreateProgressBar(13,
3236 /* Create the non paged pool progress bar */
3237 CopyContext
.MemoryBars
[1] = CreateProgressBar((xScreen
/ 2)- (mem_bar_width
/ 2),
3239 (xScreen
/ 2) + (mem_bar_width
/ 2),
3241 (xScreen
/ 2)- (mem_bar_width
/ 2),
3246 /* Create the global memory progress bar */
3247 CopyContext
.MemoryBars
[2] = CreateProgressBar(xScreen
- 13 - mem_bar_width
,
3251 xScreen
- 13 - mem_bar_width
,
3256 /* Do the file copying */
3257 SetupCommitFileQueueW(NULL
,
3262 /* If we get here, we're done, so cleanup the queue and progress bar */
3263 SetupCloseFileQueue(SetupFileQueue
);
3264 DestroyProgressBar(CopyContext
.ProgressBar
);
3265 DestroyProgressBar(CopyContext
.MemoryBars
[0]);
3266 DestroyProgressBar(CopyContext
.MemoryBars
[1]);
3267 DestroyProgressBar(CopyContext
.MemoryBars
[2]);
3269 /* Go display the next page */
3270 return REGISTRY_PAGE
;
3274 RegistryPage(PINPUT_RECORD Ir
)
3276 INFCONTEXT InfContext
;
3283 MUIDisplayPage(REGISTRY_PAGE
);
3285 if (RepairUpdateFlag
)
3287 return SUCCESS_PAGE
;
3290 if (!SetInstallPathValue(&DestinationPath
))
3292 DPRINT("SetInstallPathValue() failed\n");
3293 MUIDisplayError(ERROR_INITIALIZE_REGISTRY
, Ir
, POPUP_WAIT_ENTER
);
3297 /* Create the default hives */
3299 Status
= NtInitializeRegistry(CM_BOOT_FLAG_SETUP
);
3300 if (!NT_SUCCESS(Status
))
3302 DPRINT("NtInitializeRegistry() failed (Status %lx)\n", Status
);
3303 MUIDisplayError(ERROR_CREATE_HIVE
, Ir
, POPUP_WAIT_ENTER
);
3307 RegInitializeRegistry();
3310 /* Update registry */
3311 CONSOLE_SetStatusText(MUIGetString(STRING_REGHIVEUPDATE
));
3313 if (!SetupFindFirstLineW(SetupInf
, L
"HiveInfs.Install", NULL
, &InfContext
))
3315 DPRINT1("SetupFindFirstLine() failed\n");
3316 MUIDisplayError(ERROR_FIND_REGISTRY
, Ir
, POPUP_WAIT_ENTER
);
3322 INF_GetDataField (&InfContext
, 0, &Action
);
3323 INF_GetDataField (&InfContext
, 1, &File
);
3324 INF_GetDataField (&InfContext
, 2, &Section
);
3326 DPRINT("Action: %S File: %S Section %S\n", Action
, File
, Section
);
3328 if (Action
== NULL
) break; // Hackfix
3330 if (!_wcsicmp (Action
, L
"AddReg"))
3334 else if (!_wcsicmp (Action
, L
"DelReg"))
3343 CONSOLE_SetStatusText(MUIGetString(STRING_IMPORTFILE
), File
);
3345 if (!ImportRegistryFile(File
, Section
, LanguageId
, Delete
))
3347 DPRINT("Importing %S failed\n", File
);
3349 MUIDisplayError(ERROR_IMPORT_HIVE
, Ir
, POPUP_WAIT_ENTER
);
3352 } while (SetupFindNextLine (&InfContext
, &InfContext
));
3354 /* Update display registry settings */
3355 CONSOLE_SetStatusText(MUIGetString(STRING_DISPLAYETTINGSUPDATE
));
3356 if (!ProcessDisplayRegistry(SetupInf
, DisplayList
))
3358 MUIDisplayError(ERROR_UPDATE_DISPLAY_SETTINGS
, Ir
, POPUP_WAIT_ENTER
);
3362 /* Set the locale */
3363 CONSOLE_SetStatusText(MUIGetString(STRING_LOCALESETTINGSUPDATE
));
3364 if (!ProcessLocaleRegistry(LanguageList
))
3366 MUIDisplayError(ERROR_UPDATE_LOCALESETTINGS
, Ir
, POPUP_WAIT_ENTER
);
3370 /* Add keyboard layouts */
3371 CONSOLE_SetStatusText(MUIGetString(STRING_ADDKBLAYOUTS
));
3372 if (!AddKeyboardLayouts())
3374 MUIDisplayError(ERROR_ADDING_KBLAYOUTS
, Ir
, POPUP_WAIT_ENTER
);
3380 if (!SetGeoID(MUIGetGeoID()))
3382 MUIDisplayError(ERROR_UPDATE_GEOID
, Ir
, POPUP_WAIT_ENTER
);
3386 if (!IsUnattendedSetup
){
3388 /* Update keyboard layout settings */
3389 CONSOLE_SetStatusText(MUIGetString(STRING_KEYBOARDSETTINGSUPDATE
));
3390 if (!ProcessKeyboardLayoutRegistry(LayoutList
))
3392 MUIDisplayError(ERROR_UPDATE_KBSETTINGS
, Ir
, POPUP_WAIT_ENTER
);
3396 /* Add codepage information to registry */
3397 CONSOLE_SetStatusText(MUIGetString(STRING_CODEPAGEINFOUPDATE
));
3400 MUIDisplayError(ERROR_ADDING_CODEPAGE
, Ir
, POPUP_WAIT_ENTER
);
3404 /* Update the mounted devices list */
3405 SetMountedDeviceValues(PartitionList
);
3407 CONSOLE_SetStatusText(MUIGetString(STRING_DONE
));
3409 return BOOT_LOADER_PAGE
;
3414 BootLoaderPage(PINPUT_RECORD Ir
)
3416 UCHAR PartitionType
;
3417 BOOLEAN InstallOnFloppy
;
3420 CONSOLE_SetStatusText(MUIGetString(STRING_PLEASEWAIT
));
3422 PartitionType
= PartitionList
->ActiveBootPartition
->
3423 PartInfo
[PartitionList
->ActiveBootPartitionNumber
].PartitionType
;
3425 if (IsUnattendedSetup
)
3427 if (UnattendMBRInstallType
== 0) /* skip MBR installation */
3429 return SUCCESS_PAGE
;
3431 else if (UnattendMBRInstallType
== 1) /* install on floppy */
3433 return BOOT_LOADER_FLOPPY_PAGE
;
3437 if (PartitionType
== PARTITION_ENTRY_UNUSED
)
3439 DPRINT("Error: active partition invalid (unused)\n");
3440 InstallOnFloppy
= TRUE
;
3442 else if (PartitionType
== 0x0A)
3444 /* OS/2 boot manager partition */
3445 DPRINT("Found OS/2 boot manager partition\n");
3446 InstallOnFloppy
= TRUE
;
3448 else if (PartitionType
== 0x83)
3450 /* Linux ext2 partition */
3451 DPRINT("Found Linux ext2 partition\n");
3452 InstallOnFloppy
= TRUE
;
3454 else if (PartitionType
== PARTITION_IFS
)
3456 /* NTFS partition */
3457 DPRINT("Found NTFS partition\n");
3458 InstallOnFloppy
= TRUE
;
3460 else if ((PartitionType
== PARTITION_FAT_12
) ||
3461 (PartitionType
== PARTITION_FAT_16
) ||
3462 (PartitionType
== PARTITION_HUGE
) ||
3463 (PartitionType
== PARTITION_XINT13
) ||
3464 (PartitionType
== PARTITION_FAT32
) ||
3465 (PartitionType
== PARTITION_FAT32_XINT13
))
3467 DPRINT("Found FAT partition\n");
3468 InstallOnFloppy
= FALSE
;
3472 /* Unknown partition */
3473 DPRINT("Unknown partition found\n");
3474 InstallOnFloppy
= TRUE
;
3477 if (InstallOnFloppy
== TRUE
)
3479 return BOOT_LOADER_FLOPPY_PAGE
;
3482 /* Unattended install on hdd? */
3483 if (IsUnattendedSetup
&& UnattendMBRInstallType
== 2)
3485 return BOOT_LOADER_HARDDISK_PAGE
;
3488 MUIDisplayPage(BOOT_LOADER_PAGE
);
3489 CONSOLE_InvertTextXY(8, Line
, 60, 1);
3493 CONSOLE_ConInKey(Ir
);
3495 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
3496 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
)) /* DOWN */
3498 CONSOLE_NormalTextXY(8, Line
, 60, 1);
3501 if (Line
<12) Line
=14;
3502 if (Line
>14) Line
=12;
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);
3512 if (Line
<12) Line
=14;
3513 if (Line
>14) Line
=12;
3515 CONSOLE_InvertTextXY(8, Line
, 60, 1);
3517 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
3518 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
3520 if (ConfirmQuit(Ir
) == TRUE
)
3525 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
3529 return BOOT_LOADER_HARDDISK_PAGE
;
3531 else if (Line
== 13)
3533 return BOOT_LOADER_FLOPPY_PAGE
;
3535 else if (Line
== 14)
3537 return SUCCESS_PAGE
;
3540 return BOOT_LOADER_PAGE
;
3544 return BOOT_LOADER_PAGE
;
3549 BootLoaderFloppyPage(PINPUT_RECORD Ir
)
3553 MUIDisplayPage(BOOT_LOADER_FLOPPY_PAGE
);
3555 // SetStatusText(" Please wait...");
3559 CONSOLE_ConInKey(Ir
);
3561 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
3562 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
3564 if (ConfirmQuit(Ir
) == TRUE
)
3569 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
3571 if (DoesFileExist(L
"\\Device\\Floppy0", L
"\\") == FALSE
)
3573 MUIDisplayError(ERROR_NO_FLOPPY
, Ir
, POPUP_WAIT_ENTER
);
3574 return BOOT_LOADER_FLOPPY_PAGE
;
3577 Status
= InstallFatBootcodeToFloppy(&SourceRootPath
, &DestinationArcPath
);
3578 if (!NT_SUCCESS(Status
))
3580 /* Print error message */
3581 return BOOT_LOADER_FLOPPY_PAGE
;
3584 return SUCCESS_PAGE
;
3588 return BOOT_LOADER_FLOPPY_PAGE
;
3593 BootLoaderHarddiskPage(PINPUT_RECORD Ir
)
3595 UCHAR PartitionType
;
3598 PartitionType
= PartitionList
->ActiveBootPartition
->
3599 PartInfo
[PartitionList
->ActiveBootPartitionNumber
].PartitionType
;
3600 if ((PartitionType
== PARTITION_FAT_12
) ||
3601 (PartitionType
== PARTITION_FAT_16
) ||
3602 (PartitionType
== PARTITION_HUGE
) ||
3603 (PartitionType
== PARTITION_XINT13
) ||
3604 (PartitionType
== PARTITION_FAT32
) ||
3605 (PartitionType
== PARTITION_FAT32_XINT13
))
3607 Status
= InstallFatBootcodeToPartition(&SystemRootPath
,
3609 &DestinationArcPath
,
3611 if (!NT_SUCCESS(Status
))
3613 MUIDisplayError(ERROR_INSTALL_BOOTCODE
, Ir
, POPUP_WAIT_ENTER
);
3617 return SUCCESS_PAGE
;
3621 MUIDisplayError(ERROR_WRITE_BOOT
, Ir
, POPUP_WAIT_ENTER
);
3625 return BOOT_LOADER_HARDDISK_PAGE
;
3630 QuitPage(PINPUT_RECORD Ir
)
3632 MUIDisplayPage(QUIT_PAGE
);
3634 /* Destroy partition list */
3635 if (PartitionList
!= NULL
)
3637 DestroyPartitionList (PartitionList
);
3638 PartitionList
= NULL
;
3641 /* Destroy filesystem list */
3642 if (FileSystemList
!= NULL
)
3644 DestroyFileSystemList (FileSystemList
);
3645 FileSystemList
= NULL
;
3648 /* Destroy computer settings list */
3649 if (ComputerList
!= NULL
)
3651 DestroyGenericList(ComputerList
, TRUE
);
3652 ComputerList
= NULL
;
3655 /* Destroy display settings list */
3656 if (DisplayList
!= NULL
)
3658 DestroyGenericList(DisplayList
, TRUE
);
3662 /* Destroy keyboard settings list */
3663 if (KeyboardList
!= NULL
)
3665 DestroyGenericList(KeyboardList
, TRUE
);
3666 KeyboardList
= NULL
;
3669 /* Destroy keyboard layout list */
3670 if (LayoutList
!= NULL
)
3672 DestroyGenericList(LayoutList
, TRUE
);
3676 if (LanguageList
!= NULL
)
3678 DestroyGenericList(LanguageList
, FALSE
);
3679 LanguageList
= NULL
;
3682 CONSOLE_SetStatusText(MUIGetString(STRING_REBOOTCOMPUTER2
));
3686 CONSOLE_ConInKey(Ir
);
3688 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
3697 SuccessPage(PINPUT_RECORD Ir
)
3699 MUIDisplayPage(SUCCESS_PAGE
);
3701 if (IsUnattendedSetup
)
3708 CONSOLE_ConInKey(Ir
);
3710 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
3719 FlushPage(PINPUT_RECORD Ir
)
3721 MUIDisplayPage(FLUSH_PAGE
);
3727 PnpEventThread(IN LPVOID lpParameter
);
3737 NtQuerySystemTime(&Time
);
3739 Status
= RtlCreateUserThread(NtCurrentProcess(), NULL
, TRUE
, 0, 0, 0, PnpEventThread
, &SetupInf
, &hPnpThread
, NULL
);
3740 if (!NT_SUCCESS(Status
))
3741 hPnpThread
= INVALID_HANDLE_VALUE
;
3743 if (!CONSOLE_Init())
3745 PrintString(MUIGetString(STRING_CONSOLEFAIL1
));
3746 PrintString(MUIGetString(STRING_CONSOLEFAIL2
));
3747 PrintString(MUIGetString(STRING_CONSOLEFAIL3
));
3749 /* Raise a hard error (crash the system/BSOD) */
3750 NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED
,
3754 /* Initialize global unicode strings */
3755 RtlInitUnicodeString(&SourcePath
, NULL
);
3756 RtlInitUnicodeString(&SourceRootPath
, NULL
);
3757 RtlInitUnicodeString(&SourceRootDir
, NULL
);
3758 RtlInitUnicodeString(&InstallPath
, NULL
);
3759 RtlInitUnicodeString(&DestinationPath
, NULL
);
3760 RtlInitUnicodeString(&DestinationArcPath
, NULL
);
3761 RtlInitUnicodeString(&DestinationRootPath
, NULL
);
3762 RtlInitUnicodeString(&SystemRootPath
, NULL
);
3764 /* Hide the cursor */
3765 CONSOLE_SetCursorType(TRUE
, FALSE
);
3768 while (Page
!= REBOOT_PAGE
)
3770 CONSOLE_ClearScreen();
3773 //CONSOLE_SetUnderlinedTextXY(4, 3, " ReactOS " KERNEL_VERSION_STR " Setup ");
3780 Page
= SetupStartPage(&Ir
);
3785 Page
= LanguagePage(&Ir
);
3790 Page
= LicensePage(&Ir
);
3795 Page
= IntroPage(&Ir
);
3799 case INSTALL_INTRO_PAGE
:
3800 Page
= InstallIntroPage(&Ir
);
3804 case SCSI_CONTROLLER_PAGE
:
3805 Page
= ScsiControllerPage(&Ir
);
3810 case OEM_DRIVER_PAGE
:
3811 Page
= OemDriverPage(&Ir
);
3815 case DEVICE_SETTINGS_PAGE
:
3816 Page
= DeviceSettingsPage(&Ir
);
3819 case COMPUTER_SETTINGS_PAGE
:
3820 Page
= ComputerSettingsPage(&Ir
);
3823 case DISPLAY_SETTINGS_PAGE
:
3824 Page
= DisplaySettingsPage(&Ir
);
3827 case KEYBOARD_SETTINGS_PAGE
:
3828 Page
= KeyboardSettingsPage(&Ir
);
3831 case LAYOUT_SETTINGS_PAGE
:
3832 Page
= LayoutSettingsPage(&Ir
);
3835 case SELECT_PARTITION_PAGE
:
3836 Page
= SelectPartitionPage(&Ir
);
3839 case CREATE_PARTITION_PAGE
:
3840 Page
= CreatePartitionPage(&Ir
);
3843 case DELETE_PARTITION_PAGE
:
3844 Page
= DeletePartitionPage(&Ir
);
3847 case SELECT_FILE_SYSTEM_PAGE
:
3848 Page
= SelectFileSystemPage(&Ir
);
3851 case FORMAT_PARTITION_PAGE
:
3852 Page
= (PAGE_NUMBER
) FormatPartitionPage(&Ir
);
3855 case CHECK_FILE_SYSTEM_PAGE
:
3856 Page
= (PAGE_NUMBER
) CheckFileSystemPage(&Ir
);
3859 case INSTALL_DIRECTORY_PAGE
:
3860 Page
= InstallDirectoryPage(&Ir
);
3863 case PREPARE_COPY_PAGE
:
3864 Page
= PrepareCopyPage(&Ir
);
3867 case FILE_COPY_PAGE
:
3868 Page
= FileCopyPage(&Ir
);
3872 Page
= RegistryPage(&Ir
);
3875 case BOOT_LOADER_PAGE
:
3876 Page
= BootLoaderPage(&Ir
);
3879 case BOOT_LOADER_FLOPPY_PAGE
:
3880 Page
= BootLoaderFloppyPage(&Ir
);
3883 case BOOT_LOADER_HARDDISK_PAGE
:
3884 Page
= BootLoaderHarddiskPage(&Ir
);
3888 case REPAIR_INTRO_PAGE
:
3889 Page
= RepairIntroPage(&Ir
);
3893 Page
= SuccessPage(&Ir
);
3897 Page
= FlushPage(&Ir
);
3901 Page
= QuitPage(&Ir
);
3911 /* Avoid bugcheck */
3912 Time
.QuadPart
+= 50000000;
3913 NtDelayExecution(FALSE
, &Time
);
3916 NtShutdownSystem(ShutdownReboot
);
3917 NtTerminateProcess(NtCurrentProcess(), 0);
3924 NtProcessStartup(PPEB Peb
)
3926 RtlNormalizeProcessParams(Peb
->ProcessParameters
);
3928 ProcessHeap
= Peb
->ProcessHeap
;
3929 INF_SetHeap(ProcessHeap
);
3932 #endif /* __REACTOS__ */