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
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, 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)
28 #include <ddk/ntddk.h>
29 #include <ntdll/rtl.h>
31 #include <ntos/minmax.h>
32 #include <reactos/resource.h>
39 #include "filequeue.h"
55 typedef enum _PAGE_NUMBER
62 COMPUTER_SETTINGS_PAGE
,
63 DISPLAY_SETTINGS_PAGE
,
64 KEYBOARD_SETTINGS_PAGE
,
66 POINTER_SETTINGS_PAGE
,
68 SELECT_PARTITION_PAGE
,
69 CREATE_PARTITION_PAGE
,
70 DELETE_PARTITION_PAGE
,
72 SELECT_FILE_SYSTEM_PAGE
,
73 FORMAT_PARTITION_PAGE
,
74 CHECK_FILE_SYSTEM_PAGE
,
77 INSTALL_DIRECTORY_PAGE
,
89 REBOOT_PAGE
, /* virtual page */
90 } PAGE_NUMBER
, *PPAGE_NUMBER
;
92 typedef struct _COPYCONTEXT
94 ULONG TotalOperations
;
95 ULONG CompletedOperations
;
96 PPROGRESSBAR ProgressBar
;
97 } COPYCONTEXT
, *PCOPYCONTEXT
;
100 /* GLOBALS ******************************************************************/
103 UNICODE_STRING SourceRootPath
;
104 BOOLEAN IsUnattendedSetup
;
105 LONG UnattendDestinationDiskNumber
;
106 LONG UnattendDestinationPartitionNumber
;
107 WCHAR UnattendInstallationDirectory
[MAX_PATH
];
109 /* LOCALS *******************************************************************/
111 static PPARTLIST PartitionList
= NULL
;
113 static PFILE_SYSTEM_LIST FileSystemList
= NULL
;
116 static UNICODE_STRING SourcePath
;
118 static UNICODE_STRING InstallPath
;
120 /* Path to the install directory */
121 static UNICODE_STRING DestinationPath
;
122 static UNICODE_STRING DestinationArcPath
;
123 static UNICODE_STRING DestinationRootPath
;
125 /* Path to the active partition (boot manager) */
126 static UNICODE_STRING SystemRootPath
;
128 static HINF SetupInf
;
130 static HSPFILEQ SetupFileQueue
= NULL
;
132 static BOOLEAN WarnLinuxPartitions
= TRUE
;
134 static PGENERIC_LIST ComputerList
= NULL
;
135 static PGENERIC_LIST DisplayList
= NULL
;
136 static PGENERIC_LIST KeyboardList
= NULL
;
137 static PGENERIC_LIST LayoutList
= NULL
;
138 static PGENERIC_LIST PointerList
= NULL
;
141 /* FUNCTIONS ****************************************************************/
144 PrintString(char* fmt
,...)
148 UNICODE_STRING UnicodeString
;
149 ANSI_STRING AnsiString
;
152 vsprintf(buffer
, fmt
, ap
);
155 RtlInitAnsiString(&AnsiString
, buffer
);
156 RtlAnsiStringToUnicodeString(&UnicodeString
,
159 NtDisplayString(&UnicodeString
);
160 RtlFreeUnicodeString(&UnicodeString
);
165 PopupError(PCHAR Text
,
183 /* Count text lines and longest line */
189 p
= strchr(pnext
, '\n');
192 Length
= strlen(pnext
);
197 Length
= (ULONG
)(p
- pnext
);
202 if (Length
> MaxLength
)
205 if (LastLine
== TRUE
)
211 /* Check length of status line */
214 Length
= strlen(Status
);
215 if (Length
> MaxLength
)
219 GetScreenSize(&xScreen
, &yScreen
);
221 Width
= MaxLength
+ 4;
226 yTop
= (yScreen
- Height
) / 2;
227 xLeft
= (xScreen
- Width
) / 2;
230 /* Set screen attributes */
232 for (coPos
.Y
= yTop
; coPos
.Y
< yTop
+ Height
; coPos
.Y
++)
234 FillConsoleOutputAttribute(0x74,
240 /* draw upper left corner */
243 FillConsoleOutputCharacter(0xDA, // '+',
248 /* draw upper edge */
251 FillConsoleOutputCharacter(0xC4, // '-',
256 /* draw upper right corner */
257 coPos
.X
= xLeft
+ Width
- 1;
259 FillConsoleOutputCharacter(0xBF, // '+',
264 /* Draw right edge, inner space and left edge */
265 for (coPos
.Y
= yTop
+ 1; coPos
.Y
< yTop
+ Height
- 1; coPos
.Y
++)
268 FillConsoleOutputCharacter(0xB3, // '|',
274 FillConsoleOutputCharacter(' ',
279 coPos
.X
= xLeft
+ Width
- 1;
280 FillConsoleOutputCharacter(0xB3, // '|',
286 /* draw lower left corner */
288 coPos
.Y
= yTop
+ Height
- 1;
289 FillConsoleOutputCharacter(0xC0, // '+',
294 /* draw lower edge */
296 coPos
.Y
= yTop
+ Height
- 1;
297 FillConsoleOutputCharacter(0xC4, // '-',
302 /* draw lower right corner */
303 coPos
.X
= xLeft
+ Width
- 1;
304 coPos
.Y
= yTop
+ Height
- 1;
305 FillConsoleOutputCharacter(0xD9, // '+',
310 /* Print message text */
315 p
= strchr(pnext
, '\n');
318 Length
= strlen(pnext
);
323 Length
= (ULONG
)(p
- pnext
);
330 WriteConsoleOutputCharacters(pnext
,
335 if (LastLine
== TRUE
)
342 /* Print separator line and status text */
345 coPos
.Y
= yTop
+ Height
- 3;
347 FillConsoleOutputCharacter(0xC3, // '+',
353 FillConsoleOutputCharacter(0xC4, // '-',
358 coPos
.X
= xLeft
+ Width
- 1;
359 FillConsoleOutputCharacter(0xB4, // '+',
366 WriteConsoleOutputCharacters(Status
,
367 min(strlen(Status
), Width
- 4),
377 * FALSE: Don't quit setup.
380 ConfirmQuit(PINPUT_RECORD Ir
)
384 PopupError("ReactOS is not completely installed on your\n"
385 "computer. If you quit Setup now, you will need to\n"
386 "run Setup again to install ReactOS.\n"
388 " \x07 Press ENTER to continue Setup.\n"
389 " \x07 Press F3 to quit Setup.",
390 "F3= Quit ENTER = Continue");
396 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
397 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
402 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
414 CheckUnattendedSetup(VOID
)
416 WCHAR UnattendInfPath
[MAX_PATH
];
417 UNICODE_STRING FileName
;
425 if (DoesFileExist(SourcePath
.Buffer
, L
"unattend.inf") == FALSE
)
427 DPRINT("Does not exist: %S\\%S\n", SourcePath
.Buffer
, L
"unattend.inf");
428 IsUnattendedSetup
= FALSE
;
432 wcscpy(UnattendInfPath
, SourcePath
.Buffer
);
433 wcscat(UnattendInfPath
, L
"\\unattend.inf");
435 RtlInitUnicodeString(&FileName
,
438 /* Load txtsetup.sif from install media. */
440 Status
= InfOpenFile(&UnattendInf
,
443 if (!NT_SUCCESS(Status
))
445 DPRINT("InfOpenFile() failed with status 0x%x\n", Status
);
449 /* Open 'Unattend' section */
450 if (!InfFindFirstLine(UnattendInf
, L
"Unattend", L
"Signature", &Context
))
452 DPRINT("InfFindFirstLine() failed for section 'Unattend'\n");
453 InfCloseFile(UnattendInf
);
457 /* Get pointer 'Signature' key */
458 if (!InfGetData(&Context
, NULL
, &Value
))
460 DPRINT("InfGetData() failed for key 'Signature'\n");
461 InfCloseFile(UnattendInf
);
465 /* Check 'Signature' string */
466 if (_wcsicmp(Value
, L
"$ReactOS$") != 0)
468 DPRINT("Signature not $ReactOS$\n");
469 InfCloseFile(UnattendInf
);
473 /* Search for 'DestinationDiskNumber' in the 'Unattend' section */
474 if (!InfFindFirstLine(UnattendInf
, L
"Unattend", L
"DestinationDiskNumber", &Context
))
476 DPRINT("InfFindFirstLine() failed for key 'DestinationDiskNumber'\n");
477 InfCloseFile(UnattendInf
);
480 if (!InfGetIntField(&Context
, 0, &IntValue
))
482 DPRINT("InfGetIntField() failed for key 'DestinationDiskNumber'\n");
483 InfCloseFile(UnattendInf
);
486 UnattendDestinationDiskNumber
= IntValue
;
488 /* Search for 'DestinationPartitionNumber' in the 'Unattend' section */
489 if (!InfFindFirstLine(UnattendInf
, L
"Unattend", L
"DestinationPartitionNumber", &Context
))
491 DPRINT("InfFindFirstLine() failed for key 'DestinationPartitionNumber'\n");
492 InfCloseFile(UnattendInf
);
495 if (!InfGetIntField(&Context
, 0, &IntValue
))
497 DPRINT("InfGetIntField() failed for key 'DestinationPartitionNumber'\n");
498 InfCloseFile(UnattendInf
);
501 UnattendDestinationPartitionNumber
= IntValue
;
503 /* Search for 'DestinationPartitionNumber' in the 'Unattend' section */
504 if (!InfFindFirstLine(UnattendInf
, L
"Unattend", L
"DestinationPartitionNumber", &Context
))
506 DPRINT("InfFindFirstLine() failed for key 'DestinationPartitionNumber'\n");
507 InfCloseFile(UnattendInf
);
511 /* Get pointer 'InstallationDirectory' key */
512 if (!InfGetData(&Context
, NULL
, &Value
))
514 DPRINT("InfGetData() failed for key 'InstallationDirectory'\n");
515 InfCloseFile(UnattendInf
);
518 wcscpy(UnattendInstallationDirectory
, Value
);
520 InfCloseFile(UnattendInf
);
522 IsUnattendedSetup
= TRUE
;
524 DPRINT("Running unattended setup\n");
531 * Number of the next page.
534 StartPage(PINPUT_RECORD Ir
)
536 SYSTEM_DEVICE_INFORMATION Sdi
;
538 WCHAR FileNameBuffer
[MAX_PATH
];
539 UNICODE_STRING FileName
;
545 SetStatusText(" Please wait...");
548 /* Check whether a harddisk is available */
549 Status
= NtQuerySystemInformation (SystemDeviceInformation
,
551 sizeof(SYSTEM_DEVICE_INFORMATION
),
553 if (!NT_SUCCESS (Status
))
555 PrintTextXY(6, 15, "NtQuerySystemInformation() failed (Status 0x%08lx)", Status
);
556 PopupError("Setup could not retrieve system drive information.\n",
557 "ENTER = Reboot computer");
562 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
569 if (Sdi
.NumberOfDisks
== 0)
571 PopupError("Setup could not find a harddisk.\n",
572 "ENTER = Reboot computer");
577 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
584 /* Get the source path and source root path */
585 Status
= GetSourcePaths(&SourcePath
,
587 if (!NT_SUCCESS(Status
))
589 PrintTextXY(6, 15, "GetSourcePath() failed (Status 0x%08lx)", Status
);
590 PopupError("Setup could not find its source drive.\n",
591 "ENTER = Reboot computer");
596 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
605 PrintTextXY(6, 15, "SourcePath: '%wZ'", &SourcePath
);
606 PrintTextXY(6, 16, "SourceRootPath: '%wZ'", &SourceRootPath
);
610 /* Load txtsetup.sif from install media. */
611 wcscpy(FileNameBuffer
, SourceRootPath
.Buffer
);
612 wcscat(FileNameBuffer
, L
"\\reactos\\txtsetup.sif");
613 RtlInitUnicodeString(&FileName
,
616 Status
= InfOpenFile(&SetupInf
,
619 if (!NT_SUCCESS(Status
))
621 PopupError("Setup failed to load the file TXTSETUP.SIF.\n",
622 "ENTER = Reboot computer");
628 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
635 /* Open 'Version' section */
636 if (!InfFindFirstLine (SetupInf
, L
"Version", L
"Signature", &Context
))
638 PopupError("Setup found a corrupt TXTSETUP.SIF.\n",
639 "ENTER = Reboot computer");
645 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
653 /* Get pointer 'Signature' key */
654 if (!InfGetData (&Context
, NULL
, &Value
))
656 PopupError("Setup found a corrupt TXTSETUP.SIF.\n",
657 "ENTER = Reboot computer");
663 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
670 /* Check 'Signature' string */
671 if (_wcsicmp(Value
, L
"$ReactOS$") != 0)
673 PopupError("Setup found an invalid signature in TXTSETUP.SIF.\n",
674 "ENTER = Reboot computer");
680 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
687 CheckUnattendedSetup();
699 IntroPage(PINPUT_RECORD Ir
)
701 SetHighlightedTextXY(6, 8, "Welcome to ReactOS Setup");
703 SetTextXY(6, 11, "This part of the setup copies the ReactOS Operating System to your");
704 SetTextXY(6, 12, "computer and prepares the second part of the setup.");
706 SetTextXY(8, 15, "\x07 Press ENTER to install ReactOS.");
707 SetTextXY(8, 17, "\x07 Press E to start the emergency console.");
708 SetTextXY(8, 19, "\x07 Press R to repair ReactOS.");
709 SetTextXY(8, 21, "\x07 Press F3 to quit without installing ReactOS.");
711 SetStatusText(" ENTER = Continue F3 = Quit");
713 if (IsUnattendedSetup
)
715 return INSTALL_INTRO_PAGE
;
722 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
723 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
725 if (ConfirmQuit(Ir
) == TRUE
)
729 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
731 return INSTALL_INTRO_PAGE
;
733 else if (toupper(Ir
->Event
.KeyEvent
.uChar
.AsciiChar
) == 'E') /* E */
735 return EMERGENCY_INTRO_PAGE
;
737 else if (toupper(Ir
->Event
.KeyEvent
.uChar
.AsciiChar
) == 'R') /* R */
739 return REPAIR_INTRO_PAGE
;
748 EmergencyIntroPage(PINPUT_RECORD Ir
)
750 SetTextXY(6, 8, "ReactOS Setup is in an early development phase. It does not yet");
751 SetTextXY(6, 9, "support all the functions of a fully usable setup application.");
753 SetTextXY(6, 12, "The emergency console is not implemented yet.");
755 SetTextXY(8, 15, "\x07 Press ESC to return to the main page.");
757 SetTextXY(8, 17, "\x07 Press ENTER to reboot your computer.");
759 SetStatusText(" ESC = Main page ENTER = Reboot");
765 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
769 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
770 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
)) /* ESC */
776 return REPAIR_INTRO_PAGE
;
781 RepairIntroPage(PINPUT_RECORD Ir
)
783 SetTextXY(6, 8, "ReactOS Setup is in an early development phase. It does not yet");
784 SetTextXY(6, 9, "support all the functions of a fully usable setup application.");
786 SetTextXY(6, 12, "The repair functions are not implemented yet.");
788 SetTextXY(8, 15, "\x07 Press ESC to return to the main page.");
790 SetTextXY(8, 17, "\x07 Press ENTER to reboot your computer.");
792 SetStatusText(" ESC = Main page ENTER = Reboot");
798 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
802 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
803 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
)) /* ESC */
809 return REPAIR_INTRO_PAGE
;
814 InstallIntroPage(PINPUT_RECORD Ir
)
816 SetTextXY(6, 8, "ReactOS Setup is in an early development phase. It does not yet");
817 SetTextXY(6, 9, "support all the functions of a fully usable setup application.");
819 SetTextXY(6, 12, "The following limitations apply:");
820 SetTextXY(8, 13, "- Setup can not handle more than one primary partition per disk.");
821 SetTextXY(8, 14, "- Setup can not delete a primary partition from a disk");
822 SetTextXY(8, 15, " as long as extended partitions exist on this disk.");
823 SetTextXY(8, 16, "- Setup can not delete the first extended partition from a disk");
824 SetTextXY(8, 17, " as long as other extended partitions exist on this disk.");
825 SetTextXY(8, 18, "- Setup supports FAT file systems only.");
826 SetTextXY(8, 19, "- File system checks are not implemented yet.");
829 SetTextXY(8, 23, "\x07 Press ENTER to install ReactOS.");
831 SetTextXY(8, 25, "\x07 Press F3 to quit without installing ReactOS.");
834 SetStatusText(" ENTER = Continue F3 = Quit");
836 if (IsUnattendedSetup
)
838 return(SELECT_PARTITION_PAGE
);
845 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
846 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
848 if (ConfirmQuit(Ir
) == TRUE
)
852 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
854 return DEVICE_SETTINGS_PAGE
;
858 return INSTALL_INTRO_PAGE
;
863 DeviceSettingsPage(PINPUT_RECORD Ir
)
865 static ULONG Line
= 17;
867 /* Initialize the computer settings list */
868 if (ComputerList
== NULL
)
870 ComputerList
= CreateComputerTypeList(SetupInf
);
871 if (ComputerList
== NULL
)
873 /* FIXME: report error */
877 /* Initialize the display settings list */
878 if (DisplayList
== NULL
)
880 DisplayList
= CreateDisplayDriverList(SetupInf
);
881 if (DisplayList
== NULL
)
883 /* FIXME: report error */
887 /* Initialize the keyboard settings list */
888 if (KeyboardList
== NULL
)
890 KeyboardList
= CreateKeyboardDriverList(SetupInf
);
891 if (KeyboardList
== NULL
)
893 /* FIXME: report error */
897 /* Initialize the keyboard layout list */
898 if (LayoutList
== NULL
)
900 LayoutList
= CreateKeyboardLayoutList(SetupInf
);
901 if (LayoutList
== NULL
)
903 /* FIXME: report error */
904 PopupError("Setup failed to load the keyboard layout list.\n",
905 "ENTER = Reboot computer");
911 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
919 /* Initialize the pointer settings list */
920 if (PointerList
== NULL
)
922 PointerList
= CreateMouseDriverList(SetupInf
);
923 if (PointerList
== NULL
)
925 /* FIXME: report error */
929 SetTextXY(6, 8, "The list below shows the current device settings.");
931 SetTextXY(8, 11, " Computer:");
932 SetTextXY(8, 12, " Display:");
933 SetTextXY(8, 13, " Keyboard:");
934 SetTextXY(8, 14, "Keyboard layout:");
935 SetTextXY(8, 15, " Pointer device:");
937 SetTextXY(8, 17, " Accept:");
939 SetTextXY(25, 11, GetGenericListEntry(ComputerList
)->Text
);
940 SetTextXY(25, 12, GetGenericListEntry(DisplayList
)->Text
);
941 SetTextXY(25, 13, GetGenericListEntry(KeyboardList
)->Text
);
942 SetTextXY(25, 14, GetGenericListEntry(LayoutList
)->Text
);
943 SetTextXY(25, 15, GetGenericListEntry(PointerList
)->Text
);
945 SetTextXY(25, 17, "Accept these device setings");
946 InvertTextXY (24, Line
, 48, 1);
949 SetTextXY(6, 20, "You can change the hardware settings by pressing the UP or DOWN keys");
950 SetTextXY(6, 21, "to select an entry. Then press the ENTER key to select alternative");
951 SetTextXY(6, 22, "settings.");
953 SetTextXY(6, 24, "When all settings are correct, select \"Accept these device setings\"");
954 SetTextXY(6, 25, "and press ENTER.");
956 SetStatusText(" ENTER = Continue F3 = Quit");
962 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
963 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
)) /* DOWN */
965 NormalTextXY (24, Line
, 48, 1);
972 InvertTextXY (24, Line
, 48, 1);
974 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
975 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_UP
)) /* UP */
977 NormalTextXY (24, Line
, 48, 1);
984 InvertTextXY (24, Line
, 48, 1);
986 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
987 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
989 if (ConfirmQuit(Ir
) == TRUE
)
993 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
996 return COMPUTER_SETTINGS_PAGE
;
998 return DISPLAY_SETTINGS_PAGE
;
1000 return KEYBOARD_SETTINGS_PAGE
;
1001 else if (Line
== 14)
1002 return LAYOUT_SETTINGS_PAGE
;
1003 else if (Line
== 15)
1004 return POINTER_SETTINGS_PAGE
;
1005 else if (Line
== 17)
1006 return SELECT_PARTITION_PAGE
;
1010 return DEVICE_SETTINGS_PAGE
;
1015 ComputerSettingsPage(PINPUT_RECORD Ir
)
1020 SetTextXY(6, 8, "You want to change the type of computer to be installed.");
1022 SetTextXY(8, 10, "\x07 Press the UP or DOWN key to select the desired computer type.");
1023 SetTextXY(8, 11, " Then press ENTER.");
1025 SetTextXY(8, 13, "\x07 Press the ESC key to return to the previous page without changing");
1026 SetTextXY(8, 14, " the computer type.");
1028 GetScreenSize(&xScreen
, &yScreen
);
1030 DrawGenericList(ComputerList
,
1036 SetStatusText(" ENTER = Continue ESC = Cancel F3 = Quit");
1038 SaveGenericListState(ComputerList
);
1044 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1045 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
)) /* DOWN */
1047 ScrollDownGenericList (ComputerList
);
1049 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1050 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_UP
)) /* UP */
1052 ScrollUpGenericList (ComputerList
);
1054 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1055 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1057 if (ConfirmQuit(Ir
) == TRUE
)
1061 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1062 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
)) /* ESC */
1064 RestoreGenericListState(ComputerList
);
1065 return DEVICE_SETTINGS_PAGE
;
1067 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
1069 return DEVICE_SETTINGS_PAGE
;
1073 return COMPUTER_SETTINGS_PAGE
;
1078 DisplaySettingsPage(PINPUT_RECORD Ir
)
1083 SetTextXY(6, 8, "You want to change the type of display to be installed.");
1085 SetTextXY(8, 10, "\x07 Press the UP or DOWN key to select the desired display type.");
1086 SetTextXY(8, 11, " Then press ENTER.");
1088 SetTextXY(8, 13, "\x07 Press the ESC key to return to the previous page without changing");
1089 SetTextXY(8, 14, " the display type.");
1091 GetScreenSize(&xScreen
, &yScreen
);
1093 DrawGenericList(DisplayList
,
1099 SetStatusText(" ENTER = Continue ESC = Cancel F3 = Quit");
1101 SaveGenericListState(DisplayList
);
1107 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1108 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
)) /* DOWN */
1110 ScrollDownGenericList (DisplayList
);
1112 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1113 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_UP
)) /* UP */
1115 ScrollUpGenericList (DisplayList
);
1117 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1118 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1120 if (ConfirmQuit(Ir
) == TRUE
)
1126 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1127 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
)) /* ESC */
1129 RestoreGenericListState(DisplayList
);
1130 return DEVICE_SETTINGS_PAGE
;
1132 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
1134 return DEVICE_SETTINGS_PAGE
;
1138 return DISPLAY_SETTINGS_PAGE
;
1143 KeyboardSettingsPage(PINPUT_RECORD Ir
)
1148 SetTextXY(6, 8, "You want to change the type of keyboard to be installed.");
1150 SetTextXY(8, 10, "\x07 Press the UP or DOWN key to select the desired keyboard type.");
1151 SetTextXY(8, 11, " Then press ENTER.");
1153 SetTextXY(8, 13, "\x07 Press the ESC key to return to the previous page without changing");
1154 SetTextXY(8, 14, " the keyboard type.");
1156 GetScreenSize(&xScreen
, &yScreen
);
1158 DrawGenericList(KeyboardList
,
1164 SetStatusText(" ENTER = Continue ESC = Cancel F3 = Quit");
1166 SaveGenericListState(KeyboardList
);
1172 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1173 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
)) /* DOWN */
1175 ScrollDownGenericList (KeyboardList
);
1177 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1178 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_UP
)) /* UP */
1180 ScrollUpGenericList (KeyboardList
);
1182 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1183 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1185 if (ConfirmQuit(Ir
) == TRUE
)
1189 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1190 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
)) /* ESC */
1192 RestoreGenericListState(KeyboardList
);
1193 return DEVICE_SETTINGS_PAGE
;
1195 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
1197 return DEVICE_SETTINGS_PAGE
;
1201 return DISPLAY_SETTINGS_PAGE
;
1206 LayoutSettingsPage(PINPUT_RECORD Ir
)
1211 SetTextXY(6, 8, "You want to change the keyboard layout to be installed.");
1213 SetTextXY(8, 10, "\x07 Press the UP or DOWN key to select the desired keyboard");
1214 SetTextXY(8, 11, " layout. Then press ENTER.");
1216 SetTextXY(8, 13, "\x07 Press the ESC key to return to the previous page without changing");
1217 SetTextXY(8, 14, " the keyboard layout.");
1219 GetScreenSize(&xScreen
, &yScreen
);
1221 DrawGenericList(LayoutList
,
1227 SetStatusText(" ENTER = Continue ESC = Cancel F3 = Quit");
1229 SaveGenericListState(LayoutList
);
1235 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1236 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
)) /* DOWN */
1238 ScrollDownGenericList (LayoutList
);
1240 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1241 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_UP
)) /* UP */
1243 ScrollUpGenericList (LayoutList
);
1245 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1246 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1248 if (ConfirmQuit(Ir
) == TRUE
)
1252 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1253 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
)) /* ESC */
1255 RestoreGenericListState(LayoutList
);
1256 return DEVICE_SETTINGS_PAGE
;
1258 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
1260 return DEVICE_SETTINGS_PAGE
;
1264 return DISPLAY_SETTINGS_PAGE
;
1269 PointerSettingsPage(PINPUT_RECORD Ir
)
1274 SetTextXY(6, 8, "You want to change the pointing device to be installed.");
1276 SetTextXY(8, 10, "\x07 Press the UP or DOWN key to select the desired pointing");
1277 SetTextXY(8, 11, " device. Then press ENTER.");
1279 SetTextXY(8, 13, "\x07 Press the ESC key to return to the previous page without changing");
1280 SetTextXY(8, 14, " the pointing device.");
1282 GetScreenSize(&xScreen
, &yScreen
);
1284 DrawGenericList(PointerList
,
1290 SetStatusText(" ENTER = Continue ESC = Cancel F3 = Quit");
1292 SaveGenericListState(PointerList
);
1298 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1299 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
)) /* DOWN */
1301 ScrollDownGenericList(PointerList
);
1303 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1304 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_UP
)) /* UP */
1306 ScrollUpGenericList(PointerList
);
1308 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1309 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1311 if (ConfirmQuit(Ir
) == TRUE
)
1315 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1316 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
)) /* ESC */
1318 RestoreGenericListState(PointerList
);
1319 return DEVICE_SETTINGS_PAGE
;
1321 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
1323 return DEVICE_SETTINGS_PAGE
;
1327 return DISPLAY_SETTINGS_PAGE
;
1332 SelectPartitionPage(PINPUT_RECORD Ir
)
1337 SetTextXY(6, 8, "The list below shows existing partitions and unused disk");
1338 SetTextXY(6, 9, "space for new partitions.");
1340 SetTextXY(8, 11, "\x07 Press UP or DOWN to select a list entry.");
1341 SetTextXY(8, 13, "\x07 Press ENTER to install ReactOS onto the selected partition.");
1342 SetTextXY(8, 15, "\x07 Press C to create a new partition.");
1343 SetTextXY(8, 17, "\x07 Press D to delete an existing partition.");
1345 SetStatusText(" Please wait...");
1347 GetScreenSize(&xScreen
, &yScreen
);
1349 if (PartitionList
== NULL
)
1351 PartitionList
= CreatePartitionList (2,
1355 if (PartitionList
== NULL
)
1357 /* FIXME: show an error dialog */
1362 CheckActiveBootPartition (PartitionList
);
1364 DrawPartitionList (PartitionList
);
1366 /* Warn about partitions created by Linux Fdisk */
1367 if (WarnLinuxPartitions
== TRUE
&&
1368 CheckForLinuxFdiskPartitions (PartitionList
) == TRUE
)
1370 PopupError ("Setup found that at least one harddisk contains an incompatible\n"
1371 "partition table that can not be handled properly!\n"
1373 "Creating or deleting partitions can destroy the partiton table.\n"
1375 " \x07 Press F3 to quit Setup."
1376 " \x07 Press ENTER to continue.",
1377 "F3= Quit ENTER = Continue");
1382 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1383 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1387 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_RETURN
) /* ENTER */
1389 WarnLinuxPartitions
= FALSE
;
1390 return SELECT_PARTITION_PAGE
;
1395 if (IsUnattendedSetup
)
1397 SelectPartition(PartitionList
,
1398 UnattendDestinationDiskNumber
,
1399 UnattendDestinationPartitionNumber
);
1400 return(SELECT_FILE_SYSTEM_PAGE
);
1405 /* Update status text */
1406 if (PartitionList
->CurrentPartition
== NULL
||
1407 PartitionList
->CurrentPartition
->Unpartitioned
== TRUE
)
1409 SetStatusText (" ENTER = Install C = Create Partition F3 = Quit");
1413 SetStatusText (" ENTER = Install D = Delete Partition F3 = Quit");
1418 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1419 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1421 if (ConfirmQuit(Ir
) == TRUE
)
1423 DestroyPartitionList (PartitionList
);
1424 PartitionList
= NULL
;
1429 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1430 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
)) /* DOWN */
1432 ScrollDownPartitionList (PartitionList
);
1434 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1435 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_UP
)) /* UP */
1437 ScrollUpPartitionList (PartitionList
);
1439 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_RETURN
) /* ENTER */
1441 if (PartitionList
->CurrentPartition
== NULL
||
1442 PartitionList
->CurrentPartition
->Unpartitioned
== TRUE
)
1444 CreateNewPartition (PartitionList
,
1449 return SELECT_FILE_SYSTEM_PAGE
;
1451 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_C
) /* C */
1453 if (PartitionList
->CurrentPartition
->Unpartitioned
== FALSE
)
1455 PopupError ("You can not create a new Partition inside\n"
1456 "of an already existing Partition!\n"
1458 " * Press any key to continue.",
1462 return SELECT_PARTITION_PAGE
;
1465 return CREATE_PARTITION_PAGE
;
1467 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_D
) /* D */
1469 if (PartitionList
->CurrentPartition
->Unpartitioned
== TRUE
)
1471 PopupError ("You can not delete unpartitioned disk space!\n"
1473 " * Press any key to continue.",
1477 return SELECT_PARTITION_PAGE
;
1480 return DELETE_PARTITION_PAGE
;
1484 return SELECT_PARTITION_PAGE
;
1489 DrawInputField(ULONG FieldLength
,
1499 memset(buf
, '_', sizeof(buf
));
1500 buf
[FieldLength
- strlen(FieldContent
)] = 0;
1501 strcat(buf
, FieldContent
);
1503 WriteConsoleOutputCharacters (buf
,
1509 #define PARTITION_SIZE_INPUT_FIELD_LENGTH 6
1512 ShowPartitionSizeInputBox(SHORT Left
,
1537 /* draw upper left corner */
1540 FillConsoleOutputCharacter(0xDA, // '+',
1545 /* draw upper edge */
1548 FillConsoleOutputCharacter(0xC4, // '-',
1553 /* draw upper right corner */
1556 FillConsoleOutputCharacter(0xBF, // '+',
1561 /* draw left and right edge */
1562 for (i
= Top
+ 1; i
< Bottom
; i
++)
1566 FillConsoleOutputCharacter(0xB3, // '|',
1572 FillConsoleOutputCharacter(0xB3, //'|',
1578 /* draw lower left corner */
1581 FillConsoleOutputCharacter(0xC0, // '+',
1586 /* draw lower edge */
1589 FillConsoleOutputCharacter(0xC4, // '-',
1594 /* draw lower right corner */
1597 FillConsoleOutputCharacter(0xD9, // '+',
1605 strcpy (Buffer
, "Size of new partition:");
1606 iLeft
= coPos
.X
+ strlen (Buffer
) + 1;
1608 WriteConsoleOutputCharacters (Buffer
,
1612 sprintf (Buffer
, "MB (max. %lu MB)", MaxSize
);
1613 coPos
.X
= iLeft
+ PARTITION_SIZE_INPUT_FIELD_LENGTH
+ 1;
1615 WriteConsoleOutputCharacters (Buffer
,
1621 DrawInputField (PARTITION_SIZE_INPUT_FIELD_LENGTH
,
1630 if ((Ir
.Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1631 (Ir
.Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1638 else if (Ir
.Event
.KeyEvent
.wVirtualKeyCode
== VK_RETURN
) /* ENTER */
1642 else if (Ir
.Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
) /* ESCAPE */
1649 else if ((Ir
.Event
.KeyEvent
.wVirtualKeyCode
== VK_BACK
) && /* BACKSPACE */
1654 DrawInputField (PARTITION_SIZE_INPUT_FIELD_LENGTH
,
1659 else if ((Ir
.Event
.KeyEvent
.uChar
.AsciiChar
!= 0x00) &&
1660 (Index
< PARTITION_SIZE_INPUT_FIELD_LENGTH
))
1662 ch
= Ir
.Event
.KeyEvent
.uChar
.AsciiChar
;
1663 if ((ch
>= '0') && (ch
<= '9'))
1668 DrawInputField (PARTITION_SIZE_INPUT_FIELD_LENGTH
,
1676 strcpy (InputBuffer
,
1682 CreatePartitionPage (PINPUT_RECORD Ir
)
1684 PDISKENTRY DiskEntry
;
1685 PPARTENTRY PartEntry
;
1690 CHAR InputBuffer
[50];
1696 if (PartitionList
== NULL
||
1697 PartitionList
->CurrentDisk
== NULL
||
1698 PartitionList
->CurrentPartition
== NULL
)
1700 /* FIXME: show an error dialog */
1704 DiskEntry
= PartitionList
->CurrentDisk
;
1705 PartEntry
= PartitionList
->CurrentPartition
;
1707 SetStatusText (" Please wait...");
1709 GetScreenSize (&xScreen
, &yScreen
);
1711 SetTextXY (6, 8, "You have chosen to create a new partition on");
1714 if (DiskEntry
->DiskSize
>= 0x280000000ULL
) /* 10 GB */
1716 DiskSize
= (DiskEntry
->DiskSize
+ (1 << 29)) >> 30;
1722 DiskSize
= (DiskEntry
->DiskSize
+ (1 << 19)) >> 20;
1728 if (DiskEntry
->DriverName
.Length
> 0)
1731 "%I64u %s Harddisk %lu (Port=%hu, Bus=%hu, Id=%hu) on %wZ.",
1734 DiskEntry
->DiskNumber
,
1738 &DiskEntry
->DriverName
);
1743 "%I64u %s Harddisk %lu (Port=%hu, Bus=%hu, Id=%hu).",
1746 DiskEntry
->DiskNumber
,
1753 SetTextXY (6, 12, "Please enter the size of the new partition in megabytes.");
1756 PrintTextXY (8, 10, "Maximum size of the new partition is %I64u MB",
1757 PartitionList
->CurrentPartition
->UnpartitionedLength
/ (1024*1024));
1760 SetStatusText (" ENTER = Create Partition ESC = Cancel F3 = Quit");
1762 PartEntry
= PartitionList
->CurrentPartition
;
1765 MaxSize
= (PartEntry
->UnpartitionedLength
+ (1 << 19)) >> 20; /* in MBytes (rounded) */
1766 ShowPartitionSizeInputBox (12, 14, xScreen
- 12, 17, /* left, top, right, bottom */
1767 MaxSize
, InputBuffer
, &Quit
, &Cancel
);
1770 if (ConfirmQuit (Ir
) == TRUE
)
1775 else if (Cancel
== TRUE
)
1777 return SELECT_PARTITION_PAGE
;
1781 PartSize
= atoi (InputBuffer
);
1788 if (PartSize
> MaxSize
)
1794 /* Convert to bytes */
1795 if (PartSize
== MaxSize
)
1797 /* Use all of the unpartitioned disk space */
1798 PartSize
= PartEntry
->UnpartitionedLength
;
1802 /* Round-up by cylinder size */
1803 PartSize
= ROUND_UP (PartSize
* 1024 * 1024,
1804 DiskEntry
->CylinderSize
);
1806 /* But never get larger than the unpartitioned disk space */
1807 if (PartSize
> PartEntry
->UnpartitionedLength
)
1808 PartSize
= PartEntry
->UnpartitionedLength
;
1811 DPRINT ("Partition size: %I64u bytes\n", PartSize
);
1813 CreateNewPartition (PartitionList
,
1817 return SELECT_PARTITION_PAGE
;
1821 return CREATE_PARTITION_PAGE
;
1826 DeletePartitionPage (PINPUT_RECORD Ir
)
1828 PDISKENTRY DiskEntry
;
1829 PPARTENTRY PartEntry
;
1835 if (PartitionList
== NULL
||
1836 PartitionList
->CurrentDisk
== NULL
||
1837 PartitionList
->CurrentPartition
== NULL
)
1839 /* FIXME: show an error dialog */
1843 DiskEntry
= PartitionList
->CurrentDisk
;
1844 PartEntry
= PartitionList
->CurrentPartition
;
1846 SetTextXY (6, 8, "You have chosen to delete the partition");
1848 /* Determine partition type */
1850 if (PartEntry
->New
== TRUE
)
1852 PartType
= "New (Unformatted)";
1854 else if (PartEntry
->Unpartitioned
== FALSE
)
1856 if ((PartEntry
->PartInfo
[0].PartitionType
== PARTITION_FAT_12
) ||
1857 (PartEntry
->PartInfo
[0].PartitionType
== PARTITION_FAT_16
) ||
1858 (PartEntry
->PartInfo
[0].PartitionType
== PARTITION_HUGE
) ||
1859 (PartEntry
->PartInfo
[0].PartitionType
== PARTITION_XINT13
))
1863 else if ((PartEntry
->PartInfo
[0].PartitionType
== PARTITION_FAT32
) ||
1864 (PartEntry
->PartInfo
[0].PartitionType
== PARTITION_FAT32_XINT13
))
1868 else if (PartEntry
->PartInfo
[0].PartitionType
== PARTITION_IFS
)
1870 PartType
= "NTFS"; /* FIXME: Not quite correct! */
1875 if (PartEntry
->PartInfo
[0].PartitionLength
.QuadPart
>= 0x280000000ULL
) /* 10 GB */
1877 PartSize
= (PartEntry
->PartInfo
[0].PartitionLength
.QuadPart
+ (1 << 29)) >> 30;
1882 if (PartEntry
->PartInfo
[0].PartitionLength
.QuadPart
>= 0xA00000ULL
) /* 10 MB */
1884 PartSize
= (PartEntry
->PartInfo
[0].PartitionLength
.QuadPart
+ (1 << 19)) >> 20;
1889 PartSize
= (PartEntry
->PartInfo
[0].PartitionLength
.QuadPart
+ (1 << 9)) >> 10;
1893 if (PartType
== NULL
)
1896 " %c%c Type %lu %I64u %s",
1897 (PartEntry
->DriveLetter
== 0) ? '-' : PartEntry
->DriveLetter
,
1898 (PartEntry
->DriveLetter
== 0) ? '-' : ':',
1899 PartEntry
->PartInfo
[0].PartitionType
,
1906 " %c%c %s %I64u %s",
1907 (PartEntry
->DriveLetter
== 0) ? '-' : PartEntry
->DriveLetter
,
1908 (PartEntry
->DriveLetter
== 0) ? '-' : ':',
1915 if (DiskEntry
->DiskSize
>= 0x280000000ULL
) /* 10 GB */
1917 DiskSize
= (DiskEntry
->DiskSize
+ (1 << 29)) >> 30;
1923 DiskSize
= (DiskEntry
->DiskSize
+ (1 << 19)) >> 20;
1929 if (DiskEntry
->DriverName
.Length
> 0)
1932 "on %I64u %s Harddisk %lu (Port=%hu, Bus=%hu, Id=%hu) on %wZ.",
1935 DiskEntry
->DiskNumber
,
1939 &DiskEntry
->DriverName
);
1944 "on %I64u %s Harddisk %lu (Port=%hu, Bus=%hu, Id=%hu).",
1947 DiskEntry
->DiskNumber
,
1953 SetTextXY (8, 18, "\x07 Press D to delete the partition.");
1954 SetTextXY (11, 19, "WARNING: All data on this partition will be lost!");
1956 SetTextXY (8, 21, "\x07 Press ESC to cancel.");
1958 SetStatusText (" D = Delete Partition ESC = Cancel F3 = Quit");
1964 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1965 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1967 if (ConfirmQuit (Ir
) == TRUE
)
1973 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
) /* ESC */
1975 return SELECT_PARTITION_PAGE
;
1977 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_D
) /* D */
1979 DeleteCurrentPartition (PartitionList
);
1981 return SELECT_PARTITION_PAGE
;
1985 return DELETE_PARTITION_PAGE
;
1990 SelectFileSystemPage (PINPUT_RECORD Ir
)
1992 PDISKENTRY DiskEntry
;
1993 PPARTENTRY PartEntry
;
2000 if (PartitionList
== NULL
||
2001 PartitionList
->CurrentDisk
== NULL
||
2002 PartitionList
->CurrentPartition
== NULL
)
2004 /* FIXME: show an error dialog */
2008 DiskEntry
= PartitionList
->CurrentDisk
;
2009 PartEntry
= PartitionList
->CurrentPartition
;
2011 /* adjust disk size */
2012 if (DiskEntry
->DiskSize
>= 0x280000000ULL
) /* 10 GB */
2014 DiskSize
= (DiskEntry
->DiskSize
+ (1 << 29)) >> 30;
2019 DiskSize
= (DiskEntry
->DiskSize
+ (1 << 19)) >> 20;
2023 /* adjust partition size */
2024 if (PartEntry
->PartInfo
[0].PartitionLength
.QuadPart
>= 0x280000000ULL
) /* 10 GB */
2026 PartSize
= (PartEntry
->PartInfo
[0].PartitionLength
.QuadPart
+ (1 << 29)) >> 30;
2031 PartSize
= (PartEntry
->PartInfo
[0].PartitionLength
.QuadPart
+ (1 << 19)) >> 20;
2035 /* adjust partition type */
2036 if ((PartEntry
->PartInfo
[0].PartitionType
== PARTITION_FAT_12
) ||
2037 (PartEntry
->PartInfo
[0].PartitionType
== PARTITION_FAT_16
) ||
2038 (PartEntry
->PartInfo
[0].PartitionType
== PARTITION_HUGE
) ||
2039 (PartEntry
->PartInfo
[0].PartitionType
== PARTITION_XINT13
))
2043 else if ((PartEntry
->PartInfo
[0].PartitionType
== PARTITION_FAT32
) ||
2044 (PartEntry
->PartInfo
[0].PartitionType
== PARTITION_FAT32_XINT13
))
2048 else if (PartEntry
->PartInfo
[0].PartitionType
== PARTITION_IFS
)
2050 PartType
= "NTFS"; /* FIXME: Not quite correct! */
2052 else if (PartEntry
->PartInfo
[0].PartitionType
== PARTITION_ENTRY_UNUSED
)
2054 PartType
= "Unused";
2058 PartType
= "Unknown";
2061 if (PartEntry
->AutoCreate
== TRUE
)
2063 SetTextXY(6, 8, "Setup created a new partition on");
2066 PrintTextXY(8, 10, "Partition %lu (%I64u %s) %s of",
2067 PartEntry
->PartInfo
[0].PartitionNumber
,
2073 PrintTextXY(8, 10, "Harddisk %lu (%I64u %s), Port=%hu, Bus=%hu, Id=%hu (%wZ).",
2074 DiskEntry
->DiskNumber
,
2080 &DiskEntry
->DriverName
);
2082 SetTextXY(6, 12, "This Partition will be formatted next.");
2085 PartEntry
->AutoCreate
= FALSE
;
2087 else if (PartEntry
->New
== TRUE
)
2089 SetTextXY(6, 8, "You chose to install ReactOS on a new or unformatted Partition.");
2090 SetTextXY(6, 10, "This Partition will be formatted next.");
2094 SetTextXY(6, 8, "Setup install ReactOS onto Partition");
2096 if (PartType
== NULL
)
2099 "%c%c Type %lu %I64u %s",
2100 (PartEntry
->DriveLetter
== 0) ? '-' : PartEntry
->DriveLetter
,
2101 (PartEntry
->DriveLetter
== 0) ? '-' : ':',
2102 PartEntry
->PartInfo
[0].PartitionType
,
2110 (PartEntry
->DriveLetter
== 0) ? '-' : PartEntry
->DriveLetter
,
2111 (PartEntry
->DriveLetter
== 0) ? '-' : ':',
2117 PrintTextXY(6, 12, "on Harddisk %lu (%I64u %s), Port=%hu, Bus=%hu, Id=%hu (%wZ).",
2118 DiskEntry
->DiskNumber
,
2124 &DiskEntry
->DriverName
);
2128 SetTextXY(6, 17, "Select a file system from the list below.");
2130 SetTextXY(8, 19, "\x07 Press UP or DOWN to select a file system.");
2131 SetTextXY(8, 21, "\x07 Press ENTER to format the partition.");
2132 SetTextXY(8, 23, "\x07 Press ESC to select another partition.");
2134 if (FileSystemList
== NULL
)
2136 FileSystemList
= CreateFileSystemList (6, 26, PartEntry
->New
, FsFat
);
2137 if (FileSystemList
== NULL
)
2139 /* FIXME: show an error dialog */
2143 /* FIXME: Add file systems to list */
2145 DrawFileSystemList (FileSystemList
);
2147 SetStatusText (" ENTER = Continue ESC = Cancel F3 = Quit");
2149 if (IsUnattendedSetup
)
2151 return(CHECK_FILE_SYSTEM_PAGE
);
2158 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
2159 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
2161 if (ConfirmQuit (Ir
) == TRUE
)
2167 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
2168 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
)) /* ESC */
2170 return SELECT_PARTITION_PAGE
;
2172 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
2173 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
)) /* DOWN */
2175 ScrollDownFileSystemList (FileSystemList
);
2177 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
2178 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_UP
)) /* UP */
2180 ScrollUpFileSystemList (FileSystemList
);
2182 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_RETURN
) /* ENTER */
2184 if (FileSystemList
->CurrentFileSystem
== FsKeep
)
2186 return CHECK_FILE_SYSTEM_PAGE
;
2190 return FORMAT_PARTITION_PAGE
;
2195 return SELECT_FILE_SYSTEM_PAGE
;
2200 FormatPartitionPage (PINPUT_RECORD Ir
)
2202 WCHAR PathBuffer
[MAX_PATH
];
2203 PDISKENTRY DiskEntry
;
2204 PPARTENTRY PartEntry
;
2213 SetTextXY(6, 8, "Format partition");
2215 SetTextXY(6, 10, "Setup will now format the partition. Press ENTER to continue.");
2217 SetStatusText(" ENTER = Continue F3 = Quit");
2220 if (PartitionList
== NULL
||
2221 PartitionList
->CurrentDisk
== NULL
||
2222 PartitionList
->CurrentPartition
== NULL
)
2224 /* FIXME: show an error dialog */
2228 DiskEntry
= PartitionList
->CurrentDisk
;
2229 PartEntry
= PartitionList
->CurrentPartition
;
2235 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
2236 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
2238 if (ConfirmQuit (Ir
) == TRUE
)
2244 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_RETURN
) /* ENTER */
2246 SetStatusText (" Please wait ...");
2248 if (PartEntry
->PartInfo
[0].PartitionType
== PARTITION_ENTRY_UNUSED
)
2250 switch (FileSystemList
->CurrentFileSystem
)
2253 if (PartEntry
->PartInfo
[0].PartitionLength
.QuadPart
< (4200ULL * 1024ULL))
2255 /* FAT12 CHS partition (disk is smaller than 4.1MB) */
2256 PartEntry
->PartInfo
[0].PartitionType
= PARTITION_FAT_12
;
2258 else if (PartEntry
->PartInfo
[0].StartingOffset
.QuadPart
< (1024ULL * 255ULL * 63ULL * 512ULL))
2260 /* Partition starts below the 8.4GB boundary ==> CHS partition */
2262 if (PartEntry
->PartInfo
[0].PartitionLength
.QuadPart
< (32ULL * 1024ULL * 1024ULL))
2264 /* FAT16 CHS partition (partiton size < 32MB) */
2265 PartEntry
->PartInfo
[0].PartitionType
= PARTITION_FAT_16
;
2267 else if (PartEntry
->PartInfo
[0].PartitionLength
.QuadPart
< (512ULL * 1024ULL * 1024ULL))
2269 /* FAT16 CHS partition (partition size < 512MB) */
2270 PartEntry
->PartInfo
[0].PartitionType
= PARTITION_HUGE
;
2274 /* FAT32 CHS partition (partition size >= 512MB) */
2275 PartEntry
->PartInfo
[0].PartitionType
= PARTITION_FAT32
;
2280 /* Partition starts above the 8.4GB boundary ==> LBA partition */
2282 if (PartEntry
->PartInfo
[0].PartitionLength
.QuadPart
< (512ULL * 1024ULL * 1024ULL))
2284 /* FAT16 LBA partition (partition size < 512MB) */
2285 PartEntry
->PartInfo
[0].PartitionType
= PARTITION_XINT13
;
2289 /* FAT32 LBA partition (partition size >= 512MB) */
2290 PartEntry
->PartInfo
[0].PartitionType
= PARTITION_FAT32_XINT13
;
2303 CheckActiveBootPartition (PartitionList
);
2307 "Disk: %I64u Cylinder: %I64u Track: %I64u",
2308 DiskEntry
->DiskSize
,
2309 DiskEntry
->CylinderSize
,
2310 DiskEntry
->TrackSize
);
2313 DiskEntry
= PartitionList
->CurrentDisk
;
2314 Entry
= DiskEntry
->PartListHead
.Flink
;
2315 while (Entry
!= &DiskEntry
->PartListHead
)
2317 PartEntry
= CONTAINING_RECORD(Entry
, PARTENTRY
, ListEntry
);
2319 if (PartEntry
->Unpartitioned
== FALSE
)
2322 for (i
= 0; i
< 4; i
++)
2324 PrintTextXY (6, Line
,
2325 "%2u: %2u %c %12I64u %12I64u %2u %c",
2327 PartEntry
->PartInfo
[i
].PartitionNumber
,
2328 PartEntry
->PartInfo
[i
].BootIndicator
? 'A' : '-',
2329 PartEntry
->PartInfo
[i
].StartingOffset
.QuadPart
,
2330 PartEntry
->PartInfo
[i
].PartitionLength
.QuadPart
,
2331 PartEntry
->PartInfo
[i
].PartitionType
,
2332 PartEntry
->PartInfo
[i
].RewritePartition
? '*' : ' ');
2340 Entry
= Entry
->Flink
;
2343 /* Restore the old entry */
2344 PartEntry
= PartitionList
->CurrentPartition
;
2347 if (WritePartitionsToDisk (PartitionList
) == FALSE
)
2349 DPRINT ("WritePartitionsToDisk() failed\n");
2351 PopupError ("Setup failed to write partition tables.\n",
2352 "ENTER = Reboot computer");
2358 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2365 /* Set DestinationRootPath */
2366 RtlFreeUnicodeString (&DestinationRootPath
);
2367 swprintf (PathBuffer
,
2368 L
"\\Device\\Harddisk%lu\\Partition%lu",
2369 PartitionList
->CurrentDisk
->DiskNumber
,
2370 PartitionList
->CurrentPartition
->PartInfo
[0].PartitionNumber
);
2371 RtlCreateUnicodeString (&DestinationRootPath
,
2373 DPRINT ("DestinationRootPath: %wZ\n", &DestinationRootPath
);
2376 /* Set SystemRootPath */
2377 RtlFreeUnicodeString (&SystemRootPath
);
2378 swprintf (PathBuffer
,
2379 L
"\\Device\\Harddisk%lu\\Partition%lu",
2380 PartitionList
->ActiveBootDisk
->DiskNumber
,
2381 PartitionList
->ActiveBootPartition
->PartInfo
[0].PartitionNumber
);
2382 RtlCreateUnicodeString (&SystemRootPath
,
2384 DPRINT ("SystemRootPath: %wZ\n", &SystemRootPath
);
2387 switch (FileSystemList
->CurrentFileSystem
)
2390 Status
= FormatPartition (&DestinationRootPath
);
2391 if (!NT_SUCCESS (Status
))
2393 DPRINT1 ("FormatPartition() failed with status 0x%.08x\n", Status
);
2394 /* FIXME: show an error dialog */
2398 PartEntry
->New
= FALSE
;
2399 if (FileSystemList
!= NULL
)
2401 DestroyFileSystemList (FileSystemList
);
2402 FileSystemList
= NULL
;
2405 CheckActiveBootPartition (PartitionList
);
2407 /* FIXME: Install boot code. This is a hack! */
2408 if ((PartEntry
->PartInfo
[0].PartitionType
== PARTITION_FAT32_XINT13
) ||
2409 (PartEntry
->PartInfo
[0].PartitionType
== PARTITION_FAT32
))
2411 wcscpy (PathBuffer
, SourceRootPath
.Buffer
);
2412 wcscat (PathBuffer
, L
"\\loader\\fat32.bin");
2414 DPRINT ("Install FAT32 bootcode: %S ==> %S\n", PathBuffer
,
2415 DestinationRootPath
.Buffer
);
2416 Status
= InstallFat32BootCodeToDisk (PathBuffer
,
2417 DestinationRootPath
.Buffer
);
2418 if (!NT_SUCCESS (Status
))
2420 DPRINT1 ("InstallFat32BootCodeToDisk() failed with status 0x%.08x\n", Status
);
2421 /* FIXME: show an error dialog */
2427 wcscpy (PathBuffer
, SourceRootPath
.Buffer
);
2428 wcscat (PathBuffer
, L
"\\loader\\fat.bin");
2430 DPRINT ("Install FAT bootcode: %S ==> %S\n", PathBuffer
,
2431 DestinationRootPath
.Buffer
);
2432 Status
= InstallFat16BootCodeToDisk (PathBuffer
,
2433 DestinationRootPath
.Buffer
);
2434 if (!NT_SUCCESS (Status
))
2436 DPRINT1 ("InstallFat16BootCodeToDisk() failed with status 0x%.08x\n", Status
);
2437 /* FIXME: show an error dialog */
2450 SetStatusText (" Done. Press any key ...");
2453 return INSTALL_DIRECTORY_PAGE
;
2457 return FORMAT_PARTITION_PAGE
;
2462 CheckFileSystemPage(PINPUT_RECORD Ir
)
2464 WCHAR PathBuffer
[MAX_PATH
];
2466 SetTextXY(6, 8, "Check file system");
2468 SetTextXY(6, 10, "At present, ReactOS can not check file systems.");
2470 SetStatusText(" Please wait ...");
2473 SetStatusText(" ENTER = Continue F3 = Quit");
2476 /* Set DestinationRootPath */
2477 RtlFreeUnicodeString (&DestinationRootPath
);
2478 swprintf (PathBuffer
,
2479 L
"\\Device\\Harddisk%lu\\Partition%lu",
2480 PartitionList
->CurrentDisk
->DiskNumber
,
2481 PartitionList
->CurrentPartition
->PartInfo
[0].PartitionNumber
);
2482 RtlCreateUnicodeString (&DestinationRootPath
,
2484 DPRINT ("DestinationRootPath: %wZ\n", &DestinationRootPath
);
2486 /* Set SystemRootPath */
2487 RtlFreeUnicodeString (&SystemRootPath
);
2488 swprintf (PathBuffer
,
2489 L
"\\Device\\Harddisk%lu\\Partition%lu",
2490 PartitionList
->ActiveBootDisk
->DiskNumber
,
2491 PartitionList
->ActiveBootPartition
->PartInfo
[0].PartitionNumber
);
2492 RtlCreateUnicodeString (&SystemRootPath
,
2494 DPRINT ("SystemRootPath: %wZ\n", &SystemRootPath
);
2497 if (IsUnattendedSetup
)
2499 return(INSTALL_DIRECTORY_PAGE
);
2506 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
2507 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
2509 if (ConfirmQuit(Ir
) == TRUE
)
2513 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2515 return(INSTALL_DIRECTORY_PAGE
);
2519 return(CHECK_FILE_SYSTEM_PAGE
);
2524 InstallDirectoryPage1(PWCHAR InstallDir
, PDISKENTRY DiskEntry
, PPARTENTRY PartEntry
)
2526 WCHAR PathBuffer
[MAX_PATH
];
2528 /* Create 'InstallPath' string */
2529 RtlFreeUnicodeString(&InstallPath
);
2530 RtlCreateUnicodeString(&InstallPath
,
2533 /* Create 'DestinationPath' string */
2534 RtlFreeUnicodeString(&DestinationPath
);
2536 DestinationRootPath
.Buffer
);
2537 if (InstallDir
[0] != L
'\\')
2540 wcscat(PathBuffer
, InstallDir
);
2541 RtlCreateUnicodeString(&DestinationPath
,
2544 /* Create 'DestinationArcPath' */
2545 RtlFreeUnicodeString(&DestinationArcPath
);
2546 swprintf(PathBuffer
,
2547 L
"multi(0)disk(0)rdisk(%lu)partition(%lu)",
2548 DiskEntry
->DiskNumber
,
2549 PartEntry
->PartInfo
[0].PartitionNumber
);
2550 if (InstallDir
[0] != L
'\\')
2553 wcscat(PathBuffer
, InstallDir
);
2554 RtlCreateUnicodeString(&DestinationArcPath
,
2557 return(PREPARE_COPY_PAGE
);
2562 InstallDirectoryPage(PINPUT_RECORD Ir
)
2564 PDISKENTRY DiskEntry
;
2565 PPARTENTRY PartEntry
;
2566 WCHAR InstallDir
[51];
2571 if (PartitionList
== NULL
||
2572 PartitionList
->CurrentDisk
== NULL
||
2573 PartitionList
->CurrentPartition
== NULL
)
2575 /* FIXME: show an error dialog */
2579 DiskEntry
= PartitionList
->CurrentDisk
;
2580 PartEntry
= PartitionList
->CurrentPartition
;
2582 /* Search for 'DefaultPath' in the 'SetupData' section */
2583 if (!InfFindFirstLine (SetupInf
, L
"SetupData", L
"DefaultPath", &Context
))
2585 PopupError("Setup failed to find the 'SetupData' section\n"
2586 "in TXTSETUP.SIF.\n",
2587 "ENTER = Reboot computer");
2593 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2600 /* Read the 'DefaultPath' data */
2601 if (InfGetData (&Context
, NULL
, &DefaultPath
))
2603 wcscpy(InstallDir
, DefaultPath
);
2607 wcscpy(InstallDir
, L
"\\ReactOS");
2609 Length
= wcslen(InstallDir
);
2611 SetTextXY(6, 8, "Setup installs ReactOS files onto the selected partition. Choose a");
2612 SetTextXY(6, 9, "directory where you want ReactOS to be installed:");
2614 SetInputTextXY(8, 11, 51, InstallDir
);
2616 SetTextXY(6, 14, "To change the suggested directory, press BACKSPACE to delete");
2617 SetTextXY(6, 15, "characters and then type the directory where you want ReactOS to");
2618 SetTextXY(6, 16, "be installed.");
2620 SetStatusText(" ENTER = Continue F3 = Quit");
2622 if (IsUnattendedSetup
)
2624 return(InstallDirectoryPage1 (InstallDir
, DiskEntry
, PartEntry
));
2631 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
2632 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
2634 if (ConfirmQuit(Ir
) == TRUE
)
2638 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2640 return (InstallDirectoryPage1 (InstallDir
, DiskEntry
, PartEntry
));
2642 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x08) /* BACKSPACE */
2647 InstallDir
[Length
] = 0;
2648 SetInputTextXY(8, 11, 51, InstallDir
);
2651 else if (isprint(Ir
->Event
.KeyEvent
.uChar
.AsciiChar
))
2655 InstallDir
[Length
] = (WCHAR
)Ir
->Event
.KeyEvent
.uChar
.AsciiChar
;
2657 InstallDir
[Length
] = 0;
2658 SetInputTextXY(8, 11, 51, InstallDir
);
2663 return(INSTALL_DIRECTORY_PAGE
);
2668 PrepareCopyPageInfFile(HINF InfFile
, PWCHAR SourceCabinet
, PINPUT_RECORD Ir
)
2670 WCHAR PathBuffer
[MAX_PATH
];
2671 INFCONTEXT FilesContext
;
2672 INFCONTEXT DirContext
;
2677 PWCHAR FileKeyValue
;
2679 PWCHAR TargetFileName
;
2681 /* Search for the 'SourceFiles' section */
2682 if (!InfFindFirstLine (InfFile
, L
"SourceFiles", NULL
, &FilesContext
))
2684 PopupError("Setup failed to find the 'SourceFiles' section\n"
2685 "in TXTSETUP.SIF.\n", // FIXME
2686 "ENTER = Reboot computer");
2692 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2700 * Enumerate the files in the 'SourceFiles' section
2701 * and add them to the file queue.
2705 /* Get source file name and target directory id */
2706 if (!InfGetData (&FilesContext
, &FileKeyName
, &FileKeyValue
))
2708 /* FIXME: Handle error! */
2709 DPRINT1("InfGetData() failed\n");
2713 /* Get optional target file name */
2714 if (!InfGetDataField (&FilesContext
, 2, &TargetFileName
))
2715 TargetFileName
= NULL
;
2717 DPRINT ("FileKeyName: '%S' FileKeyValue: '%S'\n", FileKeyName
, FileKeyValue
);
2719 /* Lookup target directory */
2720 if (!InfFindFirstLine (InfFile
, L
"Directories", FileKeyValue
, &DirContext
))
2722 /* FIXME: Handle error! */
2723 DPRINT1("InfFindFirstLine() failed\n");
2727 if (!InfGetData (&DirContext
, NULL
, &DirKeyValue
))
2729 /* FIXME: Handle error! */
2730 DPRINT1("InfGetData() failed\n");
2734 if (!SetupQueueCopy(SetupFileQueue
,
2736 SourceRootPath
.Buffer
,
2742 /* FIXME: Handle error! */
2743 DPRINT1("SetupQueueCopy() failed\n");
2746 while (InfFindNextLine(&FilesContext
, &FilesContext
));
2749 /* Create directories */
2753 * Install directories like '\reactos\test' are not handled yet.
2756 /* Get destination path */
2757 wcscpy(PathBuffer
, DestinationPath
.Buffer
);
2759 /* Remove trailing backslash */
2760 Length
= wcslen(PathBuffer
);
2761 if ((Length
> 0) && (PathBuffer
[Length
- 1] == '\\'))
2763 PathBuffer
[Length
- 1] = 0;
2766 /* Create the install directory */
2767 Status
= CreateDirectory(PathBuffer
);
2768 if (!NT_SUCCESS(Status
) && Status
!= STATUS_OBJECT_NAME_COLLISION
)
2770 DPRINT("Creating directory '%S' failed: Status = 0x%08lx", PathBuffer
, Status
);
2771 PopupError("Setup could not create the install directory.",
2772 "ENTER = Reboot computer");
2778 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2786 /* Search for the 'Directories' section */
2787 if (!InfFindFirstLine(InfFile
, L
"Directories", NULL
, &DirContext
))
2791 PopupError("Setup failed to find the 'Directories' section\n"
2792 "in the cabinet.\n", "ENTER = Reboot computer");
2796 PopupError("Setup failed to find the 'Directories' section\n"
2797 "in TXTSETUP.SIF.\n", "ENTER = Reboot computer");
2804 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2811 /* Enumerate the directory values and create the subdirectories */
2814 if (!InfGetData (&DirContext
, NULL
, &KeyValue
))
2820 if (KeyValue
[0] == L
'\\' && KeyValue
[1] != 0)
2822 DPRINT("Absolute Path: '%S'\n", KeyValue
);
2824 wcscpy(PathBuffer
, DestinationRootPath
.Buffer
);
2825 wcscat(PathBuffer
, KeyValue
);
2827 DPRINT("FullPath: '%S'\n", PathBuffer
);
2829 else if (KeyValue
[0] != L
'\\')
2831 DPRINT("RelativePath: '%S'\n", KeyValue
);
2832 wcscpy(PathBuffer
, DestinationPath
.Buffer
);
2833 wcscat(PathBuffer
, L
"\\");
2834 wcscat(PathBuffer
, KeyValue
);
2836 DPRINT("FullPath: '%S'\n", PathBuffer
);
2838 Status
= CreateDirectory(PathBuffer
);
2839 if (!NT_SUCCESS(Status
) && Status
!= STATUS_OBJECT_NAME_COLLISION
)
2841 DPRINT("Creating directory '%S' failed: Status = 0x%08lx", PathBuffer
, Status
);
2842 PopupError("Setup could not create install directories.",
2843 "ENTER = Reboot computer");
2849 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2857 while (InfFindNextLine (&DirContext
, &DirContext
));
2864 PrepareCopyPage(PINPUT_RECORD Ir
)
2867 WCHAR PathBuffer
[MAX_PATH
];
2868 INFCONTEXT CabinetsContext
;
2875 SetTextXY(6, 8, "Setup prepares your computer for copying the ReactOS files. ");
2879 * Build the file copy list
2881 SetStatusText(" Building the file copy list...");
2883 /* Create the file queue */
2884 SetupFileQueue
= SetupOpenFileQueue();
2885 if (SetupFileQueue
== NULL
)
2887 PopupError("Setup failed to open the copy file queue.\n",
2888 "ENTER = Reboot computer");
2894 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2902 if (!PrepareCopyPageInfFile(SetupInf
, NULL
, Ir
))
2908 /* Search for the 'Cabinets' section */
2909 if (!InfFindFirstLine (SetupInf
, L
"Cabinets", NULL
, &CabinetsContext
))
2911 PopupError("Setup failed to find the 'Cabinets' section\n"
2912 "in TXTSETUP.SIF.\n",
2913 "ENTER = Reboot computer");
2919 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2928 * Enumerate the directory values in the 'Cabinets'
2929 * section and parse their inf files.
2933 if (!InfGetData (&CabinetsContext
, NULL
, &KeyValue
))
2936 wcscpy(PathBuffer
, SourcePath
.Buffer
);
2937 wcscat(PathBuffer
, L
"\\");
2938 wcscat(PathBuffer
, KeyValue
);
2940 CabinetInitialize();
2941 CabinetSetEventHandlers(NULL
, NULL
, NULL
);
2942 CabinetSetCabinetName(PathBuffer
);
2944 if (CabinetOpen() == CAB_STATUS_SUCCESS
)
2946 DPRINT("Cabinet %S\n", CabinetGetCabinetName());
2948 InfFileData
= CabinetGetCabinetReservedArea(&InfFileSize
);
2949 if (InfFileData
== NULL
)
2951 PopupError("Cabinet has no setup script.\n",
2952 "ENTER = Reboot computer");
2958 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2967 DPRINT("Cannot open cabinet: %S.\n", CabinetGetCabinetName());
2969 PopupError("Cabinet not found.\n",
2970 "ENTER = Reboot computer");
2976 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2983 Status
= InfOpenBufferedFile(&InfHandle
,
2987 if (!NT_SUCCESS(Status
))
2989 PopupError("Cabinet has no valid inf file.\n",
2990 "ENTER = Reboot computer");
2996 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
3005 if (!PrepareCopyPageInfFile(InfHandle
, KeyValue
, Ir
))
3010 while (InfFindNextLine (&CabinetsContext
, &CabinetsContext
));
3012 return(FILE_COPY_PAGE
);
3017 FileCopyCallback(PVOID Context
,
3022 PCOPYCONTEXT CopyContext
;
3024 CopyContext
= (PCOPYCONTEXT
)Context
;
3026 switch (Notification
)
3028 case SPFILENOTIFY_STARTSUBQUEUE
:
3029 CopyContext
->TotalOperations
= (ULONG
)Param2
;
3030 ProgressSetStepCount(CopyContext
->ProgressBar
,
3031 CopyContext
->TotalOperations
);
3034 case SPFILENOTIFY_STARTCOPY
:
3035 /* Display copy message */
3036 PrintTextXYN(6, 16, 60, "Copying file: %S", (PWSTR
)Param1
);
3038 PrintTextXYN(6, 18, 60, "File %lu of %lu",
3039 CopyContext
->CompletedOperations
+ 1,
3040 CopyContext
->TotalOperations
);
3043 case SPFILENOTIFY_ENDCOPY
:
3044 CopyContext
->CompletedOperations
++;
3045 ProgressNextStep(CopyContext
->ProgressBar
);
3054 FileCopyPage(PINPUT_RECORD Ir
)
3056 COPYCONTEXT CopyContext
;
3060 SetStatusText(" Please wait...");
3062 SetTextXY(6, 8, "Copying files");
3064 GetScreenSize(&xScreen
, &yScreen
);
3066 CopyContext
.TotalOperations
= 0;
3067 CopyContext
.CompletedOperations
= 0;
3068 CopyContext
.ProgressBar
= CreateProgressBar(6,
3073 SetupCommitFileQueue(SetupFileQueue
,
3074 DestinationRootPath
.Buffer
,
3076 (PSP_FILE_CALLBACK
)FileCopyCallback
,
3079 SetupCloseFileQueue(SetupFileQueue
);
3081 DestroyProgressBar(CopyContext
.ProgressBar
);
3083 return(REGISTRY_PAGE
);
3088 RegistryPage(PINPUT_RECORD Ir
)
3090 INFCONTEXT InfContext
;
3099 SetTextXY(6, 8, "Setup is updating the system configuration");
3101 SetStatusText(" Creating registry hives...");
3103 if (!SetInstallPathValue(&DestinationPath
))
3105 DPRINT("SetInstallPathValue() failed\n");
3106 PopupError("Setup failed to set the initialize the registry.",
3107 "ENTER = Reboot computer");
3113 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
3120 /* Create the default hives */
3121 Status
= NtInitializeRegistry(TRUE
);
3122 if (!NT_SUCCESS(Status
))
3124 DPRINT("NtInitializeRegistry() failed (Status %lx)\n", Status
);
3125 PopupError("Setup failed to create the registry hives.",
3126 "ENTER = Reboot computer");
3132 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
3139 /* Update registry */
3140 SetStatusText(" Updating registry hives...");
3142 if (!InfFindFirstLine(SetupInf
, L
"HiveInfs.Install", NULL
, &InfContext
))
3144 DPRINT1("InfFindFirstLine() failed\n");
3145 PopupError("Setup failed to find the registry data files.",
3146 "ENTER = Reboot computer");
3152 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
3161 InfGetDataField (&InfContext
, 0, &Action
);
3162 InfGetDataField (&InfContext
, 1, &File
);
3163 InfGetDataField (&InfContext
, 2, &Section
);
3165 DPRINT1("Action: %S File: %S Section %S\n", Action
, File
, Section
);
3167 if (!_wcsicmp (Action
, L
"AddReg"))
3171 else if (!_wcsicmp (Action
, L
"DelReg"))
3180 SetStatusText(" Importing %S...", File
);
3182 if (!ImportRegistryFile(File
, Section
, Delete
))
3184 DPRINT1("Importing %S failed\n", File
);
3186 PopupError("Setup failed to import a hive file.",
3187 "ENTER = Reboot computer");
3193 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
3200 while (InfFindNextLine (&InfContext
, &InfContext
));
3202 SetStatusText(" Done...");
3204 return(BOOT_LOADER_PAGE
);
3209 BootLoaderPage(PINPUT_RECORD Ir
)
3211 WCHAR SrcPath
[MAX_PATH
];
3212 WCHAR DstPath
[MAX_PATH
];
3215 SetTextXY(6, 8, "Installing the boot loader");
3217 SetStatusText(" Please wait...");
3219 if (PartitionList
->ActiveBootPartition
->PartInfo
[0].PartitionType
== PARTITION_ENTRY_UNUSED
)
3221 DPRINT1("Error: active partition invalid (unused)\n");
3222 PopupError("The active partition is unused (invalid).\n",
3223 "ENTER = Reboot computer");
3229 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
3236 if (PartitionList
->ActiveBootPartition
->PartInfo
[0].PartitionType
== 0x0A)
3238 /* OS/2 boot manager partition */
3239 DPRINT1("Found OS/2 boot manager partition\n");
3240 PopupError("Setup found an OS/2 boot manager partiton.\n"
3241 "The OS/2 boot manager is not supported yet!",
3242 "ENTER = Reboot computer");
3248 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
3254 else if (PartitionList
->ActiveBootPartition
->PartInfo
[0].PartitionType
== 0x83)
3256 /* Linux ext2 partition */
3257 DPRINT1("Found Linux ext2 partition\n");
3258 PopupError("Setup found a Linux ext2 partiton.\n"
3259 "Linux ext2 partitions are not supported yet!",
3260 "ENTER = Reboot computer");
3266 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
3272 else if (PartitionList
->ActiveBootPartition
->PartInfo
[0].PartitionType
== PARTITION_IFS
)
3274 /* NTFS partition */
3275 DPRINT1("Found NTFS partition\n");
3276 PopupError("Setup found an NTFS partiton.\n"
3277 "NTFS partitions are not supported yet!",
3278 "ENTER = Reboot computer");
3284 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
3290 else if ((PartitionList
->ActiveBootPartition
->PartInfo
[0].PartitionType
== PARTITION_FAT_12
) ||
3291 (PartitionList
->ActiveBootPartition
->PartInfo
[0].PartitionType
== PARTITION_FAT_16
) ||
3292 (PartitionList
->ActiveBootPartition
->PartInfo
[0].PartitionType
== PARTITION_HUGE
) ||
3293 (PartitionList
->ActiveBootPartition
->PartInfo
[0].PartitionType
== PARTITION_XINT13
) ||
3294 (PartitionList
->ActiveBootPartition
->PartInfo
[0].PartitionType
== PARTITION_FAT32
) ||
3295 (PartitionList
->ActiveBootPartition
->PartInfo
[0].PartitionType
== PARTITION_FAT32_XINT13
))
3297 /* FAT or FAT32 partition */
3298 DPRINT1("System path: '%wZ'\n", &SystemRootPath
);
3300 if (DoesFileExist(SystemRootPath
.Buffer
, L
"ntldr") == TRUE
||
3301 DoesFileExist(SystemRootPath
.Buffer
, L
"boot.ini") == TRUE
)
3303 /* Search root directory for 'ntldr' and 'boot.ini'. */
3304 DPRINT1("Found Microsoft Windows NT/2000/XP boot loader\n");
3306 /* Copy FreeLoader to the boot partition */
3307 wcscpy(SrcPath
, SourceRootPath
.Buffer
);
3308 wcscat(SrcPath
, L
"\\loader\\freeldr.sys");
3309 wcscpy(DstPath
, SystemRootPath
.Buffer
);
3310 wcscat(DstPath
, L
"\\freeldr.sys");
3312 DPRINT1("Copy: %S ==> %S\n", SrcPath
, DstPath
);
3313 Status
= SetupCopyFile(SrcPath
, DstPath
);
3314 if (!NT_SUCCESS(Status
))
3316 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status
);
3317 PopupError("Setup failed to copy 'freeldr.sys'.",
3318 "ENTER = Reboot computer");
3324 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
3331 /* Create or update freeldr.ini */
3332 if (DoesFileExist(SystemRootPath
.Buffer
, L
"freeldr.ini") == FALSE
)
3334 /* Create new 'freeldr.ini' */
3335 DPRINT1("Create new 'freeldr.ini'\n");
3336 wcscpy(DstPath
, SystemRootPath
.Buffer
);
3337 wcscat(DstPath
, L
"\\freeldr.ini");
3339 Status
= CreateFreeLoaderIniForReactos(DstPath
,
3340 DestinationArcPath
.Buffer
);
3341 if (!NT_SUCCESS(Status
))
3343 DPRINT1("CreateFreeLoaderIniForReactos() failed (Status %lx)\n", Status
);
3344 PopupError("Setup failed to create 'freeldr.ini'.",
3345 "ENTER = Reboot computer");
3351 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
3358 /* Install new bootcode */
3359 if ((PartitionList
->ActiveBootPartition
->PartInfo
[0].PartitionType
== PARTITION_FAT32
) ||
3360 (PartitionList
->ActiveBootPartition
->PartInfo
[0].PartitionType
== PARTITION_FAT32_XINT13
))
3362 /* Install FAT32 bootcode */
3363 wcscpy(SrcPath
, SourceRootPath
.Buffer
);
3364 wcscat(SrcPath
, L
"\\loader\\fat32.bin");
3365 wcscpy(DstPath
, SystemRootPath
.Buffer
);
3366 wcscat(DstPath
, L
"\\bootsect.ros");
3368 DPRINT1("Install FAT32 bootcode: %S ==> %S\n", SrcPath
, DstPath
);
3369 Status
= InstallFat32BootCodeToFile(SrcPath
,
3371 SystemRootPath
.Buffer
);
3372 if (!NT_SUCCESS(Status
))
3374 DPRINT1("InstallFat32BootCodeToFile() failed (Status %lx)\n", Status
);
3375 PopupError("Setup failed to install the FAT32 bootcode.",
3376 "ENTER = Reboot computer");
3382 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
3391 /* Install FAT16 bootcode */
3392 wcscpy(SrcPath
, SourceRootPath
.Buffer
);
3393 wcscat(SrcPath
, L
"\\loader\\fat.bin");
3394 wcscpy(DstPath
, SystemRootPath
.Buffer
);
3395 wcscat(DstPath
, L
"\\bootsect.ros");
3397 DPRINT1("Install FAT bootcode: %S ==> %S\n", SrcPath
, DstPath
);
3398 Status
= InstallFat16BootCodeToFile(SrcPath
,
3400 SystemRootPath
.Buffer
);
3401 if (!NT_SUCCESS(Status
))
3403 DPRINT1("InstallFat16BootCodeToFile() failed (Status %lx)\n", Status
);
3404 PopupError("Setup failed to install the FAT bootcode.",
3405 "ENTER = Reboot computer");
3411 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
3419 /* Update 'boot.ini' */
3420 wcscpy(DstPath
, SystemRootPath
.Buffer
);
3421 wcscat(DstPath
, L
"\\boot.ini");
3423 DPRINT1("Update 'boot.ini': %S\n", DstPath
);
3424 Status
= UpdateBootIni(DstPath
,
3425 L
"C:\\bootsect.ros",
3427 if (!NT_SUCCESS(Status
))
3429 DPRINT1("UpdateBootIni() failed (Status %lx)\n", Status
);
3430 PopupError("Setup failed to update \'boot.ini\'.",
3431 "ENTER = Reboot computer");
3437 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
3446 /* Update existing 'freeldr.ini' */
3447 DPRINT1("Update existing 'freeldr.ini'\n");
3448 wcscpy(DstPath
, SystemRootPath
.Buffer
);
3449 wcscat(DstPath
, L
"\\freeldr.ini");
3451 Status
= UpdateFreeLoaderIni(DstPath
,
3452 DestinationArcPath
.Buffer
);
3453 if (!NT_SUCCESS(Status
))
3455 DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status
);
3456 PopupError("Setup failed to update 'freeldr.ini'.",
3457 "ENTER = Reboot computer");
3463 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
3471 else if (DoesFileExist(SystemRootPath
.Buffer
, L
"io.sys") == TRUE
||
3472 DoesFileExist(SystemRootPath
.Buffer
, L
"msdos.sys") == TRUE
)
3474 /* Search for root directory for 'io.sys' and 'msdos.sys'. */
3475 DPRINT1("Found Microsoft DOS or Windows 9x boot loader\n");
3477 /* Copy FreeLoader to the boot partition */
3478 wcscpy(SrcPath
, SourceRootPath
.Buffer
);
3479 wcscat(SrcPath
, L
"\\loader\\freeldr.sys");
3480 wcscpy(DstPath
, SystemRootPath
.Buffer
);
3481 wcscat(DstPath
, L
"\\freeldr.sys");
3483 DPRINT("Copy: %S ==> %S\n", SrcPath
, DstPath
);
3484 Status
= SetupCopyFile(SrcPath
, DstPath
);
3485 if (!NT_SUCCESS(Status
))
3487 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status
);
3488 PopupError("Setup failed to copy 'freeldr.sys'.",
3489 "ENTER = Reboot computer");
3495 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
3502 /* Create or update 'freeldr.ini' */
3503 if (DoesFileExist(SystemRootPath
.Buffer
, L
"freeldr.ini") == FALSE
)
3505 /* Create new 'freeldr.ini' */
3506 DPRINT1("Create new 'freeldr.ini'\n");
3507 wcscpy(DstPath
, SystemRootPath
.Buffer
);
3508 wcscat(DstPath
, L
"\\freeldr.ini");
3510 Status
= CreateFreeLoaderIniForDos(DstPath
,
3511 DestinationArcPath
.Buffer
);
3512 if (!NT_SUCCESS(Status
))
3514 DPRINT1("CreateFreeLoaderIniForDos() failed (Status %lx)\n", Status
);
3515 PopupError("Setup failed to create 'freeldr.ini'.",
3516 "ENTER = Reboot computer");
3522 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
3529 /* Save current bootsector as 'BOOTSECT.DOS' */
3530 wcscpy(SrcPath
, SystemRootPath
.Buffer
);
3531 wcscpy(DstPath
, SystemRootPath
.Buffer
);
3532 wcscat(DstPath
, L
"\\bootsect.dos");
3534 DPRINT1("Save bootsector: %S ==> %S\n", SrcPath
, DstPath
);
3535 Status
= SaveCurrentBootSector(SrcPath
,
3537 if (!NT_SUCCESS(Status
))
3539 DPRINT1("SaveCurrentBootSector() failed (Status %lx)\n", Status
);
3540 PopupError("Setup failed to save the current bootsector.",
3541 "ENTER = Reboot computer");
3547 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
3554 /* Install new bootsector */
3555 if ((PartitionList
->ActiveBootPartition
->PartInfo
[0].PartitionType
== PARTITION_FAT32
) ||
3556 (PartitionList
->ActiveBootPartition
->PartInfo
[0].PartitionType
== PARTITION_FAT32_XINT13
))
3558 wcscpy(SrcPath
, SourceRootPath
.Buffer
);
3559 wcscat(SrcPath
, L
"\\loader\\fat32.bin");
3561 DPRINT1("Install FAT32 bootcode: %S ==> %S\n", SrcPath
, SystemRootPath
.Buffer
);
3562 Status
= InstallFat32BootCodeToDisk(SrcPath
,
3563 SystemRootPath
.Buffer
);
3564 if (!NT_SUCCESS(Status
))
3566 DPRINT1("InstallFat32BootCodeToDisk() failed (Status %lx)\n", Status
);
3567 PopupError("Setup failed to install the FAT32 bootcode.",
3568 "ENTER = Reboot computer");
3574 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
3583 wcscpy(SrcPath
, SourceRootPath
.Buffer
);
3584 wcscat(SrcPath
, L
"\\loader\\fat.bin");
3586 DPRINT1("Install FAT bootcode: %S ==> %S\n", SrcPath
, SystemRootPath
.Buffer
);
3587 Status
= InstallFat16BootCodeToDisk(SrcPath
,
3588 SystemRootPath
.Buffer
);
3589 if (!NT_SUCCESS(Status
))
3591 DPRINT1("InstallFat16BootCodeToDisk() failed (Status %lx)\n", Status
);
3592 PopupError("Setup failed to install the FAT bootcode.",
3593 "ENTER = Reboot computer");
3599 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
3609 /* Update existing 'freeldr.ini' */
3610 wcscpy(DstPath
, SystemRootPath
.Buffer
);
3611 wcscat(DstPath
, L
"\\freeldr.ini");
3613 Status
= UpdateFreeLoaderIni(DstPath
,
3614 DestinationArcPath
.Buffer
);
3615 if (!NT_SUCCESS(Status
))
3617 DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status
);
3618 PopupError("Setup failed to update 'freeldr.ini'.",
3619 "ENTER = Reboot computer");
3625 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
3635 /* No or unknown boot loader */
3636 DPRINT1("No or unknown boot loader found\n");
3638 /* Copy FreeLoader to the boot partition */
3639 wcscpy(SrcPath
, SourceRootPath
.Buffer
);
3640 wcscat(SrcPath
, L
"\\loader\\freeldr.sys");
3641 wcscpy(DstPath
, SystemRootPath
.Buffer
);
3642 wcscat(DstPath
, L
"\\freeldr.sys");
3644 DPRINT1("Copy: %S ==> %S\n", SrcPath
, DstPath
);
3645 Status
= SetupCopyFile(SrcPath
, DstPath
);
3646 if (!NT_SUCCESS(Status
))
3648 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status
);
3649 PopupError("Setup failed to copy 'freeldr.sys'.",
3650 "ENTER = Reboot computer");
3656 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
3663 /* Create or update 'freeldr.ini' */
3664 if (DoesFileExist(SystemRootPath
.Buffer
, L
"freeldr.ini") == FALSE
)
3666 /* Create new freeldr.ini */
3667 wcscpy(DstPath
, SystemRootPath
.Buffer
);
3668 wcscat(DstPath
, L
"\\freeldr.ini");
3670 DPRINT1("Copy: %S ==> %S\n", SrcPath
, DstPath
);
3671 Status
= CreateFreeLoaderIniForReactos(DstPath
,
3672 DestinationArcPath
.Buffer
);
3673 if (!NT_SUCCESS(Status
))
3675 DPRINT1("CreateFreeLoaderIniForReactos() failed (Status %lx)\n", Status
);
3676 PopupError("Setup failed to create \'freeldr.ini\'.",
3677 "ENTER = Reboot computer");
3683 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
3690 /* Save current bootsector as 'BOOTSECT.OLD' */
3691 wcscpy(SrcPath
, SystemRootPath
.Buffer
);
3692 wcscpy(DstPath
, SystemRootPath
.Buffer
);
3693 wcscat(DstPath
, L
"\\bootsect.old");
3695 DPRINT1("Save bootsector: %S ==> %S\n", SrcPath
, DstPath
);
3696 Status
= SaveCurrentBootSector(SrcPath
,
3698 if (!NT_SUCCESS(Status
))
3700 DPRINT1("SaveCurrentBootSector() failed (Status %lx)\n", Status
);
3701 PopupError("Setup failed save the current bootsector.",
3702 "ENTER = Reboot computer");
3708 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
3715 /* Install new bootsector */
3716 if ((PartitionList
->ActiveBootPartition
->PartInfo
[0].PartitionType
== PARTITION_FAT32
) ||
3717 (PartitionList
->ActiveBootPartition
->PartInfo
[0].PartitionType
== PARTITION_FAT32_XINT13
))
3719 wcscpy(SrcPath
, SourceRootPath
.Buffer
);
3720 wcscat(SrcPath
, L
"\\loader\\fat32.bin");
3722 DPRINT1("Install FAT32 bootcode: %S ==> %S\n", SrcPath
, SystemRootPath
.Buffer
);
3723 Status
= InstallFat32BootCodeToDisk(SrcPath
,
3724 SystemRootPath
.Buffer
);
3725 if (!NT_SUCCESS(Status
))
3727 DPRINT1("InstallFat32BootCodeToDisk() failed (Status %lx)\n", Status
);
3728 PopupError("Setup failed to install the FAT32 bootcode.",
3729 "ENTER = Reboot computer");
3735 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
3744 wcscpy(SrcPath
, SourceRootPath
.Buffer
);
3745 wcscat(SrcPath
, L
"\\loader\\fat.bin");
3747 DPRINT1("Install FAT bootcode: %S ==> %S\n", SrcPath
, SystemRootPath
.Buffer
);
3748 Status
= InstallFat16BootCodeToDisk(SrcPath
,
3749 SystemRootPath
.Buffer
);
3750 if (!NT_SUCCESS(Status
))
3752 DPRINT1("InstallFat16BootCodeToDisk() failed (Status %lx)\n", Status
);
3753 PopupError("Setup failed to install the FAT bootcode.",
3754 "ENTER = Reboot computer");
3760 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
3770 /* Update existing 'freeldr.ini' */
3771 wcscpy(DstPath
, SystemRootPath
.Buffer
);
3772 wcscat(DstPath
, L
"\\freeldr.ini");
3774 Status
= UpdateFreeLoaderIni(DstPath
,
3775 DestinationArcPath
.Buffer
);
3776 if (!NT_SUCCESS(Status
))
3778 DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status
);
3779 PopupError("Setup failed to update 'freeldr.ini'.",
3780 "ENTER = Reboot computer");
3786 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
3797 /* Unknown partition */
3798 DPRINT1("Unknown partition found\n");
3799 PopupError("Setup found an unknown partiton type.\n"
3800 "This partition type is not supported!",
3801 "ENTER = Reboot computer");
3807 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
3814 return SUCCESS_PAGE
;
3819 QuitPage(PINPUT_RECORD Ir
)
3821 SetTextXY(10, 6, "ReactOS is not completely installed");
3823 SetTextXY(10, 8, "Remove floppy disk from Drive A: and");
3824 SetTextXY(10, 9, "all CD-ROMs from CD-Drives.");
3826 SetTextXY(10, 11, "Press ENTER to reboot your computer.");
3828 SetStatusText(" Please wait ...");
3830 /* Destroy partition list */
3831 if (PartitionList
!= NULL
)
3833 DestroyPartitionList (PartitionList
);
3834 PartitionList
= NULL
;
3837 /* Destroy filesystem list */
3838 if (FileSystemList
!= NULL
)
3840 DestroyFileSystemList (FileSystemList
);
3841 FileSystemList
= NULL
;
3844 /* Destroy computer settings list */
3845 if (ComputerList
!= NULL
)
3847 DestroyGenericList(ComputerList
, TRUE
);
3848 ComputerList
= NULL
;
3851 /* Destroy display settings list */
3852 if (DisplayList
!= NULL
)
3854 DestroyGenericList(DisplayList
, TRUE
);
3858 /* Destroy keyboard settings list */
3859 if (KeyboardList
!= NULL
)
3861 DestroyGenericList(KeyboardList
, TRUE
);
3862 KeyboardList
= NULL
;
3865 /* Destroy keyboard layout list */
3866 if (LayoutList
!= NULL
)
3868 DestroyGenericList(LayoutList
, TRUE
);
3872 /* Destroy pointer device list */
3873 if (PointerList
!= NULL
)
3875 DestroyGenericList(PointerList
, TRUE
);
3879 SetStatusText(" ENTER = Reboot computer");
3885 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
3894 SuccessPage(PINPUT_RECORD Ir
)
3896 SetTextXY(10, 6, "The basic components of ReactOS have been installed successfully.");
3898 SetTextXY(10, 8, "Remove floppy disk from Drive A: and");
3899 SetTextXY(10, 9, "all CD-ROMs from CD-Drive.");
3901 SetTextXY(10, 11, "Press ENTER to reboot your computer.");
3903 SetStatusText(" ENTER = Reboot computer");
3905 if (IsUnattendedSetup
)
3914 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
3923 FlushPage(PINPUT_RECORD Ir
)
3925 SetTextXY(10, 6, "The system is now making sure all data is stored on your disk");
3927 SetTextXY(10, 8, "This may take a minute");
3928 SetTextXY(10, 9, "When finished, your computer will reboot automatically");
3930 SetStatusText(" Flushing cache");
3937 NtProcessStartup(PPEB Peb
)
3943 RtlNormalizeProcessParams(Peb
->ProcessParameters
);
3945 ProcessHeap
= Peb
->ProcessHeap
;
3947 Status
= AllocConsole();
3948 if (!NT_SUCCESS(Status
))
3950 PrintString("AllocConsole() failed (Status = 0x%08lx)\n", Status
);
3952 /* Raise a hard error (crash the system/BSOD) */
3953 NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED
,
3958 /* Initialize global unicode strings */
3959 RtlInitUnicodeString(&SourcePath
, NULL
);
3960 RtlInitUnicodeString(&SourceRootPath
, NULL
);
3961 RtlInitUnicodeString(&InstallPath
, NULL
);
3962 RtlInitUnicodeString(&DestinationPath
, NULL
);
3963 RtlInitUnicodeString(&DestinationArcPath
, NULL
);
3964 RtlInitUnicodeString(&DestinationRootPath
, NULL
);
3965 RtlInitUnicodeString(&SystemRootPath
, NULL
);
3967 /* Hide the cursor */
3968 SetCursorType(TRUE
, FALSE
);
3971 while (Page
!= REBOOT_PAGE
)
3975 SetUnderlinedTextXY(4, 3, " ReactOS " KERNEL_VERSION_STR
" Setup ");
3981 Page
= StartPage(&Ir
);
3986 Page
= IntroPage(&Ir
);
3990 case INSTALL_INTRO_PAGE
:
3991 Page
= InstallIntroPage(&Ir
);
3995 case OEM_DRIVER_PAGE
:
3996 Page
= OemDriverPage(&Ir
);
4000 case DEVICE_SETTINGS_PAGE
:
4001 Page
= DeviceSettingsPage(&Ir
);
4004 case COMPUTER_SETTINGS_PAGE
:
4005 Page
= ComputerSettingsPage(&Ir
);
4008 case DISPLAY_SETTINGS_PAGE
:
4009 Page
= DisplaySettingsPage(&Ir
);
4012 case KEYBOARD_SETTINGS_PAGE
:
4013 Page
= KeyboardSettingsPage(&Ir
);
4016 case LAYOUT_SETTINGS_PAGE
:
4017 Page
= LayoutSettingsPage(&Ir
);
4020 case POINTER_SETTINGS_PAGE
:
4021 Page
= PointerSettingsPage(&Ir
);
4024 case SELECT_PARTITION_PAGE
:
4025 Page
= SelectPartitionPage(&Ir
);
4028 case CREATE_PARTITION_PAGE
:
4029 Page
= CreatePartitionPage(&Ir
);
4032 case DELETE_PARTITION_PAGE
:
4033 Page
= DeletePartitionPage(&Ir
);
4036 case SELECT_FILE_SYSTEM_PAGE
:
4037 Page
= SelectFileSystemPage(&Ir
);
4040 case FORMAT_PARTITION_PAGE
:
4041 Page
= FormatPartitionPage(&Ir
);
4044 case CHECK_FILE_SYSTEM_PAGE
:
4045 Page
= CheckFileSystemPage(&Ir
);
4048 case INSTALL_DIRECTORY_PAGE
:
4049 Page
= InstallDirectoryPage(&Ir
);
4052 case PREPARE_COPY_PAGE
:
4053 Page
= PrepareCopyPage(&Ir
);
4056 case FILE_COPY_PAGE
:
4057 Page
= FileCopyPage(&Ir
);
4061 Page
= RegistryPage(&Ir
);
4064 case BOOT_LOADER_PAGE
:
4065 Page
= BootLoaderPage(&Ir
);
4070 case REPAIR_INTRO_PAGE
:
4071 Page
= RepairIntroPage(&Ir
);
4075 /* Emergency pages */
4076 case EMERGENCY_INTRO_PAGE
:
4077 Page
= EmergencyIntroPage(&Ir
);
4082 Page
= SuccessPage(&Ir
);
4086 Page
= FlushPage(&Ir
);
4090 Page
= QuitPage(&Ir
);
4100 NtShutdownSystem(ShutdownReboot
);