3 * Copyright (C) 2002, 2003 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"
51 typedef enum _PAGE_NUMBER
57 SELECT_PARTITION_PAGE
,
58 CREATE_PARTITION_PAGE
,
59 DELETE_PARTITION_PAGE
,
61 SELECT_FILE_SYSTEM_PAGE
,
62 FORMAT_PARTITION_PAGE
,
63 CHECK_FILE_SYSTEM_PAGE
,
66 INSTALL_DIRECTORY_PAGE
,
77 REBOOT_PAGE
, /* virtual page */
78 } PAGE_NUMBER
, *PPAGE_NUMBER
;
80 typedef struct _COPYCONTEXT
82 ULONG TotalOperations
;
83 ULONG CompletedOperations
;
84 PPROGRESS ProgressBar
;
85 } COPYCONTEXT
, *PCOPYCONTEXT
;
88 /* GLOBALS ******************************************************************/
91 UNICODE_STRING SourceRootPath
;
94 /* LOCALS *******************************************************************/
96 static PPARTLIST PartitionList
= NULL
;
98 static PFILE_SYSTEM_LIST FileSystemList
= NULL
;
101 static UNICODE_STRING SourcePath
;
103 static UNICODE_STRING InstallPath
;
105 /* Path to the install directory */
106 static UNICODE_STRING DestinationPath
;
107 static UNICODE_STRING DestinationArcPath
;
108 static UNICODE_STRING DestinationRootPath
;
110 /* Path to the active partition (boot manager) */
111 static UNICODE_STRING SystemRootPath
;
113 static HINF SetupInf
;
115 static HSPFILEQ SetupFileQueue
= NULL
;
117 static BOOLEAN WarnLinuxPartitions
= TRUE
;
120 /* FUNCTIONS ****************************************************************/
123 PrintString(char* fmt
,...)
127 UNICODE_STRING UnicodeString
;
128 ANSI_STRING AnsiString
;
131 vsprintf(buffer
, fmt
, ap
);
134 RtlInitAnsiString(&AnsiString
, buffer
);
135 RtlAnsiStringToUnicodeString(&UnicodeString
,
138 NtDisplayString(&UnicodeString
);
139 RtlFreeUnicodeString(&UnicodeString
);
144 PopupError(PCHAR Text
,
162 /* Count text lines and longest line */
168 p
= strchr(pnext
, '\n');
171 Length
= strlen(pnext
);
176 Length
= (ULONG
)(p
- pnext
);
181 if (Length
> MaxLength
)
184 if (LastLine
== TRUE
)
190 /* Check length of status line */
193 Length
= strlen(Status
);
194 if (Length
> MaxLength
)
198 GetScreenSize(&xScreen
, &yScreen
);
200 Width
= MaxLength
+ 4;
205 yTop
= (yScreen
- Height
) / 2;
206 xLeft
= (xScreen
- Width
) / 2;
209 /* Set screen attributes */
211 for (coPos
.Y
= yTop
; coPos
.Y
< yTop
+ Height
; coPos
.Y
++)
213 FillConsoleOutputAttribute(0x74,
219 /* draw upper left corner */
222 FillConsoleOutputCharacter(0xDA, // '+',
227 /* draw upper edge */
230 FillConsoleOutputCharacter(0xC4, // '-',
235 /* draw upper right corner */
236 coPos
.X
= xLeft
+ Width
- 1;
238 FillConsoleOutputCharacter(0xBF, // '+',
243 /* Draw right edge, inner space and left edge */
244 for (coPos
.Y
= yTop
+ 1; coPos
.Y
< yTop
+ Height
- 1; coPos
.Y
++)
247 FillConsoleOutputCharacter(0xB3, // '|',
253 FillConsoleOutputCharacter(' ',
258 coPos
.X
= xLeft
+ Width
- 1;
259 FillConsoleOutputCharacter(0xB3, // '|',
265 /* draw lower left corner */
267 coPos
.Y
= yTop
+ Height
- 1;
268 FillConsoleOutputCharacter(0xC0, // '+',
273 /* draw lower edge */
275 coPos
.Y
= yTop
+ Height
- 1;
276 FillConsoleOutputCharacter(0xC4, // '-',
281 /* draw lower right corner */
282 coPos
.X
= xLeft
+ Width
- 1;
283 coPos
.Y
= yTop
+ Height
- 1;
284 FillConsoleOutputCharacter(0xD9, // '+',
289 /* Print message text */
294 p
= strchr(pnext
, '\n');
297 Length
= strlen(pnext
);
302 Length
= (ULONG
)(p
- pnext
);
309 WriteConsoleOutputCharacters(pnext
,
314 if (LastLine
== TRUE
)
321 /* Print separator line and status text */
324 coPos
.Y
= yTop
+ Height
- 3;
326 FillConsoleOutputCharacter(0xC3, // '+',
332 FillConsoleOutputCharacter(0xC4, // '-',
337 coPos
.X
= xLeft
+ Width
- 1;
338 FillConsoleOutputCharacter(0xB4, // '+',
345 WriteConsoleOutputCharacters(Status
,
346 min(strlen(Status
), Width
- 4),
356 * FALSE: Don't quit setup.
359 ConfirmQuit(PINPUT_RECORD Ir
)
363 PopupError("ReactOS is not completely installed on your\n"
364 "computer. If you quit Setup now, you will need to\n"
365 "run Setup again to install ReactOS.\n"
367 " \x07 Press ENTER to continue Setup.\n"
368 " \x07 Press F3 to quit Setup.",
369 "F3= Quit ENTER = Continue");
375 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
376 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
381 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
396 * Number of the next page.
399 StartPage(PINPUT_RECORD Ir
)
402 WCHAR FileNameBuffer
[MAX_PATH
];
403 UNICODE_STRING FileName
;
408 SetStatusText(" Please wait...");
410 Status
= GetSourcePaths(&SourcePath
,
412 if (!NT_SUCCESS(Status
))
414 PrintTextXY(6, 15, "GetSourcePath() failed (Status 0x%08lx)", Status
);
415 PopupError("Setup could not find its source drive.\n",
416 "ENTER = Reboot computer");
421 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
430 PrintTextXY(6, 15, "SourcePath: '%wZ'", &SourcePath
);
431 PrintTextXY(6, 16, "SourceRootPath: '%wZ'", &SourceRootPath
);
435 /* Load txtsetup.sif from install media. */
436 wcscpy(FileNameBuffer
, SourceRootPath
.Buffer
);
437 wcscat(FileNameBuffer
, L
"\\reactos\\txtsetup.sif");
438 RtlInitUnicodeString(&FileName
,
441 Status
= InfOpenFile(&SetupInf
,
444 if (!NT_SUCCESS(Status
))
446 PopupError("Setup failed to load the file TXTSETUP.SIF.\n",
447 "ENTER = Reboot computer");
453 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
460 /* Open 'Version' section */
461 if (!InfFindFirstLine (SetupInf
, L
"Version", L
"Signature", &Context
))
463 PopupError("Setup found a corrupt TXTSETUP.SIF.\n",
464 "ENTER = Reboot computer");
470 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
478 /* Get pointer 'Signature' key */
479 if (!InfGetData (&Context
, NULL
, &Value
))
481 PopupError("Setup found a corrupt TXTSETUP.SIF.\n",
482 "ENTER = Reboot computer");
488 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
495 /* Check 'Signature' string */
496 if (_wcsicmp(Value
, L
"$ReactOS$") != 0)
498 PopupError("Setup found an invalid signature in TXTSETUP.SIF.\n",
499 "ENTER = Reboot computer");
505 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
522 IntroPage(PINPUT_RECORD Ir
)
524 SetHighlightedTextXY(6, 8, "Welcome to ReactOS Setup");
526 SetTextXY(6, 11, "This part of the setup copies the ReactOS Operating System to your");
527 SetTextXY(6, 12, "computer and prepares the second part of the setup.");
529 SetTextXY(8, 15, "\x07 Press ENTER to install ReactOS.");
531 SetTextXY(8, 17, "\x07 Press E to start the emergency console.");
533 SetTextXY(8, 19, "\x07 Press R to repair ReactOS.");
535 SetTextXY(8, 21, "\x07 Press F3 to quit without installing ReactOS.");
538 SetStatusText(" ENTER = Continue F3 = Quit");
544 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
545 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
547 if (ConfirmQuit(Ir
) == TRUE
)
551 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
553 return(INSTALL_INTRO_PAGE
);
555 else if (toupper(Ir
->Event
.KeyEvent
.uChar
.AsciiChar
) == 'E') /* E */
557 return(EMERGENCY_INTRO_PAGE
);
559 else if (toupper(Ir
->Event
.KeyEvent
.uChar
.AsciiChar
) == 'R') /* R */
561 return(REPAIR_INTRO_PAGE
);
570 EmergencyIntroPage(PINPUT_RECORD Ir
)
572 SetTextXY(6, 8, "ReactOS Setup is in an early development phase. It does not yet");
573 SetTextXY(6, 9, "support all the functions of a fully usable setup application.");
575 SetTextXY(6, 12, "The emergency console is not implemented yet.");
577 SetTextXY(8, 15, "\x07 Press ESC to return to the main page.");
579 SetTextXY(8, 17, "\x07 Press ENTER to reboot your computer.");
581 SetStatusText(" ESC = Main page ENTER = Reboot");
587 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
591 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
592 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
)) /* ESC */
598 return(REPAIR_INTRO_PAGE
);
603 RepairIntroPage(PINPUT_RECORD Ir
)
605 SetTextXY(6, 8, "ReactOS Setup is in an early development phase. It does not yet");
606 SetTextXY(6, 9, "support all the functions of a fully usable setup application.");
608 SetTextXY(6, 12, "The repair functions are not implemented yet.");
610 SetTextXY(8, 15, "\x07 Press ESC to return to the main page.");
612 SetTextXY(8, 17, "\x07 Press ENTER to reboot your computer.");
614 SetStatusText(" ESC = Main page ENTER = Reboot");
620 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
624 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
625 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
)) /* ESC */
631 return(REPAIR_INTRO_PAGE
);
636 InstallIntroPage(PINPUT_RECORD Ir
)
638 SetTextXY(6, 8, "ReactOS Setup is in an early development phase. It does not yet");
639 SetTextXY(6, 9, "support all the functions of a fully usable setup application.");
641 SetTextXY(6, 12, "The following functions are missing:");
642 SetTextXY(8, 13, "- Creating and deleting harddisk partitions.");
643 SetTextXY(8, 14, "- Formatting partitions.");
644 SetTextXY(8, 15, "- Support for non-FAT file systems.");
645 SetTextXY(8, 16, "- Checking file systems.");
649 SetTextXY(8, 21, "\x07 Press ENTER to install ReactOS.");
651 SetTextXY(8, 23, "\x07 Press F3 to quit without installing ReactOS.");
654 SetStatusText(" ENTER = Continue F3 = Quit");
660 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
661 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
663 if (ConfirmQuit(Ir
) == TRUE
)
667 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
669 return(SELECT_PARTITION_PAGE
);
673 return(INSTALL_INTRO_PAGE
);
678 SelectPartitionPage(PINPUT_RECORD Ir
)
683 SetTextXY(6, 8, "The list below shows existing partitions and unused disk");
684 SetTextXY(6, 9, "space for new partitions.");
686 SetTextXY(8, 11, "\x07 Press UP or DOWN to select a list entry.");
687 SetTextXY(8, 13, "\x07 Press ENTER to install ReactOS onto the selected partition.");
688 SetTextXY(8, 15, "\x07 Press C to create a new partition.");
689 SetTextXY(8, 17, "\x07 Press D to delete an existing partition.");
691 SetStatusText(" Please wait...");
693 GetScreenSize(&xScreen
, &yScreen
);
695 if (PartitionList
== NULL
)
697 PartitionList
= CreatePartitionList (2,
701 if (PartitionList
== NULL
)
703 /* FIXME: show an error dialog */
708 CheckActiveBootPartition (PartitionList
);
710 DrawPartitionList (PartitionList
);
712 /* Warn about partitions created by Linux Fdisk */
713 if (WarnLinuxPartitions
== TRUE
&&
714 CheckForLinuxFdiskPartitions (PartitionList
) == TRUE
)
716 PopupError ("Setup found that at least one harddisk contains an incompatible\n"
717 "partition table that can not be handled properly!\n"
719 "Creating or deleting partitions can destroy the partiton table.\n"
721 " \x07 Press F3 to quit Setup."
722 " \x07 Press ENTER to continue.",
723 "F3= Quit ENTER = Continue");
728 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
729 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
733 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_RETURN
) /* ENTER */
735 WarnLinuxPartitions
= FALSE
;
736 return SELECT_PARTITION_PAGE
;
743 /* Update status text */
744 if (PartitionList
->CurrentPartition
== NULL
||
745 PartitionList
->CurrentPartition
->Unpartitioned
== TRUE
)
747 SetStatusText (" ENTER = Install C = Create Partition F3 = Quit");
751 SetStatusText (" ENTER = Install D = Delete Partition F3 = Quit");
756 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
757 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
759 if (ConfirmQuit(Ir
) == TRUE
)
761 DestroyPartitionList (PartitionList
);
762 PartitionList
= NULL
;
767 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
768 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
)) /* DOWN */
770 ScrollDownPartitionList (PartitionList
);
772 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
773 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_UP
)) /* UP */
775 ScrollUpPartitionList (PartitionList
);
777 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_RETURN
) /* ENTER */
779 if (PartitionList
->CurrentPartition
== NULL
||
780 PartitionList
->CurrentPartition
->Unpartitioned
== TRUE
)
782 CreateNewPartition (PartitionList
,
787 return SELECT_FILE_SYSTEM_PAGE
;
789 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_C
) /* C */
791 if (PartitionList
->CurrentPartition
->Unpartitioned
== FALSE
)
793 PopupError ("You can not create a new Partition inside\n"
794 "of an already existing Partition!\n"
796 " * Press any key to continue.",
800 return SELECT_PARTITION_PAGE
;
803 return CREATE_PARTITION_PAGE
;
805 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_D
) /* D */
807 if (PartitionList
->CurrentPartition
->Unpartitioned
== TRUE
)
809 PopupError ("You can not delete unpartitioned disk space!\n"
811 " * Press any key to continue.",
815 return SELECT_PARTITION_PAGE
;
818 return DELETE_PARTITION_PAGE
;
822 return SELECT_PARTITION_PAGE
;
827 DrawInputField(ULONG FieldLength
,
837 memset(buf
, '_', sizeof(buf
));
838 buf
[FieldLength
- strlen(FieldContent
)] = 0;
839 strcat(buf
, FieldContent
);
841 WriteConsoleOutputCharacters (buf
,
847 #define PARTITION_SIZE_INPUT_FIELD_LENGTH 6
850 ShowPartitionSizeInputBox(SHORT Left
,
875 /* draw upper left corner */
878 FillConsoleOutputCharacter(0xDA, // '+',
883 /* draw upper edge */
886 FillConsoleOutputCharacter(0xC4, // '-',
891 /* draw upper right corner */
894 FillConsoleOutputCharacter(0xBF, // '+',
899 /* draw left and right edge */
900 for (i
= Top
+ 1; i
< Bottom
; i
++)
904 FillConsoleOutputCharacter(0xB3, // '|',
910 FillConsoleOutputCharacter(0xB3, //'|',
916 /* draw lower left corner */
919 FillConsoleOutputCharacter(0xC0, // '+',
924 /* draw lower edge */
927 FillConsoleOutputCharacter(0xC4, // '-',
932 /* draw lower right corner */
935 FillConsoleOutputCharacter(0xD9, // '+',
943 strcpy (Buffer
, "Size of new partition:");
944 iLeft
= coPos
.X
+ strlen (Buffer
) + 1;
946 WriteConsoleOutputCharacters (Buffer
,
950 sprintf (Buffer
, "MB (max. %d MB)", MaxSize
);
951 coPos
.X
= iLeft
+ PARTITION_SIZE_INPUT_FIELD_LENGTH
+ 1;
953 WriteConsoleOutputCharacters (Buffer
,
959 DrawInputField (PARTITION_SIZE_INPUT_FIELD_LENGTH
,
968 if ((Ir
.Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
969 (Ir
.Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
976 else if (Ir
.Event
.KeyEvent
.wVirtualKeyCode
== VK_RETURN
) /* ENTER */
980 else if (Ir
.Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
) /* ESCAPE */
987 else if ((Ir
.Event
.KeyEvent
.wVirtualKeyCode
== VK_BACK
) && /* BACKSPACE */
992 DrawInputField (PARTITION_SIZE_INPUT_FIELD_LENGTH
,
997 else if ((Ir
.Event
.KeyEvent
.uChar
.AsciiChar
!= 0x00) &&
998 (Index
< PARTITION_SIZE_INPUT_FIELD_LENGTH
))
1000 ch
= Ir
.Event
.KeyEvent
.uChar
.AsciiChar
;
1001 if ((ch
>= '0') && (ch
<= '9'))
1006 DrawInputField (PARTITION_SIZE_INPUT_FIELD_LENGTH
,
1014 strcpy (InputBuffer
,
1020 CreatePartitionPage (PINPUT_RECORD Ir
)
1022 PDISKENTRY DiskEntry
;
1023 PPARTENTRY PartEntry
;
1028 CHAR InputBuffer
[50];
1034 if (PartitionList
== NULL
||
1035 PartitionList
->CurrentDisk
== NULL
||
1036 PartitionList
->CurrentPartition
== NULL
)
1038 /* FIXME: show an error dialog */
1042 DiskEntry
= PartitionList
->CurrentDisk
;
1043 PartEntry
= PartitionList
->CurrentPartition
;
1045 SetStatusText (" Please wait...");
1047 GetScreenSize (&xScreen
, &yScreen
);
1049 SetTextXY (6, 8, "You have chosen to create a new partition on");
1052 if (DiskEntry
->DiskSize
>= 0x280000000ULL
) /* 10 GB */
1054 DiskSize
= (DiskEntry
->DiskSize
+ (1 << 29)) >> 30;
1060 DiskSize
= (DiskEntry
->DiskSize
+ (1 << 19)) >> 20;
1066 if (DiskEntry
->DriverName
.Length
> 0)
1069 "%I64u %s Harddisk %lu (Port=%hu, Bus=%hu, Id=%hu) on %wZ.",
1072 DiskEntry
->DiskNumber
,
1076 &DiskEntry
->DriverName
);
1081 "%I64u %s Harddisk %lu (Port=%hu, Bus=%hu, Id=%hu).",
1084 DiskEntry
->DiskNumber
,
1091 SetTextXY (6, 12, "Please enter the size of the new partition in megabytes.");
1094 PrintTextXY (8, 10, "Maximum size of the new partition is %I64u MB",
1095 PartitionList
->CurrentPartition
->UnpartitionedLength
/ (1024*1024));
1098 SetStatusText (" ENTER = Create Partition ESC = Cancel F3 = Quit");
1100 PartEntry
= PartitionList
->CurrentPartition
;
1103 MaxSize
= (PartEntry
->UnpartitionedLength
+ (1 << 19)) >> 20; /* in MBytes (rounded) */
1104 ShowPartitionSizeInputBox (12, 14, xScreen
- 12, 17, /* left, top, right, bottom */
1105 MaxSize
, InputBuffer
, &Quit
, &Cancel
);
1108 if (ConfirmQuit (Ir
) == TRUE
)
1113 else if (Cancel
== TRUE
)
1115 return SELECT_PARTITION_PAGE
;
1119 PartSize
= atoi (InputBuffer
);
1126 if (PartSize
> MaxSize
)
1132 /* Convert to bytes */
1133 if (PartSize
== MaxSize
)
1135 /* Use all of the unpartitioned disk space */
1136 PartSize
= PartEntry
->UnpartitionedLength
;
1140 /* Round-up by cylinder size */
1141 PartSize
= ROUND_UP (PartSize
* 1024 * 1024,
1142 DiskEntry
->CylinderSize
);
1144 /* But never get larger than the unpartitioned disk space */
1145 if (PartSize
> PartEntry
->UnpartitionedLength
)
1146 PartSize
= PartEntry
->UnpartitionedLength
;
1149 DPRINT ("Partition size: %I64u bytes\n", PartSize
);
1151 CreateNewPartition (PartitionList
,
1155 return SELECT_PARTITION_PAGE
;
1159 return CREATE_PARTITION_PAGE
;
1164 DeletePartitionPage (PINPUT_RECORD Ir
)
1166 PDISKENTRY DiskEntry
;
1167 PPARTENTRY PartEntry
;
1173 if (PartitionList
== NULL
||
1174 PartitionList
->CurrentDisk
== NULL
||
1175 PartitionList
->CurrentPartition
== NULL
)
1177 /* FIXME: show an error dialog */
1181 DiskEntry
= PartitionList
->CurrentDisk
;
1182 PartEntry
= PartitionList
->CurrentPartition
;
1184 SetTextXY (6, 8, "You have chosen to delete the partition");
1186 /* Determine partition type */
1188 if (PartEntry
->New
== TRUE
)
1190 PartType
= "New (Unformatted)";
1192 else if (PartEntry
->Unpartitioned
== FALSE
)
1194 if ((PartEntry
->PartInfo
[0].PartitionType
== PARTITION_FAT_12
) ||
1195 (PartEntry
->PartInfo
[0].PartitionType
== PARTITION_FAT_16
) ||
1196 (PartEntry
->PartInfo
[0].PartitionType
== PARTITION_HUGE
) ||
1197 (PartEntry
->PartInfo
[0].PartitionType
== PARTITION_XINT13
))
1201 else if ((PartEntry
->PartInfo
[0].PartitionType
== PARTITION_FAT32
) ||
1202 (PartEntry
->PartInfo
[0].PartitionType
== PARTITION_FAT32_XINT13
))
1206 else if (PartEntry
->PartInfo
[0].PartitionType
== PARTITION_IFS
)
1208 PartType
= "NTFS"; /* FIXME: Not quite correct! */
1213 if (PartEntry
->PartInfo
[0].PartitionLength
.QuadPart
>= 0x280000000ULL
) /* 10 GB */
1215 PartSize
= (PartEntry
->PartInfo
[0].PartitionLength
.QuadPart
+ (1 << 29)) >> 30;
1220 if (PartEntry
->PartInfo
[0].PartitionLength
.QuadPart
>= 0xA00000ULL
) /* 10 MB */
1222 PartSize
= (PartEntry
->PartInfo
[0].PartitionLength
.QuadPart
+ (1 << 19)) >> 20;
1227 PartSize
= (PartEntry
->PartInfo
[0].PartitionLength
.QuadPart
+ (1 << 9)) >> 10;
1231 if (PartType
== NULL
)
1234 " %c%c Type %lu %I64u %s",
1235 (PartEntry
->DriveLetter
== 0) ? '-' : PartEntry
->DriveLetter
,
1236 (PartEntry
->DriveLetter
== 0) ? '-' : ':',
1237 PartEntry
->PartInfo
[0].PartitionType
,
1244 " %c%c %s %I64u %s",
1245 (PartEntry
->DriveLetter
== 0) ? '-' : PartEntry
->DriveLetter
,
1246 (PartEntry
->DriveLetter
== 0) ? '-' : ':',
1253 if (DiskEntry
->DiskSize
>= 0x280000000ULL
) /* 10 GB */
1255 DiskSize
= (DiskEntry
->DiskSize
+ (1 << 29)) >> 30;
1261 DiskSize
= (DiskEntry
->DiskSize
+ (1 << 19)) >> 20;
1267 if (DiskEntry
->DriverName
.Length
> 0)
1270 "on %I64u %s Harddisk %lu (Port=%hu, Bus=%hu, Id=%hu) on %wZ.",
1273 DiskEntry
->DiskNumber
,
1277 &DiskEntry
->DriverName
);
1282 "on %I64u %s Harddisk %lu (Port=%hu, Bus=%hu, Id=%hu).",
1285 DiskEntry
->DiskNumber
,
1291 SetTextXY (8, 18, "\x07 Press D to delete the partition.");
1292 SetTextXY (11, 19, "WARNING: All data on this partition will be lost!");
1294 SetTextXY (8, 21, "\x07 Press ESC to cancel.");
1296 SetStatusText (" D = Delete Partition ESC = Cancel F3 = Quit");
1302 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1303 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1305 if (ConfirmQuit (Ir
) == TRUE
)
1311 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
) /* ESC */
1313 return SELECT_PARTITION_PAGE
;
1315 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_D
) /* D */
1317 DeleteCurrentPartition (PartitionList
);
1319 return SELECT_PARTITION_PAGE
;
1323 return DELETE_PARTITION_PAGE
;
1328 SelectFileSystemPage (PINPUT_RECORD Ir
)
1330 PDISKENTRY DiskEntry
;
1331 PPARTENTRY PartEntry
;
1338 if (PartitionList
== NULL
||
1339 PartitionList
->CurrentDisk
== NULL
||
1340 PartitionList
->CurrentPartition
== NULL
)
1342 /* FIXME: show an error dialog */
1346 DiskEntry
= PartitionList
->CurrentDisk
;
1347 PartEntry
= PartitionList
->CurrentPartition
;
1349 /* adjust disk size */
1350 if (DiskEntry
->DiskSize
>= 0x280000000ULL
) /* 10 GB */
1352 DiskSize
= (DiskEntry
->DiskSize
+ (1 << 29)) >> 30;
1357 DiskSize
= (DiskEntry
->DiskSize
+ (1 << 19)) >> 20;
1361 /* adjust partition size */
1362 if (PartEntry
->PartInfo
[0].PartitionLength
.QuadPart
>= 0x280000000ULL
) /* 10 GB */
1364 PartSize
= (PartEntry
->PartInfo
[0].PartitionLength
.QuadPart
+ (1 << 29)) >> 30;
1369 PartSize
= (PartEntry
->PartInfo
[0].PartitionLength
.QuadPart
+ (1 << 19)) >> 20;
1373 /* adjust partition type */
1374 if ((PartEntry
->PartInfo
[0].PartitionType
== PARTITION_FAT_12
) ||
1375 (PartEntry
->PartInfo
[0].PartitionType
== PARTITION_FAT_16
) ||
1376 (PartEntry
->PartInfo
[0].PartitionType
== PARTITION_HUGE
) ||
1377 (PartEntry
->PartInfo
[0].PartitionType
== PARTITION_XINT13
))
1381 else if ((PartEntry
->PartInfo
[0].PartitionType
== PARTITION_FAT32
) ||
1382 (PartEntry
->PartInfo
[0].PartitionType
== PARTITION_FAT32_XINT13
))
1386 else if (PartEntry
->PartInfo
[0].PartitionType
== PARTITION_IFS
)
1388 PartType
= "NTFS"; /* FIXME: Not quite correct! */
1390 else if (PartEntry
->PartInfo
[0].PartitionType
== PARTITION_ENTRY_UNUSED
)
1392 PartType
= "Unused";
1396 PartType
= "Unknown";
1399 if (PartEntry
->AutoCreate
== TRUE
)
1401 SetTextXY(6, 8, "Setup created a new partition on");
1404 PrintTextXY(8, 10, "Partition %lu (%I64u %s) %s of",
1405 PartEntry
->PartInfo
[0].PartitionNumber
,
1411 PrintTextXY(8, 10, "Harddisk %lu (%I64u %s), Port=%hu, Bus=%hu, Id=%hu (%wZ).",
1412 DiskEntry
->DiskNumber
,
1418 &DiskEntry
->DriverName
);
1420 SetTextXY(6, 12, "This Partition will be formatted next.");
1423 PartEntry
->AutoCreate
= FALSE
;
1425 else if (PartEntry
->New
== TRUE
)
1427 SetTextXY(6, 8, "You chose to install ReactOS on a new or unformatted Partition.");
1428 SetTextXY(6, 10, "This Partition will be formatted next.");
1432 SetTextXY(6, 8, "Setup install ReactOS onto Partition");
1434 if (PartType
== NULL
)
1437 "%c%c Type %lu %I64u %s",
1438 (PartEntry
->DriveLetter
== 0) ? '-' : PartEntry
->DriveLetter
,
1439 (PartEntry
->DriveLetter
== 0) ? '-' : ':',
1440 PartEntry
->PartInfo
[0].PartitionType
,
1448 (PartEntry
->DriveLetter
== 0) ? '-' : PartEntry
->DriveLetter
,
1449 (PartEntry
->DriveLetter
== 0) ? '-' : ':',
1455 PrintTextXY(6, 12, "on Harddisk %lu (%I64u %s), Port=%hu, Bus=%hu, Id=%hu (%wZ).",
1456 DiskEntry
->DiskNumber
,
1462 &DiskEntry
->DriverName
);
1466 SetTextXY(6, 17, "Select a file system from the list below.");
1468 SetTextXY(8, 19, "\x07 Press UP or DOWN to select a file system.");
1469 SetTextXY(8, 21, "\x07 Press ENTER to format the partition.");
1470 SetTextXY(8, 23, "\x07 Press ESC to select another partition.");
1472 if (FileSystemList
== NULL
)
1474 FileSystemList
= CreateFileSystemList (6, 26, PartEntry
->New
, FsFat
);
1475 if (FileSystemList
== NULL
)
1477 /* FIXME: show an error dialog */
1481 /* FIXME: Add file systems to list */
1483 DrawFileSystemList (FileSystemList
);
1485 SetStatusText (" ENTER = Continue ESC = Cancel F3 = Quit");
1491 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1492 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1494 if (ConfirmQuit (Ir
) == TRUE
)
1500 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1501 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
)) /* ESC */
1503 return SELECT_PARTITION_PAGE
;
1505 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1506 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
)) /* DOWN */
1508 ScrollDownFileSystemList (FileSystemList
);
1510 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1511 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_UP
)) /* UP */
1513 ScrollUpFileSystemList (FileSystemList
);
1515 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_RETURN
) /* ENTER */
1517 if (FileSystemList
->CurrentFileSystem
== FsKeep
)
1519 return CHECK_FILE_SYSTEM_PAGE
;
1523 return FORMAT_PARTITION_PAGE
;
1528 return SELECT_FILE_SYSTEM_PAGE
;
1533 FormatPartitionPage (PINPUT_RECORD Ir
)
1535 WCHAR PathBuffer
[MAX_PATH
];
1536 PDISKENTRY DiskEntry
;
1537 PPARTENTRY PartEntry
;
1547 SetTextXY(6, 8, "Format partition");
1549 SetTextXY(6, 10, "Setup will now format the partition. Press ENTER to continue.");
1551 SetStatusText(" ENTER = Continue F3 = Quit");
1554 if (PartitionList
== NULL
||
1555 PartitionList
->CurrentDisk
== NULL
||
1556 PartitionList
->CurrentPartition
== NULL
)
1558 /* FIXME: show an error dialog */
1562 DiskEntry
= PartitionList
->CurrentDisk
;
1563 PartEntry
= PartitionList
->CurrentPartition
;
1569 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1570 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1572 if (ConfirmQuit (Ir
) == TRUE
)
1578 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_RETURN
) /* ENTER */
1580 SetStatusText (" Please wait ...");
1582 if (PartEntry
->PartInfo
[0].PartitionType
== PARTITION_ENTRY_UNUSED
)
1584 switch (FileSystemList
->CurrentFileSystem
)
1587 if (PartEntry
->PartInfo
[0].PartitionLength
.QuadPart
< (4200ULL * 1024ULL))
1589 /* FAT12 CHS partition (disk is smaller than 4.1MB) */
1590 PartEntry
->PartInfo
[0].PartitionType
= PARTITION_FAT_12
;
1592 else if (PartEntry
->PartInfo
[0].StartingOffset
.QuadPart
< (1024ULL * 255ULL * 63ULL * 512ULL))
1594 /* Partition starts below the 8.4GB boundary ==> CHS partition */
1596 if (PartEntry
->PartInfo
[0].PartitionLength
.QuadPart
< (32ULL * 1024ULL * 1024ULL))
1598 /* FAT16 CHS partition (partiton size < 32MB) */
1599 PartEntry
->PartInfo
[0].PartitionType
= PARTITION_FAT_16
;
1601 else if (PartEntry
->PartInfo
[0].PartitionLength
.QuadPart
< (512ULL * 1024ULL * 1024ULL))
1603 /* FAT16 CHS partition (partition size < 512MB) */
1604 PartEntry
->PartInfo
[0].PartitionType
= PARTITION_HUGE
;
1608 /* FAT32 CHS partition (partition size >= 512MB) */
1609 PartEntry
->PartInfo
[0].PartitionType
= PARTITION_FAT32
;
1614 /* Partition starts above the 8.4GB boundary ==> LBA partition */
1616 if (PartEntry
->PartInfo
[0].PartitionLength
.QuadPart
< (512ULL * 1024ULL * 1024ULL))
1618 /* FAT16 LBA partition (partition size < 512MB) */
1619 PartEntry
->PartInfo
[0].PartitionType
= PARTITION_XINT13
;
1623 /* FAT32 LBA partition (partition size >= 512MB) */
1624 PartEntry
->PartInfo
[0].PartitionType
= PARTITION_FAT32_XINT13
;
1637 CheckActiveBootPartition (PartitionList
);
1641 "Disk: %I64u Cylinder: %I64u Track: %I64u",
1642 DiskEntry
->DiskSize
,
1643 DiskEntry
->CylinderSize
,
1644 DiskEntry
->TrackSize
);
1647 DiskEntry
= PartitionList
->CurrentDisk
;
1648 Entry
= DiskEntry
->PartListHead
.Flink
;
1649 while (Entry
!= &DiskEntry
->PartListHead
)
1651 PartEntry
= CONTAINING_RECORD(Entry
, PARTENTRY
, ListEntry
);
1653 if (PartEntry
->Unpartitioned
== FALSE
)
1656 for (i
= 0; i
< 4; i
++)
1658 PrintTextXY (6, Line
,
1659 "%2u: %2u %c %12I64u %12I64u %2u %c",
1661 PartEntry
->PartInfo
[i
].PartitionNumber
,
1662 PartEntry
->PartInfo
[i
].BootIndicator
? 'A' : '-',
1663 PartEntry
->PartInfo
[i
].StartingOffset
.QuadPart
,
1664 PartEntry
->PartInfo
[i
].PartitionLength
.QuadPart
,
1665 PartEntry
->PartInfo
[i
].PartitionType
,
1666 PartEntry
->PartInfo
[i
].RewritePartition
? '*' : ' ');
1674 Entry
= Entry
->Flink
;
1677 /* Restore the old entry */
1678 PartEntry
= PartitionList
->CurrentPartition
;
1681 if (WritePartitionsToDisk (PartitionList
) == FALSE
)
1683 DPRINT ("WritePartitionsToDisk() failed\n");
1685 PopupError ("Setup failed to write partition tables.\n",
1686 "ENTER = Reboot computer");
1692 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
1700 /* Set DestinationRootPath */
1701 RtlFreeUnicodeString (&DestinationRootPath
);
1702 swprintf (PathBuffer
,
1703 L
"\\Device\\Harddisk%lu\\Partition%lu",
1704 PartitionList
->CurrentDisk
->DiskNumber
,
1705 PartitionList
->CurrentPartition
->PartInfo
[0].PartitionNumber
);
1706 RtlCreateUnicodeString (&DestinationRootPath
,
1708 DPRINT ("DestinationRootPath: %wZ\n", &DestinationRootPath
);
1711 /* Set SystemRootPath */
1712 RtlFreeUnicodeString (&SystemRootPath
);
1713 swprintf (PathBuffer
,
1714 L
"\\Device\\Harddisk%lu\\Partition%lu",
1715 PartitionList
->ActiveBootDisk
->DiskNumber
,
1716 PartitionList
->ActiveBootPartition
->PartInfo
[0].PartitionNumber
);
1717 RtlCreateUnicodeString (&SystemRootPath
,
1719 DPRINT ("SystemRootPath: %wZ\n", &SystemRootPath
);
1722 switch (FileSystemList
->CurrentFileSystem
)
1725 Status
= FormatPartition (&DestinationRootPath
);
1726 if (!NT_SUCCESS (Status
))
1728 DPRINT1 ("FormatPartition() failed with status 0x%.08x\n", Status
);
1729 /* FIXME: show an error dialog */
1733 PartEntry
->New
= FALSE
;
1734 if (FileSystemList
!= NULL
)
1736 DestroyFileSystemList (FileSystemList
);
1737 FileSystemList
= NULL
;
1740 CheckActiveBootPartition (PartitionList
);
1742 /* FIXME: Install boot code. This is a hack! */
1743 if ((PartEntry
->PartInfo
[0].PartitionType
== PARTITION_FAT32_XINT13
) ||
1744 (PartEntry
->PartInfo
[0].PartitionType
== PARTITION_FAT32
))
1746 wcscpy (PathBuffer
, SourceRootPath
.Buffer
);
1747 wcscat (PathBuffer
, L
"\\loader\\fat32.bin");
1749 DPRINT1 ("Install FAT32 bootcode: %S ==> %S\n", PathBuffer
,
1750 DestinationRootPath
.Buffer
);
1751 Status
= InstallFat32BootCodeToDisk (PathBuffer
,
1752 DestinationRootPath
.Buffer
);
1753 if (!NT_SUCCESS (Status
))
1755 DPRINT1 ("InstallFat32BootCodeToDisk() failed with status 0x%.08x\n", Status
);
1756 /* FIXME: show an error dialog */
1762 wcscpy (PathBuffer
, SourceRootPath
.Buffer
);
1763 wcscat (PathBuffer
, L
"\\loader\\fat.bin");
1765 DPRINT1 ("Install FAT bootcode: %S ==> %S\n", PathBuffer
,
1766 DestinationRootPath
.Buffer
);
1767 Status
= InstallFat16BootCodeToDisk (PathBuffer
,
1768 DestinationRootPath
.Buffer
);
1769 if (!NT_SUCCESS (Status
))
1771 DPRINT1 ("InstallFat16BootCodeToDisk() failed with status 0x%.08x\n", Status
);
1772 /* FIXME: show an error dialog */
1785 SetStatusText (" Done. Press any key ...");
1788 return INSTALL_DIRECTORY_PAGE
;
1792 return FORMAT_PARTITION_PAGE
;
1797 CheckFileSystemPage(PINPUT_RECORD Ir
)
1799 WCHAR PathBuffer
[MAX_PATH
];
1801 SetTextXY(6, 8, "Check file system");
1803 SetTextXY(6, 10, "At present, ReactOS can not check file systems.");
1805 SetStatusText(" Please wait ...");
1808 SetStatusText(" ENTER = Continue F3 = Quit");
1811 /* Set DestinationRootPath */
1812 RtlFreeUnicodeString (&DestinationRootPath
);
1813 swprintf (PathBuffer
,
1814 L
"\\Device\\Harddisk%lu\\Partition%lu",
1815 PartitionList
->CurrentDisk
->DiskNumber
,
1816 PartitionList
->CurrentPartition
->PartInfo
[0].PartitionNumber
);
1817 RtlCreateUnicodeString (&DestinationRootPath
,
1819 DPRINT ("DestinationRootPath: %wZ\n", &DestinationRootPath
);
1821 /* Set SystemRootPath */
1822 RtlFreeUnicodeString (&SystemRootPath
);
1823 swprintf (PathBuffer
,
1824 L
"\\Device\\Harddisk%lu\\Partition%lu",
1825 PartitionList
->ActiveBootDisk
->DiskNumber
,
1826 PartitionList
->ActiveBootPartition
->PartInfo
[0].PartitionNumber
);
1827 RtlCreateUnicodeString (&SystemRootPath
,
1829 DPRINT ("SystemRootPath: %wZ\n", &SystemRootPath
);
1836 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1837 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1839 if (ConfirmQuit(Ir
) == TRUE
)
1843 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
1845 return(INSTALL_DIRECTORY_PAGE
);
1849 return(CHECK_FILE_SYSTEM_PAGE
);
1854 InstallDirectoryPage(PINPUT_RECORD Ir
)
1856 PDISKENTRY DiskEntry
;
1857 PPARTENTRY PartEntry
;
1858 WCHAR PathBuffer
[MAX_PATH
];
1859 WCHAR InstallDir
[51];
1865 if (PartitionList
== NULL
||
1866 PartitionList
->CurrentDisk
== NULL
||
1867 PartitionList
->CurrentPartition
== NULL
)
1869 /* FIXME: show an error dialog */
1873 DiskEntry
= PartitionList
->CurrentDisk
;
1874 PartEntry
= PartitionList
->CurrentPartition
;
1876 /* Search for 'DefaultPath' in the 'SetupData' section */
1877 if (!InfFindFirstLine (SetupInf
, L
"SetupData", L
"DefaultPath", &Context
))
1879 PopupError("Setup failed to find the 'SetupData' section\n"
1880 "in TXTSETUP.SIF.\n",
1881 "ENTER = Reboot computer");
1887 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
1894 /* Read the 'DefaultPath' data */
1895 if (InfGetData (&Context
, NULL
, &DefaultPath
))
1897 wcscpy(InstallDir
, DefaultPath
);
1901 wcscpy(InstallDir
, L
"\\ReactOS");
1903 Length
= wcslen(InstallDir
);
1905 SetTextXY(6, 8, "Setup installs ReactOS files onto the selected partition. Choose a");
1906 SetTextXY(6, 9, "directory where you want ReactOS to be installed:");
1908 SetInputTextXY(8, 11, 51, InstallDir
);
1910 SetTextXY(6, 14, "To change the suggested directory, press BACKSPACE to delete");
1911 SetTextXY(6, 15, "characters and then type the directory where you want ReactOS to");
1912 SetTextXY(6, 16, "be installed.");
1914 SetStatusText(" ENTER = Continue F3 = Quit");
1920 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1921 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1923 if (ConfirmQuit(Ir
) == TRUE
)
1927 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
1929 /* Create 'InstallPath' string */
1930 RtlFreeUnicodeString(&InstallPath
);
1931 RtlCreateUnicodeString(&InstallPath
,
1934 /* Create 'DestinationPath' string */
1935 RtlFreeUnicodeString(&DestinationPath
);
1937 DestinationRootPath
.Buffer
);
1938 if (InstallDir
[0] != L
'\\')
1941 wcscat(PathBuffer
, InstallDir
);
1942 RtlCreateUnicodeString(&DestinationPath
,
1945 /* Create 'DestinationArcPath' */
1946 RtlFreeUnicodeString(&DestinationArcPath
);
1947 swprintf(PathBuffer
,
1948 L
"multi(0)disk(0)rdisk(%lu)partition(%lu)",
1949 DiskEntry
->DiskNumber
,
1950 PartEntry
->PartInfo
[0].PartitionNumber
);
1951 if (InstallDir
[0] != L
'\\')
1954 wcscat(PathBuffer
, InstallDir
);
1955 RtlCreateUnicodeString(&DestinationArcPath
,
1958 return(PREPARE_COPY_PAGE
);
1960 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x08) /* BACKSPACE */
1965 InstallDir
[Length
] = 0;
1966 SetInputTextXY(8, 11, 51, InstallDir
);
1969 else if (isprint(Ir
->Event
.KeyEvent
.uChar
.AsciiChar
))
1973 InstallDir
[Length
] = (WCHAR
)Ir
->Event
.KeyEvent
.uChar
.AsciiChar
;
1975 InstallDir
[Length
] = 0;
1976 SetInputTextXY(8, 11, 51, InstallDir
);
1981 return(INSTALL_DIRECTORY_PAGE
);
1986 PrepareCopyPageInfFile(HINF InfFile
, PWCHAR SourceCabinet
, PINPUT_RECORD Ir
)
1988 WCHAR PathBuffer
[MAX_PATH
];
1989 INFCONTEXT FilesContext
;
1990 INFCONTEXT DirContext
;
1996 PWCHAR FileKeyValue
;
2000 /* Search for the 'SourceFiles' section */
2001 if (!InfFindFirstLine (InfFile
, L
"SourceFiles", NULL
, &FilesContext
))
2003 PopupError("Setup failed to find the 'SourceFiles' section\n"
2004 "in TXTSETUP.SIF.\n", // FIXME
2005 "ENTER = Reboot computer");
2011 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2019 * Enumerate the files in the 'SourceFiles' section
2020 * and add them to the file queue.
2024 if (!InfGetData (&FilesContext
, &FileKeyName
, &FileKeyValue
))
2030 DPRINT ("FileKeyName: '%S' FileKeyValue: '%S'\n", FileKeyName
, FileKeyValue
);
2032 /* Lookup target directory */
2033 if (!InfFindFirstLine (InfFile
, L
"Directories", FileKeyValue
, &DirContext
))
2035 /* FIXME: Handle error! */
2036 DPRINT1("InfFindFirstLine() failed\n");
2040 if (!InfGetData (&DirContext
, NULL
, &DirKeyValue
))
2042 /* FIXME: Handle error! */
2043 DPRINT1("InfGetData() failed\n");
2047 if (!SetupQueueCopy(SetupFileQueue
,
2049 SourceRootPath
.Buffer
,
2055 /* FIXME: Handle error! */
2056 DPRINT1("SetupQueueCopy() failed\n");
2059 while (InfFindNextLine(&FilesContext
, &FilesContext
));
2062 /* Create directories */
2066 * Install directories like '\reactos\test' are not handled yet.
2069 /* Get destination path */
2070 wcscpy(PathBuffer
, DestinationPath
.Buffer
);
2072 /* Remove trailing backslash */
2073 Length
= wcslen(PathBuffer
);
2074 if ((Length
> 0) && (PathBuffer
[Length
- 1] == '\\'))
2076 PathBuffer
[Length
- 1] = 0;
2079 /* Create the install directory */
2080 Status
= CreateDirectory(PathBuffer
);
2081 if (!NT_SUCCESS(Status
) && Status
!= STATUS_OBJECT_NAME_COLLISION
)
2083 DPRINT("Creating directory '%S' failed: Status = 0x%08lx", PathBuffer
, Status
);
2084 PopupError("Setup could not create the install directory.",
2085 "ENTER = Reboot computer");
2091 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2099 /* Search for the 'Directories' section */
2100 if (!InfFindFirstLine(InfFile
, L
"Directories", NULL
, &DirContext
))
2104 PopupError("Setup failed to find the 'Directories' section\n"
2105 "in the cabinet.\n", "ENTER = Reboot computer");
2109 PopupError("Setup failed to find the 'Directories' section\n"
2110 "in TXTSETUP.SIF.\n", "ENTER = Reboot computer");
2117 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2124 /* Enumerate the directory values and create the subdirectories */
2127 if (!InfGetData (&DirContext
, NULL
, &KeyValue
))
2133 if (KeyValue
[0] == L
'\\' && KeyValue
[1] != 0)
2135 DPRINT("Absolute Path: '%S'\n", KeyValue
);
2137 wcscpy(PathBuffer
, DestinationRootPath
.Buffer
);
2138 wcscat(PathBuffer
, KeyValue
);
2140 DPRINT("FullPath: '%S'\n", PathBuffer
);
2142 else if (KeyValue
[0] != L
'\\')
2144 DPRINT("RelativePath: '%S'\n", KeyValue
);
2145 wcscpy(PathBuffer
, DestinationPath
.Buffer
);
2146 wcscat(PathBuffer
, L
"\\");
2147 wcscat(PathBuffer
, KeyValue
);
2149 DPRINT("FullPath: '%S'\n", PathBuffer
);
2151 Status
= CreateDirectory(PathBuffer
);
2152 if (!NT_SUCCESS(Status
) && Status
!= STATUS_OBJECT_NAME_COLLISION
)
2154 DPRINT("Creating directory '%S' failed: Status = 0x%08lx", PathBuffer
, Status
);
2155 PopupError("Setup could not create install directories.",
2156 "ENTER = Reboot computer");
2162 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2170 while (InfFindNextLine (&DirContext
, &DirContext
));
2177 PrepareCopyPage(PINPUT_RECORD Ir
)
2181 WCHAR PathBuffer
[MAX_PATH
];
2182 INFCONTEXT CabinetsContext
;
2189 SetTextXY(6, 8, "Setup prepares your computer for copying the ReactOS files. ");
2193 * Build the file copy list
2195 SetStatusText(" Building the file copy list...");
2197 /* Create the file queue */
2198 SetupFileQueue
= SetupOpenFileQueue();
2199 if (SetupFileQueue
== NULL
)
2201 PopupError("Setup failed to open the copy file queue.\n",
2202 "ENTER = Reboot computer");
2208 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2216 if (!PrepareCopyPageInfFile(SetupInf
, NULL
, Ir
))
2222 /* Search for the 'Cabinets' section */
2223 if (!InfFindFirstLine (SetupInf
, L
"Cabinets", NULL
, &CabinetsContext
))
2225 PopupError("Setup failed to find the 'Cabinets' section\n"
2226 "in TXTSETUP.SIF.\n",
2227 "ENTER = Reboot computer");
2233 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2242 * Enumerate the directory values in the 'Cabinets'
2243 * section and parse their inf files.
2247 if (!InfGetData (&CabinetsContext
, NULL
, &KeyValue
))
2250 wcscpy(PathBuffer
, SourcePath
.Buffer
);
2251 wcscat(PathBuffer
, L
"\\");
2252 wcscat(PathBuffer
, KeyValue
);
2254 CabinetInitialize();
2255 CabinetSetEventHandlers(NULL
, NULL
, NULL
);
2256 CabinetSetCabinetName(PathBuffer
);
2258 if (CabinetOpen() == CAB_STATUS_SUCCESS
)
2260 DPRINT("Cabinet %S\n", CabinetGetCabinetName());
2262 InfFileData
= CabinetGetCabinetReservedArea(&InfFileSize
);
2263 if (InfFileData
== NULL
)
2265 PopupError("Cabinet has no setup script.\n",
2266 "ENTER = Reboot computer");
2272 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2281 DPRINT("Cannot open cabinet: %S.\n", CabinetGetCabinetName());
2283 PopupError("Cabinet not found.\n", "ENTER = Reboot computer");
2289 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2296 Status
= InfOpenBufferedFile(&InfHandle
,
2300 if (!NT_SUCCESS(Status
))
2302 PopupError("Cabinet has no valid inf file.\n",
2303 "ENTER = Reboot computer");
2309 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2318 if (!PrepareCopyPageInfFile(InfHandle
, KeyValue
, Ir
))
2323 while (InfFindNextLine (&CabinetsContext
, &CabinetsContext
));
2325 return(FILE_COPY_PAGE
);
2330 FileCopyCallback(PVOID Context
,
2335 PCOPYCONTEXT CopyContext
;
2337 CopyContext
= (PCOPYCONTEXT
)Context
;
2339 switch (Notification
)
2341 case SPFILENOTIFY_STARTSUBQUEUE
:
2342 CopyContext
->TotalOperations
= (ULONG
)Param2
;
2343 ProgressSetStepCount(CopyContext
->ProgressBar
,
2344 CopyContext
->TotalOperations
);
2347 case SPFILENOTIFY_STARTCOPY
:
2348 /* Display copy message */
2349 PrintTextXYN(6, 16, 60, "Copying file: %S", (PWSTR
)Param1
);
2351 PrintTextXYN(6, 18, 60, "File %lu of %lu",
2352 CopyContext
->CompletedOperations
+ 1,
2353 CopyContext
->TotalOperations
);
2356 case SPFILENOTIFY_ENDCOPY
:
2357 CopyContext
->CompletedOperations
++;
2358 ProgressNextStep(CopyContext
->ProgressBar
);
2367 FileCopyPage(PINPUT_RECORD Ir
)
2369 COPYCONTEXT CopyContext
;
2373 SetStatusText(" Please wait...");
2375 SetTextXY(6, 8, "Copying files");
2377 GetScreenSize(&xScreen
, &yScreen
);
2379 CopyContext
.TotalOperations
= 0;
2380 CopyContext
.CompletedOperations
= 0;
2381 CopyContext
.ProgressBar
= CreateProgressBar(6,
2386 SetupCommitFileQueue(SetupFileQueue
,
2387 DestinationRootPath
.Buffer
,
2389 (PSP_FILE_CALLBACK
)FileCopyCallback
,
2392 SetupCloseFileQueue(SetupFileQueue
);
2394 DestroyProgressBar(CopyContext
.ProgressBar
);
2396 return(REGISTRY_PAGE
);
2401 RegistryPage(PINPUT_RECORD Ir
)
2403 INFCONTEXT InfContext
;
2412 SetTextXY(6, 8, "Setup is updating the system configuration");
2414 SetStatusText(" Creating registry hives...");
2416 if (!SetInstallPathValue(&DestinationPath
))
2418 DPRINT("SetInstallPathValue() failed\n");
2419 PopupError("Setup failed to set the initialize the registry.",
2420 "ENTER = Reboot computer");
2426 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2433 /* Create the default hives */
2434 Status
= NtInitializeRegistry(TRUE
);
2435 if (!NT_SUCCESS(Status
))
2437 DPRINT("NtInitializeRegistry() failed (Status %lx)\n", Status
);
2438 PopupError("Setup failed to create the registry hives.",
2439 "ENTER = Reboot computer");
2445 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2452 /* Update registry */
2453 SetStatusText(" Updating registry hives...");
2455 if (!InfFindFirstLine(SetupInf
, L
"HiveInfs.Install", NULL
, &InfContext
))
2457 DPRINT1("InfFindFirstLine() failed\n");
2458 PopupError("Setup failed to find the registry data files.",
2459 "ENTER = Reboot computer");
2465 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2474 InfGetDataField (&InfContext
, 0, &Action
);
2475 InfGetDataField (&InfContext
, 1, &File
);
2476 InfGetDataField (&InfContext
, 2, &Section
);
2478 DPRINT1("Action: %S File: %S Section %S\n", Action
, File
, Section
);
2480 if (!_wcsicmp (Action
, L
"AddReg"))
2484 else if (!_wcsicmp (Action
, L
"DelReg"))
2493 SetStatusText(" Importing %S...", File
);
2495 if (!ImportRegistryFile(File
, Section
, Delete
))
2497 DPRINT1("Importing %S failed\n", File
);
2499 PopupError("Setup failed to import a hive file.",
2500 "ENTER = Reboot computer");
2506 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2513 while (InfFindNextLine (&InfContext
, &InfContext
));
2515 SetStatusText(" Done...");
2517 return(BOOT_LOADER_PAGE
);
2522 BootLoaderPage(PINPUT_RECORD Ir
)
2524 WCHAR SrcPath
[MAX_PATH
];
2525 WCHAR DstPath
[MAX_PATH
];
2527 PINICACHESECTION IniSection
;
2530 SetTextXY(6, 8, "Installing the boot loader");
2532 SetStatusText(" Please wait...");
2534 if (PartitionList
->ActiveBootPartition
->PartInfo
[0].PartitionType
== PARTITION_ENTRY_UNUSED
)
2536 DPRINT1("Error: active partition invalid (unused)\n");
2537 PopupError("The active partition is unused (invalid).\n",
2538 "ENTER = Reboot computer");
2544 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2550 if (PartitionList
->ActiveBootPartition
->PartInfo
[0].PartitionType
== 0x0A)
2552 /* OS/2 boot manager partition */
2553 DPRINT1("Found OS/2 boot manager partition\n");
2554 PopupError("Setup found an OS/2 boot manager partiton.\n"
2555 "The OS/2 boot manager is not supported yet!",
2556 "ENTER = Reboot computer");
2562 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2568 else if (PartitionList
->ActiveBootPartition
->PartInfo
[0].PartitionType
== 0x83)
2570 /* Linux ext2 partition */
2571 DPRINT1("Found Linux ext2 partition\n");
2572 PopupError("Setup found a Linux ext2 partiton.\n"
2573 "Linux ext2 partitions are not supported yet!",
2574 "ENTER = Reboot computer");
2580 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2586 else if (PartitionList
->ActiveBootPartition
->PartInfo
[0].PartitionType
== PARTITION_IFS
)
2588 /* NTFS partition */
2589 DPRINT1("Found NTFS partition\n");
2590 PopupError("Setup found an NTFS partiton.\n"
2591 "NTFS partitions are not supported yet!",
2592 "ENTER = Reboot computer");
2598 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2604 else if ((PartitionList
->ActiveBootPartition
->PartInfo
[0].PartitionType
== PARTITION_FAT_12
) ||
2605 (PartitionList
->ActiveBootPartition
->PartInfo
[0].PartitionType
== PARTITION_FAT_16
) ||
2606 (PartitionList
->ActiveBootPartition
->PartInfo
[0].PartitionType
== PARTITION_HUGE
) ||
2607 (PartitionList
->ActiveBootPartition
->PartInfo
[0].PartitionType
== PARTITION_XINT13
) ||
2608 (PartitionList
->ActiveBootPartition
->PartInfo
[0].PartitionType
== PARTITION_FAT32
) ||
2609 (PartitionList
->ActiveBootPartition
->PartInfo
[0].PartitionType
== PARTITION_FAT32_XINT13
))
2611 /* FAT or FAT32 partition */
2612 DPRINT1("System path: '%wZ'\n", &SystemRootPath
);
2614 if (DoesFileExist(SystemRootPath
.Buffer
, L
"ntldr") == TRUE
||
2615 DoesFileExist(SystemRootPath
.Buffer
, L
"boot.ini") == TRUE
)
2617 /* Search root directory for 'ntldr' and 'boot.ini'. */
2618 DPRINT1("Found Microsoft Windows NT/2000/XP boot loader\n");
2620 /* Copy FreeLoader to the boot partition */
2621 wcscpy(SrcPath
, SourceRootPath
.Buffer
);
2622 wcscat(SrcPath
, L
"\\loader\\freeldr.sys");
2623 wcscpy(DstPath
, SystemRootPath
.Buffer
);
2624 wcscat(DstPath
, L
"\\freeldr.sys");
2626 DPRINT1("Copy: %S ==> %S\n", SrcPath
, DstPath
);
2627 Status
= SetupCopyFile(SrcPath
, DstPath
);
2628 if (!NT_SUCCESS(Status
))
2630 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status
);
2631 PopupError("Setup failed to copy 'freeldr.sys'.",
2632 "ENTER = Reboot computer");
2638 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2645 /* Create or update freeldr.ini */
2646 if (DoesFileExist(SystemRootPath
.Buffer
, L
"freeldr.ini") == FALSE
)
2648 /* Create new 'freeldr.ini' */
2649 DPRINT1("Create new 'freeldr.ini'\n");
2650 wcscpy(DstPath
, SystemRootPath
.Buffer
);
2651 wcscat(DstPath
, L
"\\freeldr.ini");
2653 Status
= CreateFreeLoaderIniForReactos(DstPath
,
2654 DestinationArcPath
.Buffer
);
2655 if (!NT_SUCCESS(Status
))
2657 DPRINT1("CreateFreeLoaderIniForReactos() failed (Status %lx)\n", Status
);
2658 PopupError("Setup failed to create 'freeldr.ini'.",
2659 "ENTER = Reboot computer");
2665 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2672 /* Install new bootcode */
2673 if ((PartitionList
->ActiveBootPartition
->PartInfo
[0].PartitionType
== PARTITION_FAT32
) ||
2674 (PartitionList
->ActiveBootPartition
->PartInfo
[0].PartitionType
== PARTITION_FAT32_XINT13
))
2676 /* Install FAT32 bootcode */
2677 wcscpy(SrcPath
, SourceRootPath
.Buffer
);
2678 wcscat(SrcPath
, L
"\\loader\\fat32.bin");
2679 wcscpy(DstPath
, SystemRootPath
.Buffer
);
2680 wcscat(DstPath
, L
"\\bootsect.ros");
2682 DPRINT1("Install FAT32 bootcode: %S ==> %S\n", SrcPath
, DstPath
);
2683 Status
= InstallFat32BootCodeToFile(SrcPath
,
2685 SystemRootPath
.Buffer
);
2686 if (!NT_SUCCESS(Status
))
2688 DPRINT1("InstallFat32BootCodeToFile() failed (Status %lx)\n", Status
);
2689 PopupError("Setup failed to install the FAT32 bootcode.",
2690 "ENTER = Reboot computer");
2696 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2705 /* Install FAT16 bootcode */
2706 wcscpy(SrcPath
, SourceRootPath
.Buffer
);
2707 wcscat(SrcPath
, L
"\\loader\\fat.bin");
2708 wcscpy(DstPath
, SystemRootPath
.Buffer
);
2709 wcscat(DstPath
, L
"\\bootsect.ros");
2711 DPRINT1("Install FAT bootcode: %S ==> %S\n", SrcPath
, DstPath
);
2712 Status
= InstallFat16BootCodeToFile(SrcPath
,
2714 SystemRootPath
.Buffer
);
2715 if (!NT_SUCCESS(Status
))
2717 DPRINT1("InstallFat16BootCodeToFile() failed (Status %lx)\n", Status
);
2718 PopupError("Setup failed to install the FAT bootcode.",
2719 "ENTER = Reboot computer");
2725 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2733 /* Update 'boot.ini' */
2734 wcscpy(DstPath
, SystemRootPath
.Buffer
);
2735 wcscat(DstPath
, L
"\\boot.ini");
2737 DPRINT1("Update 'boot.ini': %S\n", DstPath
);
2738 Status
= UpdateBootIni(DstPath
,
2739 L
"C:\\bootsect.ros",
2741 if (!NT_SUCCESS(Status
))
2743 DPRINT1("UpdateBootIni() failed (Status %lx)\n", Status
);
2744 PopupError("Setup failed to update \'boot.ini\'.",
2745 "ENTER = Reboot computer");
2751 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2760 /* Update existing 'freeldr.ini' */
2761 DPRINT1("Update existing 'freeldr.ini'\n");
2762 wcscpy(DstPath
, SystemRootPath
.Buffer
);
2763 wcscat(DstPath
, L
"\\freeldr.ini");
2765 Status
= UpdateFreeLoaderIni(DstPath
,
2766 DestinationArcPath
.Buffer
);
2767 if (!NT_SUCCESS(Status
))
2769 DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status
);
2770 PopupError("Setup failed to update 'freeldr.ini'.",
2771 "ENTER = Reboot computer");
2777 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2785 else if (DoesFileExist(SystemRootPath
.Buffer
, L
"io.sys") == TRUE
||
2786 DoesFileExist(SystemRootPath
.Buffer
, L
"msdos.sys") == TRUE
)
2788 /* Search for root directory for 'io.sys' and 'msdos.sys'. */
2789 DPRINT1("Found Microsoft DOS or Windows 9x boot loader\n");
2791 /* Copy FreeLoader to the boot partition */
2792 wcscpy(SrcPath
, SourceRootPath
.Buffer
);
2793 wcscat(SrcPath
, L
"\\loader\\freeldr.sys");
2794 wcscpy(DstPath
, SystemRootPath
.Buffer
);
2795 wcscat(DstPath
, L
"\\freeldr.sys");
2797 DPRINT("Copy: %S ==> %S\n", SrcPath
, DstPath
);
2798 Status
= SetupCopyFile(SrcPath
, DstPath
);
2799 if (!NT_SUCCESS(Status
))
2801 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status
);
2802 PopupError("Setup failed to copy 'freeldr.sys'.",
2803 "ENTER = Reboot computer");
2809 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2816 /* Create or update 'freeldr.ini' */
2817 if (DoesFileExist(SystemRootPath
.Buffer
, L
"freeldr.ini") == FALSE
)
2819 /* Create new 'freeldr.ini' */
2820 DPRINT1("Create new 'freeldr.ini'\n");
2821 wcscpy(DstPath
, SystemRootPath
.Buffer
);
2822 wcscat(DstPath
, L
"\\freeldr.ini");
2824 Status
= CreateFreeLoaderIniForDos(DstPath
,
2825 DestinationArcPath
.Buffer
);
2826 if (!NT_SUCCESS(Status
))
2828 DPRINT1("CreateFreeLoaderIniForDos() failed (Status %lx)\n", Status
);
2829 PopupError("Setup failed to create 'freeldr.ini'.",
2830 "ENTER = Reboot computer");
2836 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2843 /* Save current bootsector as 'BOOTSECT.DOS' */
2844 wcscpy(SrcPath
, SystemRootPath
.Buffer
);
2845 wcscpy(DstPath
, SystemRootPath
.Buffer
);
2846 wcscat(DstPath
, L
"\\bootsect.dos");
2848 DPRINT1("Save bootsector: %S ==> %S\n", SrcPath
, DstPath
);
2849 Status
= SaveCurrentBootSector(SrcPath
,
2851 if (!NT_SUCCESS(Status
))
2853 DPRINT1("SaveCurrentBootSector() failed (Status %lx)\n", Status
);
2854 PopupError("Setup failed to save the current bootsector.",
2855 "ENTER = Reboot computer");
2861 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2868 /* Install new bootsector */
2869 if ((PartitionList
->ActiveBootPartition
->PartInfo
[0].PartitionType
== PARTITION_FAT32
) ||
2870 (PartitionList
->ActiveBootPartition
->PartInfo
[0].PartitionType
== PARTITION_FAT32_XINT13
))
2872 wcscpy(SrcPath
, SourceRootPath
.Buffer
);
2873 wcscat(SrcPath
, L
"\\loader\\fat32.bin");
2875 DPRINT1("Install FAT32 bootcode: %S ==> %S\n", SrcPath
, SystemRootPath
.Buffer
);
2876 Status
= InstallFat32BootCodeToDisk(SrcPath
,
2877 SystemRootPath
.Buffer
);
2878 if (!NT_SUCCESS(Status
))
2880 DPRINT1("InstallFat32BootCodeToDisk() failed (Status %lx)\n", Status
);
2881 PopupError("Setup failed to install the FAT32 bootcode.",
2882 "ENTER = Reboot computer");
2888 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2897 wcscpy(SrcPath
, SourceRootPath
.Buffer
);
2898 wcscat(SrcPath
, L
"\\loader\\fat.bin");
2900 DPRINT1("Install FAT bootcode: %S ==> %S\n", SrcPath
, SystemRootPath
.Buffer
);
2901 Status
= InstallFat16BootCodeToDisk(SrcPath
,
2902 SystemRootPath
.Buffer
);
2903 if (!NT_SUCCESS(Status
))
2905 DPRINT1("InstallFat16BootCodeToDisk() failed (Status %lx)\n", Status
);
2906 PopupError("Setup failed to install the FAT bootcode.",
2907 "ENTER = Reboot computer");
2913 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2923 /* Update existing 'freeldr.ini' */
2924 wcscpy(DstPath
, SystemRootPath
.Buffer
);
2925 wcscat(DstPath
, L
"\\freeldr.ini");
2927 Status
= UpdateFreeLoaderIni(DstPath
,
2928 DestinationArcPath
.Buffer
);
2929 if (!NT_SUCCESS(Status
))
2931 DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status
);
2932 PopupError("Setup failed to update 'freeldr.ini'.",
2933 "ENTER = Reboot computer");
2939 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2949 /* No or unknown boot loader */
2950 DPRINT1("No or unknown boot loader found\n");
2952 /* Copy FreeLoader to the boot partition */
2953 wcscpy(SrcPath
, SourceRootPath
.Buffer
);
2954 wcscat(SrcPath
, L
"\\loader\\freeldr.sys");
2955 wcscpy(DstPath
, SystemRootPath
.Buffer
);
2956 wcscat(DstPath
, L
"\\freeldr.sys");
2958 DPRINT1("Copy: %S ==> %S\n", SrcPath
, DstPath
);
2959 Status
= SetupCopyFile(SrcPath
, DstPath
);
2960 if (!NT_SUCCESS(Status
))
2962 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status
);
2963 PopupError("Setup failed to copy 'freeldr.sys'.",
2964 "ENTER = Reboot computer");
2970 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2977 /* Create or update 'freeldr.ini' */
2978 if (DoesFileExist(SystemRootPath
.Buffer
, L
"freeldr.ini") == FALSE
)
2980 /* Create new freeldr.ini */
2981 wcscpy(DstPath
, SystemRootPath
.Buffer
);
2982 wcscat(DstPath
, L
"\\freeldr.ini");
2984 DPRINT1("Copy: %S ==> %S\n", SrcPath
, DstPath
);
2985 Status
= CreateFreeLoaderIniForReactos(DstPath
,
2986 DestinationArcPath
.Buffer
);
2987 if (!NT_SUCCESS(Status
))
2989 DPRINT1("CreateFreeLoaderIniForReactos() failed (Status %lx)\n", Status
);
2990 PopupError("Setup failed to create \'freeldr.ini\'.",
2991 "ENTER = Reboot computer");
2997 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
3004 /* Save current bootsector as 'BOOTSECT.OLD' */
3005 wcscpy(SrcPath
, SystemRootPath
.Buffer
);
3006 wcscpy(DstPath
, SystemRootPath
.Buffer
);
3007 wcscat(DstPath
, L
"\\bootsect.old");
3009 DPRINT1("Save bootsector: %S ==> %S\n", SrcPath
, DstPath
);
3010 Status
= SaveCurrentBootSector(SrcPath
,
3012 if (!NT_SUCCESS(Status
))
3014 DPRINT1("SaveCurrentBootSector() failed (Status %lx)\n", Status
);
3015 PopupError("Setup failed save the current bootsector.",
3016 "ENTER = Reboot computer");
3022 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
3029 /* Install new bootsector */
3030 if ((PartitionList
->ActiveBootPartition
->PartInfo
[0].PartitionType
== PARTITION_FAT32
) ||
3031 (PartitionList
->ActiveBootPartition
->PartInfo
[0].PartitionType
== PARTITION_FAT32_XINT13
))
3033 wcscpy(SrcPath
, SourceRootPath
.Buffer
);
3034 wcscat(SrcPath
, L
"\\loader\\fat32.bin");
3036 DPRINT1("Install FAT32 bootcode: %S ==> %S\n", SrcPath
, SystemRootPath
.Buffer
);
3037 Status
= InstallFat32BootCodeToDisk(SrcPath
,
3038 SystemRootPath
.Buffer
);
3039 if (!NT_SUCCESS(Status
))
3041 DPRINT1("InstallFat32BootCodeToDisk() failed (Status %lx)\n", Status
);
3042 PopupError("Setup failed to install the FAT32 bootcode.",
3043 "ENTER = Reboot computer");
3049 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
3058 wcscpy(SrcPath
, SourceRootPath
.Buffer
);
3059 wcscat(SrcPath
, L
"\\loader\\fat.bin");
3061 DPRINT1("Install FAT bootcode: %S ==> %S\n", SrcPath
, SystemRootPath
.Buffer
);
3062 Status
= InstallFat16BootCodeToDisk(SrcPath
,
3063 SystemRootPath
.Buffer
);
3064 if (!NT_SUCCESS(Status
))
3066 DPRINT1("InstallFat16BootCodeToDisk() failed (Status %lx)\n", Status
);
3067 PopupError("Setup failed to install the FAT bootcode.",
3068 "ENTER = Reboot computer");
3074 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
3084 /* Update existing 'freeldr.ini' */
3085 wcscpy(DstPath
, SystemRootPath
.Buffer
);
3086 wcscat(DstPath
, L
"\\freeldr.ini");
3088 Status
= UpdateFreeLoaderIni(DstPath
,
3089 DestinationArcPath
.Buffer
);
3090 if (!NT_SUCCESS(Status
))
3092 DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status
);
3093 PopupError("Setup failed to update 'freeldr.ini'.",
3094 "ENTER = Reboot computer");
3100 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
3111 /* Unknown partition */
3112 DPRINT1("Unknown partition found\n");
3113 PopupError("Setup found an unknown partiton type.\n"
3114 "This partition type is not supported!",
3115 "ENTER = Reboot computer");
3121 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
3128 return(SUCCESS_PAGE
);
3134 QuitPage(PINPUT_RECORD Ir
)
3136 SetTextXY(10, 6, "ReactOS is not completely installed");
3138 SetTextXY(10, 8, "Remove floppy disk from Drive A: and");
3139 SetTextXY(10, 9, "all CD-ROMs from CD-Drives.");
3141 SetTextXY(10, 11, "Press ENTER to reboot your computer.");
3143 SetStatusText(" Please wait ...");
3145 /* Destroy partition list */
3146 if (PartitionList
!= NULL
)
3148 DestroyPartitionList (PartitionList
);
3149 PartitionList
= NULL
;
3152 /* Destroy filesystem list */
3153 if (FileSystemList
!= NULL
)
3155 DestroyFileSystemList (FileSystemList
);
3156 FileSystemList
= NULL
;
3159 SetStatusText(" ENTER = Reboot computer");
3165 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
3167 return(REBOOT_PAGE
);
3174 SuccessPage(PINPUT_RECORD Ir
)
3176 SetTextXY(10, 6, "The basic components of ReactOS have been installed successfully.");
3178 SetTextXY(10, 8, "Remove floppy disk from Drive A: and");
3179 SetTextXY(10, 9, "all CD-ROMs from CD-Drive.");
3181 SetTextXY(10, 11, "Press ENTER to reboot your computer.");
3183 SetStatusText(" ENTER = Reboot computer");
3189 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
3191 return(REBOOT_PAGE
);
3198 NtProcessStartup(PPEB Peb
)
3204 RtlNormalizeProcessParams(Peb
->ProcessParameters
);
3206 ProcessHeap
= Peb
->ProcessHeap
;
3208 Status
= AllocConsole();
3209 if (!NT_SUCCESS(Status
))
3211 PrintString("AllocConsole() failed (Status = 0x%08lx)\n", Status
);
3213 /* Raise a hard error (crash the system/BSOD) */
3214 NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED
,
3219 /* Initialize global unicode strings */
3220 RtlInitUnicodeString(&SourcePath
, NULL
);
3221 RtlInitUnicodeString(&SourceRootPath
, NULL
);
3222 RtlInitUnicodeString(&InstallPath
, NULL
);
3223 RtlInitUnicodeString(&DestinationPath
, NULL
);
3224 RtlInitUnicodeString(&DestinationArcPath
, NULL
);
3225 RtlInitUnicodeString(&DestinationRootPath
, NULL
);
3226 RtlInitUnicodeString(&SystemRootPath
, NULL
);
3230 while (Page
!= REBOOT_PAGE
)
3234 SetUnderlinedTextXY(4, 3, " ReactOS " KERNEL_VERSION_STR
" Setup ");
3240 Page
= StartPage(&Ir
);
3245 Page
= IntroPage(&Ir
);
3249 case INSTALL_INTRO_PAGE
:
3250 Page
= InstallIntroPage(&Ir
);
3254 case OEM_DRIVER_PAGE
:
3255 Page
= OemDriverPage(&Ir
);
3260 case DEVICE_SETTINGS_PAGE
:
3263 case SELECT_PARTITION_PAGE
:
3264 Page
= SelectPartitionPage(&Ir
);
3267 case CREATE_PARTITION_PAGE
:
3268 Page
= CreatePartitionPage(&Ir
);
3271 case DELETE_PARTITION_PAGE
:
3272 Page
= DeletePartitionPage(&Ir
);
3275 case SELECT_FILE_SYSTEM_PAGE
:
3276 Page
= SelectFileSystemPage(&Ir
);
3279 case FORMAT_PARTITION_PAGE
:
3280 Page
= FormatPartitionPage(&Ir
);
3283 case CHECK_FILE_SYSTEM_PAGE
:
3284 Page
= CheckFileSystemPage(&Ir
);
3287 case INSTALL_DIRECTORY_PAGE
:
3288 Page
= InstallDirectoryPage(&Ir
);
3291 case PREPARE_COPY_PAGE
:
3292 Page
= PrepareCopyPage(&Ir
);
3295 case FILE_COPY_PAGE
:
3296 Page
= FileCopyPage(&Ir
);
3300 Page
= RegistryPage(&Ir
);
3303 case BOOT_LOADER_PAGE
:
3304 Page
= BootLoaderPage(&Ir
);
3309 case REPAIR_INTRO_PAGE
:
3310 Page
= RepairIntroPage(&Ir
);
3314 /* Emergency pages */
3315 case EMERGENCY_INTRO_PAGE
:
3316 Page
= EmergencyIntroPage(&Ir
);
3321 Page
= SuccessPage(&Ir
);
3325 Page
= QuitPage(&Ir
);
3332 NtShutdownSystem(ShutdownReboot
);