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)
41 /* GLOBALS ******************************************************************/
44 UNICODE_STRING SourceRootPath
;
45 UNICODE_STRING SourceRootDir
;
46 UNICODE_STRING SourcePath
;
47 BOOLEAN IsUnattendedSetup
= FALSE
;
48 LONG UnattendDestinationDiskNumber
;
49 LONG UnattendDestinationPartitionNumber
;
50 LONG UnattendMBRInstallType
= -1;
51 LONG UnattendFormatPartition
= 0;
52 LONG AutoPartition
= 0;
53 WCHAR UnattendInstallationDirectory
[MAX_PATH
];
54 PWCHAR SelectedLanguageId
;
56 WCHAR DefaultLanguage
[20];
57 WCHAR DefaultKBLayout
[20];
58 BOOLEAN RepairUpdateFlag
= FALSE
;
59 HANDLE hPnpThread
= INVALID_HANDLE_VALUE
;
60 PPARTLIST PartitionList
= NULL
;
62 /* LOCALS *******************************************************************/
64 static PFILE_SYSTEM_LIST FileSystemList
= NULL
;
66 static UNICODE_STRING InstallPath
;
68 /* Path to the install directory */
69 static UNICODE_STRING DestinationPath
;
70 static UNICODE_STRING DestinationArcPath
;
71 static UNICODE_STRING DestinationRootPath
;
73 /* Path to the active partition (boot manager) */
74 static UNICODE_STRING SystemRootPath
;
78 static HSPFILEQ SetupFileQueue
= NULL
;
80 static BOOLEAN WarnLinuxPartitions
= TRUE
;
82 static PGENERIC_LIST ComputerList
= NULL
;
83 static PGENERIC_LIST DisplayList
= NULL
;
84 static PGENERIC_LIST KeyboardList
= NULL
;
85 static PGENERIC_LIST LayoutList
= NULL
;
86 static PGENERIC_LIST LanguageList
= NULL
;
88 static LANGID LanguageId
= 0;
90 static ULONG RequiredPartitionDiskSpace
= ~0;
92 /* FUNCTIONS ****************************************************************/
95 PrintString(char* fmt
,...)
99 UNICODE_STRING UnicodeString
;
100 ANSI_STRING AnsiString
;
103 vsprintf(buffer
, fmt
, ap
);
106 RtlInitAnsiString(&AnsiString
, buffer
);
107 RtlAnsiStringToUnicodeString(&UnicodeString
, &AnsiString
, TRUE
);
108 NtDisplayString(&UnicodeString
);
109 RtlFreeUnicodeString(&UnicodeString
);
114 DrawBox(IN SHORT xLeft
,
122 /* draw upper left corner */
125 FillConsoleOutputCharacterA(StdOutput
,
131 /* draw upper edge */
134 FillConsoleOutputCharacterA(StdOutput
,
140 /* draw upper right corner */
141 coPos
.X
= xLeft
+ Width
- 1;
143 FillConsoleOutputCharacterA(StdOutput
,
149 /* Draw right edge, inner space and left edge */
150 for (coPos
.Y
= yTop
+ 1; coPos
.Y
< yTop
+ Height
- 1; coPos
.Y
++)
153 FillConsoleOutputCharacterA(StdOutput
,
160 FillConsoleOutputCharacterA(StdOutput
,
166 coPos
.X
= xLeft
+ Width
- 1;
167 FillConsoleOutputCharacterA(StdOutput
,
174 /* draw lower left corner */
176 coPos
.Y
= yTop
+ Height
- 1;
177 FillConsoleOutputCharacterA(StdOutput
,
183 /* draw lower edge */
185 coPos
.Y
= yTop
+ Height
- 1;
186 FillConsoleOutputCharacterA(StdOutput
,
192 /* draw lower right corner */
193 coPos
.X
= xLeft
+ Width
- 1;
194 coPos
.Y
= yTop
+ Height
- 1;
195 FillConsoleOutputCharacterA(StdOutput
,
204 PopupError(PCCH Text
,
222 /* Count text lines and longest line */
229 p
= strchr(pnext
, '\n');
233 Length
= strlen(pnext
);
238 Length
= (ULONG
)(p
- pnext
);
244 if (Length
> MaxLength
)
247 if (LastLine
== TRUE
)
253 /* Check length of status line */
256 Length
= strlen(Status
);
258 if (Length
> MaxLength
)
262 Width
= MaxLength
+ 4;
268 yTop
= (yScreen
- Height
) / 2;
269 xLeft
= (xScreen
- Width
) / 2;
272 /* Set screen attributes */
274 for (coPos
.Y
= yTop
; coPos
.Y
< yTop
+ Height
; coPos
.Y
++)
276 FillConsoleOutputAttribute(StdOutput
,
277 FOREGROUND_RED
| BACKGROUND_WHITE
,
283 DrawBox(xLeft
, yTop
, Width
, Height
);
285 /* Print message text */
290 p
= strchr(pnext
, '\n');
294 Length
= strlen(pnext
);
299 Length
= (ULONG
)(p
- pnext
);
306 WriteConsoleOutputCharacterA(StdOutput
,
313 if (LastLine
== TRUE
)
320 /* Print separator line and status text */
323 coPos
.Y
= yTop
+ Height
- 3;
325 FillConsoleOutputCharacterA(StdOutput
,
332 FillConsoleOutputCharacterA(StdOutput
,
338 coPos
.X
= xLeft
+ Width
- 1;
339 FillConsoleOutputCharacterA(StdOutput
,
347 WriteConsoleOutputCharacterA(StdOutput
,
349 min(strlen(Status
), (SIZE_T
)Width
- 4),
354 if (WaitEvent
== POPUP_WAIT_NONE
)
359 CONSOLE_ConInKey(Ir
);
361 if (WaitEvent
== POPUP_WAIT_ANY_KEY
||
362 Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D)
374 * FALSE: Don't quit setup.
377 ConfirmQuit(PINPUT_RECORD Ir
)
380 MUIDisplayError(ERROR_NOT_INSTALLED
, NULL
, POPUP_WAIT_NONE
);
384 CONSOLE_ConInKey(Ir
);
386 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
387 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
392 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
404 CheckUnattendedSetup(VOID
)
406 WCHAR UnattendInfPath
[MAX_PATH
];
413 if (DoesFileExist(SourcePath
.Buffer
, L
"unattend.inf") == FALSE
)
415 DPRINT("Does not exist: %S\\%S\n", SourcePath
.Buffer
, L
"unattend.inf");
419 wcscpy(UnattendInfPath
, SourcePath
.Buffer
);
420 wcscat(UnattendInfPath
, L
"\\unattend.inf");
422 /* Load 'unattend.inf' from install media. */
423 UnattendInf
= SetupOpenInfFileW(UnattendInfPath
,
429 if (UnattendInf
== INVALID_HANDLE_VALUE
)
431 DPRINT("SetupOpenInfFileW() failed\n");
435 /* Open 'Unattend' section */
436 if (!SetupFindFirstLineW(UnattendInf
, L
"Unattend", L
"Signature", &Context
))
438 DPRINT("SetupFindFirstLineW() failed for section 'Unattend'\n");
439 SetupCloseInfFile(UnattendInf
);
443 /* Get pointer 'Signature' key */
444 if (!INF_GetData(&Context
, NULL
, &Value
))
446 DPRINT("INF_GetData() failed for key 'Signature'\n");
447 SetupCloseInfFile(UnattendInf
);
451 /* Check 'Signature' string */
452 if (_wcsicmp(Value
, L
"$ReactOS$") != 0)
454 DPRINT("Signature not $ReactOS$\n");
455 SetupCloseInfFile(UnattendInf
);
459 /* Check if Unattend setup is enabled */
460 if (!SetupFindFirstLineW(UnattendInf
, L
"Unattend", L
"UnattendSetupEnabled", &Context
))
462 DPRINT("Can't find key 'UnattendSetupEnabled'\n");
463 SetupCloseInfFile(UnattendInf
);
467 if (!INF_GetData(&Context
, NULL
, &Value
))
469 DPRINT("Can't read key 'UnattendSetupEnabled'\n");
470 SetupCloseInfFile(UnattendInf
);
474 if (_wcsicmp(Value
, L
"yes") != 0)
476 DPRINT("Unattend setup is disabled by 'UnattendSetupEnabled' key!\n");
477 SetupCloseInfFile(UnattendInf
);
481 /* Search for 'DestinationDiskNumber' in the 'Unattend' section */
482 if (!SetupFindFirstLineW(UnattendInf
, L
"Unattend", L
"DestinationDiskNumber", &Context
))
484 DPRINT("SetupFindFirstLine() failed for key 'DestinationDiskNumber'\n");
485 SetupCloseInfFile(UnattendInf
);
489 if (!SetupGetIntField(&Context
, 1, &IntValue
))
491 DPRINT("SetupGetIntField() failed for key 'DestinationDiskNumber'\n");
492 SetupCloseInfFile(UnattendInf
);
496 UnattendDestinationDiskNumber
= (LONG
)IntValue
;
498 /* Search for 'DestinationPartitionNumber' in the 'Unattend' section */
499 if (!SetupFindFirstLineW(UnattendInf
, L
"Unattend", L
"DestinationPartitionNumber", &Context
))
501 DPRINT("SetupFindFirstLine() failed for key 'DestinationPartitionNumber'\n");
502 SetupCloseInfFile(UnattendInf
);
506 if (!SetupGetIntField(&Context
, 1, &IntValue
))
508 DPRINT("SetupGetIntField() failed for key 'DestinationPartitionNumber'\n");
509 SetupCloseInfFile(UnattendInf
);
513 UnattendDestinationPartitionNumber
= IntValue
;
515 /* Search for 'InstallationDirectory' in the 'Unattend' section */
516 if (!SetupFindFirstLineW(UnattendInf
, L
"Unattend", L
"InstallationDirectory", &Context
))
518 DPRINT("SetupFindFirstLine() failed for key 'InstallationDirectory'\n");
519 SetupCloseInfFile(UnattendInf
);
523 /* Get pointer 'InstallationDirectory' key */
524 if (!INF_GetData(&Context
, NULL
, &Value
))
526 DPRINT("INF_GetData() failed for key 'InstallationDirectory'\n");
527 SetupCloseInfFile(UnattendInf
);
531 wcscpy(UnattendInstallationDirectory
, Value
);
533 IsUnattendedSetup
= TRUE
;
535 /* Search for 'MBRInstallType' in the 'Unattend' section */
536 if (SetupFindFirstLineW(UnattendInf
, L
"Unattend", L
"MBRInstallType", &Context
))
538 if (SetupGetIntField(&Context
, 1, &IntValue
))
540 UnattendMBRInstallType
= IntValue
;
544 /* Search for 'FormatPartition' in the 'Unattend' section */
545 if (SetupFindFirstLineW(UnattendInf
, L
"Unattend", L
"FormatPartition", &Context
))
547 if (SetupGetIntField(&Context
, 1, &IntValue
))
549 UnattendFormatPartition
= IntValue
;
553 if (SetupFindFirstLineW(UnattendInf
, L
"Unattend", L
"AutoPartition", &Context
))
555 if (SetupGetIntField(&Context
, 1, &IntValue
))
557 AutoPartition
= IntValue
;
561 /* search for LocaleID in the 'Unattend' section*/
562 if (SetupFindFirstLineW (UnattendInf
, L
"Unattend", L
"LocaleID", &Context
))
564 if (INF_GetData (&Context
, NULL
, &Value
))
566 LONG Id
= wcstol(Value
, NULL
, 16);
567 swprintf(LocaleID
,L
"%08lx", Id
);
571 SetupCloseInfFile(UnattendInf
);
573 DPRINT("Running unattended setup\n");
580 PGENERIC_LIST_ENTRY ListEntry
;
581 LPCWSTR pszNewLayout
;
583 pszNewLayout
= MUIDefaultKeyboardLayout();
585 if (LayoutList
== NULL
)
587 LayoutList
= CreateKeyboardLayoutList(SetupInf
, DefaultKBLayout
);
588 if (LayoutList
== NULL
)
590 /* FIXME: Handle error! */
595 ListEntry
= GetFirstListEntry(LayoutList
);
597 /* Search for default layout (if provided) */
598 if (pszNewLayout
!= NULL
)
600 while (ListEntry
!= NULL
)
602 if (!wcscmp(pszNewLayout
, GetListEntryUserData(ListEntry
)))
604 SetCurrentListEntry(LayoutList
, ListEntry
);
608 ListEntry
= GetNextListEntry(ListEntry
);
615 LanguagePage(PINPUT_RECORD Ir
)
617 PWCHAR NewLanguageId
;
618 BOOL RefreshPage
= FALSE
;
620 /* Initialize the computer settings list */
621 if (LanguageList
== NULL
)
623 LanguageList
= CreateLanguageList(SetupInf
, DefaultLanguage
);
625 if (LanguageList
== NULL
)
627 PopupError("Setup failed to initialize available translations", NULL
, NULL
, POPUP_WAIT_NONE
);
633 SelectedLanguageId
= DefaultLanguage
;
634 SetConsoleCodePage();
636 DrawGenericList(LanguageList
,
642 ScrollToPositionGenericList (LanguageList
, GetDefaultLanguageIndex());
644 MUIDisplayPage(LANGUAGE_PAGE
);
648 CONSOLE_ConInKey(Ir
);
650 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
651 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
)) /* DOWN */
653 ScrollDownGenericList (LanguageList
);
656 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
657 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_UP
)) /* UP */
659 ScrollUpGenericList(LanguageList
);
662 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
663 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_NEXT
)) /* PAGE DOWN */
665 ScrollPageDownGenericList(LanguageList
);
668 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
669 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_PRIOR
)) /* PAGE UP */
671 ScrollPageUpGenericList(LanguageList
);
674 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
675 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
677 if (ConfirmQuit(Ir
) == TRUE
)
680 RedrawGenericList(LanguageList
);
682 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
684 SelectedLanguageId
= (PWCHAR
)GetListEntryUserData(GetCurrentListEntry(LanguageList
));
686 LanguageId
= (LANGID
)(wcstol(SelectedLanguageId
, NULL
, 16) & 0xFFFF);
688 if (wcscmp(SelectedLanguageId
, DefaultLanguage
))
694 SetConsoleCodePage();
698 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
> 0x60) && (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
< 0x7b))
701 GenericListKeyPress (LanguageList
, Ir
->Event
.KeyEvent
.uChar
.AsciiChar
);
707 NewLanguageId
= (PWCHAR
)GetListEntryUserData(GetCurrentListEntry(LanguageList
));
709 if (SelectedLanguageId
!= NewLanguageId
)
711 /* Clear the language page */
712 MUIClearPage(LANGUAGE_PAGE
);
714 SelectedLanguageId
= NewLanguageId
;
717 SetConsoleCodePage();
719 /* Redraw language selection page in native language */
720 MUIDisplayPage(LANGUAGE_PAGE
);
734 * Number of the next page.
737 SetupStartPage(PINPUT_RECORD Ir
)
739 //SYSTEM_DEVICE_INFORMATION Sdi;
741 WCHAR FileNameBuffer
[MAX_PATH
];
746 PGENERIC_LIST_ENTRY ListEntry
;
749 CONSOLE_SetStatusText(MUIGetString(STRING_PLEASEWAIT
));
752 /* Check whether a harddisk is available */
753 Status
= NtQuerySystemInformation(SystemDeviceInformation
,
755 sizeof(SYSTEM_DEVICE_INFORMATION
),
758 if (!NT_SUCCESS(Status
))
760 CONSOLE_PrintTextXY(6, 15, "NtQuerySystemInformation() failed (Status 0x%08lx)", Status
);
761 MUIDisplayError(ERROR_DRIVE_INFORMATION
, Ir
, POPUP_WAIT_ENTER
);
765 if (Sdi
.NumberOfDisks
== 0)
767 MUIDisplayError(ERROR_NO_HDD
, Ir
, POPUP_WAIT_ENTER
);
772 /* Get the source path and source root path */
773 Status
= GetSourcePaths(&SourcePath
,
777 if (!NT_SUCCESS(Status
))
779 CONSOLE_PrintTextXY(6, 15, "GetSourcePaths() failed (Status 0x%08lx)", Status
);
780 MUIDisplayError(ERROR_NO_SOURCE_DRIVE
, Ir
, POPUP_WAIT_ENTER
);
786 CONSOLE_PrintTextXY(6, 15, "SourcePath: '%wZ'", &SourcePath
);
787 CONSOLE_PrintTextXY(6, 16, "SourceRootPath: '%wZ'", &SourceRootPath
);
788 CONSOLE_PrintTextXY(6, 17, "SourceRootDir: '%wZ'", &SourceRootDir
);
792 /* Load txtsetup.sif from install media. */
793 wcscpy(FileNameBuffer
, SourcePath
.Buffer
);
794 wcscat(FileNameBuffer
, L
"\\txtsetup.sif");
796 SetupInf
= SetupOpenInfFileW(FileNameBuffer
,
802 if (SetupInf
== INVALID_HANDLE_VALUE
)
804 MUIDisplayError(ERROR_LOAD_TXTSETUPSIF
, Ir
, POPUP_WAIT_ENTER
);
808 /* Open 'Version' section */
809 if (!SetupFindFirstLineW(SetupInf
, L
"Version", L
"Signature", &Context
))
811 MUIDisplayError(ERROR_CORRUPT_TXTSETUPSIF
, Ir
, POPUP_WAIT_ENTER
);
815 /* Get pointer 'Signature' key */
816 if (!INF_GetData(&Context
, NULL
, &Value
))
818 MUIDisplayError(ERROR_CORRUPT_TXTSETUPSIF
, Ir
, POPUP_WAIT_ENTER
);
822 /* Check 'Signature' string */
823 if (_wcsicmp(Value
, L
"$ReactOS$") != 0)
825 MUIDisplayError(ERROR_SIGNATURE_TXTSETUPSIF
, Ir
, POPUP_WAIT_ENTER
);
829 /* Open 'DiskSpaceRequirements' section */
830 if (!SetupFindFirstLineW(SetupInf
, L
"DiskSpaceRequirements", L
"FreeSysPartDiskSpace", &Context
))
832 MUIDisplayError(ERROR_CORRUPT_TXTSETUPSIF
, Ir
, POPUP_WAIT_ENTER
);
836 /* Get the 'FreeSysPartDiskSpace' value */
837 if (!SetupGetIntField(&Context
, 1, &IntValue
))
839 MUIDisplayError(ERROR_CORRUPT_TXTSETUPSIF
, Ir
, POPUP_WAIT_ENTER
);
843 RequiredPartitionDiskSpace
= (ULONG
)IntValue
;
845 /* Start PnP thread */
846 if (hPnpThread
!= INVALID_HANDLE_VALUE
)
848 NtResumeThread(hPnpThread
, NULL
);
849 hPnpThread
= INVALID_HANDLE_VALUE
;
852 CheckUnattendedSetup();
854 if (IsUnattendedSetup
)
857 //read options from inf
858 ComputerList
= CreateComputerTypeList(SetupInf
);
859 DisplayList
= CreateDisplayDriverList(SetupInf
);
860 KeyboardList
= CreateKeyboardDriverList(SetupInf
);
861 LayoutList
= CreateKeyboardLayoutList(SetupInf
, DefaultKBLayout
);
862 LanguageList
= CreateLanguageList(SetupInf
, DefaultLanguage
);
865 wcscpy(SelectedLanguageId
,LocaleID
);
867 /* first we hack LanguageList */
868 ListEntry
= GetFirstListEntry(LanguageList
);
870 while (ListEntry
!= NULL
)
872 if (!wcsicmp(LocaleID
, GetListEntryUserData(ListEntry
)))
874 DPRINT("found %S in LanguageList\n",GetListEntryUserData(ListEntry
));
875 SetCurrentListEntry(LanguageList
, ListEntry
);
879 ListEntry
= GetNextListEntry(ListEntry
);
883 ListEntry
= GetFirstListEntry(LayoutList
);
885 while (ListEntry
!= NULL
)
887 if (!wcsicmp(LocaleID
, GetListEntryUserData(ListEntry
)))
889 DPRINT("found %S in LayoutList\n",GetListEntryUserData(ListEntry
));
890 SetCurrentListEntry(LayoutList
, ListEntry
);
894 ListEntry
= GetNextListEntry(ListEntry
);
897 SetConsoleCodePage();
899 return INSTALL_INTRO_PAGE
;
902 return LANGUAGE_PAGE
;
912 IntroPage(PINPUT_RECORD Ir
)
914 MUIDisplayPage(START_PAGE
);
918 CONSOLE_ConInKey(Ir
);
920 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
921 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
923 if (ConfirmQuit(Ir
) == TRUE
)
928 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
930 return INSTALL_INTRO_PAGE
;
933 else if (toupper(Ir
->Event
.KeyEvent
.uChar
.AsciiChar
) == 'R') /* R */
935 return REPAIR_INTRO_PAGE
;
938 else if (toupper(Ir
->Event
.KeyEvent
.uChar
.AsciiChar
) == 'L') /* R */
952 * Back to main setup page.
955 LicensePage(PINPUT_RECORD Ir
)
957 MUIDisplayPage(LICENSE_PAGE
);
961 CONSOLE_ConInKey(Ir
);
963 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
975 RepairIntroPage(PINPUT_RECORD Ir
)
977 MUIDisplayPage(REPAIR_INTRO_PAGE
);
981 CONSOLE_ConInKey(Ir
);
983 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
987 else if (toupper(Ir
->Event
.KeyEvent
.uChar
.AsciiChar
) == 'U') /* U */
989 RepairUpdateFlag
= TRUE
;
990 return INSTALL_INTRO_PAGE
;
992 else if (toupper(Ir
->Event
.KeyEvent
.uChar
.AsciiChar
) == 'R') /* R */
996 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
997 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
)) /* ESC */
1003 return REPAIR_INTRO_PAGE
;
1008 InstallIntroPage(PINPUT_RECORD Ir
)
1010 MUIDisplayPage(INSTALL_INTRO_PAGE
);
1012 if (RepairUpdateFlag
)
1014 //return SELECT_PARTITION_PAGE;
1015 return DEVICE_SETTINGS_PAGE
;
1018 if (IsUnattendedSetup
)
1020 return SELECT_PARTITION_PAGE
;
1025 CONSOLE_ConInKey(Ir
);
1027 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1028 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1030 if (ConfirmQuit(Ir
) == TRUE
)
1035 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
1037 return DEVICE_SETTINGS_PAGE
;
1038 // return SCSI_CONTROLLER_PAGE;
1042 return INSTALL_INTRO_PAGE
;
1048 ScsiControllerPage(PINPUT_RECORD Ir
)
1050 SetTextXY(6, 8, "Setup detected the following mass storage devices:");
1052 /* FIXME: print loaded mass storage driver descriptions */
1054 SetTextXY(8, 10, "TEST device");
1058 SetStatusText(" ENTER = Continue F3 = Quit");
1064 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1065 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1067 if (ConfirmQuit(Ir
) == TRUE
)
1072 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
1074 return DEVICE_SETTINGS_PAGE
;
1078 return SCSI_CONTROLLER_PAGE
;
1084 DeviceSettingsPage(PINPUT_RECORD Ir
)
1086 static ULONG Line
= 16;
1087 MUIDisplayPage(DEVICE_SETTINGS_PAGE
);
1089 /* Initialize the computer settings list */
1090 if (ComputerList
== NULL
)
1092 ComputerList
= CreateComputerTypeList(SetupInf
);
1093 if (ComputerList
== NULL
)
1095 MUIDisplayError(ERROR_LOAD_COMPUTER
, Ir
, POPUP_WAIT_ENTER
);
1100 /* Initialize the display settings list */
1101 if (DisplayList
== NULL
)
1103 DisplayList
= CreateDisplayDriverList(SetupInf
);
1104 if (DisplayList
== NULL
)
1106 MUIDisplayError(ERROR_LOAD_DISPLAY
, Ir
, POPUP_WAIT_ENTER
);
1111 /* Initialize the keyboard settings list */
1112 if (KeyboardList
== NULL
)
1114 KeyboardList
= CreateKeyboardDriverList(SetupInf
);
1115 if (KeyboardList
== NULL
)
1117 MUIDisplayError(ERROR_LOAD_KEYBOARD
, Ir
, POPUP_WAIT_ENTER
);
1122 /* Initialize the keyboard layout list */
1123 if (LayoutList
== NULL
)
1125 LayoutList
= CreateKeyboardLayoutList(SetupInf
, DefaultKBLayout
);
1126 if (LayoutList
== NULL
)
1128 /* FIXME: report error */
1129 MUIDisplayError(ERROR_LOAD_KBLAYOUT
, Ir
, POPUP_WAIT_ENTER
);
1134 MUIDisplayPage(DEVICE_SETTINGS_PAGE
);
1137 CONSOLE_SetTextXY(25, 11, GetListEntryText(GetCurrentListEntry((ComputerList
))));
1138 CONSOLE_SetTextXY(25, 12, GetListEntryText(GetCurrentListEntry((DisplayList
))));
1139 CONSOLE_SetTextXY(25, 13, GetListEntryText(GetCurrentListEntry((KeyboardList
))));
1140 CONSOLE_SetTextXY(25, 14, GetListEntryText(GetCurrentListEntry((LayoutList
))));
1142 CONSOLE_InvertTextXY(24, Line
, 48, 1);
1144 if (RepairUpdateFlag
)
1146 return SELECT_PARTITION_PAGE
;
1151 CONSOLE_ConInKey(Ir
);
1153 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1154 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
)) /* DOWN */
1156 CONSOLE_NormalTextXY(24, Line
, 48, 1);
1160 else if (Line
== 16)
1165 CONSOLE_InvertTextXY(24, Line
, 48, 1);
1167 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1168 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_UP
)) /* UP */
1170 CONSOLE_NormalTextXY(24, Line
, 48, 1);
1174 else if (Line
== 16)
1179 CONSOLE_InvertTextXY(24, Line
, 48, 1);
1181 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1182 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1184 if (ConfirmQuit(Ir
) == TRUE
)
1189 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
1192 return COMPUTER_SETTINGS_PAGE
;
1193 else if (Line
== 12)
1194 return DISPLAY_SETTINGS_PAGE
;
1195 else if (Line
== 13)
1196 return KEYBOARD_SETTINGS_PAGE
;
1197 else if (Line
== 14)
1198 return LAYOUT_SETTINGS_PAGE
;
1199 else if (Line
== 16)
1200 return SELECT_PARTITION_PAGE
;
1204 return DEVICE_SETTINGS_PAGE
;
1209 ComputerSettingsPage(PINPUT_RECORD Ir
)
1211 MUIDisplayPage(COMPUTER_SETTINGS_PAGE
);
1213 DrawGenericList(ComputerList
,
1219 SaveGenericListState(ComputerList
);
1223 CONSOLE_ConInKey(Ir
);
1225 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1226 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
)) /* DOWN */
1228 ScrollDownGenericList(ComputerList
);
1230 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1231 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_UP
)) /* UP */
1233 ScrollUpGenericList(ComputerList
);
1235 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1236 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1238 if (ConfirmQuit(Ir
) == TRUE
)
1243 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1244 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
)) /* ESC */
1246 RestoreGenericListState(ComputerList
);
1247 return DEVICE_SETTINGS_PAGE
;
1249 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
1251 return DEVICE_SETTINGS_PAGE
;
1255 return COMPUTER_SETTINGS_PAGE
;
1260 DisplaySettingsPage(PINPUT_RECORD Ir
)
1262 MUIDisplayPage(DISPLAY_SETTINGS_PAGE
);
1264 DrawGenericList(DisplayList
,
1270 SaveGenericListState(DisplayList
);
1274 CONSOLE_ConInKey(Ir
);
1276 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1277 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
)) /* DOWN */
1279 ScrollDownGenericList(DisplayList
);
1281 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1282 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_UP
)) /* UP */
1284 ScrollUpGenericList(DisplayList
);
1286 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1287 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1289 if (ConfirmQuit(Ir
) == TRUE
)
1296 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1297 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
)) /* ESC */
1299 RestoreGenericListState(DisplayList
);
1300 return DEVICE_SETTINGS_PAGE
;
1302 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
1304 return DEVICE_SETTINGS_PAGE
;
1308 return DISPLAY_SETTINGS_PAGE
;
1313 KeyboardSettingsPage(PINPUT_RECORD Ir
)
1315 MUIDisplayPage(KEYBOARD_SETTINGS_PAGE
);
1317 DrawGenericList(KeyboardList
,
1323 SaveGenericListState(KeyboardList
);
1327 CONSOLE_ConInKey(Ir
);
1329 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1330 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
)) /* DOWN */
1332 ScrollDownGenericList(KeyboardList
);
1334 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1335 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_UP
)) /* UP */
1337 ScrollUpGenericList(KeyboardList
);
1339 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1340 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1342 if (ConfirmQuit(Ir
) == TRUE
)
1347 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1348 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
)) /* ESC */
1350 RestoreGenericListState(KeyboardList
);
1351 return DEVICE_SETTINGS_PAGE
;
1353 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
1355 return DEVICE_SETTINGS_PAGE
;
1359 return KEYBOARD_SETTINGS_PAGE
;
1364 LayoutSettingsPage(PINPUT_RECORD Ir
)
1366 MUIDisplayPage(LAYOUT_SETTINGS_PAGE
);
1368 DrawGenericList(LayoutList
,
1374 SaveGenericListState(LayoutList
);
1378 CONSOLE_ConInKey(Ir
);
1380 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1381 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
)) /* DOWN */
1383 ScrollDownGenericList(LayoutList
);
1385 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1386 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_UP
)) /* UP */
1388 ScrollUpGenericList(LayoutList
);
1390 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1391 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_NEXT
)) /* PAGE DOWN */
1393 ScrollPageDownGenericList(LayoutList
);
1395 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1396 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_PRIOR
)) /* PAGE UP */
1398 ScrollPageUpGenericList(LayoutList
);
1400 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1401 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1403 if (ConfirmQuit(Ir
) == TRUE
)
1408 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1409 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
)) /* ESC */
1411 RestoreGenericListState(LayoutList
);
1412 return DEVICE_SETTINGS_PAGE
;
1414 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
1416 return DEVICE_SETTINGS_PAGE
;
1418 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
> 0x60) && (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
< 0x7b))
1421 GenericListKeyPress(LayoutList
, Ir
->Event
.KeyEvent
.uChar
.AsciiChar
);
1425 return LAYOUT_SETTINGS_PAGE
;
1430 IsDiskSizeValid(PPARTENTRY PartEntry
)
1434 /* check for unpartitioned space */
1435 m1
= PartEntry
->UnpartitionedLength
;
1436 m1
= (m1
+ (1 << 19)) >> 20; /* in MBytes (rounded) */
1438 if( m1
> RequiredPartitionDiskSpace
)
1443 /* check for partitioned space */
1444 m2
= PartEntry
->PartInfo
[0].PartitionLength
.QuadPart
;
1445 m2
= (m2
+ (1 << 19)) >> 20; /* in MBytes (rounded) */
1446 if (m2
< RequiredPartitionDiskSpace
)
1448 /* partition is too small so ask for another partion */
1449 DPRINT1("Partition is too small(unpartitioned: %I64u MB, partitioned: %I64u MB), required disk space is %lu MB\n", m1
, m2
, RequiredPartitionDiskSpace
);
1460 SelectPartitionPage(PINPUT_RECORD Ir
)
1462 MUIDisplayPage(SELECT_PARTITION_PAGE
);
1464 if (PartitionList
== NULL
)
1466 PartitionList
= CreatePartitionList(2,
1470 if (PartitionList
== NULL
)
1472 /* FIXME: show an error dialog */
1477 DrawPartitionList(PartitionList
);
1479 /* Warn about partitions created by Linux Fdisk */
1480 if (WarnLinuxPartitions
== TRUE
&&
1481 CheckForLinuxFdiskPartitions(PartitionList
) == TRUE
)
1483 MUIDisplayError(ERROR_WARN_PARTITION
, NULL
, POPUP_WAIT_NONE
);
1487 CONSOLE_ConInKey(Ir
);
1489 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1490 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1494 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_RETURN
) /* ENTER */
1496 WarnLinuxPartitions
= FALSE
;
1497 return SELECT_PARTITION_PAGE
;
1502 if (IsUnattendedSetup
)
1504 if (!SelectPartition(PartitionList
, UnattendDestinationDiskNumber
, UnattendDestinationPartitionNumber
))
1508 PPARTENTRY PartEntry
= PartitionList
->CurrentPartition
;
1509 ULONG MaxSize
= (PartEntry
->UnpartitionedLength
+ (1 << 19)) >> 20; /* in MBytes (rounded) */
1510 if(!IsDiskSizeValid(PartitionList
->CurrentPartition
))
1512 MUIDisplayError(ERROR_INSUFFICIENT_DISKSPACE
, Ir
, POPUP_WAIT_ANY_KEY
);
1513 return SELECT_PARTITION_PAGE
; /* let the user select another partition */
1516 CreateNewPartition(PartitionList
,
1520 return SELECT_FILE_SYSTEM_PAGE
;
1525 if(!IsDiskSizeValid(PartitionList
->CurrentPartition
))
1527 MUIDisplayError(ERROR_INSUFFICIENT_DISKSPACE
, Ir
, POPUP_WAIT_ANY_KEY
);
1528 return SELECT_PARTITION_PAGE
; /* let the user select another partition */
1531 return SELECT_FILE_SYSTEM_PAGE
;
1537 /* Update status text */
1538 if (PartitionList
->CurrentPartition
== NULL
||
1539 PartitionList
->CurrentPartition
->Unpartitioned
== TRUE
)
1541 CONSOLE_SetStatusText(MUIGetString(STRING_INSTALLCREATEPARTITION
));
1545 CONSOLE_SetStatusText(MUIGetString(STRING_INSTALLDELETEPARTITION
));
1548 CONSOLE_ConInKey(Ir
);
1550 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1551 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1553 if (ConfirmQuit(Ir
) == TRUE
)
1555 DestroyPartitionList(PartitionList
);
1556 PartitionList
= NULL
;
1562 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1563 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
)) /* DOWN */
1565 ScrollDownPartitionList(PartitionList
);
1567 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1568 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_UP
)) /* UP */
1570 ScrollUpPartitionList(PartitionList
);
1572 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_RETURN
) /* ENTER */
1574 if(!IsDiskSizeValid(PartitionList
->CurrentPartition
))
1576 MUIDisplayError(ERROR_INSUFFICIENT_DISKSPACE
, Ir
, POPUP_WAIT_ANY_KEY
);
1577 return SELECT_PARTITION_PAGE
; /* let the user select another partition */
1579 if (PartitionList
->CurrentPartition
== NULL
||
1580 PartitionList
->CurrentPartition
->Unpartitioned
== TRUE
)
1582 CreateNewPartition(PartitionList
,
1587 return SELECT_FILE_SYSTEM_PAGE
;
1589 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== 'C') /* C */
1591 if (PartitionList
->CurrentPartition
->Unpartitioned
== FALSE
)
1593 MUIDisplayError(ERROR_NEW_PARTITION
, Ir
, POPUP_WAIT_ANY_KEY
);
1594 return SELECT_PARTITION_PAGE
;
1597 return CREATE_PARTITION_PAGE
;
1599 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== 'D') /* D */
1601 if (PartitionList
->CurrentPartition
->Unpartitioned
== TRUE
)
1603 MUIDisplayError(ERROR_DELETE_SPACE
, Ir
, POPUP_WAIT_ANY_KEY
);
1604 return SELECT_PARTITION_PAGE
;
1607 return DELETE_PARTITION_PAGE
;
1611 return SELECT_PARTITION_PAGE
;
1616 DrawInputField(ULONG FieldLength
,
1627 memset(buf
, '_', sizeof(buf
));
1628 buf
[FieldLength
- strlen(FieldContent
)] = 0;
1629 strcat(buf
, FieldContent
);
1631 WriteConsoleOutputCharacterA(StdOutput
,
1639 #define PARTITION_SIZE_INPUT_FIELD_LENGTH 6
1640 /* Restriction for MaxSize: pow(10, PARTITION_SIZE_INPUT_FIELD_LENGTH)-1 */
1641 #define PARTITION_MAXSIZE 999999
1644 ShowPartitionSizeInputBox(SHORT Left
,
1668 DrawBox(Left
, Top
, Right
- Left
+ 1, Bottom
- Top
+ 1);
1673 strcpy(Buffer
, MUIGetString(STRING_PARTITIONSIZE
));
1674 iLeft
= coPos
.X
+ strlen(Buffer
) + 1;
1677 WriteConsoleOutputCharacterA(StdOutput
,
1683 sprintf(Buffer
, MUIGetString(STRING_MAXSIZE
), MaxSize
);
1684 coPos
.X
= iLeft
+ PARTITION_SIZE_INPUT_FIELD_LENGTH
+ 1;
1686 WriteConsoleOutputCharacterA(StdOutput
,
1692 sprintf(Buffer
, "%lu", MaxSize
);
1693 Index
= strlen(Buffer
);
1694 DrawInputField(PARTITION_SIZE_INPUT_FIELD_LENGTH
,
1701 CONSOLE_ConInKey(&Ir
);
1703 if ((Ir
.Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1704 (Ir
.Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1712 else if (Ir
.Event
.KeyEvent
.wVirtualKeyCode
== VK_RETURN
) /* ENTER */
1716 else if (Ir
.Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
) /* ESCAPE */
1724 else if ((Ir
.Event
.KeyEvent
.wVirtualKeyCode
== VK_BACK
) && /* BACKSPACE */
1730 DrawInputField(PARTITION_SIZE_INPUT_FIELD_LENGTH
,
1735 else if ((Ir
.Event
.KeyEvent
.uChar
.AsciiChar
!= 0x00) &&
1736 (Index
< PARTITION_SIZE_INPUT_FIELD_LENGTH
))
1738 ch
= Ir
.Event
.KeyEvent
.uChar
.AsciiChar
;
1740 if ((ch
>= '0') && (ch
<= '9'))
1746 DrawInputField(PARTITION_SIZE_INPUT_FIELD_LENGTH
,
1754 strcpy(InputBuffer
, Buffer
);
1759 CreatePartitionPage(PINPUT_RECORD Ir
)
1761 PDISKENTRY DiskEntry
;
1762 PPARTENTRY PartEntry
;
1765 CHAR InputBuffer
[50];
1771 if (PartitionList
== NULL
||
1772 PartitionList
->CurrentDisk
== NULL
||
1773 PartitionList
->CurrentPartition
== NULL
)
1775 /* FIXME: show an error dialog */
1779 DiskEntry
= PartitionList
->CurrentDisk
;
1780 PartEntry
= PartitionList
->CurrentPartition
;
1782 CONSOLE_SetStatusText(MUIGetString(STRING_PLEASEWAIT
));
1784 CONSOLE_SetTextXY(6, 8, MUIGetString(STRING_CHOOSENEWPARTITION
));
1787 if (DiskEntry
->DiskSize
>= 0x280000000ULL
) /* 10 GB */
1789 DiskSize
= (DiskEntry
->DiskSize
+ (1 << 29)) >> 30;
1790 Unit
= MUIGetString(STRING_GB
);
1795 DiskSize
= (DiskEntry
->DiskSize
+ (1 << 19)) >> 20;
1800 Unit
= MUIGetString(STRING_MB
);
1803 if (DiskEntry
->DriverName
.Length
> 0)
1805 CONSOLE_PrintTextXY(6, 10,
1806 MUIGetString(STRING_HDINFOPARTCREATE
),
1809 DiskEntry
->DiskNumber
,
1813 &DiskEntry
->DriverName
);
1817 CONSOLE_PrintTextXY(6, 10,
1818 MUIGetString(STRING_HDDINFOUNK1
),
1821 DiskEntry
->DiskNumber
,
1827 CONSOLE_SetTextXY(6, 12, MUIGetString(STRING_HDDSIZE
));
1830 CONSOLE_PrintTextXY(8, 10, "Maximum size of the new partition is %I64u MB",
1831 PartitionList
->CurrentPartition
->UnpartitionedLength
/ (1024*1024));
1834 CONSOLE_SetStatusText(MUIGetString(STRING_CREATEPARTITION
));
1836 PartEntry
= PartitionList
->CurrentPartition
;
1839 MaxSize
= (PartEntry
->UnpartitionedLength
+ (1 << 19)) >> 20; /* in MBytes (rounded) */
1841 if (MaxSize
> PARTITION_MAXSIZE
) MaxSize
= PARTITION_MAXSIZE
;
1843 ShowPartitionSizeInputBox(12, 14, xScreen
- 12, 17, /* left, top, right, bottom */
1844 MaxSize
, InputBuffer
, &Quit
, &Cancel
);
1848 if (ConfirmQuit (Ir
) == TRUE
)
1853 else if (Cancel
== TRUE
)
1855 return SELECT_PARTITION_PAGE
;
1859 PartSize
= atoi(InputBuffer
);
1867 if (PartSize
> MaxSize
)
1873 /* Convert to bytes */
1874 if (PartSize
== MaxSize
)
1876 /* Use all of the unpartitioned disk space */
1877 PartSize
= PartEntry
->UnpartitionedLength
;
1881 /* Round-up by cylinder size */
1882 PartSize
= (PartSize
* 1024 * 1024 + DiskEntry
->CylinderSize
- 1) /
1883 DiskEntry
->CylinderSize
* DiskEntry
->CylinderSize
;
1885 /* But never get larger than the unpartitioned disk space */
1886 if (PartSize
> PartEntry
->UnpartitionedLength
)
1887 PartSize
= PartEntry
->UnpartitionedLength
;
1890 DPRINT ("Partition size: %I64u bytes\n", PartSize
);
1892 CreateNewPartition(PartitionList
,
1896 return SELECT_PARTITION_PAGE
;
1900 return CREATE_PARTITION_PAGE
;
1905 DeletePartitionPage(PINPUT_RECORD Ir
)
1907 PDISKENTRY DiskEntry
;
1908 PPARTENTRY PartEntry
;
1915 if (PartitionList
== NULL
||
1916 PartitionList
->CurrentDisk
== NULL
||
1917 PartitionList
->CurrentPartition
== NULL
)
1919 /* FIXME: show an error dialog */
1923 DiskEntry
= PartitionList
->CurrentDisk
;
1924 PartEntry
= PartitionList
->CurrentPartition
;
1925 PartNumber
= PartitionList
->CurrentPartitionNumber
;
1927 MUIDisplayPage(DELETE_PARTITION_PAGE
);
1929 /* Determine partition type */
1931 if (PartEntry
->New
== TRUE
)
1933 PartType
= MUIGetString(STRING_UNFORMATTED
);
1935 else if (PartEntry
->Unpartitioned
== FALSE
)
1937 if ((PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_FAT_12
) ||
1938 (PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_FAT_16
) ||
1939 (PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_HUGE
) ||
1940 (PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_XINT13
))
1944 else if ((PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_FAT32
) ||
1945 (PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_FAT32_XINT13
))
1949 else if (PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_EXT2
)
1953 else if (PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_IFS
)
1955 PartType
= "NTFS"; /* FIXME: Not quite correct! */
1960 if (PartEntry
->PartInfo
[PartNumber
].PartitionLength
.QuadPart
>= 0x280000000LL
) /* 10 GB */
1962 PartSize
= (PartEntry
->PartInfo
[PartNumber
].PartitionLength
.QuadPart
+ (1 << 29)) >> 30;
1963 Unit
= MUIGetString(STRING_GB
);
1967 if (PartEntry
->PartInfo
[PartNumber
].PartitionLength
.QuadPart
>= 0xA00000LL
) /* 10 MB */
1969 PartSize
= (PartEntry
->PartInfo
[PartNumber
].PartitionLength
.QuadPart
+ (1 << 19)) >> 20;
1970 Unit
= MUIGetString(STRING_MB
);
1974 PartSize
= (PartEntry
->PartInfo
[PartNumber
].PartitionLength
.QuadPart
+ (1 << 9)) >> 10;
1975 Unit
= MUIGetString(STRING_KB
);
1978 if (PartType
== NULL
)
1980 CONSOLE_PrintTextXY(6, 10,
1981 MUIGetString(STRING_HDDINFOUNK2
),
1982 (PartEntry
->DriveLetter
[PartNumber
] == 0) ? '-' : PartEntry
->DriveLetter
[PartNumber
],
1983 (PartEntry
->DriveLetter
[PartNumber
] == 0) ? '-' : ':',
1984 PartEntry
->PartInfo
[PartNumber
].PartitionType
,
1990 CONSOLE_PrintTextXY(6, 10,
1991 " %c%c %s %I64u %s",
1992 (PartEntry
->DriveLetter
[PartNumber
] == 0) ? '-' : PartEntry
->DriveLetter
[PartNumber
],
1993 (PartEntry
->DriveLetter
[PartNumber
] == 0) ? '-' : ':',
2000 if (DiskEntry
->DiskSize
>= 0x280000000ULL
) /* 10 GB */
2002 DiskSize
= (DiskEntry
->DiskSize
+ (1 << 29)) >> 30;
2003 Unit
= MUIGetString(STRING_GB
);
2008 DiskSize
= (DiskEntry
->DiskSize
+ (1 << 19)) >> 20;
2013 Unit
= MUIGetString(STRING_MB
);
2016 if (DiskEntry
->DriverName
.Length
> 0)
2018 CONSOLE_PrintTextXY(6, 12,
2019 MUIGetString(STRING_HDINFOPARTDELETE
),
2022 DiskEntry
->DiskNumber
,
2026 &DiskEntry
->DriverName
);
2030 CONSOLE_PrintTextXY(6, 12,
2031 MUIGetString(STRING_HDDINFOUNK3
),
2034 DiskEntry
->DiskNumber
,
2042 CONSOLE_ConInKey(Ir
);
2044 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
2045 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
2047 if (ConfirmQuit(Ir
) == TRUE
)
2054 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
) /* ESC */
2056 return SELECT_PARTITION_PAGE
;
2058 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== 'D') /* D */
2060 DeleteCurrentPartition(PartitionList
);
2062 return SELECT_PARTITION_PAGE
;
2066 return DELETE_PARTITION_PAGE
;
2071 SelectFileSystemPage(PINPUT_RECORD Ir
)
2073 PDISKENTRY DiskEntry
;
2074 PPARTENTRY PartEntry
;
2082 if (PartitionList
== NULL
||
2083 PartitionList
->CurrentDisk
== NULL
||
2084 PartitionList
->CurrentPartition
== NULL
)
2086 /* FIXME: show an error dialog */
2090 DiskEntry
= PartitionList
->CurrentDisk
;
2091 PartEntry
= PartitionList
->CurrentPartition
;
2092 PartNumber
= PartitionList
->CurrentPartitionNumber
;
2094 /* adjust disk size */
2095 if (DiskEntry
->DiskSize
>= 0x280000000ULL
) /* 10 GB */
2097 DiskSize
= (DiskEntry
->DiskSize
+ (1 << 29)) >> 30;
2098 DiskUnit
= MUIGetString(STRING_GB
);
2102 DiskSize
= (DiskEntry
->DiskSize
+ (1 << 19)) >> 20;
2103 DiskUnit
= MUIGetString(STRING_MB
);
2106 /* adjust partition size */
2107 if (PartEntry
->PartInfo
[PartNumber
].PartitionLength
.QuadPart
>= 0x280000000LL
) /* 10 GB */
2109 PartSize
= (PartEntry
->PartInfo
[PartNumber
].PartitionLength
.QuadPart
+ (1 << 29)) >> 30;
2110 PartUnit
= MUIGetString(STRING_GB
);
2114 PartSize
= (PartEntry
->PartInfo
[PartNumber
].PartitionLength
.QuadPart
+ (1 << 19)) >> 20;
2115 PartUnit
= MUIGetString(STRING_MB
);
2118 /* adjust partition type */
2119 if ((PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_FAT_12
) ||
2120 (PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_FAT_16
) ||
2121 (PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_HUGE
) ||
2122 (PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_XINT13
))
2126 else if ((PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_FAT32
) ||
2127 (PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_FAT32_XINT13
))
2131 else if (PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_EXT2
)
2135 else if (PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_IFS
)
2137 PartType
= "NTFS"; /* FIXME: Not quite correct! */
2139 else if (PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_ENTRY_UNUSED
)
2141 PartType
= MUIGetString(STRING_FORMATUNUSED
);
2145 PartType
= MUIGetString(STRING_FORMATUNKNOWN
);
2148 if (PartEntry
->AutoCreate
== TRUE
)
2150 CONSOLE_SetTextXY(6, 8, MUIGetString(STRING_NEWPARTITION
));
2153 CONSOLE_PrintTextXY(8, 10, "Partition %lu (%I64u %s) %s of",
2154 PartEntry
->PartInfo
[PartNumber
].PartitionNumber
,
2160 CONSOLE_PrintTextXY(8, 10, MUIGetString(STRING_HDINFOPARTZEROED
),
2161 DiskEntry
->DiskNumber
,
2167 &DiskEntry
->DriverName
);
2169 CONSOLE_SetTextXY(6, 12, MUIGetString(STRING_PARTFORMAT
));
2172 PartEntry
->AutoCreate
= FALSE
;
2174 else if (PartEntry
->New
== TRUE
)
2176 CONSOLE_SetTextXY(6, 8, MUIGetString(STRING_NONFORMATTEDPART
));
2177 CONSOLE_SetTextXY(6, 10, MUIGetString(STRING_PARTFORMAT
));
2181 CONSOLE_SetTextXY(6, 8, MUIGetString(STRING_INSTALLONPART
));
2183 if (PartType
== NULL
)
2185 CONSOLE_PrintTextXY(8, 10,
2186 MUIGetString(STRING_HDDINFOUNK4
),
2187 (PartEntry
->DriveLetter
[PartNumber
] == 0) ? '-' : PartEntry
->DriveLetter
[PartNumber
],
2188 (PartEntry
->DriveLetter
[PartNumber
] == 0) ? '-' : ':',
2189 PartEntry
->PartInfo
[PartNumber
].PartitionType
,
2195 CONSOLE_PrintTextXY(8, 10,
2197 (PartEntry
->DriveLetter
[PartNumber
] == 0) ? '-' : PartEntry
->DriveLetter
[PartNumber
],
2198 (PartEntry
->DriveLetter
[PartNumber
] == 0) ? '-' : ':',
2204 CONSOLE_PrintTextXY(6, 12, MUIGetString(STRING_HDINFOPARTEXISTS
),
2205 DiskEntry
->DiskNumber
,
2211 &DiskEntry
->DriverName
);
2214 MUIDisplayPage(SELECT_FILE_SYSTEM_PAGE
);
2216 if (FileSystemList
== NULL
)
2218 FileSystemList
= CreateFileSystemList(6, 26, PartEntry
->New
, L
"FAT");
2219 if (FileSystemList
== NULL
)
2221 /* FIXME: show an error dialog */
2225 /* FIXME: Add file systems to list */
2227 DrawFileSystemList(FileSystemList
);
2229 if (RepairUpdateFlag
)
2231 return CHECK_FILE_SYSTEM_PAGE
;
2232 //return SELECT_PARTITION_PAGE;
2235 if (IsUnattendedSetup
)
2237 if (UnattendFormatPartition
)
2239 return FORMAT_PARTITION_PAGE
;
2242 return CHECK_FILE_SYSTEM_PAGE
;
2247 CONSOLE_ConInKey(Ir
);
2249 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
2250 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
2252 if (ConfirmQuit(Ir
) == TRUE
)
2259 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
2260 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
)) /* ESC */
2262 return SELECT_PARTITION_PAGE
;
2264 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
2265 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
)) /* DOWN */
2267 ScrollDownFileSystemList(FileSystemList
);
2269 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
2270 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_UP
)) /* UP */
2272 ScrollUpFileSystemList(FileSystemList
);
2274 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_RETURN
) /* ENTER */
2276 if (!FileSystemList
->Selected
->FormatFunc
)
2278 return CHECK_FILE_SYSTEM_PAGE
;
2282 return FORMAT_PARTITION_PAGE
;
2287 return SELECT_FILE_SYSTEM_PAGE
;
2292 FormatPartitionPage(PINPUT_RECORD Ir
)
2294 WCHAR PathBuffer
[MAX_PATH
];
2295 PPARTENTRY PartEntry
;
2300 PDISKENTRY DiskEntry
;
2306 MUIDisplayPage(FORMAT_PARTITION_PAGE
);
2308 if (PartitionList
== NULL
||
2309 PartitionList
->CurrentDisk
== NULL
||
2310 PartitionList
->CurrentPartition
== NULL
)
2312 /* FIXME: show an error dialog */
2317 DiskEntry
= PartitionList
->CurrentDisk
;
2319 PartEntry
= PartitionList
->CurrentPartition
;
2320 PartNum
= PartitionList
->CurrentPartitionNumber
;
2324 if (!IsUnattendedSetup
)
2326 CONSOLE_ConInKey(Ir
);
2329 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
2330 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
2332 if (ConfirmQuit(Ir
) == TRUE
)
2339 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_RETURN
|| IsUnattendedSetup
) /* ENTER */
2341 CONSOLE_SetStatusText(MUIGetString(STRING_PLEASEWAIT
));
2343 if (wcscmp(FileSystemList
->Selected
->FileSystem
, L
"FAT") == 0)
2345 if (PartEntry
->PartInfo
[PartNum
].PartitionLength
.QuadPart
< (4200LL * 1024LL))
2347 /* FAT12 CHS partition (disk is smaller than 4.1MB) */
2348 PartEntry
->PartInfo
[PartNum
].PartitionType
= PARTITION_FAT_12
;
2350 else if (PartEntry
->PartInfo
[PartNum
].StartingOffset
.QuadPart
< (1024LL * 255LL * 63LL * 512LL))
2352 /* Partition starts below the 8.4GB boundary ==> CHS partition */
2354 if (PartEntry
->PartInfo
[PartNum
].PartitionLength
.QuadPart
< (32LL * 1024LL * 1024LL))
2356 /* FAT16 CHS partition (partiton size < 32MB) */
2357 PartEntry
->PartInfo
[PartNum
].PartitionType
= PARTITION_FAT_16
;
2359 else if (PartEntry
->PartInfo
[PartNum
].PartitionLength
.QuadPart
< (512LL * 1024LL * 1024LL))
2361 /* FAT16 CHS partition (partition size < 512MB) */
2362 PartEntry
->PartInfo
[PartNum
].PartitionType
= PARTITION_HUGE
;
2366 /* FAT32 CHS partition (partition size >= 512MB) */
2367 PartEntry
->PartInfo
[PartNum
].PartitionType
= PARTITION_FAT32
;
2372 /* Partition starts above the 8.4GB boundary ==> LBA partition */
2374 if (PartEntry
->PartInfo
[PartNum
].PartitionLength
.QuadPart
< (512LL * 1024LL * 1024LL))
2376 /* FAT16 LBA partition (partition size < 512MB) */
2377 PartEntry
->PartInfo
[PartNum
].PartitionType
= PARTITION_XINT13
;
2381 /* FAT32 LBA partition (partition size >= 512MB) */
2382 PartEntry
->PartInfo
[PartNum
].PartitionType
= PARTITION_FAT32_XINT13
;
2386 else if (wcscmp(FileSystemList
->Selected
->FileSystem
, L
"EXT2") == 0)
2387 PartEntry
->PartInfo
[PartNum
].PartitionType
= PARTITION_EXT2
;
2388 else if (!FileSystemList
->Selected
->FormatFunc
)
2392 CONSOLE_PrintTextXY(6, 12,
2393 "Disk: %I64u Cylinder: %I64u Track: %I64u",
2394 DiskEntry
->DiskSize
,
2395 DiskEntry
->CylinderSize
,
2396 DiskEntry
->TrackSize
);
2399 DiskEntry
= PartitionList
->CurrentDisk
;
2400 Entry
= DiskEntry
->PartListHead
.Flink
;
2402 while (Entry
!= &DiskEntry
->PartListHead
)
2404 PartEntry
= CONTAINING_RECORD(Entry
, PARTENTRY
, ListEntry
);
2406 if (PartEntry
->Unpartitioned
== FALSE
)
2408 for (i
= 0; i
< 4; i
++)
2410 CONSOLE_PrintTextXY(6, Line
,
2411 "%2u: %2u %c %12I64u %12I64u %2u %c",
2413 PartEntry
->PartInfo
[i
].PartitionNumber
,
2414 PartEntry
->PartInfo
[i
].BootIndicator
? 'A' : '-',
2415 PartEntry
->PartInfo
[i
].StartingOffset
.QuadPart
,
2416 PartEntry
->PartInfo
[i
].PartitionLength
.QuadPart
,
2417 PartEntry
->PartInfo
[i
].PartitionType
,
2418 PartEntry
->PartInfo
[i
].RewritePartition
? '*' : ' ');
2426 Entry
= Entry
->Flink
;
2429 /* Restore the old entry */
2430 PartEntry
= PartitionList
->CurrentPartition
;
2433 if (WritePartitionsToDisk(PartitionList
) == FALSE
)
2435 DPRINT("WritePartitionsToDisk() failed\n");
2436 MUIDisplayError(ERROR_WRITE_PTABLE
, Ir
, POPUP_WAIT_ENTER
);
2440 /* Set DestinationRootPath */
2441 RtlFreeUnicodeString(&DestinationRootPath
);
2442 swprintf(PathBuffer
,
2443 L
"\\Device\\Harddisk%lu\\Partition%lu",
2444 PartitionList
->CurrentDisk
->DiskNumber
,
2445 PartitionList
->CurrentPartition
->PartInfo
[PartNum
].PartitionNumber
);
2446 RtlCreateUnicodeString(&DestinationRootPath
,
2448 DPRINT("DestinationRootPath: %wZ\n", &DestinationRootPath
);
2450 if (FileSystemList
->Selected
->FormatFunc
)
2452 Status
= FormatPartition(&DestinationRootPath
,
2453 FileSystemList
->Selected
);
2454 if (!NT_SUCCESS(Status
))
2456 DPRINT1("FormatPartition() failed with status 0x%08lx\n", Status
);
2457 /* FIXME: show an error dialog */
2461 PartEntry
->New
= FALSE
;
2463 CheckActiveBootPartition(PartitionList
);
2467 CONSOLE_SetStatusText(" Done. Press any key ...");
2468 CONSOLE_ConInKey(Ir
);
2471 DestroyFileSystemList(FileSystemList
);
2472 FileSystemList
= NULL
;
2473 return INSTALL_DIRECTORY_PAGE
;
2477 return FORMAT_PARTITION_PAGE
;
2482 CheckFileSystemPage(PINPUT_RECORD Ir
)
2484 PFILE_SYSTEM_ITEM CurrentFileSystem
;
2485 WCHAR PathBuffer
[MAX_PATH
];
2486 CHAR Buffer
[MAX_PATH
];
2488 UCHAR PartNum
= PartitionList
->CurrentPartitionNumber
;
2490 /* FIXME: code duplicated in FormatPartitionPage */
2491 /* Set DestinationRootPath */
2492 RtlFreeUnicodeString(&DestinationRootPath
);
2493 swprintf(PathBuffer
,
2494 L
"\\Device\\Harddisk%lu\\Partition%lu",
2495 PartitionList
->CurrentDisk
->DiskNumber
,
2496 PartitionList
->CurrentPartition
->PartInfo
[PartNum
].PartitionNumber
);
2497 RtlCreateUnicodeString(&DestinationRootPath
, PathBuffer
);
2498 DPRINT("DestinationRootPath: %wZ\n", &DestinationRootPath
);
2500 CONSOLE_SetTextXY(6, 8, MUIGetString(STRING_CHECKINGPART
));
2502 CONSOLE_SetStatusText(MUIGetString(STRING_PLEASEWAIT
));
2504 /* WRONG: first filesystem is not necesseraly the one of the current partition! */
2505 CurrentFileSystem
= CONTAINING_RECORD(FileSystemList
->ListHead
.Flink
, FILE_SYSTEM_ITEM
, ListEntry
);
2507 if (!CurrentFileSystem
->ChkdskFunc
)
2510 "Setup is currently unable to check a partition formatted in %S.\n"
2512 " \x07 Press ENTER to continue Setup.\n"
2513 " \x07 Press F3 to quit Setup.",
2514 CurrentFileSystem
->FileSystem
);
2517 MUIGetString(STRING_QUITCONTINUE
),
2518 NULL
, POPUP_WAIT_NONE
);
2522 CONSOLE_ConInKey(Ir
);
2524 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00 &&
2525 Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
) /* F3 */
2527 if (ConfirmQuit(Ir
))
2530 return CHECK_FILE_SYSTEM_PAGE
;
2532 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== VK_RETURN
) /* ENTER */
2534 return INSTALL_DIRECTORY_PAGE
;
2540 Status
= ChkdskPartition(&DestinationRootPath
, CurrentFileSystem
);
2541 if (!NT_SUCCESS(Status
))
2543 DPRINT("ChkdskPartition() failed with status 0x%08lx\n", Status
);
2544 sprintf(Buffer
, "Setup failed to verify the selected partition.\n"
2545 "(Status 0x%08lx).\n", Status
);
2548 MUIGetString(STRING_REBOOTCOMPUTER
),
2549 Ir
, POPUP_WAIT_ENTER
);
2554 return INSTALL_DIRECTORY_PAGE
;
2560 InstallDirectoryPage1(PWCHAR InstallDir
,
2561 PDISKENTRY DiskEntry
,
2562 PPARTENTRY PartEntry
,
2565 WCHAR PathBuffer
[MAX_PATH
];
2567 /* Create 'InstallPath' string */
2568 RtlFreeUnicodeString(&InstallPath
);
2569 RtlCreateUnicodeString(&InstallPath
,
2572 /* Create 'DestinationPath' string */
2573 RtlFreeUnicodeString(&DestinationPath
);
2574 wcscpy(PathBuffer
, DestinationRootPath
.Buffer
);
2576 if (InstallDir
[0] != L
'\\')
2577 wcscat(PathBuffer
, L
"\\");
2579 wcscat(PathBuffer
, InstallDir
);
2580 RtlCreateUnicodeString(&DestinationPath
, PathBuffer
);
2582 /* Create 'DestinationArcPath' */
2583 RtlFreeUnicodeString(&DestinationArcPath
);
2584 swprintf(PathBuffer
,
2585 L
"multi(0)disk(0)rdisk(%lu)partition(%lu)",
2586 DiskEntry
->BiosDiskNumber
,
2587 PartEntry
->PartInfo
[PartNum
].PartitionNumber
);
2589 if (InstallDir
[0] != L
'\\')
2590 wcscat(PathBuffer
, L
"\\");
2592 wcscat(PathBuffer
, InstallDir
);
2593 RtlCreateUnicodeString(&DestinationArcPath
, PathBuffer
);
2595 return PREPARE_COPY_PAGE
;
2600 InstallDirectoryPage(PINPUT_RECORD Ir
)
2602 PDISKENTRY DiskEntry
;
2603 PPARTENTRY PartEntry
;
2604 WCHAR InstallDir
[51];
2607 if (PartitionList
== NULL
||
2608 PartitionList
->CurrentDisk
== NULL
||
2609 PartitionList
->CurrentPartition
== NULL
)
2611 /* FIXME: show an error dialog */
2615 DiskEntry
= PartitionList
->CurrentDisk
;
2616 PartEntry
= PartitionList
->CurrentPartition
;
2618 if (IsUnattendedSetup
)
2619 wcscpy(InstallDir
, UnattendInstallationDirectory
);
2621 wcscpy(InstallDir
, L
"\\ReactOS");
2623 Length
= wcslen(InstallDir
);
2624 CONSOLE_SetInputTextXY(8, 11, 51, InstallDir
);
2625 MUIDisplayPage(INSTALL_DIRECTORY_PAGE
);
2627 if (IsUnattendedSetup
)
2629 return InstallDirectoryPage1(InstallDir
,
2632 PartitionList
->CurrentPartitionNumber
);
2637 CONSOLE_ConInKey(Ir
);
2639 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
2640 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
2642 if (ConfirmQuit(Ir
) == TRUE
)
2647 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2649 return InstallDirectoryPage1(InstallDir
,
2652 PartitionList
->CurrentPartitionNumber
);
2654 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x08) /* BACKSPACE */
2659 InstallDir
[Length
] = 0;
2660 CONSOLE_SetInputTextXY(8, 11, 51, InstallDir
);
2663 else if (isprint(Ir
->Event
.KeyEvent
.uChar
.AsciiChar
))
2667 InstallDir
[Length
] = (WCHAR
)Ir
->Event
.KeyEvent
.uChar
.AsciiChar
;
2669 InstallDir
[Length
] = 0;
2670 CONSOLE_SetInputTextXY(8, 11, 51, InstallDir
);
2675 return INSTALL_DIRECTORY_PAGE
;
2680 AddSectionToCopyQueueCab(HINF InfFile
,
2682 PWCHAR SourceCabinet
,
2683 PCUNICODE_STRING DestinationPath
,
2686 INFCONTEXT FilesContext
;
2687 INFCONTEXT DirContext
;
2689 PWCHAR FileKeyValue
;
2691 PWCHAR TargetFileName
;
2693 /* Search for the SectionName section */
2694 if (!SetupFindFirstLineW(InfFile
, SectionName
, NULL
, &FilesContext
))
2697 sprintf(Buffer
, MUIGetString(STRING_TXTSETUPFAILED
), SectionName
);
2698 PopupError(Buffer
, MUIGetString(STRING_REBOOTCOMPUTER
), Ir
, POPUP_WAIT_ENTER
);
2703 * Enumerate the files in the section
2704 * and add them to the file queue.
2708 /* Get source file name and target directory id */
2709 if (!INF_GetData(&FilesContext
, &FileKeyName
, &FileKeyValue
))
2711 /* FIXME: Handle error! */
2712 DPRINT1("INF_GetData() failed\n");
2716 /* Get optional target file name */
2717 if (!INF_GetDataField(&FilesContext
, 2, &TargetFileName
))
2718 TargetFileName
= NULL
;
2720 DPRINT("FileKeyName: '%S' FileKeyValue: '%S'\n", FileKeyName
, FileKeyValue
);
2722 /* Lookup target directory */
2723 if (!SetupFindFirstLineW(InfFile
, L
"Directories", FileKeyValue
, &DirContext
))
2725 /* FIXME: Handle error! */
2726 DPRINT1("SetupFindFirstLine() failed\n");
2730 if (!INF_GetData(&DirContext
, NULL
, &DirKeyValue
))
2732 /* FIXME: Handle error! */
2733 DPRINT1("INF_GetData() failed\n");
2737 if (!SetupQueueCopy(SetupFileQueue
,
2739 SourceRootPath
.Buffer
,
2740 SourceRootDir
.Buffer
,
2745 /* FIXME: Handle error! */
2746 DPRINT1("SetupQueueCopy() failed\n");
2748 } while (SetupFindNextLine(&FilesContext
, &FilesContext
));
2755 AddSectionToCopyQueue(HINF InfFile
,
2757 PWCHAR SourceCabinet
,
2758 PCUNICODE_STRING DestinationPath
,
2761 INFCONTEXT FilesContext
;
2762 INFCONTEXT DirContext
;
2764 PWCHAR FileKeyValue
;
2766 PWCHAR TargetFileName
;
2767 WCHAR CompleteOrigFileName
[512];
2770 return AddSectionToCopyQueueCab(InfFile
, L
"SourceFiles", SourceCabinet
, DestinationPath
, Ir
);
2772 /* Search for the SectionName section */
2773 if (!SetupFindFirstLineW(InfFile
, SectionName
, NULL
, &FilesContext
))
2776 sprintf(Buffer
, MUIGetString(STRING_TXTSETUPFAILED
), SectionName
);
2777 PopupError(Buffer
, MUIGetString(STRING_REBOOTCOMPUTER
), Ir
, POPUP_WAIT_ENTER
);
2782 * Enumerate the files in the section
2783 * and add them to the file queue.
2787 /* Get source file name and target directory id */
2788 if (!INF_GetData(&FilesContext
, &FileKeyName
, &FileKeyValue
))
2790 /* FIXME: Handle error! */
2791 DPRINT1("INF_GetData() failed\n");
2795 /* Get target directory id */
2796 if (!INF_GetDataField(&FilesContext
, 13, &FileKeyValue
))
2798 /* FIXME: Handle error! */
2799 DPRINT1("INF_GetData() failed\n");
2803 /* Get optional target file name */
2804 if (!INF_GetDataField(&FilesContext
, 11, &TargetFileName
))
2805 TargetFileName
= NULL
;
2806 else if (!*TargetFileName
)
2807 TargetFileName
= NULL
;
2809 DPRINT("FileKeyName: '%S' FileKeyValue: '%S'\n", FileKeyName
, FileKeyValue
);
2811 /* Lookup target directory */
2812 if (!SetupFindFirstLineW(InfFile
, L
"Directories", FileKeyValue
, &DirContext
))
2814 /* FIXME: Handle error! */
2815 DPRINT1("SetupFindFirstLine() failed\n");
2819 if (!INF_GetData(&DirContext
, NULL
, &DirKeyValue
))
2821 /* FIXME: Handle error! */
2822 DPRINT1("INF_GetData() failed\n");
2826 wcscpy(CompleteOrigFileName
, SourceRootDir
.Buffer
);
2827 wcscat(CompleteOrigFileName
, L
"\\");
2828 wcscat(CompleteOrigFileName
, DirKeyValue
);
2830 if (!SetupQueueCopy(SetupFileQueue
,
2832 SourceRootPath
.Buffer
,
2833 CompleteOrigFileName
,
2838 /* FIXME: Handle error! */
2839 DPRINT1("SetupQueueCopy() failed\n");
2841 } while (SetupFindNextLine(&FilesContext
, &FilesContext
));
2848 PrepareCopyPageInfFile(HINF InfFile
,
2849 PWCHAR SourceCabinet
,
2852 WCHAR PathBuffer
[MAX_PATH
];
2853 INFCONTEXT DirContext
;
2854 PWCHAR AdditionalSectionName
= NULL
;
2859 /* Add common files */
2860 if (!AddSectionToCopyQueue(InfFile
, L
"SourceDisksFiles", SourceCabinet
, &DestinationPath
, Ir
))
2863 /* Add specific files depending of computer type */
2864 if (SourceCabinet
== NULL
)
2866 if (!ProcessComputerFiles(InfFile
, ComputerList
, &AdditionalSectionName
))
2869 if (AdditionalSectionName
)
2871 if (!AddSectionToCopyQueue(InfFile
, AdditionalSectionName
, SourceCabinet
, &DestinationPath
, Ir
))
2876 /* Create directories */
2880 * Install directories like '\reactos\test' are not handled yet.
2883 /* Get destination path */
2884 wcscpy(PathBuffer
, DestinationPath
.Buffer
);
2886 /* Remove trailing backslash */
2887 Length
= wcslen(PathBuffer
);
2888 if ((Length
> 0) && (PathBuffer
[Length
- 1] == '\\'))
2890 PathBuffer
[Length
- 1] = 0;
2893 /* Create the install directory */
2894 Status
= SetupCreateDirectory(PathBuffer
);
2895 if (!NT_SUCCESS(Status
) && Status
!= STATUS_OBJECT_NAME_COLLISION
)
2897 DPRINT("Creating directory '%S' failed: Status = 0x%08lx", PathBuffer
, Status
);
2898 MUIDisplayError(ERROR_CREATE_INSTALL_DIR
, Ir
, POPUP_WAIT_ENTER
);
2902 /* Search for the 'Directories' section */
2903 if (!SetupFindFirstLineW(InfFile
, L
"Directories", NULL
, &DirContext
))
2907 MUIDisplayError(ERROR_CABINET_SECTION
, Ir
, POPUP_WAIT_ENTER
);
2911 MUIDisplayError(ERROR_TXTSETUP_SECTION
, Ir
, POPUP_WAIT_ENTER
);
2917 /* Enumerate the directory values and create the subdirectories */
2920 if (!INF_GetData(&DirContext
, NULL
, &KeyValue
))
2926 if (KeyValue
[0] == L
'\\' && KeyValue
[1] != 0)
2928 DPRINT("Absolute Path: '%S'\n", KeyValue
);
2930 wcscpy(PathBuffer
, DestinationRootPath
.Buffer
);
2931 wcscat(PathBuffer
, KeyValue
);
2933 DPRINT("FullPath: '%S'\n", PathBuffer
);
2935 else if (KeyValue
[0] != L
'\\')
2937 DPRINT("RelativePath: '%S'\n", KeyValue
);
2938 wcscpy(PathBuffer
, DestinationPath
.Buffer
);
2939 wcscat(PathBuffer
, L
"\\");
2940 wcscat(PathBuffer
, KeyValue
);
2942 DPRINT("FullPath: '%S'\n", PathBuffer
);
2944 Status
= SetupCreateDirectory(PathBuffer
);
2945 if (!NT_SUCCESS(Status
) && Status
!= STATUS_OBJECT_NAME_COLLISION
)
2947 DPRINT("Creating directory '%S' failed: Status = 0x%08lx", PathBuffer
, Status
);
2948 MUIDisplayError(ERROR_CREATE_DIR
, Ir
, POPUP_WAIT_ENTER
);
2952 } while (SetupFindNextLine (&DirContext
, &DirContext
));
2959 PrepareCopyPage(PINPUT_RECORD Ir
)
2962 WCHAR PathBuffer
[MAX_PATH
];
2963 INFCONTEXT CabinetsContext
;
2969 MUIDisplayPage(PREPARE_COPY_PAGE
);
2971 /* Create the file queue */
2972 SetupFileQueue
= SetupOpenFileQueue();
2973 if (SetupFileQueue
== NULL
)
2975 MUIDisplayError(ERROR_COPY_QUEUE
, Ir
, POPUP_WAIT_ENTER
);
2979 if (!PrepareCopyPageInfFile(SetupInf
, NULL
, Ir
))
2984 /* Search for the 'Cabinets' section */
2985 if (!SetupFindFirstLineW(SetupInf
, L
"Cabinets", NULL
, &CabinetsContext
))
2987 return FILE_COPY_PAGE
;
2991 * Enumerate the directory values in the 'Cabinets'
2992 * section and parse their inf files.
2996 if (!INF_GetData(&CabinetsContext
, NULL
, &KeyValue
))
2999 wcscpy(PathBuffer
, SourcePath
.Buffer
);
3000 wcscat(PathBuffer
, L
"\\");
3001 wcscat(PathBuffer
, KeyValue
);
3004 CabinetInitialize();
3005 CabinetSetEventHandlers(NULL
, NULL
, NULL
);
3006 CabinetSetCabinetName(PathBuffer
);
3008 if (CabinetOpen() == CAB_STATUS_SUCCESS
)
3010 DPRINT("Cabinet %S\n", CabinetGetCabinetName());
3012 InfFileData
= CabinetGetCabinetReservedArea(&InfFileSize
);
3013 if (InfFileData
== NULL
)
3015 MUIDisplayError(ERROR_CABINET_SCRIPT
, Ir
, POPUP_WAIT_ENTER
);
3021 DPRINT("Cannot open cabinet: %S.\n", CabinetGetCabinetName());
3022 MUIDisplayError(ERROR_CABINET_MISSING
, Ir
, POPUP_WAIT_ENTER
);
3026 InfHandle
= INF_OpenBufferedFileA((CHAR
*) InfFileData
,
3033 if (InfHandle
== INVALID_HANDLE_VALUE
)
3035 MUIDisplayError(ERROR_INVALID_CABINET_INF
, Ir
, POPUP_WAIT_ENTER
);
3041 if (!PrepareCopyPageInfFile(InfHandle
, KeyValue
, Ir
))
3046 } while (SetupFindNextLine(&CabinetsContext
, &CabinetsContext
));
3048 return FILE_COPY_PAGE
;
3054 SetupUpdateMemoryInfo(IN PCOPYCONTEXT CopyContext
,
3057 SYSTEM_PERFORMANCE_INFORMATION PerfInfo
;
3059 /* Get the memory information from the system */
3060 NtQuerySystemInformation(SystemPerformanceInformation
,
3065 /* Check if this is initial setup */
3068 /* Set maximum limits to be total RAM pages */
3069 ProgressSetStepCount(CopyContext
->MemoryBars
[0], PerfInfo
.CommitLimit
);
3070 ProgressSetStepCount(CopyContext
->MemoryBars
[1], PerfInfo
.CommitLimit
);
3071 ProgressSetStepCount(CopyContext
->MemoryBars
[2], PerfInfo
.CommitLimit
);
3074 /* Set current values */
3075 ProgressSetStep(CopyContext
->MemoryBars
[0], PerfInfo
.PagedPoolPages
+ PerfInfo
.NonPagedPoolPages
);
3076 ProgressSetStep(CopyContext
->MemoryBars
[1], PerfInfo
.ResidentSystemCachePage
);
3077 ProgressSetStep(CopyContext
->MemoryBars
[2], PerfInfo
.AvailablePages
);
3083 FileCopyCallback(PVOID Context
,
3088 PCOPYCONTEXT CopyContext
;
3090 CopyContext
= (PCOPYCONTEXT
)Context
;
3092 switch (Notification
)
3094 case SPFILENOTIFY_STARTSUBQUEUE
:
3095 CopyContext
->TotalOperations
= (ULONG
)Param2
;
3096 ProgressSetStepCount(CopyContext
->ProgressBar
,
3097 CopyContext
->TotalOperations
);
3098 SetupUpdateMemoryInfo(CopyContext
, TRUE
);
3101 case SPFILENOTIFY_STARTCOPY
:
3102 /* Display copy message */
3103 CONSOLE_SetStatusText(MUIGetString(STRING_COPYING
), (PWSTR
)Param1
);
3104 SetupUpdateMemoryInfo(CopyContext
, FALSE
);
3107 case SPFILENOTIFY_ENDCOPY
:
3108 CopyContext
->CompletedOperations
++;
3110 /* SYSREG checkpoint */
3111 if (CopyContext
->TotalOperations
>> 1 == CopyContext
->CompletedOperations
)
3112 DPRINT1("CHECKPOINT:HALF_COPIED\n");
3114 ProgressNextStep(CopyContext
->ProgressBar
);
3115 SetupUpdateMemoryInfo(CopyContext
, FALSE
);
3125 FileCopyPage(PINPUT_RECORD Ir
)
3127 COPYCONTEXT CopyContext
;
3128 unsigned int mem_bar_width
;
3130 MUIDisplayPage(FILE_COPY_PAGE
);
3132 /* Create context for the copy process */
3133 CopyContext
.DestinationRootPath
= DestinationRootPath
.Buffer
;
3134 CopyContext
.InstallPath
= InstallPath
.Buffer
;
3135 CopyContext
.TotalOperations
= 0;
3136 CopyContext
.CompletedOperations
= 0;
3138 /* Create the progress bar as well */
3139 CopyContext
.ProgressBar
= CreateProgressBar(13,
3146 MUIGetString(STRING_SETUPCOPYINGFILES
));
3148 // fit memory bars to screen width, distribute them uniform
3149 mem_bar_width
= (xScreen
- 26) / 5;
3150 mem_bar_width
-= mem_bar_width
% 2; // make even
3151 /* ATTENTION: The following progress bars are debug stuff, which should not be translated!! */
3152 /* Create the paged pool progress bar */
3153 CopyContext
.MemoryBars
[0] = CreateProgressBar(13,
3162 /* Create the non paged pool progress bar */
3163 CopyContext
.MemoryBars
[1] = CreateProgressBar((xScreen
/ 2)- (mem_bar_width
/ 2),
3165 (xScreen
/ 2) + (mem_bar_width
/ 2),
3167 (xScreen
/ 2)- (mem_bar_width
/ 2),
3172 /* Create the global memory progress bar */
3173 CopyContext
.MemoryBars
[2] = CreateProgressBar(xScreen
- 13 - mem_bar_width
,
3177 xScreen
- 13 - mem_bar_width
,
3182 /* Do the file copying */
3183 SetupCommitFileQueueW(NULL
,
3188 /* If we get here, we're done, so cleanup the queue and progress bar */
3189 SetupCloseFileQueue(SetupFileQueue
);
3190 DestroyProgressBar(CopyContext
.ProgressBar
);
3191 DestroyProgressBar(CopyContext
.MemoryBars
[0]);
3192 DestroyProgressBar(CopyContext
.MemoryBars
[1]);
3193 DestroyProgressBar(CopyContext
.MemoryBars
[2]);
3195 /* Go display the next page */
3196 return REGISTRY_PAGE
;
3201 RegistryPage(PINPUT_RECORD Ir
)
3203 INFCONTEXT InfContext
;
3210 MUIDisplayPage(REGISTRY_PAGE
);
3212 if (RepairUpdateFlag
)
3214 return SUCCESS_PAGE
;
3217 if (!SetInstallPathValue(&DestinationPath
))
3219 DPRINT("SetInstallPathValue() failed\n");
3220 MUIDisplayError(ERROR_INITIALIZE_REGISTRY
, Ir
, POPUP_WAIT_ENTER
);
3224 /* Create the default hives */
3226 Status
= NtInitializeRegistry(CM_BOOT_FLAG_SETUP
);
3227 if (!NT_SUCCESS(Status
))
3229 DPRINT("NtInitializeRegistry() failed (Status %lx)\n", Status
);
3230 MUIDisplayError(ERROR_CREATE_HIVE
, Ir
, POPUP_WAIT_ENTER
);
3234 RegInitializeRegistry();
3237 /* Update registry */
3238 CONSOLE_SetStatusText(MUIGetString(STRING_REGHIVEUPDATE
));
3240 if (!SetupFindFirstLineW(SetupInf
, L
"HiveInfs.Install", NULL
, &InfContext
))
3242 DPRINT1("SetupFindFirstLine() failed\n");
3243 MUIDisplayError(ERROR_FIND_REGISTRY
, Ir
, POPUP_WAIT_ENTER
);
3249 INF_GetDataField (&InfContext
, 0, &Action
);
3250 INF_GetDataField (&InfContext
, 1, &File
);
3251 INF_GetDataField (&InfContext
, 2, &Section
);
3253 DPRINT("Action: %S File: %S Section %S\n", Action
, File
, Section
);
3258 if (!_wcsicmp (Action
, L
"AddReg"))
3262 else if (!_wcsicmp (Action
, L
"DelReg"))
3271 CONSOLE_SetStatusText(MUIGetString(STRING_IMPORTFILE
), File
);
3273 if (!ImportRegistryFile(File
, Section
, LanguageId
, Delete
))
3275 DPRINT("Importing %S failed\n", File
);
3277 MUIDisplayError(ERROR_IMPORT_HIVE
, Ir
, POPUP_WAIT_ENTER
);
3280 } while (SetupFindNextLine(&InfContext
, &InfContext
));
3282 /* Update display registry settings */
3283 CONSOLE_SetStatusText(MUIGetString(STRING_DISPLAYETTINGSUPDATE
));
3284 if (!ProcessDisplayRegistry(SetupInf
, DisplayList
))
3286 MUIDisplayError(ERROR_UPDATE_DISPLAY_SETTINGS
, Ir
, POPUP_WAIT_ENTER
);
3290 /* Set the locale */
3291 CONSOLE_SetStatusText(MUIGetString(STRING_LOCALESETTINGSUPDATE
));
3292 if (!ProcessLocaleRegistry(LanguageList
))
3294 MUIDisplayError(ERROR_UPDATE_LOCALESETTINGS
, Ir
, POPUP_WAIT_ENTER
);
3298 /* Add keyboard layouts */
3299 CONSOLE_SetStatusText(MUIGetString(STRING_ADDKBLAYOUTS
));
3300 if (!AddKeyboardLayouts())
3302 MUIDisplayError(ERROR_ADDING_KBLAYOUTS
, Ir
, POPUP_WAIT_ENTER
);
3308 if (!SetGeoID(MUIGetGeoID()))
3310 MUIDisplayError(ERROR_UPDATE_GEOID
, Ir
, POPUP_WAIT_ENTER
);
3314 if (!IsUnattendedSetup
)
3316 /* Update keyboard layout settings */
3317 CONSOLE_SetStatusText(MUIGetString(STRING_KEYBOARDSETTINGSUPDATE
));
3318 if (!ProcessKeyboardLayoutRegistry(LayoutList
))
3320 MUIDisplayError(ERROR_UPDATE_KBSETTINGS
, Ir
, POPUP_WAIT_ENTER
);
3325 /* Add codepage information to registry */
3326 CONSOLE_SetStatusText(MUIGetString(STRING_CODEPAGEINFOUPDATE
));
3329 MUIDisplayError(ERROR_ADDING_CODEPAGE
, Ir
, POPUP_WAIT_ENTER
);
3333 /* Update the mounted devices list */
3334 SetMountedDeviceValues(PartitionList
);
3336 CONSOLE_SetStatusText(MUIGetString(STRING_DONE
));
3338 return BOOT_LOADER_PAGE
;
3343 BootLoaderPage(PINPUT_RECORD Ir
)
3345 UCHAR PartitionType
;
3346 BOOLEAN InstallOnFloppy
;
3348 WCHAR PathBuffer
[MAX_PATH
];
3350 CONSOLE_SetStatusText(MUIGetString(STRING_PLEASEWAIT
));
3352 /* Find or set the active partition */
3353 CheckActiveBootPartition(PartitionList
);
3355 /* Update the partition table because we may have changed the active partition */
3356 if (WritePartitionsToDisk(PartitionList
) == FALSE
)
3358 DPRINT("WritePartitionsToDisk() failed\n");
3359 MUIDisplayError(ERROR_WRITE_PTABLE
, Ir
, POPUP_WAIT_ENTER
);
3363 RtlFreeUnicodeString(&SystemRootPath
);
3364 swprintf(PathBuffer
,
3365 L
"\\Device\\Harddisk%lu\\Partition%lu",
3366 PartitionList
->ActiveBootDisk
->DiskNumber
,
3367 PartitionList
->ActiveBootPartition
->
3368 PartInfo
[PartitionList
->ActiveBootPartitionNumber
].PartitionNumber
);
3369 RtlCreateUnicodeString(&SystemRootPath
,
3371 DPRINT("SystemRootPath: %wZ\n", &SystemRootPath
);
3373 PartitionType
= PartitionList
->ActiveBootPartition
->
3374 PartInfo
[PartitionList
->ActiveBootPartitionNumber
].PartitionType
;
3376 if (IsUnattendedSetup
)
3378 if (UnattendMBRInstallType
== 0) /* skip MBR installation */
3380 return SUCCESS_PAGE
;
3382 else if (UnattendMBRInstallType
== 1) /* install on floppy */
3384 return BOOT_LOADER_FLOPPY_PAGE
;
3388 if (PartitionType
== PARTITION_ENTRY_UNUSED
)
3390 DPRINT("Error: active partition invalid (unused)\n");
3391 InstallOnFloppy
= TRUE
;
3393 else if (PartitionType
== 0x0A)
3395 /* OS/2 boot manager partition */
3396 DPRINT("Found OS/2 boot manager partition\n");
3397 InstallOnFloppy
= TRUE
;
3399 else if (PartitionType
== 0x83)
3401 /* Linux ext2 partition */
3402 DPRINT("Found Linux ext2 partition\n");
3403 InstallOnFloppy
= TRUE
;
3405 else if (PartitionType
== PARTITION_IFS
)
3407 /* NTFS partition */
3408 DPRINT("Found NTFS partition\n");
3409 InstallOnFloppy
= TRUE
;
3411 else if ((PartitionType
== PARTITION_FAT_12
) ||
3412 (PartitionType
== PARTITION_FAT_16
) ||
3413 (PartitionType
== PARTITION_HUGE
) ||
3414 (PartitionType
== PARTITION_XINT13
) ||
3415 (PartitionType
== PARTITION_FAT32
) ||
3416 (PartitionType
== PARTITION_FAT32_XINT13
))
3418 DPRINT("Found FAT partition\n");
3419 InstallOnFloppy
= FALSE
;
3423 /* Unknown partition */
3424 DPRINT("Unknown partition found\n");
3425 InstallOnFloppy
= TRUE
;
3428 if (InstallOnFloppy
== TRUE
)
3430 return BOOT_LOADER_FLOPPY_PAGE
;
3433 /* Unattended install on hdd? */
3434 if (IsUnattendedSetup
&& UnattendMBRInstallType
== 2)
3436 return BOOT_LOADER_HARDDISK_MBR_PAGE
;
3439 MUIDisplayPage(BOOT_LOADER_PAGE
);
3440 CONSOLE_InvertTextXY(8, Line
, 60, 1);
3444 CONSOLE_ConInKey(Ir
);
3446 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
3447 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
)) /* DOWN */
3449 CONSOLE_NormalTextXY(8, Line
, 60, 1);
3458 CONSOLE_InvertTextXY(8, Line
, 60, 1);
3460 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
3461 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_UP
)) /* UP */
3463 CONSOLE_NormalTextXY(8, Line
, 60, 1);
3472 CONSOLE_InvertTextXY(8, Line
, 60, 1);
3474 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
3475 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
3477 if (ConfirmQuit(Ir
) == TRUE
)
3482 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
3486 return BOOT_LOADER_HARDDISK_MBR_PAGE
;
3488 else if (Line
== 13)
3490 return BOOT_LOADER_HARDDISK_VBR_PAGE
;
3492 else if (Line
== 14)
3494 return BOOT_LOADER_FLOPPY_PAGE
;
3496 else if (Line
== 15)
3498 return SUCCESS_PAGE
;
3501 return BOOT_LOADER_PAGE
;
3505 return BOOT_LOADER_PAGE
;
3510 BootLoaderFloppyPage(PINPUT_RECORD Ir
)
3514 MUIDisplayPage(BOOT_LOADER_FLOPPY_PAGE
);
3516 // SetStatusText(" Please wait...");
3520 CONSOLE_ConInKey(Ir
);
3522 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
3523 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
3525 if (ConfirmQuit(Ir
) == TRUE
)
3530 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
3532 if (DoesFileExist(L
"\\Device\\Floppy0", L
"\\") == FALSE
)
3534 MUIDisplayError(ERROR_NO_FLOPPY
, Ir
, POPUP_WAIT_ENTER
);
3535 return BOOT_LOADER_FLOPPY_PAGE
;
3538 Status
= InstallFatBootcodeToFloppy(&SourceRootPath
, &DestinationArcPath
);
3539 if (!NT_SUCCESS(Status
))
3541 /* Print error message */
3542 return BOOT_LOADER_FLOPPY_PAGE
;
3545 return SUCCESS_PAGE
;
3549 return BOOT_LOADER_FLOPPY_PAGE
;
3553 BootLoaderHarddiskVbrPage(PINPUT_RECORD Ir
)
3555 UCHAR PartitionType
;
3558 PartitionType
= PartitionList
->ActiveBootPartition
->
3559 PartInfo
[PartitionList
->ActiveBootPartitionNumber
].PartitionType
;
3561 Status
= InstallVBRToPartition(&SystemRootPath
,
3563 &DestinationArcPath
,
3565 if (!NT_SUCCESS(Status
))
3567 MUIDisplayError(ERROR_WRITE_BOOT
, Ir
, POPUP_WAIT_ENTER
);
3571 return SUCCESS_PAGE
;
3575 BootLoaderHarddiskMbrPage(PINPUT_RECORD Ir
)
3577 UCHAR PartitionType
;
3579 WCHAR DestinationDevicePathBuffer
[MAX_PATH
];
3580 WCHAR SourceMbrPathBuffer
[MAX_PATH
];
3582 /* Step 1: Write the VBR */
3583 PartitionType
= PartitionList
->ActiveBootPartition
->
3584 PartInfo
[PartitionList
->ActiveBootPartitionNumber
].PartitionType
;
3586 Status
= InstallVBRToPartition(&SystemRootPath
,
3588 &DestinationArcPath
,
3590 if (!NT_SUCCESS(Status
))
3592 MUIDisplayError(ERROR_WRITE_BOOT
, Ir
, POPUP_WAIT_ENTER
);
3596 /* Step 2: Write the MBR */
3597 swprintf(DestinationDevicePathBuffer
,
3598 L
"\\Device\\Harddisk%d\\Partition0",
3599 PartitionList
->ActiveBootDisk
->DiskNumber
);
3601 wcscpy(SourceMbrPathBuffer
, SourceRootPath
.Buffer
);
3602 wcscat(SourceMbrPathBuffer
, L
"\\loader\\dosmbr.bin");
3604 DPRINT("Install MBR bootcode: %S ==> %S\n",
3605 SourceMbrPathBuffer
, DestinationDevicePathBuffer
);
3607 Status
= InstallMbrBootCodeToDisk(SourceMbrPathBuffer
,
3608 DestinationDevicePathBuffer
);
3609 if (!NT_SUCCESS (Status
))
3611 DPRINT1("InstallMbrBootCodeToDisk() failed (Status %lx)\n",
3613 MUIDisplayError(ERROR_INSTALL_BOOTCODE
, Ir
, POPUP_WAIT_ENTER
);
3617 return SUCCESS_PAGE
;
3622 QuitPage(PINPUT_RECORD Ir
)
3624 MUIDisplayPage(QUIT_PAGE
);
3626 /* Destroy partition list */
3627 if (PartitionList
!= NULL
)
3629 DestroyPartitionList (PartitionList
);
3630 PartitionList
= NULL
;
3633 /* Destroy filesystem list */
3634 if (FileSystemList
!= NULL
)
3636 DestroyFileSystemList (FileSystemList
);
3637 FileSystemList
= NULL
;
3640 /* Destroy computer settings list */
3641 if (ComputerList
!= NULL
)
3643 DestroyGenericList(ComputerList
, TRUE
);
3644 ComputerList
= NULL
;
3647 /* Destroy display settings list */
3648 if (DisplayList
!= NULL
)
3650 DestroyGenericList(DisplayList
, TRUE
);
3654 /* Destroy keyboard settings list */
3655 if (KeyboardList
!= NULL
)
3657 DestroyGenericList(KeyboardList
, TRUE
);
3658 KeyboardList
= NULL
;
3661 /* Destroy keyboard layout list */
3662 if (LayoutList
!= NULL
)
3664 DestroyGenericList(LayoutList
, TRUE
);
3668 if (LanguageList
!= NULL
)
3670 DestroyGenericList(LanguageList
, FALSE
);
3671 LanguageList
= NULL
;
3674 CONSOLE_SetStatusText(MUIGetString(STRING_REBOOTCOMPUTER2
));
3678 CONSOLE_ConInKey(Ir
);
3680 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
3689 SuccessPage(PINPUT_RECORD Ir
)
3691 MUIDisplayPage(SUCCESS_PAGE
);
3693 if (IsUnattendedSetup
)
3700 CONSOLE_ConInKey(Ir
);
3702 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
3711 FlushPage(PINPUT_RECORD Ir
)
3713 MUIDisplayPage(FLUSH_PAGE
);
3719 PnpEventThread(IN LPVOID lpParameter
);
3729 NtQuerySystemTime(&Time
);
3731 Status
= RtlCreateUserThread(NtCurrentProcess(),
3741 if (!NT_SUCCESS(Status
))
3742 hPnpThread
= INVALID_HANDLE_VALUE
;
3744 if (!CONSOLE_Init())
3746 PrintString(MUIGetString(STRING_CONSOLEFAIL1
));
3747 PrintString(MUIGetString(STRING_CONSOLEFAIL2
));
3748 PrintString(MUIGetString(STRING_CONSOLEFAIL3
));
3750 /* Raise a hard error (crash the system/BSOD) */
3751 NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED
,
3755 /* Initialize global unicode strings */
3756 RtlInitUnicodeString(&SourcePath
, NULL
);
3757 RtlInitUnicodeString(&SourceRootPath
, NULL
);
3758 RtlInitUnicodeString(&SourceRootDir
, NULL
);
3759 RtlInitUnicodeString(&InstallPath
, NULL
);
3760 RtlInitUnicodeString(&DestinationPath
, NULL
);
3761 RtlInitUnicodeString(&DestinationArcPath
, NULL
);
3762 RtlInitUnicodeString(&DestinationRootPath
, NULL
);
3763 RtlInitUnicodeString(&SystemRootPath
, NULL
);
3765 /* Hide the cursor */
3766 CONSOLE_SetCursorType(TRUE
, FALSE
);
3769 while (Page
!= REBOOT_PAGE
)
3771 CONSOLE_ClearScreen();
3774 //CONSOLE_SetUnderlinedTextXY(4, 3, " ReactOS " KERNEL_VERSION_STR " Setup ");
3781 Page
= SetupStartPage(&Ir
);
3786 Page
= LanguagePage(&Ir
);
3791 Page
= LicensePage(&Ir
);
3796 Page
= IntroPage(&Ir
);
3800 case INSTALL_INTRO_PAGE
:
3801 Page
= InstallIntroPage(&Ir
);
3805 case SCSI_CONTROLLER_PAGE
:
3806 Page
= ScsiControllerPage(&Ir
);
3811 case OEM_DRIVER_PAGE
:
3812 Page
= OemDriverPage(&Ir
);
3816 case DEVICE_SETTINGS_PAGE
:
3817 Page
= DeviceSettingsPage(&Ir
);
3820 case COMPUTER_SETTINGS_PAGE
:
3821 Page
= ComputerSettingsPage(&Ir
);
3824 case DISPLAY_SETTINGS_PAGE
:
3825 Page
= DisplaySettingsPage(&Ir
);
3828 case KEYBOARD_SETTINGS_PAGE
:
3829 Page
= KeyboardSettingsPage(&Ir
);
3832 case LAYOUT_SETTINGS_PAGE
:
3833 Page
= LayoutSettingsPage(&Ir
);
3836 case SELECT_PARTITION_PAGE
:
3837 Page
= SelectPartitionPage(&Ir
);
3840 case CREATE_PARTITION_PAGE
:
3841 Page
= CreatePartitionPage(&Ir
);
3844 case DELETE_PARTITION_PAGE
:
3845 Page
= DeletePartitionPage(&Ir
);
3848 case SELECT_FILE_SYSTEM_PAGE
:
3849 Page
= SelectFileSystemPage(&Ir
);
3852 case FORMAT_PARTITION_PAGE
:
3853 Page
= (PAGE_NUMBER
) FormatPartitionPage(&Ir
);
3856 case CHECK_FILE_SYSTEM_PAGE
:
3857 Page
= (PAGE_NUMBER
) CheckFileSystemPage(&Ir
);
3860 case INSTALL_DIRECTORY_PAGE
:
3861 Page
= InstallDirectoryPage(&Ir
);
3864 case PREPARE_COPY_PAGE
:
3865 Page
= PrepareCopyPage(&Ir
);
3868 case FILE_COPY_PAGE
:
3869 Page
= FileCopyPage(&Ir
);
3873 Page
= RegistryPage(&Ir
);
3876 case BOOT_LOADER_PAGE
:
3877 Page
= BootLoaderPage(&Ir
);
3880 case BOOT_LOADER_FLOPPY_PAGE
:
3881 Page
= BootLoaderFloppyPage(&Ir
);
3884 case BOOT_LOADER_HARDDISK_MBR_PAGE
:
3885 Page
= BootLoaderHarddiskMbrPage(&Ir
);
3888 case BOOT_LOADER_HARDDISK_VBR_PAGE
:
3889 Page
= BootLoaderHarddiskVbrPage(&Ir
);
3893 case REPAIR_INTRO_PAGE
:
3894 Page
= RepairIntroPage(&Ir
);
3898 Page
= SuccessPage(&Ir
);
3902 Page
= FlushPage(&Ir
);
3906 Page
= QuitPage(&Ir
);
3916 /* Avoid bugcheck */
3917 Time
.QuadPart
+= 50000000;
3918 NtDelayExecution(FALSE
, &Time
);
3921 NtShutdownSystem(ShutdownReboot
);
3922 NtTerminateProcess(NtCurrentProcess(), 0);
3929 NtProcessStartup(PPEB Peb
)
3931 RtlNormalizeProcessParams(Peb
->ProcessParameters
);
3933 ProcessHeap
= Peb
->ProcessHeap
;
3934 InfSetHeap(ProcessHeap
);
3937 #endif /* __REACTOS__ */