3 * Copyright (C) 2002, 2003, 2004 ReactOS Team
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 * COPYRIGHT: See COPYING in the top level directory
21 * PROJECT: ReactOS text-mode setup
22 * FILE: subsys/system/usetup/usetup.c
23 * PURPOSE: Text-mode setup
24 * PROGRAMMER: Eric Kohl
25 * Casper S. Hornstrup (chorns@users.sourceforge.net)
26 * Hervé Poussineau (hpoussin@reactos.org)
35 /* GLOBALS ******************************************************************/
38 UNICODE_STRING SourceRootPath
;
39 UNICODE_STRING SourceRootDir
;
40 UNICODE_STRING SourcePath
;
41 BOOLEAN IsUnattendedSetup
= FALSE
;
42 LONG UnattendDestinationDiskNumber
;
43 LONG UnattendDestinationPartitionNumber
;
44 LONG UnattendMBRInstallType
= -1;
45 LONG UnattendFormatPartition
= 0;
46 LONG AutoPartition
= 0;
47 WCHAR UnattendInstallationDirectory
[MAX_PATH
];
48 PWCHAR SelectedLanguageId
;
50 WCHAR DefaultLanguage
[20];
51 WCHAR DefaultKBLayout
[20];
52 BOOLEAN RepairUpdateFlag
= FALSE
;
53 HANDLE hPnpThread
= INVALID_HANDLE_VALUE
;
54 PPARTLIST PartitionList
= NULL
;
56 /* LOCALS *******************************************************************/
58 static PFILE_SYSTEM_LIST FileSystemList
= NULL
;
60 static UNICODE_STRING InstallPath
;
62 /* Path to the install directory */
63 static UNICODE_STRING DestinationPath
;
64 static UNICODE_STRING DestinationArcPath
;
65 static UNICODE_STRING DestinationRootPath
;
67 /* Path to the active partition (boot manager) */
68 static UNICODE_STRING SystemRootPath
;
72 static HSPFILEQ SetupFileQueue
= NULL
;
74 static BOOLEAN WarnLinuxPartitions
= TRUE
;
76 static PGENERIC_LIST ComputerList
= NULL
;
77 static PGENERIC_LIST DisplayList
= NULL
;
78 static PGENERIC_LIST KeyboardList
= NULL
;
79 static PGENERIC_LIST LayoutList
= NULL
;
80 static PGENERIC_LIST LanguageList
= NULL
;
82 static LANGID LanguageId
= 0;
84 static ULONG RequiredPartitionDiskSpace
= ~0;
86 /* FUNCTIONS ****************************************************************/
89 PrintString(char* fmt
,...)
93 UNICODE_STRING UnicodeString
;
94 ANSI_STRING AnsiString
;
97 vsprintf(buffer
, fmt
, ap
);
100 RtlInitAnsiString(&AnsiString
, buffer
);
101 RtlAnsiStringToUnicodeString(&UnicodeString
, &AnsiString
, TRUE
);
102 NtDisplayString(&UnicodeString
);
103 RtlFreeUnicodeString(&UnicodeString
);
108 DrawBox(IN SHORT xLeft
,
116 /* draw upper left corner */
119 FillConsoleOutputCharacterA(StdOutput
,
125 /* draw upper edge */
128 FillConsoleOutputCharacterA(StdOutput
,
134 /* draw upper right corner */
135 coPos
.X
= xLeft
+ Width
- 1;
137 FillConsoleOutputCharacterA(StdOutput
,
143 /* Draw right edge, inner space and left edge */
144 for (coPos
.Y
= yTop
+ 1; coPos
.Y
< yTop
+ Height
- 1; coPos
.Y
++)
147 FillConsoleOutputCharacterA(StdOutput
,
154 FillConsoleOutputCharacterA(StdOutput
,
160 coPos
.X
= xLeft
+ Width
- 1;
161 FillConsoleOutputCharacterA(StdOutput
,
168 /* draw lower left corner */
170 coPos
.Y
= yTop
+ Height
- 1;
171 FillConsoleOutputCharacterA(StdOutput
,
177 /* draw lower edge */
179 coPos
.Y
= yTop
+ Height
- 1;
180 FillConsoleOutputCharacterA(StdOutput
,
186 /* draw lower right corner */
187 coPos
.X
= xLeft
+ Width
- 1;
188 coPos
.Y
= yTop
+ Height
- 1;
189 FillConsoleOutputCharacterA(StdOutput
,
198 PopupError(PCCH Text
,
216 /* Count text lines and longest line */
223 p
= strchr(pnext
, '\n');
227 Length
= strlen(pnext
);
232 Length
= (ULONG
)(p
- pnext
);
238 if (Length
> MaxLength
)
241 if (LastLine
== TRUE
)
247 /* Check length of status line */
250 Length
= strlen(Status
);
252 if (Length
> MaxLength
)
256 Width
= MaxLength
+ 4;
262 yTop
= (yScreen
- Height
) / 2;
263 xLeft
= (xScreen
- Width
) / 2;
266 /* Set screen attributes */
268 for (coPos
.Y
= yTop
; coPos
.Y
< yTop
+ Height
; coPos
.Y
++)
270 FillConsoleOutputAttribute(StdOutput
,
271 FOREGROUND_RED
| BACKGROUND_WHITE
,
277 DrawBox(xLeft
, yTop
, Width
, Height
);
279 /* Print message text */
284 p
= strchr(pnext
, '\n');
288 Length
= strlen(pnext
);
293 Length
= (ULONG
)(p
- pnext
);
300 WriteConsoleOutputCharacterA(StdOutput
,
307 if (LastLine
== TRUE
)
314 /* Print separator line and status text */
317 coPos
.Y
= yTop
+ Height
- 3;
319 FillConsoleOutputCharacterA(StdOutput
,
326 FillConsoleOutputCharacterA(StdOutput
,
332 coPos
.X
= xLeft
+ Width
- 1;
333 FillConsoleOutputCharacterA(StdOutput
,
341 WriteConsoleOutputCharacterA(StdOutput
,
343 min(strlen(Status
), (SIZE_T
)Width
- 4),
348 if (WaitEvent
== POPUP_WAIT_NONE
)
353 CONSOLE_ConInKey(Ir
);
355 if (WaitEvent
== POPUP_WAIT_ANY_KEY
||
356 Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D)
368 * FALSE: Don't quit setup.
371 ConfirmQuit(PINPUT_RECORD Ir
)
374 MUIDisplayError(ERROR_NOT_INSTALLED
, NULL
, POPUP_WAIT_NONE
);
378 CONSOLE_ConInKey(Ir
);
380 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
381 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
386 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
398 CheckUnattendedSetup(VOID
)
400 WCHAR UnattendInfPath
[MAX_PATH
];
407 if (DoesFileExist(SourcePath
.Buffer
, L
"unattend.inf") == FALSE
)
409 DPRINT("Does not exist: %S\\%S\n", SourcePath
.Buffer
, L
"unattend.inf");
413 wcscpy(UnattendInfPath
, SourcePath
.Buffer
);
414 wcscat(UnattendInfPath
, L
"\\unattend.inf");
416 /* Load 'unattend.inf' from install media. */
417 UnattendInf
= SetupOpenInfFileW(UnattendInfPath
,
423 if (UnattendInf
== INVALID_HANDLE_VALUE
)
425 DPRINT("SetupOpenInfFileW() failed\n");
429 /* Open 'Unattend' section */
430 if (!SetupFindFirstLineW(UnattendInf
, L
"Unattend", L
"Signature", &Context
))
432 DPRINT("SetupFindFirstLineW() failed for section 'Unattend'\n");
433 SetupCloseInfFile(UnattendInf
);
437 /* Get pointer 'Signature' key */
438 if (!INF_GetData(&Context
, NULL
, &Value
))
440 DPRINT("INF_GetData() failed for key 'Signature'\n");
441 SetupCloseInfFile(UnattendInf
);
445 /* Check 'Signature' string */
446 if (_wcsicmp(Value
, L
"$ReactOS$") != 0)
448 DPRINT("Signature not $ReactOS$\n");
449 SetupCloseInfFile(UnattendInf
);
453 /* Check if Unattend setup is enabled */
454 if (!SetupFindFirstLineW(UnattendInf
, L
"Unattend", L
"UnattendSetupEnabled", &Context
))
456 DPRINT("Can't find key 'UnattendSetupEnabled'\n");
457 SetupCloseInfFile(UnattendInf
);
461 if (!INF_GetData(&Context
, NULL
, &Value
))
463 DPRINT("Can't read key 'UnattendSetupEnabled'\n");
464 SetupCloseInfFile(UnattendInf
);
468 if (_wcsicmp(Value
, L
"yes") != 0)
470 DPRINT("Unattend setup is disabled by 'UnattendSetupEnabled' key!\n");
471 SetupCloseInfFile(UnattendInf
);
475 /* Search for 'DestinationDiskNumber' in the 'Unattend' section */
476 if (!SetupFindFirstLineW(UnattendInf
, L
"Unattend", L
"DestinationDiskNumber", &Context
))
478 DPRINT("SetupFindFirstLine() failed for key 'DestinationDiskNumber'\n");
479 SetupCloseInfFile(UnattendInf
);
483 if (!SetupGetIntField(&Context
, 1, &IntValue
))
485 DPRINT("SetupGetIntField() failed for key 'DestinationDiskNumber'\n");
486 SetupCloseInfFile(UnattendInf
);
490 UnattendDestinationDiskNumber
= (LONG
)IntValue
;
492 /* Search for 'DestinationPartitionNumber' in the 'Unattend' section */
493 if (!SetupFindFirstLineW(UnattendInf
, L
"Unattend", L
"DestinationPartitionNumber", &Context
))
495 DPRINT("SetupFindFirstLine() failed for key 'DestinationPartitionNumber'\n");
496 SetupCloseInfFile(UnattendInf
);
500 if (!SetupGetIntField(&Context
, 1, &IntValue
))
502 DPRINT("SetupGetIntField() failed for key 'DestinationPartitionNumber'\n");
503 SetupCloseInfFile(UnattendInf
);
507 UnattendDestinationPartitionNumber
= IntValue
;
509 /* Search for 'DestinationPartitionNumber' in the 'Unattend' section */
510 if (!SetupFindFirstLineW(UnattendInf
, L
"Unattend", L
"DestinationPartitionNumber", &Context
))
512 DPRINT("SetupFindFirstLine() failed for key 'DestinationPartitionNumber'\n");
513 SetupCloseInfFile(UnattendInf
);
517 /* Get pointer 'InstallationDirectory' key */
518 if (!INF_GetData(&Context
, NULL
, &Value
))
520 DPRINT("INF_GetData() failed for key 'InstallationDirectory'\n");
521 SetupCloseInfFile(UnattendInf
);
525 wcscpy(UnattendInstallationDirectory
, Value
);
527 IsUnattendedSetup
= TRUE
;
529 /* Search for 'MBRInstallType' in the 'Unattend' section */
530 if (SetupFindFirstLineW(UnattendInf
, L
"Unattend", L
"MBRInstallType", &Context
))
532 if (SetupGetIntField(&Context
, 1, &IntValue
))
534 UnattendMBRInstallType
= IntValue
;
538 /* Search for 'FormatPartition' in the 'Unattend' section */
539 if (SetupFindFirstLineW(UnattendInf
, L
"Unattend", L
"FormatPartition", &Context
))
541 if (SetupGetIntField(&Context
, 1, &IntValue
))
543 UnattendFormatPartition
= IntValue
;
547 if (SetupFindFirstLineW(UnattendInf
, L
"Unattend", L
"AutoPartition", &Context
))
549 if (SetupGetIntField(&Context
, 1, &IntValue
))
551 AutoPartition
= IntValue
;
555 /* search for LocaleID in the 'Unattend' section*/
556 if (SetupFindFirstLineW (UnattendInf
, L
"Unattend", L
"LocaleID", &Context
))
558 if (INF_GetData (&Context
, NULL
, &Value
))
560 LONG Id
= wcstol(Value
, NULL
, 16);
561 swprintf(LocaleID
,L
"%08lx", Id
);
565 SetupCloseInfFile(UnattendInf
);
567 DPRINT("Running unattended setup\n");
574 PGENERIC_LIST_ENTRY ListEntry
;
575 LPCWSTR pszNewLayout
;
577 pszNewLayout
= MUIDefaultKeyboardLayout();
579 if (LayoutList
== NULL
)
581 LayoutList
= CreateKeyboardLayoutList(SetupInf
, DefaultKBLayout
);
582 if (LayoutList
== NULL
)
584 /* FIXME: Handle error! */
589 ListEntry
= GetFirstListEntry(LayoutList
);
591 /* Search for default layout (if provided) */
592 if (pszNewLayout
!= NULL
)
594 while (ListEntry
!= NULL
)
596 if (!wcscmp(pszNewLayout
, GetListEntryUserData(ListEntry
)))
598 SetCurrentListEntry(LayoutList
, ListEntry
);
602 ListEntry
= GetNextListEntry(ListEntry
);
609 LanguagePage(PINPUT_RECORD Ir
)
611 PWCHAR NewLanguageId
;
612 BOOL RefreshPage
= FALSE
;
614 /* Initialize the computer settings list */
615 if (LanguageList
== NULL
)
617 LanguageList
= CreateLanguageList(SetupInf
, DefaultLanguage
);
619 if (LanguageList
== NULL
)
621 PopupError("Setup failed to initialize available translations", NULL
, NULL
, POPUP_WAIT_NONE
);
627 SelectedLanguageId
= DefaultLanguage
;
628 SetConsoleCodePage();
630 DrawGenericList(LanguageList
,
636 ScrollToPositionGenericList (LanguageList
, GetDefaultLanguageIndex());
638 MUIDisplayPage(LANGUAGE_PAGE
);
642 CONSOLE_ConInKey(Ir
);
644 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
645 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
)) /* DOWN */
647 ScrollDownGenericList (LanguageList
);
650 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
651 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_UP
)) /* UP */
653 ScrollUpGenericList(LanguageList
);
656 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
657 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_NEXT
)) /* PAGE DOWN */
659 ScrollPageDownGenericList(LanguageList
);
662 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
663 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_PRIOR
)) /* PAGE UP */
665 ScrollPageUpGenericList(LanguageList
);
668 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
669 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
671 if (ConfirmQuit(Ir
) == TRUE
)
674 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
676 SelectedLanguageId
= (PWCHAR
)GetListEntryUserData(GetCurrentListEntry(LanguageList
));
678 LanguageId
= (LANGID
)(wcstol(SelectedLanguageId
, NULL
, 16) & 0xFFFF);
680 if (wcscmp(SelectedLanguageId
, DefaultLanguage
))
686 SetConsoleCodePage();
690 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
> 0x60) && (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
< 0x7b))
693 GenericListKeyPress (LanguageList
, Ir
->Event
.KeyEvent
.uChar
.AsciiChar
);
699 NewLanguageId
= (PWCHAR
)GetListEntryUserData(GetCurrentListEntry(LanguageList
));
701 if (SelectedLanguageId
!= NewLanguageId
)
703 /* Clear the language page */
704 MUIClearPage(LANGUAGE_PAGE
);
706 SelectedLanguageId
= NewLanguageId
;
709 SetConsoleCodePage();
711 /* Redraw language selection page in native language */
712 MUIDisplayPage(LANGUAGE_PAGE
);
726 * Number of the next page.
729 SetupStartPage(PINPUT_RECORD Ir
)
731 SYSTEM_DEVICE_INFORMATION Sdi
;
733 WCHAR FileNameBuffer
[MAX_PATH
];
738 PGENERIC_LIST_ENTRY ListEntry
;
741 CONSOLE_SetStatusText(MUIGetString(STRING_PLEASEWAIT
));
744 /* Check whether a harddisk is available */
745 Status
= NtQuerySystemInformation(SystemDeviceInformation
,
747 sizeof(SYSTEM_DEVICE_INFORMATION
),
750 if (!NT_SUCCESS(Status
))
752 CONSOLE_PrintTextXY(6, 15, "NtQuerySystemInformation() failed (Status 0x%08lx)", Status
);
753 MUIDisplayError(ERROR_DRIVE_INFORMATION
, Ir
, POPUP_WAIT_ENTER
);
757 if (Sdi
.NumberOfDisks
== 0)
759 MUIDisplayError(ERROR_NO_HDD
, Ir
, POPUP_WAIT_ENTER
);
763 /* Get the source path and source root path */
764 Status
= GetSourcePaths(&SourcePath
,
768 if (!NT_SUCCESS(Status
))
770 CONSOLE_PrintTextXY(6, 15, "GetSourcePaths() failed (Status 0x%08lx)", Status
);
771 MUIDisplayError(ERROR_NO_SOURCE_DRIVE
, Ir
, POPUP_WAIT_ENTER
);
777 CONSOLE_PrintTextXY(6, 15, "SourcePath: '%wZ'", &SourcePath
);
778 CONSOLE_PrintTextXY(6, 16, "SourceRootPath: '%wZ'", &SourceRootPath
);
779 CONSOLE_PrintTextXY(6, 17, "SourceRootDir: '%wZ'", &SourceRootDir
);
783 /* Load txtsetup.sif from install media. */
784 wcscpy(FileNameBuffer
, SourcePath
.Buffer
);
785 wcscat(FileNameBuffer
, L
"\\txtsetup.sif");
787 SetupInf
= SetupOpenInfFileW(FileNameBuffer
,
793 if (SetupInf
== INVALID_HANDLE_VALUE
)
795 MUIDisplayError(ERROR_LOAD_TXTSETUPSIF
, Ir
, POPUP_WAIT_ENTER
);
799 /* Open 'Version' section */
800 if (!SetupFindFirstLineW(SetupInf
, L
"Version", L
"Signature", &Context
))
802 MUIDisplayError(ERROR_CORRUPT_TXTSETUPSIF
, Ir
, POPUP_WAIT_ENTER
);
806 /* Get pointer 'Signature' key */
807 if (!INF_GetData(&Context
, NULL
, &Value
))
809 MUIDisplayError(ERROR_CORRUPT_TXTSETUPSIF
, Ir
, POPUP_WAIT_ENTER
);
813 /* Check 'Signature' string */
814 if (_wcsicmp(Value
, L
"$ReactOS$") != 0)
816 MUIDisplayError(ERROR_SIGNATURE_TXTSETUPSIF
, Ir
, POPUP_WAIT_ENTER
);
820 /* Open 'DiskSpaceRequirements' section */
821 if (!SetupFindFirstLineW(SetupInf
, L
"DiskSpaceRequirements", L
"FreeSysPartDiskSpace", &Context
))
823 MUIDisplayError(ERROR_CORRUPT_TXTSETUPSIF
, Ir
, POPUP_WAIT_ENTER
);
827 /* Get the 'FreeSysPartDiskSpace' value */
828 if (!SetupGetIntField(&Context
, 1, &IntValue
))
830 MUIDisplayError(ERROR_CORRUPT_TXTSETUPSIF
, Ir
, POPUP_WAIT_ENTER
);
834 RequiredPartitionDiskSpace
= (ULONG
)IntValue
;
836 /* Start PnP thread */
837 if (hPnpThread
!= INVALID_HANDLE_VALUE
)
839 NtResumeThread(hPnpThread
, NULL
);
840 hPnpThread
= INVALID_HANDLE_VALUE
;
843 CheckUnattendedSetup();
845 if (IsUnattendedSetup
)
848 //read options from inf
849 ComputerList
= CreateComputerTypeList(SetupInf
);
850 DisplayList
= CreateDisplayDriverList(SetupInf
);
851 KeyboardList
= CreateKeyboardDriverList(SetupInf
);
852 LayoutList
= CreateKeyboardLayoutList(SetupInf
, DefaultKBLayout
);
853 LanguageList
= CreateLanguageList(SetupInf
, DefaultLanguage
);
856 wcscpy(SelectedLanguageId
,LocaleID
);
858 /* first we hack LanguageList */
859 ListEntry
= GetFirstListEntry(LanguageList
);
861 while (ListEntry
!= NULL
)
863 if (!wcsicmp(LocaleID
, GetListEntryUserData(ListEntry
)))
865 DPRINT("found %S in LanguageList\n",GetListEntryUserData(ListEntry
));
866 SetCurrentListEntry(LanguageList
, ListEntry
);
870 ListEntry
= GetNextListEntry(ListEntry
);
874 ListEntry
= GetFirstListEntry(LayoutList
);
876 while (ListEntry
!= NULL
)
878 if (!wcsicmp(LocaleID
, GetListEntryUserData(ListEntry
)))
880 DPRINT("found %S in LayoutList\n",GetListEntryUserData(ListEntry
));
881 SetCurrentListEntry(LayoutList
, ListEntry
);
885 ListEntry
= GetNextListEntry(ListEntry
);
888 SetConsoleCodePage();
890 return INSTALL_INTRO_PAGE
;
893 return LANGUAGE_PAGE
;
903 IntroPage(PINPUT_RECORD Ir
)
905 MUIDisplayPage(START_PAGE
);
909 CONSOLE_ConInKey(Ir
);
911 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
912 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
914 if (ConfirmQuit(Ir
) == TRUE
)
919 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
921 return INSTALL_INTRO_PAGE
;
924 else if (toupper(Ir
->Event
.KeyEvent
.uChar
.AsciiChar
) == 'R') /* R */
926 return REPAIR_INTRO_PAGE
;
929 else if (toupper(Ir
->Event
.KeyEvent
.uChar
.AsciiChar
) == 'L') /* R */
943 * Back to main setup page.
946 LicensePage(PINPUT_RECORD Ir
)
948 MUIDisplayPage(LICENSE_PAGE
);
952 CONSOLE_ConInKey(Ir
);
954 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
966 RepairIntroPage(PINPUT_RECORD Ir
)
968 MUIDisplayPage(REPAIR_INTRO_PAGE
);
972 CONSOLE_ConInKey(Ir
);
974 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
978 else if (toupper(Ir
->Event
.KeyEvent
.uChar
.AsciiChar
) == 'U') /* U */
980 RepairUpdateFlag
= TRUE
;
981 return INSTALL_INTRO_PAGE
;
983 else if (toupper(Ir
->Event
.KeyEvent
.uChar
.AsciiChar
) == 'R') /* R */
987 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
988 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
)) /* ESC */
994 return REPAIR_INTRO_PAGE
;
999 InstallIntroPage(PINPUT_RECORD Ir
)
1001 MUIDisplayPage(INSTALL_INTRO_PAGE
);
1003 if (RepairUpdateFlag
)
1005 //return SELECT_PARTITION_PAGE;
1006 return DEVICE_SETTINGS_PAGE
;
1009 if (IsUnattendedSetup
)
1011 return SELECT_PARTITION_PAGE
;
1016 CONSOLE_ConInKey(Ir
);
1018 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1019 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1021 if (ConfirmQuit(Ir
) == TRUE
)
1026 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
1028 return DEVICE_SETTINGS_PAGE
;
1029 // return SCSI_CONTROLLER_PAGE;
1033 return INSTALL_INTRO_PAGE
;
1039 ScsiControllerPage(PINPUT_RECORD Ir
)
1041 SetTextXY(6, 8, "Setup detected the following mass storage devices:");
1043 /* FIXME: print loaded mass storage driver descriptions */
1045 SetTextXY(8, 10, "TEST device");
1049 SetStatusText(" ENTER = Continue F3 = Quit");
1055 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1056 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1058 if (ConfirmQuit(Ir
) == TRUE
)
1063 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
1065 return DEVICE_SETTINGS_PAGE
;
1069 return SCSI_CONTROLLER_PAGE
;
1075 DeviceSettingsPage(PINPUT_RECORD Ir
)
1077 static ULONG Line
= 16;
1078 MUIDisplayPage(DEVICE_SETTINGS_PAGE
);
1080 /* Initialize the computer settings list */
1081 if (ComputerList
== NULL
)
1083 ComputerList
= CreateComputerTypeList(SetupInf
);
1084 if (ComputerList
== NULL
)
1086 MUIDisplayError(ERROR_LOAD_COMPUTER
, Ir
, POPUP_WAIT_ENTER
);
1091 /* Initialize the display settings list */
1092 if (DisplayList
== NULL
)
1094 DisplayList
= CreateDisplayDriverList(SetupInf
);
1095 if (DisplayList
== NULL
)
1097 MUIDisplayError(ERROR_LOAD_DISPLAY
, Ir
, POPUP_WAIT_ENTER
);
1102 /* Initialize the keyboard settings list */
1103 if (KeyboardList
== NULL
)
1105 KeyboardList
= CreateKeyboardDriverList(SetupInf
);
1106 if (KeyboardList
== NULL
)
1108 MUIDisplayError(ERROR_LOAD_KEYBOARD
, Ir
, POPUP_WAIT_ENTER
);
1113 /* Initialize the keyboard layout list */
1114 if (LayoutList
== NULL
)
1116 LayoutList
= CreateKeyboardLayoutList(SetupInf
, DefaultKBLayout
);
1117 if (LayoutList
== NULL
)
1119 /* FIXME: report error */
1120 MUIDisplayError(ERROR_LOAD_KBLAYOUT
, Ir
, POPUP_WAIT_ENTER
);
1125 MUIDisplayPage(DEVICE_SETTINGS_PAGE
);
1128 CONSOLE_SetTextXY(25, 11, GetListEntryText(GetCurrentListEntry((ComputerList
))));
1129 CONSOLE_SetTextXY(25, 12, GetListEntryText(GetCurrentListEntry((DisplayList
))));
1130 CONSOLE_SetTextXY(25, 13, GetListEntryText(GetCurrentListEntry((KeyboardList
))));
1131 CONSOLE_SetTextXY(25, 14, GetListEntryText(GetCurrentListEntry((LayoutList
))));
1133 CONSOLE_InvertTextXY(24, Line
, 48, 1);
1135 if (RepairUpdateFlag
)
1137 return SELECT_PARTITION_PAGE
;
1142 CONSOLE_ConInKey(Ir
);
1144 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1145 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
)) /* DOWN */
1147 CONSOLE_NormalTextXY(24, Line
, 48, 1);
1151 else if (Line
== 16)
1156 CONSOLE_InvertTextXY(24, Line
, 48, 1);
1158 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1159 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_UP
)) /* UP */
1161 CONSOLE_NormalTextXY(24, Line
, 48, 1);
1165 else if (Line
== 16)
1170 CONSOLE_InvertTextXY(24, Line
, 48, 1);
1172 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1173 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1175 if (ConfirmQuit(Ir
) == TRUE
)
1180 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
1183 return COMPUTER_SETTINGS_PAGE
;
1184 else if (Line
== 12)
1185 return DISPLAY_SETTINGS_PAGE
;
1186 else if (Line
== 13)
1187 return KEYBOARD_SETTINGS_PAGE
;
1188 else if (Line
== 14)
1189 return LAYOUT_SETTINGS_PAGE
;
1190 else if (Line
== 16)
1191 return SELECT_PARTITION_PAGE
;
1195 return DEVICE_SETTINGS_PAGE
;
1200 ComputerSettingsPage(PINPUT_RECORD Ir
)
1202 MUIDisplayPage(COMPUTER_SETTINGS_PAGE
);
1204 DrawGenericList(ComputerList
,
1210 SaveGenericListState(ComputerList
);
1214 CONSOLE_ConInKey(Ir
);
1216 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1217 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
)) /* DOWN */
1219 ScrollDownGenericList(ComputerList
);
1221 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1222 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_UP
)) /* UP */
1224 ScrollUpGenericList(ComputerList
);
1226 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1227 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1229 if (ConfirmQuit(Ir
) == TRUE
)
1234 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1235 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
)) /* ESC */
1237 RestoreGenericListState(ComputerList
);
1238 return DEVICE_SETTINGS_PAGE
;
1240 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
1242 return DEVICE_SETTINGS_PAGE
;
1246 return COMPUTER_SETTINGS_PAGE
;
1251 DisplaySettingsPage(PINPUT_RECORD Ir
)
1253 MUIDisplayPage(DISPLAY_SETTINGS_PAGE
);
1255 DrawGenericList(DisplayList
,
1261 SaveGenericListState(DisplayList
);
1265 CONSOLE_ConInKey(Ir
);
1267 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1268 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
)) /* DOWN */
1270 ScrollDownGenericList(DisplayList
);
1272 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1273 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_UP
)) /* UP */
1275 ScrollUpGenericList(DisplayList
);
1277 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1278 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1280 if (ConfirmQuit(Ir
) == TRUE
)
1287 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1288 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
)) /* ESC */
1290 RestoreGenericListState(DisplayList
);
1291 return DEVICE_SETTINGS_PAGE
;
1293 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
1295 return DEVICE_SETTINGS_PAGE
;
1299 return DISPLAY_SETTINGS_PAGE
;
1304 KeyboardSettingsPage(PINPUT_RECORD Ir
)
1306 MUIDisplayPage(KEYBOARD_SETTINGS_PAGE
);
1308 DrawGenericList(KeyboardList
,
1314 SaveGenericListState(KeyboardList
);
1318 CONSOLE_ConInKey(Ir
);
1320 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1321 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
)) /* DOWN */
1323 ScrollDownGenericList(KeyboardList
);
1325 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1326 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_UP
)) /* UP */
1328 ScrollUpGenericList(KeyboardList
);
1330 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1331 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1333 if (ConfirmQuit(Ir
) == TRUE
)
1338 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1339 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
)) /* ESC */
1341 RestoreGenericListState(KeyboardList
);
1342 return DEVICE_SETTINGS_PAGE
;
1344 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
1346 return DEVICE_SETTINGS_PAGE
;
1350 return DISPLAY_SETTINGS_PAGE
;
1355 LayoutSettingsPage(PINPUT_RECORD Ir
)
1357 MUIDisplayPage(LAYOUT_SETTINGS_PAGE
);
1359 DrawGenericList(LayoutList
,
1365 SaveGenericListState(LayoutList
);
1369 CONSOLE_ConInKey(Ir
);
1371 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1372 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
)) /* DOWN */
1374 ScrollDownGenericList(LayoutList
);
1376 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1377 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_UP
)) /* UP */
1379 ScrollUpGenericList(LayoutList
);
1381 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1382 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_NEXT
)) /* PAGE DOWN */
1384 ScrollPageDownGenericList(LayoutList
);
1386 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1387 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_PRIOR
)) /* PAGE UP */
1389 ScrollPageUpGenericList(LayoutList
);
1391 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1392 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1394 if (ConfirmQuit(Ir
) == TRUE
)
1399 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1400 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
)) /* ESC */
1402 RestoreGenericListState(LayoutList
);
1403 return DEVICE_SETTINGS_PAGE
;
1405 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
1407 return DEVICE_SETTINGS_PAGE
;
1409 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
> 0x60) && (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
< 0x7b))
1412 GenericListKeyPress(LayoutList
, Ir
->Event
.KeyEvent
.uChar
.AsciiChar
);
1416 return DISPLAY_SETTINGS_PAGE
;
1421 IsDiskSizeValid(PPARTENTRY PartEntry
)
1425 /* check for unpartitioned space */
1426 m1
= PartEntry
->UnpartitionedLength
;
1427 m1
= (m1
+ (1 << 19)) >> 20; /* in MBytes (rounded) */
1429 if( m1
> RequiredPartitionDiskSpace
)
1434 /* check for partitioned space */
1435 m2
= PartEntry
->PartInfo
[0].PartitionLength
.QuadPart
;
1436 m2
= (m2
+ (1 << 19)) >> 20; /* in MBytes (rounded) */
1437 if (m2
< RequiredPartitionDiskSpace
)
1439 /* partition is too small so ask for another partion */
1440 DPRINT1("Partition is too small(unpartitioned: %I64u MB, partitioned: %I64u MB), required disk space is %lu MB\n", m1
, m2
, RequiredPartitionDiskSpace
);
1451 SelectPartitionPage(PINPUT_RECORD Ir
)
1453 MUIDisplayPage(SELECT_PARTITION_PAGE
);
1455 if (PartitionList
== NULL
)
1457 PartitionList
= CreatePartitionList(2,
1461 if (PartitionList
== NULL
)
1463 /* FIXME: show an error dialog */
1468 CheckActiveBootPartition(PartitionList
);
1470 DrawPartitionList(PartitionList
);
1472 /* Warn about partitions created by Linux Fdisk */
1473 if (WarnLinuxPartitions
== TRUE
&&
1474 CheckForLinuxFdiskPartitions(PartitionList
) == TRUE
)
1476 MUIDisplayError(ERROR_WARN_PARTITION
, NULL
, POPUP_WAIT_NONE
);
1480 CONSOLE_ConInKey(Ir
);
1482 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1483 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1487 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_RETURN
) /* ENTER */
1489 WarnLinuxPartitions
= FALSE
;
1490 return SELECT_PARTITION_PAGE
;
1495 if (IsUnattendedSetup
)
1497 if (!SelectPartition(PartitionList
, UnattendDestinationDiskNumber
, UnattendDestinationPartitionNumber
))
1501 PPARTENTRY PartEntry
= PartitionList
->CurrentPartition
;
1502 ULONG MaxSize
= (PartEntry
->UnpartitionedLength
+ (1 << 19)) >> 20; /* in MBytes (rounded) */
1503 if(!IsDiskSizeValid(PartitionList
->CurrentPartition
))
1505 MUIDisplayError(ERROR_INSUFFICIENT_DISKSPACE
, Ir
, POPUP_WAIT_ANY_KEY
);
1506 return SELECT_PARTITION_PAGE
; /* let the user select another partition */
1509 CreateNewPartition(PartitionList
,
1513 return SELECT_FILE_SYSTEM_PAGE
;
1518 if(!IsDiskSizeValid(PartitionList
->CurrentPartition
))
1520 MUIDisplayError(ERROR_INSUFFICIENT_DISKSPACE
, Ir
, POPUP_WAIT_ANY_KEY
);
1521 return SELECT_PARTITION_PAGE
; /* let the user select another partition */
1524 return SELECT_FILE_SYSTEM_PAGE
;
1530 /* Update status text */
1531 if (PartitionList
->CurrentPartition
== NULL
||
1532 PartitionList
->CurrentPartition
->Unpartitioned
== TRUE
)
1534 CONSOLE_SetStatusText(MUIGetString(STRING_INSTALLCREATEPARTITION
));
1538 CONSOLE_SetStatusText(MUIGetString(STRING_INSTALLDELETEPARTITION
));
1541 CONSOLE_ConInKey(Ir
);
1543 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1544 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1546 if (ConfirmQuit(Ir
) == TRUE
)
1548 DestroyPartitionList(PartitionList
);
1549 PartitionList
= NULL
;
1555 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1556 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
)) /* DOWN */
1558 ScrollDownPartitionList(PartitionList
);
1560 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1561 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_UP
)) /* UP */
1563 ScrollUpPartitionList(PartitionList
);
1565 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_RETURN
) /* ENTER */
1567 if(!IsDiskSizeValid(PartitionList
->CurrentPartition
))
1569 MUIDisplayError(ERROR_INSUFFICIENT_DISKSPACE
, Ir
, POPUP_WAIT_ANY_KEY
);
1570 return SELECT_PARTITION_PAGE
; /* let the user select another partition */
1572 if (PartitionList
->CurrentPartition
== NULL
||
1573 PartitionList
->CurrentPartition
->Unpartitioned
== TRUE
)
1575 CreateNewPartition(PartitionList
,
1580 return SELECT_FILE_SYSTEM_PAGE
;
1582 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== 'C') /* C */
1584 if (PartitionList
->CurrentPartition
->Unpartitioned
== FALSE
)
1586 MUIDisplayError(ERROR_NEW_PARTITION
, Ir
, POPUP_WAIT_ANY_KEY
);
1587 return SELECT_PARTITION_PAGE
;
1590 return CREATE_PARTITION_PAGE
;
1592 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== 'D') /* D */
1594 if (PartitionList
->CurrentPartition
->Unpartitioned
== TRUE
)
1596 MUIDisplayError(ERROR_DELETE_SPACE
, Ir
, POPUP_WAIT_ANY_KEY
);
1597 return SELECT_PARTITION_PAGE
;
1600 return DELETE_PARTITION_PAGE
;
1604 return SELECT_PARTITION_PAGE
;
1609 DrawInputField(ULONG FieldLength
,
1620 memset(buf
, '_', sizeof(buf
));
1621 buf
[FieldLength
- strlen(FieldContent
)] = 0;
1622 strcat(buf
, FieldContent
);
1624 WriteConsoleOutputCharacterA(StdOutput
,
1632 #define PARTITION_SIZE_INPUT_FIELD_LENGTH 6
1633 /* Restriction for MaxSize: pow(10, PARTITION_SIZE_INPUT_FIELD_LENGTH)-1 */
1634 #define PARTITION_MAXSIZE 999999
1637 ShowPartitionSizeInputBox(SHORT Left
,
1661 DrawBox(Left
, Top
, Right
- Left
+ 1, Bottom
- Top
+ 1);
1666 strcpy(Buffer
, MUIGetString(STRING_PARTITIONSIZE
));
1667 iLeft
= coPos
.X
+ strlen(Buffer
) + 1;
1670 WriteConsoleOutputCharacterA(StdOutput
,
1676 sprintf(Buffer
, MUIGetString(STRING_MAXSIZE
), MaxSize
);
1677 coPos
.X
= iLeft
+ PARTITION_SIZE_INPUT_FIELD_LENGTH
+ 1;
1679 WriteConsoleOutputCharacterA(StdOutput
,
1685 sprintf(Buffer
, "%lu", MaxSize
);
1686 Index
= strlen(Buffer
);
1687 DrawInputField(PARTITION_SIZE_INPUT_FIELD_LENGTH
,
1694 CONSOLE_ConInKey(&Ir
);
1696 if ((Ir
.Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1697 (Ir
.Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1705 else if (Ir
.Event
.KeyEvent
.wVirtualKeyCode
== VK_RETURN
) /* ENTER */
1709 else if (Ir
.Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
) /* ESCAPE */
1717 else if ((Ir
.Event
.KeyEvent
.wVirtualKeyCode
== VK_BACK
) && /* BACKSPACE */
1723 DrawInputField(PARTITION_SIZE_INPUT_FIELD_LENGTH
,
1728 else if ((Ir
.Event
.KeyEvent
.uChar
.AsciiChar
!= 0x00) &&
1729 (Index
< PARTITION_SIZE_INPUT_FIELD_LENGTH
))
1731 ch
= Ir
.Event
.KeyEvent
.uChar
.AsciiChar
;
1733 if ((ch
>= '0') && (ch
<= '9'))
1739 DrawInputField(PARTITION_SIZE_INPUT_FIELD_LENGTH
,
1747 strcpy(InputBuffer
, Buffer
);
1752 CreatePartitionPage(PINPUT_RECORD Ir
)
1754 PDISKENTRY DiskEntry
;
1755 PPARTENTRY PartEntry
;
1758 CHAR InputBuffer
[50];
1764 if (PartitionList
== NULL
||
1765 PartitionList
->CurrentDisk
== NULL
||
1766 PartitionList
->CurrentPartition
== NULL
)
1768 /* FIXME: show an error dialog */
1772 DiskEntry
= PartitionList
->CurrentDisk
;
1773 PartEntry
= PartitionList
->CurrentPartition
;
1775 CONSOLE_SetStatusText(MUIGetString(STRING_PLEASEWAIT
));
1777 CONSOLE_SetTextXY(6, 8, MUIGetString(STRING_CHOOSENEWPARTITION
));
1780 if (DiskEntry
->DiskSize
>= 0x280000000ULL
) /* 10 GB */
1782 DiskSize
= (DiskEntry
->DiskSize
+ (1 << 29)) >> 30;
1783 Unit
= MUIGetString(STRING_GB
);
1788 DiskSize
= (DiskEntry
->DiskSize
+ (1 << 19)) >> 20;
1793 Unit
= MUIGetString(STRING_MB
);
1796 if (DiskEntry
->DriverName
.Length
> 0)
1798 CONSOLE_PrintTextXY(6, 10,
1799 MUIGetString(STRING_HDINFOPARTCREATE
),
1802 DiskEntry
->DiskNumber
,
1806 &DiskEntry
->DriverName
);
1810 CONSOLE_PrintTextXY(6, 10,
1811 MUIGetString(STRING_HDDINFOUNK1
),
1814 DiskEntry
->DiskNumber
,
1820 CONSOLE_SetTextXY(6, 12, MUIGetString(STRING_HDDSIZE
));
1823 CONSOLE_PrintTextXY(8, 10, "Maximum size of the new partition is %I64u MB",
1824 PartitionList
->CurrentPartition
->UnpartitionedLength
/ (1024*1024));
1827 CONSOLE_SetStatusText(MUIGetString(STRING_CREATEPARTITION
));
1829 PartEntry
= PartitionList
->CurrentPartition
;
1832 MaxSize
= (PartEntry
->UnpartitionedLength
+ (1 << 19)) >> 20; /* in MBytes (rounded) */
1834 if (MaxSize
> PARTITION_MAXSIZE
) MaxSize
= PARTITION_MAXSIZE
;
1836 ShowPartitionSizeInputBox(12, 14, xScreen
- 12, 17, /* left, top, right, bottom */
1837 MaxSize
, InputBuffer
, &Quit
, &Cancel
);
1841 if (ConfirmQuit (Ir
) == TRUE
)
1846 else if (Cancel
== TRUE
)
1848 return SELECT_PARTITION_PAGE
;
1852 PartSize
= atoi(InputBuffer
);
1860 if (PartSize
> MaxSize
)
1866 /* Convert to bytes */
1867 if (PartSize
== MaxSize
)
1869 /* Use all of the unpartitioned disk space */
1870 PartSize
= PartEntry
->UnpartitionedLength
;
1874 /* Round-up by cylinder size */
1875 PartSize
= (PartSize
* 1024 * 1024 + DiskEntry
->CylinderSize
- 1) /
1876 DiskEntry
->CylinderSize
* DiskEntry
->CylinderSize
;
1878 /* But never get larger than the unpartitioned disk space */
1879 if (PartSize
> PartEntry
->UnpartitionedLength
)
1880 PartSize
= PartEntry
->UnpartitionedLength
;
1883 DPRINT ("Partition size: %I64u bytes\n", PartSize
);
1885 CreateNewPartition(PartitionList
,
1889 return SELECT_PARTITION_PAGE
;
1893 return CREATE_PARTITION_PAGE
;
1898 DeletePartitionPage(PINPUT_RECORD Ir
)
1900 PDISKENTRY DiskEntry
;
1901 PPARTENTRY PartEntry
;
1908 if (PartitionList
== NULL
||
1909 PartitionList
->CurrentDisk
== NULL
||
1910 PartitionList
->CurrentPartition
== NULL
)
1912 /* FIXME: show an error dialog */
1916 DiskEntry
= PartitionList
->CurrentDisk
;
1917 PartEntry
= PartitionList
->CurrentPartition
;
1918 PartNumber
= PartitionList
->CurrentPartitionNumber
;
1920 MUIDisplayPage(DELETE_PARTITION_PAGE
);
1922 /* Determine partition type */
1924 if (PartEntry
->New
== TRUE
)
1926 PartType
= MUIGetString(STRING_UNFORMATTED
);
1928 else if (PartEntry
->Unpartitioned
== FALSE
)
1930 if ((PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_FAT_12
) ||
1931 (PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_FAT_16
) ||
1932 (PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_HUGE
) ||
1933 (PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_XINT13
))
1937 else if ((PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_FAT32
) ||
1938 (PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_FAT32_XINT13
))
1942 else if (PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_EXT2
)
1946 else if (PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_IFS
)
1948 PartType
= "NTFS"; /* FIXME: Not quite correct! */
1953 if (PartEntry
->PartInfo
[PartNumber
].PartitionLength
.QuadPart
>= 0x280000000LL
) /* 10 GB */
1955 PartSize
= (PartEntry
->PartInfo
[PartNumber
].PartitionLength
.QuadPart
+ (1 << 29)) >> 30;
1956 Unit
= MUIGetString(STRING_GB
);
1960 if (PartEntry
->PartInfo
[PartNumber
].PartitionLength
.QuadPart
>= 0xA00000LL
) /* 10 MB */
1962 PartSize
= (PartEntry
->PartInfo
[PartNumber
].PartitionLength
.QuadPart
+ (1 << 19)) >> 20;
1963 Unit
= MUIGetString(STRING_MB
);
1967 PartSize
= (PartEntry
->PartInfo
[PartNumber
].PartitionLength
.QuadPart
+ (1 << 9)) >> 10;
1968 Unit
= MUIGetString(STRING_KB
);
1971 if (PartType
== NULL
)
1973 CONSOLE_PrintTextXY(6, 10,
1974 MUIGetString(STRING_HDDINFOUNK2
),
1975 (PartEntry
->DriveLetter
[PartNumber
] == 0) ? '-' : PartEntry
->DriveLetter
[PartNumber
],
1976 (PartEntry
->DriveLetter
[PartNumber
] == 0) ? '-' : ':',
1977 PartEntry
->PartInfo
[PartNumber
].PartitionType
,
1983 CONSOLE_PrintTextXY(6, 10,
1984 " %c%c %s %I64u %s",
1985 (PartEntry
->DriveLetter
[PartNumber
] == 0) ? '-' : PartEntry
->DriveLetter
[PartNumber
],
1986 (PartEntry
->DriveLetter
[PartNumber
] == 0) ? '-' : ':',
1993 if (DiskEntry
->DiskSize
>= 0x280000000ULL
) /* 10 GB */
1995 DiskSize
= (DiskEntry
->DiskSize
+ (1 << 29)) >> 30;
1996 Unit
= MUIGetString(STRING_GB
);
2001 DiskSize
= (DiskEntry
->DiskSize
+ (1 << 19)) >> 20;
2006 Unit
= MUIGetString(STRING_MB
);
2009 if (DiskEntry
->DriverName
.Length
> 0)
2011 CONSOLE_PrintTextXY(6, 12,
2012 MUIGetString(STRING_HDINFOPARTDELETE
),
2015 DiskEntry
->DiskNumber
,
2019 &DiskEntry
->DriverName
);
2023 CONSOLE_PrintTextXY(6, 12,
2024 MUIGetString(STRING_HDDINFOUNK3
),
2027 DiskEntry
->DiskNumber
,
2035 CONSOLE_ConInKey(Ir
);
2037 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
2038 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
2040 if (ConfirmQuit(Ir
) == TRUE
)
2047 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
) /* ESC */
2049 return SELECT_PARTITION_PAGE
;
2051 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== 'D') /* D */
2053 DeleteCurrentPartition(PartitionList
);
2055 return SELECT_PARTITION_PAGE
;
2059 return DELETE_PARTITION_PAGE
;
2064 SelectFileSystemPage(PINPUT_RECORD Ir
)
2066 PDISKENTRY DiskEntry
;
2067 PPARTENTRY PartEntry
;
2075 if (PartitionList
== NULL
||
2076 PartitionList
->CurrentDisk
== NULL
||
2077 PartitionList
->CurrentPartition
== NULL
)
2079 /* FIXME: show an error dialog */
2083 DiskEntry
= PartitionList
->CurrentDisk
;
2084 PartEntry
= PartitionList
->CurrentPartition
;
2085 PartNumber
= PartitionList
->CurrentPartitionNumber
;
2087 /* adjust disk size */
2088 if (DiskEntry
->DiskSize
>= 0x280000000ULL
) /* 10 GB */
2090 DiskSize
= (DiskEntry
->DiskSize
+ (1 << 29)) >> 30;
2091 DiskUnit
= MUIGetString(STRING_GB
);
2095 DiskSize
= (DiskEntry
->DiskSize
+ (1 << 19)) >> 20;
2096 DiskUnit
= MUIGetString(STRING_MB
);
2099 /* adjust partition size */
2100 if (PartEntry
->PartInfo
[PartNumber
].PartitionLength
.QuadPart
>= 0x280000000LL
) /* 10 GB */
2102 PartSize
= (PartEntry
->PartInfo
[PartNumber
].PartitionLength
.QuadPart
+ (1 << 29)) >> 30;
2103 PartUnit
= MUIGetString(STRING_GB
);
2107 PartSize
= (PartEntry
->PartInfo
[PartNumber
].PartitionLength
.QuadPart
+ (1 << 19)) >> 20;
2108 PartUnit
= MUIGetString(STRING_MB
);
2111 /* adjust partition type */
2112 if ((PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_FAT_12
) ||
2113 (PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_FAT_16
) ||
2114 (PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_HUGE
) ||
2115 (PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_XINT13
))
2119 else if ((PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_FAT32
) ||
2120 (PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_FAT32_XINT13
))
2124 else if (PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_EXT2
)
2128 else if (PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_IFS
)
2130 PartType
= "NTFS"; /* FIXME: Not quite correct! */
2132 else if (PartEntry
->PartInfo
[PartNumber
].PartitionType
== PARTITION_ENTRY_UNUSED
)
2134 PartType
= MUIGetString(STRING_FORMATUNUSED
);
2138 PartType
= MUIGetString(STRING_FORMATUNKNOWN
);
2141 if (PartEntry
->AutoCreate
== TRUE
)
2143 CONSOLE_SetTextXY(6, 8, MUIGetString(STRING_NEWPARTITION
));
2146 CONSOLE_PrintTextXY(8, 10, "Partition %lu (%I64u %s) %s of",
2147 PartEntry
->PartInfo
[PartNumber
].PartitionNumber
,
2153 CONSOLE_PrintTextXY(8, 10, MUIGetString(STRING_HDINFOPARTZEROED
),
2154 DiskEntry
->DiskNumber
,
2160 &DiskEntry
->DriverName
);
2162 CONSOLE_SetTextXY(6, 12, MUIGetString(STRING_PARTFORMAT
));
2165 PartEntry
->AutoCreate
= FALSE
;
2167 else if (PartEntry
->New
== TRUE
)
2169 CONSOLE_SetTextXY(6, 8, MUIGetString(STRING_NONFORMATTEDPART
));
2170 CONSOLE_SetTextXY(6, 10, MUIGetString(STRING_PARTFORMAT
));
2174 CONSOLE_SetTextXY(6, 8, MUIGetString(STRING_INSTALLONPART
));
2176 if (PartType
== NULL
)
2178 CONSOLE_PrintTextXY(8, 10,
2179 MUIGetString(STRING_HDDINFOUNK4
),
2180 (PartEntry
->DriveLetter
[PartNumber
] == 0) ? '-' : PartEntry
->DriveLetter
[PartNumber
],
2181 (PartEntry
->DriveLetter
[PartNumber
] == 0) ? '-' : ':',
2182 PartEntry
->PartInfo
[PartNumber
].PartitionType
,
2188 CONSOLE_PrintTextXY(8, 10,
2190 (PartEntry
->DriveLetter
[PartNumber
] == 0) ? '-' : PartEntry
->DriveLetter
[PartNumber
],
2191 (PartEntry
->DriveLetter
[PartNumber
] == 0) ? '-' : ':',
2197 CONSOLE_PrintTextXY(6, 12, MUIGetString(STRING_HDINFOPARTEXISTS
),
2198 DiskEntry
->DiskNumber
,
2204 &DiskEntry
->DriverName
);
2207 MUIDisplayPage(SELECT_FILE_SYSTEM_PAGE
);
2209 if (FileSystemList
== NULL
)
2211 FileSystemList
= CreateFileSystemList(6, 26, PartEntry
->New
, L
"FAT");
2212 if (FileSystemList
== NULL
)
2214 /* FIXME: show an error dialog */
2218 /* FIXME: Add file systems to list */
2220 DrawFileSystemList(FileSystemList
);
2222 if (RepairUpdateFlag
)
2224 return CHECK_FILE_SYSTEM_PAGE
;
2225 //return SELECT_PARTITION_PAGE;
2228 if (IsUnattendedSetup
)
2230 if (UnattendFormatPartition
)
2232 return FORMAT_PARTITION_PAGE
;
2235 return CHECK_FILE_SYSTEM_PAGE
;
2240 CONSOLE_ConInKey(Ir
);
2242 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
2243 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
2245 if (ConfirmQuit(Ir
) == TRUE
)
2252 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
2253 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
)) /* ESC */
2255 return SELECT_PARTITION_PAGE
;
2257 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
2258 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
)) /* DOWN */
2260 ScrollDownFileSystemList(FileSystemList
);
2262 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
2263 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_UP
)) /* UP */
2265 ScrollUpFileSystemList(FileSystemList
);
2267 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_RETURN
) /* ENTER */
2269 if (!FileSystemList
->Selected
->FormatFunc
)
2271 return CHECK_FILE_SYSTEM_PAGE
;
2275 return FORMAT_PARTITION_PAGE
;
2280 return SELECT_FILE_SYSTEM_PAGE
;
2285 FormatPartitionPage(PINPUT_RECORD Ir
)
2287 WCHAR PathBuffer
[MAX_PATH
];
2288 PPARTENTRY PartEntry
;
2293 PDISKENTRY DiskEntry
;
2299 MUIDisplayPage(FORMAT_PARTITION_PAGE
);
2301 if (PartitionList
== NULL
||
2302 PartitionList
->CurrentDisk
== NULL
||
2303 PartitionList
->CurrentPartition
== NULL
)
2305 /* FIXME: show an error dialog */
2310 DiskEntry
= PartitionList
->CurrentDisk
;
2312 PartEntry
= PartitionList
->CurrentPartition
;
2313 PartNum
= PartitionList
->CurrentPartitionNumber
;
2317 if (!IsUnattendedSetup
)
2319 CONSOLE_ConInKey(Ir
);
2322 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
2323 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
2325 if (ConfirmQuit(Ir
) == TRUE
)
2332 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_RETURN
|| IsUnattendedSetup
) /* ENTER */
2334 CONSOLE_SetStatusText(MUIGetString(STRING_PLEASEWAIT
));
2336 if (wcscmp(FileSystemList
->Selected
->FileSystem
, L
"FAT") == 0)
2338 if (PartEntry
->PartInfo
[PartNum
].PartitionLength
.QuadPart
< (4200LL * 1024LL))
2340 /* FAT12 CHS partition (disk is smaller than 4.1MB) */
2341 PartEntry
->PartInfo
[PartNum
].PartitionType
= PARTITION_FAT_12
;
2343 else if (PartEntry
->PartInfo
[PartNum
].StartingOffset
.QuadPart
< (1024LL * 255LL * 63LL * 512LL))
2345 /* Partition starts below the 8.4GB boundary ==> CHS partition */
2347 if (PartEntry
->PartInfo
[PartNum
].PartitionLength
.QuadPart
< (32LL * 1024LL * 1024LL))
2349 /* FAT16 CHS partition (partiton size < 32MB) */
2350 PartEntry
->PartInfo
[PartNum
].PartitionType
= PARTITION_FAT_16
;
2352 else if (PartEntry
->PartInfo
[PartNum
].PartitionLength
.QuadPart
< (512LL * 1024LL * 1024LL))
2354 /* FAT16 CHS partition (partition size < 512MB) */
2355 PartEntry
->PartInfo
[PartNum
].PartitionType
= PARTITION_HUGE
;
2359 /* FAT32 CHS partition (partition size >= 512MB) */
2360 PartEntry
->PartInfo
[PartNum
].PartitionType
= PARTITION_FAT32
;
2365 /* Partition starts above the 8.4GB boundary ==> LBA partition */
2367 if (PartEntry
->PartInfo
[PartNum
].PartitionLength
.QuadPart
< (512LL * 1024LL * 1024LL))
2369 /* FAT16 LBA partition (partition size < 512MB) */
2370 PartEntry
->PartInfo
[PartNum
].PartitionType
= PARTITION_XINT13
;
2374 /* FAT32 LBA partition (partition size >= 512MB) */
2375 PartEntry
->PartInfo
[PartNum
].PartitionType
= PARTITION_FAT32_XINT13
;
2379 else if (wcscmp(FileSystemList
->Selected
->FileSystem
, L
"EXT2") == 0)
2380 PartEntry
->PartInfo
[PartNum
].PartitionType
= PARTITION_EXT2
;
2381 else if (!FileSystemList
->Selected
->FormatFunc
)
2384 CheckActiveBootPartition(PartitionList
);
2387 CONSOLE_PrintTextXY(6, 12,
2388 "Disk: %I64u Cylinder: %I64u Track: %I64u",
2389 DiskEntry
->DiskSize
,
2390 DiskEntry
->CylinderSize
,
2391 DiskEntry
->TrackSize
);
2394 DiskEntry
= PartitionList
->CurrentDisk
;
2395 Entry
= DiskEntry
->PartListHead
.Flink
;
2397 while (Entry
!= &DiskEntry
->PartListHead
)
2399 PartEntry
= CONTAINING_RECORD(Entry
, PARTENTRY
, ListEntry
);
2401 if (PartEntry
->Unpartitioned
== FALSE
)
2403 for (i
= 0; i
< 4; i
++)
2405 CONSOLE_PrintTextXY(6, Line
,
2406 "%2u: %2u %c %12I64u %12I64u %2u %c",
2408 PartEntry
->PartInfo
[i
].PartitionNumber
,
2409 PartEntry
->PartInfo
[i
].BootIndicator
? 'A' : '-',
2410 PartEntry
->PartInfo
[i
].StartingOffset
.QuadPart
,
2411 PartEntry
->PartInfo
[i
].PartitionLength
.QuadPart
,
2412 PartEntry
->PartInfo
[i
].PartitionType
,
2413 PartEntry
->PartInfo
[i
].RewritePartition
? '*' : ' ');
2421 Entry
= Entry
->Flink
;
2424 /* Restore the old entry */
2425 PartEntry
= PartitionList
->CurrentPartition
;
2428 if (WritePartitionsToDisk(PartitionList
) == FALSE
)
2430 DPRINT("WritePartitionsToDisk() failed\n");
2431 MUIDisplayError(ERROR_WRITE_PTABLE
, Ir
, POPUP_WAIT_ENTER
);
2435 /* Set DestinationRootPath */
2436 RtlFreeUnicodeString(&DestinationRootPath
);
2437 swprintf(PathBuffer
,
2438 L
"\\Device\\Harddisk%lu\\Partition%lu",
2439 PartitionList
->CurrentDisk
->DiskNumber
,
2440 PartitionList
->CurrentPartition
->PartInfo
[PartNum
].PartitionNumber
);
2441 RtlCreateUnicodeString(&DestinationRootPath
,
2443 DPRINT("DestinationRootPath: %wZ\n", &DestinationRootPath
);
2446 /* Set SystemRootPath */
2447 RtlFreeUnicodeString(&SystemRootPath
);
2448 swprintf(PathBuffer
,
2449 L
"\\Device\\Harddisk%lu\\Partition%lu",
2450 PartitionList
->ActiveBootDisk
->DiskNumber
,
2451 PartitionList
->ActiveBootPartition
->
2452 PartInfo
[PartitionList
->ActiveBootPartitionNumber
].PartitionNumber
);
2453 RtlCreateUnicodeString(&SystemRootPath
,
2455 DPRINT("SystemRootPath: %wZ\n", &SystemRootPath
);
2458 if (FileSystemList
->Selected
->FormatFunc
)
2460 Status
= FormatPartition(&DestinationRootPath
,
2461 FileSystemList
->Selected
);
2462 if (!NT_SUCCESS(Status
))
2464 DPRINT1("FormatPartition() failed with status 0x%08lx\n", Status
);
2465 /* FIXME: show an error dialog */
2469 PartEntry
->New
= FALSE
;
2471 CheckActiveBootPartition(PartitionList
);
2475 CONSOLE_SetStatusText(" Done. Press any key ...");
2476 CONSOLE_ConInKey(Ir
);
2479 DestroyFileSystemList(FileSystemList
);
2480 FileSystemList
= NULL
;
2481 return INSTALL_DIRECTORY_PAGE
;
2485 return FORMAT_PARTITION_PAGE
;
2490 CheckFileSystemPage(PINPUT_RECORD Ir
)
2492 PFILE_SYSTEM_ITEM CurrentFileSystem
;
2493 WCHAR PathBuffer
[MAX_PATH
];
2494 CHAR Buffer
[MAX_PATH
];
2496 UCHAR PartNum
= PartitionList
->CurrentPartitionNumber
;
2498 /* FIXME: code duplicated in FormatPartitionPage */
2499 /* Set DestinationRootPath */
2500 RtlFreeUnicodeString(&DestinationRootPath
);
2501 swprintf(PathBuffer
,
2502 L
"\\Device\\Harddisk%lu\\Partition%lu",
2503 PartitionList
->CurrentDisk
->DiskNumber
,
2504 PartitionList
->CurrentPartition
->PartInfo
[PartNum
].PartitionNumber
);
2505 RtlCreateUnicodeString(&DestinationRootPath
, PathBuffer
);
2506 DPRINT("DestinationRootPath: %wZ\n", &DestinationRootPath
);
2508 /* Set SystemRootPath */
2509 RtlFreeUnicodeString(&SystemRootPath
);
2510 swprintf(PathBuffer
,
2511 L
"\\Device\\Harddisk%lu\\Partition%lu",
2512 PartitionList
->ActiveBootDisk
->DiskNumber
,
2513 PartitionList
->ActiveBootPartition
->PartInfo
[PartNum
].PartitionNumber
);
2514 RtlCreateUnicodeString(&SystemRootPath
, PathBuffer
);
2515 DPRINT("SystemRootPath: %wZ\n", &SystemRootPath
);
2517 CONSOLE_SetTextXY(6, 8, MUIGetString(STRING_CHECKINGPART
));
2519 CONSOLE_SetStatusText(MUIGetString(STRING_PLEASEWAIT
));
2521 /* WRONG: first filesystem is not necesseraly the one of the current partition! */
2522 CurrentFileSystem
= CONTAINING_RECORD(FileSystemList
->ListHead
.Flink
, FILE_SYSTEM_ITEM
, ListEntry
);
2524 if (!CurrentFileSystem
->ChkdskFunc
)
2527 "Setup is currently unable to check a partition formatted in %S.\n"
2529 " \x07 Press ENTER to continue Setup.\n"
2530 " \x07 Press F3 to quit Setup.",
2531 CurrentFileSystem
->FileSystem
);
2534 MUIGetString(STRING_QUITCONTINUE
),
2535 NULL
, POPUP_WAIT_NONE
);
2539 CONSOLE_ConInKey(Ir
);
2541 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00 &&
2542 Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
) /* F3 */
2544 if (ConfirmQuit(Ir
))
2547 return CHECK_FILE_SYSTEM_PAGE
;
2549 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== VK_RETURN
) /* ENTER */
2551 return INSTALL_DIRECTORY_PAGE
;
2557 Status
= ChkdskPartition(&DestinationRootPath
, CurrentFileSystem
);
2558 if (!NT_SUCCESS(Status
))
2560 DPRINT("ChkdskPartition() failed with status 0x%08lx\n", Status
);
2561 sprintf(Buffer
, "Setup failed to verify the selected partition.\n"
2562 "(Status 0x%08lx).\n", Status
);
2565 MUIGetString(STRING_REBOOTCOMPUTER
),
2566 Ir
, POPUP_WAIT_ENTER
);
2571 return INSTALL_DIRECTORY_PAGE
;
2577 InstallDirectoryPage1(PWCHAR InstallDir
,
2578 PDISKENTRY DiskEntry
,
2579 PPARTENTRY PartEntry
,
2582 WCHAR PathBuffer
[MAX_PATH
];
2584 /* Create 'InstallPath' string */
2585 RtlFreeUnicodeString(&InstallPath
);
2586 RtlCreateUnicodeString(&InstallPath
,
2589 /* Create 'DestinationPath' string */
2590 RtlFreeUnicodeString(&DestinationPath
);
2591 wcscpy(PathBuffer
, DestinationRootPath
.Buffer
);
2593 if (InstallDir
[0] != L
'\\')
2594 wcscat(PathBuffer
, L
"\\");
2596 wcscat(PathBuffer
, InstallDir
);
2597 RtlCreateUnicodeString(&DestinationPath
, PathBuffer
);
2599 /* Create 'DestinationArcPath' */
2600 RtlFreeUnicodeString(&DestinationArcPath
);
2601 swprintf(PathBuffer
,
2602 L
"multi(0)disk(0)rdisk(%lu)partition(%lu)",
2603 DiskEntry
->BiosDiskNumber
,
2604 PartEntry
->PartInfo
[PartNum
].PartitionNumber
);
2606 if (InstallDir
[0] != L
'\\')
2607 wcscat(PathBuffer
, L
"\\");
2609 wcscat(PathBuffer
, InstallDir
);
2610 RtlCreateUnicodeString(&DestinationArcPath
, PathBuffer
);
2612 return PREPARE_COPY_PAGE
;
2617 InstallDirectoryPage(PINPUT_RECORD Ir
)
2619 PDISKENTRY DiskEntry
;
2620 PPARTENTRY PartEntry
;
2621 WCHAR InstallDir
[51];
2626 if (PartitionList
== NULL
||
2627 PartitionList
->CurrentDisk
== NULL
||
2628 PartitionList
->CurrentPartition
== NULL
)
2630 /* FIXME: show an error dialog */
2634 DiskEntry
= PartitionList
->CurrentDisk
;
2635 PartEntry
= PartitionList
->CurrentPartition
;
2637 /* Search for 'DefaultPath' in the 'SetupData' section */
2638 if (!SetupFindFirstLineW(SetupInf
, L
"SetupData", L
"DefaultPath", &Context
))
2640 MUIDisplayError(ERROR_FIND_SETUPDATA
, Ir
, POPUP_WAIT_ENTER
);
2644 /* Read the 'DefaultPath' data */
2645 if (INF_GetData(&Context
, NULL
, &DefaultPath
))
2647 wcscpy(InstallDir
, DefaultPath
);
2651 wcscpy(InstallDir
, L
"\\ReactOS");
2654 Length
= wcslen(InstallDir
);
2655 CONSOLE_SetInputTextXY(8, 11, 51, InstallDir
);
2656 MUIDisplayPage(INSTALL_DIRECTORY_PAGE
);
2658 if (IsUnattendedSetup
)
2660 return InstallDirectoryPage1(InstallDir
,
2663 PartitionList
->CurrentPartitionNumber
);
2668 CONSOLE_ConInKey(Ir
);
2670 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
2671 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
2673 if (ConfirmQuit(Ir
) == TRUE
)
2678 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2680 return InstallDirectoryPage1(InstallDir
,
2683 PartitionList
->CurrentPartitionNumber
);
2685 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x08) /* BACKSPACE */
2690 InstallDir
[Length
] = 0;
2691 CONSOLE_SetInputTextXY(8, 11, 51, InstallDir
);
2694 else if (isprint(Ir
->Event
.KeyEvent
.uChar
.AsciiChar
))
2698 InstallDir
[Length
] = (WCHAR
)Ir
->Event
.KeyEvent
.uChar
.AsciiChar
;
2700 InstallDir
[Length
] = 0;
2701 CONSOLE_SetInputTextXY(8, 11, 51, InstallDir
);
2706 return INSTALL_DIRECTORY_PAGE
;
2711 AddSectionToCopyQueueCab(HINF InfFile
,
2713 PWCHAR SourceCabinet
,
2714 PCUNICODE_STRING DestinationPath
,
2717 INFCONTEXT FilesContext
;
2718 INFCONTEXT DirContext
;
2720 PWCHAR FileKeyValue
;
2722 PWCHAR TargetFileName
;
2724 /* Search for the SectionName section */
2725 if (!SetupFindFirstLineW(InfFile
, SectionName
, NULL
, &FilesContext
))
2728 sprintf(Buffer
, MUIGetString(STRING_TXTSETUPFAILED
), SectionName
);
2729 PopupError(Buffer
, MUIGetString(STRING_REBOOTCOMPUTER
), Ir
, POPUP_WAIT_ENTER
);
2734 * Enumerate the files in the section
2735 * and add them to the file queue.
2739 /* Get source file name and target directory id */
2740 if (!INF_GetData(&FilesContext
, &FileKeyName
, &FileKeyValue
))
2742 /* FIXME: Handle error! */
2743 DPRINT1("INF_GetData() failed\n");
2747 /* Get optional target file name */
2748 if (!INF_GetDataField(&FilesContext
, 2, &TargetFileName
))
2749 TargetFileName
= NULL
;
2751 DPRINT("FileKeyName: '%S' FileKeyValue: '%S'\n", FileKeyName
, FileKeyValue
);
2753 /* Lookup target directory */
2754 if (!SetupFindFirstLineW(InfFile
, L
"Directories", FileKeyValue
, &DirContext
))
2756 /* FIXME: Handle error! */
2757 DPRINT1("SetupFindFirstLine() failed\n");
2761 if (!INF_GetData(&DirContext
, NULL
, &DirKeyValue
))
2763 /* FIXME: Handle error! */
2764 DPRINT1("INF_GetData() failed\n");
2768 if (!SetupQueueCopy(SetupFileQueue
,
2770 SourceRootPath
.Buffer
,
2771 SourceRootDir
.Buffer
,
2776 /* FIXME: Handle error! */
2777 DPRINT1("SetupQueueCopy() failed\n");
2779 } while (SetupFindNextLine(&FilesContext
, &FilesContext
));
2786 AddSectionToCopyQueue(HINF InfFile
,
2788 PWCHAR SourceCabinet
,
2789 PCUNICODE_STRING DestinationPath
,
2792 INFCONTEXT FilesContext
;
2793 INFCONTEXT DirContext
;
2795 PWCHAR FileKeyValue
;
2797 PWCHAR TargetFileName
;
2798 WCHAR CompleteOrigFileName
[512];
2801 return AddSectionToCopyQueueCab(InfFile
, L
"SourceFiles", SourceCabinet
, DestinationPath
, Ir
);
2803 /* Search for the SectionName section */
2804 if (!SetupFindFirstLineW(InfFile
, SectionName
, NULL
, &FilesContext
))
2807 sprintf(Buffer
, MUIGetString(STRING_TXTSETUPFAILED
), SectionName
);
2808 PopupError(Buffer
, MUIGetString(STRING_REBOOTCOMPUTER
), Ir
, POPUP_WAIT_ENTER
);
2813 * Enumerate the files in the section
2814 * and add them to the file queue.
2818 /* Get source file name and target directory id */
2819 if (!INF_GetData(&FilesContext
, &FileKeyName
, &FileKeyValue
))
2821 /* FIXME: Handle error! */
2822 DPRINT1("INF_GetData() failed\n");
2826 /* Get target directory id */
2827 if (!INF_GetDataField(&FilesContext
, 13, &FileKeyValue
))
2829 /* FIXME: Handle error! */
2830 DPRINT1("INF_GetData() failed\n");
2834 /* Get optional target file name */
2835 if (!INF_GetDataField(&FilesContext
, 11, &TargetFileName
))
2836 TargetFileName
= NULL
;
2837 else if (!*TargetFileName
)
2838 TargetFileName
= NULL
;
2840 DPRINT("FileKeyName: '%S' FileKeyValue: '%S'\n", FileKeyName
, FileKeyValue
);
2842 /* Lookup target directory */
2843 if (!SetupFindFirstLineW(InfFile
, L
"Directories", FileKeyValue
, &DirContext
))
2845 /* FIXME: Handle error! */
2846 DPRINT1("SetupFindFirstLine() failed\n");
2850 if (!INF_GetData(&DirContext
, NULL
, &DirKeyValue
))
2852 /* FIXME: Handle error! */
2853 DPRINT1("INF_GetData() failed\n");
2857 wcscpy(CompleteOrigFileName
, SourceRootDir
.Buffer
);
2858 wcscat(CompleteOrigFileName
, L
"\\");
2859 wcscat(CompleteOrigFileName
, DirKeyValue
);
2861 if (!SetupQueueCopy(SetupFileQueue
,
2863 SourceRootPath
.Buffer
,
2864 CompleteOrigFileName
,
2869 /* FIXME: Handle error! */
2870 DPRINT1("SetupQueueCopy() failed\n");
2872 } while (SetupFindNextLine(&FilesContext
, &FilesContext
));
2879 PrepareCopyPageInfFile(HINF InfFile
,
2880 PWCHAR SourceCabinet
,
2883 WCHAR PathBuffer
[MAX_PATH
];
2884 INFCONTEXT DirContext
;
2885 PWCHAR AdditionalSectionName
= NULL
;
2890 /* Add common files */
2891 if (!AddSectionToCopyQueue(InfFile
, L
"SourceDisksFiles", SourceCabinet
, &DestinationPath
, Ir
))
2894 /* Add specific files depending of computer type */
2895 if (SourceCabinet
== NULL
)
2897 if (!ProcessComputerFiles(InfFile
, ComputerList
, &AdditionalSectionName
))
2900 if (AdditionalSectionName
)
2902 if (!AddSectionToCopyQueue(InfFile
, AdditionalSectionName
, SourceCabinet
, &DestinationPath
, Ir
))
2907 /* Create directories */
2911 * Install directories like '\reactos\test' are not handled yet.
2914 /* Get destination path */
2915 wcscpy(PathBuffer
, DestinationPath
.Buffer
);
2917 /* Remove trailing backslash */
2918 Length
= wcslen(PathBuffer
);
2919 if ((Length
> 0) && (PathBuffer
[Length
- 1] == '\\'))
2921 PathBuffer
[Length
- 1] = 0;
2924 /* Create the install directory */
2925 Status
= SetupCreateDirectory(PathBuffer
);
2926 if (!NT_SUCCESS(Status
) && Status
!= STATUS_OBJECT_NAME_COLLISION
)
2928 DPRINT("Creating directory '%S' failed: Status = 0x%08lx", PathBuffer
, Status
);
2929 MUIDisplayError(ERROR_CREATE_INSTALL_DIR
, Ir
, POPUP_WAIT_ENTER
);
2933 /* Search for the 'Directories' section */
2934 if (!SetupFindFirstLineW(InfFile
, L
"Directories", NULL
, &DirContext
))
2938 MUIDisplayError(ERROR_CABINET_SECTION
, Ir
, POPUP_WAIT_ENTER
);
2942 MUIDisplayError(ERROR_TXTSETUP_SECTION
, Ir
, POPUP_WAIT_ENTER
);
2948 /* Enumerate the directory values and create the subdirectories */
2951 if (!INF_GetData(&DirContext
, NULL
, &KeyValue
))
2957 if (KeyValue
[0] == L
'\\' && KeyValue
[1] != 0)
2959 DPRINT("Absolute Path: '%S'\n", KeyValue
);
2961 wcscpy(PathBuffer
, DestinationRootPath
.Buffer
);
2962 wcscat(PathBuffer
, KeyValue
);
2964 DPRINT("FullPath: '%S'\n", PathBuffer
);
2966 else if (KeyValue
[0] != L
'\\')
2968 DPRINT("RelativePath: '%S'\n", KeyValue
);
2969 wcscpy(PathBuffer
, DestinationPath
.Buffer
);
2970 wcscat(PathBuffer
, L
"\\");
2971 wcscat(PathBuffer
, KeyValue
);
2973 DPRINT("FullPath: '%S'\n", PathBuffer
);
2975 Status
= SetupCreateDirectory(PathBuffer
);
2976 if (!NT_SUCCESS(Status
) && Status
!= STATUS_OBJECT_NAME_COLLISION
)
2978 DPRINT("Creating directory '%S' failed: Status = 0x%08lx", PathBuffer
, Status
);
2979 MUIDisplayError(ERROR_CREATE_DIR
, Ir
, POPUP_WAIT_ENTER
);
2983 } while (SetupFindNextLine (&DirContext
, &DirContext
));
2990 PrepareCopyPage(PINPUT_RECORD Ir
)
2993 WCHAR PathBuffer
[MAX_PATH
];
2994 INFCONTEXT CabinetsContext
;
3000 MUIDisplayPage(PREPARE_COPY_PAGE
);
3002 /* Create the file queue */
3003 SetupFileQueue
= SetupOpenFileQueue();
3004 if (SetupFileQueue
== NULL
)
3006 MUIDisplayError(ERROR_COPY_QUEUE
, Ir
, POPUP_WAIT_ENTER
);
3010 if (!PrepareCopyPageInfFile(SetupInf
, NULL
, Ir
))
3015 /* Search for the 'Cabinets' section */
3016 if (!SetupFindFirstLineW(SetupInf
, L
"Cabinets", NULL
, &CabinetsContext
))
3018 return FILE_COPY_PAGE
;
3022 * Enumerate the directory values in the 'Cabinets'
3023 * section and parse their inf files.
3027 if (!INF_GetData(&CabinetsContext
, NULL
, &KeyValue
))
3030 wcscpy(PathBuffer
, SourcePath
.Buffer
);
3031 wcscat(PathBuffer
, L
"\\");
3032 wcscat(PathBuffer
, KeyValue
);
3035 CabinetInitialize();
3036 CabinetSetEventHandlers(NULL
, NULL
, NULL
);
3037 CabinetSetCabinetName(PathBuffer
);
3039 if (CabinetOpen() == CAB_STATUS_SUCCESS
)
3041 DPRINT("Cabinet %S\n", CabinetGetCabinetName());
3043 InfFileData
= CabinetGetCabinetReservedArea(&InfFileSize
);
3044 if (InfFileData
== NULL
)
3046 MUIDisplayError(ERROR_CABINET_SCRIPT
, Ir
, POPUP_WAIT_ENTER
);
3052 DPRINT("Cannot open cabinet: %S.\n", CabinetGetCabinetName());
3053 MUIDisplayError(ERROR_CABINET_MISSING
, Ir
, POPUP_WAIT_ENTER
);
3057 InfHandle
= INF_OpenBufferedFileA((CHAR
*) InfFileData
,
3064 if (InfHandle
== INVALID_HANDLE_VALUE
)
3066 MUIDisplayError(ERROR_INVALID_CABINET_INF
, Ir
, POPUP_WAIT_ENTER
);
3072 if (!PrepareCopyPageInfFile(InfHandle
, KeyValue
, Ir
))
3077 } while (SetupFindNextLine(&CabinetsContext
, &CabinetsContext
));
3079 return FILE_COPY_PAGE
;
3085 SetupUpdateMemoryInfo(IN PCOPYCONTEXT CopyContext
,
3088 SYSTEM_PERFORMANCE_INFORMATION PerfInfo
;
3090 /* Get the memory information from the system */
3091 NtQuerySystemInformation(SystemPerformanceInformation
,
3096 /* Check if this is initial setup */
3099 /* Set maximum limits to be total RAM pages */
3100 ProgressSetStepCount(CopyContext
->MemoryBars
[0], PerfInfo
.CommitLimit
);
3101 ProgressSetStepCount(CopyContext
->MemoryBars
[1], PerfInfo
.CommitLimit
);
3102 ProgressSetStepCount(CopyContext
->MemoryBars
[2], PerfInfo
.CommitLimit
);
3105 /* Set current values */
3106 ProgressSetStep(CopyContext
->MemoryBars
[0], PerfInfo
.PagedPoolPages
+ PerfInfo
.NonPagedPoolPages
);
3107 ProgressSetStep(CopyContext
->MemoryBars
[1], PerfInfo
.ResidentSystemCachePage
);
3108 ProgressSetStep(CopyContext
->MemoryBars
[2], PerfInfo
.AvailablePages
);
3114 FileCopyCallback(PVOID Context
,
3119 PCOPYCONTEXT CopyContext
;
3121 CopyContext
= (PCOPYCONTEXT
)Context
;
3123 switch (Notification
)
3125 case SPFILENOTIFY_STARTSUBQUEUE
:
3126 CopyContext
->TotalOperations
= (ULONG
)Param2
;
3127 ProgressSetStepCount(CopyContext
->ProgressBar
,
3128 CopyContext
->TotalOperations
);
3129 SetupUpdateMemoryInfo(CopyContext
, TRUE
);
3132 case SPFILENOTIFY_STARTCOPY
:
3133 /* Display copy message */
3134 CONSOLE_SetStatusText(MUIGetString(STRING_COPYING
), (PWSTR
)Param1
);
3135 SetupUpdateMemoryInfo(CopyContext
, FALSE
);
3138 case SPFILENOTIFY_ENDCOPY
:
3139 CopyContext
->CompletedOperations
++;
3140 ProgressNextStep(CopyContext
->ProgressBar
);
3141 SetupUpdateMemoryInfo(CopyContext
, FALSE
);
3151 FileCopyPage(PINPUT_RECORD Ir
)
3153 COPYCONTEXT CopyContext
;
3154 unsigned int mem_bar_width
;
3156 MUIDisplayPage(FILE_COPY_PAGE
);
3158 /* Create context for the copy process */
3159 CopyContext
.DestinationRootPath
= DestinationRootPath
.Buffer
;
3160 CopyContext
.InstallPath
= InstallPath
.Buffer
;
3161 CopyContext
.TotalOperations
= 0;
3162 CopyContext
.CompletedOperations
= 0;
3164 /* Create the progress bar as well */
3165 CopyContext
.ProgressBar
= CreateProgressBar(13,
3172 MUIGetString(STRING_SETUPCOPYINGFILES
));
3174 // fit memory bars to screen width, distribute them uniform
3175 mem_bar_width
= (xScreen
- 26) / 5;
3176 mem_bar_width
-= mem_bar_width
% 2; // make even
3177 /* ATTENTION: The following progress bars are debug stuff, which should not be translated!! */
3178 /* Create the paged pool progress bar */
3179 CopyContext
.MemoryBars
[0] = CreateProgressBar(13,
3188 /* Create the non paged pool progress bar */
3189 CopyContext
.MemoryBars
[1] = CreateProgressBar((xScreen
/ 2)- (mem_bar_width
/ 2),
3191 (xScreen
/ 2) + (mem_bar_width
/ 2),
3193 (xScreen
/ 2)- (mem_bar_width
/ 2),
3198 /* Create the global memory progress bar */
3199 CopyContext
.MemoryBars
[2] = CreateProgressBar(xScreen
- 13 - mem_bar_width
,
3203 xScreen
- 13 - mem_bar_width
,
3208 /* Do the file copying */
3209 SetupCommitFileQueueW(NULL
,
3214 /* If we get here, we're done, so cleanup the queue and progress bar */
3215 SetupCloseFileQueue(SetupFileQueue
);
3216 DestroyProgressBar(CopyContext
.ProgressBar
);
3217 DestroyProgressBar(CopyContext
.MemoryBars
[0]);
3218 DestroyProgressBar(CopyContext
.MemoryBars
[1]);
3219 DestroyProgressBar(CopyContext
.MemoryBars
[2]);
3221 /* Go display the next page */
3222 return REGISTRY_PAGE
;
3227 RegistryPage(PINPUT_RECORD Ir
)
3229 INFCONTEXT InfContext
;
3236 MUIDisplayPage(REGISTRY_PAGE
);
3238 if (RepairUpdateFlag
)
3240 return SUCCESS_PAGE
;
3243 if (!SetInstallPathValue(&DestinationPath
))
3245 DPRINT("SetInstallPathValue() failed\n");
3246 MUIDisplayError(ERROR_INITIALIZE_REGISTRY
, Ir
, POPUP_WAIT_ENTER
);
3250 /* Create the default hives */
3252 Status
= NtInitializeRegistry(CM_BOOT_FLAG_SETUP
);
3253 if (!NT_SUCCESS(Status
))
3255 DPRINT("NtInitializeRegistry() failed (Status %lx)\n", Status
);
3256 MUIDisplayError(ERROR_CREATE_HIVE
, Ir
, POPUP_WAIT_ENTER
);
3260 RegInitializeRegistry();
3263 /* Update registry */
3264 CONSOLE_SetStatusText(MUIGetString(STRING_REGHIVEUPDATE
));
3266 if (!SetupFindFirstLineW(SetupInf
, L
"HiveInfs.Install", NULL
, &InfContext
))
3268 DPRINT1("SetupFindFirstLine() failed\n");
3269 MUIDisplayError(ERROR_FIND_REGISTRY
, Ir
, POPUP_WAIT_ENTER
);
3275 INF_GetDataField (&InfContext
, 0, &Action
);
3276 INF_GetDataField (&InfContext
, 1, &File
);
3277 INF_GetDataField (&InfContext
, 2, &Section
);
3279 DPRINT("Action: %S File: %S Section %S\n", Action
, File
, Section
);
3284 if (!_wcsicmp (Action
, L
"AddReg"))
3288 else if (!_wcsicmp (Action
, L
"DelReg"))
3297 CONSOLE_SetStatusText(MUIGetString(STRING_IMPORTFILE
), File
);
3299 if (!ImportRegistryFile(File
, Section
, LanguageId
, Delete
))
3301 DPRINT("Importing %S failed\n", File
);
3303 MUIDisplayError(ERROR_IMPORT_HIVE
, Ir
, POPUP_WAIT_ENTER
);
3306 } while (SetupFindNextLine(&InfContext
, &InfContext
));
3308 /* Update display registry settings */
3309 CONSOLE_SetStatusText(MUIGetString(STRING_DISPLAYETTINGSUPDATE
));
3310 if (!ProcessDisplayRegistry(SetupInf
, DisplayList
))
3312 MUIDisplayError(ERROR_UPDATE_DISPLAY_SETTINGS
, Ir
, POPUP_WAIT_ENTER
);
3316 /* Set the locale */
3317 CONSOLE_SetStatusText(MUIGetString(STRING_LOCALESETTINGSUPDATE
));
3318 if (!ProcessLocaleRegistry(LanguageList
))
3320 MUIDisplayError(ERROR_UPDATE_LOCALESETTINGS
, Ir
, POPUP_WAIT_ENTER
);
3324 /* Add keyboard layouts */
3325 CONSOLE_SetStatusText(MUIGetString(STRING_ADDKBLAYOUTS
));
3326 if (!AddKeyboardLayouts())
3328 MUIDisplayError(ERROR_ADDING_KBLAYOUTS
, Ir
, POPUP_WAIT_ENTER
);
3334 if (!SetGeoID(MUIGetGeoID()))
3336 MUIDisplayError(ERROR_UPDATE_GEOID
, Ir
, POPUP_WAIT_ENTER
);
3340 if (!IsUnattendedSetup
)
3342 /* Update keyboard layout settings */
3343 CONSOLE_SetStatusText(MUIGetString(STRING_KEYBOARDSETTINGSUPDATE
));
3344 if (!ProcessKeyboardLayoutRegistry(LayoutList
))
3346 MUIDisplayError(ERROR_UPDATE_KBSETTINGS
, Ir
, POPUP_WAIT_ENTER
);
3351 /* Add codepage information to registry */
3352 CONSOLE_SetStatusText(MUIGetString(STRING_CODEPAGEINFOUPDATE
));
3355 MUIDisplayError(ERROR_ADDING_CODEPAGE
, Ir
, POPUP_WAIT_ENTER
);
3359 /* Update the mounted devices list */
3360 SetMountedDeviceValues(PartitionList
);
3362 CONSOLE_SetStatusText(MUIGetString(STRING_DONE
));
3364 return BOOT_LOADER_PAGE
;
3369 BootLoaderPage(PINPUT_RECORD Ir
)
3371 UCHAR PartitionType
;
3372 BOOLEAN InstallOnFloppy
;
3375 CONSOLE_SetStatusText(MUIGetString(STRING_PLEASEWAIT
));
3377 PartitionType
= PartitionList
->ActiveBootPartition
->
3378 PartInfo
[PartitionList
->ActiveBootPartitionNumber
].PartitionType
;
3380 if (IsUnattendedSetup
)
3382 if (UnattendMBRInstallType
== 0) /* skip MBR installation */
3384 return SUCCESS_PAGE
;
3386 else if (UnattendMBRInstallType
== 1) /* install on floppy */
3388 return BOOT_LOADER_FLOPPY_PAGE
;
3392 if (PartitionType
== PARTITION_ENTRY_UNUSED
)
3394 DPRINT("Error: active partition invalid (unused)\n");
3395 InstallOnFloppy
= TRUE
;
3397 else if (PartitionType
== 0x0A)
3399 /* OS/2 boot manager partition */
3400 DPRINT("Found OS/2 boot manager partition\n");
3401 InstallOnFloppy
= TRUE
;
3403 else if (PartitionType
== 0x83)
3405 /* Linux ext2 partition */
3406 DPRINT("Found Linux ext2 partition\n");
3407 InstallOnFloppy
= TRUE
;
3409 else if (PartitionType
== PARTITION_IFS
)
3411 /* NTFS partition */
3412 DPRINT("Found NTFS partition\n");
3413 InstallOnFloppy
= TRUE
;
3415 else if ((PartitionType
== PARTITION_FAT_12
) ||
3416 (PartitionType
== PARTITION_FAT_16
) ||
3417 (PartitionType
== PARTITION_HUGE
) ||
3418 (PartitionType
== PARTITION_XINT13
) ||
3419 (PartitionType
== PARTITION_FAT32
) ||
3420 (PartitionType
== PARTITION_FAT32_XINT13
))
3422 DPRINT("Found FAT partition\n");
3423 InstallOnFloppy
= FALSE
;
3427 /* Unknown partition */
3428 DPRINT("Unknown partition found\n");
3429 InstallOnFloppy
= TRUE
;
3432 if (InstallOnFloppy
== TRUE
)
3434 return BOOT_LOADER_FLOPPY_PAGE
;
3437 /* Unattended install on hdd? */
3438 if (IsUnattendedSetup
&& UnattendMBRInstallType
== 2)
3440 return BOOT_LOADER_HARDDISK_MBR_PAGE
;
3443 MUIDisplayPage(BOOT_LOADER_PAGE
);
3444 CONSOLE_InvertTextXY(8, Line
, 60, 1);
3448 CONSOLE_ConInKey(Ir
);
3450 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
3451 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
)) /* DOWN */
3453 CONSOLE_NormalTextXY(8, Line
, 60, 1);
3462 CONSOLE_InvertTextXY(8, Line
, 60, 1);
3464 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
3465 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_UP
)) /* UP */
3467 CONSOLE_NormalTextXY(8, Line
, 60, 1);
3476 CONSOLE_InvertTextXY(8, Line
, 60, 1);
3478 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
3479 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
3481 if (ConfirmQuit(Ir
) == TRUE
)
3486 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
3490 return BOOT_LOADER_HARDDISK_MBR_PAGE
;
3492 else if (Line
== 13)
3494 return BOOT_LOADER_HARDDISK_VBR_PAGE
;
3496 else if (Line
== 14)
3498 return BOOT_LOADER_FLOPPY_PAGE
;
3500 else if (Line
== 15)
3502 return SUCCESS_PAGE
;
3505 return BOOT_LOADER_PAGE
;
3509 return BOOT_LOADER_PAGE
;
3514 BootLoaderFloppyPage(PINPUT_RECORD Ir
)
3518 MUIDisplayPage(BOOT_LOADER_FLOPPY_PAGE
);
3520 // SetStatusText(" Please wait...");
3524 CONSOLE_ConInKey(Ir
);
3526 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
3527 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
3529 if (ConfirmQuit(Ir
) == TRUE
)
3534 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
3536 if (DoesFileExist(L
"\\Device\\Floppy0", L
"\\") == FALSE
)
3538 MUIDisplayError(ERROR_NO_FLOPPY
, Ir
, POPUP_WAIT_ENTER
);
3539 return BOOT_LOADER_FLOPPY_PAGE
;
3542 Status
= InstallFatBootcodeToFloppy(&SourceRootPath
, &DestinationArcPath
);
3543 if (!NT_SUCCESS(Status
))
3545 /* Print error message */
3546 return BOOT_LOADER_FLOPPY_PAGE
;
3549 return SUCCESS_PAGE
;
3553 return BOOT_LOADER_FLOPPY_PAGE
;
3557 BootLoaderHarddiskVbrPage(PINPUT_RECORD Ir
)
3559 UCHAR PartitionType
;
3562 PartitionType
= PartitionList
->ActiveBootPartition
->
3563 PartInfo
[PartitionList
->ActiveBootPartitionNumber
].PartitionType
;
3565 Status
= InstallVBRToPartition(&SystemRootPath
,
3567 &DestinationArcPath
,
3569 if (!NT_SUCCESS(Status
))
3571 MUIDisplayError(ERROR_WRITE_BOOT
, Ir
, POPUP_WAIT_ENTER
);
3575 return SUCCESS_PAGE
;
3579 BootLoaderHarddiskMbrPage(PINPUT_RECORD Ir
)
3581 UCHAR PartitionType
;
3583 WCHAR DestinationDevicePathBuffer
[MAX_PATH
];
3584 WCHAR SourceMbrPathBuffer
[MAX_PATH
];
3586 /* Step 1: Write the VBR */
3587 PartitionType
= PartitionList
->ActiveBootPartition
->
3588 PartInfo
[PartitionList
->ActiveBootPartitionNumber
].PartitionType
;
3590 Status
= InstallVBRToPartition(&SystemRootPath
,
3592 &DestinationArcPath
,
3594 if (!NT_SUCCESS(Status
))
3596 MUIDisplayError(ERROR_WRITE_BOOT
, Ir
, POPUP_WAIT_ENTER
);
3600 /* Step 2: Write the MBR */
3601 swprintf(DestinationDevicePathBuffer
,
3602 L
"\\Device\\Harddisk%d\\Partition0",
3603 PartitionList
->ActiveBootDisk
->DiskNumber
);
3605 wcscpy(SourceMbrPathBuffer
, SourceRootPath
.Buffer
);
3606 wcscat(SourceMbrPathBuffer
, L
"\\loader\\dosmbr.bin");
3608 DPRINT("Install MBR bootcode: %S ==> %S\n",
3609 SourceMbrPathBuffer
, DestinationDevicePathBuffer
);
3611 Status
= InstallMbrBootCodeToDisk(SourceMbrPathBuffer
,
3612 DestinationDevicePathBuffer
);
3613 if (!NT_SUCCESS (Status
))
3615 DPRINT1("InstallMbrBootCodeToDisk() failed (Status %lx)\n",
3617 MUIDisplayError(ERROR_INSTALL_BOOTCODE
, Ir
, POPUP_WAIT_ENTER
);
3621 return SUCCESS_PAGE
;
3626 QuitPage(PINPUT_RECORD Ir
)
3628 MUIDisplayPage(QUIT_PAGE
);
3630 /* Destroy partition list */
3631 if (PartitionList
!= NULL
)
3633 DestroyPartitionList (PartitionList
);
3634 PartitionList
= NULL
;
3637 /* Destroy filesystem list */
3638 if (FileSystemList
!= NULL
)
3640 DestroyFileSystemList (FileSystemList
);
3641 FileSystemList
= NULL
;
3644 /* Destroy computer settings list */
3645 if (ComputerList
!= NULL
)
3647 DestroyGenericList(ComputerList
, TRUE
);
3648 ComputerList
= NULL
;
3651 /* Destroy display settings list */
3652 if (DisplayList
!= NULL
)
3654 DestroyGenericList(DisplayList
, TRUE
);
3658 /* Destroy keyboard settings list */
3659 if (KeyboardList
!= NULL
)
3661 DestroyGenericList(KeyboardList
, TRUE
);
3662 KeyboardList
= NULL
;
3665 /* Destroy keyboard layout list */
3666 if (LayoutList
!= NULL
)
3668 DestroyGenericList(LayoutList
, TRUE
);
3672 if (LanguageList
!= NULL
)
3674 DestroyGenericList(LanguageList
, FALSE
);
3675 LanguageList
= NULL
;
3678 CONSOLE_SetStatusText(MUIGetString(STRING_REBOOTCOMPUTER2
));
3682 CONSOLE_ConInKey(Ir
);
3684 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
3693 SuccessPage(PINPUT_RECORD Ir
)
3695 MUIDisplayPage(SUCCESS_PAGE
);
3697 if (IsUnattendedSetup
)
3704 CONSOLE_ConInKey(Ir
);
3706 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
3715 FlushPage(PINPUT_RECORD Ir
)
3717 MUIDisplayPage(FLUSH_PAGE
);
3723 PnpEventThread(IN LPVOID lpParameter
);
3733 NtQuerySystemTime(&Time
);
3735 Status
= RtlCreateUserThread(NtCurrentProcess(),
3745 if (!NT_SUCCESS(Status
))
3746 hPnpThread
= INVALID_HANDLE_VALUE
;
3748 if (!CONSOLE_Init())
3750 PrintString(MUIGetString(STRING_CONSOLEFAIL1
));
3751 PrintString(MUIGetString(STRING_CONSOLEFAIL2
));
3752 PrintString(MUIGetString(STRING_CONSOLEFAIL3
));
3754 /* Raise a hard error (crash the system/BSOD) */
3755 NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED
,
3759 /* Initialize global unicode strings */
3760 RtlInitUnicodeString(&SourcePath
, NULL
);
3761 RtlInitUnicodeString(&SourceRootPath
, NULL
);
3762 RtlInitUnicodeString(&SourceRootDir
, NULL
);
3763 RtlInitUnicodeString(&InstallPath
, NULL
);
3764 RtlInitUnicodeString(&DestinationPath
, NULL
);
3765 RtlInitUnicodeString(&DestinationArcPath
, NULL
);
3766 RtlInitUnicodeString(&DestinationRootPath
, NULL
);
3767 RtlInitUnicodeString(&SystemRootPath
, NULL
);
3769 /* Hide the cursor */
3770 CONSOLE_SetCursorType(TRUE
, FALSE
);
3773 while (Page
!= REBOOT_PAGE
)
3775 CONSOLE_ClearScreen();
3778 //CONSOLE_SetUnderlinedTextXY(4, 3, " ReactOS " KERNEL_VERSION_STR " Setup ");
3785 Page
= SetupStartPage(&Ir
);
3790 Page
= LanguagePage(&Ir
);
3795 Page
= LicensePage(&Ir
);
3800 Page
= IntroPage(&Ir
);
3804 case INSTALL_INTRO_PAGE
:
3805 Page
= InstallIntroPage(&Ir
);
3809 case SCSI_CONTROLLER_PAGE
:
3810 Page
= ScsiControllerPage(&Ir
);
3815 case OEM_DRIVER_PAGE
:
3816 Page
= OemDriverPage(&Ir
);
3820 case DEVICE_SETTINGS_PAGE
:
3821 Page
= DeviceSettingsPage(&Ir
);
3824 case COMPUTER_SETTINGS_PAGE
:
3825 Page
= ComputerSettingsPage(&Ir
);
3828 case DISPLAY_SETTINGS_PAGE
:
3829 Page
= DisplaySettingsPage(&Ir
);
3832 case KEYBOARD_SETTINGS_PAGE
:
3833 Page
= KeyboardSettingsPage(&Ir
);
3836 case LAYOUT_SETTINGS_PAGE
:
3837 Page
= LayoutSettingsPage(&Ir
);
3840 case SELECT_PARTITION_PAGE
:
3841 Page
= SelectPartitionPage(&Ir
);
3844 case CREATE_PARTITION_PAGE
:
3845 Page
= CreatePartitionPage(&Ir
);
3848 case DELETE_PARTITION_PAGE
:
3849 Page
= DeletePartitionPage(&Ir
);
3852 case SELECT_FILE_SYSTEM_PAGE
:
3853 Page
= SelectFileSystemPage(&Ir
);
3856 case FORMAT_PARTITION_PAGE
:
3857 Page
= (PAGE_NUMBER
) FormatPartitionPage(&Ir
);
3860 case CHECK_FILE_SYSTEM_PAGE
:
3861 Page
= (PAGE_NUMBER
) CheckFileSystemPage(&Ir
);
3864 case INSTALL_DIRECTORY_PAGE
:
3865 Page
= InstallDirectoryPage(&Ir
);
3868 case PREPARE_COPY_PAGE
:
3869 Page
= PrepareCopyPage(&Ir
);
3872 case FILE_COPY_PAGE
:
3873 Page
= FileCopyPage(&Ir
);
3877 Page
= RegistryPage(&Ir
);
3880 case BOOT_LOADER_PAGE
:
3881 Page
= BootLoaderPage(&Ir
);
3884 case BOOT_LOADER_FLOPPY_PAGE
:
3885 Page
= BootLoaderFloppyPage(&Ir
);
3888 case BOOT_LOADER_HARDDISK_MBR_PAGE
:
3889 Page
= BootLoaderHarddiskMbrPage(&Ir
);
3892 case BOOT_LOADER_HARDDISK_VBR_PAGE
:
3893 Page
= BootLoaderHarddiskVbrPage(&Ir
);
3897 case REPAIR_INTRO_PAGE
:
3898 Page
= RepairIntroPage(&Ir
);
3902 Page
= SuccessPage(&Ir
);
3906 Page
= FlushPage(&Ir
);
3910 Page
= QuitPage(&Ir
);
3920 /* Avoid bugcheck */
3921 Time
.QuadPart
+= 50000000;
3922 NtDelayExecution(FALSE
, &Time
);
3925 NtShutdownSystem(ShutdownReboot
);
3926 NtTerminateProcess(NtCurrentProcess(), 0);
3933 NtProcessStartup(PPEB Peb
)
3935 RtlNormalizeProcessParams(Peb
->ProcessParameters
);
3937 ProcessHeap
= Peb
->ProcessHeap
;
3938 InfSetHeap(ProcessHeap
);
3941 #endif /* __REACTOS__ */