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].PartitionLength
.QuadPart
< (32ULL * 1024ULL * 1024ULL))
1594 /* FAT16 CHS partition (disk is smaller than 32MB) */
1595 PartEntry
->PartInfo
[0].PartitionType
= PARTITION_FAT_16
;
1597 else if (DiskEntry
->UseLba
== FALSE
)
1599 if (PartEntry
->PartInfo
[0].PartitionLength
.QuadPart
< (512ULL * 1024ULL * 1024ULL))
1601 /* FAT16 CHS partition (disk is smaller than 512MB) */
1602 PartEntry
->PartInfo
[0].PartitionType
= PARTITION_HUGE
;
1606 /* FAT32 CHS partition (partition size 512MB or larger) */
1607 PartEntry
->PartInfo
[0].PartitionType
= PARTITION_FAT32
;
1612 if (PartEntry
->PartInfo
[0].PartitionLength
.QuadPart
< (512ULL * 1024ULL * 1024ULL))
1614 /* FAT16 LBA partition (partition size is smaller than 512MB) */
1615 PartEntry
->PartInfo
[0].PartitionType
= PARTITION_XINT13
;
1619 /* FAT32 LBA partition (partition size 512MB or larger) */
1620 PartEntry
->PartInfo
[0].PartitionType
= PARTITION_FAT32_XINT13
;
1633 CheckActiveBootPartition (PartitionList
);
1637 "Disk: %I64u Cylinder: %I64u Track: %I64u",
1638 DiskEntry
->DiskSize
,
1639 DiskEntry
->CylinderSize
,
1640 DiskEntry
->TrackSize
);
1643 DiskEntry
= PartitionList
->CurrentDisk
;
1644 Entry
= DiskEntry
->PartListHead
.Flink
;
1645 while (Entry
!= &DiskEntry
->PartListHead
)
1647 PartEntry
= CONTAINING_RECORD(Entry
, PARTENTRY
, ListEntry
);
1649 if (PartEntry
->Unpartitioned
== FALSE
)
1652 for (i
= 0; i
< 4; i
++)
1654 PrintTextXY (6, Line
,
1655 "%2u: %2u %c %12I64u %12I64u %2u %c",
1657 PartEntry
->PartInfo
[i
].PartitionNumber
,
1658 PartEntry
->PartInfo
[i
].BootIndicator
? 'A' : '-',
1659 PartEntry
->PartInfo
[i
].StartingOffset
.QuadPart
,
1660 PartEntry
->PartInfo
[i
].PartitionLength
.QuadPart
,
1661 PartEntry
->PartInfo
[i
].PartitionType
,
1662 PartEntry
->PartInfo
[i
].RewritePartition
? '*' : ' ');
1670 Entry
= Entry
->Flink
;
1673 /* Restore the old entry */
1674 PartEntry
= PartitionList
->CurrentPartition
;
1677 if (WritePartitionsToDisk (PartitionList
) == FALSE
)
1679 DPRINT ("WritePartitionsToDisk() failed\n");
1681 PopupError ("Setup failed to write partition tables.\n",
1682 "ENTER = Reboot computer");
1688 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
1696 /* Set DestinationRootPath */
1697 RtlFreeUnicodeString (&DestinationRootPath
);
1698 swprintf (PathBuffer
,
1699 L
"\\Device\\Harddisk%lu\\Partition%lu",
1700 PartitionList
->CurrentDisk
->DiskNumber
,
1701 PartitionList
->CurrentPartition
->PartInfo
[0].PartitionNumber
);
1702 RtlCreateUnicodeString (&DestinationRootPath
,
1704 DPRINT ("DestinationRootPath: %wZ\n", &DestinationRootPath
);
1707 /* Set SystemRootPath */
1708 RtlFreeUnicodeString (&SystemRootPath
);
1709 swprintf (PathBuffer
,
1710 L
"\\Device\\Harddisk%lu\\Partition%lu",
1711 PartitionList
->ActiveBootDisk
->DiskNumber
,
1712 PartitionList
->ActiveBootPartition
->PartInfo
[0].PartitionNumber
);
1713 RtlCreateUnicodeString (&SystemRootPath
,
1715 DPRINT ("SystemRootPath: %wZ\n", &SystemRootPath
);
1718 switch (FileSystemList
->CurrentFileSystem
)
1721 Status
= FormatPartition (&DestinationRootPath
);
1722 if (!NT_SUCCESS (Status
))
1724 DPRINT1 ("FormatPartition() failed with status 0x%.08x\n", Status
);
1725 /* FIXME: show an error dialog */
1729 PartEntry
->New
= FALSE
;
1730 if (FileSystemList
!= NULL
)
1732 DestroyFileSystemList (FileSystemList
);
1733 FileSystemList
= NULL
;
1736 CheckActiveBootPartition (PartitionList
);
1738 /* FIXME: Install boot code. This is a hack! */
1739 if ((PartEntry
->PartInfo
[0].PartitionType
== PARTITION_FAT32_XINT13
) ||
1740 (PartEntry
->PartInfo
[0].PartitionType
== PARTITION_FAT32
))
1742 wcscpy (PathBuffer
, SourceRootPath
.Buffer
);
1743 wcscat (PathBuffer
, L
"\\loader\\fat32.bin");
1745 DPRINT1 ("Install FAT32 bootcode: %S ==> %S\n", PathBuffer
,
1746 DestinationRootPath
.Buffer
);
1747 Status
= InstallFat32BootCodeToDisk (PathBuffer
,
1748 DestinationRootPath
.Buffer
);
1749 if (!NT_SUCCESS (Status
))
1751 DPRINT1 ("InstallFat32BootCodeToDisk() failed with status 0x%.08x\n", Status
);
1752 /* FIXME: show an error dialog */
1758 wcscpy (PathBuffer
, SourceRootPath
.Buffer
);
1759 wcscat (PathBuffer
, L
"\\loader\\fat.bin");
1761 DPRINT1 ("Install FAT bootcode: %S ==> %S\n", PathBuffer
,
1762 DestinationRootPath
.Buffer
);
1763 Status
= InstallFat16BootCodeToDisk (PathBuffer
,
1764 DestinationRootPath
.Buffer
);
1765 if (!NT_SUCCESS (Status
))
1767 DPRINT1 ("InstallFat16BootCodeToDisk() failed with status 0x%.08x\n", Status
);
1768 /* FIXME: show an error dialog */
1781 SetStatusText (" Done. Press any key ...");
1784 return INSTALL_DIRECTORY_PAGE
;
1788 return FORMAT_PARTITION_PAGE
;
1793 CheckFileSystemPage(PINPUT_RECORD Ir
)
1795 WCHAR PathBuffer
[MAX_PATH
];
1797 SetTextXY(6, 8, "Check file system");
1799 SetTextXY(6, 10, "At present, ReactOS can not check file systems.");
1801 SetStatusText(" Please wait ...");
1804 SetStatusText(" ENTER = Continue F3 = Quit");
1807 /* Set DestinationRootPath */
1808 RtlFreeUnicodeString (&DestinationRootPath
);
1809 swprintf (PathBuffer
,
1810 L
"\\Device\\Harddisk%lu\\Partition%lu",
1811 PartitionList
->CurrentDisk
->DiskNumber
,
1812 PartitionList
->CurrentPartition
->PartInfo
[0].PartitionNumber
);
1813 RtlCreateUnicodeString (&DestinationRootPath
,
1815 DPRINT ("DestinationRootPath: %wZ\n", &DestinationRootPath
);
1817 /* Set SystemRootPath */
1818 RtlFreeUnicodeString (&SystemRootPath
);
1819 swprintf (PathBuffer
,
1820 L
"\\Device\\Harddisk%lu\\Partition%lu",
1821 PartitionList
->ActiveBootDisk
->DiskNumber
,
1822 PartitionList
->ActiveBootPartition
->PartInfo
[0].PartitionNumber
);
1823 RtlCreateUnicodeString (&SystemRootPath
,
1825 DPRINT ("SystemRootPath: %wZ\n", &SystemRootPath
);
1832 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1833 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1835 if (ConfirmQuit(Ir
) == TRUE
)
1839 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
1841 return(INSTALL_DIRECTORY_PAGE
);
1845 return(CHECK_FILE_SYSTEM_PAGE
);
1850 InstallDirectoryPage(PINPUT_RECORD Ir
)
1852 PDISKENTRY DiskEntry
;
1853 PPARTENTRY PartEntry
;
1854 WCHAR PathBuffer
[MAX_PATH
];
1855 WCHAR InstallDir
[51];
1861 if (PartitionList
== NULL
||
1862 PartitionList
->CurrentDisk
== NULL
||
1863 PartitionList
->CurrentPartition
== NULL
)
1865 /* FIXME: show an error dialog */
1869 DiskEntry
= PartitionList
->CurrentDisk
;
1870 PartEntry
= PartitionList
->CurrentPartition
;
1872 /* Search for 'DefaultPath' in the 'SetupData' section */
1873 if (!InfFindFirstLine (SetupInf
, L
"SetupData", L
"DefaultPath", &Context
))
1875 PopupError("Setup failed to find the 'SetupData' section\n"
1876 "in TXTSETUP.SIF.\n",
1877 "ENTER = Reboot computer");
1883 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
1890 /* Read the 'DefaultPath' data */
1891 if (InfGetData (&Context
, NULL
, &DefaultPath
))
1893 wcscpy(InstallDir
, DefaultPath
);
1897 wcscpy(InstallDir
, L
"\\ReactOS");
1899 Length
= wcslen(InstallDir
);
1901 SetTextXY(6, 8, "Setup installs ReactOS files onto the selected partition. Choose a");
1902 SetTextXY(6, 9, "directory where you want ReactOS to be installed:");
1904 SetInputTextXY(8, 11, 51, InstallDir
);
1906 SetTextXY(6, 14, "To change the suggested directory, press BACKSPACE to delete");
1907 SetTextXY(6, 15, "characters and then type the directory where you want ReactOS to");
1908 SetTextXY(6, 16, "be installed.");
1910 SetStatusText(" ENTER = Continue F3 = Quit");
1916 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1917 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1919 if (ConfirmQuit(Ir
) == TRUE
)
1923 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
1925 /* Create 'InstallPath' string */
1926 RtlFreeUnicodeString(&InstallPath
);
1927 RtlCreateUnicodeString(&InstallPath
,
1930 /* Create 'DestinationPath' string */
1931 RtlFreeUnicodeString(&DestinationPath
);
1933 DestinationRootPath
.Buffer
);
1934 if (InstallDir
[0] != L
'\\')
1937 wcscat(PathBuffer
, InstallDir
);
1938 RtlCreateUnicodeString(&DestinationPath
,
1941 /* Create 'DestinationArcPath' */
1942 RtlFreeUnicodeString(&DestinationArcPath
);
1943 swprintf(PathBuffer
,
1944 L
"multi(0)disk(0)rdisk(%lu)partition(%lu)",
1945 DiskEntry
->DiskNumber
,
1946 PartEntry
->PartInfo
[0].PartitionNumber
);
1947 if (InstallDir
[0] != L
'\\')
1950 wcscat(PathBuffer
, InstallDir
);
1951 RtlCreateUnicodeString(&DestinationArcPath
,
1954 return(PREPARE_COPY_PAGE
);
1956 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x08) /* BACKSPACE */
1961 InstallDir
[Length
] = 0;
1962 SetInputTextXY(8, 11, 51, InstallDir
);
1965 else if (isprint(Ir
->Event
.KeyEvent
.uChar
.AsciiChar
))
1969 InstallDir
[Length
] = (WCHAR
)Ir
->Event
.KeyEvent
.uChar
.AsciiChar
;
1971 InstallDir
[Length
] = 0;
1972 SetInputTextXY(8, 11, 51, InstallDir
);
1977 return(INSTALL_DIRECTORY_PAGE
);
1982 PrepareCopyPageInfFile(HINF InfFile
, PWCHAR SourceCabinet
, PINPUT_RECORD Ir
)
1984 WCHAR PathBuffer
[MAX_PATH
];
1985 INFCONTEXT FilesContext
;
1986 INFCONTEXT DirContext
;
1992 PWCHAR FileKeyValue
;
1996 /* Search for the 'SourceFiles' section */
1997 if (!InfFindFirstLine (InfFile
, L
"SourceFiles", NULL
, &FilesContext
))
1999 PopupError("Setup failed to find the 'SourceFiles' section\n"
2000 "in TXTSETUP.SIF.\n", // FIXME
2001 "ENTER = Reboot computer");
2007 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2015 * Enumerate the files in the 'SourceFiles' section
2016 * and add them to the file queue.
2020 if (!InfGetData (&FilesContext
, &FileKeyName
, &FileKeyValue
))
2026 DPRINT ("FileKeyName: '%S' FileKeyValue: '%S'\n", FileKeyName
, FileKeyValue
);
2028 /* Lookup target directory */
2029 if (!InfFindFirstLine (InfFile
, L
"Directories", FileKeyValue
, &DirContext
))
2031 /* FIXME: Handle error! */
2032 DPRINT1("InfFindFirstLine() failed\n");
2036 if (!InfGetData (&DirContext
, NULL
, &DirKeyValue
))
2038 /* FIXME: Handle error! */
2039 DPRINT1("InfGetData() failed\n");
2043 if (!SetupQueueCopy(SetupFileQueue
,
2045 SourceRootPath
.Buffer
,
2051 /* FIXME: Handle error! */
2052 DPRINT1("SetupQueueCopy() failed\n");
2055 while (InfFindNextLine(&FilesContext
, &FilesContext
));
2058 /* Create directories */
2062 * Install directories like '\reactos\test' are not handled yet.
2065 /* Get destination path */
2066 wcscpy(PathBuffer
, DestinationPath
.Buffer
);
2068 /* Remove trailing backslash */
2069 Length
= wcslen(PathBuffer
);
2070 if ((Length
> 0) && (PathBuffer
[Length
- 1] == '\\'))
2072 PathBuffer
[Length
- 1] = 0;
2075 /* Create the install directory */
2076 Status
= CreateDirectory(PathBuffer
);
2077 if (!NT_SUCCESS(Status
) && Status
!= STATUS_OBJECT_NAME_COLLISION
)
2079 DPRINT("Creating directory '%S' failed: Status = 0x%08lx", PathBuffer
, Status
);
2080 PopupError("Setup could not create the install directory.",
2081 "ENTER = Reboot computer");
2087 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2095 /* Search for the 'Directories' section */
2096 if (!InfFindFirstLine(InfFile
, L
"Directories", NULL
, &DirContext
))
2100 PopupError("Setup failed to find the 'Directories' section\n"
2101 "in the cabinet.\n", "ENTER = Reboot computer");
2105 PopupError("Setup failed to find the 'Directories' section\n"
2106 "in TXTSETUP.SIF.\n", "ENTER = Reboot computer");
2113 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2120 /* Enumerate the directory values and create the subdirectories */
2123 if (!InfGetData (&DirContext
, NULL
, &KeyValue
))
2129 if (KeyValue
[0] == L
'\\' && KeyValue
[1] != 0)
2131 DPRINT("Absolute Path: '%S'\n", KeyValue
);
2133 wcscpy(PathBuffer
, DestinationRootPath
.Buffer
);
2134 wcscat(PathBuffer
, KeyValue
);
2136 DPRINT("FullPath: '%S'\n", PathBuffer
);
2138 else if (KeyValue
[0] != L
'\\')
2140 DPRINT("RelativePath: '%S'\n", KeyValue
);
2141 wcscpy(PathBuffer
, DestinationPath
.Buffer
);
2142 wcscat(PathBuffer
, L
"\\");
2143 wcscat(PathBuffer
, KeyValue
);
2145 DPRINT("FullPath: '%S'\n", PathBuffer
);
2147 Status
= CreateDirectory(PathBuffer
);
2148 if (!NT_SUCCESS(Status
) && Status
!= STATUS_OBJECT_NAME_COLLISION
)
2150 DPRINT("Creating directory '%S' failed: Status = 0x%08lx", PathBuffer
, Status
);
2151 PopupError("Setup could not create install directories.",
2152 "ENTER = Reboot computer");
2158 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2166 while (InfFindNextLine (&DirContext
, &DirContext
));
2173 PrepareCopyPage(PINPUT_RECORD Ir
)
2177 WCHAR PathBuffer
[MAX_PATH
];
2178 INFCONTEXT CabinetsContext
;
2185 SetTextXY(6, 8, "Setup prepares your computer for copying the ReactOS files. ");
2189 * Build the file copy list
2191 SetStatusText(" Building the file copy list...");
2193 /* Create the file queue */
2194 SetupFileQueue
= SetupOpenFileQueue();
2195 if (SetupFileQueue
== NULL
)
2197 PopupError("Setup failed to open the copy file queue.\n",
2198 "ENTER = Reboot computer");
2204 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2212 if (!PrepareCopyPageInfFile(SetupInf
, NULL
, Ir
))
2218 /* Search for the 'Cabinets' section */
2219 if (!InfFindFirstLine (SetupInf
, L
"Cabinets", NULL
, &CabinetsContext
))
2221 PopupError("Setup failed to find the 'Cabinets' section\n"
2222 "in TXTSETUP.SIF.\n",
2223 "ENTER = Reboot computer");
2229 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2238 * Enumerate the directory values in the 'Cabinets'
2239 * section and parse their inf files.
2243 if (!InfGetData (&CabinetsContext
, NULL
, &KeyValue
))
2246 wcscpy(PathBuffer
, SourcePath
.Buffer
);
2247 wcscat(PathBuffer
, L
"\\");
2248 wcscat(PathBuffer
, KeyValue
);
2250 CabinetInitialize();
2251 CabinetSetEventHandlers(NULL
, NULL
, NULL
);
2252 CabinetSetCabinetName(PathBuffer
);
2254 if (CabinetOpen() == CAB_STATUS_SUCCESS
)
2256 DPRINT("Cabinet %S\n", CabinetGetCabinetName());
2258 InfFileData
= CabinetGetCabinetReservedArea(&InfFileSize
);
2259 if (InfFileData
== NULL
)
2261 PopupError("Cabinet has no setup script.\n",
2262 "ENTER = Reboot computer");
2268 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2277 DPRINT("Cannot open cabinet: %S.\n", CabinetGetCabinetName());
2279 PopupError("Cabinet not found.\n", "ENTER = Reboot computer");
2285 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2292 Status
= InfOpenBufferedFile(&InfHandle
,
2296 if (!NT_SUCCESS(Status
))
2298 PopupError("Cabinet has no valid inf file.\n",
2299 "ENTER = Reboot computer");
2305 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2314 if (!PrepareCopyPageInfFile(InfHandle
, KeyValue
, Ir
))
2319 while (InfFindNextLine (&CabinetsContext
, &CabinetsContext
));
2321 return(FILE_COPY_PAGE
);
2326 FileCopyCallback(PVOID Context
,
2331 PCOPYCONTEXT CopyContext
;
2333 CopyContext
= (PCOPYCONTEXT
)Context
;
2335 switch (Notification
)
2337 case SPFILENOTIFY_STARTSUBQUEUE
:
2338 CopyContext
->TotalOperations
= (ULONG
)Param2
;
2339 ProgressSetStepCount(CopyContext
->ProgressBar
,
2340 CopyContext
->TotalOperations
);
2343 case SPFILENOTIFY_STARTCOPY
:
2344 /* Display copy message */
2345 PrintTextXYN(6, 16, 60, "Copying file: %S", (PWSTR
)Param1
);
2347 PrintTextXYN(6, 18, 60, "File %lu of %lu",
2348 CopyContext
->CompletedOperations
+ 1,
2349 CopyContext
->TotalOperations
);
2352 case SPFILENOTIFY_ENDCOPY
:
2353 CopyContext
->CompletedOperations
++;
2354 ProgressNextStep(CopyContext
->ProgressBar
);
2363 FileCopyPage(PINPUT_RECORD Ir
)
2365 COPYCONTEXT CopyContext
;
2369 SetStatusText(" Please wait...");
2371 SetTextXY(6, 8, "Copying files");
2373 GetScreenSize(&xScreen
, &yScreen
);
2375 CopyContext
.TotalOperations
= 0;
2376 CopyContext
.CompletedOperations
= 0;
2377 CopyContext
.ProgressBar
= CreateProgressBar(6,
2382 SetupCommitFileQueue(SetupFileQueue
,
2383 DestinationRootPath
.Buffer
,
2385 (PSP_FILE_CALLBACK
)FileCopyCallback
,
2388 SetupCloseFileQueue(SetupFileQueue
);
2390 DestroyProgressBar(CopyContext
.ProgressBar
);
2392 return(REGISTRY_PAGE
);
2397 RegistryPage(PINPUT_RECORD Ir
)
2399 INFCONTEXT InfContext
;
2408 SetTextXY(6, 8, "Setup is updating the system configuration");
2410 SetStatusText(" Creating registry hives...");
2412 if (!SetInstallPathValue(&DestinationPath
))
2414 DPRINT("SetInstallPathValue() failed\n");
2415 PopupError("Setup failed to set the initialize the registry.",
2416 "ENTER = Reboot computer");
2422 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2429 /* Create the default hives */
2430 Status
= NtInitializeRegistry(TRUE
);
2431 if (!NT_SUCCESS(Status
))
2433 DPRINT("NtInitializeRegistry() failed (Status %lx)\n", Status
);
2434 PopupError("Setup failed to create the registry hives.",
2435 "ENTER = Reboot computer");
2441 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2448 /* Update registry */
2449 SetStatusText(" Updating registry hives...");
2451 if (!InfFindFirstLine(SetupInf
, L
"HiveInfs.Install", NULL
, &InfContext
))
2453 DPRINT1("InfFindFirstLine() failed\n");
2454 PopupError("Setup failed to find the registry data files.",
2455 "ENTER = Reboot computer");
2461 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2470 InfGetDataField (&InfContext
, 0, &Action
);
2471 InfGetDataField (&InfContext
, 1, &File
);
2472 InfGetDataField (&InfContext
, 2, &Section
);
2474 DPRINT1("Action: %S File: %S Section %S\n", Action
, File
, Section
);
2476 if (!_wcsicmp (Action
, L
"AddReg"))
2480 else if (!_wcsicmp (Action
, L
"DelReg"))
2489 SetStatusText(" Importing %S...", File
);
2491 if (!ImportRegistryFile(File
, Section
, Delete
))
2493 DPRINT1("Importing %S failed\n", File
);
2495 PopupError("Setup failed to import a hive file.",
2496 "ENTER = Reboot computer");
2502 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2509 while (InfFindNextLine (&InfContext
, &InfContext
));
2511 SetStatusText(" Done...");
2513 return(BOOT_LOADER_PAGE
);
2518 BootLoaderPage(PINPUT_RECORD Ir
)
2520 WCHAR SrcPath
[MAX_PATH
];
2521 WCHAR DstPath
[MAX_PATH
];
2523 PINICACHESECTION IniSection
;
2526 SetTextXY(6, 8, "Installing the boot loader");
2528 SetStatusText(" Please wait...");
2530 if (PartitionList
->ActiveBootPartition
->PartInfo
[0].PartitionType
== PARTITION_ENTRY_UNUSED
)
2532 DPRINT1("Error: active partition invalid (unused)\n");
2533 PopupError("The active partition is unused (invalid).\n",
2534 "ENTER = Reboot computer");
2540 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2546 if (PartitionList
->ActiveBootPartition
->PartInfo
[0].PartitionType
== 0x0A)
2548 /* OS/2 boot manager partition */
2549 DPRINT1("Found OS/2 boot manager partition\n");
2550 PopupError("Setup found an OS/2 boot manager partiton.\n"
2551 "The OS/2 boot manager is not supported yet!",
2552 "ENTER = Reboot computer");
2558 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2564 else if (PartitionList
->ActiveBootPartition
->PartInfo
[0].PartitionType
== 0x83)
2566 /* Linux ext2 partition */
2567 DPRINT1("Found Linux ext2 partition\n");
2568 PopupError("Setup found a Linux ext2 partiton.\n"
2569 "Linux ext2 partitions are not supported yet!",
2570 "ENTER = Reboot computer");
2576 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2582 else if (PartitionList
->ActiveBootPartition
->PartInfo
[0].PartitionType
== PARTITION_IFS
)
2584 /* NTFS partition */
2585 DPRINT1("Found NTFS partition\n");
2586 PopupError("Setup found an NTFS partiton.\n"
2587 "NTFS partitions are not supported yet!",
2588 "ENTER = Reboot computer");
2594 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2600 else if ((PartitionList
->ActiveBootPartition
->PartInfo
[0].PartitionType
== PARTITION_FAT_12
) ||
2601 (PartitionList
->ActiveBootPartition
->PartInfo
[0].PartitionType
== PARTITION_FAT_16
) ||
2602 (PartitionList
->ActiveBootPartition
->PartInfo
[0].PartitionType
== PARTITION_HUGE
) ||
2603 (PartitionList
->ActiveBootPartition
->PartInfo
[0].PartitionType
== PARTITION_XINT13
) ||
2604 (PartitionList
->ActiveBootPartition
->PartInfo
[0].PartitionType
== PARTITION_FAT32
) ||
2605 (PartitionList
->ActiveBootPartition
->PartInfo
[0].PartitionType
== PARTITION_FAT32_XINT13
))
2607 /* FAT or FAT32 partition */
2608 DPRINT1("System path: '%wZ'\n", &SystemRootPath
);
2610 if (DoesFileExist(SystemRootPath
.Buffer
, L
"ntldr") == TRUE
||
2611 DoesFileExist(SystemRootPath
.Buffer
, L
"boot.ini") == TRUE
)
2613 /* Search root directory for 'ntldr' and 'boot.ini'. */
2614 DPRINT1("Found Microsoft Windows NT/2000/XP boot loader\n");
2616 /* Copy FreeLoader to the boot partition */
2617 wcscpy(SrcPath
, SourceRootPath
.Buffer
);
2618 wcscat(SrcPath
, L
"\\loader\\freeldr.sys");
2619 wcscpy(DstPath
, SystemRootPath
.Buffer
);
2620 wcscat(DstPath
, L
"\\freeldr.sys");
2622 DPRINT1("Copy: %S ==> %S\n", SrcPath
, DstPath
);
2623 Status
= SetupCopyFile(SrcPath
, DstPath
);
2624 if (!NT_SUCCESS(Status
))
2626 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status
);
2627 PopupError("Setup failed to copy 'freeldr.sys'.",
2628 "ENTER = Reboot computer");
2634 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2641 /* Create or update freeldr.ini */
2642 if (DoesFileExist(SystemRootPath
.Buffer
, L
"freeldr.ini") == FALSE
)
2644 /* Create new 'freeldr.ini' */
2645 DPRINT1("Create new 'freeldr.ini'\n");
2646 wcscpy(DstPath
, SystemRootPath
.Buffer
);
2647 wcscat(DstPath
, L
"\\freeldr.ini");
2649 Status
= CreateFreeLoaderIniForReactos(DstPath
,
2650 DestinationArcPath
.Buffer
);
2651 if (!NT_SUCCESS(Status
))
2653 DPRINT1("CreateFreeLoaderIniForReactos() failed (Status %lx)\n", Status
);
2654 PopupError("Setup failed to create 'freeldr.ini'.",
2655 "ENTER = Reboot computer");
2661 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2668 /* Install new bootcode */
2669 if ((PartitionList
->ActiveBootPartition
->PartInfo
[0].PartitionType
== PARTITION_FAT32
) ||
2670 (PartitionList
->ActiveBootPartition
->PartInfo
[0].PartitionType
== PARTITION_FAT32_XINT13
))
2672 /* Install FAT32 bootcode */
2673 wcscpy(SrcPath
, SourceRootPath
.Buffer
);
2674 wcscat(SrcPath
, L
"\\loader\\fat32.bin");
2675 wcscpy(DstPath
, SystemRootPath
.Buffer
);
2676 wcscat(DstPath
, L
"\\bootsect.ros");
2678 DPRINT1("Install FAT32 bootcode: %S ==> %S\n", SrcPath
, DstPath
);
2679 Status
= InstallFat32BootCodeToFile(SrcPath
,
2681 SystemRootPath
.Buffer
);
2682 if (!NT_SUCCESS(Status
))
2684 DPRINT1("InstallFat32BootCodeToFile() failed (Status %lx)\n", Status
);
2685 PopupError("Setup failed to install the FAT32 bootcode.",
2686 "ENTER = Reboot computer");
2692 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2701 /* Install FAT16 bootcode */
2702 wcscpy(SrcPath
, SourceRootPath
.Buffer
);
2703 wcscat(SrcPath
, L
"\\loader\\fat.bin");
2704 wcscpy(DstPath
, SystemRootPath
.Buffer
);
2705 wcscat(DstPath
, L
"\\bootsect.ros");
2707 DPRINT1("Install FAT bootcode: %S ==> %S\n", SrcPath
, DstPath
);
2708 Status
= InstallFat16BootCodeToFile(SrcPath
,
2710 SystemRootPath
.Buffer
);
2711 if (!NT_SUCCESS(Status
))
2713 DPRINT1("InstallFat16BootCodeToFile() failed (Status %lx)\n", Status
);
2714 PopupError("Setup failed to install the FAT bootcode.",
2715 "ENTER = Reboot computer");
2721 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2729 /* Update 'boot.ini' */
2730 wcscpy(DstPath
, SystemRootPath
.Buffer
);
2731 wcscat(DstPath
, L
"\\boot.ini");
2733 DPRINT1("Update 'boot.ini': %S\n", DstPath
);
2734 Status
= UpdateBootIni(DstPath
,
2735 L
"C:\\bootsect.ros",
2737 if (!NT_SUCCESS(Status
))
2739 DPRINT1("UpdateBootIni() failed (Status %lx)\n", Status
);
2740 PopupError("Setup failed to update \'boot.ini\'.",
2741 "ENTER = Reboot computer");
2747 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2756 /* Update existing 'freeldr.ini' */
2757 DPRINT1("Update existing 'freeldr.ini'\n");
2758 wcscpy(DstPath
, SystemRootPath
.Buffer
);
2759 wcscat(DstPath
, L
"\\freeldr.ini");
2761 Status
= UpdateFreeLoaderIni(DstPath
,
2762 DestinationArcPath
.Buffer
);
2763 if (!NT_SUCCESS(Status
))
2765 DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status
);
2766 PopupError("Setup failed to update 'freeldr.ini'.",
2767 "ENTER = Reboot computer");
2773 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2781 else if (DoesFileExist(SystemRootPath
.Buffer
, L
"io.sys") == TRUE
||
2782 DoesFileExist(SystemRootPath
.Buffer
, L
"msdos.sys") == TRUE
)
2784 /* Search for root directory for 'io.sys' and 'msdos.sys'. */
2785 DPRINT1("Found Microsoft DOS or Windows 9x boot loader\n");
2787 /* Copy FreeLoader to the boot partition */
2788 wcscpy(SrcPath
, SourceRootPath
.Buffer
);
2789 wcscat(SrcPath
, L
"\\loader\\freeldr.sys");
2790 wcscpy(DstPath
, SystemRootPath
.Buffer
);
2791 wcscat(DstPath
, L
"\\freeldr.sys");
2793 DPRINT("Copy: %S ==> %S\n", SrcPath
, DstPath
);
2794 Status
= SetupCopyFile(SrcPath
, DstPath
);
2795 if (!NT_SUCCESS(Status
))
2797 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status
);
2798 PopupError("Setup failed to copy 'freeldr.sys'.",
2799 "ENTER = Reboot computer");
2805 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2812 /* Create or update 'freeldr.ini' */
2813 if (DoesFileExist(SystemRootPath
.Buffer
, L
"freeldr.ini") == FALSE
)
2815 /* Create new 'freeldr.ini' */
2816 DPRINT1("Create new 'freeldr.ini'\n");
2817 wcscpy(DstPath
, SystemRootPath
.Buffer
);
2818 wcscat(DstPath
, L
"\\freeldr.ini");
2820 Status
= CreateFreeLoaderIniForDos(DstPath
,
2821 DestinationArcPath
.Buffer
);
2822 if (!NT_SUCCESS(Status
))
2824 DPRINT1("CreateFreeLoaderIniForDos() failed (Status %lx)\n", Status
);
2825 PopupError("Setup failed to create 'freeldr.ini'.",
2826 "ENTER = Reboot computer");
2832 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2839 /* Save current bootsector as 'BOOTSECT.DOS' */
2840 wcscpy(SrcPath
, SystemRootPath
.Buffer
);
2841 wcscpy(DstPath
, SystemRootPath
.Buffer
);
2842 wcscat(DstPath
, L
"\\bootsect.dos");
2844 DPRINT1("Save bootsector: %S ==> %S\n", SrcPath
, DstPath
);
2845 Status
= SaveCurrentBootSector(SrcPath
,
2847 if (!NT_SUCCESS(Status
))
2849 DPRINT1("SaveCurrentBootSector() failed (Status %lx)\n", Status
);
2850 PopupError("Setup failed to save the current bootsector.",
2851 "ENTER = Reboot computer");
2857 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2864 /* Install new bootsector */
2865 if ((PartitionList
->ActiveBootPartition
->PartInfo
[0].PartitionType
== PARTITION_FAT32
) ||
2866 (PartitionList
->ActiveBootPartition
->PartInfo
[0].PartitionType
== PARTITION_FAT32_XINT13
))
2868 wcscpy(SrcPath
, SourceRootPath
.Buffer
);
2869 wcscat(SrcPath
, L
"\\loader\\fat32.bin");
2871 DPRINT1("Install FAT32 bootcode: %S ==> %S\n", SrcPath
, SystemRootPath
.Buffer
);
2872 Status
= InstallFat32BootCodeToDisk(SrcPath
,
2873 SystemRootPath
.Buffer
);
2874 if (!NT_SUCCESS(Status
))
2876 DPRINT1("InstallFat32BootCodeToDisk() failed (Status %lx)\n", Status
);
2877 PopupError("Setup failed to install the FAT32 bootcode.",
2878 "ENTER = Reboot computer");
2884 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2893 wcscpy(SrcPath
, SourceRootPath
.Buffer
);
2894 wcscat(SrcPath
, L
"\\loader\\fat.bin");
2896 DPRINT1("Install FAT bootcode: %S ==> %S\n", SrcPath
, SystemRootPath
.Buffer
);
2897 Status
= InstallFat16BootCodeToDisk(SrcPath
,
2898 SystemRootPath
.Buffer
);
2899 if (!NT_SUCCESS(Status
))
2901 DPRINT1("InstallFat16BootCodeToDisk() failed (Status %lx)\n", Status
);
2902 PopupError("Setup failed to install the FAT bootcode.",
2903 "ENTER = Reboot computer");
2909 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2919 /* Update existing 'freeldr.ini' */
2920 wcscpy(DstPath
, SystemRootPath
.Buffer
);
2921 wcscat(DstPath
, L
"\\freeldr.ini");
2923 Status
= UpdateFreeLoaderIni(DstPath
,
2924 DestinationArcPath
.Buffer
);
2925 if (!NT_SUCCESS(Status
))
2927 DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status
);
2928 PopupError("Setup failed to update 'freeldr.ini'.",
2929 "ENTER = Reboot computer");
2935 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2945 /* No or unknown boot loader */
2946 DPRINT1("No or unknown boot loader found\n");
2948 /* Copy FreeLoader to the boot partition */
2949 wcscpy(SrcPath
, SourceRootPath
.Buffer
);
2950 wcscat(SrcPath
, L
"\\loader\\freeldr.sys");
2951 wcscpy(DstPath
, SystemRootPath
.Buffer
);
2952 wcscat(DstPath
, L
"\\freeldr.sys");
2954 DPRINT1("Copy: %S ==> %S\n", SrcPath
, DstPath
);
2955 Status
= SetupCopyFile(SrcPath
, DstPath
);
2956 if (!NT_SUCCESS(Status
))
2958 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status
);
2959 PopupError("Setup failed to copy 'freeldr.sys'.",
2960 "ENTER = Reboot computer");
2966 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2973 /* Create or update 'freeldr.ini' */
2974 if (DoesFileExist(SystemRootPath
.Buffer
, L
"freeldr.ini") == FALSE
)
2976 /* Create new freeldr.ini */
2977 wcscpy(DstPath
, SystemRootPath
.Buffer
);
2978 wcscat(DstPath
, L
"\\freeldr.ini");
2980 DPRINT1("Copy: %S ==> %S\n", SrcPath
, DstPath
);
2981 Status
= CreateFreeLoaderIniForReactos(DstPath
,
2982 DestinationArcPath
.Buffer
);
2983 if (!NT_SUCCESS(Status
))
2985 DPRINT1("CreateFreeLoaderIniForReactos() failed (Status %lx)\n", Status
);
2986 PopupError("Setup failed to create \'freeldr.ini\'.",
2987 "ENTER = Reboot computer");
2993 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
3000 /* Save current bootsector as 'BOOTSECT.OLD' */
3001 wcscpy(SrcPath
, SystemRootPath
.Buffer
);
3002 wcscpy(DstPath
, SystemRootPath
.Buffer
);
3003 wcscat(DstPath
, L
"\\bootsect.old");
3005 DPRINT1("Save bootsector: %S ==> %S\n", SrcPath
, DstPath
);
3006 Status
= SaveCurrentBootSector(SrcPath
,
3008 if (!NT_SUCCESS(Status
))
3010 DPRINT1("SaveCurrentBootSector() failed (Status %lx)\n", Status
);
3011 PopupError("Setup failed save the current bootsector.",
3012 "ENTER = Reboot computer");
3018 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
3025 /* Install new bootsector */
3026 if ((PartitionList
->ActiveBootPartition
->PartInfo
[0].PartitionType
== PARTITION_FAT32
) ||
3027 (PartitionList
->ActiveBootPartition
->PartInfo
[0].PartitionType
== PARTITION_FAT32_XINT13
))
3029 wcscpy(SrcPath
, SourceRootPath
.Buffer
);
3030 wcscat(SrcPath
, L
"\\loader\\fat32.bin");
3032 DPRINT1("Install FAT32 bootcode: %S ==> %S\n", SrcPath
, SystemRootPath
.Buffer
);
3033 Status
= InstallFat32BootCodeToDisk(SrcPath
,
3034 SystemRootPath
.Buffer
);
3035 if (!NT_SUCCESS(Status
))
3037 DPRINT1("InstallFat32BootCodeToDisk() failed (Status %lx)\n", Status
);
3038 PopupError("Setup failed to install the FAT32 bootcode.",
3039 "ENTER = Reboot computer");
3045 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
3054 wcscpy(SrcPath
, SourceRootPath
.Buffer
);
3055 wcscat(SrcPath
, L
"\\loader\\fat.bin");
3057 DPRINT1("Install FAT bootcode: %S ==> %S\n", SrcPath
, SystemRootPath
.Buffer
);
3058 Status
= InstallFat16BootCodeToDisk(SrcPath
,
3059 SystemRootPath
.Buffer
);
3060 if (!NT_SUCCESS(Status
))
3062 DPRINT1("InstallFat16BootCodeToDisk() failed (Status %lx)\n", Status
);
3063 PopupError("Setup failed to install the FAT bootcode.",
3064 "ENTER = Reboot computer");
3070 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
3080 /* Update existing 'freeldr.ini' */
3081 wcscpy(DstPath
, SystemRootPath
.Buffer
);
3082 wcscat(DstPath
, L
"\\freeldr.ini");
3084 Status
= UpdateFreeLoaderIni(DstPath
,
3085 DestinationArcPath
.Buffer
);
3086 if (!NT_SUCCESS(Status
))
3088 DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status
);
3089 PopupError("Setup failed to update 'freeldr.ini'.",
3090 "ENTER = Reboot computer");
3096 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
3107 /* Unknown partition */
3108 DPRINT1("Unknown partition found\n");
3109 PopupError("Setup found an unknown partiton type.\n"
3110 "This partition type is not supported!",
3111 "ENTER = Reboot computer");
3117 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
3124 return(SUCCESS_PAGE
);
3130 QuitPage(PINPUT_RECORD Ir
)
3132 SetTextXY(10, 6, "ReactOS is not completely installed");
3134 SetTextXY(10, 8, "Remove floppy disk from Drive A: and");
3135 SetTextXY(10, 9, "all CD-ROMs from CD-Drives.");
3137 SetTextXY(10, 11, "Press ENTER to reboot your computer.");
3139 SetStatusText(" Please wait ...");
3141 /* Destroy partition list */
3142 if (PartitionList
!= NULL
)
3144 DestroyPartitionList (PartitionList
);
3145 PartitionList
= NULL
;
3148 /* Destroy filesystem list */
3149 if (FileSystemList
!= NULL
)
3151 DestroyFileSystemList (FileSystemList
);
3152 FileSystemList
= NULL
;
3155 SetStatusText(" ENTER = Reboot computer");
3161 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
3163 return(REBOOT_PAGE
);
3170 SuccessPage(PINPUT_RECORD Ir
)
3172 SetTextXY(10, 6, "The basic components of ReactOS have been installed successfully.");
3174 SetTextXY(10, 8, "Remove floppy disk from Drive A: and");
3175 SetTextXY(10, 9, "all CD-ROMs from CD-Drive.");
3177 SetTextXY(10, 11, "Press ENTER to reboot your computer.");
3179 SetStatusText(" ENTER = Reboot computer");
3185 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
3187 return(REBOOT_PAGE
);
3194 NtProcessStartup(PPEB Peb
)
3200 RtlNormalizeProcessParams(Peb
->ProcessParameters
);
3202 ProcessHeap
= Peb
->ProcessHeap
;
3204 Status
= AllocConsole();
3205 if (!NT_SUCCESS(Status
))
3207 PrintString("AllocConsole() failed (Status = 0x%08lx)\n", Status
);
3209 /* Raise a hard error (crash the system/BSOD) */
3210 NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED
,
3215 /* Initialize global unicode strings */
3216 RtlInitUnicodeString(&SourcePath
, NULL
);
3217 RtlInitUnicodeString(&SourceRootPath
, NULL
);
3218 RtlInitUnicodeString(&InstallPath
, NULL
);
3219 RtlInitUnicodeString(&DestinationPath
, NULL
);
3220 RtlInitUnicodeString(&DestinationArcPath
, NULL
);
3221 RtlInitUnicodeString(&DestinationRootPath
, NULL
);
3222 RtlInitUnicodeString(&SystemRootPath
, NULL
);
3226 while (Page
!= REBOOT_PAGE
)
3230 SetUnderlinedTextXY(4, 3, " ReactOS " KERNEL_VERSION_STR
" Setup ");
3236 Page
= StartPage(&Ir
);
3241 Page
= IntroPage(&Ir
);
3245 case INSTALL_INTRO_PAGE
:
3246 Page
= InstallIntroPage(&Ir
);
3250 case OEM_DRIVER_PAGE
:
3251 Page
= OemDriverPage(&Ir
);
3256 case DEVICE_SETTINGS_PAGE
:
3259 case SELECT_PARTITION_PAGE
:
3260 Page
= SelectPartitionPage(&Ir
);
3263 case CREATE_PARTITION_PAGE
:
3264 Page
= CreatePartitionPage(&Ir
);
3267 case DELETE_PARTITION_PAGE
:
3268 Page
= DeletePartitionPage(&Ir
);
3271 case SELECT_FILE_SYSTEM_PAGE
:
3272 Page
= SelectFileSystemPage(&Ir
);
3275 case FORMAT_PARTITION_PAGE
:
3276 Page
= FormatPartitionPage(&Ir
);
3279 case CHECK_FILE_SYSTEM_PAGE
:
3280 Page
= CheckFileSystemPage(&Ir
);
3283 case INSTALL_DIRECTORY_PAGE
:
3284 Page
= InstallDirectoryPage(&Ir
);
3287 case PREPARE_COPY_PAGE
:
3288 Page
= PrepareCopyPage(&Ir
);
3291 case FILE_COPY_PAGE
:
3292 Page
= FileCopyPage(&Ir
);
3296 Page
= RegistryPage(&Ir
);
3299 case BOOT_LOADER_PAGE
:
3300 Page
= BootLoaderPage(&Ir
);
3305 case REPAIR_INTRO_PAGE
:
3306 Page
= RepairIntroPage(&Ir
);
3310 /* Emergency pages */
3311 case EMERGENCY_INTRO_PAGE
:
3312 Page
= EmergencyIntroPage(&Ir
);
3317 Page
= SuccessPage(&Ir
);
3321 Page
= QuitPage(&Ir
);
3328 NtShutdownSystem(ShutdownReboot
);