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
)
401 SYSTEM_DEVICE_INFORMATION Sdi
;
403 WCHAR FileNameBuffer
[MAX_PATH
];
404 UNICODE_STRING FileName
;
410 SetStatusText(" Please wait...");
413 /* Check whether a harddisk is available */
414 Status
= NtQuerySystemInformation (SystemDeviceInformation
,
416 sizeof(SYSTEM_DEVICE_INFORMATION
),
418 if (!NT_SUCCESS (Status
))
420 PrintTextXY(6, 15, "NtQuerySystemInformation() failed (Status 0x%08lx)", Status
);
421 PopupError("Setup could not retrieve system drive information.\n",
422 "ENTER = Reboot computer");
427 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
434 if (Sdi
.NumberOfDisks
== 0)
436 PopupError("Setup could not find a harddisk.\n",
437 "ENTER = Reboot computer");
442 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
449 /* Get the source path and source root path */
450 Status
= GetSourcePaths(&SourcePath
,
452 if (!NT_SUCCESS(Status
))
454 PrintTextXY(6, 15, "GetSourcePath() failed (Status 0x%08lx)", Status
);
455 PopupError("Setup could not find its source drive.\n",
456 "ENTER = Reboot computer");
461 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
470 PrintTextXY(6, 15, "SourcePath: '%wZ'", &SourcePath
);
471 PrintTextXY(6, 16, "SourceRootPath: '%wZ'", &SourceRootPath
);
475 /* Load txtsetup.sif from install media. */
476 wcscpy(FileNameBuffer
, SourceRootPath
.Buffer
);
477 wcscat(FileNameBuffer
, L
"\\reactos\\txtsetup.sif");
478 RtlInitUnicodeString(&FileName
,
481 Status
= InfOpenFile(&SetupInf
,
484 if (!NT_SUCCESS(Status
))
486 PopupError("Setup failed to load the file TXTSETUP.SIF.\n",
487 "ENTER = Reboot computer");
493 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
500 /* Open 'Version' section */
501 if (!InfFindFirstLine (SetupInf
, L
"Version", L
"Signature", &Context
))
503 PopupError("Setup found a corrupt TXTSETUP.SIF.\n",
504 "ENTER = Reboot computer");
510 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
518 /* Get pointer 'Signature' key */
519 if (!InfGetData (&Context
, NULL
, &Value
))
521 PopupError("Setup found a corrupt TXTSETUP.SIF.\n",
522 "ENTER = Reboot computer");
528 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
535 /* Check 'Signature' string */
536 if (_wcsicmp(Value
, L
"$ReactOS$") != 0)
538 PopupError("Setup found an invalid signature in TXTSETUP.SIF.\n",
539 "ENTER = Reboot computer");
545 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
562 IntroPage(PINPUT_RECORD Ir
)
564 SetHighlightedTextXY(6, 8, "Welcome to ReactOS Setup");
566 SetTextXY(6, 11, "This part of the setup copies the ReactOS Operating System to your");
567 SetTextXY(6, 12, "computer and prepares the second part of the setup.");
569 SetTextXY(8, 15, "\x07 Press ENTER to install ReactOS.");
571 SetTextXY(8, 17, "\x07 Press E to start the emergency console.");
573 SetTextXY(8, 19, "\x07 Press R to repair ReactOS.");
575 SetTextXY(8, 21, "\x07 Press F3 to quit without installing ReactOS.");
578 SetStatusText(" ENTER = Continue F3 = Quit");
584 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
585 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
587 if (ConfirmQuit(Ir
) == TRUE
)
591 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
593 return(INSTALL_INTRO_PAGE
);
595 else if (toupper(Ir
->Event
.KeyEvent
.uChar
.AsciiChar
) == 'E') /* E */
597 return(EMERGENCY_INTRO_PAGE
);
599 else if (toupper(Ir
->Event
.KeyEvent
.uChar
.AsciiChar
) == 'R') /* R */
601 return(REPAIR_INTRO_PAGE
);
610 EmergencyIntroPage(PINPUT_RECORD Ir
)
612 SetTextXY(6, 8, "ReactOS Setup is in an early development phase. It does not yet");
613 SetTextXY(6, 9, "support all the functions of a fully usable setup application.");
615 SetTextXY(6, 12, "The emergency console is not implemented yet.");
617 SetTextXY(8, 15, "\x07 Press ESC to return to the main page.");
619 SetTextXY(8, 17, "\x07 Press ENTER to reboot your computer.");
621 SetStatusText(" ESC = Main page ENTER = Reboot");
627 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
631 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
632 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
)) /* ESC */
638 return(REPAIR_INTRO_PAGE
);
643 RepairIntroPage(PINPUT_RECORD Ir
)
645 SetTextXY(6, 8, "ReactOS Setup is in an early development phase. It does not yet");
646 SetTextXY(6, 9, "support all the functions of a fully usable setup application.");
648 SetTextXY(6, 12, "The repair functions are not implemented yet.");
650 SetTextXY(8, 15, "\x07 Press ESC to return to the main page.");
652 SetTextXY(8, 17, "\x07 Press ENTER to reboot your computer.");
654 SetStatusText(" ESC = Main page ENTER = Reboot");
660 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
664 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
665 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
)) /* ESC */
671 return(REPAIR_INTRO_PAGE
);
676 InstallIntroPage(PINPUT_RECORD Ir
)
678 SetTextXY(6, 8, "ReactOS Setup is in an early development phase. It does not yet");
679 SetTextXY(6, 9, "support all the functions of a fully usable setup application.");
681 SetTextXY(6, 12, "The following limitations apply:");
682 SetTextXY(8, 13, "- Setup can not handle more than one primary partition per disk.");
683 SetTextXY(8, 14, "- Setup can not delete a primary partition from a disk");
684 SetTextXY(8, 15, " as long as extended partitions exist on this disk.");
685 SetTextXY(8, 16, "- Setup can not delete the first extended partition from a disk");
686 SetTextXY(8, 17, " as long as other extended partitions exist on this disk.");
687 SetTextXY(8, 18, "- Setup supports FAT file systems only.");
688 SetTextXY(8, 19, "- File system checks are not implemented yet.");
691 SetTextXY(8, 23, "\x07 Press ENTER to install ReactOS.");
693 SetTextXY(8, 25, "\x07 Press F3 to quit without installing ReactOS.");
696 SetStatusText(" ENTER = Continue F3 = Quit");
702 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
703 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
705 if (ConfirmQuit(Ir
) == TRUE
)
709 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
711 return(SELECT_PARTITION_PAGE
);
715 return(INSTALL_INTRO_PAGE
);
720 SelectPartitionPage(PINPUT_RECORD Ir
)
725 SetTextXY(6, 8, "The list below shows existing partitions and unused disk");
726 SetTextXY(6, 9, "space for new partitions.");
728 SetTextXY(8, 11, "\x07 Press UP or DOWN to select a list entry.");
729 SetTextXY(8, 13, "\x07 Press ENTER to install ReactOS onto the selected partition.");
730 SetTextXY(8, 15, "\x07 Press C to create a new partition.");
731 SetTextXY(8, 17, "\x07 Press D to delete an existing partition.");
733 SetStatusText(" Please wait...");
735 GetScreenSize(&xScreen
, &yScreen
);
737 if (PartitionList
== NULL
)
739 PartitionList
= CreatePartitionList (2,
743 if (PartitionList
== NULL
)
745 /* FIXME: show an error dialog */
750 CheckActiveBootPartition (PartitionList
);
752 DrawPartitionList (PartitionList
);
754 /* Warn about partitions created by Linux Fdisk */
755 if (WarnLinuxPartitions
== TRUE
&&
756 CheckForLinuxFdiskPartitions (PartitionList
) == TRUE
)
758 PopupError ("Setup found that at least one harddisk contains an incompatible\n"
759 "partition table that can not be handled properly!\n"
761 "Creating or deleting partitions can destroy the partiton table.\n"
763 " \x07 Press F3 to quit Setup."
764 " \x07 Press ENTER to continue.",
765 "F3= Quit ENTER = Continue");
770 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
771 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
775 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_RETURN
) /* ENTER */
777 WarnLinuxPartitions
= FALSE
;
778 return SELECT_PARTITION_PAGE
;
785 /* Update status text */
786 if (PartitionList
->CurrentPartition
== NULL
||
787 PartitionList
->CurrentPartition
->Unpartitioned
== TRUE
)
789 SetStatusText (" ENTER = Install C = Create Partition F3 = Quit");
793 SetStatusText (" ENTER = Install D = Delete Partition F3 = Quit");
798 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
799 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
801 if (ConfirmQuit(Ir
) == TRUE
)
803 DestroyPartitionList (PartitionList
);
804 PartitionList
= NULL
;
809 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
810 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
)) /* DOWN */
812 ScrollDownPartitionList (PartitionList
);
814 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
815 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_UP
)) /* UP */
817 ScrollUpPartitionList (PartitionList
);
819 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_RETURN
) /* ENTER */
821 if (PartitionList
->CurrentPartition
== NULL
||
822 PartitionList
->CurrentPartition
->Unpartitioned
== TRUE
)
824 CreateNewPartition (PartitionList
,
829 return SELECT_FILE_SYSTEM_PAGE
;
831 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_C
) /* C */
833 if (PartitionList
->CurrentPartition
->Unpartitioned
== FALSE
)
835 PopupError ("You can not create a new Partition inside\n"
836 "of an already existing Partition!\n"
838 " * Press any key to continue.",
842 return SELECT_PARTITION_PAGE
;
845 return CREATE_PARTITION_PAGE
;
847 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_D
) /* D */
849 if (PartitionList
->CurrentPartition
->Unpartitioned
== TRUE
)
851 PopupError ("You can not delete unpartitioned disk space!\n"
853 " * Press any key to continue.",
857 return SELECT_PARTITION_PAGE
;
860 return DELETE_PARTITION_PAGE
;
864 return SELECT_PARTITION_PAGE
;
869 DrawInputField(ULONG FieldLength
,
879 memset(buf
, '_', sizeof(buf
));
880 buf
[FieldLength
- strlen(FieldContent
)] = 0;
881 strcat(buf
, FieldContent
);
883 WriteConsoleOutputCharacters (buf
,
889 #define PARTITION_SIZE_INPUT_FIELD_LENGTH 6
892 ShowPartitionSizeInputBox(SHORT Left
,
917 /* draw upper left corner */
920 FillConsoleOutputCharacter(0xDA, // '+',
925 /* draw upper edge */
928 FillConsoleOutputCharacter(0xC4, // '-',
933 /* draw upper right corner */
936 FillConsoleOutputCharacter(0xBF, // '+',
941 /* draw left and right edge */
942 for (i
= Top
+ 1; i
< Bottom
; i
++)
946 FillConsoleOutputCharacter(0xB3, // '|',
952 FillConsoleOutputCharacter(0xB3, //'|',
958 /* draw lower left corner */
961 FillConsoleOutputCharacter(0xC0, // '+',
966 /* draw lower edge */
969 FillConsoleOutputCharacter(0xC4, // '-',
974 /* draw lower right corner */
977 FillConsoleOutputCharacter(0xD9, // '+',
985 strcpy (Buffer
, "Size of new partition:");
986 iLeft
= coPos
.X
+ strlen (Buffer
) + 1;
988 WriteConsoleOutputCharacters (Buffer
,
992 sprintf (Buffer
, "MB (max. %d MB)", MaxSize
);
993 coPos
.X
= iLeft
+ PARTITION_SIZE_INPUT_FIELD_LENGTH
+ 1;
995 WriteConsoleOutputCharacters (Buffer
,
1001 DrawInputField (PARTITION_SIZE_INPUT_FIELD_LENGTH
,
1010 if ((Ir
.Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1011 (Ir
.Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1018 else if (Ir
.Event
.KeyEvent
.wVirtualKeyCode
== VK_RETURN
) /* ENTER */
1022 else if (Ir
.Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
) /* ESCAPE */
1029 else if ((Ir
.Event
.KeyEvent
.wVirtualKeyCode
== VK_BACK
) && /* BACKSPACE */
1034 DrawInputField (PARTITION_SIZE_INPUT_FIELD_LENGTH
,
1039 else if ((Ir
.Event
.KeyEvent
.uChar
.AsciiChar
!= 0x00) &&
1040 (Index
< PARTITION_SIZE_INPUT_FIELD_LENGTH
))
1042 ch
= Ir
.Event
.KeyEvent
.uChar
.AsciiChar
;
1043 if ((ch
>= '0') && (ch
<= '9'))
1048 DrawInputField (PARTITION_SIZE_INPUT_FIELD_LENGTH
,
1056 strcpy (InputBuffer
,
1062 CreatePartitionPage (PINPUT_RECORD Ir
)
1064 PDISKENTRY DiskEntry
;
1065 PPARTENTRY PartEntry
;
1070 CHAR InputBuffer
[50];
1076 if (PartitionList
== NULL
||
1077 PartitionList
->CurrentDisk
== NULL
||
1078 PartitionList
->CurrentPartition
== NULL
)
1080 /* FIXME: show an error dialog */
1084 DiskEntry
= PartitionList
->CurrentDisk
;
1085 PartEntry
= PartitionList
->CurrentPartition
;
1087 SetStatusText (" Please wait...");
1089 GetScreenSize (&xScreen
, &yScreen
);
1091 SetTextXY (6, 8, "You have chosen to create a new partition on");
1094 if (DiskEntry
->DiskSize
>= 0x280000000ULL
) /* 10 GB */
1096 DiskSize
= (DiskEntry
->DiskSize
+ (1 << 29)) >> 30;
1102 DiskSize
= (DiskEntry
->DiskSize
+ (1 << 19)) >> 20;
1108 if (DiskEntry
->DriverName
.Length
> 0)
1111 "%I64u %s Harddisk %lu (Port=%hu, Bus=%hu, Id=%hu) on %wZ.",
1114 DiskEntry
->DiskNumber
,
1118 &DiskEntry
->DriverName
);
1123 "%I64u %s Harddisk %lu (Port=%hu, Bus=%hu, Id=%hu).",
1126 DiskEntry
->DiskNumber
,
1133 SetTextXY (6, 12, "Please enter the size of the new partition in megabytes.");
1136 PrintTextXY (8, 10, "Maximum size of the new partition is %I64u MB",
1137 PartitionList
->CurrentPartition
->UnpartitionedLength
/ (1024*1024));
1140 SetStatusText (" ENTER = Create Partition ESC = Cancel F3 = Quit");
1142 PartEntry
= PartitionList
->CurrentPartition
;
1145 MaxSize
= (PartEntry
->UnpartitionedLength
+ (1 << 19)) >> 20; /* in MBytes (rounded) */
1146 ShowPartitionSizeInputBox (12, 14, xScreen
- 12, 17, /* left, top, right, bottom */
1147 MaxSize
, InputBuffer
, &Quit
, &Cancel
);
1150 if (ConfirmQuit (Ir
) == TRUE
)
1155 else if (Cancel
== TRUE
)
1157 return SELECT_PARTITION_PAGE
;
1161 PartSize
= atoi (InputBuffer
);
1168 if (PartSize
> MaxSize
)
1174 /* Convert to bytes */
1175 if (PartSize
== MaxSize
)
1177 /* Use all of the unpartitioned disk space */
1178 PartSize
= PartEntry
->UnpartitionedLength
;
1182 /* Round-up by cylinder size */
1183 PartSize
= ROUND_UP (PartSize
* 1024 * 1024,
1184 DiskEntry
->CylinderSize
);
1186 /* But never get larger than the unpartitioned disk space */
1187 if (PartSize
> PartEntry
->UnpartitionedLength
)
1188 PartSize
= PartEntry
->UnpartitionedLength
;
1191 DPRINT ("Partition size: %I64u bytes\n", PartSize
);
1193 CreateNewPartition (PartitionList
,
1197 return SELECT_PARTITION_PAGE
;
1201 return CREATE_PARTITION_PAGE
;
1206 DeletePartitionPage (PINPUT_RECORD Ir
)
1208 PDISKENTRY DiskEntry
;
1209 PPARTENTRY PartEntry
;
1215 if (PartitionList
== NULL
||
1216 PartitionList
->CurrentDisk
== NULL
||
1217 PartitionList
->CurrentPartition
== NULL
)
1219 /* FIXME: show an error dialog */
1223 DiskEntry
= PartitionList
->CurrentDisk
;
1224 PartEntry
= PartitionList
->CurrentPartition
;
1226 SetTextXY (6, 8, "You have chosen to delete the partition");
1228 /* Determine partition type */
1230 if (PartEntry
->New
== TRUE
)
1232 PartType
= "New (Unformatted)";
1234 else if (PartEntry
->Unpartitioned
== FALSE
)
1236 if ((PartEntry
->PartInfo
[0].PartitionType
== PARTITION_FAT_12
) ||
1237 (PartEntry
->PartInfo
[0].PartitionType
== PARTITION_FAT_16
) ||
1238 (PartEntry
->PartInfo
[0].PartitionType
== PARTITION_HUGE
) ||
1239 (PartEntry
->PartInfo
[0].PartitionType
== PARTITION_XINT13
))
1243 else if ((PartEntry
->PartInfo
[0].PartitionType
== PARTITION_FAT32
) ||
1244 (PartEntry
->PartInfo
[0].PartitionType
== PARTITION_FAT32_XINT13
))
1248 else if (PartEntry
->PartInfo
[0].PartitionType
== PARTITION_IFS
)
1250 PartType
= "NTFS"; /* FIXME: Not quite correct! */
1255 if (PartEntry
->PartInfo
[0].PartitionLength
.QuadPart
>= 0x280000000ULL
) /* 10 GB */
1257 PartSize
= (PartEntry
->PartInfo
[0].PartitionLength
.QuadPart
+ (1 << 29)) >> 30;
1262 if (PartEntry
->PartInfo
[0].PartitionLength
.QuadPart
>= 0xA00000ULL
) /* 10 MB */
1264 PartSize
= (PartEntry
->PartInfo
[0].PartitionLength
.QuadPart
+ (1 << 19)) >> 20;
1269 PartSize
= (PartEntry
->PartInfo
[0].PartitionLength
.QuadPart
+ (1 << 9)) >> 10;
1273 if (PartType
== NULL
)
1276 " %c%c Type %lu %I64u %s",
1277 (PartEntry
->DriveLetter
== 0) ? '-' : PartEntry
->DriveLetter
,
1278 (PartEntry
->DriveLetter
== 0) ? '-' : ':',
1279 PartEntry
->PartInfo
[0].PartitionType
,
1286 " %c%c %s %I64u %s",
1287 (PartEntry
->DriveLetter
== 0) ? '-' : PartEntry
->DriveLetter
,
1288 (PartEntry
->DriveLetter
== 0) ? '-' : ':',
1295 if (DiskEntry
->DiskSize
>= 0x280000000ULL
) /* 10 GB */
1297 DiskSize
= (DiskEntry
->DiskSize
+ (1 << 29)) >> 30;
1303 DiskSize
= (DiskEntry
->DiskSize
+ (1 << 19)) >> 20;
1309 if (DiskEntry
->DriverName
.Length
> 0)
1312 "on %I64u %s Harddisk %lu (Port=%hu, Bus=%hu, Id=%hu) on %wZ.",
1315 DiskEntry
->DiskNumber
,
1319 &DiskEntry
->DriverName
);
1324 "on %I64u %s Harddisk %lu (Port=%hu, Bus=%hu, Id=%hu).",
1327 DiskEntry
->DiskNumber
,
1333 SetTextXY (8, 18, "\x07 Press D to delete the partition.");
1334 SetTextXY (11, 19, "WARNING: All data on this partition will be lost!");
1336 SetTextXY (8, 21, "\x07 Press ESC to cancel.");
1338 SetStatusText (" D = Delete Partition ESC = Cancel F3 = Quit");
1344 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1345 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1347 if (ConfirmQuit (Ir
) == TRUE
)
1353 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
) /* ESC */
1355 return SELECT_PARTITION_PAGE
;
1357 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_D
) /* D */
1359 DeleteCurrentPartition (PartitionList
);
1361 return SELECT_PARTITION_PAGE
;
1365 return DELETE_PARTITION_PAGE
;
1370 SelectFileSystemPage (PINPUT_RECORD Ir
)
1372 PDISKENTRY DiskEntry
;
1373 PPARTENTRY PartEntry
;
1380 if (PartitionList
== NULL
||
1381 PartitionList
->CurrentDisk
== NULL
||
1382 PartitionList
->CurrentPartition
== NULL
)
1384 /* FIXME: show an error dialog */
1388 DiskEntry
= PartitionList
->CurrentDisk
;
1389 PartEntry
= PartitionList
->CurrentPartition
;
1391 /* adjust disk size */
1392 if (DiskEntry
->DiskSize
>= 0x280000000ULL
) /* 10 GB */
1394 DiskSize
= (DiskEntry
->DiskSize
+ (1 << 29)) >> 30;
1399 DiskSize
= (DiskEntry
->DiskSize
+ (1 << 19)) >> 20;
1403 /* adjust partition size */
1404 if (PartEntry
->PartInfo
[0].PartitionLength
.QuadPart
>= 0x280000000ULL
) /* 10 GB */
1406 PartSize
= (PartEntry
->PartInfo
[0].PartitionLength
.QuadPart
+ (1 << 29)) >> 30;
1411 PartSize
= (PartEntry
->PartInfo
[0].PartitionLength
.QuadPart
+ (1 << 19)) >> 20;
1415 /* adjust partition type */
1416 if ((PartEntry
->PartInfo
[0].PartitionType
== PARTITION_FAT_12
) ||
1417 (PartEntry
->PartInfo
[0].PartitionType
== PARTITION_FAT_16
) ||
1418 (PartEntry
->PartInfo
[0].PartitionType
== PARTITION_HUGE
) ||
1419 (PartEntry
->PartInfo
[0].PartitionType
== PARTITION_XINT13
))
1423 else if ((PartEntry
->PartInfo
[0].PartitionType
== PARTITION_FAT32
) ||
1424 (PartEntry
->PartInfo
[0].PartitionType
== PARTITION_FAT32_XINT13
))
1428 else if (PartEntry
->PartInfo
[0].PartitionType
== PARTITION_IFS
)
1430 PartType
= "NTFS"; /* FIXME: Not quite correct! */
1432 else if (PartEntry
->PartInfo
[0].PartitionType
== PARTITION_ENTRY_UNUSED
)
1434 PartType
= "Unused";
1438 PartType
= "Unknown";
1441 if (PartEntry
->AutoCreate
== TRUE
)
1443 SetTextXY(6, 8, "Setup created a new partition on");
1446 PrintTextXY(8, 10, "Partition %lu (%I64u %s) %s of",
1447 PartEntry
->PartInfo
[0].PartitionNumber
,
1453 PrintTextXY(8, 10, "Harddisk %lu (%I64u %s), Port=%hu, Bus=%hu, Id=%hu (%wZ).",
1454 DiskEntry
->DiskNumber
,
1460 &DiskEntry
->DriverName
);
1462 SetTextXY(6, 12, "This Partition will be formatted next.");
1465 PartEntry
->AutoCreate
= FALSE
;
1467 else if (PartEntry
->New
== TRUE
)
1469 SetTextXY(6, 8, "You chose to install ReactOS on a new or unformatted Partition.");
1470 SetTextXY(6, 10, "This Partition will be formatted next.");
1474 SetTextXY(6, 8, "Setup install ReactOS onto Partition");
1476 if (PartType
== NULL
)
1479 "%c%c Type %lu %I64u %s",
1480 (PartEntry
->DriveLetter
== 0) ? '-' : PartEntry
->DriveLetter
,
1481 (PartEntry
->DriveLetter
== 0) ? '-' : ':',
1482 PartEntry
->PartInfo
[0].PartitionType
,
1490 (PartEntry
->DriveLetter
== 0) ? '-' : PartEntry
->DriveLetter
,
1491 (PartEntry
->DriveLetter
== 0) ? '-' : ':',
1497 PrintTextXY(6, 12, "on Harddisk %lu (%I64u %s), Port=%hu, Bus=%hu, Id=%hu (%wZ).",
1498 DiskEntry
->DiskNumber
,
1504 &DiskEntry
->DriverName
);
1508 SetTextXY(6, 17, "Select a file system from the list below.");
1510 SetTextXY(8, 19, "\x07 Press UP or DOWN to select a file system.");
1511 SetTextXY(8, 21, "\x07 Press ENTER to format the partition.");
1512 SetTextXY(8, 23, "\x07 Press ESC to select another partition.");
1514 if (FileSystemList
== NULL
)
1516 FileSystemList
= CreateFileSystemList (6, 26, PartEntry
->New
, FsFat
);
1517 if (FileSystemList
== NULL
)
1519 /* FIXME: show an error dialog */
1523 /* FIXME: Add file systems to list */
1525 DrawFileSystemList (FileSystemList
);
1527 SetStatusText (" ENTER = Continue ESC = Cancel F3 = Quit");
1533 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1534 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1536 if (ConfirmQuit (Ir
) == TRUE
)
1542 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1543 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_ESCAPE
)) /* ESC */
1545 return SELECT_PARTITION_PAGE
;
1547 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1548 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_DOWN
)) /* DOWN */
1550 ScrollDownFileSystemList (FileSystemList
);
1552 else if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1553 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_UP
)) /* UP */
1555 ScrollUpFileSystemList (FileSystemList
);
1557 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_RETURN
) /* ENTER */
1559 if (FileSystemList
->CurrentFileSystem
== FsKeep
)
1561 return CHECK_FILE_SYSTEM_PAGE
;
1565 return FORMAT_PARTITION_PAGE
;
1570 return SELECT_FILE_SYSTEM_PAGE
;
1575 FormatPartitionPage (PINPUT_RECORD Ir
)
1577 WCHAR PathBuffer
[MAX_PATH
];
1578 PDISKENTRY DiskEntry
;
1579 PPARTENTRY PartEntry
;
1589 SetTextXY(6, 8, "Format partition");
1591 SetTextXY(6, 10, "Setup will now format the partition. Press ENTER to continue.");
1593 SetStatusText(" ENTER = Continue F3 = Quit");
1596 if (PartitionList
== NULL
||
1597 PartitionList
->CurrentDisk
== NULL
||
1598 PartitionList
->CurrentPartition
== NULL
)
1600 /* FIXME: show an error dialog */
1604 DiskEntry
= PartitionList
->CurrentDisk
;
1605 PartEntry
= PartitionList
->CurrentPartition
;
1611 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1612 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1614 if (ConfirmQuit (Ir
) == TRUE
)
1620 else if (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_RETURN
) /* ENTER */
1622 SetStatusText (" Please wait ...");
1624 if (PartEntry
->PartInfo
[0].PartitionType
== PARTITION_ENTRY_UNUSED
)
1626 switch (FileSystemList
->CurrentFileSystem
)
1629 if (PartEntry
->PartInfo
[0].PartitionLength
.QuadPart
< (4200ULL * 1024ULL))
1631 /* FAT12 CHS partition (disk is smaller than 4.1MB) */
1632 PartEntry
->PartInfo
[0].PartitionType
= PARTITION_FAT_12
;
1634 else if (PartEntry
->PartInfo
[0].StartingOffset
.QuadPart
< (1024ULL * 255ULL * 63ULL * 512ULL))
1636 /* Partition starts below the 8.4GB boundary ==> CHS partition */
1638 if (PartEntry
->PartInfo
[0].PartitionLength
.QuadPart
< (32ULL * 1024ULL * 1024ULL))
1640 /* FAT16 CHS partition (partiton size < 32MB) */
1641 PartEntry
->PartInfo
[0].PartitionType
= PARTITION_FAT_16
;
1643 else if (PartEntry
->PartInfo
[0].PartitionLength
.QuadPart
< (512ULL * 1024ULL * 1024ULL))
1645 /* FAT16 CHS partition (partition size < 512MB) */
1646 PartEntry
->PartInfo
[0].PartitionType
= PARTITION_HUGE
;
1650 /* FAT32 CHS partition (partition size >= 512MB) */
1651 PartEntry
->PartInfo
[0].PartitionType
= PARTITION_FAT32
;
1656 /* Partition starts above the 8.4GB boundary ==> LBA partition */
1658 if (PartEntry
->PartInfo
[0].PartitionLength
.QuadPart
< (512ULL * 1024ULL * 1024ULL))
1660 /* FAT16 LBA partition (partition size < 512MB) */
1661 PartEntry
->PartInfo
[0].PartitionType
= PARTITION_XINT13
;
1665 /* FAT32 LBA partition (partition size >= 512MB) */
1666 PartEntry
->PartInfo
[0].PartitionType
= PARTITION_FAT32_XINT13
;
1679 CheckActiveBootPartition (PartitionList
);
1683 "Disk: %I64u Cylinder: %I64u Track: %I64u",
1684 DiskEntry
->DiskSize
,
1685 DiskEntry
->CylinderSize
,
1686 DiskEntry
->TrackSize
);
1689 DiskEntry
= PartitionList
->CurrentDisk
;
1690 Entry
= DiskEntry
->PartListHead
.Flink
;
1691 while (Entry
!= &DiskEntry
->PartListHead
)
1693 PartEntry
= CONTAINING_RECORD(Entry
, PARTENTRY
, ListEntry
);
1695 if (PartEntry
->Unpartitioned
== FALSE
)
1698 for (i
= 0; i
< 4; i
++)
1700 PrintTextXY (6, Line
,
1701 "%2u: %2u %c %12I64u %12I64u %2u %c",
1703 PartEntry
->PartInfo
[i
].PartitionNumber
,
1704 PartEntry
->PartInfo
[i
].BootIndicator
? 'A' : '-',
1705 PartEntry
->PartInfo
[i
].StartingOffset
.QuadPart
,
1706 PartEntry
->PartInfo
[i
].PartitionLength
.QuadPart
,
1707 PartEntry
->PartInfo
[i
].PartitionType
,
1708 PartEntry
->PartInfo
[i
].RewritePartition
? '*' : ' ');
1716 Entry
= Entry
->Flink
;
1719 /* Restore the old entry */
1720 PartEntry
= PartitionList
->CurrentPartition
;
1723 if (WritePartitionsToDisk (PartitionList
) == FALSE
)
1725 DPRINT ("WritePartitionsToDisk() failed\n");
1727 PopupError ("Setup failed to write partition tables.\n",
1728 "ENTER = Reboot computer");
1734 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
1742 /* Set DestinationRootPath */
1743 RtlFreeUnicodeString (&DestinationRootPath
);
1744 swprintf (PathBuffer
,
1745 L
"\\Device\\Harddisk%lu\\Partition%lu",
1746 PartitionList
->CurrentDisk
->DiskNumber
,
1747 PartitionList
->CurrentPartition
->PartInfo
[0].PartitionNumber
);
1748 RtlCreateUnicodeString (&DestinationRootPath
,
1750 DPRINT ("DestinationRootPath: %wZ\n", &DestinationRootPath
);
1753 /* Set SystemRootPath */
1754 RtlFreeUnicodeString (&SystemRootPath
);
1755 swprintf (PathBuffer
,
1756 L
"\\Device\\Harddisk%lu\\Partition%lu",
1757 PartitionList
->ActiveBootDisk
->DiskNumber
,
1758 PartitionList
->ActiveBootPartition
->PartInfo
[0].PartitionNumber
);
1759 RtlCreateUnicodeString (&SystemRootPath
,
1761 DPRINT ("SystemRootPath: %wZ\n", &SystemRootPath
);
1764 switch (FileSystemList
->CurrentFileSystem
)
1767 Status
= FormatPartition (&DestinationRootPath
);
1768 if (!NT_SUCCESS (Status
))
1770 DPRINT1 ("FormatPartition() failed with status 0x%.08x\n", Status
);
1771 /* FIXME: show an error dialog */
1775 PartEntry
->New
= FALSE
;
1776 if (FileSystemList
!= NULL
)
1778 DestroyFileSystemList (FileSystemList
);
1779 FileSystemList
= NULL
;
1782 CheckActiveBootPartition (PartitionList
);
1784 /* FIXME: Install boot code. This is a hack! */
1785 if ((PartEntry
->PartInfo
[0].PartitionType
== PARTITION_FAT32_XINT13
) ||
1786 (PartEntry
->PartInfo
[0].PartitionType
== PARTITION_FAT32
))
1788 wcscpy (PathBuffer
, SourceRootPath
.Buffer
);
1789 wcscat (PathBuffer
, L
"\\loader\\fat32.bin");
1791 DPRINT1 ("Install FAT32 bootcode: %S ==> %S\n", PathBuffer
,
1792 DestinationRootPath
.Buffer
);
1793 Status
= InstallFat32BootCodeToDisk (PathBuffer
,
1794 DestinationRootPath
.Buffer
);
1795 if (!NT_SUCCESS (Status
))
1797 DPRINT1 ("InstallFat32BootCodeToDisk() failed with status 0x%.08x\n", Status
);
1798 /* FIXME: show an error dialog */
1804 wcscpy (PathBuffer
, SourceRootPath
.Buffer
);
1805 wcscat (PathBuffer
, L
"\\loader\\fat.bin");
1807 DPRINT1 ("Install FAT bootcode: %S ==> %S\n", PathBuffer
,
1808 DestinationRootPath
.Buffer
);
1809 Status
= InstallFat16BootCodeToDisk (PathBuffer
,
1810 DestinationRootPath
.Buffer
);
1811 if (!NT_SUCCESS (Status
))
1813 DPRINT1 ("InstallFat16BootCodeToDisk() failed with status 0x%.08x\n", Status
);
1814 /* FIXME: show an error dialog */
1827 SetStatusText (" Done. Press any key ...");
1830 return INSTALL_DIRECTORY_PAGE
;
1834 return FORMAT_PARTITION_PAGE
;
1839 CheckFileSystemPage(PINPUT_RECORD Ir
)
1841 WCHAR PathBuffer
[MAX_PATH
];
1843 SetTextXY(6, 8, "Check file system");
1845 SetTextXY(6, 10, "At present, ReactOS can not check file systems.");
1847 SetStatusText(" Please wait ...");
1850 SetStatusText(" ENTER = Continue F3 = Quit");
1853 /* Set DestinationRootPath */
1854 RtlFreeUnicodeString (&DestinationRootPath
);
1855 swprintf (PathBuffer
,
1856 L
"\\Device\\Harddisk%lu\\Partition%lu",
1857 PartitionList
->CurrentDisk
->DiskNumber
,
1858 PartitionList
->CurrentPartition
->PartInfo
[0].PartitionNumber
);
1859 RtlCreateUnicodeString (&DestinationRootPath
,
1861 DPRINT ("DestinationRootPath: %wZ\n", &DestinationRootPath
);
1863 /* Set SystemRootPath */
1864 RtlFreeUnicodeString (&SystemRootPath
);
1865 swprintf (PathBuffer
,
1866 L
"\\Device\\Harddisk%lu\\Partition%lu",
1867 PartitionList
->ActiveBootDisk
->DiskNumber
,
1868 PartitionList
->ActiveBootPartition
->PartInfo
[0].PartitionNumber
);
1869 RtlCreateUnicodeString (&SystemRootPath
,
1871 DPRINT ("SystemRootPath: %wZ\n", &SystemRootPath
);
1878 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1879 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1881 if (ConfirmQuit(Ir
) == TRUE
)
1885 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
1887 return(INSTALL_DIRECTORY_PAGE
);
1891 return(CHECK_FILE_SYSTEM_PAGE
);
1896 InstallDirectoryPage(PINPUT_RECORD Ir
)
1898 PDISKENTRY DiskEntry
;
1899 PPARTENTRY PartEntry
;
1900 WCHAR PathBuffer
[MAX_PATH
];
1901 WCHAR InstallDir
[51];
1907 if (PartitionList
== NULL
||
1908 PartitionList
->CurrentDisk
== NULL
||
1909 PartitionList
->CurrentPartition
== NULL
)
1911 /* FIXME: show an error dialog */
1915 DiskEntry
= PartitionList
->CurrentDisk
;
1916 PartEntry
= PartitionList
->CurrentPartition
;
1918 /* Search for 'DefaultPath' in the 'SetupData' section */
1919 if (!InfFindFirstLine (SetupInf
, L
"SetupData", L
"DefaultPath", &Context
))
1921 PopupError("Setup failed to find the 'SetupData' section\n"
1922 "in TXTSETUP.SIF.\n",
1923 "ENTER = Reboot computer");
1929 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
1936 /* Read the 'DefaultPath' data */
1937 if (InfGetData (&Context
, NULL
, &DefaultPath
))
1939 wcscpy(InstallDir
, DefaultPath
);
1943 wcscpy(InstallDir
, L
"\\ReactOS");
1945 Length
= wcslen(InstallDir
);
1947 SetTextXY(6, 8, "Setup installs ReactOS files onto the selected partition. Choose a");
1948 SetTextXY(6, 9, "directory where you want ReactOS to be installed:");
1950 SetInputTextXY(8, 11, 51, InstallDir
);
1952 SetTextXY(6, 14, "To change the suggested directory, press BACKSPACE to delete");
1953 SetTextXY(6, 15, "characters and then type the directory where you want ReactOS to");
1954 SetTextXY(6, 16, "be installed.");
1956 SetStatusText(" ENTER = Continue F3 = Quit");
1962 if ((Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x00) &&
1963 (Ir
->Event
.KeyEvent
.wVirtualKeyCode
== VK_F3
)) /* F3 */
1965 if (ConfirmQuit(Ir
) == TRUE
)
1969 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
1971 /* Create 'InstallPath' string */
1972 RtlFreeUnicodeString(&InstallPath
);
1973 RtlCreateUnicodeString(&InstallPath
,
1976 /* Create 'DestinationPath' string */
1977 RtlFreeUnicodeString(&DestinationPath
);
1979 DestinationRootPath
.Buffer
);
1980 if (InstallDir
[0] != L
'\\')
1983 wcscat(PathBuffer
, InstallDir
);
1984 RtlCreateUnicodeString(&DestinationPath
,
1987 /* Create 'DestinationArcPath' */
1988 RtlFreeUnicodeString(&DestinationArcPath
);
1989 swprintf(PathBuffer
,
1990 L
"multi(0)disk(0)rdisk(%lu)partition(%lu)",
1991 DiskEntry
->DiskNumber
,
1992 PartEntry
->PartInfo
[0].PartitionNumber
);
1993 if (InstallDir
[0] != L
'\\')
1996 wcscat(PathBuffer
, InstallDir
);
1997 RtlCreateUnicodeString(&DestinationArcPath
,
2000 return(PREPARE_COPY_PAGE
);
2002 else if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x08) /* BACKSPACE */
2007 InstallDir
[Length
] = 0;
2008 SetInputTextXY(8, 11, 51, InstallDir
);
2011 else if (isprint(Ir
->Event
.KeyEvent
.uChar
.AsciiChar
))
2015 InstallDir
[Length
] = (WCHAR
)Ir
->Event
.KeyEvent
.uChar
.AsciiChar
;
2017 InstallDir
[Length
] = 0;
2018 SetInputTextXY(8, 11, 51, InstallDir
);
2023 return(INSTALL_DIRECTORY_PAGE
);
2028 PrepareCopyPageInfFile(HINF InfFile
, PWCHAR SourceCabinet
, PINPUT_RECORD Ir
)
2030 WCHAR PathBuffer
[MAX_PATH
];
2031 INFCONTEXT FilesContext
;
2032 INFCONTEXT DirContext
;
2038 PWCHAR FileKeyValue
;
2041 PWCHAR TargetFileName
;
2043 /* Search for the 'SourceFiles' section */
2044 if (!InfFindFirstLine (InfFile
, L
"SourceFiles", NULL
, &FilesContext
))
2046 PopupError("Setup failed to find the 'SourceFiles' section\n"
2047 "in TXTSETUP.SIF.\n", // FIXME
2048 "ENTER = Reboot computer");
2054 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2062 * Enumerate the files in the 'SourceFiles' section
2063 * and add them to the file queue.
2067 /* Get source file name and target directory id */
2068 if (!InfGetData (&FilesContext
, &FileKeyName
, &FileKeyValue
))
2070 /* FIXME: Handle error! */
2071 DPRINT1("InfGetData() failed\n");
2075 /* Get optional target file name */
2076 if (!InfGetDataField (&FilesContext
, 2, &TargetFileName
))
2077 TargetFileName
= NULL
;
2079 DPRINT ("FileKeyName: '%S' FileKeyValue: '%S'\n", FileKeyName
, FileKeyValue
);
2081 /* Lookup target directory */
2082 if (!InfFindFirstLine (InfFile
, L
"Directories", FileKeyValue
, &DirContext
))
2084 /* FIXME: Handle error! */
2085 DPRINT1("InfFindFirstLine() failed\n");
2089 if (!InfGetData (&DirContext
, NULL
, &DirKeyValue
))
2091 /* FIXME: Handle error! */
2092 DPRINT1("InfGetData() failed\n");
2096 if (!SetupQueueCopy(SetupFileQueue
,
2098 SourceRootPath
.Buffer
,
2104 /* FIXME: Handle error! */
2105 DPRINT1("SetupQueueCopy() failed\n");
2108 while (InfFindNextLine(&FilesContext
, &FilesContext
));
2111 /* Create directories */
2115 * Install directories like '\reactos\test' are not handled yet.
2118 /* Get destination path */
2119 wcscpy(PathBuffer
, DestinationPath
.Buffer
);
2121 /* Remove trailing backslash */
2122 Length
= wcslen(PathBuffer
);
2123 if ((Length
> 0) && (PathBuffer
[Length
- 1] == '\\'))
2125 PathBuffer
[Length
- 1] = 0;
2128 /* Create the install directory */
2129 Status
= CreateDirectory(PathBuffer
);
2130 if (!NT_SUCCESS(Status
) && Status
!= STATUS_OBJECT_NAME_COLLISION
)
2132 DPRINT("Creating directory '%S' failed: Status = 0x%08lx", PathBuffer
, Status
);
2133 PopupError("Setup could not create the install directory.",
2134 "ENTER = Reboot computer");
2140 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2148 /* Search for the 'Directories' section */
2149 if (!InfFindFirstLine(InfFile
, L
"Directories", NULL
, &DirContext
))
2153 PopupError("Setup failed to find the 'Directories' section\n"
2154 "in the cabinet.\n", "ENTER = Reboot computer");
2158 PopupError("Setup failed to find the 'Directories' section\n"
2159 "in TXTSETUP.SIF.\n", "ENTER = Reboot computer");
2166 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2173 /* Enumerate the directory values and create the subdirectories */
2176 if (!InfGetData (&DirContext
, NULL
, &KeyValue
))
2182 if (KeyValue
[0] == L
'\\' && KeyValue
[1] != 0)
2184 DPRINT("Absolute Path: '%S'\n", KeyValue
);
2186 wcscpy(PathBuffer
, DestinationRootPath
.Buffer
);
2187 wcscat(PathBuffer
, KeyValue
);
2189 DPRINT("FullPath: '%S'\n", PathBuffer
);
2191 else if (KeyValue
[0] != L
'\\')
2193 DPRINT("RelativePath: '%S'\n", KeyValue
);
2194 wcscpy(PathBuffer
, DestinationPath
.Buffer
);
2195 wcscat(PathBuffer
, L
"\\");
2196 wcscat(PathBuffer
, KeyValue
);
2198 DPRINT("FullPath: '%S'\n", PathBuffer
);
2200 Status
= CreateDirectory(PathBuffer
);
2201 if (!NT_SUCCESS(Status
) && Status
!= STATUS_OBJECT_NAME_COLLISION
)
2203 DPRINT("Creating directory '%S' failed: Status = 0x%08lx", PathBuffer
, Status
);
2204 PopupError("Setup could not create install directories.",
2205 "ENTER = Reboot computer");
2211 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2219 while (InfFindNextLine (&DirContext
, &DirContext
));
2226 PrepareCopyPage(PINPUT_RECORD Ir
)
2230 WCHAR PathBuffer
[MAX_PATH
];
2231 INFCONTEXT CabinetsContext
;
2238 SetTextXY(6, 8, "Setup prepares your computer for copying the ReactOS files. ");
2242 * Build the file copy list
2244 SetStatusText(" Building the file copy list...");
2246 /* Create the file queue */
2247 SetupFileQueue
= SetupOpenFileQueue();
2248 if (SetupFileQueue
== NULL
)
2250 PopupError("Setup failed to open the copy file queue.\n",
2251 "ENTER = Reboot computer");
2257 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2265 if (!PrepareCopyPageInfFile(SetupInf
, NULL
, Ir
))
2271 /* Search for the 'Cabinets' section */
2272 if (!InfFindFirstLine (SetupInf
, L
"Cabinets", NULL
, &CabinetsContext
))
2274 PopupError("Setup failed to find the 'Cabinets' section\n"
2275 "in TXTSETUP.SIF.\n",
2276 "ENTER = Reboot computer");
2282 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2291 * Enumerate the directory values in the 'Cabinets'
2292 * section and parse their inf files.
2296 if (!InfGetData (&CabinetsContext
, NULL
, &KeyValue
))
2299 wcscpy(PathBuffer
, SourcePath
.Buffer
);
2300 wcscat(PathBuffer
, L
"\\");
2301 wcscat(PathBuffer
, KeyValue
);
2303 CabinetInitialize();
2304 CabinetSetEventHandlers(NULL
, NULL
, NULL
);
2305 CabinetSetCabinetName(PathBuffer
);
2307 if (CabinetOpen() == CAB_STATUS_SUCCESS
)
2309 DPRINT("Cabinet %S\n", CabinetGetCabinetName());
2311 InfFileData
= CabinetGetCabinetReservedArea(&InfFileSize
);
2312 if (InfFileData
== NULL
)
2314 PopupError("Cabinet has no setup script.\n",
2315 "ENTER = Reboot computer");
2321 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2330 DPRINT("Cannot open cabinet: %S.\n", CabinetGetCabinetName());
2332 PopupError("Cabinet not found.\n",
2333 "ENTER = Reboot computer");
2339 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2346 Status
= InfOpenBufferedFile(&InfHandle
,
2350 if (!NT_SUCCESS(Status
))
2352 PopupError("Cabinet has no valid inf file.\n",
2353 "ENTER = Reboot computer");
2359 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2368 if (!PrepareCopyPageInfFile(InfHandle
, KeyValue
, Ir
))
2373 while (InfFindNextLine (&CabinetsContext
, &CabinetsContext
));
2375 return(FILE_COPY_PAGE
);
2380 FileCopyCallback(PVOID Context
,
2385 PCOPYCONTEXT CopyContext
;
2387 CopyContext
= (PCOPYCONTEXT
)Context
;
2389 switch (Notification
)
2391 case SPFILENOTIFY_STARTSUBQUEUE
:
2392 CopyContext
->TotalOperations
= (ULONG
)Param2
;
2393 ProgressSetStepCount(CopyContext
->ProgressBar
,
2394 CopyContext
->TotalOperations
);
2397 case SPFILENOTIFY_STARTCOPY
:
2398 /* Display copy message */
2399 PrintTextXYN(6, 16, 60, "Copying file: %S", (PWSTR
)Param1
);
2401 PrintTextXYN(6, 18, 60, "File %lu of %lu",
2402 CopyContext
->CompletedOperations
+ 1,
2403 CopyContext
->TotalOperations
);
2406 case SPFILENOTIFY_ENDCOPY
:
2407 CopyContext
->CompletedOperations
++;
2408 ProgressNextStep(CopyContext
->ProgressBar
);
2417 FileCopyPage(PINPUT_RECORD Ir
)
2419 COPYCONTEXT CopyContext
;
2423 SetStatusText(" Please wait...");
2425 SetTextXY(6, 8, "Copying files");
2427 GetScreenSize(&xScreen
, &yScreen
);
2429 CopyContext
.TotalOperations
= 0;
2430 CopyContext
.CompletedOperations
= 0;
2431 CopyContext
.ProgressBar
= CreateProgressBar(6,
2436 SetupCommitFileQueue(SetupFileQueue
,
2437 DestinationRootPath
.Buffer
,
2439 (PSP_FILE_CALLBACK
)FileCopyCallback
,
2442 SetupCloseFileQueue(SetupFileQueue
);
2444 DestroyProgressBar(CopyContext
.ProgressBar
);
2446 return(REGISTRY_PAGE
);
2451 RegistryPage(PINPUT_RECORD Ir
)
2453 INFCONTEXT InfContext
;
2462 SetTextXY(6, 8, "Setup is updating the system configuration");
2464 SetStatusText(" Creating registry hives...");
2466 if (!SetInstallPathValue(&DestinationPath
))
2468 DPRINT("SetInstallPathValue() failed\n");
2469 PopupError("Setup failed to set the initialize the registry.",
2470 "ENTER = Reboot computer");
2476 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2483 /* Create the default hives */
2484 Status
= NtInitializeRegistry(TRUE
);
2485 if (!NT_SUCCESS(Status
))
2487 DPRINT("NtInitializeRegistry() failed (Status %lx)\n", Status
);
2488 PopupError("Setup failed to create the registry hives.",
2489 "ENTER = Reboot computer");
2495 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2502 /* Update registry */
2503 SetStatusText(" Updating registry hives...");
2505 if (!InfFindFirstLine(SetupInf
, L
"HiveInfs.Install", NULL
, &InfContext
))
2507 DPRINT1("InfFindFirstLine() failed\n");
2508 PopupError("Setup failed to find the registry data files.",
2509 "ENTER = Reboot computer");
2515 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2524 InfGetDataField (&InfContext
, 0, &Action
);
2525 InfGetDataField (&InfContext
, 1, &File
);
2526 InfGetDataField (&InfContext
, 2, &Section
);
2528 DPRINT1("Action: %S File: %S Section %S\n", Action
, File
, Section
);
2530 if (!_wcsicmp (Action
, L
"AddReg"))
2534 else if (!_wcsicmp (Action
, L
"DelReg"))
2543 SetStatusText(" Importing %S...", File
);
2545 if (!ImportRegistryFile(File
, Section
, Delete
))
2547 DPRINT1("Importing %S failed\n", File
);
2549 PopupError("Setup failed to import a hive file.",
2550 "ENTER = Reboot computer");
2556 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2563 while (InfFindNextLine (&InfContext
, &InfContext
));
2565 SetStatusText(" Done...");
2567 return(BOOT_LOADER_PAGE
);
2572 BootLoaderPage(PINPUT_RECORD Ir
)
2574 WCHAR SrcPath
[MAX_PATH
];
2575 WCHAR DstPath
[MAX_PATH
];
2577 PINICACHESECTION IniSection
;
2580 SetTextXY(6, 8, "Installing the boot loader");
2582 SetStatusText(" Please wait...");
2584 if (PartitionList
->ActiveBootPartition
->PartInfo
[0].PartitionType
== PARTITION_ENTRY_UNUSED
)
2586 DPRINT1("Error: active partition invalid (unused)\n");
2587 PopupError("The active partition is unused (invalid).\n",
2588 "ENTER = Reboot computer");
2594 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2601 if (PartitionList
->ActiveBootPartition
->PartInfo
[0].PartitionType
== 0x0A)
2603 /* OS/2 boot manager partition */
2604 DPRINT1("Found OS/2 boot manager partition\n");
2605 PopupError("Setup found an OS/2 boot manager partiton.\n"
2606 "The OS/2 boot manager is not supported yet!",
2607 "ENTER = Reboot computer");
2613 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2619 else if (PartitionList
->ActiveBootPartition
->PartInfo
[0].PartitionType
== 0x83)
2621 /* Linux ext2 partition */
2622 DPRINT1("Found Linux ext2 partition\n");
2623 PopupError("Setup found a Linux ext2 partiton.\n"
2624 "Linux ext2 partitions are not supported yet!",
2625 "ENTER = Reboot computer");
2631 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2637 else if (PartitionList
->ActiveBootPartition
->PartInfo
[0].PartitionType
== PARTITION_IFS
)
2639 /* NTFS partition */
2640 DPRINT1("Found NTFS partition\n");
2641 PopupError("Setup found an NTFS partiton.\n"
2642 "NTFS partitions are not supported yet!",
2643 "ENTER = Reboot computer");
2649 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2655 else if ((PartitionList
->ActiveBootPartition
->PartInfo
[0].PartitionType
== PARTITION_FAT_12
) ||
2656 (PartitionList
->ActiveBootPartition
->PartInfo
[0].PartitionType
== PARTITION_FAT_16
) ||
2657 (PartitionList
->ActiveBootPartition
->PartInfo
[0].PartitionType
== PARTITION_HUGE
) ||
2658 (PartitionList
->ActiveBootPartition
->PartInfo
[0].PartitionType
== PARTITION_XINT13
) ||
2659 (PartitionList
->ActiveBootPartition
->PartInfo
[0].PartitionType
== PARTITION_FAT32
) ||
2660 (PartitionList
->ActiveBootPartition
->PartInfo
[0].PartitionType
== PARTITION_FAT32_XINT13
))
2662 /* FAT or FAT32 partition */
2663 DPRINT1("System path: '%wZ'\n", &SystemRootPath
);
2665 if (DoesFileExist(SystemRootPath
.Buffer
, L
"ntldr") == TRUE
||
2666 DoesFileExist(SystemRootPath
.Buffer
, L
"boot.ini") == TRUE
)
2668 /* Search root directory for 'ntldr' and 'boot.ini'. */
2669 DPRINT1("Found Microsoft Windows NT/2000/XP boot loader\n");
2671 /* Copy FreeLoader to the boot partition */
2672 wcscpy(SrcPath
, SourceRootPath
.Buffer
);
2673 wcscat(SrcPath
, L
"\\loader\\freeldr.sys");
2674 wcscpy(DstPath
, SystemRootPath
.Buffer
);
2675 wcscat(DstPath
, L
"\\freeldr.sys");
2677 DPRINT1("Copy: %S ==> %S\n", SrcPath
, DstPath
);
2678 Status
= SetupCopyFile(SrcPath
, DstPath
);
2679 if (!NT_SUCCESS(Status
))
2681 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status
);
2682 PopupError("Setup failed to copy 'freeldr.sys'.",
2683 "ENTER = Reboot computer");
2689 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2696 /* Create or update freeldr.ini */
2697 if (DoesFileExist(SystemRootPath
.Buffer
, L
"freeldr.ini") == FALSE
)
2699 /* Create new 'freeldr.ini' */
2700 DPRINT1("Create new 'freeldr.ini'\n");
2701 wcscpy(DstPath
, SystemRootPath
.Buffer
);
2702 wcscat(DstPath
, L
"\\freeldr.ini");
2704 Status
= CreateFreeLoaderIniForReactos(DstPath
,
2705 DestinationArcPath
.Buffer
);
2706 if (!NT_SUCCESS(Status
))
2708 DPRINT1("CreateFreeLoaderIniForReactos() failed (Status %lx)\n", Status
);
2709 PopupError("Setup failed to create 'freeldr.ini'.",
2710 "ENTER = Reboot computer");
2716 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2723 /* Install new bootcode */
2724 if ((PartitionList
->ActiveBootPartition
->PartInfo
[0].PartitionType
== PARTITION_FAT32
) ||
2725 (PartitionList
->ActiveBootPartition
->PartInfo
[0].PartitionType
== PARTITION_FAT32_XINT13
))
2727 /* Install FAT32 bootcode */
2728 wcscpy(SrcPath
, SourceRootPath
.Buffer
);
2729 wcscat(SrcPath
, L
"\\loader\\fat32.bin");
2730 wcscpy(DstPath
, SystemRootPath
.Buffer
);
2731 wcscat(DstPath
, L
"\\bootsect.ros");
2733 DPRINT1("Install FAT32 bootcode: %S ==> %S\n", SrcPath
, DstPath
);
2734 Status
= InstallFat32BootCodeToFile(SrcPath
,
2736 SystemRootPath
.Buffer
);
2737 if (!NT_SUCCESS(Status
))
2739 DPRINT1("InstallFat32BootCodeToFile() failed (Status %lx)\n", Status
);
2740 PopupError("Setup failed to install the FAT32 bootcode.",
2741 "ENTER = Reboot computer");
2747 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2756 /* Install FAT16 bootcode */
2757 wcscpy(SrcPath
, SourceRootPath
.Buffer
);
2758 wcscat(SrcPath
, L
"\\loader\\fat.bin");
2759 wcscpy(DstPath
, SystemRootPath
.Buffer
);
2760 wcscat(DstPath
, L
"\\bootsect.ros");
2762 DPRINT1("Install FAT bootcode: %S ==> %S\n", SrcPath
, DstPath
);
2763 Status
= InstallFat16BootCodeToFile(SrcPath
,
2765 SystemRootPath
.Buffer
);
2766 if (!NT_SUCCESS(Status
))
2768 DPRINT1("InstallFat16BootCodeToFile() failed (Status %lx)\n", Status
);
2769 PopupError("Setup failed to install the FAT bootcode.",
2770 "ENTER = Reboot computer");
2776 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2784 /* Update 'boot.ini' */
2785 wcscpy(DstPath
, SystemRootPath
.Buffer
);
2786 wcscat(DstPath
, L
"\\boot.ini");
2788 DPRINT1("Update 'boot.ini': %S\n", DstPath
);
2789 Status
= UpdateBootIni(DstPath
,
2790 L
"C:\\bootsect.ros",
2792 if (!NT_SUCCESS(Status
))
2794 DPRINT1("UpdateBootIni() failed (Status %lx)\n", Status
);
2795 PopupError("Setup failed to update \'boot.ini\'.",
2796 "ENTER = Reboot computer");
2802 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2811 /* Update existing 'freeldr.ini' */
2812 DPRINT1("Update existing 'freeldr.ini'\n");
2813 wcscpy(DstPath
, SystemRootPath
.Buffer
);
2814 wcscat(DstPath
, L
"\\freeldr.ini");
2816 Status
= UpdateFreeLoaderIni(DstPath
,
2817 DestinationArcPath
.Buffer
);
2818 if (!NT_SUCCESS(Status
))
2820 DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status
);
2821 PopupError("Setup failed to update 'freeldr.ini'.",
2822 "ENTER = Reboot computer");
2828 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2836 else if (DoesFileExist(SystemRootPath
.Buffer
, L
"io.sys") == TRUE
||
2837 DoesFileExist(SystemRootPath
.Buffer
, L
"msdos.sys") == TRUE
)
2839 /* Search for root directory for 'io.sys' and 'msdos.sys'. */
2840 DPRINT1("Found Microsoft DOS or Windows 9x boot loader\n");
2842 /* Copy FreeLoader to the boot partition */
2843 wcscpy(SrcPath
, SourceRootPath
.Buffer
);
2844 wcscat(SrcPath
, L
"\\loader\\freeldr.sys");
2845 wcscpy(DstPath
, SystemRootPath
.Buffer
);
2846 wcscat(DstPath
, L
"\\freeldr.sys");
2848 DPRINT("Copy: %S ==> %S\n", SrcPath
, DstPath
);
2849 Status
= SetupCopyFile(SrcPath
, DstPath
);
2850 if (!NT_SUCCESS(Status
))
2852 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status
);
2853 PopupError("Setup failed to copy 'freeldr.sys'.",
2854 "ENTER = Reboot computer");
2860 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2867 /* Create or update 'freeldr.ini' */
2868 if (DoesFileExist(SystemRootPath
.Buffer
, L
"freeldr.ini") == FALSE
)
2870 /* Create new 'freeldr.ini' */
2871 DPRINT1("Create new 'freeldr.ini'\n");
2872 wcscpy(DstPath
, SystemRootPath
.Buffer
);
2873 wcscat(DstPath
, L
"\\freeldr.ini");
2875 Status
= CreateFreeLoaderIniForDos(DstPath
,
2876 DestinationArcPath
.Buffer
);
2877 if (!NT_SUCCESS(Status
))
2879 DPRINT1("CreateFreeLoaderIniForDos() failed (Status %lx)\n", Status
);
2880 PopupError("Setup failed to create 'freeldr.ini'.",
2881 "ENTER = Reboot computer");
2887 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2894 /* Save current bootsector as 'BOOTSECT.DOS' */
2895 wcscpy(SrcPath
, SystemRootPath
.Buffer
);
2896 wcscpy(DstPath
, SystemRootPath
.Buffer
);
2897 wcscat(DstPath
, L
"\\bootsect.dos");
2899 DPRINT1("Save bootsector: %S ==> %S\n", SrcPath
, DstPath
);
2900 Status
= SaveCurrentBootSector(SrcPath
,
2902 if (!NT_SUCCESS(Status
))
2904 DPRINT1("SaveCurrentBootSector() failed (Status %lx)\n", Status
);
2905 PopupError("Setup failed to save the current bootsector.",
2906 "ENTER = Reboot computer");
2912 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2919 /* Install new bootsector */
2920 if ((PartitionList
->ActiveBootPartition
->PartInfo
[0].PartitionType
== PARTITION_FAT32
) ||
2921 (PartitionList
->ActiveBootPartition
->PartInfo
[0].PartitionType
== PARTITION_FAT32_XINT13
))
2923 wcscpy(SrcPath
, SourceRootPath
.Buffer
);
2924 wcscat(SrcPath
, L
"\\loader\\fat32.bin");
2926 DPRINT1("Install FAT32 bootcode: %S ==> %S\n", SrcPath
, SystemRootPath
.Buffer
);
2927 Status
= InstallFat32BootCodeToDisk(SrcPath
,
2928 SystemRootPath
.Buffer
);
2929 if (!NT_SUCCESS(Status
))
2931 DPRINT1("InstallFat32BootCodeToDisk() failed (Status %lx)\n", Status
);
2932 PopupError("Setup failed to install the FAT32 bootcode.",
2933 "ENTER = Reboot computer");
2939 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2948 wcscpy(SrcPath
, SourceRootPath
.Buffer
);
2949 wcscat(SrcPath
, L
"\\loader\\fat.bin");
2951 DPRINT1("Install FAT bootcode: %S ==> %S\n", SrcPath
, SystemRootPath
.Buffer
);
2952 Status
= InstallFat16BootCodeToDisk(SrcPath
,
2953 SystemRootPath
.Buffer
);
2954 if (!NT_SUCCESS(Status
))
2956 DPRINT1("InstallFat16BootCodeToDisk() failed (Status %lx)\n", Status
);
2957 PopupError("Setup failed to install the FAT bootcode.",
2958 "ENTER = Reboot computer");
2964 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
2974 /* Update existing 'freeldr.ini' */
2975 wcscpy(DstPath
, SystemRootPath
.Buffer
);
2976 wcscat(DstPath
, L
"\\freeldr.ini");
2978 Status
= UpdateFreeLoaderIni(DstPath
,
2979 DestinationArcPath
.Buffer
);
2980 if (!NT_SUCCESS(Status
))
2982 DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status
);
2983 PopupError("Setup failed to update 'freeldr.ini'.",
2984 "ENTER = Reboot computer");
2990 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
3000 /* No or unknown boot loader */
3001 DPRINT1("No or unknown boot loader found\n");
3003 /* Copy FreeLoader to the boot partition */
3004 wcscpy(SrcPath
, SourceRootPath
.Buffer
);
3005 wcscat(SrcPath
, L
"\\loader\\freeldr.sys");
3006 wcscpy(DstPath
, SystemRootPath
.Buffer
);
3007 wcscat(DstPath
, L
"\\freeldr.sys");
3009 DPRINT1("Copy: %S ==> %S\n", SrcPath
, DstPath
);
3010 Status
= SetupCopyFile(SrcPath
, DstPath
);
3011 if (!NT_SUCCESS(Status
))
3013 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status
);
3014 PopupError("Setup failed to copy 'freeldr.sys'.",
3015 "ENTER = Reboot computer");
3021 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
3028 /* Create or update 'freeldr.ini' */
3029 if (DoesFileExist(SystemRootPath
.Buffer
, L
"freeldr.ini") == FALSE
)
3031 /* Create new freeldr.ini */
3032 wcscpy(DstPath
, SystemRootPath
.Buffer
);
3033 wcscat(DstPath
, L
"\\freeldr.ini");
3035 DPRINT1("Copy: %S ==> %S\n", SrcPath
, DstPath
);
3036 Status
= CreateFreeLoaderIniForReactos(DstPath
,
3037 DestinationArcPath
.Buffer
);
3038 if (!NT_SUCCESS(Status
))
3040 DPRINT1("CreateFreeLoaderIniForReactos() failed (Status %lx)\n", Status
);
3041 PopupError("Setup failed to create \'freeldr.ini\'.",
3042 "ENTER = Reboot computer");
3048 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
3055 /* Save current bootsector as 'BOOTSECT.OLD' */
3056 wcscpy(SrcPath
, SystemRootPath
.Buffer
);
3057 wcscpy(DstPath
, SystemRootPath
.Buffer
);
3058 wcscat(DstPath
, L
"\\bootsect.old");
3060 DPRINT1("Save bootsector: %S ==> %S\n", SrcPath
, DstPath
);
3061 Status
= SaveCurrentBootSector(SrcPath
,
3063 if (!NT_SUCCESS(Status
))
3065 DPRINT1("SaveCurrentBootSector() failed (Status %lx)\n", Status
);
3066 PopupError("Setup failed save the current bootsector.",
3067 "ENTER = Reboot computer");
3073 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
3080 /* Install new bootsector */
3081 if ((PartitionList
->ActiveBootPartition
->PartInfo
[0].PartitionType
== PARTITION_FAT32
) ||
3082 (PartitionList
->ActiveBootPartition
->PartInfo
[0].PartitionType
== PARTITION_FAT32_XINT13
))
3084 wcscpy(SrcPath
, SourceRootPath
.Buffer
);
3085 wcscat(SrcPath
, L
"\\loader\\fat32.bin");
3087 DPRINT1("Install FAT32 bootcode: %S ==> %S\n", SrcPath
, SystemRootPath
.Buffer
);
3088 Status
= InstallFat32BootCodeToDisk(SrcPath
,
3089 SystemRootPath
.Buffer
);
3090 if (!NT_SUCCESS(Status
))
3092 DPRINT1("InstallFat32BootCodeToDisk() failed (Status %lx)\n", Status
);
3093 PopupError("Setup failed to install the FAT32 bootcode.",
3094 "ENTER = Reboot computer");
3100 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
3109 wcscpy(SrcPath
, SourceRootPath
.Buffer
);
3110 wcscat(SrcPath
, L
"\\loader\\fat.bin");
3112 DPRINT1("Install FAT bootcode: %S ==> %S\n", SrcPath
, SystemRootPath
.Buffer
);
3113 Status
= InstallFat16BootCodeToDisk(SrcPath
,
3114 SystemRootPath
.Buffer
);
3115 if (!NT_SUCCESS(Status
))
3117 DPRINT1("InstallFat16BootCodeToDisk() failed (Status %lx)\n", Status
);
3118 PopupError("Setup failed to install the FAT bootcode.",
3119 "ENTER = Reboot computer");
3125 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
3135 /* Update existing 'freeldr.ini' */
3136 wcscpy(DstPath
, SystemRootPath
.Buffer
);
3137 wcscat(DstPath
, L
"\\freeldr.ini");
3139 Status
= UpdateFreeLoaderIni(DstPath
,
3140 DestinationArcPath
.Buffer
);
3141 if (!NT_SUCCESS(Status
))
3143 DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status
);
3144 PopupError("Setup failed to update 'freeldr.ini'.",
3145 "ENTER = Reboot computer");
3151 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
3162 /* Unknown partition */
3163 DPRINT1("Unknown partition found\n");
3164 PopupError("Setup found an unknown partiton type.\n"
3165 "This partition type is not supported!",
3166 "ENTER = Reboot computer");
3172 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
3179 return(SUCCESS_PAGE
);
3185 QuitPage(PINPUT_RECORD Ir
)
3187 SetTextXY(10, 6, "ReactOS is not completely installed");
3189 SetTextXY(10, 8, "Remove floppy disk from Drive A: and");
3190 SetTextXY(10, 9, "all CD-ROMs from CD-Drives.");
3192 SetTextXY(10, 11, "Press ENTER to reboot your computer.");
3194 SetStatusText(" Please wait ...");
3196 /* Destroy partition list */
3197 if (PartitionList
!= NULL
)
3199 DestroyPartitionList (PartitionList
);
3200 PartitionList
= NULL
;
3203 /* Destroy filesystem list */
3204 if (FileSystemList
!= NULL
)
3206 DestroyFileSystemList (FileSystemList
);
3207 FileSystemList
= NULL
;
3210 SetStatusText(" ENTER = Reboot computer");
3216 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
3218 return(REBOOT_PAGE
);
3225 SuccessPage(PINPUT_RECORD Ir
)
3227 SetTextXY(10, 6, "The basic components of ReactOS have been installed successfully.");
3229 SetTextXY(10, 8, "Remove floppy disk from Drive A: and");
3230 SetTextXY(10, 9, "all CD-ROMs from CD-Drive.");
3232 SetTextXY(10, 11, "Press ENTER to reboot your computer.");
3234 SetStatusText(" ENTER = Reboot computer");
3240 if (Ir
->Event
.KeyEvent
.uChar
.AsciiChar
== 0x0D) /* ENTER */
3242 return(REBOOT_PAGE
);
3249 NtProcessStartup(PPEB Peb
)
3255 RtlNormalizeProcessParams(Peb
->ProcessParameters
);
3257 ProcessHeap
= Peb
->ProcessHeap
;
3259 Status
= AllocConsole();
3260 if (!NT_SUCCESS(Status
))
3262 PrintString("AllocConsole() failed (Status = 0x%08lx)\n", Status
);
3264 /* Raise a hard error (crash the system/BSOD) */
3265 NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED
,
3270 /* Initialize global unicode strings */
3271 RtlInitUnicodeString(&SourcePath
, NULL
);
3272 RtlInitUnicodeString(&SourceRootPath
, NULL
);
3273 RtlInitUnicodeString(&InstallPath
, NULL
);
3274 RtlInitUnicodeString(&DestinationPath
, NULL
);
3275 RtlInitUnicodeString(&DestinationArcPath
, NULL
);
3276 RtlInitUnicodeString(&DestinationRootPath
, NULL
);
3277 RtlInitUnicodeString(&SystemRootPath
, NULL
);
3281 while (Page
!= REBOOT_PAGE
)
3285 SetUnderlinedTextXY(4, 3, " ReactOS " KERNEL_VERSION_STR
" Setup ");
3291 Page
= StartPage(&Ir
);
3296 Page
= IntroPage(&Ir
);
3300 case INSTALL_INTRO_PAGE
:
3301 Page
= InstallIntroPage(&Ir
);
3305 case OEM_DRIVER_PAGE
:
3306 Page
= OemDriverPage(&Ir
);
3311 case DEVICE_SETTINGS_PAGE
:
3314 case SELECT_PARTITION_PAGE
:
3315 Page
= SelectPartitionPage(&Ir
);
3318 case CREATE_PARTITION_PAGE
:
3319 Page
= CreatePartitionPage(&Ir
);
3322 case DELETE_PARTITION_PAGE
:
3323 Page
= DeletePartitionPage(&Ir
);
3326 case SELECT_FILE_SYSTEM_PAGE
:
3327 Page
= SelectFileSystemPage(&Ir
);
3330 case FORMAT_PARTITION_PAGE
:
3331 Page
= FormatPartitionPage(&Ir
);
3334 case CHECK_FILE_SYSTEM_PAGE
:
3335 Page
= CheckFileSystemPage(&Ir
);
3338 case INSTALL_DIRECTORY_PAGE
:
3339 Page
= InstallDirectoryPage(&Ir
);
3342 case PREPARE_COPY_PAGE
:
3343 Page
= PrepareCopyPage(&Ir
);
3346 case FILE_COPY_PAGE
:
3347 Page
= FileCopyPage(&Ir
);
3351 Page
= RegistryPage(&Ir
);
3354 case BOOT_LOADER_PAGE
:
3355 Page
= BootLoaderPage(&Ir
);
3360 case REPAIR_INTRO_PAGE
:
3361 Page
= RepairIntroPage(&Ir
);
3365 /* Emergency pages */
3366 case EMERGENCY_INTRO_PAGE
:
3367 Page
= EmergencyIntroPage(&Ir
);
3372 Page
= SuccessPage(&Ir
);
3376 Page
= QuitPage(&Ir
);
3383 NtShutdownSystem(ShutdownReboot
);