#include <ddk/ntddk.h>
#include <ntdll/rtl.h>
+#include <ntos/minmax.h>
+#include <reactos/resource.h>
+
#include "usetup.h"
#include "console.h"
#include "partlist.h"
-
+#include "inicache.h"
+#include "filequeue.h"
+#include "progress.h"
+#include "bootsup.h"
#define START_PAGE 0
#define PREPARE_COPY_PAGE 7
#define INSTALL_DIRECTORY_PAGE 8
#define FILE_COPY_PAGE 9
-#define INIT_SYSTEM_PAGE 10
+#define REGISTRY_PAGE 10
+#define BOOT_LOADER_PAGE 11
#define REPAIR_INTRO_PAGE 20
#define REBOOT_PAGE 102
+typedef struct _COPYCONTEXT
+{
+ ULONG TotalOperations;
+ ULONG CompletedOperations;
+ PPROGRESS ProgressBar;
+} COPYCONTEXT, *PCOPYCONTEXT;
+
+
/* GLOBALS ******************************************************************/
HANDLE ProcessHeap;
-BOOL PartDataValid = FALSE;
+BOOLEAN PartDataValid;
PARTDATA PartData;
-CHAR InstallDir[51];
+BOOLEAN ActivePartitionValid;
+PARTDATA ActivePartition;
UNICODE_STRING SourcePath;
UNICODE_STRING SourceRootPath;
+UNICODE_STRING InstallPath;
+UNICODE_STRING DestinationPath;
+UNICODE_STRING DestinationArcPath;
+UNICODE_STRING DestinationRootPath;
+
+UNICODE_STRING SystemRootPath; /* Path to the active partition */
+
+PINICACHE IniCache;
+
+HSPFILEQ SetupFileQueue = NULL;
+
/* FUNCTIONS ****************************************************************/
}
+static VOID
+PopupError(PCHAR Text,
+ PCHAR Status)
+{
+ SHORT xScreen;
+ SHORT yScreen;
+ SHORT yTop;
+ SHORT xLeft;
+ COORD coPos;
+ ULONG Written;
+ ULONG Length;
+ ULONG MaxLength;
+ ULONG Lines;
+ PCHAR p;
+ PCHAR pnext;
+ BOOLEAN LastLine;
+ SHORT Width;
+ SHORT Height;
+
+ /* Count text lines and longest line */
+ MaxLength = 0;
+ Lines = 0;
+ pnext = Text;
+ while (TRUE)
+ {
+ p = strchr(pnext, '\n');
+ if (p == NULL)
+ {
+ Length = strlen(pnext);
+ LastLine = TRUE;
+ }
+ else
+ {
+ Length = (ULONG)(p - pnext);
+ LastLine = FALSE;
+ }
+
+ Lines++;
+ if (Length > MaxLength)
+ MaxLength = Length;
+
+ if (LastLine == TRUE)
+ break;
+
+ pnext = p + 1;
+ }
+
+ /* Check length of status line */
+ if (Status != NULL)
+ {
+ Length = strlen(Status);
+ if (Length > MaxLength)
+ MaxLength = Length;
+ }
+
+ GetScreenSize(&xScreen, &yScreen);
+
+ Width = MaxLength + 4;
+ Height = Lines + 2;
+ if (Status != NULL)
+ Height += 2;
+
+ yTop = (yScreen - Height) / 2;
+ xLeft = (xScreen - Width) / 2;
+
+
+ /* Set screen attributes */
+ coPos.X = xLeft;
+ for (coPos.Y = yTop; coPos.Y < yTop + Height; coPos.Y++)
+ {
+ FillConsoleOutputAttribute(0x74,
+ Width,
+ coPos,
+ &Written);
+ }
+
+ /* draw upper left corner */
+ coPos.X = xLeft;
+ coPos.Y = yTop;
+ FillConsoleOutputCharacter(0xDA, // '+',
+ 1,
+ coPos,
+ &Written);
+
+ /* draw upper edge */
+ coPos.X = xLeft + 1;
+ coPos.Y = yTop;
+ FillConsoleOutputCharacter(0xC4, // '-',
+ Width - 2,
+ coPos,
+ &Written);
+
+ /* draw upper right corner */
+ coPos.X = xLeft + Width - 1;
+ coPos.Y = yTop;
+ FillConsoleOutputCharacter(0xBF, // '+',
+ 1,
+ coPos,
+ &Written);
+
+ /* Draw right edge, inner space and left edge */
+ for (coPos.Y = yTop + 1; coPos.Y < yTop + Height - 1; coPos.Y++)
+ {
+ coPos.X = xLeft;
+ FillConsoleOutputCharacter(0xB3, // '|',
+ 1,
+ coPos,
+ &Written);
+
+ coPos.X = xLeft + 1;
+ FillConsoleOutputCharacter(' ',
+ Width - 2,
+ coPos,
+ &Written);
+
+ coPos.X = xLeft + Width - 1;
+ FillConsoleOutputCharacter(0xB3, // '|',
+ 1,
+ coPos,
+ &Written);
+ }
+
+ /* draw lower left corner */
+ coPos.X = xLeft;
+ coPos.Y = yTop + Height - 1;
+ FillConsoleOutputCharacter(0xC0, // '+',
+ 1,
+ coPos,
+ &Written);
+
+ /* draw lower edge */
+ coPos.X = xLeft + 1;
+ coPos.Y = yTop + Height - 1;
+ FillConsoleOutputCharacter(0xC4, // '-',
+ Width - 2,
+ coPos,
+ &Written);
+
+ /* draw lower right corner */
+ coPos.X = xLeft + Width - 1;
+ coPos.Y = yTop + Height - 1;
+ FillConsoleOutputCharacter(0xD9, // '+',
+ 1,
+ coPos,
+ &Written);
+
+ /* Print message text */
+ coPos.Y = yTop + 1;
+ pnext = Text;
+ while (TRUE)
+ {
+ p = strchr(pnext, '\n');
+ if (p == NULL)
+ {
+ Length = strlen(pnext);
+ LastLine = TRUE;
+ }
+ else
+ {
+ Length = (ULONG)(p - pnext);
+ LastLine = FALSE;
+ }
+
+ if (Length != 0)
+ {
+ coPos.X = xLeft + 2;
+ WriteConsoleOutputCharacters(pnext,
+ Length,
+ coPos);
+ }
+
+ if (LastLine == TRUE)
+ break;
+
+ coPos.Y++;
+ pnext = p + 1;
+ }
+
+ /* Print separator line and status text */
+ if (Status != NULL)
+ {
+ coPos.Y = yTop + Height - 3;
+ coPos.X = xLeft;
+ FillConsoleOutputCharacter(0xC3, // '+',
+ 1,
+ coPos,
+ &Written);
+
+ coPos.X = xLeft + 1;
+ FillConsoleOutputCharacter(0xC4, // '-',
+ Width - 2,
+ coPos,
+ &Written);
+
+ coPos.X = xLeft + Width - 1;
+ FillConsoleOutputCharacter(0xB4, // '+',
+ 1,
+ coPos,
+ &Written);
+
+ coPos.Y++;
+ coPos.X = xLeft + 2;
+ WriteConsoleOutputCharacters(Status,
+ min(strlen(Status), Width - 4),
+ coPos);
+ }
+}
+
+
/*
* Confirm quit setup
* RETURNS
static BOOL
ConfirmQuit(PINPUT_RECORD Ir)
{
- SHORT xScreen;
- SHORT yScreen;
- SHORT yTop;
- SHORT xLeft;
BOOL Result = FALSE;
- PUSHORT pAttributes = NULL;
- PUCHAR pCharacters = NULL;
- COORD Pos;
-
- GetScreenSize(&xScreen, &yScreen);
- yTop = (yScreen - 10) / 2;
- xLeft = (xScreen - 52) / 2;
-
- /* Save screen */
-#if 0
- Pos.X = 0;
- Pos.Y = 0;
- pAttributes = (PUSHORT)RtlAllocateHeap(ProcessHeap,
- 0,
- xScreen * yScreen * sizeof(USHORT));
-CHECKPOINT1;
-DPRINT1("pAttributes %p\n", pAttributes);
- ReadConsoleOutputAttributes(pAttributes,
- xScreen * yScreen,
- Pos,
- NULL);
-CHECKPOINT1;
- pCharacters = (PUCHAR)RtlAllocateHeap(ProcessHeap,
- 0,
- xScreen * yScreen * sizeof(UCHAR));
-CHECKPOINT1;
- ReadConsoleOutputCharacters(pCharacters,
- xScreen * yScreen,
- Pos,
- NULL);
-CHECKPOINT1;
-#endif
- /* Draw popup window */
- SetTextXY(xLeft, yTop,
- "+----------------------------------------------------+");
- SetTextXY(xLeft, yTop + 1,
- "| ReactOS 0.0.20 is not completely installed on your |");
- SetTextXY(xLeft, yTop + 2,
- "| computer. If you quit Setup now, you will need to |");
- SetTextXY(xLeft, yTop + 3,
- "| run Setup again to install ReactOS. |");
- SetTextXY(xLeft, yTop + 4,
- "| |");
- SetTextXY(xLeft, yTop + 5,
- "| * Press ENTER to continue Setup. |");
- SetTextXY(xLeft, yTop + 6,
- "| * Press F3 to quit Setup. |");
- SetTextXY(xLeft, yTop + 7,
- "+----------------------------------------------------+");
- SetTextXY(xLeft, yTop + 8,
- "| F3= Quit ENTER = Continue |");
- SetTextXY(xLeft, yTop + 9,
- "+----------------------------------------------------+");
+ PopupError("ReactOS is not completely installed on your\n"
+ "computer. If you quit Setup now, you will need to\n"
+ "run Setup again to install ReactOS.\n"
+ "\n"
+ " * Press ENTER to continue Setup.\n"
+ " * Press F3 to quit Setup.",
+ "F3= Quit ENTER = Continue");
while(TRUE)
{
}
}
- /* Restore screen */
-#if 0
-CHECKPOINT1;
- WriteConsoleOutputAttributes(pAttributes,
- xScreen * yScreen,
- Pos,
- NULL);
-CHECKPOINT1;
-
- WriteConsoleOutputCharacters(pCharacters,
- xScreen * yScreen,
- Pos);
-CHECKPOINT1;
-
- RtlFreeHeap(ProcessHeap,
- 0,
- pAttributes);
- RtlFreeHeap(ProcessHeap,
- 0,
- pCharacters);
-#endif
-
return(Result);
}
-
/*
* Start page
* RETURNS
StartPage(PINPUT_RECORD Ir)
{
NTSTATUS Status;
+ WCHAR FileNameBuffer[MAX_PATH];
+ UNICODE_STRING FileName;
+
+ PINICACHESECTION Section;
+ PWCHAR Value;
+
SetStatusText(" Please wait...");
PrintTextXY(6, 16, "SourceRootPath: '%wZ'", &SourceRootPath);
}
- /*
- * FIXME: Open and load txtsetup.sif here. A pointer (or handle) to the
- * ini data should be stored in a global variable.
- * The full path to txtsetup.sif is created by appending '\txtsetup.sif'
- * to the unicode string SourceRootPath.
- */
- SetStatusText(" ENTER = Continue");
+ /* Load txtsetup.sif from install media. */
+ wcscpy(FileNameBuffer, SourceRootPath.Buffer);
+ wcscat(FileNameBuffer, L"\\install\\txtsetup.sif");
+ RtlInitUnicodeString(&FileName,
+ FileNameBuffer);
- while(TRUE)
+ IniCache = NULL;
+ Status = IniCacheLoad(&IniCache,
+ &FileName,
+ TRUE);
+ if (!NT_SUCCESS(Status))
{
- ConInKey(Ir);
+ PopupError("Setup failed to load the file TXTSETUP.SIF.\n",
+ "ENTER = Reboot computer");
- if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
+ while(TRUE)
{
- return(INTRO_PAGE);
+ ConInKey(Ir);
+
+ if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
+ {
+ return(QUIT_PAGE);
+ }
+ }
+ }
+
+ /* Open 'Version' section */
+ Section = IniCacheGetSection(IniCache,
+ L"Version");
+ if (Section == NULL)
+ {
+ PopupError("Setup found a corrupt TXTSETUP.SIF.\n",
+ "ENTER = Reboot computer");
+
+ while(TRUE)
+ {
+ ConInKey(Ir);
+
+ if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
+ {
+ return(QUIT_PAGE);
+ }
+ }
+ }
+
+
+ /* Get pointer 'Signature' key */
+ Status = IniCacheGetKey(Section,
+ L"Signature",
+ &Value);
+ if (!NT_SUCCESS(Status))
+ {
+ PopupError("Setup found a corrupt TXTSETUP.SIF.\n",
+ "ENTER = Reboot computer");
+
+ while(TRUE)
+ {
+ ConInKey(Ir);
+
+ if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
+ {
+ return(QUIT_PAGE);
+ }
+ }
+ }
+
+ /* Check 'Signature' string */
+ if (_wcsicmp(Value, L"$ReactOS$") != 0)
+ {
+ PopupError("Setup found an invalid signature in TXTSETUP.SIF.\n",
+ "ENTER = Reboot computer");
+
+ while(TRUE)
+ {
+ ConInKey(Ir);
+
+ if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
+ {
+ return(QUIT_PAGE);
+ }
}
}
- return(START_PAGE);
+ return(INTRO_PAGE);
}
SetTextXY(6, 12, "The repair functions are not implemented yet.");
- SetTextXY(8, 15, "\xf9 Press ESC to return to the main page.");
+ SetTextXY(8, 15, "\xfa Press ESC to return to the main page.");
- SetTextXY(8, 17, "\xf9 Press ENTER to reboot your computer.");
+ SetTextXY(8, 17, "\xfa Press ENTER to reboot your computer.");
SetStatusText(" ESC = Main page ENTER = Reboot");
SetTextXY(6, 11, "This part of the setup copies the ReactOS Operating System to your");
SetTextXY(6, 12, "computer and prepares the second part of the setup.");
- SetTextXY(8, 15, "\xf9 Press ENTER to install ReactOS.");
+ SetTextXY(8, 15, "\xfa Press ENTER to install ReactOS.");
- SetTextXY(8, 17, "\xf9 Press E to start the emergency repair console.");
+ SetTextXY(8, 17, "\xfa Press E to start the emergency repair console.");
- SetTextXY(8, 19, "\xf9 Press R to repair ReactOS.");
+ SetTextXY(8, 19, "\xfa Press R to repair ReactOS.");
- SetTextXY(8, 21, "\xf9 Press F3 to quit without installing ReactOS.");
+ SetTextXY(8, 21, "\xfa Press F3 to quit without installing ReactOS.");
SetStatusText(" ENTER = Continue F3 = Quit");
SetTextXY(8, 14, "- Formatting partitions.");
SetTextXY(8, 15, "- Support for non-FAT file systems.");
SetTextXY(8, 16, "- Checking file systems.");
- SetTextXY(8, 17, "- Installing the bootloader.");
- SetTextXY(8, 21, "\xf9 Press ENTER to install ReactOS.");
+ SetTextXY(8, 21, "\xfa Press ENTER to install ReactOS.");
- SetTextXY(8, 23, "\xf9 Press F3 to quit without installing ReactOS.");
+ SetTextXY(8, 23, "\xfa Press F3 to quit without installing ReactOS.");
SetStatusText(" ENTER = Continue F3 = Quit");
static ULONG
SelectPartitionPage(PINPUT_RECORD Ir)
{
+ WCHAR PathBuffer[MAX_PATH];
PPARTLIST PartList;
SHORT xScreen;
SHORT yScreen;
SetTextXY(6, 8, "The list below shows existing partitions and unused disk");
SetTextXY(6, 9, "space for new partitions.");
- SetTextXY(8, 11, "\xf9 Press UP or DOWN to select a list entry.");
- SetTextXY(8, 13, "\xf9 Press ENTER to install ReactOS onto the selected partition.");
- SetTextXY(8, 15, "\xf9 Press C to create a new partition.");
- SetTextXY(8, 17, "\xf9 Press D to delete an existing partition.");
+ SetTextXY(8, 11, "\xfa Press UP or DOWN to select a list entry.");
+ SetTextXY(8, 13, "\xfa Press ENTER to install ReactOS onto the selected partition.");
+ SetTextXY(8, 15, "\xfa Press C to create a new partition.");
+ SetTextXY(8, 17, "\xfa Press D to delete an existing partition.");
SetStatusText(" Please wait...");
+ RtlFreeUnicodeString(&DestinationPath);
+ RtlFreeUnicodeString(&DestinationRootPath);
+
GetScreenSize(&xScreen, &yScreen);
PartList = CreatePartitionList(2, 19, xScreen - 3, yScreen - 3);
}
else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
{
- PartDataValid = GetPartitionData(PartList, &PartData);
+ PartDataValid = GetSelectedPartition(PartList,
+ &PartData);
+ ActivePartitionValid = GetActiveBootPartition(PartList,
+ &ActivePartition);
DestroyPartitionList(PartList);
+
+ RtlFreeUnicodeString(&DestinationRootPath);
+ swprintf(PathBuffer,
+ L"\\Device\\Harddisk%lu\\Partition%lu",
+ PartData.DiskNumber,
+ PartData.PartNumber);
+ RtlCreateUnicodeString(&DestinationRootPath,
+ PathBuffer);
+
+ RtlFreeUnicodeString(&SystemRootPath);
+ swprintf(PathBuffer,
+ L"\\Device\\Harddisk%lu\\Partition%lu",
+ ActivePartition.DiskNumber,
+ ActivePartition.PartNumber);
+ RtlCreateUnicodeString(&SystemRootPath,
+ PathBuffer);
+
return(SELECT_FILE_SYSTEM_PAGE);
}
PartType = "Unknown";
}
- SetTextXY(6, 8, "ReactOS will be installed");
+ SetTextXY(6, 8, "Setup will install ReactOS on");
+
+ PrintTextXY(8, 10, "Partition %lu (%I64u %s) %s on",
+ PartData.PartNumber,
+ PartSize,
+ PartUnit,
+ PartType);
- PrintTextXY(8, 9, "on Harddisk %lu (%I64u %s), Port=%hu, Bus=%hu, Id=%hu.",
+ PrintTextXY(8, 12, "Harddisk %lu (%I64u %s), Port=%hu, Bus=%hu, Id=%hu (%wZ).",
PartData.DiskNumber,
DiskSize,
DiskUnit,
PartData.Port,
PartData.Bus,
- PartData.Id);
+ PartData.Id,
+ &PartData.DriverName);
- PrintTextXY(8, 10, "on Partition %lu (%I64u %s) %s",
- PartData.PartNumber,
- PartSize,
- PartUnit,
- PartType);
- SetTextXY(6, 13, "Select a file system for the partition from the list below.");
+ SetTextXY(6, 17, "Select a file system for the partition from the list below.");
- SetTextXY(8, 15, "\xf9 Press UP or DOWN to select a file system.");
- SetTextXY(8, 17, "\xf9 Press ENTER to format the partition.");
- SetTextXY(8, 19, "\xf9 Press ESC to select another partition.");
+ SetTextXY(8, 19, "\xfa Press UP or DOWN to select a file system.");
+ SetTextXY(8, 21, "\xfa Press ENTER to format the partition.");
+ SetTextXY(8, 23, "\xfa Press ESC to select another partition.");
/* FIXME: use a real list later */
- SetInvertedTextXY(6, 22, " Keep current file system (no changes) ");
+ SetInvertedTextXY(6, 26, " Keep current file system (no changes) ");
SetStatusText(" ENTER = Continue ESC = Cancel F3 = Quit");
static ULONG
InstallDirectoryPage(PINPUT_RECORD Ir)
{
+ PINICACHESECTION Section;
+ WCHAR PathBuffer[MAX_PATH];
+ WCHAR InstallDir[51];
+ PWCHAR DefaultPath;
ULONG Length;
+ NTSTATUS Status;
+
+ /* Open 'SetupData' section */
+ Section = IniCacheGetSection(IniCache,
+ L"SetupData");
+ if (Section == NULL)
+ {
+ PopupError("Setup failed to find the 'SetupData' section\n"
+ "in TXTSETUP.SIF.\n",
+ "ENTER = Reboot computer");
+
+ while(TRUE)
+ {
+ ConInKey(Ir);
+
+ if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
+ {
+ return(QUIT_PAGE);
+ }
+ }
+ }
+
+ /* Read the 'DefaultPath' key */
+ Status = IniCacheGetKey(Section,
+ L"DefaultPath",
+ &DefaultPath);
+ if (!NT_SUCCESS(Status))
+ {
+ wcscpy(InstallDir, L"\\reactos");
+ }
+ else
+ {
+ wcscpy(InstallDir, DefaultPath);
+ }
+ Length = wcslen(InstallDir);
SetTextXY(6, 8, "Setup installs ReactOS files onto the selected partition. Choose a");
SetTextXY(6, 9, "directory where you want ReactOS to be installed:");
- strcpy(InstallDir, "\\reactos");
- Length = strlen(InstallDir);
-
SetInputTextXY(8, 11, 51, InstallDir);
SetTextXY(6, 14, "To change the suggested directory, press BACKSPACE to delete");
SetTextXY(6, 15, "characters and then type the directory where you want ReactOS to");
SetTextXY(6, 16, "be installed.");
-
SetStatusText(" ENTER = Continue F3 = Quit");
while(TRUE)
}
else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
{
+ /* Create 'InstallPath' string */
+ RtlFreeUnicodeString(&InstallPath);
+ RtlCreateUnicodeString(&InstallPath,
+ InstallDir);
+
+ /* Create 'DestinationPath' string */
+ RtlFreeUnicodeString(&DestinationPath);
+ wcscpy(PathBuffer,
+ DestinationRootPath.Buffer);
+ if (InstallDir[0] != L'\\')
+ wcscat(PathBuffer,
+ L"\\");
+ wcscat(PathBuffer, InstallDir);
+ RtlCreateUnicodeString(&DestinationPath,
+ PathBuffer);
+
+ /* Create 'DestinationArcPath' */
+ RtlFreeUnicodeString(&DestinationArcPath);
+ swprintf(PathBuffer,
+ L"multi(0)disk(0)rdisk(%lu)partition(%lu)",
+ PartData.DiskNumber,
+ PartData.PartNumber);
+ if (InstallDir[0] != L'\\')
+ wcscat(PathBuffer,
+ L"\\");
+ wcscat(PathBuffer, InstallDir);
+ RtlCreateUnicodeString(&DestinationArcPath,
+ PathBuffer);
+
return(PREPARE_COPY_PAGE);
}
else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x08) /* BACKSPACE */
{
if (Length < 50)
{
- InstallDir[Length] = Ir->Event.KeyEvent.uChar.AsciiChar;
+ InstallDir[Length] = (WCHAR)Ir->Event.KeyEvent.uChar.AsciiChar;
Length++;
InstallDir[Length] = 0;
SetInputTextXY(8, 11, 51, InstallDir);
static ULONG
PrepareCopyPage(PINPUT_RECORD Ir)
{
- OBJECT_ATTRIBUTES ObjectAttributes;
- IO_STATUS_BLOCK IoStatusBlock;
- CHAR PathBuffer[MAX_PATH];
- UNICODE_STRING PathName;
- HANDLE DirectoryHandle;
- NTSTATUS Status;
- PCHAR End;
+ WCHAR PathBuffer[MAX_PATH];
+ PINICACHESECTION DirSection;
+ PINICACHESECTION FilesSection;
+ PINICACHEITERATOR Iterator;
+ PWCHAR KeyName;
+ PWCHAR KeyValue;
ULONG Length;
- ULONG i;
+ NTSTATUS Status;
- PCHAR Dirs[]= {
- "System32",
- "System32\\Config",
- "System32\\Drivers",
- "Inf",
- "Help",
- "Fonts",
- NULL};
+ PWCHAR FileKeyName;
+ PWCHAR FileKeyValue;
+ PWCHAR DirKeyName;
+ PWCHAR DirKeyValue;
SetTextXY(6, 8, "Setup prepares your computer for copying the ReactOS files. ");
- SetTextXY(8, 12, "Build file copy list");
+// SetTextXY(8, 12, "Build file copy list");
- SetTextXY(8, 14, "Create directories");
+// SetTextXY(8, 14, "Create directories");
- SetStatusText(" Please wait...");
+// SetStatusText(" Please wait...");
- /* build the file copy list */
+ /*
+ * Build the file copy list
+ */
+ SetStatusText(" Building the file copy list...");
+// SetInvertedTextXY(8, 12, "Build file copy list");
- SetInvertedTextXY(8, 12, "Build file copy list");
- /* FIXME: build that list */
+ /* Open 'Directories' section */
+ DirSection = IniCacheGetSection(IniCache,
+ L"Directories");
+ if (DirSection == NULL)
+ {
+ PopupError("Setup failed to find the 'Directories' section\n"
+ "in TXTSETUP.SIF.\n",
+ "ENTER = Reboot computer");
- SetTextXY(8, 12, "Build file copy list");
- SetHighlightedTextXY(50, 12, "Done");
+ while(TRUE)
+ {
+ ConInKey(Ir);
+ if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
+ {
+ return(QUIT_PAGE);
+ }
+ }
+ }
+
+ /* Open 'SourceFiles' section */
+ FilesSection = IniCacheGetSection(IniCache,
+ L"SourceFiles");
+ if (FilesSection == NULL)
+ {
+ PopupError("Setup failed to find the 'SourceFiles' section\n"
+ "in TXTSETUP.SIF.\n",
+ "ENTER = Reboot computer");
+
+ while(TRUE)
+ {
+ ConInKey(Ir);
+
+ if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
+ {
+ return(QUIT_PAGE);
+ }
+ }
+ }
- /* create directories */
- SetInvertedTextXY(8, 14, "Create directories");
+ /* Create the file queue */
+ SetupFileQueue = SetupOpenFileQueue();
+ if (SetupFileQueue == NULL)
+ {
+ PopupError("Setup failed to open the copy file queue.\n",
+ "ENTER = Reboot computer");
+
+ while(TRUE)
+ {
+ ConInKey(Ir);
+
+ if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
+ {
+ return(QUIT_PAGE);
+ }
+ }
+ }
/*
- * FIXME: Enumerate the ini section 'Directories' and create all "relative" directories
+ * Enumerate the files in the 'SourceFiles' section
+ * and add them to the file queue.
*/
+ Iterator = IniCacheFindFirstValue(FilesSection,
+ &FileKeyName,
+ &FileKeyValue);
+ if (Iterator != NULL)
+ {
+ do
+ {
+ DPRINT1("FileKeyName: '%S' FileKeyValue: '%S'\n", FileKeyName, FileKeyValue);
+ /* Lookup target directory */
+ Status = IniCacheGetKey(DirSection,
+ FileKeyValue,
+ &DirKeyValue);
+ if (!NT_SUCCESS(Status))
+ {
+ /* FIXME: Handle error! */
+ DPRINT1("IniCacheGetKey() failed (Status 0x%lX)\n", Status);
+ }
+
+ if (SetupQueueCopy(SetupFileQueue,
+ SourceRootPath.Buffer,
+ L"\\install",
+ FileKeyName,
+ DirKeyValue,
+ NULL) == FALSE)
+ {
+ /* FIXME: Handle error! */
+ DPRINT1("SetupQueueCopy() failed\n");
+ }
+ }
+ while (IniCacheFindNextValue(Iterator, &FileKeyName, &FileKeyValue));
- /* create the systemroot directory */
- sprintf(PathBuffer,
- "\\Device\\Harddisk%lu\\Partition%lu",
- PartData.DiskNumber,
- PartData.PartNumber);
- if (InstallDir[0] != '\\')
- strcat(PathBuffer, "\\");
- strcat(PathBuffer, InstallDir);
+ IniCacheFindClose(Iterator);
+ }
+
+ /* Report that the file queue has been built */
+// SetTextXY(8, 12, "Build file copy list");
+// SetHighlightedTextXY(50, 12, "Done");
+
+ /* create directories */
+ SetStatusText(" Creating directories...");
+// SetInvertedTextXY(8, 14, "Create directories");
- /* remove trailing backslash */
- Length = strlen(PathBuffer);
+
+ /*
+ * FIXME:
+ * Install directories like '\reactos\test' are not handled yet.
+ */
+
+ /* Get destination path */
+ wcscpy(PathBuffer, DestinationPath.Buffer);
+
+ /* Remove trailing backslash */
+ Length = wcslen(PathBuffer);
if ((Length > 0) && (PathBuffer[Length - 1] == '\\'))
PathBuffer[Length - 1] = 0;
- RtlCreateUnicodeStringFromAsciiz(&PathName,
- PathBuffer);
-
- ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
- ObjectAttributes.RootDirectory = NULL;
- ObjectAttributes.ObjectName = &PathName;
- ObjectAttributes.Attributes = OBJ_CASE_INSENSITIVE | OBJ_INHERIT;
- ObjectAttributes.SecurityDescriptor = NULL;
- ObjectAttributes.SecurityQualityOfService = NULL;
-
- Status = NtCreateFile(&DirectoryHandle,
- DIRECTORY_ALL_ACCESS,
- &ObjectAttributes,
- &IoStatusBlock,
- NULL,
- FILE_ATTRIBUTE_DIRECTORY,
- 0,
- FILE_CREATE,
- FILE_DIRECTORY_FILE,
- NULL,
- 0);
- if (!NT_SUCCESS(Status))
+ /* Create the install directory */
+ Status = CreateDirectory(PathBuffer);
+ if (!NT_SUCCESS(Status) && Status != STATUS_OBJECT_NAME_COLLISION)
+ {
+ DPRINT("Creating directory '%S' failed: Status = 0x%08lx", PathBuffer, Status);
+
+ PopupError("Setup could not create the install directory.",
+ "ENTER = Reboot computer");
+
+ while(TRUE)
{
- PrintTextXY(6, 25, "Creating directory failed: Status = 0x%08lx", Status);
+ ConInKey(Ir);
+ if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
+ {
+ return(QUIT_PAGE);
+ }
}
- else
+ }
+
+
+ /* Enumerate the directory values and create the subdirectories */
+ Iterator = IniCacheFindFirstValue(DirSection,
+ &KeyName,
+ &KeyValue);
+ if (Iterator != NULL)
+ {
+ do
{
- PrintTextXY(6, 25, "Created directory.");
- NtClose (DirectoryHandle);
- }
+ if (KeyValue[0] == L'\\' && KeyValue[1] != 0)
+ {
+ DPRINT("Absolute Path: '%S'\n", KeyValue);
+ wcscpy(PathBuffer, DestinationRootPath.Buffer);
+ wcscat(PathBuffer, KeyValue);
- RtlFreeUnicodeString(&PathName);
+ DPRINT("FullPath: '%S'\n", PathBuffer);
+ }
+ else if (KeyValue[0] != L'\\')
+ {
+ DPRINT("RelativePath: '%S'\n", KeyValue);
+ wcscpy(PathBuffer, DestinationPath.Buffer);
+ wcscat(PathBuffer, L"\\");
+ wcscat(PathBuffer, KeyValue);
+ DPRINT("FullPath: '%S'\n", PathBuffer);
- /* create the subdirectories */
+ Status = CreateDirectory(PathBuffer);
+ if (!NT_SUCCESS(Status) && Status != STATUS_OBJECT_NAME_COLLISION)
+ {
+ DPRINT("Creating directory '%S' failed: Status = 0x%08lx", PathBuffer, Status);
- /* append backslash and init end pointer */
- strcat(PathBuffer, "\\");
- Length = strlen(PathBuffer);
- End = &PathBuffer[Length];
+ PopupError("Setup could not create install directories.",
+ "ENTER = Reboot computer");
- for (i = 0; Dirs[i] != NULL; i++)
- {
- strcpy(End, Dirs[i]);
-
-
- RtlCreateUnicodeStringFromAsciiz(&PathName,
- PathBuffer);
-
-
- ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
- ObjectAttributes.RootDirectory = NULL;
- ObjectAttributes.ObjectName = &PathName;
- ObjectAttributes.Attributes = OBJ_CASE_INSENSITIVE | OBJ_INHERIT;
- ObjectAttributes.SecurityDescriptor = NULL;
- ObjectAttributes.SecurityQualityOfService = NULL;
-
- Status = NtCreateFile(&DirectoryHandle,
- DIRECTORY_ALL_ACCESS,
- &ObjectAttributes,
- &IoStatusBlock,
- NULL,
- FILE_ATTRIBUTE_DIRECTORY,
- 0,
- FILE_CREATE,
- FILE_DIRECTORY_FILE,
- NULL,
- 0);
- if (!NT_SUCCESS(Status))
- {
- PrintTextXY(6, 25, "Creating directory failed: Status = 0x%08lx", Status);
- }
- else
- {
- PrintTextXY(6, 25, "Created directory.");
- NtClose (DirectoryHandle);
- }
+ while(TRUE)
+ {
+ ConInKey(Ir);
- RtlFreeUnicodeString(&PathName);
+ if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
+ {
+ IniCacheFindClose(Iterator);
+ return(QUIT_PAGE);
+ }
+ }
+ }
+ }
}
+ while (IniCacheFindNextValue(Iterator, &KeyName, &KeyValue));
+ IniCacheFindClose(Iterator);
+ }
+
+
+ return(FILE_COPY_PAGE);
+#if 0
SetTextXY(8, 14, "Create directories");
SetHighlightedTextXY(50, 14, "Done");
}
return(PREPARE_COPY_PAGE);
+#endif
+}
+
+
+static ULONG
+FileCopyCallback(PVOID Context,
+ ULONG Notification,
+ PVOID Param1,
+ PVOID Param2)
+{
+ PCOPYCONTEXT CopyContext;
+
+ CopyContext = (PCOPYCONTEXT)Context;
+
+ switch (Notification)
+ {
+ case SPFILENOTIFY_STARTSUBQUEUE:
+ CopyContext->TotalOperations = (ULONG)Param2;
+ ProgressSetStepCount(CopyContext->ProgressBar,
+ CopyContext->TotalOperations);
+ break;
+
+ case SPFILENOTIFY_STARTCOPY:
+ /* Display copy message */
+ PrintTextXYN(6, 16, 60, "Copying file: %S", (PWSTR)Param1);
+
+ PrintTextXYN(6, 18, 60, "File %lu of %lu",
+ CopyContext->CompletedOperations + 1,
+ CopyContext->TotalOperations);
+ break;
+
+
+ case SPFILENOTIFY_ENDCOPY:
+ CopyContext->CompletedOperations++;
+ ProgressNextStep(CopyContext->ProgressBar);
+ break;
+ }
+
+ return(0);
}
static ULONG
FileCopyPage(PINPUT_RECORD Ir)
{
+ COPYCONTEXT CopyContext;
+ SHORT xScreen;
+ SHORT yScreen;
+
+ SetStatusText(" Please wait...");
SetTextXY(6, 8, "Copying files");
+ GetScreenSize(&xScreen, &yScreen);
+
+ CopyContext.TotalOperations = 0;
+ CopyContext.CompletedOperations = 0;
+ CopyContext.ProgressBar = CreateProgressBar(6,
+ yScreen - 14,
+ xScreen - 7,
+ yScreen - 10);
+
+ SetupCommitFileQueue(SetupFileQueue,
+ DestinationRootPath.Buffer,
+ InstallPath.Buffer,
+ (PSP_FILE_CALLBACK)FileCopyCallback,
+ &CopyContext);
+
+ SetupCloseFileQueue(SetupFileQueue);
+
+ DestroyProgressBar(CopyContext.ProgressBar);
+ return(REGISTRY_PAGE);
+
+#if 0
SetStatusText(" ENTER = Continue F3 = Quit");
while(TRUE)
}
else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
{
- return(INIT_SYSTEM_PAGE);
+ return(REGISTRY_PAGE);
}
}
return(FILE_COPY_PAGE);
+#endif
}
-#if 0
-static NTSTATUS
-UpdateSystemRootLink(VOID)
+
+static ULONG
+RegistryPage(PINPUT_RECORD Ir)
{
OBJECT_ATTRIBUTES ObjectAttributes;
- UNICODE_STRING LinkName;
- UNICODE_STRING TargetName;
- CHAR TargetBuffer[MAX_PATH];
- HANDLE Handle;
+ UNICODE_STRING KeyName;
+ UNICODE_STRING ValueName;
+ HANDLE KeyHandle;
NTSTATUS Status;
- RtlInitUnicodeString(&LinkName,
- L"\\SystemRoot");
+ SetTextXY(6, 8, "Setup initializes system settings");
+
+
+// SetTextXY(6, 12, "Create registry hives");
+
+// SetTextXY(6, 14, "Update registry hives");
+
+// SetStatusText(" Please wait...");
+
+ SetStatusText(" Creating registry hives...");
+
+ /* Create the 'secret' InstallPath key */
+ RtlInitUnicodeStringFromLiteral(&KeyName,
+ L"\\Registry\\Machine\\HARDWARE");
InitializeObjectAttributes(&ObjectAttributes,
- &LinkName,
- OBJ_OPENLINK,
+ &KeyName,
+ OBJ_CASE_INSENSITIVE,
NULL,
NULL);
+ Status = NtOpenKey(&KeyHandle,
+ KEY_ALL_ACCESS,
+ &ObjectAttributes);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("NtOpenKey() failed (Status %lx)\n", Status);
+ PopupError("Setup failed to open the HARDWARE registry key.",
+ "ENTER = Reboot computer");
- Status = NtOpenSymbolicLinkObject(&Handle,
- SYMBOLIC_LINK_ALL_ACCESS,
- &ObjectAttributes);
+ while(TRUE)
+ {
+ ConInKey(Ir);
+
+ if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
+ {
+ return(QUIT_PAGE);
+ }
+ }
+ }
+
+ RtlInitUnicodeStringFromLiteral(&ValueName,
+ L"InstallPath");
+
+ Status = NtSetValueKey(KeyHandle,
+ &ValueName,
+ 0,
+ REG_SZ,
+ (PVOID)DestinationPath.Buffer,
+ DestinationPath.Length);
+ NtClose(KeyHandle);
if (!NT_SUCCESS(Status))
- return(Status);
+ {
+ DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status);
+ PopupError("Setup failed to set the \'InstallPath\' registry value.",
+ "ENTER = Reboot computer");
- Status = NtMakeTemporaryObject(Handle);
- NtClose(Handle);
+ while(TRUE)
+ {
+ ConInKey(Ir);
+
+ if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
+ {
+ return(QUIT_PAGE);
+ }
+ }
+ }
+
+ /* Create the standard hives */
+ Status = NtInitializeRegistry(TRUE);
if (!NT_SUCCESS(Status))
- return(Status);
+ {
+ DPRINT1("NtInitializeRegistry() failed (Status %lx)\n", Status);
+ PopupError("Setup failed to initialize the registry.",
+ "ENTER = Reboot computer");
- sprintf(TargetBuffer,
- "\\Device\\Harddisk%lu\\Partition%lu",
- PartData.DiskNumber,
- PartData.PartNumber);
- if (InstallDir[0] != '\\')
- strcat(TargetBuffer, "\\");
- strcat(TargetBuffer, InstallDir);
+ while(TRUE)
+ {
+ ConInKey(Ir);
- RtlCreateUnicodeStringFromAsciiz(&TargetName,
- TargetBuffer);
+ if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
+ {
+ return(QUIT_PAGE);
+ }
+ }
+ }
- Status = NtCreateSymbolicLinkObject(&Handle,
- SYMBOLIC_LINK_ALL_ACCESS,
- &ObjectAttributes,
- &TargetName);
- RtlFreeUnicodeString(&TargetName);
+ /* Update registry */
+ SetStatusText(" Updating registry hives...");
- if (!NT_SUCCESS(Status))
- return(Status);
+ /* FIXME: Create key '\Registry\Machine\System\Setup' */
- NtClose(Handle);
+ /* FIXME: Create value 'SystemSetupInProgress' */
- return(STATUS_SUCCESS);
-}
+
+ return(BOOT_LOADER_PAGE);
+
+#if 0
+ SetStatusText(" ENTER = Continue F3 = Quit");
+
+ while(TRUE)
+ {
+ ConInKey(Ir);
+
+ if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) &&
+ (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */
+ {
+ if (ConfirmQuit(Ir) == TRUE)
+ return(QUIT_PAGE);
+ break;
+ }
+ else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
+ {
+ return(BOOT_LOADER_PAGE);
+ }
+ }
+
+ return(REGISTRY_PAGE);
#endif
+}
static ULONG
-InitSystemPage(PINPUT_RECORD Ir)
+BootLoaderPage(PINPUT_RECORD Ir)
{
-#if 0
+ WCHAR SrcPath[MAX_PATH];
+ WCHAR DstPath[MAX_PATH];
+ PINICACHE IniCache;
+ PINICACHESECTION IniSection;
NTSTATUS Status;
-#endif
- SetTextXY(6, 8, "Initializing system settings");
+ SetTextXY(6, 8, "Installing the boot loader");
+ SetStatusText(" Please wait...");
- SetTextXY(6, 12, "Create registry hives");
+ if (ActivePartitionValid == FALSE)
+ {
+ DPRINT1("Error: no active partition found\n");
+ PopupError("Setup could not find an active partiton\n",
+ "ENTER = Reboot computer");
- SetTextXY(6, 14, "Update registry hives");
+ while(TRUE)
+ {
+ ConInKey(Ir);
- SetTextXY(6, 16, "Install/update boot manager");
+ if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
+ {
+ return(QUIT_PAGE);
+ }
+ }
+ }
- SetStatusText(" Please wait...");
+ if (ActivePartition.PartType == PARTITION_ENTRY_UNUSED)
+ {
+ DPRINT1("Error: active partition invalid (unused)\n");
+ PopupError("The active partition is unused (invalid).\n",
+ "ENTER = Reboot computer");
-#if 0
- /*
- * Initialize registry
- */
+ while(TRUE)
+ {
+ ConInKey(Ir);
- /* Update 'SystemRoot' link */
- Status = UpdateSystemRootLink();
- if (!NT_SUCCESS(Status))
+ if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
+ {
+ return(QUIT_PAGE);
+ }
+ }
+ }
+
+ if (ActivePartition.PartType == 0x0A)
+ {
+ /* OS/2 boot manager partition */
+ DPRINT1("Found OS/2 boot manager partition\n");
+ PopupError("Setup found an OS/2 boot manager partiton.\n"
+ "The OS/2 boot manager is not supported yet!",
+ "ENTER = Reboot computer");
+
+ while(TRUE)
{
+ ConInKey(Ir);
- PrintTextXY(6, 25, "UpdateSystemRootLink() failed (Status = 0x%08lx)", Status);
+ if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
+ {
+ return(QUIT_PAGE);
+ }
}
+ }
+ else if (ActivePartition.PartType == 0x83)
+ {
+ /* Linux ext2 partition */
+ DPRINT1("Found Linux ext2 partition\n");
+ PopupError("Setup found a Linux ext2 partiton.\n"
+ "Linux ext2 partitions are not supported yet!",
+ "ENTER = Reboot computer");
+
+ while(TRUE)
+ {
+ ConInKey(Ir);
+ if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
+ {
+ return(QUIT_PAGE);
+ }
+ }
+ }
+ else if (ActivePartition.PartType == PARTITION_IFS)
+ {
+ /* NTFS partition */
+ DPRINT1("Found NTFS partition\n");
+ PopupError("Setup found an NTFS partiton.\n"
+ "NTFS partitions are not supported yet!",
+ "ENTER = Reboot computer");
+
+ while(TRUE)
+ {
+ ConInKey(Ir);
- Status = NtInitializeRegistry(TRUE);
- if (!NT_SUCCESS(Status))
+ if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
+ {
+ return(QUIT_PAGE);
+ }
+ }
+ }
+ else if ((ActivePartition.PartType == PARTITION_FAT_12) ||
+ (ActivePartition.PartType == PARTITION_FAT_16) ||
+ (ActivePartition.PartType == PARTITION_HUGE) ||
+ (ActivePartition.PartType == PARTITION_XINT13) ||
+ (ActivePartition.PartType == PARTITION_FAT32) ||
+ (ActivePartition.PartType == PARTITION_FAT32_XINT13))
+ {
+ /* FAT or FAT32 partition */
+ DPRINT1("System path: '%wZ'\n", &SystemRootPath);
+
+ if (DoesFileExist(SystemRootPath.Buffer, L"ntldr") == TRUE ||
+ DoesFileExist(SystemRootPath.Buffer, L"boot.ini") == TRUE)
{
+ /* Search root directory for 'ntldr' and 'boot.ini'. */
+ DPRINT1("Found Microsoft Windows NT/2000/XP boot loader\n");
+
+ /* Copy FreeLoader to the boot partition */
+ wcscpy(SrcPath, SourceRootPath.Buffer);
+ wcscat(SrcPath, L"\\loader\\freeldr.sys");
+ wcscpy(DstPath, SystemRootPath.Buffer);
+ wcscat(DstPath, L"\\freeldr.sys");
+
+ DPRINT1("Copy: %S ==> %S\n", SrcPath, DstPath);
+ Status = SetupCopyFile(SrcPath, DstPath);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status);
+ PopupError("Setup failed to copy 'freeldr.sys'.",
+ "ENTER = Reboot computer");
+
+ while(TRUE)
+ {
+ ConInKey(Ir);
+
+ if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
+ {
+ return(QUIT_PAGE);
+ }
+ }
+ }
+
+ /* Create or update freeldr.ini */
+ if (DoesFileExist(SystemRootPath.Buffer, L"freeldr.ini") == FALSE)
+ {
+ /* Create new 'freeldr.ini' */
+ DPRINT1("Create new 'freeldr.ini'\n");
+ wcscpy(DstPath, SystemRootPath.Buffer);
+ wcscat(DstPath, L"\\freeldr.ini");
+
+ Status = CreateFreeLoaderIniForReactos(DstPath,
+ DestinationArcPath.Buffer);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("CreateFreeLoaderIniForReactos() failed (Status %lx)\n", Status);
+ PopupError("Setup failed to create 'freeldr.ini'.",
+ "ENTER = Reboot computer");
+
+ while(TRUE)
+ {
+ ConInKey(Ir);
+
+ if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
+ {
+ return(QUIT_PAGE);
+ }
+ }
+ }
+
+ /* Install new bootcode */
+ if ((ActivePartition.PartType == PARTITION_FAT32) ||
+ (ActivePartition.PartType == PARTITION_FAT32_XINT13))
+ {
+ /* Install FAT32 bootcode */
+ wcscpy(SrcPath, SourceRootPath.Buffer);
+ wcscat(SrcPath, L"\\loader\\fat32.bin");
+ wcscpy(DstPath, SystemRootPath.Buffer);
+ wcscat(DstPath, L"\\bootsect.ros");
+
+ DPRINT1("Install FAT32 bootcode: %S ==> %S\n", SrcPath, DstPath);
+ Status = InstallFat32BootCodeToFile(SrcPath,
+ DstPath,
+ SystemRootPath.Buffer);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("InstallFat32BootCodeToFile() failed (Status %lx)\n", Status);
+ PopupError("Setup failed to install the FAT32 bootcode.",
+ "ENTER = Reboot computer");
+
+ while(TRUE)
+ {
+ ConInKey(Ir);
- PrintTextXY(6, 26, "NtInitializeRegistry() failed (Status = 0x%08lx)", Status);
+ if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
+ {
+ return(QUIT_PAGE);
+ }
+ }
+ }
+ }
+ else
+ {
+ /* Install FAT16 bootcode */
+ wcscpy(SrcPath, SourceRootPath.Buffer);
+ wcscat(SrcPath, L"\\loader\\fat.bin");
+ wcscpy(DstPath, SystemRootPath.Buffer);
+ wcscat(DstPath, L"\\bootsect.ros");
+
+ DPRINT1("Install FAT bootcode: %S ==> %S\n", SrcPath, DstPath);
+ Status = InstallFat16BootCodeToFile(SrcPath,
+ DstPath,
+ SystemRootPath.Buffer);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("InstallFat16BootCodeToFile() failed (Status %lx)\n", Status);
+ PopupError("Setup failed to install the FAT bootcode.",
+ "ENTER = Reboot computer");
+
+ while(TRUE)
+ {
+ ConInKey(Ir);
+
+ if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
+ {
+ return(QUIT_PAGE);
+ }
+ }
+ }
+ }
+
+ /* Update 'boot.ini' */
+ wcscpy(DstPath, SystemRootPath.Buffer);
+ wcscat(DstPath, L"\\boot.ini");
+
+ DPRINT1("Update 'boot.ini': %S\n", DstPath);
+ Status = UpdateBootIni(DstPath,
+ L"C:\\bootsect.ros",
+ L"\"ReactOS\"");
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("UpdateBootIni() failed (Status %lx)\n", Status);
+ PopupError("Setup failed to update \'boot.ini\'.",
+ "ENTER = Reboot computer");
+
+ while(TRUE)
+ {
+ ConInKey(Ir);
+
+ if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
+ {
+ return(QUIT_PAGE);
+ }
+ }
+ }
+ }
+ else
+ {
+ /* Update existing 'freeldr.ini' */
+ DPRINT1("Update existing 'freeldr.ini'\n");
+ wcscpy(DstPath, SystemRootPath.Buffer);
+ wcscat(DstPath, L"\\freeldr.ini");
+
+ Status = UpdateFreeLoaderIni(DstPath,
+ DestinationArcPath.Buffer);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status);
+ PopupError("Setup failed to update 'freeldr.ini'.",
+ "ENTER = Reboot computer");
+
+ while(TRUE)
+ {
+ ConInKey(Ir);
+
+ if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
+ {
+ return(QUIT_PAGE);
+ }
+ }
+ }
+ }
}
-#endif
+ else if (DoesFileExist(SystemRootPath.Buffer, L"io.sys") == TRUE ||
+ DoesFileExist(SystemRootPath.Buffer, L"msdos.sys") == TRUE)
+ {
+ /* Search for root directory for 'io.sys' and 'msdos.sys'. */
+ DPRINT1("Found Microsoft DOS or Windows 9x boot loader\n");
- /*
- * Update registry
- */
+ /* Copy FreeLoader to the boot partition */
+ wcscpy(SrcPath, SourceRootPath.Buffer);
+ wcscat(SrcPath, L"\\loader\\freeldr.sys");
+ wcscpy(DstPath, SystemRootPath.Buffer);
+ wcscat(DstPath, L"\\freeldr.sys");
- /* FIXME: Create key '\Registry\Machine\System\Setup' */
+ DPRINT("Copy: %S ==> %S\n", SrcPath, DstPath);
+ Status = SetupCopyFile(SrcPath, DstPath);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status);
+ PopupError("Setup failed to copy 'freeldr.sys'.",
+ "ENTER = Reboot computer");
- /* FIXME: Create value 'SystemSetupInProgress' */
+ while(TRUE)
+ {
+ ConInKey(Ir);
+
+ if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
+ {
+ return(QUIT_PAGE);
+ }
+ }
+ }
+
+ /* Create or update 'freeldr.ini' */
+ if (DoesFileExist(SystemRootPath.Buffer, L"freeldr.ini") == FALSE)
+ {
+ /* Create new 'freeldr.ini' */
+ DPRINT1("Create new 'freeldr.ini'\n");
+ wcscpy(DstPath, SystemRootPath.Buffer);
+ wcscat(DstPath, L"\\freeldr.ini");
+
+ Status = CreateFreeLoaderIniForDos(DstPath,
+ DestinationArcPath.Buffer);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("CreateFreeLoaderIniForDos() failed (Status %lx)\n", Status);
+ PopupError("Setup failed to create 'freeldr.ini'.",
+ "ENTER = Reboot computer");
+
+ while(TRUE)
+ {
+ ConInKey(Ir);
+
+ if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
+ {
+ return(QUIT_PAGE);
+ }
+ }
+ }
+
+ /* Save current bootsector as 'BOOTSECT.DOS' */
+ wcscpy(SrcPath, SystemRootPath.Buffer);
+ wcscpy(DstPath, SystemRootPath.Buffer);
+ wcscat(DstPath, L"\\bootsect.dos");
+
+ DPRINT1("Save bootsector: %S ==> %S\n", SrcPath, DstPath);
+ Status = SaveCurrentBootSector(SrcPath,
+ DstPath);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("SaveCurrentBootSector() failed (Status %lx)\n", Status);
+ PopupError("Setup failed to save the current bootsector.",
+ "ENTER = Reboot computer");
+
+ while(TRUE)
+ {
+ ConInKey(Ir);
+
+ if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
+ {
+ return(QUIT_PAGE);
+ }
+ }
+ }
+
+ /* Install new bootsector */
+ if ((ActivePartition.PartType == PARTITION_FAT32) ||
+ (ActivePartition.PartType == PARTITION_FAT32_XINT13))
+ {
+ wcscpy(SrcPath, SourceRootPath.Buffer);
+ wcscat(SrcPath, L"\\loader\\fat32.bin");
+
+ DPRINT1("Install FAT32 bootcode: %S ==> %S\n", SrcPath, SystemRootPath.Buffer);
+ Status = InstallFat32BootCodeToDisk(SrcPath,
+ SystemRootPath.Buffer);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("InstallFat32BootCodeToDisk() failed (Status %lx)\n", Status);
+ PopupError("Setup failed to install the FAT32 bootcode.",
+ "ENTER = Reboot computer");
+
+ while(TRUE)
+ {
+ ConInKey(Ir);
+
+ if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
+ {
+ return(QUIT_PAGE);
+ }
+ }
+ }
+ }
+ else
+ {
+ wcscpy(SrcPath, SourceRootPath.Buffer);
+ wcscat(SrcPath, L"\\loader\\fat.bin");
+
+ DPRINT1("Install FAT bootcode: %S ==> %S\n", SrcPath, SystemRootPath.Buffer);
+ Status = InstallFat16BootCodeToDisk(SrcPath,
+ SystemRootPath.Buffer);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("InstallFat16BootCodeToDisk() failed (Status %lx)\n", Status);
+ PopupError("Setup failed to install the FAT bootcode.",
+ "ENTER = Reboot computer");
+
+ while(TRUE)
+ {
+ ConInKey(Ir);
+
+ if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
+ {
+ return(QUIT_PAGE);
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ /* Update existing 'freeldr.ini' */
+ wcscpy(DstPath, SystemRootPath.Buffer);
+ wcscat(DstPath, L"\\freeldr.ini");
+
+ Status = UpdateFreeLoaderIni(DstPath,
+ DestinationArcPath.Buffer);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status);
+ PopupError("Setup failed to update 'freeldr.ini'.",
+ "ENTER = Reboot computer");
+
+ while(TRUE)
+ {
+ ConInKey(Ir);
+
+ if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
+ {
+ return(QUIT_PAGE);
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ /* No or unknown boot loader */
+ DPRINT1("No or unknown boot loader found\n");
+
+ /* Copy FreeLoader to the boot partition */
+ wcscpy(SrcPath, SourceRootPath.Buffer);
+ wcscat(SrcPath, L"\\loader\\freeldr.sys");
+ wcscpy(DstPath, SystemRootPath.Buffer);
+ wcscat(DstPath, L"\\freeldr.sys");
+
+ DPRINT1("Copy: %S ==> %S\n", SrcPath, DstPath);
+ Status = SetupCopyFile(SrcPath, DstPath);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status);
+ PopupError("Setup failed to copy 'freeldr.sys'.",
+ "ENTER = Reboot computer");
+
+ while(TRUE)
+ {
+ ConInKey(Ir);
+
+ if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
+ {
+ return(QUIT_PAGE);
+ }
+ }
+ }
+
+ /* Create or update 'freeldr.ini' */
+ if (DoesFileExist(SystemRootPath.Buffer, L"freeldr.ini") == FALSE)
+ {
+ /* Create new freeldr.ini */
+ wcscpy(DstPath, SystemRootPath.Buffer);
+ wcscat(DstPath, L"\\freeldr.ini");
+
+ DPRINT1("Copy: %S ==> %S\n", SrcPath, DstPath);
+ Status = CreateFreeLoaderIniForReactos(DstPath,
+ DestinationArcPath.Buffer);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("CreateFreeLoaderIniForReactos() failed (Status %lx)\n", Status);
+ PopupError("Setup failed to create \'freeldr.ini\'.",
+ "ENTER = Reboot computer");
+
+ while(TRUE)
+ {
+ ConInKey(Ir);
+
+ if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
+ {
+ return(QUIT_PAGE);
+ }
+ }
+ }
+
+ /* Save current bootsector as 'BOOTSECT.OLD' */
+ wcscpy(SrcPath, SystemRootPath.Buffer);
+ wcscpy(DstPath, SystemRootPath.Buffer);
+ wcscat(DstPath, L"\\bootsect.old");
+
+ DPRINT1("Save bootsector: %S ==> %S\n", SrcPath, DstPath);
+ Status = SaveCurrentBootSector(SrcPath,
+ DstPath);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("SaveCurrentBootSector() failed (Status %lx)\n", Status);
+ PopupError("Setup failed save the current bootsector.",
+ "ENTER = Reboot computer");
+
+ while(TRUE)
+ {
+ ConInKey(Ir);
+
+ if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
+ {
+ return(QUIT_PAGE);
+ }
+ }
+ }
+
+ /* Install new bootsector */
+ if ((ActivePartition.PartType == PARTITION_FAT32) ||
+ (ActivePartition.PartType == PARTITION_FAT32_XINT13))
+ {
+ wcscpy(SrcPath, SourceRootPath.Buffer);
+ wcscat(SrcPath, L"\\loader\\fat32.bin");
+
+ DPRINT1("Install FAT32 bootcode: %S ==> %S\n", SrcPath, SystemRootPath.Buffer);
+ Status = InstallFat32BootCodeToDisk(SrcPath,
+ SystemRootPath.Buffer);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("InstallFat32BootCodeToDisk() failed (Status %lx)\n", Status);
+ PopupError("Setup failed to install the FAT32 bootcode.",
+ "ENTER = Reboot computer");
+
+ while(TRUE)
+ {
+ ConInKey(Ir);
+
+ if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
+ {
+ return(QUIT_PAGE);
+ }
+ }
+ }
+ }
+ else
+ {
+ wcscpy(SrcPath, SourceRootPath.Buffer);
+ wcscat(SrcPath, L"\\loader\\fat.bin");
+
+ DPRINT1("Install FAT bootcode: %S ==> %S\n", SrcPath, SystemRootPath.Buffer);
+ Status = InstallFat16BootCodeToDisk(SrcPath,
+ SystemRootPath.Buffer);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("InstallFat16BootCodeToDisk() failed (Status %lx)\n", Status);
+ PopupError("Setup failed to install the FAT bootcode.",
+ "ENTER = Reboot computer");
+
+ while(TRUE)
+ {
+ ConInKey(Ir);
+ if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
+ {
+ return(QUIT_PAGE);
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ /* Update existing 'freeldr.ini' */
+ wcscpy(DstPath, SystemRootPath.Buffer);
+ wcscat(DstPath, L"\\freeldr.ini");
+
+ Status = UpdateFreeLoaderIni(DstPath,
+ DestinationArcPath.Buffer);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status);
+ PopupError("Setup failed to update 'freeldr.ini'.",
+ "ENTER = Reboot computer");
+
+ while(TRUE)
+ {
+ ConInKey(Ir);
+
+ if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
+ {
+ return(QUIT_PAGE);
+ }
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ /* Unknown partition */
+ DPRINT1("Unknown partition found\n");
+ PopupError("Setup found an unknown partiton type.\n"
+ "This partition type is not supported!",
+ "ENTER = Reboot computer");
+
+ while(TRUE)
+ {
+ ConInKey(Ir);
+
+ if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
+ {
+ return(QUIT_PAGE);
+ }
+ }
+ }
+ return(SUCCESS_PAGE);
+#if 0
SetStatusText(" ENTER = Continue F3 = Quit");
while(TRUE)
}
}
- return(INIT_SYSTEM_PAGE);
+ return(BOOT_LOADER_PAGE);
+#endif
}
+
static ULONG
QuitPage(PINPUT_RECORD Ir)
{
SetTextXY(10, 6, "ReactOS is not completely installed");
SetTextXY(10, 8, "Remove floppy disk from Drive A: and");
- SetTextXY(10, 9, "all CD-ROMs from CD-Drive.");
+ SetTextXY(10, 9, "all CD-ROMs from CD-Drives.");
SetTextXY(10, 11, "Press ENTER to reboot your computer.");
0,0,0,0,0);
}
+ PartDataValid = FALSE;
+
+ /* Initialize global unicode strings */
+ RtlInitUnicodeString(&SourcePath, NULL);
+ RtlInitUnicodeString(&SourceRootPath, NULL);
+ RtlInitUnicodeString(&InstallPath, NULL);
+ RtlInitUnicodeString(&DestinationPath, NULL);
+ RtlInitUnicodeString(&DestinationArcPath, NULL);
+ RtlInitUnicodeString(&DestinationRootPath, NULL);
+ RtlInitUnicodeString(&SystemRootPath, NULL);
+
+
Page = START_PAGE;
while (Page != REBOOT_PAGE)
{
ClearScreen();
- SetUnderlinedTextXY(4, 3, " ReactOS 0.0.20 Setup ");
+ SetUnderlinedTextXY(4, 3, " ReactOS " KERNEL_VERSION_STR " Setup ");
switch (Page)
{
Page = FileCopyPage(&Ir);
break;
- case INIT_SYSTEM_PAGE:
- Page = InitSystemPage(&Ir);
+ case REGISTRY_PAGE:
+ Page = RegistryPage(&Ir);
+ break;
+
+ case BOOT_LOADER_PAGE:
+ Page = BootLoaderPage(&Ir);
break;