3 * Copyright (C) 2002 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"
48 typedef enum _PAGE_NUMBER
54 SELECT_PARTITION_PAGE,
55 CREATE_PARTITION_PAGE,
56 SELECT_FILE_SYSTEM_PAGE,
57 FORMAT_PARTITION_PAGE,
58 CHECK_FILE_SYSTEM_PAGE,
60 INSTALL_DIRECTORY_PAGE,
69 REBOOT_PAGE, /* virtual page */
70 } PAGE_NUMBER, *PPAGE_NUMBER;
72 typedef struct _COPYCONTEXT
74 ULONG TotalOperations;
75 ULONG CompletedOperations;
76 PPROGRESS ProgressBar;
77 } COPYCONTEXT, *PCOPYCONTEXT;
80 /* GLOBALS ******************************************************************/
83 UNICODE_STRING SourceRootPath;
85 /* LOCALS *******************************************************************/
87 static BOOLEAN PartDataValid;
88 static PARTDATA PartData;
90 static BOOLEAN ActivePartitionValid;
91 static PARTDATA ActivePartition;
93 static UNICODE_STRING SourcePath;
95 static UNICODE_STRING InstallPath;
96 static UNICODE_STRING DestinationPath;
97 static UNICODE_STRING DestinationArcPath;
98 static UNICODE_STRING DestinationRootPath;
100 static UNICODE_STRING SystemRootPath; /* Path to the active partition */
102 static HINF SetupInf;
104 static HSPFILEQ SetupFileQueue = NULL;
106 static PPARTLIST CurrentPartitionList = NULL;
107 static PFILE_SYSTEM_LIST CurrentFileSystemList;
110 /* FUNCTIONS ****************************************************************/
113 PrintString(char* fmt,...)
117 UNICODE_STRING UnicodeString;
118 ANSI_STRING AnsiString;
121 vsprintf(buffer, fmt, ap);
124 RtlInitAnsiString(&AnsiString, buffer);
125 RtlAnsiStringToUnicodeString(&UnicodeString,
128 NtDisplayString(&UnicodeString);
129 RtlFreeUnicodeString(&UnicodeString);
134 PopupError(PCHAR Text,
152 /* Count text lines and longest line */
158 p = strchr(pnext, '\n');
161 Length = strlen(pnext);
166 Length = (ULONG)(p - pnext);
171 if (Length > MaxLength)
174 if (LastLine == TRUE)
180 /* Check length of status line */
183 Length = strlen(Status);
184 if (Length > MaxLength)
188 GetScreenSize(&xScreen, &yScreen);
190 Width = MaxLength + 4;
195 yTop = (yScreen - Height) / 2;
196 xLeft = (xScreen - Width) / 2;
199 /* Set screen attributes */
201 for (coPos.Y = yTop; coPos.Y < yTop + Height; coPos.Y++)
203 FillConsoleOutputAttribute(0x74,
209 /* draw upper left corner */
212 FillConsoleOutputCharacter(0xDA, // '+',
217 /* draw upper edge */
220 FillConsoleOutputCharacter(0xC4, // '-',
225 /* draw upper right corner */
226 coPos.X = xLeft + Width - 1;
228 FillConsoleOutputCharacter(0xBF, // '+',
233 /* Draw right edge, inner space and left edge */
234 for (coPos.Y = yTop + 1; coPos.Y < yTop + Height - 1; coPos.Y++)
237 FillConsoleOutputCharacter(0xB3, // '|',
243 FillConsoleOutputCharacter(' ',
248 coPos.X = xLeft + Width - 1;
249 FillConsoleOutputCharacter(0xB3, // '|',
255 /* draw lower left corner */
257 coPos.Y = yTop + Height - 1;
258 FillConsoleOutputCharacter(0xC0, // '+',
263 /* draw lower edge */
265 coPos.Y = yTop + Height - 1;
266 FillConsoleOutputCharacter(0xC4, // '-',
271 /* draw lower right corner */
272 coPos.X = xLeft + Width - 1;
273 coPos.Y = yTop + Height - 1;
274 FillConsoleOutputCharacter(0xD9, // '+',
279 /* Print message text */
284 p = strchr(pnext, '\n');
287 Length = strlen(pnext);
292 Length = (ULONG)(p - pnext);
299 WriteConsoleOutputCharacters(pnext,
304 if (LastLine == TRUE)
311 /* Print separator line and status text */
314 coPos.Y = yTop + Height - 3;
316 FillConsoleOutputCharacter(0xC3, // '+',
322 FillConsoleOutputCharacter(0xC4, // '-',
327 coPos.X = xLeft + Width - 1;
328 FillConsoleOutputCharacter(0xB4, // '+',
335 WriteConsoleOutputCharacters(Status,
336 min(strlen(Status), Width - 4),
346 * FALSE: Don't quit setup.
349 ConfirmQuit(PINPUT_RECORD Ir)
353 PopupError("ReactOS is not completely installed on your\n"
354 "computer. If you quit Setup now, you will need to\n"
355 "run Setup again to install ReactOS.\n"
357 " * Press ENTER to continue Setup.\n"
358 " * Press F3 to quit Setup.",
359 "F3= Quit ENTER = Continue");
365 if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
366 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */
371 else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
386 * Number of the next page.
389 StartPage(PINPUT_RECORD Ir)
392 WCHAR FileNameBuffer[MAX_PATH];
393 UNICODE_STRING FileName;
400 SetStatusText(" Please wait...");
402 Status = GetSourcePaths(&SourcePath,
404 if (!NT_SUCCESS(Status))
406 PrintTextXY(6, 15, "GetSourcePath() failed (Status 0x%08lx)", Status);
410 PrintTextXY(6, 15, "SourcePath: '%wZ'", &SourcePath);
411 PrintTextXY(6, 16, "SourceRootPath: '%wZ'", &SourceRootPath);
415 /* Load txtsetup.sif from install media. */
416 wcscpy(FileNameBuffer, SourceRootPath.Buffer);
417 wcscat(FileNameBuffer, L"\\install\\txtsetup.sif");
418 RtlInitUnicodeString(&FileName,
421 Status = InfOpenFile(&SetupInf,
424 if (!NT_SUCCESS(Status))
426 PopupError("Setup failed to load the file TXTSETUP.SIF.\n",
427 "ENTER = Reboot computer");
433 if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
440 /* Open 'Version' section */
441 if (!InfFindFirstLine (SetupInf, L"Version", L"Signature", &Context))
443 PopupError("Setup found a corrupt TXTSETUP.SIF.\n",
444 "ENTER = Reboot computer");
450 if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
458 /* Get pointer 'Signature' key */
459 if (!InfGetData (&Context, NULL, &Value))
461 PopupError("Setup found a corrupt TXTSETUP.SIF.\n",
462 "ENTER = Reboot computer");
468 if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
475 /* Check 'Signature' string */
476 if (_wcsicmp(Value, L"$ReactOS$") != 0)
478 PopupError("Setup found an invalid signature in TXTSETUP.SIF.\n",
479 "ENTER = Reboot computer");
485 if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
498 RepairIntroPage(PINPUT_RECORD Ir)
500 SetTextXY(6, 8, "ReactOS Setup is in an early development phase. It does not yet");
501 SetTextXY(6, 9, "support all the functions of a fully usable setup application.");
503 SetTextXY(6, 12, "The repair functions are not implemented yet.");
505 SetTextXY(8, 15, "\xfa Press ESC to return to the main page.");
507 SetTextXY(8, 17, "\xfa Press ENTER to reboot your computer.");
509 SetStatusText(" ESC = Main page ENTER = Reboot");
515 if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
519 else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
520 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE)) /* ESC */
526 return(REPAIR_INTRO_PAGE);
533 * TRUE: setup/repair completed successfully
534 * FALSE: setup/repair terminated by user
537 IntroPage(PINPUT_RECORD Ir)
539 SetHighlightedTextXY(6, 8, "Welcome to ReactOS Setup");
541 SetTextXY(6, 11, "This part of the setup copies the ReactOS Operating System to your");
542 SetTextXY(6, 12, "computer and prepares the second part of the setup.");
544 SetTextXY(8, 15, "\xfa Press ENTER to install ReactOS.");
546 SetTextXY(8, 17, "\xfa Press E to start the emergency repair console.");
548 SetTextXY(8, 19, "\xfa Press R to repair ReactOS.");
550 SetTextXY(8, 21, "\xfa Press F3 to quit without installing ReactOS.");
553 SetStatusText(" ENTER = Continue F3 = Quit");
559 if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
560 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */
562 if (ConfirmQuit(Ir) == TRUE)
566 else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
568 return(INSTALL_INTRO_PAGE);
571 else if (toupper(Ir->Event.KeyEvent.uChar.AsciiChar) == 'E') /* E */
573 return(RepairConsole());
576 else if (toupper(Ir->Event.KeyEvent.uChar.AsciiChar) == 'R') /* R */
578 return(REPAIR_INTRO_PAGE);
587 InstallIntroPage(PINPUT_RECORD Ir)
589 SetTextXY(6, 8, "ReactOS Setup is in an early development phase. It does not yet");
590 SetTextXY(6, 9, "support all the functions of a fully usable setup application.");
592 SetTextXY(6, 12, "The following functions are missing:");
593 SetTextXY(8, 13, "- Creating and deleting harddisk partitions.");
594 SetTextXY(8, 14, "- Formatting partitions.");
595 SetTextXY(8, 15, "- Support for non-FAT file systems.");
596 SetTextXY(8, 16, "- Checking file systems.");
600 SetTextXY(8, 21, "\xfa Press ENTER to install ReactOS.");
602 SetTextXY(8, 23, "\xfa Press F3 to quit without installing ReactOS.");
605 SetStatusText(" ENTER = Continue F3 = Quit");
611 if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
612 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */
614 if (ConfirmQuit(Ir) == TRUE)
618 else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
620 return(SELECT_PARTITION_PAGE);
624 return(INSTALL_INTRO_PAGE);
629 * Confirm delete partition
631 * TRUE: Delete currently selected partition.
632 * FALSE: Don't delete currently selected partition.
635 ConfirmDeletePartition(PINPUT_RECORD Ir)
639 PopupError("Are you sure you want to delete this partition?\n"
641 " * Press ENTER to delete the partition.\n"
642 " * Press ESC to NOT delete the partition.",
643 "ESC = Cancel ENTER = Delete partition");
649 if (Ir->Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE) /* ESC */
654 else if (Ir->Event.KeyEvent.wVirtualKeyCode == VK_RETURN) /* ENTER */
666 SelectPartitionPage(PINPUT_RECORD Ir)
668 WCHAR PathBuffer[MAX_PATH];
673 SetTextXY(6, 8, "The list below shows existing partitions and unused disk");
674 SetTextXY(6, 9, "space for new partitions.");
676 SetTextXY(8, 11, "\xfa Press UP or DOWN to select a list entry.");
677 SetTextXY(8, 13, "\xfa Press ENTER to install ReactOS onto the selected partition.");
678 SetTextXY(8, 15, "\xfa Press C to create a new partition.");
679 SetTextXY(8, 17, "\xfa Press D to delete an existing partition.");
681 SetStatusText(" Please wait...");
683 RtlFreeUnicodeString(&DestinationPath);
684 RtlFreeUnicodeString(&DestinationRootPath);
686 GetScreenSize(&xScreen, &yScreen);
688 PartList = CreatePartitionList(2, 19, xScreen - 3, yScreen - 3);
689 if (PartList == NULL)
691 /* FIXME: show an error dialog */
695 if (CurrentPartitionList != NULL)
697 DestroyPartitionList(CurrentPartitionList);
699 CurrentPartitionList = PartList;
701 SetStatusText(" ENTER = Continue F3 = Quit");
707 if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
708 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */
710 if (ConfirmQuit(Ir) == TRUE)
712 DestroyPartitionList(PartList);
717 else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
718 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_DOWN)) /* DOWN */
720 ScrollDownPartitionList(PartList);
722 else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
723 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_UP)) /* UP */
725 ScrollUpPartitionList(PartList);
727 else if (Ir->Event.KeyEvent.wVirtualKeyCode == VK_RETURN) /* ENTER */
729 PartDataValid = GetSelectedPartition(PartList,
733 ActivePartitionValid = GetActiveBootPartition(PartList,
736 RtlFreeUnicodeString(&DestinationRootPath);
738 L"\\Device\\Harddisk%lu\\Partition%lu",
740 PartData.PartNumber);
741 RtlCreateUnicodeString(&DestinationRootPath,
744 RtlFreeUnicodeString(&SystemRootPath);
746 if (ActivePartitionValid)
749 L"\\Device\\Harddisk%lu\\Partition%lu",
750 ActivePartition.DiskNumber,
751 ActivePartition.PartNumber);
755 /* We mark the selected partition as bootable */
757 L"\\Device\\Harddisk%lu\\Partition%lu",
759 PartData.PartNumber);
761 RtlCreateUnicodeString(&SystemRootPath,
764 return(SELECT_FILE_SYSTEM_PAGE);
768 /* FIXME: show an error dialog */
769 return(SELECT_PARTITION_PAGE);
772 else if (Ir->Event.KeyEvent.wVirtualKeyCode == VK_C) /* C */
775 /* Don't destroy the parition list here */;
776 return(CREATE_PARTITION_PAGE);
779 else if (Ir->Event.KeyEvent.wVirtualKeyCode == VK_D) /* D */
782 if (ConfirmDeletePartition(Ir) == TRUE)
784 (BOOLEAN) DeleteSelectedPartition(CurrentPartitionList);
786 return(SELECT_PARTITION_PAGE);
790 /* FIXME: Update status text */
794 return(SELECT_PARTITION_PAGE);
798 DrawInputField(ULONG FieldLength,
808 memset(buf, '_', sizeof(buf));
809 buf[FieldLength - strlen(FieldContent)] = 0;
810 strcat(buf, FieldContent);
811 WriteConsoleOutputCharacters(buf,
816 #define PARTITION_SIZE_INPUT_FIELD_LENGTH 6
819 ShowPartitionSizeInputBox(ULONG MaxSize,
845 GetScreenSize(&xScreen, &yScreen);
848 Right = xScreen - 12;
851 /* draw upper left corner */
854 FillConsoleOutputCharacter(0xDA, // '+',
859 /* draw upper edge */
862 FillConsoleOutputCharacter(0xC4, // '-',
867 /* draw upper right corner */
870 FillConsoleOutputCharacter(0xBF, // '+',
875 /* draw left and right edge */
876 for (i = Top + 1; i < Bottom; i++)
880 FillConsoleOutputCharacter(0xB3, // '|',
886 FillConsoleOutputCharacter(0xB3, //'|',
892 /* draw lower left corner */
895 FillConsoleOutputCharacter(0xC0, // '+',
900 /* draw lower edge */
903 FillConsoleOutputCharacter(0xC4, // '-',
908 /* draw lower right corner */
911 FillConsoleOutputCharacter(0xD9, // '+',
919 strcpy(buf, "Size of new partition:");
920 iLeft = coPos.X + strlen(buf) + 1;
922 WriteConsoleOutputCharacters(buf,
926 sprintf(buf, "MB (max. %d MB)", MaxSize / (1024 * 1024));
927 coPos.X = iLeft + PARTITION_SIZE_INPUT_FIELD_LENGTH + 1;
929 WriteConsoleOutputCharacters(buf,
935 DrawInputField(PARTITION_SIZE_INPUT_FIELD_LENGTH, iLeft, iTop, buf);
940 if ((Ir.Event.KeyEvent.uChar.AsciiChar == 0x00) &&
941 (Ir.Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */
948 else if (Ir.Event.KeyEvent.wVirtualKeyCode == VK_RETURN) /* ENTER */
952 else if (Ir.Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE) /* ESCAPE */
959 else if ((Ir.Event.KeyEvent.wVirtualKeyCode == VK_BACK) && (index > 0)) /* BACKSPACE */
963 DrawInputField(PARTITION_SIZE_INPUT_FIELD_LENGTH, iLeft, iTop, buf);
965 else if ((Ir.Event.KeyEvent.uChar.AsciiChar != 0x00)
966 && (index < PARTITION_SIZE_INPUT_FIELD_LENGTH))
968 ch = Ir.Event.KeyEvent.uChar.AsciiChar;
969 if ((ch >= '0') && (ch <= '9'))
974 DrawInputField(PARTITION_SIZE_INPUT_FIELD_LENGTH, iLeft, iTop, buf);
978 strcpy(InputBuffer, buf);
983 CreatePartitionPage(PINPUT_RECORD Ir)
986 WCHAR PathBuffer[MAX_PATH];
988 PPARTENTRY PartEntry;
993 CHAR InputBuffer[50];
997 SetTextXY(6, 8, "You have chosen to create a new partition in the unused disk space.");
998 SetTextXY(6, 9, "Please enter the size of the new partition in megabytes.");
1000 SetStatusText(" Please wait...");
1002 GetScreenSize(&xScreen, &yScreen);
1004 PartList = CurrentPartitionList;
1006 SetStatusText(" ENTER = Continue ESC = Cancel F3 = Quit");
1008 PartEntry = &PartList->DiskArray[PartList->CurrentDisk].PartArray[PartList->CurrentPartition];
1011 MaxSize = PartEntry->PartSize;
1012 ShowPartitionSizeInputBox(MaxSize, InputBuffer, &Quit, &Cancel);
1015 if (ConfirmQuit(Ir) == TRUE)
1017 DestroyPartitionList(PartList);
1021 else if (Cancel == TRUE)
1027 PartSize = atoi(InputBuffer);
1033 /* Convert to bytes */
1034 PartSize *= 1024 * 1024;
1036 if (PartSize > PartEntry->PartSize)
1042 assert(PartEntry->Unpartitioned == TRUE);
1043 PartEntry->PartType = PARTITION_ENTRY_UNUSED;
1044 PartEntry->Used = TRUE;
1046 PartDataValid = GetSelectedPartition(PartList,
1050 PartData.CreatePartition = TRUE;
1051 PartData.NewPartSize = PartSize;
1053 ActivePartitionValid = GetActiveBootPartition(PartList,
1056 RtlFreeUnicodeString(&DestinationRootPath);
1057 swprintf(PathBuffer,
1058 L"\\Device\\Harddisk%lu\\Partition%lu",
1059 PartData.DiskNumber,
1060 PartData.PartNumber);
1061 RtlCreateUnicodeString(&DestinationRootPath,
1064 RtlFreeUnicodeString(&SystemRootPath);
1066 if (ActivePartitionValid)
1068 swprintf(PathBuffer,
1069 L"\\Device\\Harddisk%lu\\Partition%lu",
1070 ActivePartition.DiskNumber,
1071 ActivePartition.PartNumber);
1075 /* We mark the selected partition as bootable */
1076 swprintf(PathBuffer,
1077 L"\\Device\\Harddisk%lu\\Partition%lu",
1078 PartData.DiskNumber,
1079 PartData.PartNumber);
1081 RtlCreateUnicodeString(&SystemRootPath,
1084 return(SELECT_FILE_SYSTEM_PAGE);
1088 /* FIXME: show an error dialog */
1089 return(SELECT_PARTITION_PAGE);
1094 return(SELECT_PARTITION_PAGE);
1098 static PFILE_SYSTEM_LIST
1099 CreateFileSystemList(SHORT Left,
1101 BOOLEAN ForceFormat,
1102 FILE_SYSTEM ForceFileSystem)
1104 PFILE_SYSTEM_LIST List;
1106 List = (PFILE_SYSTEM_LIST)RtlAllocateHeap(ProcessHeap, 0, sizeof(FILE_SYSTEM_LIST));
1113 #ifdef ENABLE_FORMAT
1114 List->FileSystemCount = 1;
1116 List->FileSystemCount = 0;
1120 List->CurrentFileSystem = ForceFileSystem;
1124 List->FileSystemCount++;
1125 List->CurrentFileSystem = FsKeep;
1132 DestroyFileSystemList(PFILE_SYSTEM_LIST List)
1134 RtlFreeHeap(ProcessHeap, 0, List);
1139 DrawFileSystemList(PFILE_SYSTEM_LIST List)
1147 #ifdef ENABLE_FORMAT
1148 coPos.X = List->Left;
1149 coPos.Y = List->Top + index;
1150 FillConsoleOutputAttribute(0x17,
1154 FillConsoleOutputCharacter(' ',
1159 if (List->CurrentFileSystem == FsFat)
1161 SetInvertedTextXY(List->Left, List->Top + index, " Format partition as FAT file system ");
1165 SetTextXY(List->Left, List->Top + index, " Format partition as FAT file system ");
1170 coPos.X = List->Left;
1171 coPos.Y = List->Top + index;
1172 FillConsoleOutputAttribute(0x17,
1176 FillConsoleOutputCharacter(' ',
1181 if (List->CurrentFileSystem == FsKeep)
1183 SetInvertedTextXY(List->Left, List->Top + index, " Keep current file system (no changes) ");
1187 SetTextXY(List->Left, List->Top + index, " Keep current file system (no changes) ");
1193 ScrollDownFileSystemList(PFILE_SYSTEM_LIST List)
1195 if ((ULONG) List->CurrentFileSystem < List->FileSystemCount - 1)
1197 (ULONG) List->CurrentFileSystem++;
1198 DrawFileSystemList(List);
1204 ScrollUpFileSystemList(PFILE_SYSTEM_LIST List)
1206 if ((ULONG) List->CurrentFileSystem > 0)
1208 (ULONG) List->CurrentFileSystem--;
1209 DrawFileSystemList(List);
1215 SelectFileSystemPage(PINPUT_RECORD Ir)
1217 PFILE_SYSTEM_LIST FileSystemList;
1224 if (PartDataValid == FALSE)
1226 /* FIXME: show an error dialog */
1230 /* adjust disk size */
1231 if (PartData.DiskSize >= 0x280000000ULL) /* 10 GB */
1233 DiskSize = (PartData.DiskSize + (1 << 29)) >> 30;
1238 DiskSize = (PartData.DiskSize + (1 << 19)) >> 20;
1242 /* adjust partition size */
1243 if (PartData.PartSize >= 0x280000000ULL) /* 10 GB */
1245 PartSize = (PartData.PartSize + (1 << 29)) >> 30;
1250 PartSize = (PartData.PartSize + (1 << 19)) >> 20;
1254 /* adjust partition type */
1255 if ((PartData.PartType == PARTITION_FAT_12) ||
1256 (PartData.PartType == PARTITION_FAT_16) ||
1257 (PartData.PartType == PARTITION_HUGE) ||
1258 (PartData.PartType == PARTITION_XINT13))
1262 else if ((PartData.PartType == PARTITION_FAT32) ||
1263 (PartData.PartType == PARTITION_FAT32_XINT13))
1267 else if (PartData.PartType == PARTITION_IFS)
1269 PartType = "NTFS"; /* FIXME: Not quite correct! */
1271 else if (PartData.PartType == PARTITION_ENTRY_UNUSED)
1273 PartType = "Unused";
1277 PartType = "Unknown";
1280 SetTextXY(6, 8, "Setup will install ReactOS on");
1282 PrintTextXY(8, 10, "Partition %lu (%I64u %s) %s of",
1283 PartData.PartNumber,
1288 PrintTextXY(8, 12, "Harddisk %lu (%I64u %s), Port=%hu, Bus=%hu, Id=%hu (%wZ).",
1289 PartData.DiskNumber,
1295 &PartData.DriverName);
1298 SetTextXY(6, 17, "Select a file system for the partition from the list below.");
1300 SetTextXY(8, 19, "\xfa Press UP or DOWN to select a file system.");
1301 SetTextXY(8, 21, "\xfa Press ENTER to format the partition.");
1302 SetTextXY(8, 23, "\xfa Press ESC to select another partition.");
1304 FileSystemList = CreateFileSystemList(6, 26, FALSE, FsKeep);
1305 if (FileSystemList == NULL)
1307 /* FIXME: show an error dialog */
1311 CurrentFileSystemList = FileSystemList;
1313 DrawFileSystemList(FileSystemList);
1315 SetStatusText(" ENTER = Continue ESC = Cancel F3 = Quit");
1321 if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
1322 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */
1324 if (ConfirmQuit(Ir) == TRUE)
1328 else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
1329 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE)) /* ESC */
1331 DestroyFileSystemList(FileSystemList);
1332 return(SELECT_PARTITION_PAGE);
1334 else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
1335 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_DOWN)) /* DOWN */
1337 ScrollDownFileSystemList(FileSystemList);
1339 else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
1340 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_UP)) /* UP */
1342 ScrollUpFileSystemList(FileSystemList);
1344 else if (Ir->Event.KeyEvent.wVirtualKeyCode == VK_RETURN) /* ENTER */
1346 if (FileSystemList->CurrentFileSystem == FsKeep)
1348 return(CHECK_FILE_SYSTEM_PAGE);
1352 return(FORMAT_PARTITION_PAGE);
1359 FormatPartitionPage(PINPUT_RECORD Ir)
1365 SetTextXY(6, 8, "Format partition");
1367 SetTextXY(6, 10, "Setup will now format the partition. Press ENTER to continue.");
1369 SetStatusText(" ENTER = Continue F3 = Quit");
1375 if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
1376 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */
1378 if (ConfirmQuit(Ir) == TRUE)
1384 else if (Ir->Event.KeyEvent.wVirtualKeyCode == VK_RETURN) /* ENTER */
1386 SetStatusText(" Please wait ...");
1388 switch (CurrentFileSystemList->CurrentFileSystem)
1390 #ifdef ENABLE_FORMAT
1392 PartType = PARTITION_FAT32_XINT13;
1401 if (PartData.CreatePartition)
1403 Valid = CreateSelectedPartition(CurrentPartitionList, PartType, PartData.NewPartSize);
1406 DPRINT("CreateSelectedPartition() failed\n");
1407 /* FIXME: show an error dialog */
1412 switch (CurrentFileSystemList->CurrentFileSystem)
1414 #ifdef ENABLE_FORMAT
1416 Status = FormatPartition(&DestinationRootPath);
1417 if (!NT_SUCCESS(Status))
1419 DPRINT1("FormatPartition() failed with status 0x%.08x\n", Status);
1420 /* FIXME: show an error dialog */
1430 return(INSTALL_DIRECTORY_PAGE);
1434 return(INSTALL_DIRECTORY_PAGE);
1438 CheckFileSystemPage(PINPUT_RECORD Ir)
1440 SetTextXY(6, 8, "Check file system");
1442 SetTextXY(6, 10, "At present, ReactOS can not check file systems.");
1444 SetStatusText(" Please wait ...");
1447 SetStatusText(" ENTER = Continue F3 = Quit");
1453 if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
1454 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */
1456 if (ConfirmQuit(Ir) == TRUE)
1460 else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
1462 return(INSTALL_DIRECTORY_PAGE);
1466 return(CHECK_FILE_SYSTEM_PAGE);
1471 InstallDirectoryPage(PINPUT_RECORD Ir)
1473 WCHAR PathBuffer[MAX_PATH];
1474 WCHAR InstallDir[51];
1480 /* Search for 'DefaultPath' in the 'SetupData' section */
1481 if (!InfFindFirstLine (SetupInf, L"SetupData", L"DefaultPath", &Context))
1483 PopupError("Setup failed to find the 'SetupData' section\n"
1484 "in TXTSETUP.SIF.\n",
1485 "ENTER = Reboot computer");
1491 if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
1498 /* Read the 'DefaultPath' data */
1499 if (InfGetData (&Context, NULL, &DefaultPath))
1501 wcscpy(InstallDir, DefaultPath);
1505 wcscpy(InstallDir, L"\\ReactOS");
1507 Length = wcslen(InstallDir);
1509 SetTextXY(6, 8, "Setup installs ReactOS files onto the selected partition. Choose a");
1510 SetTextXY(6, 9, "directory where you want ReactOS to be installed:");
1512 SetInputTextXY(8, 11, 51, InstallDir);
1514 SetTextXY(6, 14, "To change the suggested directory, press BACKSPACE to delete");
1515 SetTextXY(6, 15, "characters and then type the directory where you want ReactOS to");
1516 SetTextXY(6, 16, "be installed.");
1518 SetStatusText(" ENTER = Continue F3 = Quit");
1524 if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
1525 (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */
1527 if (ConfirmQuit(Ir) == TRUE)
1531 else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
1533 /* Create 'InstallPath' string */
1534 RtlFreeUnicodeString(&InstallPath);
1535 RtlCreateUnicodeString(&InstallPath,
1538 /* Create 'DestinationPath' string */
1539 RtlFreeUnicodeString(&DestinationPath);
1541 DestinationRootPath.Buffer);
1542 if (InstallDir[0] != L'\\')
1545 wcscat(PathBuffer, InstallDir);
1546 RtlCreateUnicodeString(&DestinationPath,
1549 /* Create 'DestinationArcPath' */
1550 RtlFreeUnicodeString(&DestinationArcPath);
1551 swprintf(PathBuffer,
1552 L"multi(0)disk(0)rdisk(%lu)partition(%lu)",
1553 PartData.DiskNumber,
1554 PartData.PartNumber);
1555 if (InstallDir[0] != L'\\')
1558 wcscat(PathBuffer, InstallDir);
1559 RtlCreateUnicodeString(&DestinationArcPath,
1562 return(PREPARE_COPY_PAGE);
1564 else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x08) /* BACKSPACE */
1569 InstallDir[Length] = 0;
1570 SetInputTextXY(8, 11, 51, InstallDir);
1573 else if (isprint(Ir->Event.KeyEvent.uChar.AsciiChar))
1577 InstallDir[Length] = (WCHAR)Ir->Event.KeyEvent.uChar.AsciiChar;
1579 InstallDir[Length] = 0;
1580 SetInputTextXY(8, 11, 51, InstallDir);
1585 return(INSTALL_DIRECTORY_PAGE);
1590 PrepareCopyPage(PINPUT_RECORD Ir)
1592 WCHAR PathBuffer[MAX_PATH];
1593 INFCONTEXT FilesContext;
1594 INFCONTEXT DirContext;
1601 PWCHAR FileKeyValue;
1605 SetTextXY(6, 8, "Setup prepares your computer for copying the ReactOS files. ");
1608 // SetTextXY(8, 12, "Build file copy list");
1610 // SetTextXY(8, 14, "Create directories");
1612 // SetStatusText(" Please wait...");
1615 * Build the file copy list
1617 SetStatusText(" Building the file copy list...");
1618 // SetInvertedTextXY(8, 12, "Build file copy list");
1622 /* Search for the 'SourceFiles' section */
1623 if (!InfFindFirstLine (SetupInf, L"SourceFiles", NULL, &FilesContext))
1625 PopupError("Setup failed to find the 'SourceFiles' section\n"
1626 "in TXTSETUP.SIF.\n",
1627 "ENTER = Reboot computer");
1633 if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
1641 /* Create the file queue */
1642 SetupFileQueue = SetupOpenFileQueue();
1643 if (SetupFileQueue == NULL)
1645 PopupError("Setup failed to open the copy file queue.\n",
1646 "ENTER = Reboot computer");
1652 if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
1660 * Enumerate the files in the 'SourceFiles' section
1661 * and add them to the file queue.
1665 if (!InfGetData (&FilesContext, &FileKeyName, &FileKeyValue))
1668 DPRINT1("FileKeyName: '%S' FileKeyValue: '%S'\n", FileKeyName, FileKeyValue);
1670 /* Lookup target directory */
1671 if (!InfFindFirstLine (SetupInf, L"Directories", FileKeyValue, &DirContext))
1673 /* FIXME: Handle error! */
1674 DPRINT1("InfFindFirstLine() failed\n");
1678 if (!InfGetData (&DirContext, NULL, &DirKeyValue))
1680 /* FIXME: Handle error! */
1681 DPRINT1("InfGetData() failed\n");
1685 if (!SetupQueueCopy(SetupFileQueue,
1686 SourceRootPath.Buffer,
1692 /* FIXME: Handle error! */
1693 DPRINT1("SetupQueueCopy() failed\n");
1696 while (InfFindNextLine(&FilesContext, &FilesContext));
1699 /* Create directories */
1700 SetStatusText(" Creating directories...");
1704 * Install directories like '\reactos\test' are not handled yet.
1707 /* Get destination path */
1708 wcscpy(PathBuffer, DestinationPath.Buffer);
1710 /* Remove trailing backslash */
1711 Length = wcslen(PathBuffer);
1712 if ((Length > 0) && (PathBuffer[Length - 1] == '\\'))
1714 PathBuffer[Length - 1] = 0;
1717 /* Create the install directory */
1718 Status = CreateDirectory(PathBuffer);
1719 if (!NT_SUCCESS(Status) && Status != STATUS_OBJECT_NAME_COLLISION)
1721 DPRINT("Creating directory '%S' failed: Status = 0x%08lx", PathBuffer, Status);
1722 PopupError("Setup could not create the install directory.",
1723 "ENTER = Reboot computer");
1729 if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
1737 /* Search for the 'Directories' section */
1738 if (!InfFindFirstLine(SetupInf, L"Directories", NULL, &DirContext))
1740 PopupError("Setup failed to find the 'Directories' section\n"
1741 "in TXTSETUP.SIF.\n",
1742 "ENTER = Reboot computer");
1748 if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
1755 /* Enumerate the directory values and create the subdirectories */
1758 if (!InfGetData (&DirContext, NULL, &KeyValue))
1761 if (KeyValue[0] == L'\\' && KeyValue[1] != 0)
1763 DPRINT("Absolute Path: '%S'\n", KeyValue);
1765 wcscpy(PathBuffer, DestinationRootPath.Buffer);
1766 wcscat(PathBuffer, KeyValue);
1768 DPRINT("FullPath: '%S'\n", PathBuffer);
1770 else if (KeyValue[0] != L'\\')
1772 DPRINT("RelativePath: '%S'\n", KeyValue);
1773 wcscpy(PathBuffer, DestinationPath.Buffer);
1774 wcscat(PathBuffer, L"\\");
1775 wcscat(PathBuffer, KeyValue);
1777 DPRINT("FullPath: '%S'\n", PathBuffer);
1779 Status = CreateDirectory(PathBuffer);
1780 if (!NT_SUCCESS(Status) && Status != STATUS_OBJECT_NAME_COLLISION)
1782 DPRINT("Creating directory '%S' failed: Status = 0x%08lx", PathBuffer, Status);
1783 PopupError("Setup could not create install directories.",
1784 "ENTER = Reboot computer");
1790 if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
1798 while (InfFindNextLine (&DirContext, &DirContext));
1800 return(FILE_COPY_PAGE);
1805 FileCopyCallback(PVOID Context,
1810 PCOPYCONTEXT CopyContext;
1812 CopyContext = (PCOPYCONTEXT)Context;
1814 switch (Notification)
1816 case SPFILENOTIFY_STARTSUBQUEUE:
1817 CopyContext->TotalOperations = (ULONG)Param2;
1818 ProgressSetStepCount(CopyContext->ProgressBar,
1819 CopyContext->TotalOperations);
1822 case SPFILENOTIFY_STARTCOPY:
1823 /* Display copy message */
1824 PrintTextXYN(6, 16, 60, "Copying file: %S", (PWSTR)Param1);
1826 PrintTextXYN(6, 18, 60, "File %lu of %lu",
1827 CopyContext->CompletedOperations + 1,
1828 CopyContext->TotalOperations);
1831 case SPFILENOTIFY_ENDCOPY:
1832 CopyContext->CompletedOperations++;
1833 ProgressNextStep(CopyContext->ProgressBar);
1842 FileCopyPage(PINPUT_RECORD Ir)
1844 COPYCONTEXT CopyContext;
1848 SetStatusText(" Please wait...");
1850 SetTextXY(6, 8, "Copying files");
1852 GetScreenSize(&xScreen, &yScreen);
1854 CopyContext.TotalOperations = 0;
1855 CopyContext.CompletedOperations = 0;
1856 CopyContext.ProgressBar = CreateProgressBar(6,
1861 SetupCommitFileQueue(SetupFileQueue,
1862 DestinationRootPath.Buffer,
1864 (PSP_FILE_CALLBACK)FileCopyCallback,
1867 SetupCloseFileQueue(SetupFileQueue);
1869 DestroyProgressBar(CopyContext.ProgressBar);
1871 return(REGISTRY_PAGE);
1876 RegistryPage(PINPUT_RECORD Ir)
1878 INFCONTEXT InfContext;
1887 SetTextXY(6, 8, "Setup is updating the system configuration");
1889 SetStatusText(" Creating registry hives...");
1891 if (!SetInstallPathValue(&DestinationPath))
1893 DPRINT("SetInstallPathValue() failed\n");
1894 PopupError("Setup failed to set the initialize the registry.",
1895 "ENTER = Reboot computer");
1901 if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
1908 /* Create the default hives */
1909 Status = NtInitializeRegistry(TRUE);
1910 if (!NT_SUCCESS(Status))
1912 DPRINT("NtInitializeRegistry() failed (Status %lx)\n", Status);
1913 PopupError("Setup failed to create the registry hives.",
1914 "ENTER = Reboot computer");
1920 if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
1927 /* Update registry */
1928 SetStatusText(" Updating registry hives...");
1930 if (!InfFindFirstLine(SetupInf, L"HiveInfs.Install", NULL, &InfContext))
1932 DPRINT1("InfFindFirstLine() failed\n");
1933 PopupError("Setup failed to find the registry data files.",
1934 "ENTER = Reboot computer");
1940 if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
1949 InfGetDataField (&InfContext, 0, &Action);
1950 InfGetDataField (&InfContext, 1, &File);
1951 InfGetDataField (&InfContext, 2, &Section);
1953 DPRINT1("Action: %S File: %S Section %S\n", Action, File, Section);
1955 if (!_wcsicmp (Action, L"AddReg"))
1959 else if (!_wcsicmp (Action, L"DelReg"))
1968 SetStatusText(" Importing %S...", File);
1970 if (!ImportRegistryFile(File, Section, Delete))
1972 DPRINT1("Importing %S failed\n", File);
1974 PopupError("Setup failed to import a hive file.",
1975 "ENTER = Reboot computer");
1981 if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
1988 while (InfFindNextLine (&InfContext, &InfContext));
1990 SetStatusText(" Done...");
1992 return(BOOT_LOADER_PAGE);
1997 BootLoaderPage(PINPUT_RECORD Ir)
1999 WCHAR SrcPath[MAX_PATH];
2000 WCHAR DstPath[MAX_PATH];
2002 PINICACHESECTION IniSection;
2004 BOOLEAN InstallMBR = FALSE;
2006 SetTextXY(6, 8, "Installing the boot loader");
2008 SetStatusText(" Please wait...");
2010 if (ActivePartitionValid == FALSE)
2012 /* Mark the chosen partition as active since there is no active
2015 if (!MarkPartitionActive(PartData.DiskNumber,
2016 PartData.PartNumber, &ActivePartition))
2018 PopupError("Setup could not mark the system partiton active\n",
2019 "ENTER = Reboot computer");
2025 if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
2036 WCHAR PathBuffer[MAX_PATH];
2037 UNICODE_STRING SystemRootMBRPath;
2039 RtlFreeUnicodeString(&SystemRootMBRPath);
2040 swprintf(PathBuffer,
2041 L"\\Device\\Harddisk%lu\\Partition0",
2042 PartData.DiskNumber);
2043 RtlCreateUnicodeString(&SystemRootMBRPath,
2046 /* Install MBR bootcode */
2047 wcscpy(SrcPath, SourceRootPath.Buffer);
2048 wcscat(SrcPath, L"\\loader\\dosmbr.bin");
2050 DPRINT1("Install MBR bootcode: %S ==> %S\n", SrcPath, SystemRootMBRPath.Buffer);
2051 Status = InstallMBRBootCodeToDisk(SrcPath,
2052 SystemRootMBRPath.Buffer);
2053 if (!NT_SUCCESS(Status))
2055 DPRINT1("InstallMBRBootCodeToDisk() failed (Status %lx)\n", Status);
2056 PopupError("Setup failed to install the MBR bootcode.",
2057 "ENTER = Reboot computer");
2063 if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
2071 if (ActivePartition.PartType == PARTITION_ENTRY_UNUSED)
2073 DPRINT1("Error: active partition invalid (unused)\n");
2074 PopupError("The active partition is unused (invalid).\n",
2075 "ENTER = Reboot computer");
2081 if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
2088 if (ActivePartition.PartType == 0x0A)
2090 /* OS/2 boot manager partition */
2091 DPRINT1("Found OS/2 boot manager partition\n");
2092 PopupError("Setup found an OS/2 boot manager partiton.\n"
2093 "The OS/2 boot manager is not supported yet!",
2094 "ENTER = Reboot computer");
2100 if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
2106 else if (ActivePartition.PartType == 0x83)
2108 /* Linux ext2 partition */
2109 DPRINT1("Found Linux ext2 partition\n");
2110 PopupError("Setup found a Linux ext2 partiton.\n"
2111 "Linux ext2 partitions are not supported yet!",
2112 "ENTER = Reboot computer");
2118 if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
2124 else if (ActivePartition.PartType == PARTITION_IFS)
2126 /* NTFS partition */
2127 DPRINT1("Found NTFS partition\n");
2128 PopupError("Setup found an NTFS partiton.\n"
2129 "NTFS partitions are not supported yet!",
2130 "ENTER = Reboot computer");
2136 if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
2142 else if ((ActivePartition.PartType == PARTITION_FAT_12) ||
2143 (ActivePartition.PartType == PARTITION_FAT_16) ||
2144 (ActivePartition.PartType == PARTITION_HUGE) ||
2145 (ActivePartition.PartType == PARTITION_XINT13) ||
2146 (ActivePartition.PartType == PARTITION_FAT32) ||
2147 (ActivePartition.PartType == PARTITION_FAT32_XINT13))
2149 /* FAT or FAT32 partition */
2150 DPRINT1("System path: '%wZ'\n", &SystemRootPath);
2152 if (DoesFileExist(SystemRootPath.Buffer, L"ntldr") == TRUE ||
2153 DoesFileExist(SystemRootPath.Buffer, L"boot.ini") == TRUE)
2155 /* Search root directory for 'ntldr' and 'boot.ini'. */
2156 DPRINT1("Found Microsoft Windows NT/2000/XP boot loader\n");
2158 /* Copy FreeLoader to the boot partition */
2159 wcscpy(SrcPath, SourceRootPath.Buffer);
2160 wcscat(SrcPath, L"\\loader\\freeldr.sys");
2161 wcscpy(DstPath, SystemRootPath.Buffer);
2162 wcscat(DstPath, L"\\freeldr.sys");
2164 DPRINT1("Copy: %S ==> %S\n", SrcPath, DstPath);
2165 Status = SetupCopyFile(SrcPath, DstPath);
2166 if (!NT_SUCCESS(Status))
2168 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status);
2169 PopupError("Setup failed to copy 'freeldr.sys'.",
2170 "ENTER = Reboot computer");
2176 if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
2183 /* Create or update freeldr.ini */
2184 if (DoesFileExist(SystemRootPath.Buffer, L"freeldr.ini") == FALSE)
2186 /* Create new 'freeldr.ini' */
2187 DPRINT1("Create new 'freeldr.ini'\n");
2188 wcscpy(DstPath, SystemRootPath.Buffer);
2189 wcscat(DstPath, L"\\freeldr.ini");
2191 Status = CreateFreeLoaderIniForReactos(DstPath,
2192 DestinationArcPath.Buffer);
2193 if (!NT_SUCCESS(Status))
2195 DPRINT1("CreateFreeLoaderIniForReactos() failed (Status %lx)\n", Status);
2196 PopupError("Setup failed to create 'freeldr.ini'.",
2197 "ENTER = Reboot computer");
2203 if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
2210 /* Install new bootcode */
2211 if ((ActivePartition.PartType == PARTITION_FAT32) ||
2212 (ActivePartition.PartType == PARTITION_FAT32_XINT13))
2214 /* Install FAT32 bootcode */
2215 wcscpy(SrcPath, SourceRootPath.Buffer);
2216 wcscat(SrcPath, L"\\loader\\fat32.bin");
2217 wcscpy(DstPath, SystemRootPath.Buffer);
2218 wcscat(DstPath, L"\\bootsect.ros");
2220 DPRINT1("Install FAT32 bootcode: %S ==> %S\n", SrcPath, DstPath);
2221 Status = InstallFat32BootCodeToFile(SrcPath,
2223 SystemRootPath.Buffer);
2224 if (!NT_SUCCESS(Status))
2226 DPRINT1("InstallFat32BootCodeToFile() failed (Status %lx)\n", Status);
2227 PopupError("Setup failed to install the FAT32 bootcode.",
2228 "ENTER = Reboot computer");
2234 if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
2243 /* Install FAT16 bootcode */
2244 wcscpy(SrcPath, SourceRootPath.Buffer);
2245 wcscat(SrcPath, L"\\loader\\fat.bin");
2246 wcscpy(DstPath, SystemRootPath.Buffer);
2247 wcscat(DstPath, L"\\bootsect.ros");
2249 DPRINT1("Install FAT bootcode: %S ==> %S\n", SrcPath, DstPath);
2250 Status = InstallFat16BootCodeToFile(SrcPath,
2252 SystemRootPath.Buffer);
2253 if (!NT_SUCCESS(Status))
2255 DPRINT1("InstallFat16BootCodeToFile() failed (Status %lx)\n", Status);
2256 PopupError("Setup failed to install the FAT bootcode.",
2257 "ENTER = Reboot computer");
2263 if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
2271 /* Update 'boot.ini' */
2272 wcscpy(DstPath, SystemRootPath.Buffer);
2273 wcscat(DstPath, L"\\boot.ini");
2275 DPRINT1("Update 'boot.ini': %S\n", DstPath);
2276 Status = UpdateBootIni(DstPath,
2277 L"C:\\bootsect.ros",
2279 if (!NT_SUCCESS(Status))
2281 DPRINT1("UpdateBootIni() failed (Status %lx)\n", Status);
2282 PopupError("Setup failed to update \'boot.ini\'.",
2283 "ENTER = Reboot computer");
2289 if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
2298 /* Update existing 'freeldr.ini' */
2299 DPRINT1("Update existing 'freeldr.ini'\n");
2300 wcscpy(DstPath, SystemRootPath.Buffer);
2301 wcscat(DstPath, L"\\freeldr.ini");
2303 Status = UpdateFreeLoaderIni(DstPath,
2304 DestinationArcPath.Buffer);
2305 if (!NT_SUCCESS(Status))
2307 DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status);
2308 PopupError("Setup failed to update 'freeldr.ini'.",
2309 "ENTER = Reboot computer");
2315 if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
2323 else if (DoesFileExist(SystemRootPath.Buffer, L"io.sys") == TRUE ||
2324 DoesFileExist(SystemRootPath.Buffer, L"msdos.sys") == TRUE)
2326 /* Search for root directory for 'io.sys' and 'msdos.sys'. */
2327 DPRINT1("Found Microsoft DOS or Windows 9x boot loader\n");
2329 /* Copy FreeLoader to the boot partition */
2330 wcscpy(SrcPath, SourceRootPath.Buffer);
2331 wcscat(SrcPath, L"\\loader\\freeldr.sys");
2332 wcscpy(DstPath, SystemRootPath.Buffer);
2333 wcscat(DstPath, L"\\freeldr.sys");
2335 DPRINT("Copy: %S ==> %S\n", SrcPath, DstPath);
2336 Status = SetupCopyFile(SrcPath, DstPath);
2337 if (!NT_SUCCESS(Status))
2339 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status);
2340 PopupError("Setup failed to copy 'freeldr.sys'.",
2341 "ENTER = Reboot computer");
2347 if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
2354 /* Create or update 'freeldr.ini' */
2355 if (DoesFileExist(SystemRootPath.Buffer, L"freeldr.ini") == FALSE)
2357 /* Create new 'freeldr.ini' */
2358 DPRINT1("Create new 'freeldr.ini'\n");
2359 wcscpy(DstPath, SystemRootPath.Buffer);
2360 wcscat(DstPath, L"\\freeldr.ini");
2362 Status = CreateFreeLoaderIniForDos(DstPath,
2363 DestinationArcPath.Buffer);
2364 if (!NT_SUCCESS(Status))
2366 DPRINT1("CreateFreeLoaderIniForDos() failed (Status %lx)\n", Status);
2367 PopupError("Setup failed to create 'freeldr.ini'.",
2368 "ENTER = Reboot computer");
2374 if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
2381 /* Save current bootsector as 'BOOTSECT.DOS' */
2382 wcscpy(SrcPath, SystemRootPath.Buffer);
2383 wcscpy(DstPath, SystemRootPath.Buffer);
2384 wcscat(DstPath, L"\\bootsect.dos");
2386 DPRINT1("Save bootsector: %S ==> %S\n", SrcPath, DstPath);
2387 Status = SaveCurrentBootSector(SrcPath,
2389 if (!NT_SUCCESS(Status))
2391 DPRINT1("SaveCurrentBootSector() failed (Status %lx)\n", Status);
2392 PopupError("Setup failed to save the current bootsector.",
2393 "ENTER = Reboot computer");
2399 if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
2406 /* Install new bootsector */
2407 if ((ActivePartition.PartType == PARTITION_FAT32) ||
2408 (ActivePartition.PartType == PARTITION_FAT32_XINT13))
2410 wcscpy(SrcPath, SourceRootPath.Buffer);
2411 wcscat(SrcPath, L"\\loader\\fat32.bin");
2413 DPRINT1("Install FAT32 bootcode: %S ==> %S\n", SrcPath, SystemRootPath.Buffer);
2414 Status = InstallFat32BootCodeToDisk(SrcPath,
2415 SystemRootPath.Buffer);
2416 if (!NT_SUCCESS(Status))
2418 DPRINT1("InstallFat32BootCodeToDisk() failed (Status %lx)\n", Status);
2419 PopupError("Setup failed to install the FAT32 bootcode.",
2420 "ENTER = Reboot computer");
2426 if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
2435 wcscpy(SrcPath, SourceRootPath.Buffer);
2436 wcscat(SrcPath, L"\\loader\\fat.bin");
2438 DPRINT1("Install FAT bootcode: %S ==> %S\n", SrcPath, SystemRootPath.Buffer);
2439 Status = InstallFat16BootCodeToDisk(SrcPath,
2440 SystemRootPath.Buffer);
2441 if (!NT_SUCCESS(Status))
2443 DPRINT1("InstallFat16BootCodeToDisk() failed (Status %lx)\n", Status);
2444 PopupError("Setup failed to install the FAT bootcode.",
2445 "ENTER = Reboot computer");
2451 if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
2461 /* Update existing 'freeldr.ini' */
2462 wcscpy(DstPath, SystemRootPath.Buffer);
2463 wcscat(DstPath, L"\\freeldr.ini");
2465 Status = UpdateFreeLoaderIni(DstPath,
2466 DestinationArcPath.Buffer);
2467 if (!NT_SUCCESS(Status))
2469 DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status);
2470 PopupError("Setup failed to update 'freeldr.ini'.",
2471 "ENTER = Reboot computer");
2477 if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
2487 /* No or unknown boot loader */
2488 DPRINT1("No or unknown boot loader found\n");
2490 /* Copy FreeLoader to the boot partition */
2491 wcscpy(SrcPath, SourceRootPath.Buffer);
2492 wcscat(SrcPath, L"\\loader\\freeldr.sys");
2493 wcscpy(DstPath, SystemRootPath.Buffer);
2494 wcscat(DstPath, L"\\freeldr.sys");
2496 DPRINT1("Copy: %S ==> %S\n", SrcPath, DstPath);
2497 Status = SetupCopyFile(SrcPath, DstPath);
2498 if (!NT_SUCCESS(Status))
2500 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status);
2501 PopupError("Setup failed to copy 'freeldr.sys'.",
2502 "ENTER = Reboot computer");
2508 if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
2515 /* Create or update 'freeldr.ini' */
2516 if (DoesFileExist(SystemRootPath.Buffer, L"freeldr.ini") == FALSE)
2518 /* Create new freeldr.ini */
2519 wcscpy(DstPath, SystemRootPath.Buffer);
2520 wcscat(DstPath, L"\\freeldr.ini");
2522 DPRINT1("Copy: %S ==> %S\n", SrcPath, DstPath);
2523 Status = CreateFreeLoaderIniForReactos(DstPath,
2524 DestinationArcPath.Buffer);
2525 if (!NT_SUCCESS(Status))
2527 DPRINT1("CreateFreeLoaderIniForReactos() failed (Status %lx)\n", Status);
2528 PopupError("Setup failed to create \'freeldr.ini\'.",
2529 "ENTER = Reboot computer");
2535 if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
2542 /* Save current bootsector as 'BOOTSECT.OLD' */
2543 wcscpy(SrcPath, SystemRootPath.Buffer);
2544 wcscpy(DstPath, SystemRootPath.Buffer);
2545 wcscat(DstPath, L"\\bootsect.old");
2547 DPRINT1("Save bootsector: %S ==> %S\n", SrcPath, DstPath);
2548 Status = SaveCurrentBootSector(SrcPath,
2550 if (!NT_SUCCESS(Status))
2552 DPRINT1("SaveCurrentBootSector() failed (Status %lx)\n", Status);
2553 PopupError("Setup failed save the current bootsector.",
2554 "ENTER = Reboot computer");
2560 if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
2567 /* Install new bootsector */
2568 if ((ActivePartition.PartType == PARTITION_FAT32) ||
2569 (ActivePartition.PartType == PARTITION_FAT32_XINT13))
2571 wcscpy(SrcPath, SourceRootPath.Buffer);
2572 wcscat(SrcPath, L"\\loader\\fat32.bin");
2574 DPRINT1("Install FAT32 bootcode: %S ==> %S\n", SrcPath, SystemRootPath.Buffer);
2575 Status = InstallFat32BootCodeToDisk(SrcPath,
2576 SystemRootPath.Buffer);
2577 if (!NT_SUCCESS(Status))
2579 DPRINT1("InstallFat32BootCodeToDisk() failed (Status %lx)\n", Status);
2580 PopupError("Setup failed to install the FAT32 bootcode.",
2581 "ENTER = Reboot computer");
2587 if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
2596 wcscpy(SrcPath, SourceRootPath.Buffer);
2597 wcscat(SrcPath, L"\\loader\\fat.bin");
2599 DPRINT1("Install FAT bootcode: %S ==> %S\n", SrcPath, SystemRootPath.Buffer);
2600 Status = InstallFat16BootCodeToDisk(SrcPath,
2601 SystemRootPath.Buffer);
2602 if (!NT_SUCCESS(Status))
2604 DPRINT1("InstallFat16BootCodeToDisk() failed (Status %lx)\n", Status);
2605 PopupError("Setup failed to install the FAT bootcode.",
2606 "ENTER = Reboot computer");
2612 if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
2622 /* Update existing 'freeldr.ini' */
2623 wcscpy(DstPath, SystemRootPath.Buffer);
2624 wcscat(DstPath, L"\\freeldr.ini");
2626 Status = UpdateFreeLoaderIni(DstPath,
2627 DestinationArcPath.Buffer);
2628 if (!NT_SUCCESS(Status))
2630 DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status);
2631 PopupError("Setup failed to update 'freeldr.ini'.",
2632 "ENTER = Reboot computer");
2638 if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
2649 /* Unknown partition */
2650 DPRINT1("Unknown partition found\n");
2651 PopupError("Setup found an unknown partiton type.\n"
2652 "This partition type is not supported!",
2653 "ENTER = Reboot computer");
2659 if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
2666 return(SUCCESS_PAGE);
2672 QuitPage(PINPUT_RECORD Ir)
2674 SetTextXY(10, 6, "ReactOS is not completely installed");
2676 SetTextXY(10, 8, "Remove floppy disk from Drive A: and");
2677 SetTextXY(10, 9, "all CD-ROMs from CD-Drives.");
2679 SetTextXY(10, 11, "Press ENTER to reboot your computer.");
2681 SetStatusText(" ENTER = Reboot computer");
2687 if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
2689 return(REBOOT_PAGE);
2696 SuccessPage(PINPUT_RECORD Ir)
2698 SetTextXY(10, 6, "The basic components of ReactOS have been installed successfully.");
2700 SetTextXY(10, 8, "Remove floppy disk from Drive A: and");
2701 SetTextXY(10, 9, "all CD-ROMs from CD-Drive.");
2703 SetTextXY(10, 11, "Press ENTER to reboot your computer.");
2705 SetStatusText(" ENTER = Reboot computer");
2711 if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
2713 return(REBOOT_PAGE);
2720 NtProcessStartup(PPEB Peb)
2726 RtlNormalizeProcessParams(Peb->ProcessParameters);
2728 ProcessHeap = Peb->ProcessHeap;
2730 Status = AllocConsole();
2731 if (!NT_SUCCESS(Status))
2733 PrintString("AllocConsole() failed (Status = 0x%08lx)\n", Status);
2735 /* Raise a hard error (crash the system/BSOD) */
2736 NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED,
2740 PartDataValid = FALSE;
2742 /* Initialize global unicode strings */
2743 RtlInitUnicodeString(&SourcePath, NULL);
2744 RtlInitUnicodeString(&SourceRootPath, NULL);
2745 RtlInitUnicodeString(&InstallPath, NULL);
2746 RtlInitUnicodeString(&DestinationPath, NULL);
2747 RtlInitUnicodeString(&DestinationArcPath, NULL);
2748 RtlInitUnicodeString(&DestinationRootPath, NULL);
2749 RtlInitUnicodeString(&SystemRootPath, NULL);
2753 while (Page != REBOOT_PAGE)
2757 SetUnderlinedTextXY(4, 3, " ReactOS " KERNEL_VERSION_STR " Setup ");
2763 Page = StartPage(&Ir);
2768 Page = IntroPage(&Ir);
2772 case INSTALL_INTRO_PAGE:
2773 Page = InstallIntroPage(&Ir);
2777 case OEM_DRIVER_PAGE:
2778 Page = OemDriverPage(&Ir);
2783 case DEVICE_SETTINGS_PAGE:
2786 case SELECT_PARTITION_PAGE:
2787 Page = SelectPartitionPage(&Ir);
2790 case CREATE_PARTITION_PAGE:
2791 Page = CreatePartitionPage(&Ir);
2794 case SELECT_FILE_SYSTEM_PAGE:
2795 Page = SelectFileSystemPage(&Ir);
2798 case FORMAT_PARTITION_PAGE:
2799 Page = FormatPartitionPage(&Ir);
2802 case CHECK_FILE_SYSTEM_PAGE:
2803 Page = CheckFileSystemPage(&Ir);
2806 case INSTALL_DIRECTORY_PAGE:
2807 Page = InstallDirectoryPage(&Ir);
2810 case PREPARE_COPY_PAGE:
2811 Page = PrepareCopyPage(&Ir);
2814 case FILE_COPY_PAGE:
2815 Page = FileCopyPage(&Ir);
2819 Page = RegistryPage(&Ir);
2822 case BOOT_LOADER_PAGE:
2823 Page = BootLoaderPage(&Ir);
2828 case REPAIR_INTRO_PAGE:
2829 Page = RepairIntroPage(&Ir);
2834 Page = SuccessPage(&Ir);
2838 Page = QuitPage(&Ir);
2845 NtShutdownSystem(ShutdownReboot);