#include "chkdsk.h"
#include "cmdcons.h"
#include "format.h"
-#include "drivesup.h"
#include "settings.h"
#define NDEBUG
/* GLOBALS ******************************************************************/
HANDLE ProcessHeap;
+
static UNICODE_STRING SourceRootPath;
static UNICODE_STRING SourceRootDir;
-/* static */ UNICODE_STRING SourcePath;
+static UNICODE_STRING SourcePath;
+
BOOLEAN IsUnattendedSetup = FALSE;
LONG UnattendDestinationDiskNumber;
LONG UnattendDestinationPartitionNumber;
WCHAR LocaleID[9];
WCHAR DefaultLanguage[20];
WCHAR DefaultKBLayout[20];
-BOOLEAN RepairUpdateFlag = FALSE;
-HANDLE hPnpThread = INVALID_HANDLE_VALUE;
+static BOOLEAN RepairUpdateFlag = FALSE;
+static HANDLE hPnpThread = INVALID_HANDLE_VALUE;
-PPARTLIST PartitionList = NULL;
-PPARTENTRY TempPartition = NULL;
-FORMATMACHINESTATE FormatState = Start;
+static PPARTLIST PartitionList = NULL;
+static PPARTENTRY TempPartition = NULL;
+static FORMATMACHINESTATE FormatState = Start;
/* LOCALS *******************************************************************/
static PFILE_SYSTEM_LIST FileSystemList = NULL;
+/*
+ * NOTE: Technically only used for the COPYCONTEXT InstallPath member
+ * for the filequeue functionality.
+ */
static UNICODE_STRING InstallPath;
/*
*/
static UNICODE_STRING SystemRootPath;
-/* Path to the install directory inside the ReactOS boot partition */
+/* Path to the installation directory inside the ReactOS boot partition */
static UNICODE_STRING DestinationPath;
static UNICODE_STRING DestinationArcPath;
static UNICODE_STRING DestinationRootPath;
-static WCHAR DestinationDriveLetter; // FIXME: Is it really useful??
+// FIXME: Is it really useful?? Just used for SetDefaultPagefile...
+static WCHAR DestinationDriveLetter;
static HINF SetupInf;
static HSPFILEQ SetupFileQueue = NULL;
+static PNTOS_INSTALLATION CurrentInstallation = NULL;
+static PGENERIC_LIST NtOsInstallsList = NULL;
+
static PGENERIC_LIST ComputerList = NULL;
static PGENERIC_LIST DisplayList = NULL;
static PGENERIC_LIST KeyboardList = NULL;
}
/* Load 'unattend.inf' from install media. */
- UnattendInf = SetupOpenInfFileW(UnattendInfPath,
- NULL,
- INF_STYLE_WIN4,
- LanguageId,
- &ErrorLine);
+ UnattendInf = SetupOpenInfFileExW(UnattendInfPath,
+ NULL,
+ INF_STYLE_WIN4,
+ LanguageId,
+ &ErrorLine);
if (UnattendInf == INVALID_HANDLE_VALUE)
{
- DPRINT("SetupOpenInfFileW() failed\n");
+ DPRINT("SetupOpenInfFileExW() failed\n");
return;
}
wcscpy(UnattendInstallationDirectory, Value);
IsUnattendedSetup = TRUE;
+ DPRINT("Running unattended setup\n");
/* Search for 'MBRInstallType' in the 'Unattend' section */
if (SetupFindFirstLineW(UnattendInf, L"Unattend", L"MBRInstallType", &Context))
}
SetupCloseInfFile(UnattendInf);
-
- DPRINT("Running unattended setup\n");
}
}
+static NTSTATUS
+GetSourcePaths(
+ OUT PUNICODE_STRING SourcePath,
+ OUT PUNICODE_STRING SourceRootPath,
+ OUT PUNICODE_STRING SourceRootDir)
+{
+ NTSTATUS Status;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ UNICODE_STRING LinkName = RTL_CONSTANT_STRING(L"\\SystemRoot");
+ UNICODE_STRING SourceName;
+ WCHAR SourceBuffer[MAX_PATH] = L"";
+ HANDLE Handle;
+ ULONG Length;
+ PWCHAR Ptr;
+
+ InitializeObjectAttributes(&ObjectAttributes,
+ &LinkName,
+ OBJ_CASE_INSENSITIVE,
+ NULL,
+ NULL);
+
+ Status = NtOpenSymbolicLinkObject(&Handle,
+ SYMBOLIC_LINK_ALL_ACCESS,
+ &ObjectAttributes);
+ if (!NT_SUCCESS(Status))
+ return Status;
+
+ RtlInitEmptyUnicodeString(&SourceName, SourceBuffer, sizeof(SourceBuffer));
+
+ Status = NtQuerySymbolicLinkObject(Handle,
+ &SourceName,
+ &Length);
+ NtClose(Handle);
+
+ if (!NT_SUCCESS(Status))
+ return Status;
+
+ RtlCreateUnicodeString(SourcePath,
+ SourceName.Buffer);
+
+ /* Strip trailing directory */
+ Ptr = wcsrchr(SourceName.Buffer, OBJ_NAME_PATH_SEPARATOR);
+ if (Ptr)
+ {
+ RtlCreateUnicodeString(SourceRootDir, Ptr);
+ *Ptr = UNICODE_NULL;
+ }
+ else
+ {
+ RtlCreateUnicodeString(SourceRootDir, L"");
+ }
+
+ RtlCreateUnicodeString(SourceRootPath,
+ SourceName.Buffer);
+
+ return STATUS_SUCCESS;
+}
+
+
/*
* Start page
*
MUIDisplayError(ERROR_NO_SOURCE_DRIVE, Ir, POPUP_WAIT_ENTER);
return QUIT_PAGE;
}
- DPRINT1("SourcePath: '%wZ'", &SourcePath);
- DPRINT1("SourceRootPath: '%wZ'", &SourceRootPath);
- DPRINT1("SourceRootDir: '%wZ'", &SourceRootDir);
+ DPRINT1("SourcePath: '%wZ'\n", &SourcePath);
+ DPRINT1("SourceRootPath: '%wZ'\n", &SourceRootPath);
+ DPRINT1("SourceRootDir: '%wZ'\n", &SourceRootDir);
/* Load txtsetup.sif from install media. */
CombinePaths(FileNameBuffer, ARRAYSIZE(FileNameBuffer), 2, SourcePath.Buffer, L"txtsetup.sif");
- SetupInf = SetupOpenInfFileW(FileNameBuffer,
- NULL,
- INF_STYLE_WIN4,
- LanguageId,
- &ErrorLine);
+ SetupInf = SetupOpenInfFileExW(FileNameBuffer,
+ NULL,
+ INF_STYLE_WIN4,
+ LanguageId,
+ &ErrorLine);
if (SetupInf == INVALID_HANDLE_VALUE)
{
* Next pages:
* InstallIntroPage (default)
* RepairIntroPage
+ * RecoveryPage
* LicensePage
* QuitPage
*
}
else if (toupper(Ir->Event.KeyEvent.uChar.AsciiChar) == 'R') /* R */
{
- return REPAIR_INTRO_PAGE;
+ return RECOVERY_PAGE; // REPAIR_INTRO_PAGE;
}
else if (toupper(Ir->Event.KeyEvent.uChar.AsciiChar) == 'L') /* L */
{
return REPAIR_INTRO_PAGE;
}
+/*
+ * Displays the UpgradeRepairPage.
+ *
+ * Next pages:
+ * RebootPage (default)
+ * InstallIntroPage
+ * RecoveryPage
+ * WelcomePage
+ *
+ * RETURNS
+ * Number of the next page.
+ */
+static PAGE_NUMBER
+UpgradeRepairPage(PINPUT_RECORD Ir)
+{
+ GENERIC_LIST_UI ListUi;
+
+/*** HACK!! ***/
+ if (PartitionList == NULL)
+ {
+ PartitionList = CreatePartitionList();
+ if (PartitionList == NULL)
+ {
+ /* FIXME: show an error dialog */
+ MUIDisplayError(ERROR_DRIVE_INFORMATION, Ir, POPUP_WAIT_ENTER);
+ return QUIT_PAGE;
+ }
+ else if (IsListEmpty(&PartitionList->DiskListHead))
+ {
+ MUIDisplayError(ERROR_NO_HDD, Ir, POPUP_WAIT_ENTER);
+ return QUIT_PAGE;
+ }
+
+ TempPartition = NULL;
+ FormatState = Start;
+ }
+/**************/
+
+ NtOsInstallsList = CreateNTOSInstallationsList(PartitionList);
+ if (!NtOsInstallsList)
+ DPRINT1("Failed to get a list of NTOS installations; continue installation...\n");
+ if (!NtOsInstallsList || GetNumberOfListEntries(NtOsInstallsList) == 0)
+ {
+ RepairUpdateFlag = FALSE;
+
+ // return INSTALL_INTRO_PAGE;
+ return DEVICE_SETTINGS_PAGE;
+ // return SCSI_CONTROLLER_PAGE;
+ }
+
+ MUIDisplayPage(UPGRADE_REPAIR_PAGE);
+
+ InitGenericListUi(&ListUi, NtOsInstallsList);
+ DrawGenericList(&ListUi,
+ 2, 23,
+ xScreen - 3,
+ yScreen - 3);
+
+ SaveGenericListState(NtOsInstallsList);
+
+ // return HandleGenericList(&ListUi, DEVICE_SETTINGS_PAGE, Ir);
+ while (TRUE)
+ {
+ CONSOLE_ConInKey(Ir);
+
+ if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x00)
+ {
+ switch (Ir->Event.KeyEvent.wVirtualKeyCode)
+ {
+ case VK_DOWN: /* DOWN */
+ ScrollDownGenericList(&ListUi);
+ break;
+ case VK_UP: /* UP */
+ ScrollUpGenericList(&ListUi);
+ break;
+ case VK_NEXT: /* PAGE DOWN */
+ ScrollPageDownGenericList(&ListUi);
+ break;
+ case VK_PRIOR: /* PAGE UP */
+ ScrollPageUpGenericList(&ListUi);
+ break;
+ case VK_F3: /* F3 */
+ {
+ if (ConfirmQuit(Ir) == TRUE)
+ return QUIT_PAGE;
+ else
+ RedrawGenericList(&ListUi);
+ break;
+ }
+ case VK_ESCAPE: /* ESC */
+ {
+ RestoreGenericListState(NtOsInstallsList);
+ // return nextPage; // prevPage;
+
+ // return INSTALL_INTRO_PAGE;
+ return DEVICE_SETTINGS_PAGE;
+ // return SCSI_CONTROLLER_PAGE;
+ }
+ }
+ }
+ else
+ {
+ // switch (toupper(Ir->Event.KeyEvent.uChar.AsciiChar))
+ // if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
+ if (toupper(Ir->Event.KeyEvent.uChar.AsciiChar) == 'U') /* U */
+ {
+ /* Retrieve the current installation */
+ CurrentInstallation = (PNTOS_INSTALLATION)GetListEntryUserData(GetCurrentListEntry(NtOsInstallsList));
+ DPRINT1("Selected installation for repair: \"%S\" ; DiskNumber = %d , PartitionNumber = %d\n",
+ CurrentInstallation->InstallationName, CurrentInstallation->DiskNumber, CurrentInstallation->PartitionNumber);
+
+ RepairUpdateFlag = TRUE;
+
+ // return nextPage;
+ /***/return INSTALL_INTRO_PAGE;/***/
+ }
+ else if ((Ir->Event.KeyEvent.uChar.AsciiChar > 0x60) &&
+ (Ir->Event.KeyEvent.uChar.AsciiChar < 0x7b)) /* a-z */
+ {
+ GenericListKeyPress(&ListUi, Ir->Event.KeyEvent.uChar.AsciiChar);
+ }
+ }
+ }
+
+ return UPGRADE_REPAIR_PAGE;
+}
+
+
/*
* Displays the InstallIntroPage.
*
{
if (RepairUpdateFlag)
{
- //return SELECT_PARTITION_PAGE;
+#if 1 /* Old code that looks good */
+
+ // return SELECT_PARTITION_PAGE;
return DEVICE_SETTINGS_PAGE;
+
+#else /* Possible new code? */
+
+ return DEVICE_SETTINGS_PAGE;
+ // return SCSI_CONTROLLER_PAGE;
+
+#endif
}
if (IsUnattendedSetup)
}
else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
{
- return DEVICE_SETTINGS_PAGE;
- // return SCSI_CONTROLLER_PAGE;
+ return UPGRADE_REPAIR_PAGE;
}
}
if (size < RequiredPartitionDiskSpace)
{
- /* partition is too small so ask for another partition */
+ /* Partition is too small so ask for another one */
DPRINT1("Partition is too small (size: %I64u MB), required disk space is %lu MB\n", size, RequiredPartitionDiskSpace);
return FALSE;
}
* QuitPage
*
* SIDEEFFECTS
- * Init DestinationDriveLetter (only if unattended or not free space is selected)
* Set InstallShortcut (only if not unattended + free space is selected)
*
* RETURNS
FormatState = Start;
}
+ if (RepairUpdateFlag)
+ {
+ /* Determine the selected installation disk & partition */
+ if (!SelectPartition(PartitionList,
+ CurrentInstallation->DiskNumber,
+ CurrentInstallation->PartitionNumber))
+ {
+ DPRINT1("RepairUpdateFlag == TRUE, SelectPartition() returned FALSE, assert!\n");
+ ASSERT(FALSE);
+ }
+
+ return SELECT_FILE_SYSTEM_PAGE;
+ }
+
MUIDisplayPage(SELECT_PARTITION_PAGE);
InitPartitionListUi(&ListUi, PartitionList,
return SELECT_PARTITION_PAGE; /* let the user select another partition */
}
- DestinationDriveLetter = (WCHAR)PartitionList->CurrentPartition->DriveLetter;
-
return SELECT_FILE_SYSTEM_PAGE;
}
}
return SELECT_PARTITION_PAGE; /* let the user select another partition */
}
- DestinationDriveLetter = (WCHAR)PartitionList->CurrentPartition->DriveLetter;
-
return SELECT_FILE_SYSTEM_PAGE;
}
}
return SELECT_PARTITION_PAGE; /* let the user select another partition */
}
- DestinationDriveLetter = (WCHAR)PartitionList->CurrentPartition->DriveLetter;
-
return SELECT_FILE_SYSTEM_PAGE;
}
else if (Ir->Event.KeyEvent.wVirtualKeyCode == 'P') /* P */
if (DiskEntry->DriverName.Length > 0)
{
CONSOLE_PrintTextXY(6, 10,
- MUIGetString(STRING_HDINFOPARTCREATE),
+ MUIGetString(STRING_HDINFOPARTCREATE_1),
DiskSize,
Unit,
DiskEntry->DiskNumber,
DiskEntry->Port,
DiskEntry->Bus,
DiskEntry->Id,
- &DiskEntry->DriverName);
+ &DiskEntry->DriverName,
+ DiskEntry->NoMbr ? "GPT" : "MBR");
}
else
{
CONSOLE_PrintTextXY(6, 10,
- MUIGetString(STRING_HDDINFOUNK1),
+ MUIGetString(STRING_HDINFOPARTCREATE_2),
DiskSize,
Unit,
DiskEntry->DiskNumber,
DiskEntry->Port,
DiskEntry->Bus,
- DiskEntry->Id);
+ DiskEntry->Id,
+ DiskEntry->NoMbr ? "GPT" : "MBR");
}
CONSOLE_SetTextXY(6, 12, MUIGetString(STRING_HDDSIZE));
if (DiskEntry->DriverName.Length > 0)
{
CONSOLE_PrintTextXY(6, 10,
- MUIGetString(STRING_HDINFOPARTCREATE),
+ MUIGetString(STRING_HDINFOPARTCREATE_1),
DiskSize,
Unit,
DiskEntry->DiskNumber,
DiskEntry->Port,
DiskEntry->Bus,
DiskEntry->Id,
- &DiskEntry->DriverName);
+ &DiskEntry->DriverName,
+ DiskEntry->NoMbr ? "GPT" : "MBR");
}
else
{
CONSOLE_PrintTextXY(6, 10,
- MUIGetString(STRING_HDDINFOUNK1),
+ MUIGetString(STRING_HDINFOPARTCREATE_2),
DiskSize,
Unit,
DiskEntry->DiskNumber,
DiskEntry->Port,
DiskEntry->Bus,
- DiskEntry->Id);
+ DiskEntry->Id,
+ DiskEntry->NoMbr ? "GPT" : "MBR");
}
CONSOLE_SetTextXY(6, 12, MUIGetString(STRING_HDDSIZE));
if (DiskEntry->DriverName.Length > 0)
{
CONSOLE_PrintTextXY(6, 10,
- MUIGetString(STRING_HDINFOPARTCREATE),
+ MUIGetString(STRING_HDINFOPARTCREATE_1),
DiskSize,
Unit,
DiskEntry->DiskNumber,
DiskEntry->Port,
DiskEntry->Bus,
DiskEntry->Id,
- &DiskEntry->DriverName);
+ &DiskEntry->DriverName,
+ DiskEntry->NoMbr ? "GPT" : "MBR");
}
else
{
CONSOLE_PrintTextXY(6, 10,
- MUIGetString(STRING_HDDINFOUNK1),
+ MUIGetString(STRING_HDINFOPARTCREATE_2),
DiskSize,
Unit,
DiskEntry->DiskNumber,
DiskEntry->Port,
DiskEntry->Bus,
- DiskEntry->Id);
+ DiskEntry->Id,
+ DiskEntry->NoMbr ? "GPT" : "MBR");
}
CONSOLE_SetTextXY(6, 12, MUIGetString(STRING_HDDSIZE));
if (DiskEntry->DriverName.Length > 0)
{
CONSOLE_PrintTextXY(6, 12,
- MUIGetString(STRING_HDINFOPARTDELETE),
+ MUIGetString(STRING_HDINFOPARTDELETE_1),
DiskSize,
Unit,
DiskEntry->DiskNumber,
DiskEntry->Port,
DiskEntry->Bus,
DiskEntry->Id,
- &DiskEntry->DriverName);
+ &DiskEntry->DriverName,
+ DiskEntry->NoMbr ? "GPT" : "MBR");
}
else
{
CONSOLE_PrintTextXY(6, 12,
- MUIGetString(STRING_HDDINFOUNK3),
+ MUIGetString(STRING_HDINFOPARTDELETE_2),
DiskSize,
Unit,
DiskEntry->DiskNumber,
DiskEntry->Port,
DiskEntry->Bus,
- DiskEntry->Id);
+ DiskEntry->Id,
+ DiskEntry->NoMbr ? "GPT" : "MBR");
}
while (TRUE)
PartTypeString);
#endif
- CONSOLE_PrintTextXY(8, 10, MUIGetString(STRING_HDINFOPARTZEROED),
+ CONSOLE_PrintTextXY(8, 10, MUIGetString(STRING_HDINFOPARTZEROED_1),
DiskEntry->DiskNumber,
DiskSize,
DiskUnit,
DiskEntry->Port,
DiskEntry->Bus,
DiskEntry->Id,
- &DiskEntry->DriverName);
+ &DiskEntry->DriverName,
+ DiskEntry->NoMbr ? "GPT" : "MBR");
CONSOLE_SetTextXY(6, 12, MUIGetString(STRING_PARTFORMAT));
PartUnit);
}
- CONSOLE_PrintTextXY(6, 12, MUIGetString(STRING_HDINFOPARTEXISTS),
+ CONSOLE_PrintTextXY(6, 12, MUIGetString(STRING_HDINFOPARTEXISTS_1),
DiskEntry->DiskNumber,
DiskSize,
DiskUnit,
DiskEntry->Port,
DiskEntry->Bus,
DiskEntry->Id,
- &DiskEntry->DriverName);
+ &DiskEntry->DriverName,
+ DiskEntry->NoMbr ? "GPT" : "MBR");
}
MUIDisplayPage(SELECT_FILE_SYSTEM_PAGE);
}
}
- DrawFileSystemList(FileSystemList);
-
if (RepairUpdateFlag)
{
return CHECK_FILE_SYSTEM_PAGE;
return CHECK_FILE_SYSTEM_PAGE;
}
+ DrawFileSystemList(FileSystemList);
+
while (TRUE)
{
CONSOLE_ConInKey(Ir);
{
WCHAR PathBuffer[MAX_PATH];
+/** Equivalent of 'NTOS_INSTALLATION::PathComponent' **/
/* Create 'InstallPath' string */
RtlFreeUnicodeString(&InstallPath);
RtlCreateUnicodeString(&InstallPath, InstallDir);
RtlCreateUnicodeString(&DestinationRootPath, PathBuffer);
DPRINT("DestinationRootPath: %wZ\n", &DestinationRootPath);
+/** Equivalent of 'NTOS_INSTALLATION::SystemNtPath' **/
/* Create 'DestinationPath' string */
RtlFreeUnicodeString(&DestinationPath);
CombinePaths(PathBuffer, ARRAYSIZE(PathBuffer), 2,
DestinationRootPath.Buffer, InstallDir);
RtlCreateUnicodeString(&DestinationPath, PathBuffer);
+/** Equivalent of 'NTOS_INSTALLATION::SystemArcPath' **/
/* Create 'DestinationArcPath' */
RtlFreeUnicodeString(&DestinationArcPath);
StringCchPrintfW(PathBuffer, ARRAYSIZE(PathBuffer),
PartEntry->PartitionNumber);
ConcatPaths(PathBuffer, ARRAYSIZE(PathBuffer), 1, InstallDir);
RtlCreateUnicodeString(&DestinationArcPath, PathBuffer);
+
+ /* Initialize DestinationDriveLetter */
+ DestinationDriveLetter = (WCHAR)PartEntry->DriveLetter;
}
* Displays the InstallDirectoryPage.
*
* Next pages:
- * PrepareCopyPage (As the direct result of InstallDirectoryPage1)
+ * PrepareCopyPage
* QuitPage
*
* RETURNS
WCHAR c;
ULONG Length, Pos;
- /* We do not need the filesystem list any more */
+ /* We do not need the filesystem list anymore */
if (FileSystemList != NULL)
{
DestroyFileSystemList(FileSystemList);
PartEntry = PartitionList->CurrentPartition;
if (IsUnattendedSetup)
- {
- if (!IsValidPath(UnattendInstallationDirectory))
- {
- /* FIXME: Log the error? */
- return QUIT_PAGE;
- }
+ wcscpy(InstallDir, UnattendInstallationDirectory);
+ else if (RepairUpdateFlag)
+ wcscpy(InstallDir, CurrentInstallation->PathComponent); // SystemNtPath
+ else
+ wcscpy(InstallDir, L"\\ReactOS");
- BuildInstallPaths(UnattendInstallationDirectory,
+ /*
+ * Check the validity of the predefined 'InstallDir'. If we are either
+ * in unattended setup or in update/repair mode, and the installation path
+ * is valid, just perform the installation. Otherwise (either in the case
+ * of an invalid path, or we are in regular setup), display the UI and allow
+ * the user to specify a new installation path.
+ */
+ if ((RepairUpdateFlag || IsUnattendedSetup) && IsValidPath(InstallDir))
+ {
+ BuildInstallPaths(InstallDir,
DiskEntry,
PartEntry);
return PREPARE_COPY_PAGE;
}
- wcscpy(InstallDir, L"\\ReactOS");
-
Length = wcslen(InstallDir);
Pos = Length;
+
+ MUIDisplayPage(INSTALL_DIRECTORY_PAGE);
CONSOLE_SetInputTextXY(8, 11, 51, InstallDir);
CONSOLE_SetCursorXY(8 + Pos, 11);
CONSOLE_SetCursorType(TRUE, TRUE);
- MUIDisplayPage(INSTALL_DIRECTORY_PAGE);
while (TRUE)
{
* QuitPage
*
* SIDEEFFECTS
- * Calls SetInstallPathValue
- * Calls NtInitializeRegistry
+ * Calls RegInitializeRegistry
* Calls ImportRegistryFile
* Calls SetDefaultPagefile
* Calls SetMountedDeviceValues
static PAGE_NUMBER
RegistryPage(PINPUT_RECORD Ir)
{
+ NTSTATUS Status;
INFCONTEXT InfContext;
PWSTR Action;
PWSTR File;
PWSTR Section;
+ BOOLEAN Success;
+ BOOLEAN ShouldRepairRegistry = FALSE;
BOOLEAN Delete;
- NTSTATUS Status;
MUIDisplayPage(REGISTRY_PAGE);
if (RepairUpdateFlag)
{
- // FIXME!
- DPRINT1("FIXME: Updating / repairing the registry is NOT implemented yet!\n");
- return SUCCESS_PAGE;
- }
+ DPRINT1("TODO: Updating / repairing the registry is not completely implemented yet!\n");
- /************************ HACK!!!!!!!!!!! *********************************/
- if (!SetInstallPathValue(&DestinationPath))
- {
- DPRINT1("SetInstallPathValue() failed\n");
- MUIDisplayError(ERROR_INITIALIZE_REGISTRY, Ir, POPUP_WAIT_ENTER);
- return QUIT_PAGE;
+ /* Verify the registry hives and check whether we need to update or repair any of them */
+ Status = VerifyRegistryHives(&DestinationPath, &ShouldRepairRegistry);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("VerifyRegistryHives failed, Status 0x%08lx\n", Status);
+ ShouldRepairRegistry = FALSE;
+ }
+ if (!ShouldRepairRegistry)
+ DPRINT1("No need to repair the registry\n");
}
- /************************ HACK!!!!!!!!!!! *********************************/
- /* Create the default hives */
- Status = NtInitializeRegistry(CM_BOOT_FLAG_SETUP);
+DoUpdate:
+ /* Update the registry */
+ CONSOLE_SetStatusText(MUIGetString(STRING_REGHIVEUPDATE));
+
+ /* Initialize the registry and setup the registry hives */
+ Status = RegInitializeRegistry(&DestinationPath);
if (!NT_SUCCESS(Status))
{
- DPRINT1("NtInitializeRegistry() failed (Status %lx)\n", Status);
- MUIDisplayError(ERROR_CREATE_HIVE, Ir, POPUP_WAIT_ENTER);
+ DPRINT1("RegInitializeRegistry() failed\n");
+ /********** HACK!!!!!!!!!!! **********/
+ if (Status == STATUS_NOT_IMPLEMENTED)
+ {
+ /* The hack was called, display its corresponding error */
+ MUIDisplayError(ERROR_INITIALIZE_REGISTRY, Ir, POPUP_WAIT_ENTER);
+ }
+ else
+ /*************************************/
+ {
+ /* Something else failed */
+ MUIDisplayError(ERROR_CREATE_HIVE, Ir, POPUP_WAIT_ENTER);
+ }
return QUIT_PAGE;
}
- /* Update registry */
- CONSOLE_SetStatusText(MUIGetString(STRING_REGHIVEUPDATE));
+ if (!RepairUpdateFlag || ShouldRepairRegistry)
+ {
+ /*
+ * We fully setup the hives, in case we are doing a fresh installation
+ * (RepairUpdateFlag == FALSE), or in case we are doing an update
+ * (RepairUpdateFlag == TRUE) BUT we have some registry hives to
+ * "repair" (aka. recreate: ShouldRepairRegistry == TRUE).
+ */
- if (!SetupFindFirstLineW(SetupInf, L"HiveInfs.Install", NULL, &InfContext))
+ Success = SetupFindFirstLineW(SetupInf, L"HiveInfs.Fresh", NULL, &InfContext); // Windows-compatible
+ if (!Success)
+ Success = SetupFindFirstLineW(SetupInf, L"HiveInfs.Install", NULL, &InfContext); // ReactOS-specific
+
+ if (!Success)
+ {
+ DPRINT1("SetupFindFirstLine() failed\n");
+ MUIDisplayError(ERROR_FIND_REGISTRY, Ir, POPUP_WAIT_ENTER);
+ goto Cleanup;
+ }
+ }
+ else // if (RepairUpdateFlag && !ShouldRepairRegistry)
{
- DPRINT1("SetupFindFirstLine() failed\n");
- MUIDisplayError(ERROR_FIND_REGISTRY, Ir, POPUP_WAIT_ENTER);
- return QUIT_PAGE;
+ /*
+ * In case we are doing an update (RepairUpdateFlag == TRUE) and
+ * NO registry hives need a repair (ShouldRepairRegistry == FALSE),
+ * we only update the hives.
+ */
+
+ Success = SetupFindFirstLineW(SetupInf, L"HiveInfs.Upgrade", NULL, &InfContext);
+ if (!Success)
+ {
+ /* Nothing to do for update! */
+ DPRINT1("No update needed for the registry!\n");
+ goto Cleanup;
+ }
}
do
break; // Hackfix
if (!_wcsicmp(Action, L"AddReg"))
- {
Delete = FALSE;
- }
else if (!_wcsicmp(Action, L"DelReg"))
- {
Delete = TRUE;
- }
else
{
+ DPRINT1("Unrecognized registry INF action '%S'\n", Action);
continue;
}
CONSOLE_SetStatusText(MUIGetString(STRING_IMPORTFILE), File);
- if (!ImportRegistryFile(File, Section, LanguageId, Delete))
+ if (!ImportRegistryFile(SourcePath.Buffer, File, Section, LanguageId, Delete))
{
DPRINT1("Importing %S failed\n", File);
-
MUIDisplayError(ERROR_IMPORT_HIVE, Ir, POPUP_WAIT_ENTER);
- return QUIT_PAGE;
+ goto Cleanup;
}
} while (SetupFindNextLine(&InfContext, &InfContext));
- /* Update display registry settings */
- CONSOLE_SetStatusText(MUIGetString(STRING_DISPLAYETTINGSUPDATE));
- if (!ProcessDisplayRegistry(SetupInf, DisplayList))
+ if (!RepairUpdateFlag || ShouldRepairRegistry)
{
- MUIDisplayError(ERROR_UPDATE_DISPLAY_SETTINGS, Ir, POPUP_WAIT_ENTER);
- return QUIT_PAGE;
- }
+ /* See the explanation for this test above */
- /* Set the locale */
- CONSOLE_SetStatusText(MUIGetString(STRING_LOCALESETTINGSUPDATE));
- if (!ProcessLocaleRegistry(LanguageList))
- {
- MUIDisplayError(ERROR_UPDATE_LOCALESETTINGS, Ir, POPUP_WAIT_ENTER);
- return QUIT_PAGE;
- }
+ /* Update display registry settings */
+ CONSOLE_SetStatusText(MUIGetString(STRING_DISPLAYETTINGSUPDATE));
+ if (!ProcessDisplayRegistry(SetupInf, DisplayList))
+ {
+ MUIDisplayError(ERROR_UPDATE_DISPLAY_SETTINGS, Ir, POPUP_WAIT_ENTER);
+ goto Cleanup;
+ }
- /* Add keyboard layouts */
- CONSOLE_SetStatusText(MUIGetString(STRING_ADDKBLAYOUTS));
- if (!AddKeyboardLayouts())
- {
- MUIDisplayError(ERROR_ADDING_KBLAYOUTS, Ir, POPUP_WAIT_ENTER);
- return QUIT_PAGE;
+ /* Set the locale */
+ CONSOLE_SetStatusText(MUIGetString(STRING_LOCALESETTINGSUPDATE));
+ if (!ProcessLocaleRegistry(LanguageList))
+ {
+ MUIDisplayError(ERROR_UPDATE_LOCALESETTINGS, Ir, POPUP_WAIT_ENTER);
+ goto Cleanup;
+ }
+
+ /* Add keyboard layouts */
+ CONSOLE_SetStatusText(MUIGetString(STRING_ADDKBLAYOUTS));
+ if (!AddKeyboardLayouts())
+ {
+ MUIDisplayError(ERROR_ADDING_KBLAYOUTS, Ir, POPUP_WAIT_ENTER);
+ goto Cleanup;
+ }
+
+ /* Set GeoID */
+ if (!SetGeoID(MUIGetGeoID()))
+ {
+ MUIDisplayError(ERROR_UPDATE_GEOID, Ir, POPUP_WAIT_ENTER);
+ goto Cleanup;
+ }
+
+ if (!IsUnattendedSetup)
+ {
+ /* Update keyboard layout settings */
+ CONSOLE_SetStatusText(MUIGetString(STRING_KEYBOARDSETTINGSUPDATE));
+ if (!ProcessKeyboardLayoutRegistry(LayoutList))
+ {
+ MUIDisplayError(ERROR_UPDATE_KBSETTINGS, Ir, POPUP_WAIT_ENTER);
+ goto Cleanup;
+ }
+ }
+
+ /* Add codepage information to registry */
+ CONSOLE_SetStatusText(MUIGetString(STRING_CODEPAGEINFOUPDATE));
+ if (!AddCodePage())
+ {
+ MUIDisplayError(ERROR_ADDING_CODEPAGE, Ir, POPUP_WAIT_ENTER);
+ goto Cleanup;
+ }
+
+ /* Set the default pagefile entry */
+ SetDefaultPagefile(DestinationDriveLetter);
+
+ /* Update the mounted devices list */
+ // FIXME: This should technically be done by mountmgr (if AutoMount is enabled)!
+ SetMountedDeviceValues(PartitionList);
}
- /* Set GeoID */
- if (!SetGeoID(MUIGetGeoID()))
+Cleanup:
+ //
+ // TODO: Unload all the registry stuff, perform cleanup,
+ // and copy the created hive files into .sav files.
+ //
+ RegCleanupRegistry(&DestinationPath);
+
+ /*
+ * Check whether we were in update/repair mode but we were actually
+ * repairing the registry hives. If so, we have finished repairing them,
+ * and we now reset the flag and run the proper registry update.
+ * Otherwise we have finished the registry update!
+ */
+ if (RepairUpdateFlag && ShouldRepairRegistry)
{
- MUIDisplayError(ERROR_UPDATE_GEOID, Ir, POPUP_WAIT_ENTER);
- return QUIT_PAGE;
+ ShouldRepairRegistry = FALSE;
+ goto DoUpdate;
}
- if (!IsUnattendedSetup)
+ if (NT_SUCCESS(Status))
{
- /* Update keyboard layout settings */
- CONSOLE_SetStatusText(MUIGetString(STRING_KEYBOARDSETTINGSUPDATE));
- if (!ProcessKeyboardLayoutRegistry(LayoutList))
- {
- MUIDisplayError(ERROR_UPDATE_KBSETTINGS, Ir, POPUP_WAIT_ENTER);
- return QUIT_PAGE;
- }
+ CONSOLE_SetStatusText(MUIGetString(STRING_DONE));
+ return BOOT_LOADER_PAGE;
}
-
- /* Add codepage information to registry */
- CONSOLE_SetStatusText(MUIGetString(STRING_CODEPAGEINFOUPDATE));
- if (!AddCodePage())
+ else
{
- MUIDisplayError(ERROR_ADDING_CODEPAGE, Ir, POPUP_WAIT_ENTER);
return QUIT_PAGE;
}
-
- /* Set the default pagefile entry */
- SetDefaultPagefile(DestinationDriveLetter);
-
- /* Update the mounted devices list */
- SetMountedDeviceValues(PartitionList);
-
- CONSOLE_SetStatusText(MUIGetString(STRING_DONE));
-
- return BOOT_LOADER_PAGE;
}
* QuitPage
*
* SIDEEFFECTS
- * Calls SetInstallPathValue
- * Calls NtInitializeRegistry
+ * Calls RegInitializeRegistry
* Calls ImportRegistryFile
* Calls SetDefaultPagefile
* Calls SetMountedDeviceValues
static PAGE_NUMBER
BootLoaderHarddiskVbrPage(PINPUT_RECORD Ir)
{
- UCHAR PartitionType;
NTSTATUS Status;
- PartitionType = PartitionList->SystemPartition->PartitionType;
-
Status = InstallVBRToPartition(&SystemRootPath,
&SourceRootPath,
&DestinationArcPath,
- PartitionType);
+ PartitionList->SystemPartition->PartitionType);
if (!NT_SUCCESS(Status))
{
MUIDisplayError(ERROR_WRITE_BOOT, Ir, POPUP_WAIT_ENTER);
static PAGE_NUMBER
BootLoaderHarddiskMbrPage(PINPUT_RECORD Ir)
{
- UCHAR PartitionType;
NTSTATUS Status;
WCHAR DestinationDevicePathBuffer[MAX_PATH];
WCHAR SourceMbrPathBuffer[MAX_PATH];
WCHAR DstPath[MAX_PATH];
/* Step 1: Write the VBR */
- PartitionType = PartitionList->SystemPartition->PartitionType;
-
Status = InstallVBRToPartition(&SystemRootPath,
&SourceRootPath,
&DestinationArcPath,
- PartitionType);
+ PartitionList->SystemPartition->PartitionType);
if (!NT_SUCCESS(Status))
{
MUIDisplayError(ERROR_WRITE_BOOT, Ir, POPUP_WAIT_ENTER);
{
MUIDisplayPage(QUIT_PAGE);
+ /* Destroy the NTOS installations list */
+ if (NtOsInstallsList != NULL)
+ {
+ DestroyGenericList(NtOsInstallsList, TRUE);
+ NtOsInstallsList = NULL;
+ }
+
/* Destroy the partition list */
if (PartitionList != NULL)
{
/*
* The start routine and page management
*/
-VOID
+NTSTATUS
RunUSetup(VOID)
{
+ NTSTATUS Status;
INPUT_RECORD Ir;
PAGE_NUMBER Page;
- LARGE_INTEGER Time;
- NTSTATUS Status;
BOOLEAN Old;
- NtQuerySystemTime(&Time);
+ InfSetHeap(ProcessHeap);
+
+ /* Tell the Cm this is a setup boot, and it has to behave accordingly */
+ Status = NtInitializeRegistry(CM_BOOT_FLAG_SETUP);
+ if (!NT_SUCCESS(Status))
+ DPRINT1("NtInitializeRegistry() failed (Status 0x%08lx)\n", Status);
/* Create the PnP thread in suspended state */
Status = RtlCreateUserThread(NtCurrentProcess(),
PrintString(MUIGetString(STRING_CONSOLEFAIL2));
PrintString(MUIGetString(STRING_CONSOLEFAIL3));
- /* Raise a hard error (crash the system/BSOD) */
- NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED,
- 0,0,0,0,0);
+ /* We failed to initialize the video, just quit the installer */
+ return STATUS_APP_INIT_FAILURE;
}
/* Initialize global unicode strings */
Page = RepairIntroPage(&Ir);
break;
+ case UPGRADE_REPAIR_PAGE:
+ Page = UpgradeRepairPage(&Ir);
+ break;
+
case SUCCESS_PAGE:
Page = SuccessPage(&Ir);
break;
FreeConsole();
- /* Avoid bugcheck */
- Time.QuadPart += 50000000;
- NtDelayExecution(FALSE, &Time);
-
/* Reboot */
RtlAdjustPrivilege(SE_SHUTDOWN_PRIVILEGE, TRUE, FALSE, &Old);
NtShutdownSystem(ShutdownReboot);
RtlAdjustPrivilege(SE_SHUTDOWN_PRIVILEGE, Old, FALSE, &Old);
- NtTerminateProcess(NtCurrentProcess(), 0);
+
+ return STATUS_SUCCESS;
}
VOID NTAPI
NtProcessStartup(PPEB Peb)
{
+ NTSTATUS Status;
+ LARGE_INTEGER Time;
+
RtlNormalizeProcessParams(Peb->ProcessParameters);
ProcessHeap = Peb->ProcessHeap;
- InfSetHeap(ProcessHeap);
- RunUSetup();
+
+ NtQuerySystemTime(&Time);
+
+ Status = RunUSetup();
+
+ if (NT_SUCCESS(Status))
+ {
+ /*
+ * Avoid a bugcheck if RunUSetup() finishes too quickly by implementing
+ * a protective waiting.
+ * This wait is needed because, since we are started as SMSS.EXE,
+ * the NT kernel explicitly waits 5 seconds for the initial process
+ * SMSS.EXE to initialize (as a protective measure), and otherwise
+ * bugchecks with the code SESSION5_INITIALIZATION_FAILED.
+ */
+ Time.QuadPart += 50000000;
+ NtDelayExecution(FALSE, &Time);
+ }
+ else
+ {
+ /* The installer failed to start: raise a hard error (crash the system/BSOD) */
+ Status = NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED,
+ 0, 0, NULL, 0, NULL);
+ }
+
+ NtTerminateProcess(NtCurrentProcess(), Status);
}
/* EOF */