X-Git-Url: https://git.reactos.org/?p=reactos.git;a=blobdiff_plain;f=base%2Fsetup%2Fusetup%2Fusetup.c;h=f16d6512b739bcf886a1f7cc1aed7a660f7bed86;hp=af5708ffc50350b68065cb89dbd1daa163ddd86c;hb=073c09e491f1003b07c10abfb5e209f0c5e122f5;hpb=7e248feabf1ed10b7015e3a5a7bd6fcc4eb07cd4 diff --git a/base/setup/usetup/usetup.c b/base/setup/usetup/usetup.c index af5708ffc50..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,27 +32,17 @@ #include "chkdsk.h" #include "cmdcons.h" #include "format.h" -#include "settings.h" #define NDEBUG #include -// HACK! -#include - /* GLOBALS & LOCALS *********************************************************/ HANDLE ProcessHeap; - BOOLEAN IsUnattendedSetup = FALSE; -static USETUP_DATA USetupData; -/* - * NOTE: Technically only used for the COPYCONTEXT InstallPath member - * for the filequeue functionality. - */ -static UNICODE_STRING InstallPath; +static USETUP_DATA USetupData; // FIXME: Is it really useful?? Just used for SetDefaultPagefile... static WCHAR DestinationDriveLetter; @@ -60,7 +50,7 @@ static WCHAR DestinationDriveLetter; /* OTHER Stuff *****/ -PWCHAR SelectedLanguageId; +PCWSTR SelectedLanguageId; static WCHAR DefaultLanguage[20]; // Copy of string inside LanguageList static WCHAR DefaultKBLayout[20]; // Copy of string inside KeyboardList @@ -75,19 +65,9 @@ static FORMATMACHINESTATE FormatState = Start; /*****************************************************/ -static HINF SetupInf; - -static HSPFILEQ SetupFileQueue = NULL; - static PNTOS_INSTALLATION CurrentInstallation = NULL; static PGENERIC_LIST NtOsInstallsList = NULL; -static PGENERIC_LIST ComputerList = NULL; -static PGENERIC_LIST DisplayList = NULL; -static PGENERIC_LIST KeyboardList = NULL; -static PGENERIC_LIST LayoutList = NULL; -static PGENERIC_LIST LanguageList = NULL; - /* FUNCTIONS ****************************************************************/ @@ -404,39 +384,77 @@ static VOID UpdateKBLayout(VOID) { PGENERIC_LIST_ENTRY ListEntry; - LPCWSTR pszNewLayout; + PCWSTR pszNewLayout; - pszNewLayout = MUIDefaultKeyboardLayout(); + pszNewLayout = MUIDefaultKeyboardLayout(SelectedLanguageId); - 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: Handle error! */ return; } } - ListEntry = GetFirstListEntry(LayoutList); - /* Search for default layout (if provided) */ if (pszNewLayout != NULL) { - while (ListEntry != NULL) + for (ListEntry = GetFirstListEntry(USetupData.LayoutList); ListEntry; + ListEntry = GetNextListEntry(ListEntry)) { - if (!wcscmp(pszNewLayout, GetListEntryUserData(ListEntry))) + if (!wcscmp(pszNewLayout, ((PGENENTRY)GetListEntryData(ListEntry))->Id)) { - SetCurrentListEntry(LayoutList, ListEntry); + SetCurrentListEntry(USetupData.LayoutList, ListEntry); break; } - - ListEntry = GetNextListEntry(ListEntry); } } } +static NTSTATUS +NTAPI +GetSettingDescription( + IN PGENERIC_LIST_ENTRY Entry, + OUT PSTR Buffer, + IN SIZE_T cchBufferSize) +{ + return RtlStringCchPrintfA(Buffer, cchBufferSize, "%S", + ((PGENENTRY)GetListEntryData(Entry))->Value); +} + +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 (PartEntry && PartEntry->DriveLetter) + { + /* We have retrieved a partition that is mounted */ + return RtlStringCchPrintfA(Buffer, cchBufferSize, + "%C:%S \"%S\"", + PartEntry->DriveLetter, + NtOsInstall->PathComponent, + NtOsInstall->InstallationName); + } + else + { + /* We failed somewhere, just show the NT path */ + return RtlStringCchPrintfA(Buffer, cchBufferSize, + "%wZ \"%S\"", + &NtOsInstall->SystemNtPath, + NtOsInstall->InstallationName); + } +} + + /* * Displays the LanguagePage. * @@ -453,38 +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 */ - USetupData.LanguageId = 0; 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) { 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); @@ -530,7 +550,10 @@ LanguagePage(PINPUT_RECORD Ir) } 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; USetupData.LanguageId = (LANGID)(wcstol(SelectedLanguageId, NULL, 16) & 0xFFFF); @@ -553,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); @@ -590,7 +616,7 @@ LanguagePage(PINPUT_RECORD Ir) * Init USetupData.SourcePath * Init USetupData.SourceRootPath * Init USetupData.SourceRootDir - * Init SetupInf + * Init USetupData.SetupInf * Init USetupData.RequiredPartitionDiskSpace * Init IsUnattendedSetup * If unattended, init *List and sets the Codepage @@ -603,28 +629,14 @@ LanguagePage(PINPUT_RECORD Ir) static PAGE_NUMBER SetupStartPage(PINPUT_RECORD Ir) { - NTSTATUS Status; ULONG Error; PGENERIC_LIST_ENTRY ListEntry; + PCWSTR LocaleId; CONSOLE_SetStatusText(MUIGetString(STRING_PLEASEWAIT)); - /* Get the source path and source root path */ - Status = GetSourcePaths(&USetupData.SourcePath, - &USetupData.SourceRootPath, - &USetupData.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", &USetupData.SourcePath); - DPRINT1("SourceRootPath: '%wZ'\n", &USetupData.SourceRootPath); - DPRINT1("SourceRootDir: '%wZ'\n", &USetupData.SourceRootDir); - - /* Load 'txtsetup.sif' from the installation media */ - Error = LoadSetupInf(&SetupInf, &USetupData); + /* Initialize Setup, phase 1 */ + Error = InitializeSetup(&USetupData, 1); if (Error != ERROR_SUCCESS) { MUIDisplayError(Error, Ir, POPUP_WAIT_ENTER); @@ -643,42 +655,45 @@ SetupStartPage(PINPUT_RECORD Ir) 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, USetupData.LocaleID); + 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(USetupData.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(USetupData.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(); @@ -851,6 +866,11 @@ UpgradeRepairPage(PINPUT_RECORD Ir) NtOsInstallsList = CreateNTOSInstallationsList(PartitionList); if (!NtOsInstallsList) DPRINT1("Failed to get a list of NTOS installations; continue installation...\n"); + + /* + * 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; @@ -862,14 +882,12 @@ UpgradeRepairPage(PINPUT_RECORD Ir) MUIDisplayPage(UPGRADE_REPAIR_PAGE); - InitGenericListUi(&ListUi, NtOsInstallsList); + InitGenericListUi(&ListUi, NtOsInstallsList, GetNTOSInstallationName); DrawGenericList(&ListUi, 2, 23, xScreen - 3, yScreen - 3); - SaveGenericListState(NtOsInstallsList); - // return HandleGenericList(&ListUi, DEVICE_SETTINGS_PAGE, Ir); while (TRUE) { @@ -901,7 +919,7 @@ UpgradeRepairPage(PINPUT_RECORD Ir) } case VK_ESCAPE: /* ESC */ { - RestoreGenericListState(NtOsInstallsList); + RestoreGenericListUiState(&ListUi); // return nextPage; // prevPage; // return INSTALL_INTRO_PAGE; @@ -917,7 +935,11 @@ UpgradeRepairPage(PINPUT_RECORD Ir) if (toupper(Ir->Event.KeyEvent.uChar.AsciiChar) == 'U') /* U */ { /* Retrieve the current installation */ - CurrentInstallation = (PNTOS_INSTALLATION)GetListEntryUserData(GetCurrentListEntry(NtOsInstallsList)); + 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); @@ -1078,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. @@ -1092,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; @@ -1103,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; @@ -1114,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; @@ -1125,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); @@ -1144,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); @@ -1258,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 */ @@ -1290,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); } @@ -1319,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); } @@ -1348,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); } @@ -1377,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); } @@ -1662,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) { @@ -2448,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, @@ -2458,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, @@ -2705,6 +2737,8 @@ SelectFileSystemPage(PINPUT_RECORD Ir) PartTypeString, ARRAYSIZE(PartTypeString)); + MUIDisplayPage(SELECT_FILE_SYSTEM_PAGE); + if (PartEntry->AutoCreate) { CONSOLE_SetTextXY(6, 8, MUIGetString(STRING_NEWPARTITION)); @@ -2761,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, @@ -2771,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, @@ -2789,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 */ @@ -2888,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; @@ -2977,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); @@ -2989,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); @@ -3030,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) { @@ -3050,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); @@ -3072,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" @@ -3104,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; } @@ -3132,41 +3193,60 @@ BuildInstallPaths(PWSTR InstallDir, PDISKENTRY DiskEntry, PPARTENTRY PartEntry) { - WCHAR PathBuffer[MAX_PATH]; - -/** Equivalent of 'NTOS_INSTALLATION::PathComponent' **/ - /* Create 'InstallPath' string */ - RtlFreeUnicodeString(&InstallPath); - RtlCreateUnicodeString(&InstallPath, InstallDir); + NTSTATUS Status; - /* Create 'USetupData.DestinationRootPath' string */ - RtlFreeUnicodeString(&USetupData.DestinationRootPath); - StringCchPrintfW(PathBuffer, ARRAYSIZE(PathBuffer), - L"\\Device\\Harddisk%lu\\Partition%lu\\", - DiskEntry->DiskNumber, - PartEntry->PartitionNumber); - RtlCreateUnicodeString(&USetupData.DestinationRootPath, PathBuffer); - DPRINT("DestinationRootPath: %wZ\n", &USetupData.DestinationRootPath); - -/** Equivalent of 'NTOS_INSTALLATION::SystemNtPath' **/ - /* Create 'USetupData.DestinationPath' string */ - RtlFreeUnicodeString(&USetupData.DestinationPath); - CombinePaths(PathBuffer, ARRAYSIZE(PathBuffer), 2, - USetupData.DestinationRootPath.Buffer, InstallDir); - RtlCreateUnicodeString(&USetupData.DestinationPath, PathBuffer); - -/** Equivalent of 'NTOS_INSTALLATION::SystemArcPath' **/ - /* Create 'USetupData.DestinationArcPath' */ - RtlFreeUnicodeString(&USetupData.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(&USetupData.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; } @@ -3228,6 +3308,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; } @@ -3317,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 */ @@ -3362,365 +3468,28 @@ InstallDirectoryPage(PINPUT_RECORD Ir) } -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"); - INF_FreeData(FileKeyName); - INF_FreeData(FileKeyValue); - INF_FreeData(TargetFileName); - break; - } - - INF_FreeData(FileKeyValue); - - if (!INF_GetData(&DirContext, NULL, &DirKeyValue)) - { - /* FIXME: Handle error! */ - DPRINT1("INF_GetData() failed\n"); - INF_FreeData(FileKeyName); - INF_FreeData(TargetFileName); - break; - } - - if (!SetupQueueCopy(SetupFileQueue, - SourceCabinet, - USetupData.SourceRootPath.Buffer, - USetupData.SourceRootDir.Buffer, - FileKeyName, - DirKeyValue, - TargetFileName)) - { - /* FIXME: Handle error! */ - DPRINT1("SetupQueueCopy() failed\n"); - } - - INF_FreeData(FileKeyName); - INF_FreeData(TargetFileName); - INF_FreeData(DirKeyValue); - } 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 */ - if (!INF_GetDataField(&FilesContext, 0, &FileKeyName)) - { - /* 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"); - INF_FreeData(FileKeyName); - 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"); - INF_FreeData(FileKeyName); - INF_FreeData(FileKeyValue); - INF_FreeData(TargetFileName); - break; - } - - INF_FreeData(FileKeyValue); - - if (!INF_GetData(&DirContext, NULL, &DirKeyValue)) - { - /* FIXME: Handle error! */ - DPRINT1("INF_GetData() failed\n"); - INF_FreeData(FileKeyName); - INF_FreeData(TargetFileName); - break; - } - - if ((DirKeyValue[0] == UNICODE_NULL) || (DirKeyValue[0] == L'\\' && DirKeyValue[1] == UNICODE_NULL)) - { - /* Installation path */ - DPRINT("InstallationPath: '%S'\n", DirKeyValue); - - StringCchCopyW(CompleteOrigDirName, ARRAYSIZE(CompleteOrigDirName), - USetupData.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, - USetupData.SourceRootDir.Buffer, DirKeyValue); - - DPRINT("RelativePath(2): '%S'\n", CompleteOrigDirName); - } - - if (!SetupQueueCopy(SetupFileQueue, - SourceCabinet, - USetupData.SourceRootPath.Buffer, - CompleteOrigDirName, - FileKeyName, - DirKeyValue, - TargetFileName)) - { - /* FIXME: Handle error! */ - DPRINT1("SetupQueueCopy() failed\n"); - } - - INF_FreeData(FileKeyName); - INF_FreeData(TargetFileName); - INF_FreeData(DirKeyValue); - } while (SetupFindNextLine(&FilesContext, &FilesContext)); - - return TRUE; -} - - -static BOOLEAN -PrepareCopyPageInfFile(HINF InfFile, - PWCHAR SourceCabinet, - PINPUT_RECORD Ir) +// PSETUP_ERROR_ROUTINE +static VOID +__cdecl +USetupErrorRoutine( + IN PUSETUP_DATA pSetupData, + ...) { - NTSTATUS Status; - INFCONTEXT DirContext; - PWCHAR AdditionalSectionName = NULL; - PWCHAR DirKeyValue; - WCHAR PathBuffer[MAX_PATH]; - - /* Add common files */ - if (!AddSectionToCopyQueue(InfFile, L"SourceDisksFiles", SourceCabinet, &USetupData.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, &USetupData.DestinationPath, Ir)) - return FALSE; - } - } - - /* Create directories */ - - /* - * FIXME: - * Copying files to USetupData.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 USetupData.DestinationPath specify just '\' . - */ - - /* Get destination path */ - StringCchCopyW(PathBuffer, ARRAYSIZE(PathBuffer), USetupData.DestinationPath.Buffer); - - DPRINT("FullPath(1): '%S'\n", PathBuffer); + INPUT_RECORD Ir; + va_list arg_ptr; - /* 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; - } + va_start(arg_ptr, pSetupData); - /* Search for the 'Directories' section */ - if (!SetupFindFirstLineW(InfFile, L"Directories", NULL, &DirContext)) + if (pSetupData->LastErrorNumber >= ERROR_SUCCESS && + pSetupData->LastErrorNumber < ERROR_LAST_ERROR_CODE) { - if (SourceCabinet) - { - MUIDisplayError(ERROR_CABINET_SECTION, Ir, POPUP_WAIT_ENTER); - } - else - { - MUIDisplayError(ERROR_TXTSETUP_SECTION, Ir, POPUP_WAIT_ENTER); - } - - return FALSE; + // Note: the "POPUP_WAIT_ENTER" actually depends on the LastErrorNumber... + MUIDisplayErrorV(pSetupData->LastErrorNumber, &Ir, POPUP_WAIT_ENTER, arg_ptr); } - /* 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)) - { - /* Installation path */ - DPRINT("InstallationPath: '%S'\n", DirKeyValue); - - StringCchCopyW(PathBuffer, ARRAYSIZE(PathBuffer), - USetupData.DestinationPath.Buffer); - - DPRINT("InstallationPath(2): '%S'\n", PathBuffer); - } - else if (DirKeyValue[0] == L'\\') - { - /* Absolute path */ - DPRINT("AbsolutePath: '%S'\n", DirKeyValue); - - CombinePaths(PathBuffer, ARRAYSIZE(PathBuffer), 2, - USetupData.DestinationRootPath.Buffer, DirKeyValue); - - DPRINT("AbsolutePath(2): '%S'\n", PathBuffer); - - Status = SetupCreateDirectory(PathBuffer); - if (!NT_SUCCESS(Status) && Status != STATUS_OBJECT_NAME_COLLISION) - { - INF_FreeData(DirKeyValue); - 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, - USetupData.DestinationPath.Buffer, DirKeyValue); - - DPRINT("RelativePath(2): '%S'\n", PathBuffer); - - Status = SetupCreateDirectory(PathBuffer); - if (!NT_SUCCESS(Status) && Status != STATUS_OBJECT_NAME_COLLISION) - { - INF_FreeData(DirKeyValue); - DPRINT("Creating directory '%S' failed: Status = 0x%08lx", PathBuffer, Status); - MUIDisplayError(ERROR_CREATE_DIR, Ir, POPUP_WAIT_ENTER); - return FALSE; - } - } - - INF_FreeData(DirKeyValue); - } while (SetupFindNextLine(&DirContext, &DirContext)); - - return TRUE; + va_end(arg_ptr); } - /* * Displays the PrepareCopyPage. * @@ -3729,8 +3498,7 @@ PrepareCopyPageInfFile(HINF InfFile, * QuitPage * * SIDEEFFECTS - * Inits SetupFileQueue - * Calls PrepareCopyPageInfFile + * Calls PrepareFileCopy * * RETURNS * Number of the next page. @@ -3738,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, - USetupData.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((PSTR)InfFileData, - InfFileSize, - NULL, - INF_STYLE_WIN4, - USetupData.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) { @@ -3856,7 +3556,6 @@ SetupUpdateMemoryInfo(IN PCOPYCONTEXT CopyContext, ProgressSetStep(CopyContext->MemoryBars[2], PerfInfo.AvailablePages); } - static UINT CALLBACK FileCopyCallback(PVOID Context, @@ -3864,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 */ @@ -3893,9 +3658,10 @@ FileCopyCallback(PVOID Context, ProgressNextStep(CopyContext->ProgressBar); SetupUpdateMemoryInfo(CopyContext, FALSE); break; + } } - return 0; + return FILEOP_DOIT; } @@ -3906,8 +3672,7 @@ FileCopyCallback(PVOID Context, * RegistryPage(At once) * * SIDEEFFECTS - * Calls SetupCommitFileQueueW - * Calls SetupCloseFileQueue + * Calls DoFileCopy * * RETURNS * Number of the next page. @@ -3916,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 = USetupData.DestinationRootPath.Buffer; - CopyContext.InstallPath = InstallPath.Buffer; CopyContext.TotalOperations = 0; CopyContext.CompletedOperations = 0; @@ -3937,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, @@ -3951,33 +3714,29 @@ 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]); @@ -3991,6 +3750,37 @@ FileCopyPage(PINPUT_RECORD Ir) } +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. * @@ -4000,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. @@ -4011,226 +3798,26 @@ FileCopyPage(PINPUT_RECORD Ir) static PAGE_NUMBER RegistryPage(PINPUT_RECORD Ir) { - NTSTATUS Status; - INFCONTEXT InfContext; - PWSTR Action; - PWSTR File; - PWSTR Section; - BOOLEAN Success; - BOOLEAN ShouldRepairRegistry = FALSE; - BOOLEAN Delete; + ULONG Error; MUIDisplayPage(REGISTRY_PAGE); - if (RepairUpdateFlag) - { - 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(&USetupData.DestinationPath, &ShouldRepairRegistry); - if (!NT_SUCCESS(Status)) - { - DPRINT1("VerifyRegistryHives failed, Status 0x%08lx\n", Status); - ShouldRepairRegistry = FALSE; - } - if (!ShouldRepairRegistry) - DPRINT1("No need to repair the registry\n"); - } - -DoUpdate: - /* Update the registry */ - CONSOLE_SetStatusText(MUIGetString(STRING_REGHIVEUPDATE)); - - /* Initialize the registry and setup the registry hives */ - Status = RegInitializeRegistry(&USetupData.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; } - - if (!RepairUpdateFlag || ShouldRepairRegistry) - { - /* - * We fully setup the hives, in case we are doing a fresh installation - * (RepairUpdateFlag == FALSE), or in case we are doing an update - * (RepairUpdateFlag == TRUE) BUT we have some registry hives to - * "repair" (aka. recreate: ShouldRepairRegistry == TRUE). - */ - - Success = SetupFindFirstLineW(SetupInf, L"HiveInfs.Fresh", NULL, &InfContext); // Windows-compatible - if (!Success) - Success = SetupFindFirstLineW(SetupInf, L"HiveInfs.Install", NULL, &InfContext); // ReactOS-specific - - if (!Success) - { - DPRINT1("SetupFindFirstLine() failed\n"); - MUIDisplayError(ERROR_FIND_REGISTRY, Ir, POPUP_WAIT_ENTER); - goto Cleanup; - } - } - else // if (RepairUpdateFlag && !ShouldRepairRegistry) - { - /* - * In case we are doing an update (RepairUpdateFlag == TRUE) and - * NO registry hives need a repair (ShouldRepairRegistry == FALSE), - * we only update the hives. - */ - - Success = SetupFindFirstLineW(SetupInf, L"HiveInfs.Upgrade", NULL, &InfContext); - if (!Success) - { - /* Nothing to do for update! */ - DPRINT1("No update needed for the registry!\n"); - goto Cleanup; - } - } - - do - { - 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) - { - INF_FreeData(Action); - INF_FreeData(File); - INF_FreeData(Section); - break; // Hackfix - } - - if (!_wcsicmp(Action, L"AddReg")) - Delete = FALSE; - else if (!_wcsicmp(Action, L"DelReg")) - Delete = TRUE; - else - { - DPRINT1("Unrecognized registry INF action '%S'\n", Action); - INF_FreeData(Action); - INF_FreeData(File); - INF_FreeData(Section); - continue; - } - - INF_FreeData(Action); - - CONSOLE_SetStatusText(MUIGetString(STRING_IMPORTFILE), File); - - if (!ImportRegistryFile(USetupData.SourcePath.Buffer, File, Section, USetupData.LanguageId, Delete)) - { - DPRINT1("Importing %S failed\n", File); - INF_FreeData(File); - INF_FreeData(Section); - MUIDisplayError(ERROR_IMPORT_HIVE, Ir, POPUP_WAIT_ENTER); - goto Cleanup; - } - } while (SetupFindNextLine(&InfContext, &InfContext)); - - if (!RepairUpdateFlag || ShouldRepairRegistry) - { - /* See the explanation for this test above */ - - /* 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(&USetupData.DestinationPath); - - /* - * Check whether we were in update/repair mode but we were actually - * repairing the registry hives. If so, we have finished repairing them, - * and we now reset the flag and run the proper registry update. - * Otherwise we have finished the registry update! - */ - if (RepairUpdateFlag && ShouldRepairRegistry) - { - ShouldRepairRegistry = FALSE; - goto DoUpdate; - } - - if (NT_SUCCESS(Status)) + else { CONSOLE_SetStatusText(MUIGetString(STRING_DONE)); return BOOT_LOADER_PAGE; } - else - { - return QUIT_PAGE; - } } @@ -4265,7 +3852,7 @@ BootLoaderPage(PINPUT_RECORD Ir) CONSOLE_SetStatusText(MUIGetString(STRING_PLEASEWAIT)); RtlFreeUnicodeString(&USetupData.SystemRootPath); - StringCchPrintfW(PathBuffer, ARRAYSIZE(PathBuffer), + RtlStringCchPrintfW(PathBuffer, ARRAYSIZE(PathBuffer), L"\\Device\\Harddisk%lu\\Partition%lu\\", PartitionList->SystemPartition->DiskEntry->DiskNumber, PartitionList->SystemPartition->PartitionNumber); @@ -4299,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) @@ -4481,16 +4068,14 @@ BootLoaderFloppyPage(PINPUT_RECORD Ir) } 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(&USetupData.SourceRootPath, &USetupData.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; } @@ -4520,13 +4105,15 @@ BootLoaderHarddiskVbrPage(PINPUT_RECORD Ir) { NTSTATUS Status; + // 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; } @@ -4553,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 */ + // 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, USetupData.SourceRootPath.Buffer, L"\\loader\\dosmbr.bin"); - - if (IsThereAValidBootSector(DestinationDevicePathBuffer)) - { - /* Save current MBR */ - CombinePaths(DstPath, ARRAYSIZE(DstPath), 2, USetupData.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; } @@ -4829,6 +4397,7 @@ QuitPage(PINPUT_RECORD Ir) DestroyPartitionList(PartitionList); PartitionList = NULL; } + TempPartition = NULL; FormatState = Start; @@ -4839,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 */ @@ -4955,7 +4489,7 @@ RunUSetup(VOID) 0, 0, PnpEventThread, - &SetupInf, + &USetupData.SetupInf, &hPnpThread, NULL); if (!NT_SUCCESS(Status)) @@ -4971,15 +4505,9 @@ RunUSetup(VOID) return STATUS_APP_INIT_FAILURE; } - /* Initialize global unicode strings */ - RtlInitUnicodeString(&USetupData.SourcePath, NULL); - RtlInitUnicodeString(&USetupData.SourceRootPath, NULL); - RtlInitUnicodeString(&USetupData.SourceRootDir, NULL); - RtlInitUnicodeString(&InstallPath, NULL); - RtlInitUnicodeString(&USetupData.DestinationPath, NULL); - RtlInitUnicodeString(&USetupData.DestinationArcPath, NULL); - RtlInitUnicodeString(&USetupData.DestinationRootPath, NULL); - RtlInitUnicodeString(&USetupData.SystemRootPath, NULL); + /* Initialize Setup, phase 0 */ + InitializeSetup(&USetupData, 0); + USetupData.ErrorRoutine = USetupErrorRoutine; /* Hide the cursor */ CONSOLE_SetCursorType(TRUE, FALSE); @@ -5144,7 +4672,8 @@ RunUSetup(VOID) } } - SetupCloseInfFile(SetupInf); + /* Setup has finished */ + FinishSetup(&USetupData); if (Page == RECOVERY_PAGE) RecoveryConsole();