X-Git-Url: https://git.reactos.org/?p=reactos.git;a=blobdiff_plain;f=base%2Fsetup%2Fusetup%2Fusetup.c;h=f16d6512b739bcf886a1f7cc1aed7a660f7bed86;hp=80d6345aa2e9281968c970468e7c68168d3de928;hb=073c09e491f1003b07c10abfb5e209f0c5e122f5;hpb=b20908acc80f65496ad3d153b87069c6b652ec8b diff --git a/base/setup/usetup/usetup.c b/base/setup/usetup/usetup.c index 80d6345aa2e..f16d6512b73 100644 --- a/base/setup/usetup/usetup.c +++ b/base/setup/usetup/usetup.c @@ -21,7 +21,7 @@ * PROJECT: ReactOS text-mode setup * FILE: base/setup/usetup/usetup.c * PURPOSE: Text-mode setup - * PROGRAMMER: Casper S. Hornstrup (chorns@users.sourceforge.net) + * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net) * Hervé Poussineau (hpoussin@reactos.org) */ @@ -32,85 +32,42 @@ #include "chkdsk.h" #include "cmdcons.h" #include "format.h" -#include "drivesup.h" -#include "settings.h" #define NDEBUG #include -// HACK! -#include - -/* GLOBALS ******************************************************************/ +/* GLOBALS & LOCALS *********************************************************/ HANDLE ProcessHeap; - -static UNICODE_STRING SourceRootPath; -static UNICODE_STRING SourceRootDir; -/* static */ UNICODE_STRING SourcePath; - BOOLEAN IsUnattendedSetup = FALSE; -LONG UnattendDestinationDiskNumber; -LONG UnattendDestinationPartitionNumber; -LONG UnattendMBRInstallType = -1; -LONG UnattendFormatPartition = 0; -LONG AutoPartition = 0; -WCHAR UnattendInstallationDirectory[MAX_PATH]; -PWCHAR SelectedLanguageId; -WCHAR LocaleID[9]; -WCHAR DefaultLanguage[20]; -WCHAR DefaultKBLayout[20]; -static BOOLEAN RepairUpdateFlag = FALSE; -static HANDLE hPnpThread = INVALID_HANDLE_VALUE; - -static PPARTLIST PartitionList = NULL; -static PPARTENTRY TempPartition = NULL; -static FORMATMACHINESTATE FormatState = Start; +static USETUP_DATA USetupData; -/* LOCALS *******************************************************************/ - -static PFILE_SYSTEM_LIST FileSystemList = NULL; +// FIXME: Is it really useful?? Just used for SetDefaultPagefile... +static WCHAR DestinationDriveLetter; -static UNICODE_STRING InstallPath; -/* - * Path to the system partition, where the boot manager resides. - * On x86 PCs, this is usually the active partition. - * On ARC, (u)EFI, ... platforms, this is a dedicated partition. - * - * For more information, see: - * https://en.wikipedia.org/wiki/System_partition_and_boot_partition - * http://homepage.ntlworld.com/jonathan.deboynepollard/FGA/boot-and-system-volumes.html - * http://homepage.ntlworld.com/jonathan.deboynepollard/FGA/arc-boot-process.html - * http://homepage.ntlworld.com/jonathan.deboynepollard/FGA/efi-boot-process.html - * http://homepage.ntlworld.com/jonathan.deboynepollard/FGA/determining-system-volume.html - * http://homepage.ntlworld.com/jonathan.deboynepollard/FGA/determining-boot-volume.html - */ -static UNICODE_STRING SystemRootPath; +/* OTHER Stuff *****/ -/* Path to the install directory inside the ReactOS boot partition */ -static UNICODE_STRING DestinationPath; -static UNICODE_STRING DestinationArcPath; -static UNICODE_STRING DestinationRootPath; +PCWSTR SelectedLanguageId; +static WCHAR DefaultLanguage[20]; // Copy of string inside LanguageList +static WCHAR DefaultKBLayout[20]; // Copy of string inside KeyboardList -// FIXME: Is it really useful?? Just used for SetDefaultPagefile... -static WCHAR DestinationDriveLetter; +static BOOLEAN RepairUpdateFlag = FALSE; -static HINF SetupInf; +static HANDLE hPnpThread = NULL; -static HSPFILEQ SetupFileQueue = NULL; +static PPARTLIST PartitionList = NULL; +static PPARTENTRY TempPartition = NULL; +static PFILE_SYSTEM_LIST FileSystemList = NULL; +static FORMATMACHINESTATE FormatState = Start; -static PGENERIC_LIST ComputerList = NULL; -static PGENERIC_LIST DisplayList = NULL; -static PGENERIC_LIST KeyboardList = NULL; -static PGENERIC_LIST LayoutList = NULL; -static PGENERIC_LIST LanguageList = NULL; +/*****************************************************/ -static LANGID LanguageId = 0; +static PNTOS_INSTALLATION CurrentInstallation = NULL; +static PGENERIC_LIST NtOsInstallsList = NULL; -static ULONG RequiredPartitionDiskSpace = ~0; /* FUNCTIONS ****************************************************************/ @@ -142,7 +99,7 @@ DrawBox(IN SHORT xLeft, COORD coPos; DWORD Written; - /* draw upper left corner */ + /* Draw upper left corner */ coPos.X = xLeft; coPos.Y = yTop; FillConsoleOutputCharacterA(StdOutput, @@ -151,7 +108,7 @@ DrawBox(IN SHORT xLeft, coPos, &Written); - /* draw upper edge */ + /* Draw upper edge */ coPos.X = xLeft + 1; coPos.Y = yTop; FillConsoleOutputCharacterA(StdOutput, @@ -160,7 +117,7 @@ DrawBox(IN SHORT xLeft, coPos, &Written); - /* draw upper right corner */ + /* Draw upper right corner */ coPos.X = xLeft + Width - 1; coPos.Y = yTop; FillConsoleOutputCharacterA(StdOutput, @@ -194,7 +151,7 @@ DrawBox(IN SHORT xLeft, &Written); } - /* draw lower left corner */ + /* Draw lower left corner */ coPos.X = xLeft; coPos.Y = yTop + Height - 1; FillConsoleOutputCharacterA(StdOutput, @@ -203,7 +160,7 @@ DrawBox(IN SHORT xLeft, coPos, &Written); - /* draw lower edge */ + /* Draw lower edge */ coPos.X = xLeft + 1; coPos.Y = yTop + Height - 1; FillConsoleOutputCharacterA(StdOutput, @@ -212,7 +169,7 @@ DrawBox(IN SHORT xLeft, coPos, &Written); - /* draw lower right corner */ + /* Draw lower right corner */ coPos.X = xLeft + Width - 1; coPos.Y = yTop + Height - 1; FillConsoleOutputCharacterA(StdOutput, @@ -267,7 +224,7 @@ PopupError(PCCH Text, if (Length > MaxLength) MaxLength = Length; - if (LastLine != FALSE) + if (LastLine) break; pnext = p + 1; @@ -333,7 +290,7 @@ PopupError(PCCH Text, &Written); } - if (LastLine != FALSE) + if (LastLine) break; coPos.Y++; @@ -424,210 +381,76 @@ ConfirmQuit(PINPUT_RECORD Ir) static VOID -CheckUnattendedSetup(VOID) +UpdateKBLayout(VOID) { - WCHAR UnattendInfPath[MAX_PATH]; - INFCONTEXT Context; - HINF UnattendInf; - UINT ErrorLine; - INT IntValue; - PWCHAR Value; - - CombinePaths(UnattendInfPath, ARRAYSIZE(UnattendInfPath), 2, SourcePath.Buffer, L"unattend.inf"); - - if (DoesFileExist(NULL, UnattendInfPath) == FALSE) - { - DPRINT("Does not exist: %S\n", UnattendInfPath); - return; - } - - /* Load 'unattend.inf' from install media. */ - UnattendInf = SetupOpenInfFileW(UnattendInfPath, - NULL, - INF_STYLE_WIN4, - LanguageId, - &ErrorLine); - - if (UnattendInf == INVALID_HANDLE_VALUE) - { - DPRINT("SetupOpenInfFileW() failed\n"); - return; - } - - /* Open 'Unattend' section */ - if (!SetupFindFirstLineW(UnattendInf, L"Unattend", L"Signature", &Context)) - { - DPRINT("SetupFindFirstLineW() failed for section 'Unattend'\n"); - SetupCloseInfFile(UnattendInf); - return; - } - - /* Get pointer 'Signature' key */ - if (!INF_GetData(&Context, NULL, &Value)) - { - DPRINT("INF_GetData() failed for key 'Signature'\n"); - SetupCloseInfFile(UnattendInf); - return; - } - - /* Check 'Signature' string */ - if (_wcsicmp(Value, L"$ReactOS$") != 0) - { - DPRINT("Signature not $ReactOS$\n"); - SetupCloseInfFile(UnattendInf); - return; - } - - /* Check if Unattend setup is enabled */ - if (!SetupFindFirstLineW(UnattendInf, L"Unattend", L"UnattendSetupEnabled", &Context)) - { - DPRINT("Can't find key 'UnattendSetupEnabled'\n"); - SetupCloseInfFile(UnattendInf); - return; - } - - if (!INF_GetData(&Context, NULL, &Value)) - { - DPRINT("Can't read key 'UnattendSetupEnabled'\n"); - SetupCloseInfFile(UnattendInf); - return; - } - - if (_wcsicmp(Value, L"yes") != 0) - { - DPRINT("Unattend setup is disabled by 'UnattendSetupEnabled' key!\n"); - SetupCloseInfFile(UnattendInf); - return; - } - - /* Search for 'DestinationDiskNumber' in the 'Unattend' section */ - if (!SetupFindFirstLineW(UnattendInf, L"Unattend", L"DestinationDiskNumber", &Context)) - { - DPRINT("SetupFindFirstLine() failed for key 'DestinationDiskNumber'\n"); - SetupCloseInfFile(UnattendInf); - return; - } - - if (!SetupGetIntField(&Context, 1, &IntValue)) - { - DPRINT("SetupGetIntField() failed for key 'DestinationDiskNumber'\n"); - SetupCloseInfFile(UnattendInf); - return; - } - - UnattendDestinationDiskNumber = (LONG)IntValue; - - /* Search for 'DestinationPartitionNumber' in the 'Unattend' section */ - if (!SetupFindFirstLineW(UnattendInf, L"Unattend", L"DestinationPartitionNumber", &Context)) - { - DPRINT("SetupFindFirstLine() failed for key 'DestinationPartitionNumber'\n"); - SetupCloseInfFile(UnattendInf); - return; - } - - if (!SetupGetIntField(&Context, 1, &IntValue)) - { - DPRINT("SetupGetIntField() failed for key 'DestinationPartitionNumber'\n"); - SetupCloseInfFile(UnattendInf); - return; - } - - UnattendDestinationPartitionNumber = (LONG)IntValue; - - /* Search for 'InstallationDirectory' in the 'Unattend' section */ - if (!SetupFindFirstLineW(UnattendInf, L"Unattend", L"InstallationDirectory", &Context)) - { - DPRINT("SetupFindFirstLine() failed for key 'InstallationDirectory'\n"); - SetupCloseInfFile(UnattendInf); - return; - } - - /* Get pointer 'InstallationDirectory' key */ - if (!INF_GetData(&Context, NULL, &Value)) - { - DPRINT("INF_GetData() failed for key 'InstallationDirectory'\n"); - SetupCloseInfFile(UnattendInf); - return; - } - - wcscpy(UnattendInstallationDirectory, Value); - - IsUnattendedSetup = TRUE; - DPRINT("Running unattended setup\n"); + PGENERIC_LIST_ENTRY ListEntry; + PCWSTR pszNewLayout; - /* Search for 'MBRInstallType' in the 'Unattend' section */ - if (SetupFindFirstLineW(UnattendInf, L"Unattend", L"MBRInstallType", &Context)) - { - if (SetupGetIntField(&Context, 1, &IntValue)) - { - UnattendMBRInstallType = IntValue; - } - } + pszNewLayout = MUIDefaultKeyboardLayout(SelectedLanguageId); - /* Search for 'FormatPartition' in the 'Unattend' section */ - if (SetupFindFirstLineW(UnattendInf, L"Unattend", L"FormatPartition", &Context)) + if (USetupData.LayoutList == NULL) { - if (SetupGetIntField(&Context, 1, &IntValue)) + USetupData.LayoutList = CreateKeyboardLayoutList(USetupData.SetupInf, SelectedLanguageId, DefaultKBLayout); + if (USetupData.LayoutList == NULL) { - UnattendFormatPartition = IntValue; + /* FIXME: Handle error! */ + return; } } - if (SetupFindFirstLineW(UnattendInf, L"Unattend", L"AutoPartition", &Context)) + /* Search for default layout (if provided) */ + if (pszNewLayout != NULL) { - if (SetupGetIntField(&Context, 1, &IntValue)) + for (ListEntry = GetFirstListEntry(USetupData.LayoutList); ListEntry; + ListEntry = GetNextListEntry(ListEntry)) { - AutoPartition = IntValue; + if (!wcscmp(pszNewLayout, ((PGENENTRY)GetListEntryData(ListEntry))->Id)) + { + SetCurrentListEntry(USetupData.LayoutList, ListEntry); + break; + } } } - - /* search for LocaleID in the 'Unattend' section*/ - if (SetupFindFirstLineW(UnattendInf, L"Unattend", L"LocaleID", &Context)) - { - if (INF_GetData(&Context, NULL, &Value)) - { - LONG Id = wcstol(Value, NULL, 16); - swprintf(LocaleID, L"%08lx", Id); - } - } - - SetupCloseInfFile(UnattendInf); } -static VOID -UpdateKBLayout(VOID) +static NTSTATUS +NTAPI +GetSettingDescription( + IN PGENERIC_LIST_ENTRY Entry, + OUT PSTR Buffer, + IN SIZE_T cchBufferSize) { - PGENERIC_LIST_ENTRY ListEntry; - LPCWSTR pszNewLayout; + return RtlStringCchPrintfA(Buffer, cchBufferSize, "%S", + ((PGENENTRY)GetListEntryData(Entry))->Value); +} - pszNewLayout = MUIDefaultKeyboardLayout(); +static NTSTATUS +NTAPI +GetNTOSInstallationName( + IN PGENERIC_LIST_ENTRY Entry, + OUT PSTR Buffer, + IN SIZE_T cchBufferSize) +{ + PNTOS_INSTALLATION NtOsInstall = (PNTOS_INSTALLATION)GetListEntryData(Entry); + PPARTENTRY PartEntry = NtOsInstall->PartEntry; - if (LayoutList == NULL) + if (PartEntry && PartEntry->DriveLetter) { - LayoutList = CreateKeyboardLayoutList(SetupInf, DefaultKBLayout); - if (LayoutList == NULL) - { - /* FIXME: Handle error! */ - return; - } + /* We have retrieved a partition that is mounted */ + return RtlStringCchPrintfA(Buffer, cchBufferSize, + "%C:%S \"%S\"", + PartEntry->DriveLetter, + NtOsInstall->PathComponent, + NtOsInstall->InstallationName); } - - ListEntry = GetFirstListEntry(LayoutList); - - /* Search for default layout (if provided) */ - if (pszNewLayout != NULL) + else { - while (ListEntry != NULL) - { - if (!wcscmp(pszNewLayout, GetListEntryUserData(ListEntry))) - { - SetCurrentListEntry(LayoutList, ListEntry); - break; - } - - ListEntry = GetNextListEntry(ListEntry); - } + /* We failed somewhere, just show the NT path */ + return RtlStringCchPrintfA(Buffer, cchBufferSize, + "%wZ \"%S\"", + &NtOsInstall->SystemNtPath, + NtOsInstall->InstallationName); } } @@ -639,7 +462,7 @@ UpdateKBLayout(VOID) * * SIDEEFFECTS * Init SelectedLanguageId - * Init LanguageId + * Init USetupData.LanguageId * * RETURNS * Number of the next page. @@ -648,37 +471,40 @@ static PAGE_NUMBER LanguagePage(PINPUT_RECORD Ir) { GENERIC_LIST_UI ListUi; - PWCHAR NewLanguageId; + PCWSTR NewLanguageId; BOOL RefreshPage = FALSE; /* Initialize the computer settings list */ - if (LanguageList == NULL) + if (USetupData.LanguageList == NULL) { - LanguageList = CreateLanguageList(SetupInf, DefaultLanguage); - if (LanguageList == NULL) + USetupData.LanguageList = CreateLanguageList(USetupData.SetupInf, DefaultLanguage); + if (USetupData.LanguageList == NULL) { PopupError("Setup failed to initialize available translations", NULL, NULL, POPUP_WAIT_NONE); return WELCOME_PAGE; } } - /* Load the font */ SelectedLanguageId = DefaultLanguage; + USetupData.LanguageId = 0; + + /* Load the font */ SetConsoleCodePage(); UpdateKBLayout(); - /* If there's just a single language in the list skip - * the language selection process altogether! */ - if (GenericListHasSingleEntry(LanguageList)) + /* + * If there is no language or just a single one in the list, + * skip the language selection process altogether. + */ + if (GetNumberOfListEntries(USetupData.LanguageList) <= 1) { - LanguageId = (LANGID)(wcstol(SelectedLanguageId, NULL, 16) & 0xFFFF); + USetupData.LanguageId = (LANGID)(wcstol(SelectedLanguageId, NULL, 16) & 0xFFFF); return WELCOME_PAGE; } - InitGenericListUi(&ListUi, LanguageList); + InitGenericListUi(&ListUi, USetupData.LanguageList, GetSettingDescription); DrawGenericList(&ListUi, - 2, - 18, + 2, 18, xScreen - 3, yScreen - 3); @@ -717,16 +543,19 @@ LanguagePage(PINPUT_RECORD Ir) else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) && (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */ { - if (ConfirmQuit(Ir) != FALSE) + if (ConfirmQuit(Ir)) return QUIT_PAGE; else RedrawGenericList(&ListUi); } else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */ { - SelectedLanguageId = (PWCHAR)GetListEntryUserData(GetCurrentListEntry(LanguageList)); + ASSERT(GetNumberOfListEntries(USetupData.LanguageList) >= 1); + + SelectedLanguageId = + ((PGENENTRY)GetListEntryData(GetCurrentListEntry(USetupData.LanguageList)))->Id; - LanguageId = (LANGID)(wcstol(SelectedLanguageId, NULL, 16) & 0xFFFF); + USetupData.LanguageId = (LANGID)(wcstol(SelectedLanguageId, NULL, 16) & 0xFFFF); if (wcscmp(SelectedLanguageId, DefaultLanguage)) { @@ -747,9 +576,12 @@ LanguagePage(PINPUT_RECORD Ir) if (RefreshPage) { - NewLanguageId = (PWCHAR)GetListEntryUserData(GetCurrentListEntry(LanguageList)); + ASSERT(GetNumberOfListEntries(USetupData.LanguageList) >= 1); - if (SelectedLanguageId != NewLanguageId) + NewLanguageId = + ((PGENENTRY)GetListEntryData(GetCurrentListEntry(USetupData.LanguageList)))->Id; + + if (wcscmp(SelectedLanguageId, NewLanguageId)) { /* Clear the language page */ MUIClearPage(LANGUAGE_PAGE); @@ -781,15 +613,15 @@ LanguagePage(PINPUT_RECORD Ir) * * SIDEEFFECTS * Init Sdi - * Init SourcePath - * Init SourceRootPath - * Init SourceRootDir - * Init SetupInf - * Init RequiredPartitionDiskSpace + * Init USetupData.SourcePath + * Init USetupData.SourceRootPath + * Init USetupData.SourceRootDir + * Init USetupData.SetupInf + * Init USetupData.RequiredPartitionDiskSpace * Init IsUnattendedSetup * If unattended, init *List and sets the Codepage * If unattended, init SelectedLanguageId - * If unattended, init LanguageId + * If unattended, init USetupData.LanguageId * * RETURNS * Number of the next page. @@ -797,129 +629,71 @@ LanguagePage(PINPUT_RECORD Ir) static PAGE_NUMBER SetupStartPage(PINPUT_RECORD Ir) { - NTSTATUS Status; - WCHAR FileNameBuffer[MAX_PATH]; - INFCONTEXT Context; - PWCHAR Value; - UINT ErrorLine; + ULONG Error; PGENERIC_LIST_ENTRY ListEntry; - INT IntValue; + PCWSTR LocaleId; CONSOLE_SetStatusText(MUIGetString(STRING_PLEASEWAIT)); - /* Get the source path and source root path */ - Status = GetSourcePaths(&SourcePath, - &SourceRootPath, - &SourceRootDir); - if (!NT_SUCCESS(Status)) - { - CONSOLE_PrintTextXY(6, 15, "GetSourcePaths() failed (Status 0x%08lx)", Status); - MUIDisplayError(ERROR_NO_SOURCE_DRIVE, Ir, POPUP_WAIT_ENTER); - return QUIT_PAGE; - } - 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); - - if (SetupInf == INVALID_HANDLE_VALUE) - { - MUIDisplayError(ERROR_LOAD_TXTSETUPSIF, Ir, POPUP_WAIT_ENTER); - return QUIT_PAGE; - } - - /* Open 'Version' section */ - if (!SetupFindFirstLineW(SetupInf, L"Version", L"Signature", &Context)) - { - MUIDisplayError(ERROR_CORRUPT_TXTSETUPSIF, Ir, POPUP_WAIT_ENTER); - return QUIT_PAGE; - } - - /* Get pointer 'Signature' key */ - if (!INF_GetData(&Context, NULL, &Value)) - { - MUIDisplayError(ERROR_CORRUPT_TXTSETUPSIF, Ir, POPUP_WAIT_ENTER); - return QUIT_PAGE; - } - - /* Check 'Signature' string */ - if (_wcsicmp(Value, L"$ReactOS$") != 0) - { - MUIDisplayError(ERROR_SIGNATURE_TXTSETUPSIF, Ir, POPUP_WAIT_ENTER); - return QUIT_PAGE; - } - - /* Open 'DiskSpaceRequirements' section */ - if (!SetupFindFirstLineW(SetupInf, L"DiskSpaceRequirements", L"FreeSysPartDiskSpace", &Context)) + /* Initialize Setup, phase 1 */ + Error = InitializeSetup(&USetupData, 1); + if (Error != ERROR_SUCCESS) { - MUIDisplayError(ERROR_CORRUPT_TXTSETUPSIF, Ir, POPUP_WAIT_ENTER); + MUIDisplayError(Error, Ir, POPUP_WAIT_ENTER); return QUIT_PAGE; } - /* Get the 'FreeSysPartDiskSpace' value */ - if (!SetupGetIntField(&Context, 1, &IntValue)) - { - MUIDisplayError(ERROR_CORRUPT_TXTSETUPSIF, Ir, POPUP_WAIT_ENTER); - return QUIT_PAGE; - } - - RequiredPartitionDiskSpace = (ULONG)IntValue; - /* Start the PnP thread */ - if (hPnpThread != INVALID_HANDLE_VALUE) + if (hPnpThread != NULL) { NtResumeThread(hPnpThread, NULL); - hPnpThread = INVALID_HANDLE_VALUE; + hPnpThread = NULL; } - CheckUnattendedSetup(); + CheckUnattendedSetup(&USetupData); if (IsUnattendedSetup) { // TODO: Read options from inf - ComputerList = CreateComputerTypeList(SetupInf); - DisplayList = CreateDisplayDriverList(SetupInf); - KeyboardList = CreateKeyboardDriverList(SetupInf); - LayoutList = CreateKeyboardLayoutList(SetupInf, DefaultKBLayout); - LanguageList = CreateLanguageList(SetupInf, DefaultLanguage); + /* Load the hardware, language and keyboard layout lists */ + + USetupData.ComputerList = CreateComputerTypeList(USetupData.SetupInf); + USetupData.DisplayList = CreateDisplayDriverList(USetupData.SetupInf); + USetupData.KeyboardList = CreateKeyboardDriverList(USetupData.SetupInf); + + USetupData.LanguageList = CreateLanguageList(USetupData.SetupInf, DefaultLanguage); /* new part */ - wcscpy(SelectedLanguageId, LocaleID); - LanguageId = (LANGID)(wcstol(SelectedLanguageId, NULL, 16) & 0xFFFF); + SelectedLanguageId = DefaultLanguage; + wcscpy(DefaultLanguage, USetupData.LocaleID); + USetupData.LanguageId = (LANGID)(wcstol(SelectedLanguageId, NULL, 16) & 0xFFFF); + + USetupData.LayoutList = CreateKeyboardLayoutList(USetupData.SetupInf, SelectedLanguageId, DefaultKBLayout); /* first we hack LanguageList */ - ListEntry = GetFirstListEntry(LanguageList); - while (ListEntry != NULL) + for (ListEntry = GetFirstListEntry(USetupData.LanguageList); ListEntry; + ListEntry = GetNextListEntry(ListEntry)) { - if (!wcsicmp(LocaleID, GetListEntryUserData(ListEntry))) + LocaleId = ((PGENENTRY)GetListEntryData(ListEntry))->Id; + if (!wcsicmp(USetupData.LocaleID, LocaleId)) { - DPRINT("found %S in LanguageList\n",GetListEntryUserData(ListEntry)); - SetCurrentListEntry(LanguageList, ListEntry); + DPRINT("found %S in LanguageList\n", LocaleId); + SetCurrentListEntry(USetupData.LanguageList, ListEntry); break; } - - ListEntry = GetNextListEntry(ListEntry); } /* now LayoutList */ - ListEntry = GetFirstListEntry(LayoutList); - while (ListEntry != NULL) + for (ListEntry = GetFirstListEntry(USetupData.LayoutList); ListEntry; + ListEntry = GetNextListEntry(ListEntry)) { - if (!wcsicmp(LocaleID, GetListEntryUserData(ListEntry))) + LocaleId = ((PGENENTRY)GetListEntryData(ListEntry))->Id; + if (!wcsicmp(USetupData.LocaleID, LocaleId)) { - DPRINT("found %S in LayoutList\n",GetListEntryUserData(ListEntry)); - SetCurrentListEntry(LayoutList, ListEntry); + DPRINT("found %S in LayoutList\n", LocaleId); + SetCurrentListEntry(USetupData.LayoutList, ListEntry); break; } - - ListEntry = GetNextListEntry(ListEntry); } SetConsoleCodePage(); @@ -937,6 +711,7 @@ SetupStartPage(PINPUT_RECORD Ir) * Next pages: * InstallIntroPage (default) * RepairIntroPage + * RecoveryPage * LicensePage * QuitPage * @@ -955,7 +730,7 @@ WelcomePage(PINPUT_RECORD Ir) if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) && (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */ { - if (ConfirmQuit(Ir) != FALSE) + if (ConfirmQuit(Ir)) return QUIT_PAGE; break; @@ -966,7 +741,7 @@ WelcomePage(PINPUT_RECORD Ir) } 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 */ { @@ -1051,84 +826,227 @@ RepairIntroPage(PINPUT_RECORD Ir) } /* - * Displays the InstallIntroPage. + * Displays the UpgradeRepairPage. * * Next pages: - * DeviceSettingsPage (At once if repair or update is selected) - * SelectPartitionPage (At once if unattended setup) - * DeviceSettingsPage (default) - * QuitPage + * RebootPage (default) + * InstallIntroPage + * RecoveryPage + * WelcomePage * * RETURNS * Number of the next page. */ static PAGE_NUMBER -InstallIntroPage(PINPUT_RECORD Ir) +UpgradeRepairPage(PINPUT_RECORD Ir) { - if (RepairUpdateFlag) - { - //return SELECT_PARTITION_PAGE; - return DEVICE_SETTINGS_PAGE; - } - - if (IsUnattendedSetup) - return SELECT_PARTITION_PAGE; - - MUIDisplayPage(INSTALL_INTRO_PAGE); + GENERIC_LIST_UI ListUi; - while (TRUE) +/*** HACK!! ***/ + if (PartitionList == NULL) { - CONSOLE_ConInKey(Ir); - - if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) && - (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */ + PartitionList = CreatePartitionList(); + if (PartitionList == NULL) { - if (ConfirmQuit(Ir) != FALSE) - return QUIT_PAGE; - - break; + /* FIXME: show an error dialog */ + MUIDisplayError(ERROR_DRIVE_INFORMATION, Ir, POPUP_WAIT_ENTER); + return QUIT_PAGE; } - else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */ + else if (IsListEmpty(&PartitionList->DiskListHead)) { - return DEVICE_SETTINGS_PAGE; - // return SCSI_CONTROLLER_PAGE; + MUIDisplayError(ERROR_NO_HDD, Ir, POPUP_WAIT_ENTER); + return QUIT_PAGE; } - } - return INSTALL_INTRO_PAGE; -} + TempPartition = NULL; + FormatState = Start; + } +/**************/ + NtOsInstallsList = CreateNTOSInstallationsList(PartitionList); + if (!NtOsInstallsList) + DPRINT1("Failed to get a list of NTOS installations; continue installation...\n"); -#if 0 -static PAGE_NUMBER -ScsiControllerPage(PINPUT_RECORD Ir) -{ - // MUIDisplayPage(SCSI_CONTROLLER_PAGE); + /* + * If there is no available installation (or just a single one??) that can + * be updated in the list, just continue with the regular installation. + */ + if (!NtOsInstallsList || GetNumberOfListEntries(NtOsInstallsList) == 0) + { + RepairUpdateFlag = FALSE; - CONSOLE_SetTextXY(6, 8, "Setup detected the following mass storage devices:"); + // return INSTALL_INTRO_PAGE; + return DEVICE_SETTINGS_PAGE; + // return SCSI_CONTROLLER_PAGE; + } - /* FIXME: print loaded mass storage driver descriptions */ -#if 0 - CONSOLE_SetTextXY(8, 10, "TEST device"); -#endif + MUIDisplayPage(UPGRADE_REPAIR_PAGE); - CONSOLE_SetStatusText(" ENTER = Continue F3 = Quit"); + InitGenericListUi(&ListUi, NtOsInstallsList, GetNTOSInstallationName); + DrawGenericList(&ListUi, + 2, 23, + xScreen - 3, + yScreen - 3); + // return HandleGenericList(&ListUi, DEVICE_SETTINGS_PAGE, Ir); while (TRUE) { CONSOLE_ConInKey(Ir); - if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) && - (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */ + if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) { - if (ConfirmQuit(Ir) != FALSE) - return QUIT_PAGE; + 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)) + return QUIT_PAGE; + else + RedrawGenericList(&ListUi); + break; + } + case VK_ESCAPE: /* ESC */ + { + RestoreGenericListUiState(&ListUi); + // return nextPage; // prevPage; - break; + // return INSTALL_INTRO_PAGE; + return DEVICE_SETTINGS_PAGE; + // return SCSI_CONTROLLER_PAGE; + } + } } - else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */ + else { - return DEVICE_SETTINGS_PAGE; + // 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 */ + ASSERT(GetNumberOfListEntries(NtOsInstallsList) >= 1); + + CurrentInstallation = + (PNTOS_INSTALLATION)GetListEntryData(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. + * + * Next pages: + * DeviceSettingsPage (At once if repair or update is selected) + * SelectPartitionPage (At once if unattended setup) + * DeviceSettingsPage (default) + * QuitPage + * + * RETURNS + * Number of the next page. + */ +static PAGE_NUMBER +InstallIntroPage(PINPUT_RECORD Ir) +{ + if (RepairUpdateFlag) + { +#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) + return SELECT_PARTITION_PAGE; + + MUIDisplayPage(INSTALL_INTRO_PAGE); + + while (TRUE) + { + CONSOLE_ConInKey(Ir); + + if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) && + (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */ + { + if (ConfirmQuit(Ir)) + return QUIT_PAGE; + + break; + } + else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */ + { + return UPGRADE_REPAIR_PAGE; + } + } + + return INSTALL_INTRO_PAGE; +} + + +#if 0 +static PAGE_NUMBER +ScsiControllerPage(PINPUT_RECORD Ir) +{ + // MUIDisplayPage(SCSI_CONTROLLER_PAGE); + + CONSOLE_SetTextXY(6, 8, "Setup detected the following mass storage devices:"); + + /* FIXME: print loaded mass storage driver descriptions */ +#if 0 + CONSOLE_SetTextXY(8, 10, "TEST device"); +#endif + + CONSOLE_SetStatusText(" ENTER = Continue F3 = Quit"); + + while (TRUE) + { + CONSOLE_ConInKey(Ir); + + if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) && + (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */ + { + if (ConfirmQuit(Ir)) + return QUIT_PAGE; + + break; + } + else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */ + { + return DEVICE_SETTINGS_PAGE; } } @@ -1153,7 +1071,7 @@ OemDriverPage(PINPUT_RECORD Ir) if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) && (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */ { - if (ConfirmQuit(Ir) == TRUE) + if (ConfirmQuit(Ir)) return QUIT_PAGE; break; @@ -1182,10 +1100,10 @@ OemDriverPage(PINPUT_RECORD Ir) * QuitPage * * SIDEEFFECTS - * Init ComputerList - * Init DisplayList - * Init KeyboardList - * Init LayoutList + * Init USetupData.ComputerList + * Init USetupData.DisplayList + * Init USetupData.KeyboardList + * Init USetupData.LayoutList * * RETURNS * Number of the next page. @@ -1196,10 +1114,10 @@ DeviceSettingsPage(PINPUT_RECORD Ir) static ULONG Line = 16; /* Initialize the computer settings list */ - if (ComputerList == NULL) + if (USetupData.ComputerList == NULL) { - ComputerList = CreateComputerTypeList(SetupInf); - if (ComputerList == NULL) + USetupData.ComputerList = CreateComputerTypeList(USetupData.SetupInf); + if (USetupData.ComputerList == NULL) { MUIDisplayError(ERROR_LOAD_COMPUTER, Ir, POPUP_WAIT_ENTER); return QUIT_PAGE; @@ -1207,10 +1125,10 @@ DeviceSettingsPage(PINPUT_RECORD Ir) } /* Initialize the display settings list */ - if (DisplayList == NULL) + if (USetupData.DisplayList == NULL) { - DisplayList = CreateDisplayDriverList(SetupInf); - if (DisplayList == NULL) + USetupData.DisplayList = CreateDisplayDriverList(USetupData.SetupInf); + if (USetupData.DisplayList == NULL) { MUIDisplayError(ERROR_LOAD_DISPLAY, Ir, POPUP_WAIT_ENTER); return QUIT_PAGE; @@ -1218,10 +1136,10 @@ DeviceSettingsPage(PINPUT_RECORD Ir) } /* Initialize the keyboard settings list */ - if (KeyboardList == NULL) + if (USetupData.KeyboardList == NULL) { - KeyboardList = CreateKeyboardDriverList(SetupInf); - if (KeyboardList == NULL) + USetupData.KeyboardList = CreateKeyboardDriverList(USetupData.SetupInf); + if (USetupData.KeyboardList == NULL) { MUIDisplayError(ERROR_LOAD_KEYBOARD, Ir, POPUP_WAIT_ENTER); return QUIT_PAGE; @@ -1229,10 +1147,10 @@ DeviceSettingsPage(PINPUT_RECORD Ir) } /* Initialize the keyboard layout list */ - if (LayoutList == NULL) + if (USetupData.LayoutList == NULL) { - LayoutList = CreateKeyboardLayoutList(SetupInf, DefaultKBLayout); - if (LayoutList == NULL) + USetupData.LayoutList = CreateKeyboardLayoutList(USetupData.SetupInf, SelectedLanguageId, DefaultKBLayout); + if (USetupData.LayoutList == NULL) { /* FIXME: report error */ MUIDisplayError(ERROR_LOAD_KBLAYOUT, Ir, POPUP_WAIT_ENTER); @@ -1248,10 +1166,10 @@ DeviceSettingsPage(PINPUT_RECORD Ir) MUIDisplayPage(DEVICE_SETTINGS_PAGE); - CONSOLE_SetTextXY(25, 11, GetListEntryText(GetCurrentListEntry(ComputerList))); - CONSOLE_SetTextXY(25, 12, GetListEntryText(GetCurrentListEntry(DisplayList))); - CONSOLE_SetTextXY(25, 13, GetListEntryText(GetCurrentListEntry(KeyboardList))); - CONSOLE_SetTextXY(25, 14, GetListEntryText(GetCurrentListEntry(LayoutList))); + DrawGenericListCurrentItem(USetupData.ComputerList, GetSettingDescription, 25, 11); + DrawGenericListCurrentItem(USetupData.DisplayList , GetSettingDescription, 25, 12); + DrawGenericListCurrentItem(USetupData.KeyboardList, GetSettingDescription, 25, 13); + DrawGenericListCurrentItem(USetupData.LayoutList , GetSettingDescription, 25, 14); CONSOLE_InvertTextXY(24, Line, 48, 1); @@ -1290,7 +1208,7 @@ DeviceSettingsPage(PINPUT_RECORD Ir) else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) && (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */ { - if (ConfirmQuit(Ir) != FALSE) + if (ConfirmQuit(Ir)) return QUIT_PAGE; break; @@ -1354,7 +1272,7 @@ HandleGenericList(PGENERIC_LIST_UI ListUi, else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) && (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */ { - if (ConfirmQuit(Ir) != FALSE) + if (ConfirmQuit(Ir)) return QUIT_PAGE; else RedrawGenericList(ListUi); @@ -1362,7 +1280,7 @@ HandleGenericList(PGENERIC_LIST_UI ListUi, else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) && (Ir->Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE)) /* ESC */ { - RestoreGenericListState(ListUi->List); + RestoreGenericListUiState(ListUi); return nextPage; // Use some "prevPage;" instead? } else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */ @@ -1394,15 +1312,12 @@ ComputerSettingsPage(PINPUT_RECORD Ir) GENERIC_LIST_UI ListUi; MUIDisplayPage(COMPUTER_SETTINGS_PAGE); - InitGenericListUi(&ListUi, ComputerList); + InitGenericListUi(&ListUi, USetupData.ComputerList, GetSettingDescription); DrawGenericList(&ListUi, - 2, - 18, + 2, 18, xScreen - 3, yScreen - 3); - SaveGenericListState(ComputerList); - return HandleGenericList(&ListUi, DEVICE_SETTINGS_PAGE, Ir); } @@ -1423,15 +1338,12 @@ DisplaySettingsPage(PINPUT_RECORD Ir) GENERIC_LIST_UI ListUi; MUIDisplayPage(DISPLAY_SETTINGS_PAGE); - InitGenericListUi(&ListUi, DisplayList); + InitGenericListUi(&ListUi, USetupData.DisplayList, GetSettingDescription); DrawGenericList(&ListUi, - 2, - 18, + 2, 18, xScreen - 3, yScreen - 3); - SaveGenericListState(DisplayList); - return HandleGenericList(&ListUi, DEVICE_SETTINGS_PAGE, Ir); } @@ -1452,15 +1364,12 @@ KeyboardSettingsPage(PINPUT_RECORD Ir) GENERIC_LIST_UI ListUi; MUIDisplayPage(KEYBOARD_SETTINGS_PAGE); - InitGenericListUi(&ListUi, KeyboardList); + InitGenericListUi(&ListUi, USetupData.KeyboardList, GetSettingDescription); DrawGenericList(&ListUi, - 2, - 18, + 2, 18, xScreen - 3, yScreen - 3); - SaveGenericListState(KeyboardList); - return HandleGenericList(&ListUi, DEVICE_SETTINGS_PAGE, Ir); } @@ -1481,15 +1390,12 @@ LayoutSettingsPage(PINPUT_RECORD Ir) GENERIC_LIST_UI ListUi; MUIDisplayPage(LAYOUT_SETTINGS_PAGE); - InitGenericListUi(&ListUi, LayoutList); + InitGenericListUi(&ListUi, USetupData.LayoutList, GetSettingDescription); DrawGenericList(&ListUi, - 2, - 18, + 2, 18, xScreen - 3, yScreen - 3); - SaveGenericListState(LayoutList); - return HandleGenericList(&ListUi, DEVICE_SETTINGS_PAGE, Ir); } @@ -1500,12 +1406,12 @@ IsDiskSizeValid(PPARTENTRY PartEntry) ULONGLONG size; size = PartEntry->SectorCount.QuadPart * PartEntry->DiskEntry->BytesPerSector; - size = (size + 524288) / 1048576; /* in MBytes */ + size = (size + (512 * KB)) / MB; /* in MBytes */ - if (size < RequiredPartitionDiskSpace) + if (size < USetupData.RequiredPartitionDiskSpace) { /* 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); + DPRINT1("Partition is too small (size: %I64u MB), required disk space is %lu MB\n", size, USetupData.RequiredPartitionDiskSpace); return FALSE; } else @@ -1559,6 +1465,20 @@ SelectPartitionPage(PINPUT_RECORD Ir) 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, @@ -1570,9 +1490,11 @@ SelectPartitionPage(PINPUT_RECORD Ir) if (IsUnattendedSetup) { - if (!SelectPartition(PartitionList, UnattendDestinationDiskNumber, UnattendDestinationPartitionNumber)) + if (!SelectPartition(PartitionList, + USetupData.DestinationDiskNumber, + USetupData.DestinationPartitionNumber)) { - if (AutoPartition) + if (USetupData.AutoPartition) { if (PartitionList->CurrentPartition->LogicalPartition) { @@ -1591,7 +1513,7 @@ SelectPartitionPage(PINPUT_RECORD Ir) if (!IsDiskSizeValid(PartitionList->CurrentPartition)) { MUIDisplayError(ERROR_INSUFFICIENT_PARTITION_SIZE, Ir, POPUP_WAIT_ANY_KEY, - RequiredPartitionDiskSpace); + USetupData.RequiredPartitionDiskSpace); return SELECT_PARTITION_PAGE; /* let the user select another partition */ } @@ -1606,7 +1528,7 @@ SelectPartitionPage(PINPUT_RECORD Ir) if (!IsDiskSizeValid(PartitionList->CurrentPartition)) { MUIDisplayError(ERROR_INSUFFICIENT_PARTITION_SIZE, Ir, POPUP_WAIT_ANY_KEY, - RequiredPartitionDiskSpace); + USetupData.RequiredPartitionDiskSpace); return SELECT_PARTITION_PAGE; /* let the user select another partition */ } @@ -1656,7 +1578,7 @@ SelectPartitionPage(PINPUT_RECORD Ir) if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) && (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */ { - if (ConfirmQuit(Ir) != FALSE) + if (ConfirmQuit(Ir)) { DestroyPartitionList(PartitionList); PartitionList = NULL; @@ -1700,7 +1622,7 @@ SelectPartitionPage(PINPUT_RECORD Ir) if (!IsDiskSizeValid(PartitionList->CurrentPartition)) { MUIDisplayError(ERROR_INSUFFICIENT_PARTITION_SIZE, Ir, POPUP_WAIT_ANY_KEY, - RequiredPartitionDiskSpace); + USetupData.RequiredPartitionDiskSpace); return SELECT_PARTITION_PAGE; /* let the user select another partition */ } @@ -1736,7 +1658,7 @@ SelectPartitionPage(PINPUT_RECORD Ir) } else if (Ir->Event.KeyEvent.wVirtualKeyCode == 'L') /* L */ { - if (PartitionList->CurrentPartition->LogicalPartition != FALSE) + if (PartitionList->CurrentPartition->LogicalPartition) { Error = LogicalPartitionCreationChecks(PartitionList); if (Error != NOT_AN_ERROR) @@ -1750,12 +1672,34 @@ SelectPartitionPage(PINPUT_RECORD Ir) } else if (Ir->Event.KeyEvent.wVirtualKeyCode == 'D') /* D */ { + WCHAR PathBuffer[MAX_PATH]; + UNICODE_STRING CurrentPartition; + if (PartitionList->CurrentPartition->IsPartitioned == FALSE) { MUIDisplayError(ERROR_DELETE_SPACE, Ir, POPUP_WAIT_ANY_KEY); return SELECT_PARTITION_PAGE; } + RtlStringCchPrintfW(PathBuffer, ARRAYSIZE(PathBuffer), + L"\\Device\\Harddisk%lu\\Partition%lu\\", + PartitionList->CurrentDisk->DiskNumber, + PartitionList->CurrentPartition->PartitionNumber); + RtlInitUnicodeString(&CurrentPartition, PathBuffer); + + /* + * Check whether the user attempts to delete the partition on which + * the installation source is present. If so, fail with an error. + */ + // &USetupData.SourceRootPath + if (RtlPrefixUnicodeString(&CurrentPartition, &USetupData.SourcePath, TRUE)) + { + PopupError("You cannot delete the partition containing the installation source!", + MUIGetString(STRING_CONTINUE), + Ir, POPUP_WAIT_ENTER); + return SELECT_PARTITION_PAGE; + } + if (PartitionList->CurrentPartition->BootIndicator || PartitionList->CurrentPartition == PartitionList->SystemPartition) { @@ -1999,15 +1943,15 @@ CreatePrimaryPartitionPage(PINPUT_RECORD Ir) DiskSize = DiskEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector; #if 0 - if (DiskSize >= 10737418240) /* 10 GB */ + if (DiskSize >= 10 * GB) /* 10 GB */ { - DiskSize = DiskSize / 1073741824; + DiskSize = DiskSize / GB; Unit = MUIGetString(STRING_GB); } else #endif { - DiskSize = DiskSize / 1048576; + DiskSize = DiskSize / MB; if (DiskSize == 0) DiskSize = 1; @@ -2044,7 +1988,7 @@ CreatePrimaryPartitionPage(PINPUT_RECORD Ir) #if 0 CONSOLE_PrintTextXY(8, 10, "Maximum size of the new partition is %I64u MB", - PartitionList->CurrentPartition->SectorCount * DiskEntry->BytesPerSector / 1048576); + PartitionList->CurrentPartition->SectorCount * DiskEntry->BytesPerSector / MB); #endif CONSOLE_SetStatusText(MUIGetString(STRING_CREATEPARTITION)); @@ -2052,7 +1996,7 @@ CreatePrimaryPartitionPage(PINPUT_RECORD Ir) PartEntry = PartitionList->CurrentPartition; while (TRUE) { - MaxSize = (PartEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector) / 1048576; /* in MBytes (rounded) */ + MaxSize = (PartEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector) / MB; /* in MBytes (rounded) */ if (MaxSize > PARTITION_MAXSIZE) MaxSize = PARTITION_MAXSIZE; @@ -2060,14 +2004,14 @@ CreatePrimaryPartitionPage(PINPUT_RECORD Ir) ShowPartitionSizeInputBox(12, 14, xScreen - 12, 17, /* left, top, right, bottom */ MaxSize, InputBuffer, &Quit, &Cancel); - if (Quit != FALSE) + if (Quit) { - if (ConfirmQuit(Ir) != FALSE) + if (ConfirmQuit(Ir)) return QUIT_PAGE; break; } - else if (Cancel != FALSE) + else if (Cancel) { return SELECT_PARTITION_PAGE; } @@ -2096,7 +2040,7 @@ CreatePrimaryPartitionPage(PINPUT_RECORD Ir) else { /* Calculate the sector count from the size in MB */ - SectorCount = PartSize * 1048576 / DiskEntry->BytesPerSector; + SectorCount = PartSize * MB / DiskEntry->BytesPerSector; /* But never get larger than the unpartitioned disk space */ if (SectorCount > PartEntry->SectorCount.QuadPart) @@ -2158,15 +2102,15 @@ CreateExtendedPartitionPage(PINPUT_RECORD Ir) DiskSize = DiskEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector; #if 0 - if (DiskSize >= 10737418240) /* 10 GB */ + if (DiskSize >= 10 * GB) /* 10 GB */ { - DiskSize = DiskSize / 1073741824; + DiskSize = DiskSize / GB; Unit = MUIGetString(STRING_GB); } else #endif { - DiskSize = DiskSize / 1048576; + DiskSize = DiskSize / MB; if (DiskSize == 0) DiskSize = 1; @@ -2203,7 +2147,7 @@ CreateExtendedPartitionPage(PINPUT_RECORD Ir) #if 0 CONSOLE_PrintTextXY(8, 10, "Maximum size of the new partition is %I64u MB", - PartitionList->CurrentPartition->SectorCount * DiskEntry->BytesPerSector / 1048576); + PartitionList->CurrentPartition->SectorCount * DiskEntry->BytesPerSector / MB); #endif CONSOLE_SetStatusText(MUIGetString(STRING_CREATEPARTITION)); @@ -2211,7 +2155,7 @@ CreateExtendedPartitionPage(PINPUT_RECORD Ir) PartEntry = PartitionList->CurrentPartition; while (TRUE) { - MaxSize = (PartEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector) / 1048576; /* in MBytes (rounded) */ + MaxSize = (PartEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector) / MB; /* in MBytes (rounded) */ if (MaxSize > PARTITION_MAXSIZE) MaxSize = PARTITION_MAXSIZE; @@ -2219,14 +2163,14 @@ CreateExtendedPartitionPage(PINPUT_RECORD Ir) ShowPartitionSizeInputBox(12, 14, xScreen - 12, 17, /* left, top, right, bottom */ MaxSize, InputBuffer, &Quit, &Cancel); - if (Quit != FALSE) + if (Quit) { - if (ConfirmQuit(Ir) != FALSE) + if (ConfirmQuit(Ir)) return QUIT_PAGE; break; } - else if (Cancel != FALSE) + else if (Cancel) { return SELECT_PARTITION_PAGE; } @@ -2255,7 +2199,7 @@ CreateExtendedPartitionPage(PINPUT_RECORD Ir) else { /* Calculate the sector count from the size in MB */ - SectorCount = PartSize * 1048576 / DiskEntry->BytesPerSector; + SectorCount = PartSize * MB / DiskEntry->BytesPerSector; /* But never get larger than the unpartitioned disk space */ if (SectorCount > PartEntry->SectorCount.QuadPart) @@ -2316,15 +2260,15 @@ CreateLogicalPartitionPage(PINPUT_RECORD Ir) DiskSize = DiskEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector; #if 0 - if (DiskSize >= 10737418240) /* 10 GB */ + if (DiskSize >= 10 * GB) /* 10 GB */ { - DiskSize = DiskSize / 1073741824; + DiskSize = DiskSize / GB; Unit = MUIGetString(STRING_GB); } else #endif { - DiskSize = DiskSize / 1048576; + DiskSize = DiskSize / MB; if (DiskSize == 0) DiskSize = 1; @@ -2361,7 +2305,7 @@ CreateLogicalPartitionPage(PINPUT_RECORD Ir) #if 0 CONSOLE_PrintTextXY(8, 10, "Maximum size of the new partition is %I64u MB", - PartitionList->CurrentPartition->SectorCount * DiskEntry->BytesPerSector / 1048576); + PartitionList->CurrentPartition->SectorCount * DiskEntry->BytesPerSector / MB); #endif CONSOLE_SetStatusText(MUIGetString(STRING_CREATEPARTITION)); @@ -2369,7 +2313,7 @@ CreateLogicalPartitionPage(PINPUT_RECORD Ir) PartEntry = PartitionList->CurrentPartition; while (TRUE) { - MaxSize = (PartEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector) / 1048576; /* in MBytes (rounded) */ + MaxSize = (PartEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector) / MB; /* in MBytes (rounded) */ if (MaxSize > PARTITION_MAXSIZE) MaxSize = PARTITION_MAXSIZE; @@ -2377,14 +2321,14 @@ CreateLogicalPartitionPage(PINPUT_RECORD Ir) ShowPartitionSizeInputBox(12, 14, xScreen - 12, 17, /* left, top, right, bottom */ MaxSize, InputBuffer, &Quit, &Cancel); - if (Quit != FALSE) + if (Quit) { - if (ConfirmQuit(Ir) != FALSE) + if (ConfirmQuit(Ir)) return QUIT_PAGE; break; } - else if (Cancel != FALSE) + else if (Cancel) { return SELECT_PARTITION_PAGE; } @@ -2413,7 +2357,7 @@ CreateLogicalPartitionPage(PINPUT_RECORD Ir) else { /* Calculate the sector count from the size in MB */ - SectorCount = PartSize * 1048576 / DiskEntry->BytesPerSector; + SectorCount = PartSize * MB / DiskEntry->BytesPerSector; /* But never get larger than the unpartitioned disk space */ if (SectorCount > PartEntry->SectorCount.QuadPart) @@ -2456,7 +2400,7 @@ ConfirmDeleteSystemPartitionPage(PINPUT_RECORD Ir) if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) && (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */ { - if (ConfirmQuit(Ir) == TRUE) + if (ConfirmQuit(Ir)) return QUIT_PAGE; break; @@ -2514,21 +2458,21 @@ DeletePartitionPage(PINPUT_RECORD Ir) PartSize = PartEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector; #if 0 - if (PartSize >= 10737418240) /* 10 GB */ + if (PartSize >= 10 * GB) /* 10 GB */ { - PartSize = PartSize / 1073741824; + PartSize = PartSize / GB; Unit = MUIGetString(STRING_GB); } else #endif - if (PartSize >= 10485760) /* 10 MB */ + if (PartSize >= 10 * MB) /* 10 MB */ { - PartSize = PartSize / 1048576; + PartSize = PartSize / MB; Unit = MUIGetString(STRING_MB); } else { - PartSize = PartSize / 1024; + PartSize = PartSize / KB; Unit = MUIGetString(STRING_KB); } @@ -2536,7 +2480,7 @@ DeletePartitionPage(PINPUT_RECORD Ir) { CONSOLE_PrintTextXY(6, 10, MUIGetString(STRING_HDDINFOUNK2), - (PartEntry->DriveLetter == 0) ? '-' : PartEntry->DriveLetter, + (PartEntry->DriveLetter == 0) ? '-' : (CHAR)PartEntry->DriveLetter, (PartEntry->DriveLetter == 0) ? '-' : ':', PartEntry->PartitionType, PartSize, @@ -2546,7 +2490,7 @@ DeletePartitionPage(PINPUT_RECORD Ir) { CONSOLE_PrintTextXY(6, 10, " %c%c %s %I64u %s", - (PartEntry->DriveLetter == 0) ? '-' : PartEntry->DriveLetter, + (PartEntry->DriveLetter == 0) ? '-' : (CHAR)PartEntry->DriveLetter, (PartEntry->DriveLetter == 0) ? '-' : ':', PartTypeString, PartSize, @@ -2555,15 +2499,15 @@ DeletePartitionPage(PINPUT_RECORD Ir) DiskSize = DiskEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector; #if 0 - if (DiskSize >= 10737418240) /* 10 GB */ + if (DiskSize >= 10 * GB) /* 10 GB */ { - DiskSize = DiskSize / 1073741824; + DiskSize = DiskSize / GB; Unit = MUIGetString(STRING_GB); } else #endif { - DiskSize = DiskSize / 1048576; + DiskSize = DiskSize / MB; if (DiskSize == 0) DiskSize = 1; @@ -2603,7 +2547,7 @@ DeletePartitionPage(PINPUT_RECORD Ir) if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) && (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */ { - if (ConfirmQuit(Ir) != FALSE) + if (ConfirmQuit(Ir)) return QUIT_PAGE; break; @@ -2629,8 +2573,8 @@ DeletePartitionPage(PINPUT_RECORD Ir) * * Next pages: * CheckFileSystemPage (At once if RepairUpdate is selected) - * CheckFileSystemPage (At once if Unattended and not UnattendFormatPartition) - * FormatPartitionPage (At once if Unattended and UnattendFormatPartition) + * CheckFileSystemPage (At once if Unattended and not USetupData.FormatPartition) + * FormatPartitionPage (At once if Unattended and USetupData.FormatPartition) * SelectPartitionPage (If the user aborts) * FormatPartitionPage (Default) * QuitPage @@ -2764,27 +2708,27 @@ SelectFileSystemPage(PINPUT_RECORD Ir) /* Adjust disk size */ DiskSize = DiskEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector; - if (DiskSize >= 10737418240) /* 10 GB */ + if (DiskSize >= 10 * GB) /* 10 GB */ { - DiskSize = DiskSize / 1073741824; + DiskSize = DiskSize / GB; DiskUnit = MUIGetString(STRING_GB); } else { - DiskSize = DiskSize / 1048576; + DiskSize = DiskSize / MB; DiskUnit = MUIGetString(STRING_MB); } /* Adjust partition size */ PartSize = PartEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector; - if (PartSize >= 10737418240) /* 10 GB */ + if (PartSize >= 10 * GB) /* 10 GB */ { - PartSize = PartSize / 1073741824; + PartSize = PartSize / GB; PartUnit = MUIGetString(STRING_GB); } else { - PartSize = PartSize / 1048576; + PartSize = PartSize / MB; PartUnit = MUIGetString(STRING_MB); } @@ -2793,7 +2737,9 @@ SelectFileSystemPage(PINPUT_RECORD Ir) PartTypeString, ARRAYSIZE(PartTypeString)); - if (PartEntry->AutoCreate != FALSE) + MUIDisplayPage(SELECT_FILE_SYSTEM_PAGE); + + if (PartEntry->AutoCreate) { CONSOLE_SetTextXY(6, 8, MUIGetString(STRING_NEWPARTITION)); @@ -2819,7 +2765,7 @@ SelectFileSystemPage(PINPUT_RECORD Ir) PartEntry->AutoCreate = FALSE; } - else if (PartEntry->New != FALSE) + else if (PartEntry->New) { switch (FormatState) { @@ -2849,7 +2795,7 @@ SelectFileSystemPage(PINPUT_RECORD Ir) { CONSOLE_PrintTextXY(8, 10, MUIGetString(STRING_HDDINFOUNK4), - (PartEntry->DriveLetter == 0) ? '-' : PartEntry->DriveLetter, + (PartEntry->DriveLetter == 0) ? '-' : (CHAR)PartEntry->DriveLetter, (PartEntry->DriveLetter == 0) ? '-' : ':', PartEntry->PartitionType, PartSize, @@ -2859,7 +2805,7 @@ SelectFileSystemPage(PINPUT_RECORD Ir) { CONSOLE_PrintTextXY(8, 10, "%c%c %s %I64u %s", - (PartEntry->DriveLetter == 0) ? '-' : PartEntry->DriveLetter, + (PartEntry->DriveLetter == 0) ? '-' : (CHAR)PartEntry->DriveLetter, (PartEntry->DriveLetter == 0) ? '-' : ':', PartTypeString, PartSize, @@ -2877,8 +2823,6 @@ SelectFileSystemPage(PINPUT_RECORD Ir) DiskEntry->NoMbr ? "GPT" : "MBR"); } - MUIDisplayPage(SELECT_FILE_SYSTEM_PAGE); - if (FileSystemList == NULL) { /* Create the file system list, and by default select the "FAT" file system */ @@ -2898,7 +2842,7 @@ SelectFileSystemPage(PINPUT_RECORD Ir) if (IsUnattendedSetup) { - if (UnattendFormatPartition) + if (USetupData.FormatPartition) { /* * We use whatever currently selected file system we have @@ -2922,7 +2866,7 @@ SelectFileSystemPage(PINPUT_RECORD Ir) if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) && (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */ { - if (ConfirmQuit(Ir) != FALSE) + if (ConfirmQuit(Ir)) return QUIT_PAGE; break; @@ -2968,7 +2912,7 @@ SelectFileSystemPage(PINPUT_RECORD Ir) * * SIDEEFFECTS * Sets PartitionList->CurrentPartition->FormatState - * Sets DestinationRootPath + * Sets USetupData.DestinationRootPath * * RETURNS * Number of the next page. @@ -2976,12 +2920,13 @@ SelectFileSystemPage(PINPUT_RECORD Ir) static PAGE_NUMBER FormatPartitionPage(PINPUT_RECORD Ir) { - UNICODE_STRING PartitionRootPath; - WCHAR PathBuffer[MAX_PATH]; + NTSTATUS Status; PDISKENTRY DiskEntry; PPARTENTRY PartEntry; PFILE_SYSTEM_ITEM SelectedFileSystem; - NTSTATUS Status; + UNICODE_STRING PartitionRootPath; + WCHAR PathBuffer[MAX_PATH]; + CHAR Buffer[MAX_PATH]; #ifndef NDEBUG ULONG Line; @@ -3014,7 +2959,7 @@ FormatPartitionPage(PINPUT_RECORD Ir) if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) && (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */ { - if (ConfirmQuit(Ir) != FALSE) + if (ConfirmQuit(Ir)) return QUIT_PAGE; break; @@ -3065,7 +3010,7 @@ FormatPartitionPage(PINPUT_RECORD Ir) } /* Set PartitionRootPath */ - StringCchPrintfW(PathBuffer, ARRAYSIZE(PathBuffer), + RtlStringCchPrintfW(PathBuffer, ARRAYSIZE(PathBuffer), L"\\Device\\Harddisk%lu\\Partition%lu", DiskEntry->DiskNumber, PartEntry->PartitionNumber); @@ -3077,7 +3022,38 @@ FormatPartitionPage(PINPUT_RECORD Ir) { Status = FormatPartition(&PartitionRootPath, SelectedFileSystem); - if (!NT_SUCCESS(Status)) + if (Status == STATUS_NOT_SUPPORTED) + { + sprintf(Buffer, + "Setup is currently unable to format a partition in %S.\n" + "\n" + " \x07 Press ENTER to continue Setup.\n" + " \x07 Press F3 to quit Setup.", + SelectedFileSystem->FileSystem->FileSystemName); + + PopupError(Buffer, + MUIGetString(STRING_QUITCONTINUE), + NULL, POPUP_WAIT_NONE); + + while (TRUE) + { + CONSOLE_ConInKey(Ir); + + if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x00 && + Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3) /* F3 */ + { + if (ConfirmQuit(Ir)) + return QUIT_PAGE; + else + return SELECT_FILE_SYSTEM_PAGE; + } + else if (Ir->Event.KeyEvent.uChar.AsciiChar == VK_RETURN) /* ENTER */ + { + return SELECT_FILE_SYSTEM_PAGE; + } + } + } + else if (!NT_SUCCESS(Status)) { DPRINT1("FormatPartition() failed with status 0x%08lx\n", Status); MUIDisplayError(ERROR_FORMATTING_PARTITION, Ir, POPUP_WAIT_ANY_KEY, PathBuffer); @@ -3118,13 +3094,13 @@ FormatPartitionPage(PINPUT_RECORD Ir) static PAGE_NUMBER CheckFileSystemPage(PINPUT_RECORD Ir) { + NTSTATUS Status; + PDISKENTRY DiskEntry; + PPARTENTRY PartEntry; PFILE_SYSTEM CurrentFileSystem; UNICODE_STRING PartitionRootPath; WCHAR PathBuffer[MAX_PATH]; CHAR Buffer[MAX_PATH]; - PDISKENTRY DiskEntry; - PPARTENTRY PartEntry; - NTSTATUS Status; if (PartitionList == NULL) { @@ -3138,7 +3114,7 @@ CheckFileSystemPage(PINPUT_RECORD Ir) } /* Set PartitionRootPath */ - StringCchPrintfW(PathBuffer, ARRAYSIZE(PathBuffer), + RtlStringCchPrintfW(PathBuffer, ARRAYSIZE(PathBuffer), L"\\Device\\Harddisk%lu\\Partition%lu", DiskEntry->DiskNumber, PartEntry->PartitionNumber); @@ -3160,7 +3136,8 @@ CheckFileSystemPage(PINPUT_RECORD Ir) return CHECK_FILE_SYSTEM_PAGE; } - if (CurrentFileSystem->ChkdskFunc == NULL) + Status = ChkdskPartition(&PartitionRootPath, CurrentFileSystem); + if (Status == STATUS_NOT_SUPPORTED) { sprintf(Buffer, "Setup is currently unable to check a partition formatted in %S.\n" @@ -3192,26 +3169,22 @@ CheckFileSystemPage(PINPUT_RECORD Ir) } } } - else + else if (!NT_SUCCESS(Status)) { - Status = ChkdskPartition(&PartitionRootPath, CurrentFileSystem); - if (!NT_SUCCESS(Status)) - { - DPRINT("ChkdskPartition() failed with status 0x%08lx\n", Status); - // sprintf(Buffer, "Setup failed to verify the selected partition.\n" - sprintf(Buffer, "ChkDsk detected some disk errors.\n" - "(Status 0x%08lx).\n", Status); - PopupError(Buffer, - // MUIGetString(STRING_REBOOTCOMPUTER), - MUIGetString(STRING_CONTINUE), - Ir, POPUP_WAIT_ENTER); - - // return QUIT_PAGE; - } + DPRINT("ChkdskPartition() failed with status 0x%08lx\n", Status); + // sprintf(Buffer, "Setup failed to verify the selected partition.\n" + sprintf(Buffer, "ChkDsk detected some disk errors.\n" + "(Status 0x%08lx).\n", Status); + PopupError(Buffer, + // MUIGetString(STRING_REBOOTCOMPUTER), + MUIGetString(STRING_CONTINUE), + Ir, POPUP_WAIT_ENTER); - PartEntry->NeedsCheck = FALSE; - return CHECK_FILE_SYSTEM_PAGE; + // return QUIT_PAGE; } + + PartEntry->NeedsCheck = FALSE; + return CHECK_FILE_SYSTEM_PAGE; } @@ -3220,38 +3193,60 @@ BuildInstallPaths(PWSTR InstallDir, PDISKENTRY DiskEntry, PPARTENTRY PartEntry) { - WCHAR PathBuffer[MAX_PATH]; - - /* Create 'InstallPath' string */ - RtlFreeUnicodeString(&InstallPath); - RtlCreateUnicodeString(&InstallPath, InstallDir); + NTSTATUS Status; - /* Create 'DestinationRootPath' string */ - RtlFreeUnicodeString(&DestinationRootPath); - StringCchPrintfW(PathBuffer, ARRAYSIZE(PathBuffer), - L"\\Device\\Harddisk%lu\\Partition%lu\\", - DiskEntry->DiskNumber, - PartEntry->PartitionNumber); - RtlCreateUnicodeString(&DestinationRootPath, PathBuffer); - DPRINT("DestinationRootPath: %wZ\n", &DestinationRootPath); - - /* Create 'DestinationPath' string */ - RtlFreeUnicodeString(&DestinationPath); - CombinePaths(PathBuffer, ARRAYSIZE(PathBuffer), 2, - DestinationRootPath.Buffer, InstallDir); - RtlCreateUnicodeString(&DestinationPath, PathBuffer); - - /* Create 'DestinationArcPath' */ - RtlFreeUnicodeString(&DestinationArcPath); - StringCchPrintfW(PathBuffer, ARRAYSIZE(PathBuffer), - L"multi(0)disk(0)rdisk(%lu)partition(%lu)\\", - DiskEntry->BiosDiskNumber, - PartEntry->PartitionNumber); - ConcatPaths(PathBuffer, ARRAYSIZE(PathBuffer), 1, InstallDir); - RtlCreateUnicodeString(&DestinationArcPath, PathBuffer); + Status = InitDestinationPaths(&USetupData, InstallDir, DiskEntry, PartEntry); + // TODO: Check Status + UNREFERENCED_PARAMETER(Status); /* Initialize DestinationDriveLetter */ - DestinationDriveLetter = (WCHAR)PartEntry->DriveLetter; + DestinationDriveLetter = PartEntry->DriveLetter; +} + + +static BOOLEAN +IsValidPath( + IN PCWSTR InstallDir) +{ + UINT i, Length; + + Length = wcslen(InstallDir); + + // TODO: Add check for 8.3 too. + + /* Path must be at least 2 characters long */ +// if (Length < 2) +// return FALSE; + + /* Path must start with a backslash */ +// if (InstallDir[0] != L'\\') +// return FALSE; + + /* Path must not end with a backslash */ + if (InstallDir[Length - 1] == L'\\') + return FALSE; + + /* Path must not contain whitespace characters */ + for (i = 0; i < Length; i++) + { + if (iswspace(InstallDir[i])) + return FALSE; + } + + /* Path component must not end with a dot */ + for (i = 0; i < Length; i++) + { + if (InstallDir[i] == L'\\' && i > 0) + { + if (InstallDir[i - 1] == L'.') + return FALSE; + } + } + + if (InstallDir[Length - 1] == L'.') + return FALSE; + + return TRUE; } @@ -3259,7 +3254,7 @@ BuildInstallPaths(PWSTR InstallDir, * Displays the InstallDirectoryPage. * * Next pages: - * PrepareCopyPage (As the direct result of InstallDirectoryPage1) + * PrepareCopyPage * QuitPage * * RETURNS @@ -3270,11 +3265,11 @@ InstallDirectoryPage(PINPUT_RECORD Ir) { PDISKENTRY DiskEntry; PPARTENTRY PartEntry; - WCHAR InstallDir[51]; + WCHAR InstallDir[MAX_PATH]; 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); @@ -3292,45 +3287,50 @@ InstallDirectoryPage(PINPUT_RECORD Ir) DiskEntry = PartitionList->CurrentDisk; PartEntry = PartitionList->CurrentPartition; -#if 0 + // if (IsUnattendedSetup) if (RepairUpdateFlag) - { - if (!IsValidPath(CurrentInstallation->PathComponent)) // SystemNtPath - { - /* FIXME: Log the error? */ - return QUIT_PAGE; - } + wcscpy(InstallDir, CurrentInstallation->PathComponent); // SystemNtPath + else if (USetupData.InstallationDirectory[0]) + wcscpy(InstallDir, USetupData.InstallationDirectory); + else + wcscpy(InstallDir, L"\\ReactOS"); - BuildInstallPaths(CurrentInstallation->PathComponent, // SystemNtPath + /* + * 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; - } -#endif - if (IsUnattendedSetup) - { - if (!IsValidPath(UnattendInstallationDirectory)) + /* + * Check whether the user attempts to install ReactOS within the + * installation source directory, or in a subdirectory thereof. + * If so, fail with an error. + */ + if (RtlPrefixUnicodeString(&USetupData.SourcePath, &USetupData.DestinationPath, TRUE)) { - /* FIXME: Log the error? */ - return QUIT_PAGE; + PopupError("You cannot install ReactOS within the installation source directory!", + MUIGetString(STRING_CONTINUE), + Ir, POPUP_WAIT_ENTER); + return INSTALL_DIRECTORY_PAGE; } - BuildInstallPaths(UnattendInstallationDirectory, - 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) { @@ -3341,7 +3341,7 @@ InstallDirectoryPage(PINPUT_RECORD Ir) { CONSOLE_SetCursorType(TRUE, FALSE); - if (ConfirmQuit(Ir) != FALSE) + if (ConfirmQuit(Ir)) return QUIT_PAGE; CONSOLE_SetCursorType(TRUE, TRUE); @@ -3410,6 +3410,19 @@ InstallDirectoryPage(PINPUT_RECORD Ir) DiskEntry, PartEntry); + /* + * Check whether the user attempts to install ReactOS within the + * installation source directory, or in a subdirectory thereof. + * If so, fail with an error. + */ + if (RtlPrefixUnicodeString(&USetupData.SourcePath, &USetupData.DestinationPath, TRUE)) + { + PopupError("You cannot install ReactOS within the installation source directory!", + MUIGetString(STRING_CONTINUE), + Ir, POPUP_WAIT_ENTER); + return INSTALL_DIRECTORY_PAGE; + } + return PREPARE_COPY_PAGE; } else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x08) /* BACKSPACE */ @@ -3426,367 +3439,57 @@ InstallDirectoryPage(PINPUT_RECORD Ir) Length--; CONSOLE_SetInputTextXY(8, 11, 51, InstallDir); CONSOLE_SetCursorXY(8 + Pos, 11); - } - } - else if (isprint(Ir->Event.KeyEvent.uChar.AsciiChar)) - { - if (Length < 50) - { - c = (WCHAR)Ir->Event.KeyEvent.uChar.AsciiChar; - if (iswalpha(c) || iswdigit(c) || c == '.' || c == '\\' || c == '-' || c == '_') - { - if (Pos < Length) - memmove(&InstallDir[Pos + 1], - &InstallDir[Pos], - (Length - Pos) * sizeof(WCHAR)); - InstallDir[Length + 1] = UNICODE_NULL; - InstallDir[Pos] = c; - - Pos++; - Length++; - CONSOLE_SetInputTextXY(8, 11, 51, InstallDir); - CONSOLE_SetCursorXY(8 + Pos, 11); - } - } - } - } - - return INSTALL_DIRECTORY_PAGE; -} - - -static BOOLEAN -AddSectionToCopyQueueCab(HINF InfFile, - PWCHAR SectionName, - PWCHAR SourceCabinet, - PCUNICODE_STRING DestinationPath, - PINPUT_RECORD Ir) -{ - INFCONTEXT FilesContext; - INFCONTEXT DirContext; - PWCHAR FileKeyName; - PWCHAR FileKeyValue; - PWCHAR DirKeyValue; - PWCHAR TargetFileName; - - /* - * This code enumerates the list of files in reactos.dff / reactos.inf - * that need to be extracted from reactos.cab and be installed in their - * respective directories. - */ - - /* Search for the SectionName section */ - if (!SetupFindFirstLineW(InfFile, SectionName, NULL, &FilesContext)) - { - CHAR Buffer[128]; - sprintf(Buffer, MUIGetString(STRING_TXTSETUPFAILED), SectionName); - PopupError(Buffer, MUIGetString(STRING_REBOOTCOMPUTER), Ir, POPUP_WAIT_ENTER); - return FALSE; - } - - /* - * Enumerate the files in the section and add them to the file queue. - */ - do - { - /* Get source file name and target directory id */ - if (!INF_GetData(&FilesContext, &FileKeyName, &FileKeyValue)) - { - /* FIXME: Handle error! */ - DPRINT1("INF_GetData() failed\n"); - break; - } - - /* Get optional target file name */ - if (!INF_GetDataField(&FilesContext, 2, &TargetFileName)) - TargetFileName = NULL; - - DPRINT("FileKeyName: '%S' FileKeyValue: '%S'\n", FileKeyName, FileKeyValue); - - /* Lookup target directory */ - if (!SetupFindFirstLineW(InfFile, L"Directories", FileKeyValue, &DirContext)) - { - /* FIXME: Handle error! */ - DPRINT1("SetupFindFirstLine() failed\n"); - break; - } - - if (!INF_GetData(&DirContext, NULL, &DirKeyValue)) - { - /* FIXME: Handle error! */ - DPRINT1("INF_GetData() failed\n"); - break; - } - - if (!SetupQueueCopy(SetupFileQueue, - SourceCabinet, - SourceRootPath.Buffer, - SourceRootDir.Buffer, - FileKeyName, - DirKeyValue, - TargetFileName)) - { - /* FIXME: Handle error! */ - DPRINT1("SetupQueueCopy() failed\n"); - } - } while (SetupFindNextLine(&FilesContext, &FilesContext)); - - return TRUE; -} - - -static BOOLEAN -AddSectionToCopyQueue(HINF InfFile, - PWCHAR SectionName, - PWCHAR SourceCabinet, - PCUNICODE_STRING DestinationPath, - PINPUT_RECORD Ir) -{ - INFCONTEXT FilesContext; - INFCONTEXT DirContext; - PWCHAR FileKeyName; - PWCHAR FileKeyValue; - PWCHAR DirKeyValue; - PWCHAR TargetFileName; - WCHAR CompleteOrigDirName[512]; // FIXME: MAX_PATH is not enough? - - if (SourceCabinet) - return AddSectionToCopyQueueCab(InfFile, L"SourceFiles", SourceCabinet, DestinationPath, Ir); - - /* - * This code enumerates the list of files in txtsetup.sif - * that need to be installed in their respective directories. - */ - - /* Search for the SectionName section */ - if (!SetupFindFirstLineW(InfFile, SectionName, NULL, &FilesContext)) - { - CHAR Buffer[128]; - sprintf(Buffer, MUIGetString(STRING_TXTSETUPFAILED), SectionName); - PopupError(Buffer, MUIGetString(STRING_REBOOTCOMPUTER), Ir, POPUP_WAIT_ENTER); - return FALSE; - } - - /* - * Enumerate the files in the section and add them to the file queue. - */ - do - { - /* Get source file name and target directory id */ - if (!INF_GetData(&FilesContext, &FileKeyName, &FileKeyValue)) - { - /* FIXME: Handle error! */ - DPRINT1("INF_GetData() failed\n"); - break; - } - - /* Get target directory id */ - if (!INF_GetDataField(&FilesContext, 13, &FileKeyValue)) - { - /* FIXME: Handle error! */ - DPRINT1("INF_GetData() failed\n"); - break; - } - - /* Get optional target file name */ - if (!INF_GetDataField(&FilesContext, 11, &TargetFileName)) - TargetFileName = NULL; - else if (!*TargetFileName) - TargetFileName = NULL; - - DPRINT("FileKeyName: '%S' FileKeyValue: '%S'\n", FileKeyName, FileKeyValue); - - /* Lookup target directory */ - if (!SetupFindFirstLineW(InfFile, L"Directories", FileKeyValue, &DirContext)) - { - /* FIXME: Handle error! */ - DPRINT1("SetupFindFirstLine() failed\n"); - break; - } - - if (!INF_GetData(&DirContext, NULL, &DirKeyValue)) - { - /* FIXME: Handle error! */ - DPRINT1("INF_GetData() failed\n"); - break; - } - - if ((DirKeyValue[0] == UNICODE_NULL) || (DirKeyValue[0] == L'\\' && DirKeyValue[1] == UNICODE_NULL)) - { - /* Installation path */ - DPRINT("InstallationPath: '%S'\n", DirKeyValue); - - StringCchCopyW(CompleteOrigDirName, ARRAYSIZE(CompleteOrigDirName), - SourceRootDir.Buffer); - - DPRINT("InstallationPath(2): '%S'\n", CompleteOrigDirName); - } - else if (DirKeyValue[0] == L'\\') - { - /* Absolute path */ - DPRINT("AbsolutePath: '%S'\n", DirKeyValue); - - StringCchCopyW(CompleteOrigDirName, ARRAYSIZE(CompleteOrigDirName), - DirKeyValue); - - DPRINT("AbsolutePath(2): '%S'\n", CompleteOrigDirName); - } - else // if (DirKeyValue[0] != L'\\') - { - /* Path relative to the installation path */ - DPRINT("RelativePath: '%S'\n", DirKeyValue); - - CombinePaths(CompleteOrigDirName, ARRAYSIZE(CompleteOrigDirName), 2, - SourceRootDir.Buffer, DirKeyValue); - - DPRINT("RelativePath(2): '%S'\n", CompleteOrigDirName); - } - - if (!SetupQueueCopy(SetupFileQueue, - SourceCabinet, - SourceRootPath.Buffer, - CompleteOrigDirName, - FileKeyName, - DirKeyValue, - TargetFileName)) - { - /* FIXME: Handle error! */ - DPRINT1("SetupQueueCopy() failed\n"); - } - } while (SetupFindNextLine(&FilesContext, &FilesContext)); - - return TRUE; -} - - -static BOOLEAN -PrepareCopyPageInfFile(HINF InfFile, - PWCHAR SourceCabinet, - PINPUT_RECORD Ir) -{ - NTSTATUS Status; - INFCONTEXT DirContext; - PWCHAR AdditionalSectionName = NULL; - PWCHAR DirKeyValue; - WCHAR PathBuffer[MAX_PATH]; - - /* Add common files */ - if (!AddSectionToCopyQueue(InfFile, L"SourceDisksFiles", SourceCabinet, &DestinationPath, Ir)) - return FALSE; - - /* Add specific files depending of computer type */ - if (SourceCabinet == NULL) - { - if (!ProcessComputerFiles(InfFile, ComputerList, &AdditionalSectionName)) - return FALSE; - - if (AdditionalSectionName) - { - if (!AddSectionToCopyQueue(InfFile, AdditionalSectionName, SourceCabinet, &DestinationPath, Ir)) - return FALSE; - } - } - - /* Create directories */ - - /* - * FIXME: - * Copying files to DestinationRootPath should be done from within - * the SystemPartitionFiles section. - * At the moment we check whether we specify paths like '\foo' or '\\' for that. - * For installing to DestinationPath specify just '\' . - */ - - /* Get destination path */ - StringCchCopyW(PathBuffer, ARRAYSIZE(PathBuffer), DestinationPath.Buffer); - - DPRINT("FullPath(1): '%S'\n", PathBuffer); - - /* Create the install directory */ - Status = SetupCreateDirectory(PathBuffer); - if (!NT_SUCCESS(Status) && Status != STATUS_OBJECT_NAME_COLLISION) - { - DPRINT1("Creating directory '%S' failed: Status = 0x%08lx\n", PathBuffer, Status); - MUIDisplayError(ERROR_CREATE_INSTALL_DIR, Ir, POPUP_WAIT_ENTER); - return FALSE; - } - - /* Search for the 'Directories' section */ - if (!SetupFindFirstLineW(InfFile, L"Directories", NULL, &DirContext)) - { - if (SourceCabinet) - { - MUIDisplayError(ERROR_CABINET_SECTION, Ir, POPUP_WAIT_ENTER); - } - else - { - MUIDisplayError(ERROR_TXTSETUP_SECTION, Ir, POPUP_WAIT_ENTER); - } - - return FALSE; - } - - /* Enumerate the directory values and create the subdirectories */ - do - { - if (!INF_GetData(&DirContext, NULL, &DirKeyValue)) - { - DPRINT1("break\n"); - break; + } } - - if ((DirKeyValue[0] == UNICODE_NULL) || (DirKeyValue[0] == L'\\' && DirKeyValue[1] == UNICODE_NULL)) + else if (isprint(Ir->Event.KeyEvent.uChar.AsciiChar)) { - /* Installation path */ - DPRINT("InstallationPath: '%S'\n", DirKeyValue); - - StringCchCopyW(PathBuffer, ARRAYSIZE(PathBuffer), - DestinationPath.Buffer); + if (Length < 50) + { + c = (WCHAR)Ir->Event.KeyEvent.uChar.AsciiChar; + if (iswalpha(c) || iswdigit(c) || c == '.' || c == '\\' || c == '-' || c == '_') + { + if (Pos < Length) + memmove(&InstallDir[Pos + 1], + &InstallDir[Pos], + (Length - Pos) * sizeof(WCHAR)); + InstallDir[Length + 1] = UNICODE_NULL; + InstallDir[Pos] = c; - DPRINT("InstallationPath(2): '%S'\n", PathBuffer); + Pos++; + Length++; + CONSOLE_SetInputTextXY(8, 11, 51, InstallDir); + CONSOLE_SetCursorXY(8 + Pos, 11); + } + } } - else if (DirKeyValue[0] == L'\\') - { - /* Absolute path */ - DPRINT("AbsolutePath: '%S'\n", DirKeyValue); - - CombinePaths(PathBuffer, ARRAYSIZE(PathBuffer), 2, - DestinationRootPath.Buffer, DirKeyValue); + } - DPRINT("AbsolutePath(2): '%S'\n", PathBuffer); + return INSTALL_DIRECTORY_PAGE; +} - Status = SetupCreateDirectory(PathBuffer); - if (!NT_SUCCESS(Status) && Status != STATUS_OBJECT_NAME_COLLISION) - { - DPRINT("Creating directory '%S' failed: Status = 0x%08lx", PathBuffer, Status); - MUIDisplayError(ERROR_CREATE_DIR, Ir, POPUP_WAIT_ENTER); - return FALSE; - } - } - else // if (DirKeyValue[0] != L'\\') - { - /* Path relative to the installation path */ - DPRINT("RelativePath: '%S'\n", DirKeyValue); - CombinePaths(PathBuffer, ARRAYSIZE(PathBuffer), 2, - DestinationPath.Buffer, DirKeyValue); +// PSETUP_ERROR_ROUTINE +static VOID +__cdecl +USetupErrorRoutine( + IN PUSETUP_DATA pSetupData, + ...) +{ + INPUT_RECORD Ir; + va_list arg_ptr; - DPRINT("RelativePath(2): '%S'\n", PathBuffer); + va_start(arg_ptr, pSetupData); - Status = SetupCreateDirectory(PathBuffer); - if (!NT_SUCCESS(Status) && Status != STATUS_OBJECT_NAME_COLLISION) - { - DPRINT("Creating directory '%S' failed: Status = 0x%08lx", PathBuffer, Status); - MUIDisplayError(ERROR_CREATE_DIR, Ir, POPUP_WAIT_ENTER); - return FALSE; - } - } - } while (SetupFindNextLine(&DirContext, &DirContext)); + if (pSetupData->LastErrorNumber >= ERROR_SUCCESS && + pSetupData->LastErrorNumber < ERROR_LAST_ERROR_CODE) + { + // Note: the "POPUP_WAIT_ENTER" actually depends on the LastErrorNumber... + MUIDisplayErrorV(pSetupData->LastErrorNumber, &Ir, POPUP_WAIT_ENTER, arg_ptr); + } - return TRUE; + va_end(arg_ptr); } - /* * Displays the PrepareCopyPage. * @@ -3795,8 +3498,7 @@ PrepareCopyPageInfFile(HINF InfFile, * QuitPage * * SIDEEFFECTS - * Inits SetupFileQueue - * Calls PrepareCopyPageInfFile + * Calls PrepareFileCopy * * RETURNS * Number of the next page. @@ -3804,98 +3506,30 @@ PrepareCopyPageInfFile(HINF InfFile, static PAGE_NUMBER PrepareCopyPage(PINPUT_RECORD Ir) { - HINF InfHandle; - WCHAR PathBuffer[MAX_PATH]; - INFCONTEXT CabinetsContext; - ULONG InfFileSize; - PWCHAR KeyValue; - UINT ErrorLine; - PVOID InfFileData; + // ERROR_NUMBER ErrorNumber; + BOOLEAN Success; MUIDisplayPage(PREPARE_COPY_PAGE); - /* Create the file queue */ - SetupFileQueue = SetupOpenFileQueue(); - if (SetupFileQueue == NULL) - { - MUIDisplayError(ERROR_COPY_QUEUE, Ir, POPUP_WAIT_ENTER); - return QUIT_PAGE; - } - - if (!PrepareCopyPageInfFile(SetupInf, NULL, Ir)) + /* ErrorNumber = */ Success = PrepareFileCopy(&USetupData, NULL); + if (/*ErrorNumber != ERROR_SUCCESS*/ !Success) { - /* FIXME: show an error dialog */ + // MUIDisplayError(ErrorNumber, Ir, POPUP_WAIT_ENTER); return QUIT_PAGE; } - /* Search for the 'Cabinets' section */ - if (!SetupFindFirstLineW(SetupInf, L"Cabinets", NULL, &CabinetsContext)) - { - return FILE_COPY_PAGE; - } - - /* - * Enumerate the directory values in the 'Cabinets' - * section and parse their inf files. - */ - do - { - if (!INF_GetData(&CabinetsContext, NULL, &KeyValue)) - break; - - CombinePaths(PathBuffer, ARRAYSIZE(PathBuffer), 2, - SourcePath.Buffer, KeyValue); - - CabinetInitialize(); - CabinetSetEventHandlers(NULL, NULL, NULL); - CabinetSetCabinetName(PathBuffer); - - if (CabinetOpen() == CAB_STATUS_SUCCESS) - { - DPRINT("Cabinet %S\n", CabinetGetCabinetName()); - - InfFileData = CabinetGetCabinetReservedArea(&InfFileSize); - if (InfFileData == NULL) - { - MUIDisplayError(ERROR_CABINET_SCRIPT, Ir, POPUP_WAIT_ENTER); - return QUIT_PAGE; - } - } - else - { - DPRINT("Cannot open cabinet: %S.\n", CabinetGetCabinetName()); - MUIDisplayError(ERROR_CABINET_MISSING, Ir, POPUP_WAIT_ENTER); - return QUIT_PAGE; - } - - InfHandle = INF_OpenBufferedFileA((CHAR*) InfFileData, - InfFileSize, - (const CHAR*) NULL, - INF_STYLE_WIN4, - LanguageId, - &ErrorLine); - - if (InfHandle == INVALID_HANDLE_VALUE) - { - MUIDisplayError(ERROR_INVALID_CABINET_INF, Ir, POPUP_WAIT_ENTER); - return QUIT_PAGE; - } - - CabinetCleanup(); - - if (!PrepareCopyPageInfFile(InfHandle, KeyValue, Ir)) - { - /* FIXME: show an error dialog */ - return QUIT_PAGE; - } - } while (SetupFindNextLine(&CabinetsContext, &CabinetsContext)); - return FILE_COPY_PAGE; } +typedef struct _COPYCONTEXT +{ + ULONG TotalOperations; + ULONG CompletedOperations; + PPROGRESSBAR ProgressBar; + PPROGRESSBAR MemoryBars[4]; +} COPYCONTEXT, *PCOPYCONTEXT; -VOID -NTAPI +static VOID SetupUpdateMemoryInfo(IN PCOPYCONTEXT CopyContext, IN BOOLEAN First) { @@ -3922,7 +3556,6 @@ SetupUpdateMemoryInfo(IN PCOPYCONTEXT CopyContext, ProgressSetStep(CopyContext->MemoryBars[2], PerfInfo.AvailablePages); } - static UINT CALLBACK FileCopyCallback(PVOID Context, @@ -3930,26 +3563,92 @@ FileCopyCallback(PVOID Context, UINT_PTR Param1, UINT_PTR Param2) { - PCOPYCONTEXT CopyContext; - - CopyContext = (PCOPYCONTEXT)Context; + PCOPYCONTEXT CopyContext = (PCOPYCONTEXT)Context; + PFILEPATHS_W FilePathInfo; + PCWSTR SrcFileName, DstFileName; switch (Notification) { case SPFILENOTIFY_STARTSUBQUEUE: + { CopyContext->TotalOperations = (ULONG)Param2; + CopyContext->CompletedOperations = 0; ProgressSetStepCount(CopyContext->ProgressBar, CopyContext->TotalOperations); SetupUpdateMemoryInfo(CopyContext, TRUE); break; + } + case SPFILENOTIFY_STARTDELETE: + case SPFILENOTIFY_STARTRENAME: case SPFILENOTIFY_STARTCOPY: - /* Display copy message */ - CONSOLE_SetStatusText(MUIGetString(STRING_COPYING), (PWSTR)Param1); + { + FilePathInfo = (PFILEPATHS_W)Param1; + + if (Notification == SPFILENOTIFY_STARTDELETE) + { + /* Display delete message */ + ASSERT(Param2 == FILEOP_DELETE); + + DstFileName = wcsrchr(FilePathInfo->Target, L'\\'); + if (DstFileName) ++DstFileName; + else DstFileName = FilePathInfo->Target; + + CONSOLE_SetStatusText(MUIGetString(STRING_DELETING), + DstFileName); + } + else if (Notification == SPFILENOTIFY_STARTRENAME) + { + /* Display move/rename message */ + ASSERT(Param2 == FILEOP_RENAME); + + SrcFileName = wcsrchr(FilePathInfo->Source, L'\\'); + if (SrcFileName) ++SrcFileName; + else SrcFileName = FilePathInfo->Source; + + DstFileName = wcsrchr(FilePathInfo->Target, L'\\'); + if (DstFileName) ++DstFileName; + else DstFileName = FilePathInfo->Target; + + if (!wcsicmp(SrcFileName, DstFileName)) + Param2 = STRING_MOVING; + else + Param2 = STRING_RENAMING; + + CONSOLE_SetStatusText(MUIGetString(Param2), + SrcFileName, DstFileName); + } + else if (Notification == SPFILENOTIFY_STARTCOPY) + { + /* Display copy message */ + ASSERT(Param2 == FILEOP_COPY); + + /* NOTE: When extracting from CABs the Source is the CAB name */ + DstFileName = wcsrchr(FilePathInfo->Target, L'\\'); + if (DstFileName) ++DstFileName; + else DstFileName = FilePathInfo->Target; + + CONSOLE_SetStatusText(MUIGetString(STRING_COPYING), + DstFileName); + } + SetupUpdateMemoryInfo(CopyContext, FALSE); break; + } + + case SPFILENOTIFY_COPYERROR: + { + FilePathInfo = (PFILEPATHS_W)Param1; + + DPRINT1("An error happened while trying to copy file '%S' (error 0x%08lx), skipping it...\n", + FilePathInfo->Target, FilePathInfo->Win32Error); + return FILEOP_SKIP; + } + case SPFILENOTIFY_ENDDELETE: + case SPFILENOTIFY_ENDRENAME: case SPFILENOTIFY_ENDCOPY: + { CopyContext->CompletedOperations++; /* SYSREG checkpoint */ @@ -3959,9 +3658,10 @@ FileCopyCallback(PVOID Context, ProgressNextStep(CopyContext->ProgressBar); SetupUpdateMemoryInfo(CopyContext, FALSE); break; + } } - return 0; + return FILEOP_DOIT; } @@ -3972,8 +3672,7 @@ FileCopyCallback(PVOID Context, * RegistryPage(At once) * * SIDEEFFECTS - * Calls SetupCommitFileQueueW - * Calls SetupCloseFileQueue + * Calls DoFileCopy * * RETURNS * Number of the next page. @@ -3982,13 +3681,11 @@ static PAGE_NUMBER FileCopyPage(PINPUT_RECORD Ir) { COPYCONTEXT CopyContext; - unsigned int mem_bar_width; + UINT MemBarWidth; MUIDisplayPage(FILE_COPY_PAGE); /* Create context for the copy process */ - CopyContext.DestinationRootPath = DestinationRootPath.Buffer; - CopyContext.InstallPath = InstallPath.Buffer; CopyContext.TotalOperations = 0; CopyContext.CompletedOperations = 0; @@ -4003,13 +3700,13 @@ FileCopyPage(PINPUT_RECORD Ir) MUIGetString(STRING_SETUPCOPYINGFILES)); // fit memory bars to screen width, distribute them uniform - mem_bar_width = (xScreen - 26) / 5; - mem_bar_width -= mem_bar_width % 2; // make even + MemBarWidth = (xScreen - 26) / 5; + MemBarWidth -= MemBarWidth % 2; // make even /* ATTENTION: The following progress bars are debug stuff, which should not be translated!! */ /* Create the paged pool progress bar */ CopyContext.MemoryBars[0] = CreateProgressBar(13, 40, - 13 + mem_bar_width, + 13 + MemBarWidth, 43, 13, 44, @@ -4017,43 +3714,73 @@ FileCopyPage(PINPUT_RECORD Ir) "Kernel Pool"); /* Create the non paged pool progress bar */ - CopyContext.MemoryBars[1] = CreateProgressBar((xScreen / 2)- (mem_bar_width / 2), + CopyContext.MemoryBars[1] = CreateProgressBar((xScreen / 2)- (MemBarWidth / 2), 40, - (xScreen / 2) + (mem_bar_width / 2), + (xScreen / 2) + (MemBarWidth / 2), 43, - (xScreen / 2)- (mem_bar_width / 2), + (xScreen / 2)- (MemBarWidth / 2), 44, FALSE, "Kernel Cache"); /* Create the global memory progress bar */ - CopyContext.MemoryBars[2] = CreateProgressBar(xScreen - 13 - mem_bar_width, + CopyContext.MemoryBars[2] = CreateProgressBar(xScreen - 13 - MemBarWidth, 40, xScreen - 13, 43, - xScreen - 13 - mem_bar_width, + xScreen - 13 - MemBarWidth, 44, FALSE, "Free Memory"); /* Do the file copying */ - SetupCommitFileQueueW(NULL, - SetupFileQueue, - FileCopyCallback, - &CopyContext); + DoFileCopy(&USetupData, FileCopyCallback, &CopyContext); - /* If we get here, we're done, so cleanup the queue and progress bar */ - SetupCloseFileQueue(SetupFileQueue); + /* If we get here, we're done, so cleanup the progress bar */ DestroyProgressBar(CopyContext.ProgressBar); DestroyProgressBar(CopyContext.MemoryBars[0]); DestroyProgressBar(CopyContext.MemoryBars[1]); DestroyProgressBar(CopyContext.MemoryBars[2]); + /* Create the $winnt$.inf file */ + InstallSetupInfFile(&USetupData); + /* Go display the next page */ return REGISTRY_PAGE; } +static VOID +__cdecl +RegistryStatus(IN REGISTRY_STATUS RegStatus, ...) +{ + /* WARNING: Please keep this lookup table in sync with the resources! */ + static const UINT StringIDs[] = + { + STRING_DONE, /* Success */ + STRING_REGHIVEUPDATE, /* RegHiveUpdate */ + STRING_IMPORTFILE, /* ImportRegHive */ + STRING_DISPLAYSETTINGSUPDATE, /* DisplaySettingsUpdate */ + STRING_LOCALESETTINGSUPDATE, /* LocaleSettingsUpdate */ + STRING_ADDKBLAYOUTS, /* KeybLayouts */ + STRING_KEYBOARDSETTINGSUPDATE, /* KeybSettingsUpdate */ + STRING_CODEPAGEINFOUPDATE, /* CodePageInfoUpdate */ + }; + + va_list args; + + if (RegStatus < ARRAYSIZE(StringIDs)) + { + va_start(args, RegStatus); + CONSOLE_SetStatusTextV(MUIGetString(StringIDs[RegStatus]), args); + va_end(args); + } + else + { + CONSOLE_SetStatusText("Unknown status %d", RegStatus); + } +} + /* * Displays the RegistryPage. * @@ -4063,10 +3790,7 @@ FileCopyPage(PINPUT_RECORD Ir) * QuitPage * * SIDEEFFECTS - * Calls RegInitializeRegistry - * Calls ImportRegistryFile - * Calls SetDefaultPagefile - * Calls SetMountedDeviceValues + * Calls UpdateRegistry * * RETURNS * Number of the next page. @@ -4074,168 +3798,26 @@ FileCopyPage(PINPUT_RECORD Ir) static PAGE_NUMBER RegistryPage(PINPUT_RECORD Ir) { - NTSTATUS Status; - INFCONTEXT InfContext; - PWSTR Action; - PWSTR File; - PWSTR Section; - BOOLEAN Delete; + ULONG Error; MUIDisplayPage(REGISTRY_PAGE); - if (RepairUpdateFlag) - { - BOOLEAN ShouldUpdateRegistry = FALSE; - - DPRINT1("TODO: Updating / repairing the registry is not completely implemented yet!\n"); - - /* Verify the registry hives and check whether we need to update or repair any of them */ - Status = VerifyRegistryHives(&DestinationPath, &ShouldUpdateRegistry); - if (!NT_SUCCESS(Status)) - { - DPRINT1("VerifyRegistryHives failed, Status 0x%08lx\n", Status); - ShouldUpdateRegistry = FALSE; - } - if (!ShouldUpdateRegistry) - { - DPRINT1("No need to update the registry\n"); - // return SUCCESS_PAGE; - goto Quit; - } - } - - /* Initialize the registry and setup the default installation hives */ - Status = RegInitializeRegistry(&DestinationPath); - if (!NT_SUCCESS(Status)) + Error = UpdateRegistry(&USetupData, + RepairUpdateFlag, + PartitionList, + DestinationDriveLetter, + SelectedLanguageId, + RegistryStatus); + if (Error != ERROR_SUCCESS) { - 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); - } + MUIDisplayError(Error, Ir, POPUP_WAIT_ENTER); return QUIT_PAGE; } - - /* Update registry */ - CONSOLE_SetStatusText(MUIGetString(STRING_REGHIVEUPDATE)); - - if (!SetupFindFirstLineW(SetupInf, L"HiveInfs.Install", NULL, &InfContext)) - { - DPRINT1("SetupFindFirstLine() failed\n"); - MUIDisplayError(ERROR_FIND_REGISTRY, Ir, POPUP_WAIT_ENTER); - goto Cleanup; - } - - do - { - INF_GetDataField(&InfContext, 0, &Action); - INF_GetDataField(&InfContext, 1, &File); - INF_GetDataField(&InfContext, 2, &Section); - - DPRINT("Action: %S File: %S Section %S\n", Action, File, Section); - - if (Action == NULL) - break; // Hackfix - - if (!_wcsicmp(Action, L"AddReg")) - Delete = FALSE; - else if (!_wcsicmp(Action, L"DelReg")) - Delete = TRUE; - else - continue; - - CONSOLE_SetStatusText(MUIGetString(STRING_IMPORTFILE), File); - - if (!ImportRegistryFile(File, Section, LanguageId, Delete)) - { - DPRINT1("Importing %S failed\n", File); - MUIDisplayError(ERROR_IMPORT_HIVE, Ir, POPUP_WAIT_ENTER); - goto Cleanup; - } - } while (SetupFindNextLine(&InfContext, &InfContext)); - - /* Update display registry settings */ - CONSOLE_SetStatusText(MUIGetString(STRING_DISPLAYETTINGSUPDATE)); - if (!ProcessDisplayRegistry(SetupInf, DisplayList)) - { - MUIDisplayError(ERROR_UPDATE_DISPLAY_SETTINGS, Ir, POPUP_WAIT_ENTER); - goto Cleanup; - } - - /* 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); - -Cleanup: - // - // TODO: Unload all the registry stuff, perform cleanup, - // and copy the created hive files into .sav files. - // - RegCleanupRegistry(&DestinationPath); - -Quit: - if (NT_SUCCESS(Status)) + else { CONSOLE_SetStatusText(MUIGetString(STRING_DONE)); return BOOT_LOADER_PAGE; } - else - { - return QUIT_PAGE; - } } @@ -4269,28 +3851,30 @@ BootLoaderPage(PINPUT_RECORD Ir) CONSOLE_SetStatusText(MUIGetString(STRING_PLEASEWAIT)); - RtlFreeUnicodeString(&SystemRootPath); - StringCchPrintfW(PathBuffer, ARRAYSIZE(PathBuffer), + RtlFreeUnicodeString(&USetupData.SystemRootPath); + RtlStringCchPrintfW(PathBuffer, ARRAYSIZE(PathBuffer), L"\\Device\\Harddisk%lu\\Partition%lu\\", PartitionList->SystemPartition->DiskEntry->DiskNumber, PartitionList->SystemPartition->PartitionNumber); - RtlCreateUnicodeString(&SystemRootPath, PathBuffer); - DPRINT1("SystemRootPath: %wZ\n", &SystemRootPath); + RtlCreateUnicodeString(&USetupData.SystemRootPath, PathBuffer); + DPRINT1("SystemRootPath: %wZ\n", &USetupData.SystemRootPath); PartitionType = PartitionList->SystemPartition->PartitionType; + /* For unattended setup, skip MBR installation or install on floppy if needed */ if (IsUnattendedSetup) { - if (UnattendMBRInstallType == 0) /* skip MBR installation */ + if ((USetupData.MBRInstallType == 0) || + (USetupData.MBRInstallType == 1)) { - return SUCCESS_PAGE; - } - else if (UnattendMBRInstallType == 1) /* install on floppy */ - { - return BOOT_LOADER_FLOPPY_PAGE; + goto Quit; } } + /* + * We may install an MBR or VBR, but before that, check whether + * we need to actually install the VBR on floppy. + */ if (PartitionType == PARTITION_ENTRY_UNUSED) { DPRINT("Error: system partition invalid (unused)\n"); @@ -4302,10 +3886,10 @@ BootLoaderPage(PINPUT_RECORD Ir) DPRINT("Found OS/2 boot manager partition\n"); InstallOnFloppy = TRUE; } - else if (PartitionType == PARTITION_EXT2) + else if (PartitionType == PARTITION_LINUX) { - /* Linux EXT2 partition */ - DPRINT("Found Linux EXT2 partition\n"); + /* Linux partition */ + DPRINT("Found Linux native partition (ext2/ext3/ReiserFS/BTRFS/etc)\n"); InstallOnFloppy = FALSE; } else if (PartitionType == PARTITION_IFS) @@ -4318,9 +3902,9 @@ BootLoaderPage(PINPUT_RECORD Ir) } else if ((PartitionType == PARTITION_FAT_12) || (PartitionType == PARTITION_FAT_16) || - (PartitionType == PARTITION_HUGE) || + (PartitionType == PARTITION_HUGE) || (PartitionType == PARTITION_XINT13) || - (PartitionType == PARTITION_FAT32) || + (PartitionType == PARTITION_FAT32) || (PartitionType == PARTITION_FAT32_XINT13)) { DPRINT("Found FAT partition\n"); @@ -4333,15 +3917,21 @@ BootLoaderPage(PINPUT_RECORD Ir) InstallOnFloppy = TRUE; } - if (InstallOnFloppy != FALSE) + /* We should install on floppy */ + if (InstallOnFloppy) { - return BOOT_LOADER_FLOPPY_PAGE; + USetupData.MBRInstallType = 1; + goto Quit; } - /* Unattended install on hdd? */ - if (IsUnattendedSetup && UnattendMBRInstallType == 2) + /* Is it an unattended install on hdd? */ + if (IsUnattendedSetup) { - return BOOT_LOADER_HARDDISK_MBR_PAGE; + if ((USetupData.MBRInstallType == 2) || + (USetupData.MBRInstallType == 3)) + { + goto Quit; + } } MUIDisplayPage(BOOT_LOADER_PAGE); @@ -4357,11 +3947,11 @@ BootLoaderPage(PINPUT_RECORD Ir) CONSOLE_NormalTextXY(8, Line, 60, 1); Line++; - if (Line<12) - Line=15; + if (Line < 12) + Line = 15; - if (Line>15) - Line=12; + if (Line > 15) + Line = 12; CONSOLE_InvertTextXY(8, Line, 60, 1); } @@ -4371,18 +3961,18 @@ BootLoaderPage(PINPUT_RECORD Ir) CONSOLE_NormalTextXY(8, Line, 60, 1); Line--; - if (Line<12) - Line=15; + if (Line < 12) + Line = 15; - if (Line>15) - Line=12; + if (Line > 15) + Line = 12; CONSOLE_InvertTextXY(8, Line, 60, 1); } else if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) && (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */ { - if (ConfirmQuit(Ir) != FALSE) + if (ConfirmQuit(Ir)) return QUIT_PAGE; break; @@ -4391,25 +3981,53 @@ BootLoaderPage(PINPUT_RECORD Ir) { if (Line == 12) { - return BOOT_LOADER_HARDDISK_MBR_PAGE; + /* Install on both MBR and VBR */ + USetupData.MBRInstallType = 2; + break; } else if (Line == 13) { - return BOOT_LOADER_HARDDISK_VBR_PAGE; + /* Install on VBR only */ + USetupData.MBRInstallType = 3; + break; } else if (Line == 14) { - return BOOT_LOADER_FLOPPY_PAGE; + /* Install on floppy */ + USetupData.MBRInstallType = 1; + break; } else if (Line == 15) { - return SUCCESS_PAGE; + /* Skip MBR installation */ + USetupData.MBRInstallType = 0; + break; } return BOOT_LOADER_PAGE; } } +Quit: + switch (USetupData.MBRInstallType) + { + /* Skip MBR installation */ + case 0: + return SUCCESS_PAGE; + + /* Install on floppy */ + case 1: + return BOOT_LOADER_FLOPPY_PAGE; + + /* Install on both MBR and VBR */ + case 2: + return BOOT_LOADER_HARDDISK_MBR_PAGE; + + /* Install on VBR only */ + case 3: + return BOOT_LOADER_HARDDISK_VBR_PAGE; + } + return BOOT_LOADER_PAGE; } @@ -4443,23 +4061,21 @@ BootLoaderFloppyPage(PINPUT_RECORD Ir) if ((Ir->Event.KeyEvent.uChar.AsciiChar == 0x00) && (Ir->Event.KeyEvent.wVirtualKeyCode == VK_F3)) /* F3 */ { - if (ConfirmQuit(Ir) != FALSE) + if (ConfirmQuit(Ir)) return QUIT_PAGE; break; } else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */ { - if (DoesPathExist(NULL, L"\\Device\\Floppy0\\") == FALSE) - { - MUIDisplayError(ERROR_NO_FLOPPY, Ir, POPUP_WAIT_ENTER); - return BOOT_LOADER_FLOPPY_PAGE; - } - - Status = InstallFatBootcodeToFloppy(&SourceRootPath, &DestinationArcPath); + Status = InstallFatBootcodeToFloppy(&USetupData.SourceRootPath, + &USetupData.DestinationArcPath); if (!NT_SUCCESS(Status)) { - /* Print error message */ + if (Status == STATUS_DEVICE_NOT_READY) + MUIDisplayError(ERROR_NO_FLOPPY, Ir, POPUP_WAIT_ENTER); + + /* TODO: Print error message */ return BOOT_LOADER_FLOPPY_PAGE; } @@ -4489,13 +4105,15 @@ BootLoaderHarddiskVbrPage(PINPUT_RECORD Ir) { NTSTATUS Status; - Status = InstallVBRToPartition(&SystemRootPath, - &SourceRootPath, - &DestinationArcPath, + // FIXME! We must not use the partition type, but instead use the partition FileSystem!! + Status = InstallVBRToPartition(&USetupData.SystemRootPath, + &USetupData.SourceRootPath, + &USetupData.DestinationArcPath, PartitionList->SystemPartition->PartitionType); if (!NT_SUCCESS(Status)) { - MUIDisplayError(ERROR_WRITE_BOOT, Ir, POPUP_WAIT_ENTER); + MUIDisplayError(ERROR_WRITE_BOOT, Ir, POPUP_WAIT_ENTER, + PartitionList->SystemPartition->FileSystem->FileSystemName); return QUIT_PAGE; } @@ -4522,50 +4140,31 @@ BootLoaderHarddiskMbrPage(PINPUT_RECORD Ir) { NTSTATUS Status; WCHAR DestinationDevicePathBuffer[MAX_PATH]; - WCHAR SourceMbrPathBuffer[MAX_PATH]; - WCHAR DstPath[MAX_PATH]; /* Step 1: Write the VBR */ - Status = InstallVBRToPartition(&SystemRootPath, - &SourceRootPath, - &DestinationArcPath, + // FIXME! We must not use the partition type, but instead use the partition FileSystem!! + Status = InstallVBRToPartition(&USetupData.SystemRootPath, + &USetupData.SourceRootPath, + &USetupData.DestinationArcPath, PartitionList->SystemPartition->PartitionType); if (!NT_SUCCESS(Status)) { - MUIDisplayError(ERROR_WRITE_BOOT, Ir, POPUP_WAIT_ENTER); + MUIDisplayError(ERROR_WRITE_BOOT, Ir, POPUP_WAIT_ENTER, + PartitionList->SystemPartition->FileSystem->FileSystemName); return QUIT_PAGE; } /* Step 2: Write the MBR */ - StringCchPrintfW(DestinationDevicePathBuffer, ARRAYSIZE(DestinationDevicePathBuffer), + RtlStringCchPrintfW(DestinationDevicePathBuffer, ARRAYSIZE(DestinationDevicePathBuffer), L"\\Device\\Harddisk%d\\Partition0", PartitionList->SystemPartition->DiskEntry->DiskNumber); - - CombinePaths(SourceMbrPathBuffer, ARRAYSIZE(SourceMbrPathBuffer), 2, SourceRootPath.Buffer, L"\\loader\\dosmbr.bin"); - - if (IsThereAValidBootSector(DestinationDevicePathBuffer)) - { - /* Save current MBR */ - CombinePaths(DstPath, ARRAYSIZE(DstPath), 2, SystemRootPath.Buffer, L"mbr.old"); - - DPRINT1("Save MBR: %S ==> %S\n", DestinationDevicePathBuffer, DstPath); - Status = SaveBootSector(DestinationDevicePathBuffer, DstPath, sizeof(PARTITION_SECTOR)); - if (!NT_SUCCESS(Status)) - { - DPRINT1("SaveBootSector() failed (Status %lx)\n", Status); - // Don't care if we succeeded or not saving the old MBR, just go ahead. - } - } - - DPRINT1("Install MBR bootcode: %S ==> %S\n", - SourceMbrPathBuffer, DestinationDevicePathBuffer); - Status = InstallMbrBootCodeToDisk(SourceMbrPathBuffer, + Status = InstallMbrBootCodeToDisk(&USetupData.SystemRootPath, + &USetupData.SourceRootPath, DestinationDevicePathBuffer); if (!NT_SUCCESS(Status)) { - DPRINT1("InstallMbrBootCodeToDisk() failed (Status %lx)\n", - Status); - MUIDisplayError(ERROR_INSTALL_BOOTCODE, Ir, POPUP_WAIT_ENTER); + DPRINT1("InstallMbrBootCodeToDisk() failed (Status %lx)\n", Status); + MUIDisplayError(ERROR_INSTALL_BOOTCODE, Ir, POPUP_WAIT_ENTER, L"MBR"); return QUIT_PAGE; } @@ -4785,12 +4384,20 @@ QuitPage(PINPUT_RECORD Ir) { MUIDisplayPage(QUIT_PAGE); + /* Destroy the NTOS installations list */ + if (NtOsInstallsList != NULL) + { + DestroyGenericList(NtOsInstallsList, TRUE); + NtOsInstallsList = NULL; + } + /* Destroy the partition list */ if (PartitionList != NULL) { DestroyPartitionList(PartitionList); PartitionList = NULL; } + TempPartition = NULL; FormatState = Start; @@ -4801,41 +4408,6 @@ QuitPage(PINPUT_RECORD Ir) FileSystemList = NULL; } - /* Destroy the computer settings list */ - if (ComputerList != NULL) - { - DestroyGenericList(ComputerList, TRUE); - ComputerList = NULL; - } - - /* Destroy the display settings list */ - if (DisplayList != NULL) - { - DestroyGenericList(DisplayList, TRUE); - DisplayList = NULL; - } - - /* Destroy the keyboard settings list */ - if (KeyboardList != NULL) - { - DestroyGenericList(KeyboardList, TRUE); - KeyboardList = NULL; - } - - /* Destroy the keyboard layout list */ - if (LayoutList != NULL) - { - DestroyGenericList(LayoutList, TRUE); - LayoutList = NULL; - } - - /* Destroy the languages list */ - if (LanguageList != NULL) - { - DestroyGenericList(LanguageList, FALSE); - LanguageList = NULL; - } - CONSOLE_SetStatusText(MUIGetString(STRING_REBOOTCOMPUTER2)); /* Wait for maximum 15 seconds or an ENTER key before quitting */ @@ -4917,11 +4489,11 @@ RunUSetup(VOID) 0, 0, PnpEventThread, - &SetupInf, + &USetupData.SetupInf, &hPnpThread, NULL); if (!NT_SUCCESS(Status)) - hPnpThread = INVALID_HANDLE_VALUE; + hPnpThread = NULL; if (!CONSOLE_Init()) { @@ -4933,15 +4505,9 @@ RunUSetup(VOID) return STATUS_APP_INIT_FAILURE; } - /* Initialize global unicode strings */ - RtlInitUnicodeString(&SourcePath, NULL); - RtlInitUnicodeString(&SourceRootPath, NULL); - RtlInitUnicodeString(&SourceRootDir, NULL); - RtlInitUnicodeString(&InstallPath, NULL); - RtlInitUnicodeString(&DestinationPath, NULL); - RtlInitUnicodeString(&DestinationArcPath, NULL); - RtlInitUnicodeString(&DestinationRootPath, NULL); - RtlInitUnicodeString(&SystemRootPath, NULL); + /* Initialize Setup, phase 0 */ + InitializeSetup(&USetupData, 0); + USetupData.ErrorRoutine = USetupErrorRoutine; /* Hide the cursor */ CONSOLE_SetCursorType(TRUE, FALSE); @@ -5084,6 +4650,10 @@ RunUSetup(VOID) Page = RepairIntroPage(&Ir); break; + case UPGRADE_REPAIR_PAGE: + Page = UpgradeRepairPage(&Ir); + break; + case SUCCESS_PAGE: Page = SuccessPage(&Ir); break; @@ -5102,6 +4672,9 @@ RunUSetup(VOID) } } + /* Setup has finished */ + FinishSetup(&USetupData); + if (Page == RECOVERY_PAGE) RecoveryConsole();