From: Hermès Bélusca-Maïto Date: Wed, 9 Aug 2017 20:39:45 +0000 (+0000) Subject: [USETUP][SETUPLIB] Code refactoring. X-Git-Tag: 0.4.12-dev~407 X-Git-Url: https://git.reactos.org/?p=reactos.git;a=commitdiff_plain;h=7e248feabf1ed10b7015e3a5a7bd6fcc4eb07cd4 [USETUP][SETUPLIB] Code refactoring. - Move several global setup variables into a structure "USETUP_DATA", similar to the syssetup structure "SETUPDATA" (or the WIP 1st-stage installer structure of the same name), so that these variables can be set easily by different helper setup functions; - Move CheckUnattendedSetup() and GetSourcePaths() to setuplib and make CheckUnattendedSetup() use the USETUP_DATA structure; - Add a LoadSetupInf() function that loads the txtsetup.sif file (factoring out the corresponding code in USETUP); - Add a InstallSetupInfFile() function (that I'll probably rename later on) whose purpose is to create a valid "$winnt$.inf" setup installation file in the ReactOS\system32 directory, which should help the 2nd-stage installer to correctly retrieve the source installation media we used during 1st-stage, and contain the unattended setup lines copied from unattend.inf. This is done in a Windows-compatible way. svn path=/branches/setup_improvements/; revision=75518 [USETUP] Close the txtsetup.sif file at the end of the operations. svn path=/branches/setup_improvements/; revision=75539 --- diff --git a/base/setup/lib/CMakeLists.txt b/base/setup/lib/CMakeLists.txt index c1164c809dd..cf3f2b8a2a3 100644 --- a/base/setup/lib/CMakeLists.txt +++ b/base/setup/lib/CMakeLists.txt @@ -12,6 +12,7 @@ list(APPEND SOURCE partlist.c registry.c regutil.c + setuplib.c precomp.h) add_library(setuplib ${SOURCE}) diff --git a/base/setup/lib/setuplib.c b/base/setup/lib/setuplib.c new file mode 100644 index 00000000000..306065f99a7 --- /dev/null +++ b/base/setup/lib/setuplib.c @@ -0,0 +1,515 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Setup Library + * FILE: base/setup/lib/setuplib.c + * PURPOSE: Setup Library - Main initialization helpers + * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net) + * Hermes Belusca-Maito (hermes.belusca@sfr.fr) + */ + +/* INCLUDES *****************************************************************/ + +#include "precomp.h" +#include "filesup.h" +#include "infsupp.h" +#include "inicache.h" + +#include "setuplib.h" + +// HACK! +#include + +#define NDEBUG +#include + + +/* GLOBALS ******************************************************************/ + +/* FUNCTIONS ****************************************************************/ + +VOID +CheckUnattendedSetup( + IN OUT PUSETUP_DATA pSetupData) +{ + INFCONTEXT Context; + HINF UnattendInf; + UINT ErrorLine; + INT IntValue; + PWCHAR Value; + WCHAR UnattendInfPath[MAX_PATH]; + + CombinePaths(UnattendInfPath, ARRAYSIZE(UnattendInfPath), 2, + pSetupData->SourcePath.Buffer, L"unattend.inf"); + + if (DoesFileExist(NULL, UnattendInfPath) == FALSE) + { + DPRINT("Does not exist: %S\n", UnattendInfPath); + return; + } + + /* Load 'unattend.inf' from installation media */ + UnattendInf = SetupOpenInfFileExW(UnattendInfPath, + NULL, + INF_STYLE_WIN4, + pSetupData->LanguageId, + &ErrorLine); + + if (UnattendInf == INVALID_HANDLE_VALUE) + { + DPRINT("SetupOpenInfFileExW() failed\n"); + return; + } + + /* Open 'Unattend' section */ + if (!SetupFindFirstLineW(UnattendInf, L"Unattend", L"Signature", &Context)) + { + DPRINT("SetupFindFirstLineW() failed for section 'Unattend'\n"); + goto Quit; + } + + /* Get pointer 'Signature' key */ + if (!INF_GetData(&Context, NULL, &Value)) + { + DPRINT("INF_GetData() failed for key 'Signature'\n"); + goto Quit; + } + + /* Check 'Signature' string */ + if (_wcsicmp(Value, L"$ReactOS$") != 0) + { + DPRINT("Signature not $ReactOS$\n"); + INF_FreeData(Value); + goto Quit; + } + + INF_FreeData(Value); + + /* Check if Unattend setup is enabled */ + if (!SetupFindFirstLineW(UnattendInf, L"Unattend", L"UnattendSetupEnabled", &Context)) + { + DPRINT("Can't find key 'UnattendSetupEnabled'\n"); + goto Quit; + } + + if (!INF_GetData(&Context, NULL, &Value)) + { + DPRINT("Can't read key 'UnattendSetupEnabled'\n"); + goto Quit; + } + + if (_wcsicmp(Value, L"yes") != 0) + { + DPRINT("Unattend setup is disabled by 'UnattendSetupEnabled' key!\n"); + INF_FreeData(Value); + goto Quit; + } + + INF_FreeData(Value); + + /* Search for 'DestinationDiskNumber' in the 'Unattend' section */ + if (!SetupFindFirstLineW(UnattendInf, L"Unattend", L"DestinationDiskNumber", &Context)) + { + DPRINT("SetupFindFirstLine() failed for key 'DestinationDiskNumber'\n"); + goto Quit; + } + + if (!SetupGetIntField(&Context, 1, &IntValue)) + { + DPRINT("SetupGetIntField() failed for key 'DestinationDiskNumber'\n"); + goto Quit; + } + + pSetupData->DestinationDiskNumber = (LONG)IntValue; + + /* Search for 'DestinationPartitionNumber' in the 'Unattend' section */ + if (!SetupFindFirstLineW(UnattendInf, L"Unattend", L"DestinationPartitionNumber", &Context)) + { + DPRINT("SetupFindFirstLine() failed for key 'DestinationPartitionNumber'\n"); + goto Quit; + } + + if (!SetupGetIntField(&Context, 1, &IntValue)) + { + DPRINT("SetupGetIntField() failed for key 'DestinationPartitionNumber'\n"); + goto Quit; + } + + pSetupData->DestinationPartitionNumber = (LONG)IntValue; + + /* Search for 'InstallationDirectory' in the 'Unattend' section (optional) */ + if (SetupFindFirstLineW(UnattendInf, L"Unattend", L"InstallationDirectory", &Context)) + { + /* Get pointer 'InstallationDirectory' key */ + if (!INF_GetData(&Context, NULL, &Value)) + { + DPRINT("INF_GetData() failed for key 'InstallationDirectory'\n"); + goto Quit; + } + wcscpy(pSetupData->InstallationDirectory, Value); + INF_FreeData(Value); + } + + IsUnattendedSetup = TRUE; + DPRINT("Running unattended setup\n"); + + /* Search for 'MBRInstallType' in the 'Unattend' section */ + pSetupData->MBRInstallType = -1; + if (SetupFindFirstLineW(UnattendInf, L"Unattend", L"MBRInstallType", &Context)) + { + if (SetupGetIntField(&Context, 1, &IntValue)) + { + pSetupData->MBRInstallType = IntValue; + } + } + + /* Search for 'FormatPartition' in the 'Unattend' section */ + pSetupData->FormatPartition = 0; + if (SetupFindFirstLineW(UnattendInf, L"Unattend", L"FormatPartition", &Context)) + { + if (SetupGetIntField(&Context, 1, &IntValue)) + { + pSetupData->FormatPartition = IntValue; + } + } + + pSetupData->AutoPartition = 0; + if (SetupFindFirstLineW(UnattendInf, L"Unattend", L"AutoPartition", &Context)) + { + if (SetupGetIntField(&Context, 1, &IntValue)) + { + pSetupData->AutoPartition = IntValue; + } + } + + /* 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(pSetupData->LocaleID, L"%08lx", Id); + INF_FreeData(Value); + } + } + +Quit: + SetupCloseInfFile(UnattendInf); +} + +VOID +InstallSetupInfFile( + IN OUT PUSETUP_DATA pSetupData) +{ + NTSTATUS Status; + PINICACHE IniCache; + +#if 0 // HACK FIXME! + PINICACHE UnattendCache; + PINICACHEITERATOR Iterator; +#else + // PCWSTR CrLf = L"\r\n"; + PCSTR CrLf = "\r\n"; + HANDLE FileHandle, UnattendFileHandle, SectionHandle; + FILE_STANDARD_INFORMATION FileInfo; + ULONG FileSize; + PVOID ViewBase; + UNICODE_STRING FileName; + OBJECT_ATTRIBUTES ObjectAttributes; + IO_STATUS_BLOCK IoStatusBlock; +#endif + + PINICACHESECTION IniSection; + WCHAR PathBuffer[MAX_PATH]; + WCHAR UnattendInfPath[MAX_PATH]; + + /* Create a $winnt$.inf file with default entries */ + IniCache = IniCacheCreate(); + if (!IniCache) + return; + + IniSection = IniCacheAppendSection(IniCache, L"SetupParams"); + if (IniSection) + { + /* Key "skipmissingfiles" */ + // StringCchPrintfW(PathBuffer, ARRAYSIZE(PathBuffer), + // L"\"%s\"", L"WinNt5.2"); + // IniCacheInsertKey(IniSection, NULL, INSERT_LAST, + // L"Version", PathBuffer); + } + + IniSection = IniCacheAppendSection(IniCache, L"Data"); + if (IniSection) + { + StringCchPrintfW(PathBuffer, ARRAYSIZE(PathBuffer), + L"\"%s\"", IsUnattendedSetup ? L"yes" : L"no"); + IniCacheInsertKey(IniSection, NULL, INSERT_LAST, + L"UnattendedInstall", PathBuffer); + + // "floppylessbootpath" (yes/no) + + StringCchPrintfW(PathBuffer, ARRAYSIZE(PathBuffer), + L"\"%s\"", L"winnt"); + IniCacheInsertKey(IniSection, NULL, INSERT_LAST, + L"ProductType", PathBuffer); + + StringCchPrintfW(PathBuffer, ARRAYSIZE(PathBuffer), + L"\"%s\\\"", pSetupData->SourceRootPath.Buffer); + IniCacheInsertKey(IniSection, NULL, INSERT_LAST, + L"SourcePath", PathBuffer); + + // "floppyless" ("0") + } + +#if 0 + + /* TODO: Append the standard unattend.inf file */ + CombinePaths(UnattendInfPath, ARRAYSIZE(UnattendInfPath), 2, pSetupData->SourcePath.Buffer, L"unattend.inf"); + if (DoesFileExist(NULL, UnattendInfPath) == FALSE) + { + DPRINT("Does not exist: %S\n", UnattendInfPath); + goto Quit; + } + + Status = IniCacheLoad(&UnattendCache, UnattendInfPath, FALSE); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Cannot load %S as an INI file!\n", UnattendInfPath); + goto Quit; + } + + IniCacheDestroy(UnattendCache); + +Quit: + CombinePaths(PathBuffer, ARRAYSIZE(PathBuffer), 2, + pSetupData->DestinationPath.Buffer, L"System32\\$winnt$.inf"); + IniCacheSave(IniCache, PathBuffer); + IniCacheDestroy(IniCache); + +#else + + CombinePaths(PathBuffer, ARRAYSIZE(PathBuffer), 2, + pSetupData->DestinationPath.Buffer, L"System32\\$winnt$.inf"); + IniCacheSave(IniCache, PathBuffer); + IniCacheDestroy(IniCache); + + /* TODO: Append the standard unattend.inf file */ + CombinePaths(UnattendInfPath, ARRAYSIZE(UnattendInfPath), 2, + pSetupData->SourcePath.Buffer, L"unattend.inf"); + if (DoesFileExist(NULL, UnattendInfPath) == FALSE) + { + DPRINT("Does not exist: %S\n", UnattendInfPath); + return; + } + + RtlInitUnicodeString(&FileName, PathBuffer); + InitializeObjectAttributes(&ObjectAttributes, + &FileName, + OBJ_CASE_INSENSITIVE | OBJ_OPENIF, + NULL, + NULL); + Status = NtOpenFile(&FileHandle, + FILE_APPEND_DATA | SYNCHRONIZE, + &ObjectAttributes, + &IoStatusBlock, + FILE_SHARE_READ, + FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Cannot load %S as an INI file!\n", PathBuffer); + return; + } + + /* Query the file size */ + Status = NtQueryInformationFile(FileHandle, + &IoStatusBlock, + &FileInfo, + sizeof(FileInfo), + FileStandardInformation); + if (!NT_SUCCESS(Status)) + { + DPRINT("NtQueryInformationFile() failed (Status %lx)\n", Status); + FileInfo.EndOfFile.QuadPart = 0ULL; + } + + Status = OpenAndMapFile(NULL, + UnattendInfPath, + &UnattendFileHandle, + &SectionHandle, + &ViewBase, + &FileSize, + FALSE); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Cannot load %S !\n", UnattendInfPath); + NtClose(FileHandle); + return; + } + + /* Write to the INI file */ + + /* "\r\n" */ + Status = NtWriteFile(FileHandle, + NULL, + NULL, + NULL, + &IoStatusBlock, + (PVOID)CrLf, + 2 * sizeof(CHAR), // 2 * sizeof(WCHAR), + &FileInfo.EndOfFile, + NULL); + + Status = NtWriteFile(FileHandle, + NULL, + NULL, + NULL, + &IoStatusBlock, + ViewBase, + FileSize, + NULL, + NULL); + if (!NT_SUCCESS(Status)) + { + DPRINT("NtWriteFile() failed (Status %lx)\n", Status); + } + + /* Finally, unmap and close the file */ + UnMapFile(SectionHandle, ViewBase); + NtClose(UnattendFileHandle); + + NtClose(FileHandle); +#endif +} + + + +NTSTATUS +GetSourcePaths( + OUT PUNICODE_STRING SourcePath, + OUT PUNICODE_STRING SourceRootPath, + OUT PUNICODE_STRING SourceRootDir) +{ + NTSTATUS Status; + OBJECT_ATTRIBUTES ObjectAttributes; + UNICODE_STRING LinkName = RTL_CONSTANT_STRING(L"\\SystemRoot"); + UNICODE_STRING SourceName; + WCHAR SourceBuffer[MAX_PATH] = L""; + HANDLE Handle; + ULONG Length; + PWCHAR Ptr; + + InitializeObjectAttributes(&ObjectAttributes, + &LinkName, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + + Status = NtOpenSymbolicLinkObject(&Handle, + SYMBOLIC_LINK_ALL_ACCESS, + &ObjectAttributes); + if (!NT_SUCCESS(Status)) + return Status; + + RtlInitEmptyUnicodeString(&SourceName, SourceBuffer, sizeof(SourceBuffer)); + + Status = NtQuerySymbolicLinkObject(Handle, + &SourceName, + &Length); + NtClose(Handle); + + if (!NT_SUCCESS(Status)) + return Status; + + RtlCreateUnicodeString(SourcePath, + SourceName.Buffer); + + /* Strip trailing directory */ + Ptr = wcsrchr(SourceName.Buffer, OBJ_NAME_PATH_SEPARATOR); + if (Ptr) + { + RtlCreateUnicodeString(SourceRootDir, Ptr); + *Ptr = UNICODE_NULL; + } + else + { + RtlCreateUnicodeString(SourceRootDir, L""); + } + + RtlCreateUnicodeString(SourceRootPath, + SourceName.Buffer); + + return STATUS_SUCCESS; +} + + +ERROR_NUMBER +LoadSetupInf( + OUT HINF* SetupInf, + IN OUT PUSETUP_DATA pSetupData) +{ + INFCONTEXT Context; + UINT ErrorLine; + INT IntValue; + PWCHAR Value; + WCHAR FileNameBuffer[MAX_PATH]; + + CombinePaths(FileNameBuffer, ARRAYSIZE(FileNameBuffer), 2, + pSetupData->SourcePath.Buffer, L"txtsetup.sif"); + + *SetupInf = SetupOpenInfFileExW(FileNameBuffer, + NULL, + INF_STYLE_WIN4, + pSetupData->LanguageId, + &ErrorLine); + + if (*SetupInf == INVALID_HANDLE_VALUE) + return ERROR_LOAD_TXTSETUPSIF; + + /* Open 'Version' section */ + if (!SetupFindFirstLineW(*SetupInf, L"Version", L"Signature", &Context)) + return ERROR_CORRUPT_TXTSETUPSIF; + + /* Get pointer 'Signature' key */ + if (!INF_GetData(&Context, NULL, &Value)) + return ERROR_CORRUPT_TXTSETUPSIF; + + /* Check 'Signature' string */ + if (_wcsicmp(Value, L"$ReactOS$") != 0) + { + INF_FreeData(Value); + return ERROR_SIGNATURE_TXTSETUPSIF; + } + + INF_FreeData(Value); + + /* Open 'DiskSpaceRequirements' section */ + if (!SetupFindFirstLineW(*SetupInf, L"DiskSpaceRequirements", L"FreeSysPartDiskSpace", &Context)) + return ERROR_CORRUPT_TXTSETUPSIF; + + pSetupData->RequiredPartitionDiskSpace = ~0; + + /* Get the 'FreeSysPartDiskSpace' value */ + if (!SetupGetIntField(&Context, 1, &IntValue)) + return ERROR_CORRUPT_TXTSETUPSIF; + + pSetupData->RequiredPartitionDiskSpace = (ULONG)IntValue; + + // + // TODO: Support "SetupSourceDevice" and "SetupSourcePath" in txtsetup.sif + // See CORE-9023 + // + + /* Search for 'DefaultPath' in the 'SetupData' section */ + if (SetupFindFirstLineW(*SetupInf, L"SetupData", L"DefaultPath", &Context)) + { + /* Get pointer 'DefaultPath' key */ + if (!INF_GetData(&Context, NULL, &Value)) + return ERROR_CORRUPT_TXTSETUPSIF; + + wcscpy(pSetupData->InstallationDirectory, Value); + INF_FreeData(Value); + } + + return ERROR_SUCCESS; +} + +/* EOF */ diff --git a/base/setup/lib/setuplib.h b/base/setup/lib/setuplib.h index 223a1ac6d58..154b1d5f257 100644 --- a/base/setup/lib/setuplib.h +++ b/base/setup/lib/setuplib.h @@ -32,6 +32,7 @@ extern HANDLE ProcessHeap; #include "filesup.h" #include "fsutil.h" #include "genlist.h" +#include "infsupp.h" #include "inicache.h" #include "partlist.h" #include "arcname.h" @@ -49,4 +50,74 @@ extern HANDLE ProcessHeap; // #define PB (KB*KB*KB*KB*KB) +/* TYPEDEFS *****************************************************************/ + +typedef struct _USETUP_DATA +{ +/* SOURCE Paths *****/ + UNICODE_STRING SourceRootPath; + UNICODE_STRING SourceRootDir; + UNICODE_STRING SourcePath; + +/* DESTINATION Paths *****/ + /* + * 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 + */ + UNICODE_STRING SystemRootPath; + + /* Path to the installation directory inside the ReactOS boot partition */ + UNICODE_STRING DestinationPath; /** Equivalent of 'NTOS_INSTALLATION::SystemNtPath' **/ + UNICODE_STRING DestinationArcPath; /** Equivalent of 'NTOS_INSTALLATION::SystemArcPath' **/ + UNICODE_STRING DestinationRootPath; + + LONG DestinationDiskNumber; + LONG DestinationPartitionNumber; + LONG MBRInstallType; + + LONG FormatPartition; + LONG AutoPartition; + + WCHAR LocaleID[9]; + LANGID LanguageId; + + ULONG RequiredPartitionDiskSpace; + WCHAR InstallationDirectory[MAX_PATH]; +} USETUP_DATA, *PUSETUP_DATA; + +// HACK!! +extern BOOLEAN IsUnattendedSetup; + + +/* FUNCTIONS ****************************************************************/ + +VOID +CheckUnattendedSetup( + IN OUT PUSETUP_DATA pSetupData); + +VOID +InstallSetupInfFile( + IN OUT PUSETUP_DATA pSetupData); + +NTSTATUS +GetSourcePaths( + OUT PUNICODE_STRING SourcePath, + OUT PUNICODE_STRING SourceRootPath, + OUT PUNICODE_STRING SourceRootDir); + +ERROR_NUMBER +LoadSetupInf( + OUT HINF* SetupInf, + IN OUT PUSETUP_DATA pSetupData); + + /* EOF */ diff --git a/base/setup/usetup/usetup.c b/base/setup/usetup/usetup.c index c87a3fecc87..af5708ffc50 100644 --- a/base/setup/usetup/usetup.c +++ b/base/setup/usetup/usetup.c @@ -41,36 +41,12 @@ #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; - - -/* LOCALS *******************************************************************/ - -static PFILE_SYSTEM_LIST FileSystemList = NULL; +static USETUP_DATA USetupData; /* * NOTE: Technically only used for the COPYCONTEXT InstallPath member @@ -78,29 +54,27 @@ static PFILE_SYSTEM_LIST FileSystemList = NULL; */ 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; - -/* Path to the installation directory inside the ReactOS boot partition */ -static UNICODE_STRING DestinationPath; -static UNICODE_STRING DestinationArcPath; -static UNICODE_STRING DestinationRootPath; - // FIXME: Is it really useful?? Just used for SetDefaultPagefile... static WCHAR DestinationDriveLetter; + +/* OTHER Stuff *****/ + +PWCHAR SelectedLanguageId; +static WCHAR DefaultLanguage[20]; // Copy of string inside LanguageList +static WCHAR DefaultKBLayout[20]; // Copy of string inside KeyboardList + +static BOOLEAN RepairUpdateFlag = FALSE; + +static HANDLE hPnpThread = NULL; + +static PPARTLIST PartitionList = NULL; +static PPARTENTRY TempPartition = NULL; +static PFILE_SYSTEM_LIST FileSystemList = NULL; +static FORMATMACHINESTATE FormatState = Start; + +/*****************************************************/ + static HINF SetupInf; static HSPFILEQ SetupFileQueue = NULL; @@ -114,9 +88,6 @@ static PGENERIC_LIST KeyboardList = NULL; static PGENERIC_LIST LayoutList = NULL; static PGENERIC_LIST LanguageList = NULL; -static LANGID LanguageId = 0; - -static ULONG RequiredPartitionDiskSpace = ~0; /* FUNCTIONS ****************************************************************/ @@ -273,7 +244,7 @@ PopupError(PCCH Text, if (Length > MaxLength) MaxLength = Length; - if (LastLine != FALSE) + if (LastLine) break; pnext = p + 1; @@ -339,7 +310,7 @@ PopupError(PCCH Text, &Written); } - if (LastLine != FALSE) + if (LastLine) break; coPos.Y++; @@ -429,178 +400,6 @@ ConfirmQuit(PINPUT_RECORD Ir) } -static VOID -CheckUnattendedSetup(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 = SetupOpenInfFileExW(UnattendInfPath, - NULL, - INF_STYLE_WIN4, - LanguageId, - &ErrorLine); - - if (UnattendInf == INVALID_HANDLE_VALUE) - { - DPRINT("SetupOpenInfFileExW() 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"); - - /* Search for 'MBRInstallType' in the 'Unattend' section */ - if (SetupFindFirstLineW(UnattendInf, L"Unattend", L"MBRInstallType", &Context)) - { - if (SetupGetIntField(&Context, 1, &IntValue)) - { - UnattendMBRInstallType = IntValue; - } - } - - /* Search for 'FormatPartition' in the 'Unattend' section */ - if (SetupFindFirstLineW(UnattendInf, L"Unattend", L"FormatPartition", &Context)) - { - if (SetupGetIntField(&Context, 1, &IntValue)) - { - UnattendFormatPartition = IntValue; - } - } - - if (SetupFindFirstLineW(UnattendInf, L"Unattend", L"AutoPartition", &Context)) - { - if (SetupGetIntField(&Context, 1, &IntValue)) - { - AutoPartition = IntValue; - } - } - - /* 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) { @@ -645,7 +444,7 @@ UpdateKBLayout(VOID) * * SIDEEFFECTS * Init SelectedLanguageId - * Init LanguageId + * Init USetupData.LanguageId * * RETURNS * Number of the next page. @@ -669,6 +468,7 @@ LanguagePage(PINPUT_RECORD Ir) } /* Load the font */ + USetupData.LanguageId = 0; SelectedLanguageId = DefaultLanguage; SetConsoleCodePage(); UpdateKBLayout(); @@ -677,7 +477,7 @@ LanguagePage(PINPUT_RECORD Ir) * the language selection process altogether! */ if (GenericListHasSingleEntry(LanguageList)) { - LanguageId = (LANGID)(wcstol(SelectedLanguageId, NULL, 16) & 0xFFFF); + USetupData.LanguageId = (LANGID)(wcstol(SelectedLanguageId, NULL, 16) & 0xFFFF); return WELCOME_PAGE; } @@ -723,7 +523,7 @@ 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); @@ -732,7 +532,7 @@ LanguagePage(PINPUT_RECORD Ir) { SelectedLanguageId = (PWCHAR)GetListEntryUserData(GetCurrentListEntry(LanguageList)); - LanguageId = (LANGID)(wcstol(SelectedLanguageId, NULL, 16) & 0xFFFF); + USetupData.LanguageId = (LANGID)(wcstol(SelectedLanguageId, NULL, 16) & 0xFFFF); if (wcscmp(SelectedLanguageId, DefaultLanguage)) { @@ -777,65 +577,6 @@ LanguagePage(PINPUT_RECORD Ir) } -static NTSTATUS -GetSourcePaths( - OUT PUNICODE_STRING SourcePath, - OUT PUNICODE_STRING SourceRootPath, - OUT PUNICODE_STRING SourceRootDir) -{ - NTSTATUS Status; - OBJECT_ATTRIBUTES ObjectAttributes; - UNICODE_STRING LinkName = RTL_CONSTANT_STRING(L"\\SystemRoot"); - UNICODE_STRING SourceName; - WCHAR SourceBuffer[MAX_PATH] = L""; - HANDLE Handle; - ULONG Length; - PWCHAR Ptr; - - InitializeObjectAttributes(&ObjectAttributes, - &LinkName, - OBJ_CASE_INSENSITIVE, - NULL, - NULL); - - Status = NtOpenSymbolicLinkObject(&Handle, - SYMBOLIC_LINK_ALL_ACCESS, - &ObjectAttributes); - if (!NT_SUCCESS(Status)) - return Status; - - RtlInitEmptyUnicodeString(&SourceName, SourceBuffer, sizeof(SourceBuffer)); - - Status = NtQuerySymbolicLinkObject(Handle, - &SourceName, - &Length); - NtClose(Handle); - - if (!NT_SUCCESS(Status)) - return Status; - - RtlCreateUnicodeString(SourcePath, - SourceName.Buffer); - - /* Strip trailing directory */ - Ptr = wcsrchr(SourceName.Buffer, OBJ_NAME_PATH_SEPARATOR); - if (Ptr) - { - RtlCreateUnicodeString(SourceRootDir, Ptr); - *Ptr = UNICODE_NULL; - } - else - { - RtlCreateUnicodeString(SourceRootDir, L""); - } - - RtlCreateUnicodeString(SourceRootPath, - SourceName.Buffer); - - return STATUS_SUCCESS; -} - - /* * Start page * @@ -846,15 +587,15 @@ GetSourcePaths( * * SIDEEFFECTS * Init Sdi - * Init SourcePath - * Init SourceRootPath - * Init SourceRootDir + * Init USetupData.SourcePath + * Init USetupData.SourceRootPath + * Init USetupData.SourceRootDir * Init SetupInf - * Init RequiredPartitionDiskSpace + * 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. @@ -863,80 +604,33 @@ 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; CONSOLE_SetStatusText(MUIGetString(STRING_PLEASEWAIT)); /* Get the source path and source root path */ - Status = GetSourcePaths(&SourcePath, - &SourceRootPath, - &SourceRootDir); + 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", &SourcePath); - DPRINT1("SourceRootPath: '%wZ'\n", &SourceRootPath); - DPRINT1("SourceRootDir: '%wZ'\n", &SourceRootDir); + DPRINT1("SourcePath: '%wZ'\n", &USetupData.SourcePath); + DPRINT1("SourceRootPath: '%wZ'\n", &USetupData.SourceRootPath); + DPRINT1("SourceRootDir: '%wZ'\n", &USetupData.SourceRootDir); - /* Load txtsetup.sif from install media. */ - CombinePaths(FileNameBuffer, ARRAYSIZE(FileNameBuffer), 2, SourcePath.Buffer, L"txtsetup.sif"); - SetupInf = SetupOpenInfFileExW(FileNameBuffer, - NULL, - INF_STYLE_WIN4, - LanguageId, - &ErrorLine); - - if (SetupInf == INVALID_HANDLE_VALUE) + /* Load 'txtsetup.sif' from the installation media */ + Error = LoadSetupInf(&SetupInf, &USetupData); + if (Error != ERROR_SUCCESS) { - MUIDisplayError(ERROR_LOAD_TXTSETUPSIF, Ir, POPUP_WAIT_ENTER); + MUIDisplayError(Error, 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)) - { - MUIDisplayError(ERROR_CORRUPT_TXTSETUPSIF, 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 != NULL) { @@ -944,7 +638,7 @@ SetupStartPage(PINPUT_RECORD Ir) hPnpThread = NULL; } - CheckUnattendedSetup(); + CheckUnattendedSetup(&USetupData); if (IsUnattendedSetup) { @@ -956,14 +650,14 @@ SetupStartPage(PINPUT_RECORD Ir) LanguageList = CreateLanguageList(SetupInf, DefaultLanguage); /* new part */ - wcscpy(SelectedLanguageId, LocaleID); - LanguageId = (LANGID)(wcstol(SelectedLanguageId, NULL, 16) & 0xFFFF); + wcscpy(SelectedLanguageId, USetupData.LocaleID); + USetupData.LanguageId = (LANGID)(wcstol(SelectedLanguageId, NULL, 16) & 0xFFFF); /* first we hack LanguageList */ ListEntry = GetFirstListEntry(LanguageList); while (ListEntry != NULL) { - if (!wcsicmp(LocaleID, GetListEntryUserData(ListEntry))) + if (!wcsicmp(USetupData.LocaleID, GetListEntryUserData(ListEntry))) { DPRINT("found %S in LanguageList\n",GetListEntryUserData(ListEntry)); SetCurrentListEntry(LanguageList, ListEntry); @@ -977,7 +671,7 @@ SetupStartPage(PINPUT_RECORD Ir) ListEntry = GetFirstListEntry(LayoutList); while (ListEntry != NULL) { - if (!wcsicmp(LocaleID, GetListEntryUserData(ListEntry))) + if (!wcsicmp(USetupData.LocaleID, GetListEntryUserData(ListEntry))) { DPRINT("found %S in LayoutList\n",GetListEntryUserData(ListEntry)); SetCurrentListEntry(LayoutList, ListEntry); @@ -1021,7 +715,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; @@ -1199,7 +893,7 @@ UpgradeRepairPage(PINPUT_RECORD Ir) break; case VK_F3: /* F3 */ { - if (ConfirmQuit(Ir) == TRUE) + if (ConfirmQuit(Ir)) return QUIT_PAGE; else RedrawGenericList(&ListUi); @@ -1286,7 +980,7 @@ InstallIntroPage(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; @@ -1323,7 +1017,7 @@ ScsiControllerPage(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; @@ -1355,7 +1049,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; @@ -1492,7 +1186,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; @@ -1556,7 +1250,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); @@ -1704,10 +1398,10 @@ IsDiskSizeValid(PPARTENTRY PartEntry) size = PartEntry->SectorCount.QuadPart * PartEntry->DiskEntry->BytesPerSector; 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 @@ -1786,9 +1480,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) { @@ -1807,7 +1503,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 */ } @@ -1822,7 +1518,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 */ } @@ -1872,7 +1568,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; @@ -1916,7 +1612,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 */ } @@ -1952,7 +1648,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) @@ -2276,14 +1972,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; } @@ -2435,14 +2131,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; } @@ -2593,14 +2289,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; } @@ -2672,7 +2368,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; @@ -2819,7 +2515,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; @@ -2845,8 +2541,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 @@ -3009,7 +2705,7 @@ SelectFileSystemPage(PINPUT_RECORD Ir) PartTypeString, ARRAYSIZE(PartTypeString)); - if (PartEntry->AutoCreate != FALSE) + if (PartEntry->AutoCreate) { CONSOLE_SetTextXY(6, 8, MUIGetString(STRING_NEWPARTITION)); @@ -3035,7 +2731,7 @@ SelectFileSystemPage(PINPUT_RECORD Ir) PartEntry->AutoCreate = FALSE; } - else if (PartEntry->New != FALSE) + else if (PartEntry->New) { switch (FormatState) { @@ -3114,7 +2810,7 @@ SelectFileSystemPage(PINPUT_RECORD Ir) if (IsUnattendedSetup) { - if (UnattendFormatPartition) + if (USetupData.FormatPartition) { /* * We use whatever currently selected file system we have @@ -3138,7 +2834,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; @@ -3184,7 +2880,7 @@ SelectFileSystemPage(PINPUT_RECORD Ir) * * SIDEEFFECTS * Sets PartitionList->CurrentPartition->FormatState - * Sets DestinationRootPath + * Sets USetupData.DestinationRootPath * * RETURNS * Number of the next page. @@ -3230,7 +2926,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; @@ -3443,31 +3139,31 @@ BuildInstallPaths(PWSTR InstallDir, RtlFreeUnicodeString(&InstallPath); RtlCreateUnicodeString(&InstallPath, InstallDir); - /* Create 'DestinationRootPath' string */ - RtlFreeUnicodeString(&DestinationRootPath); + /* Create 'USetupData.DestinationRootPath' string */ + RtlFreeUnicodeString(&USetupData.DestinationRootPath); StringCchPrintfW(PathBuffer, ARRAYSIZE(PathBuffer), L"\\Device\\Harddisk%lu\\Partition%lu\\", DiskEntry->DiskNumber, PartEntry->PartitionNumber); - RtlCreateUnicodeString(&DestinationRootPath, PathBuffer); - DPRINT("DestinationRootPath: %wZ\n", &DestinationRootPath); + RtlCreateUnicodeString(&USetupData.DestinationRootPath, PathBuffer); + DPRINT("DestinationRootPath: %wZ\n", &USetupData.DestinationRootPath); /** Equivalent of 'NTOS_INSTALLATION::SystemNtPath' **/ - /* Create 'DestinationPath' string */ - RtlFreeUnicodeString(&DestinationPath); + /* Create 'USetupData.DestinationPath' string */ + RtlFreeUnicodeString(&USetupData.DestinationPath); CombinePaths(PathBuffer, ARRAYSIZE(PathBuffer), 2, - DestinationRootPath.Buffer, InstallDir); - RtlCreateUnicodeString(&DestinationPath, PathBuffer); + USetupData.DestinationRootPath.Buffer, InstallDir); + RtlCreateUnicodeString(&USetupData.DestinationPath, PathBuffer); /** Equivalent of 'NTOS_INSTALLATION::SystemArcPath' **/ - /* Create 'DestinationArcPath' */ - RtlFreeUnicodeString(&DestinationArcPath); + /* 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(&DestinationArcPath, PathBuffer); + RtlCreateUnicodeString(&USetupData.DestinationArcPath, PathBuffer); /* Initialize DestinationDriveLetter */ DestinationDriveLetter = (WCHAR)PartEntry->DriveLetter; @@ -3489,7 +3185,7 @@ InstallDirectoryPage(PINPUT_RECORD Ir) { PDISKENTRY DiskEntry; PPARTENTRY PartEntry; - WCHAR InstallDir[51]; + WCHAR InstallDir[MAX_PATH]; WCHAR c; ULONG Length, Pos; @@ -3511,10 +3207,11 @@ InstallDirectoryPage(PINPUT_RECORD Ir) DiskEntry = PartitionList->CurrentDisk; PartEntry = PartitionList->CurrentPartition; - if (IsUnattendedSetup) - wcscpy(InstallDir, UnattendInstallationDirectory); - else if (RepairUpdateFlag) + // if (IsUnattendedSetup) + if (RepairUpdateFlag) wcscpy(InstallDir, CurrentInstallation->PathComponent); // SystemNtPath + else if (USetupData.InstallationDirectory[0]) + wcscpy(InstallDir, USetupData.InstallationDirectory); else wcscpy(InstallDir, L"\\ReactOS"); @@ -3551,7 +3248,7 @@ InstallDirectoryPage(PINPUT_RECORD Ir) { CONSOLE_SetCursorType(TRUE, FALSE); - if (ConfirmQuit(Ir) != FALSE) + if (ConfirmQuit(Ir)) return QUIT_PAGE; CONSOLE_SetCursorType(TRUE, TRUE); @@ -3737,8 +3434,8 @@ AddSectionToCopyQueueCab(HINF InfFile, if (!SetupQueueCopy(SetupFileQueue, SourceCabinet, - SourceRootPath.Buffer, - SourceRootDir.Buffer, + USetupData.SourceRootPath.Buffer, + USetupData.SourceRootDir.Buffer, FileKeyName, DirKeyValue, TargetFileName)) @@ -3846,7 +3543,7 @@ AddSectionToCopyQueue(HINF InfFile, DPRINT("InstallationPath: '%S'\n", DirKeyValue); StringCchCopyW(CompleteOrigDirName, ARRAYSIZE(CompleteOrigDirName), - SourceRootDir.Buffer); + USetupData.SourceRootDir.Buffer); DPRINT("InstallationPath(2): '%S'\n", CompleteOrigDirName); } @@ -3866,14 +3563,14 @@ AddSectionToCopyQueue(HINF InfFile, DPRINT("RelativePath: '%S'\n", DirKeyValue); CombinePaths(CompleteOrigDirName, ARRAYSIZE(CompleteOrigDirName), 2, - SourceRootDir.Buffer, DirKeyValue); + USetupData.SourceRootDir.Buffer, DirKeyValue); DPRINT("RelativePath(2): '%S'\n", CompleteOrigDirName); } if (!SetupQueueCopy(SetupFileQueue, SourceCabinet, - SourceRootPath.Buffer, + USetupData.SourceRootPath.Buffer, CompleteOrigDirName, FileKeyName, DirKeyValue, @@ -3904,7 +3601,7 @@ PrepareCopyPageInfFile(HINF InfFile, WCHAR PathBuffer[MAX_PATH]; /* Add common files */ - if (!AddSectionToCopyQueue(InfFile, L"SourceDisksFiles", SourceCabinet, &DestinationPath, Ir)) + if (!AddSectionToCopyQueue(InfFile, L"SourceDisksFiles", SourceCabinet, &USetupData.DestinationPath, Ir)) return FALSE; /* Add specific files depending of computer type */ @@ -3915,7 +3612,7 @@ PrepareCopyPageInfFile(HINF InfFile, if (AdditionalSectionName) { - if (!AddSectionToCopyQueue(InfFile, AdditionalSectionName, SourceCabinet, &DestinationPath, Ir)) + if (!AddSectionToCopyQueue(InfFile, AdditionalSectionName, SourceCabinet, &USetupData.DestinationPath, Ir)) return FALSE; } } @@ -3924,14 +3621,14 @@ PrepareCopyPageInfFile(HINF InfFile, /* * FIXME: - * Copying files to DestinationRootPath should be done from within + * 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 DestinationPath specify just '\' . + * For installing to USetupData.DestinationPath specify just '\' . */ /* Get destination path */ - StringCchCopyW(PathBuffer, ARRAYSIZE(PathBuffer), DestinationPath.Buffer); + StringCchCopyW(PathBuffer, ARRAYSIZE(PathBuffer), USetupData.DestinationPath.Buffer); DPRINT("FullPath(1): '%S'\n", PathBuffer); @@ -3974,7 +3671,7 @@ PrepareCopyPageInfFile(HINF InfFile, DPRINT("InstallationPath: '%S'\n", DirKeyValue); StringCchCopyW(PathBuffer, ARRAYSIZE(PathBuffer), - DestinationPath.Buffer); + USetupData.DestinationPath.Buffer); DPRINT("InstallationPath(2): '%S'\n", PathBuffer); } @@ -3984,7 +3681,7 @@ PrepareCopyPageInfFile(HINF InfFile, DPRINT("AbsolutePath: '%S'\n", DirKeyValue); CombinePaths(PathBuffer, ARRAYSIZE(PathBuffer), 2, - DestinationRootPath.Buffer, DirKeyValue); + USetupData.DestinationRootPath.Buffer, DirKeyValue); DPRINT("AbsolutePath(2): '%S'\n", PathBuffer); @@ -4003,7 +3700,7 @@ PrepareCopyPageInfFile(HINF InfFile, DPRINT("RelativePath: '%S'\n", DirKeyValue); CombinePaths(PathBuffer, ARRAYSIZE(PathBuffer), 2, - DestinationPath.Buffer, DirKeyValue); + USetupData.DestinationPath.Buffer, DirKeyValue); DPRINT("RelativePath(2): '%S'\n", PathBuffer); @@ -4081,7 +3778,7 @@ PrepareCopyPage(PINPUT_RECORD Ir) break; CombinePaths(PathBuffer, ARRAYSIZE(PathBuffer), 2, - SourcePath.Buffer, KeyValue); + USetupData.SourcePath.Buffer, KeyValue); CabinetInitialize(); CabinetSetEventHandlers(NULL, NULL, NULL); @@ -4109,7 +3806,7 @@ PrepareCopyPage(PINPUT_RECORD Ir) InfFileSize, NULL, INF_STYLE_WIN4, - LanguageId, + USetupData.LanguageId, &ErrorLine); if (InfHandle == INVALID_HANDLE_VALUE) @@ -4224,7 +3921,7 @@ FileCopyPage(PINPUT_RECORD Ir) MUIDisplayPage(FILE_COPY_PAGE); /* Create context for the copy process */ - CopyContext.DestinationRootPath = DestinationRootPath.Buffer; + CopyContext.DestinationRootPath = USetupData.DestinationRootPath.Buffer; CopyContext.InstallPath = InstallPath.Buffer; CopyContext.TotalOperations = 0; CopyContext.CompletedOperations = 0; @@ -4286,6 +3983,9 @@ FileCopyPage(PINPUT_RECORD Ir) DestroyProgressBar(CopyContext.MemoryBars[1]); DestroyProgressBar(CopyContext.MemoryBars[2]); + /* Create the $winnt$.inf file */ + InstallSetupInfFile(&USetupData); + /* Go display the next page */ return REGISTRY_PAGE; } @@ -4327,7 +4027,7 @@ RegistryPage(PINPUT_RECORD Ir) 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, &ShouldRepairRegistry); + Status = VerifyRegistryHives(&USetupData.DestinationPath, &ShouldRepairRegistry); if (!NT_SUCCESS(Status)) { DPRINT1("VerifyRegistryHives failed, Status 0x%08lx\n", Status); @@ -4342,7 +4042,7 @@ DoUpdate: CONSOLE_SetStatusText(MUIGetString(STRING_REGHIVEUPDATE)); /* Initialize the registry and setup the registry hives */ - Status = RegInitializeRegistry(&DestinationPath); + Status = RegInitializeRegistry(&USetupData.DestinationPath); if (!NT_SUCCESS(Status)) { DPRINT1("RegInitializeRegistry() failed\n"); @@ -4431,7 +4131,7 @@ DoUpdate: CONSOLE_SetStatusText(MUIGetString(STRING_IMPORTFILE), File); - if (!ImportRegistryFile(SourcePath.Buffer, File, Section, LanguageId, Delete)) + if (!ImportRegistryFile(USetupData.SourcePath.Buffer, File, Section, USetupData.LanguageId, Delete)) { DPRINT1("Importing %S failed\n", File); INF_FreeData(File); @@ -4508,7 +4208,7 @@ Cleanup: // TODO: Unload all the registry stuff, perform cleanup, // and copy the created hive files into .sav files. // - RegCleanupRegistry(&DestinationPath); + RegCleanupRegistry(&USetupData.DestinationPath); /* * Check whether we were in update/repair mode but we were actually @@ -4564,28 +4264,30 @@ BootLoaderPage(PINPUT_RECORD Ir) CONSOLE_SetStatusText(MUIGetString(STRING_PLEASEWAIT)); - RtlFreeUnicodeString(&SystemRootPath); + RtlFreeUnicodeString(&USetupData.SystemRootPath); StringCchPrintfW(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 */ - { - return SUCCESS_PAGE; - } - else if (UnattendMBRInstallType == 1) /* install on floppy */ + if ((USetupData.MBRInstallType == 0) || + (USetupData.MBRInstallType == 1)) { - 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"); @@ -4628,15 +4330,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); @@ -4677,7 +4385,7 @@ BootLoaderPage(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; @@ -4686,25 +4394,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; } @@ -4738,7 +4474,7 @@ 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; @@ -4751,7 +4487,7 @@ BootLoaderFloppyPage(PINPUT_RECORD Ir) return BOOT_LOADER_FLOPPY_PAGE; } - Status = InstallFatBootcodeToFloppy(&SourceRootPath, &DestinationArcPath); + Status = InstallFatBootcodeToFloppy(&USetupData.SourceRootPath, &USetupData.DestinationArcPath); if (!NT_SUCCESS(Status)) { /* Print error message */ @@ -4784,9 +4520,9 @@ BootLoaderHarddiskVbrPage(PINPUT_RECORD Ir) { NTSTATUS Status; - Status = InstallVBRToPartition(&SystemRootPath, - &SourceRootPath, - &DestinationArcPath, + Status = InstallVBRToPartition(&USetupData.SystemRootPath, + &USetupData.SourceRootPath, + &USetupData.DestinationArcPath, PartitionList->SystemPartition->PartitionType); if (!NT_SUCCESS(Status)) { @@ -4821,9 +4557,9 @@ BootLoaderHarddiskMbrPage(PINPUT_RECORD Ir) WCHAR DstPath[MAX_PATH]; /* Step 1: Write the VBR */ - Status = InstallVBRToPartition(&SystemRootPath, - &SourceRootPath, - &DestinationArcPath, + Status = InstallVBRToPartition(&USetupData.SystemRootPath, + &USetupData.SourceRootPath, + &USetupData.DestinationArcPath, PartitionList->SystemPartition->PartitionType); if (!NT_SUCCESS(Status)) { @@ -4836,12 +4572,12 @@ BootLoaderHarddiskMbrPage(PINPUT_RECORD Ir) L"\\Device\\Harddisk%d\\Partition0", PartitionList->SystemPartition->DiskEntry->DiskNumber); - CombinePaths(SourceMbrPathBuffer, ARRAYSIZE(SourceMbrPathBuffer), 2, SourceRootPath.Buffer, L"\\loader\\dosmbr.bin"); + CombinePaths(SourceMbrPathBuffer, ARRAYSIZE(SourceMbrPathBuffer), 2, USetupData.SourceRootPath.Buffer, L"\\loader\\dosmbr.bin"); if (IsThereAValidBootSector(DestinationDevicePathBuffer)) { /* Save current MBR */ - CombinePaths(DstPath, ARRAYSIZE(DstPath), 2, SystemRootPath.Buffer, L"mbr.old"); + 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)); @@ -5236,14 +4972,14 @@ RunUSetup(VOID) } /* Initialize global unicode strings */ - RtlInitUnicodeString(&SourcePath, NULL); - RtlInitUnicodeString(&SourceRootPath, NULL); - RtlInitUnicodeString(&SourceRootDir, NULL); + RtlInitUnicodeString(&USetupData.SourcePath, NULL); + RtlInitUnicodeString(&USetupData.SourceRootPath, NULL); + RtlInitUnicodeString(&USetupData.SourceRootDir, NULL); RtlInitUnicodeString(&InstallPath, NULL); - RtlInitUnicodeString(&DestinationPath, NULL); - RtlInitUnicodeString(&DestinationArcPath, NULL); - RtlInitUnicodeString(&DestinationRootPath, NULL); - RtlInitUnicodeString(&SystemRootPath, NULL); + RtlInitUnicodeString(&USetupData.DestinationPath, NULL); + RtlInitUnicodeString(&USetupData.DestinationArcPath, NULL); + RtlInitUnicodeString(&USetupData.DestinationRootPath, NULL); + RtlInitUnicodeString(&USetupData.SystemRootPath, NULL); /* Hide the cursor */ CONSOLE_SetCursorType(TRUE, FALSE); @@ -5408,6 +5144,8 @@ RunUSetup(VOID) } } + SetupCloseInfFile(SetupInf); + if (Page == RECOVERY_PAGE) RecoveryConsole();