ReactOS.org
Sign In
Sign Up
Sign In
Sign Up
Manage this list
×
Keyboard Shortcuts
Thread View
j
: Next unread message
k
: Previous unread message
j a
: Jump to all threads
j l
: Jump to MailingList overview
2024
December
November
October
September
August
July
June
May
April
March
February
January
2023
December
November
October
September
August
July
June
May
April
March
February
January
2022
December
November
October
September
August
July
June
May
April
March
February
January
2021
December
November
October
September
August
July
June
May
April
March
February
January
2020
December
November
October
September
August
July
June
May
April
March
February
January
2019
December
November
October
September
August
July
June
May
April
March
February
January
2018
December
November
October
September
August
July
June
May
April
March
February
January
2017
December
November
October
September
August
July
June
May
April
March
February
January
2016
December
November
October
September
August
July
June
May
April
March
February
January
2015
December
November
October
September
August
July
June
May
April
March
February
January
2014
December
November
October
September
August
July
June
May
April
March
February
January
2013
December
November
October
September
August
July
June
May
April
March
February
January
2012
December
November
October
September
August
July
June
May
April
March
February
January
2011
December
November
October
September
August
July
June
May
April
March
February
January
2010
December
November
October
September
August
July
June
May
April
March
February
January
2009
December
November
October
September
August
July
June
May
April
March
February
January
2008
December
November
October
September
August
July
June
May
April
March
February
January
2007
December
November
October
September
August
July
June
May
April
March
February
January
2006
December
November
October
September
August
July
June
May
April
March
February
January
2005
December
November
October
September
August
July
June
May
April
March
February
January
2004
December
November
October
September
August
July
June
May
April
March
February
List overview
Download
Ros-diffs
October 2018
----- 2024 -----
December 2024
November 2024
October 2024
September 2024
August 2024
July 2024
June 2024
May 2024
April 2024
March 2024
February 2024
January 2024
----- 2023 -----
December 2023
November 2023
October 2023
September 2023
August 2023
July 2023
June 2023
May 2023
April 2023
March 2023
February 2023
January 2023
----- 2022 -----
December 2022
November 2022
October 2022
September 2022
August 2022
July 2022
June 2022
May 2022
April 2022
March 2022
February 2022
January 2022
----- 2021 -----
December 2021
November 2021
October 2021
September 2021
August 2021
July 2021
June 2021
May 2021
April 2021
March 2021
February 2021
January 2021
----- 2020 -----
December 2020
November 2020
October 2020
September 2020
August 2020
July 2020
June 2020
May 2020
April 2020
March 2020
February 2020
January 2020
----- 2019 -----
December 2019
November 2019
October 2019
September 2019
August 2019
July 2019
June 2019
May 2019
April 2019
March 2019
February 2019
January 2019
----- 2018 -----
December 2018
November 2018
October 2018
September 2018
August 2018
July 2018
June 2018
May 2018
April 2018
March 2018
February 2018
January 2018
----- 2017 -----
December 2017
November 2017
October 2017
September 2017
August 2017
July 2017
June 2017
May 2017
April 2017
March 2017
February 2017
January 2017
----- 2016 -----
December 2016
November 2016
October 2016
September 2016
August 2016
July 2016
June 2016
May 2016
April 2016
March 2016
February 2016
January 2016
----- 2015 -----
December 2015
November 2015
October 2015
September 2015
August 2015
July 2015
June 2015
May 2015
April 2015
March 2015
February 2015
January 2015
----- 2014 -----
December 2014
November 2014
October 2014
September 2014
August 2014
July 2014
June 2014
May 2014
April 2014
March 2014
February 2014
January 2014
----- 2013 -----
December 2013
November 2013
October 2013
September 2013
August 2013
July 2013
June 2013
May 2013
April 2013
March 2013
February 2013
January 2013
----- 2012 -----
December 2012
November 2012
October 2012
September 2012
August 2012
July 2012
June 2012
May 2012
April 2012
March 2012
February 2012
January 2012
----- 2011 -----
December 2011
November 2011
October 2011
September 2011
August 2011
July 2011
June 2011
May 2011
April 2011
March 2011
February 2011
January 2011
----- 2010 -----
December 2010
November 2010
October 2010
September 2010
August 2010
July 2010
June 2010
May 2010
April 2010
March 2010
February 2010
January 2010
----- 2009 -----
December 2009
November 2009
October 2009
September 2009
August 2009
July 2009
June 2009
May 2009
April 2009
March 2009
February 2009
January 2009
----- 2008 -----
December 2008
November 2008
October 2008
September 2008
August 2008
July 2008
June 2008
May 2008
April 2008
March 2008
February 2008
January 2008
----- 2007 -----
December 2007
November 2007
October 2007
September 2007
August 2007
July 2007
June 2007
May 2007
April 2007
March 2007
February 2007
January 2007
----- 2006 -----
December 2006
November 2006
October 2006
September 2006
August 2006
July 2006
June 2006
May 2006
April 2006
March 2006
February 2006
January 2006
----- 2005 -----
December 2005
November 2005
October 2005
September 2005
August 2005
July 2005
June 2005
May 2005
April 2005
March 2005
February 2005
January 2005
----- 2004 -----
December 2004
November 2004
October 2004
September 2004
August 2004
July 2004
June 2004
May 2004
April 2004
March 2004
February 2004
ros-diffs@reactos.org
21 participants
354 discussions
Start a n
N
ew thread
01/02: [MKHIVE] Fix cases where 'rc' was used without being initialized.
by Hermès Bélusca-Maïto
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=e723b9f4b40d5e0c6e84e…
commit e723b9f4b40d5e0c6e84e4a0895459f3e93f8f14 Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org> AuthorDate: Thu Oct 18 23:07:41 2018 +0200 Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org> CommitDate: Thu Oct 18 23:11:55 2018 +0200 [MKHIVE] Fix cases where 'rc' was used without being initialized. Fixes crashes when the tool is compiled with Run-Time Checks enabled. And thus should fix the MSVC buildbots! Thanks to Pierre for having brought this issue to me. CORE-15201 --- sdk/tools/mkhive/registry.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sdk/tools/mkhive/registry.c b/sdk/tools/mkhive/registry.c index c188d7a53b..ad0aafc59c 100644 --- a/sdk/tools/mkhive/registry.c +++ b/sdk/tools/mkhive/registry.c @@ -572,6 +572,7 @@ RegDeleteKeyW( else { hTargetKey = hKey; + rc = ERROR_SUCCESS; } /* Don't allow deleting the root */ @@ -618,6 +619,8 @@ RegDeleteKeyW( /* Release the cell */ HvReleaseCell(Hive, ParentCell); } + + rc = ERROR_SUCCESS; } else {
6 years, 2 months
1
0
0
0
01/01: [MKHIVE] Fix compilation warnings.
by Hermès Bélusca-Maïto
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=473ca9116648a07decd6c…
commit 473ca9116648a07decd6ce4625c7d3762f31d660 Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org> AuthorDate: Mon Oct 15 00:32:48 2018 +0200 Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org> CommitDate: Mon Oct 15 00:37:08 2018 +0200 [MKHIVE] Fix compilation warnings. --- sdk/tools/mkhive/registry.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sdk/tools/mkhive/registry.c b/sdk/tools/mkhive/registry.c index d6a2028990..c188d7a53b 100644 --- a/sdk/tools/mkhive/registry.c +++ b/sdk/tools/mkhive/registry.c @@ -488,7 +488,8 @@ RegpCreateOrOpenKey( if (!NT_SUCCESS(Status)) { - DPRINT("RegpCreateOrOpenKey('%S'): Could not create or open subkey '%wZ', Status 0x%08x\n", KeyName, &KeyString, Status); + DPRINT("RegpCreateOrOpenKey('%S'): Could not create or open subkey '%.*S', Status 0x%08x\n", + KeyName, (int)(KeyString.Length / sizeof(WCHAR)), KeyString.Buffer, Status); return ERROR_GEN_FAILURE; // STATUS_UNSUCCESSFUL; }
6 years, 2 months
1
0
0
0
02/02: [SETUPLIB][USETUP] Minor code refactoring, consisting in renaming the "ntos boot loader" stuff into "boot store", since this happens to be functionality that is a bit more general than previously thought.
by Hermès Bélusca-Maïto
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=a28461124bbaa1bd12fb9…
commit a28461124bbaa1bd12fb927ae4787033ea3872c5 Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org> AuthorDate: Thu Jun 8 17:30:23 2017 +0000 Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org> CommitDate: Sun Oct 14 23:46:52 2018 +0200 [SETUPLIB][USETUP] Minor code refactoring, consisting in renaming the "ntos boot loader" stuff into "boot store", since this happens to be functionality that is a bit more general than previously thought. - Fix the usage of the BootEntry's "Version" member. - Don't surround with too many quotation marks the "friendly" boot entry name in AddBootStoreEntry(). svn path=/branches/setup_improvements/; revision=74964 --- base/setup/lib/bldrsup.c | 134 ++++++++++++++++++++++++-------------------- base/setup/lib/bldrsup.h | 83 ++++++++++++++------------- base/setup/lib/osdetect.c | 20 ++++--- base/setup/usetup/bootsup.c | 94 ++++++++++++++++--------------- 4 files changed, 174 insertions(+), 157 deletions(-) diff --git a/base/setup/lib/bldrsup.c b/base/setup/lib/bldrsup.c index 80a951a6e1..5714cec837 100644 --- a/base/setup/lib/bldrsup.c +++ b/base/setup/lib/bldrsup.c @@ -1,8 +1,8 @@ /* * PROJECT: ReactOS Setup Library * LICENSE: GPL-2.0+ (
https://spdx.org/licenses/GPL-2.0+
) - * PURPOSE: NT 5.x family (MS Windows <= 2003, and ReactOS) - * boot loaders management. + * PURPOSE: Boot Stores Management functionality, with support for + * NT 5.x family (MS Windows <= 2003, and ReactOS) bootloaders. * COPYRIGHT: Copyright 2017-2018 Hermes Belusca-Maito */ @@ -26,7 +26,7 @@ typedef NTSTATUS (*POPEN_BOOT_STORE)( OUT PVOID* Handle, IN HANDLE PartitionDirectoryHandle, // OPTIONAL - IN NTOS_BOOT_LOADER_TYPE Type, + IN BOOT_STORE_TYPE Type, IN BOOLEAN CreateNew); typedef NTSTATUS @@ -42,7 +42,7 @@ typedef NTSTATUS typedef struct _NTOS_BOOT_LOADER_FILES { - NTOS_BOOT_LOADER_TYPE Type; + BOOT_STORE_TYPE Type; PCZZWSTR LoaderExecutables; PCWSTR LoaderConfigurationFile; POPEN_BOOT_STORE OpenBootStore; @@ -56,7 +56,7 @@ typedef struct _NTOS_BOOT_LOADER_FILES */ typedef struct _BOOT_STORE_CONTEXT { - NTOS_BOOT_LOADER_TYPE Type; + BOOT_STORE_TYPE Type; // PNTOS_BOOT_LOADER_FILES ?? /* PVOID PrivateData; @@ -95,7 +95,7 @@ static NTSTATUS OpenIniBootLoaderStore( OUT PVOID* Handle, IN HANDLE PartitionDirectoryHandle, // OPTIONAL - IN NTOS_BOOT_LOADER_TYPE Type, + IN BOOT_STORE_TYPE Type, IN BOOLEAN CreateNew); static NTSTATUS @@ -134,10 +134,10 @@ C_ASSERT(_countof(NtosBootLoaders) == BldrTypeMax); /* FUNCTIONS ****************************************************************/ NTSTATUS -FindNTOSBootLoader( // By handle +FindBootStore( // By handle IN HANDLE PartitionDirectoryHandle, // OPTIONAL - IN NTOS_BOOT_LOADER_TYPE Type, - OUT PULONG Version OPTIONAL) + IN BOOT_STORE_TYPE Type, + OUT PULONG VersionNumber OPTIONAL) // OUT PHANDLE ConfigFileHande OPTIONAL ???? { PCWSTR LoaderExecutable; @@ -146,8 +146,8 @@ FindNTOSBootLoader( // By handle if (Type >= BldrTypeMax) return STATUS_INVALID_PARAMETER; - if (Version) - *Version = 0; + if (VersionNumber) + *VersionNumber = 0; /* Check whether any of the loader executables exist */ LoaderExecutable = NtosBootLoaders[Type].LoaderExecutables; @@ -172,10 +172,10 @@ FindNTOSBootLoader( // By handle } /* Check for loader version if needed */ - if (Version) + if (VersionNumber) { - *Version = 0; - // TODO: Check for BLDR version ONLY if Version != NULL + *VersionNumber = 0; + // TODO: Check for BLDR version! } /* Check whether the loader configuration file exists */ @@ -340,7 +340,7 @@ static NTSTATUS OpenIniBootLoaderStore( OUT PVOID* Handle, IN HANDLE PartitionDirectoryHandle, // OPTIONAL - IN NTOS_BOOT_LOADER_TYPE Type, + IN BOOT_STORE_TYPE Type, IN BOOLEAN CreateNew) { NTSTATUS Status; @@ -733,10 +733,10 @@ Quit: NTSTATUS -OpenNTOSBootLoaderStoreByHandle( +OpenBootStoreByHandle( OUT PVOID* Handle, IN HANDLE PartitionDirectoryHandle, // OPTIONAL - IN NTOS_BOOT_LOADER_TYPE Type, + IN BOOT_STORE_TYPE Type, IN BOOLEAN CreateNew) { /* @@ -760,10 +760,10 @@ OpenNTOSBootLoaderStoreByHandle( } NTSTATUS -OpenNTOSBootLoaderStore_UStr( +OpenBootStore_UStr( OUT PVOID* Handle, IN PUNICODE_STRING SystemPartitionPath, - IN NTOS_BOOT_LOADER_TYPE Type, + IN BOOT_STORE_TYPE Type, IN BOOLEAN CreateNew) { NTSTATUS Status; @@ -803,7 +803,7 @@ OpenNTOSBootLoaderStore_UStr( return Status; } - Status = OpenNTOSBootLoaderStoreByHandle(Handle, PartitionDirectoryHandle, Type, CreateNew); + Status = OpenBootStoreByHandle(Handle, PartitionDirectoryHandle, Type, CreateNew); /* Done! */ NtClose(PartitionDirectoryHandle); @@ -811,19 +811,19 @@ OpenNTOSBootLoaderStore_UStr( } NTSTATUS -OpenNTOSBootLoaderStore( +OpenBootStore( OUT PVOID* Handle, IN PCWSTR SystemPartition, - IN NTOS_BOOT_LOADER_TYPE Type, + IN BOOT_STORE_TYPE Type, IN BOOLEAN CreateNew) { UNICODE_STRING SystemPartitionPath; RtlInitUnicodeString(&SystemPartitionPath, SystemPartition); - return OpenNTOSBootLoaderStore_UStr(Handle, &SystemPartitionPath, Type, CreateNew); + return OpenBootStore_UStr(Handle, &SystemPartitionPath, Type, CreateNew); } NTSTATUS -CloseNTOSBootLoaderStore( +CloseBootStore( IN PVOID Handle) { PBOOT_STORE_CONTEXT BootStore = (PBOOT_STORE_CONTEXT)Handle; @@ -855,7 +855,7 @@ NTSTATUS CreateNTOSEntry( IN PBOOT_STORE_INI_CONTEXT BootStore, IN ULONG_PTR BootEntryKey, - IN PNTOS_BOOT_ENTRY BootEntry) + IN PBOOT_STORE_ENTRY BootEntry) { PINICACHESECTION IniSection; PWCHAR Section = (PWCHAR)BootEntryKey; @@ -867,7 +867,6 @@ CreateNTOSEntry( /* Create a new section */ IniSection = IniCacheAppendSection(BootStore->IniCache, Section); - // if (_wcsicmp(BootEntry->Version, L"Windows2003") == 0) if (BootEntry->OsOptionsLength >= sizeof(NTOS_OPTIONS) && RtlCompareMemory(&BootEntry->OsOptions /* Signature */, NTOS_OPTIONS_SIGNATURE, @@ -889,7 +888,6 @@ CreateNTOSEntry( L"Options", (PWSTR)Options->OsLoadOptions); } else - // if (_wcsicmp(BootEntry->Version, L"BootSector") == 0) if (BootEntry->OsOptionsLength >= sizeof(BOOT_SECTOR_OPTIONS) && RtlCompareMemory(&BootEntry->OsOptions /* Signature */, BOOT_SECTOR_OPTIONS_SIGNATURE, @@ -916,16 +914,18 @@ CreateNTOSEntry( } else { - DPRINT1("Unsupported BootType '%S'\n", BootEntry->Version); + // DPRINT1("Unsupported BootType %lu/'%*.s'\n", + // BootEntry->OsOptionsLength, 8, &BootEntry->OsOptions); + DPRINT1("Unsupported BootType %lu\n", BootEntry->OsOptionsLength); } return STATUS_SUCCESS; } NTSTATUS -AddNTOSBootEntry( +AddBootStoreEntry( IN PVOID Handle, - IN PNTOS_BOOT_ENTRY BootEntry, + IN PBOOT_STORE_ENTRY BootEntry, IN ULONG_PTR BootEntryKey) { PBOOT_STORE_CONTEXT BootStore = (PBOOT_STORE_CONTEXT)Handle; @@ -949,6 +949,9 @@ AddNTOSBootEntry( if (BootStore->Type == FreeLdr) { + if (BootEntry->Version != FreeLdr) + return STATUS_INVALID_PARAMETER; + return CreateNTOSEntry((PBOOT_STORE_INI_CONTEXT)BootStore, BootEntryKey, BootEntry); } @@ -960,15 +963,19 @@ AddNTOSBootEntry( ULONG BufferLength; PCWSTR InstallName, OsOptions; // ULONG InstallNameLength, OsOptionsLength; + BOOLEAN IsNameNotQuoted; + + if (BootEntry->Version != NtLdr) + return STATUS_INVALID_PARAMETER; - // if (_wcsicmp(BootEntry->Version, L"Windows2003") != 0) if (BootEntry->OsOptionsLength < sizeof(NTOS_OPTIONS) || RtlCompareMemory(&BootEntry->OsOptions /* Signature */, NTOS_OPTIONS_SIGNATURE, RTL_FIELD_SIZE(NTOS_OPTIONS, Signature)) != RTL_FIELD_SIZE(NTOS_OPTIONS, Signature)) { - DPRINT1("Unsupported BootType '%S'\n", BootEntry->Version); + // DPRINT1("Unsupported BootType '%S'\n", BootEntry->Version); + DPRINT1("Unsupported BootType %lu\n", BootEntry->OsOptionsLength); return STATUS_SUCCESS; // STATUS_NOT_SUPPORTED; } @@ -978,7 +985,9 @@ AddNTOSBootEntry( // if (InstallNameLength == 0) InstallName = NULL; // if (OsOptionsLength == 0) OsOptions = NULL; - BufferLength = 2 /* Quotes for FriendlyName*/ + wcslen(InstallName); + IsNameNotQuoted = (InstallName[0] != L'\"' || InstallName[wcslen(InstallName)-1] != L'\"'); + + BufferLength = (IsNameNotQuoted ? 2 /* Quotes for FriendlyName*/ : 0) + wcslen(InstallName); if (OsOptions) BufferLength += 1 /* Space between FriendlyName and options */ + wcslen(OsOptions); BufferLength++; /* NULL-termination */ @@ -987,13 +996,14 @@ AddNTOSBootEntry( if (!Buffer) return STATUS_INSUFFICIENT_RESOURCES; - wcscpy(Buffer, L"\""); - wcscat(Buffer, InstallName); - wcscat(Buffer, L"\""); + *Buffer = UNICODE_NULL; + if (IsNameNotQuoted) RtlStringCchCatW(Buffer, BufferLength, L"\""); + RtlStringCchCatW(Buffer, BufferLength, InstallName); + if (IsNameNotQuoted) RtlStringCchCatW(Buffer, BufferLength, L"\""); if (OsOptions) { - wcscat(Buffer, L" "); - wcscat(Buffer, OsOptions); + RtlStringCchCatW(Buffer, BufferLength, L" "); + RtlStringCchCatW(Buffer, BufferLength, OsOptions); } /* Insert the entry into the "Operating Systems" section */ @@ -1011,7 +1021,7 @@ AddNTOSBootEntry( } NTSTATUS -DeleteNTOSBootEntry( +DeleteBootStoreEntry( IN PVOID Handle, IN ULONG_PTR BootEntryKey) { @@ -1045,9 +1055,9 @@ DeleteNTOSBootEntry( } NTSTATUS -ModifyNTOSBootEntry( +ModifyBootStoreEntry( IN PVOID Handle, - IN PNTOS_BOOT_ENTRY BootEntry) + IN PBOOT_STORE_ENTRY BootEntry) { PBOOT_STORE_CONTEXT BootStore = (PBOOT_STORE_CONTEXT)Handle; @@ -1079,10 +1089,10 @@ ModifyNTOSBootEntry( } NTSTATUS -QueryNTOSBootEntry( +QueryBootStoreEntry( IN PVOID Handle, IN ULONG_PTR BootEntryKey, - OUT PNTOS_BOOT_ENTRY BootEntry) // Technically this should be PNTOS_BOOT_ENTRY* + OUT PBOOT_STORE_ENTRY BootEntry) // Technically this should be PBOOT_STORE_ENTRY* { PBOOT_STORE_CONTEXT BootStore = (PBOOT_STORE_CONTEXT)Handle; @@ -1114,9 +1124,9 @@ QueryNTOSBootEntry( } NTSTATUS -QueryNTOSBootOptions( +QueryBootStoreOptions( IN PVOID Handle, - IN OUT PNTOS_BOOT_OPTIONS BootOptions + IN OUT PBOOT_STORE_OPTIONS BootOptions /* , IN PULONG BootOptionsLength */ ) { NTSTATUS Status = STATUS_SUCCESS; @@ -1147,6 +1157,8 @@ QueryNTOSBootOptions( if (BootStore->Type == FreeLdr) { + BootOptions->Version = FreeLdr; + Status = IniCacheGetKey(((PBOOT_STORE_INI_CONTEXT)BootStore)->OptionsIniSection, L"DefaultOS", (PWCHAR*)&BootOptions->CurrentBootEntryKey); if (!NT_SUCCESS(Status)) @@ -1161,6 +1173,8 @@ QueryNTOSBootOptions( } else if (BootStore->Type == NtLdr) { + BootOptions->Version = NtLdr; + Status = IniCacheGetKey(((PBOOT_STORE_INI_CONTEXT)BootStore)->OptionsIniSection, L"default", (PWCHAR*)&BootOptions->CurrentBootEntryKey); if (!NT_SUCCESS(Status)) @@ -1178,9 +1192,9 @@ QueryNTOSBootOptions( } NTSTATUS -SetNTOSBootOptions( +SetBootStoreOptions( IN PVOID Handle, - IN PNTOS_BOOT_OPTIONS BootOptions, + IN PBOOT_STORE_OPTIONS BootOptions, IN ULONG FieldsToChange) { PBOOT_STORE_CONTEXT BootStore = (PBOOT_STORE_CONTEXT)Handle; @@ -1208,6 +1222,9 @@ SetNTOSBootOptions( return STATUS_NOT_SUPPORTED; } + if (BootOptions->Version != FreeLdr) + return STATUS_INVALID_PARAMETER; + // // TODO: Depending on the flags set in 'FieldsToChange', // change either one or both these bootloader options. @@ -1216,7 +1233,7 @@ SetNTOSBootOptions( NULL, INSERT_LAST, L"DefaultOS", (PWCHAR)BootOptions->CurrentBootEntryKey); - StringCchPrintfW(TimeoutStr, ARRAYSIZE(TimeoutStr), L"%d", BootOptions->Timeout); + RtlStringCchPrintfW(TimeoutStr, ARRAYSIZE(TimeoutStr), L"%d", BootOptions->Timeout); IniCacheInsertKey(((PBOOT_STORE_INI_CONTEXT)BootStore)->OptionsIniSection, NULL, INSERT_LAST, L"TimeOut", TimeoutStr); @@ -1237,9 +1254,9 @@ FreeLdrEnumerateBootEntries( PINICACHEITERATOR Iterator; PINICACHESECTION OsIniSection; PWCHAR SectionName, KeyData; - UCHAR xxBootEntry[FIELD_OFFSET(NTOS_BOOT_ENTRY, OsOptions) + + UCHAR xxBootEntry[FIELD_OFFSET(BOOT_STORE_ENTRY, OsOptions) + max(sizeof(NTOS_OPTIONS), sizeof(BOOT_SECTOR_OPTIONS))]; - PNTOS_BOOT_ENTRY BootEntry = (PNTOS_BOOT_ENTRY)&xxBootEntry; + PBOOT_STORE_ENTRY BootEntry = (PBOOT_STORE_ENTRY)&xxBootEntry; PWCHAR Buffer; /* Enumerate all the valid installations listed in the "Operating Systems" section */ @@ -1291,7 +1308,7 @@ FreeLdrEnumerateBootEntries( DPRINT1("Boot entry '%S' in OS section '%S'\n", InstallName, SectionName); - BootEntry->Version = NULL; + BootEntry->Version = FreeLdr; BootEntry->BootEntryKey = MAKESTRKEY(SectionName); BootEntry->FriendlyName = InstallName; BootEntry->BootFilePath = NULL; @@ -1318,8 +1335,7 @@ FreeLdrEnumerateBootEntries( /* BootType is Windows2003 */ PNTOS_OPTIONS Options = (PNTOS_OPTIONS)&BootEntry->OsOptions; - BootEntry->Version = L"Windows2003"; - DPRINT1("This is a '%S' boot entry\n", BootEntry->Version); + DPRINT1("This is a '%S' boot entry\n", KeyData); BootEntry->OsOptionsLength = sizeof(NTOS_OPTIONS); RtlCopyMemory(Options->Signature, @@ -1350,8 +1366,7 @@ FreeLdrEnumerateBootEntries( /* BootType is BootSector */ PBOOT_SECTOR_OPTIONS Options = (PBOOT_SECTOR_OPTIONS)&BootEntry->OsOptions; - BootEntry->Version = L"BootSector"; - DPRINT1("This is a '%S' boot entry\n", BootEntry->Version); + DPRINT1("This is a '%S' boot entry\n", KeyData); BootEntry->OsOptionsLength = sizeof(BOOT_SECTOR_OPTIONS); RtlCopyMemory(Options->Signature, @@ -1384,7 +1399,6 @@ FreeLdrEnumerateBootEntries( else { DPRINT1("Unrecognized BootType value '%S'\n", KeyData); - // BootEntry->Version = KeyData; // goto DoEnum; } @@ -1416,8 +1430,8 @@ NtLdrEnumerateBootEntries( NTSTATUS Status = STATUS_SUCCESS; PINICACHEITERATOR Iterator; PWCHAR SectionName, KeyData; - UCHAR xxBootEntry[FIELD_OFFSET(NTOS_BOOT_ENTRY, OsOptions) + sizeof(NTOS_OPTIONS)]; - PNTOS_BOOT_ENTRY BootEntry = (PNTOS_BOOT_ENTRY)&xxBootEntry; + UCHAR xxBootEntry[FIELD_OFFSET(BOOT_STORE_ENTRY, OsOptions) + sizeof(NTOS_OPTIONS)]; + PBOOT_STORE_ENTRY BootEntry = (PBOOT_STORE_ENTRY)&xxBootEntry; PNTOS_OPTIONS Options = (PNTOS_OPTIONS)&BootEntry->OsOptions; PWCHAR Buffer; ULONG BufferLength; @@ -1510,7 +1524,7 @@ NtLdrEnumerateBootEntries( DPRINT1("Boot entry '%S' in OS section (path) '%S'\n", InstallName, SectionName); // SectionName == SystemRoot; - BootEntry->Version = L"Windows2003"; + BootEntry->Version = NtLdr; BootEntry->BootEntryKey = 0; // FIXME?? BootEntry->FriendlyName = InstallName; BootEntry->BootFilePath = NULL; @@ -1541,7 +1555,7 @@ NtLdrEnumerateBootEntries( } NTSTATUS -EnumerateNTOSBootEntries( +EnumerateBootStoreEntries( IN PVOID Handle, // IN ULONG Flags, // Determine which data to retrieve IN PENUM_BOOT_ENTRIES_ROUTINE EnumBootEntriesRoutine, diff --git a/base/setup/lib/bldrsup.h b/base/setup/lib/bldrsup.h index 1c34be7e62..41cc1bb11b 100644 --- a/base/setup/lib/bldrsup.h +++ b/base/setup/lib/bldrsup.h @@ -1,8 +1,8 @@ /* * PROJECT: ReactOS Setup Library * LICENSE: GPL-2.0+ (
https://spdx.org/licenses/GPL-2.0+
) - * PURPOSE: NT 5.x family (MS Windows <= 2003, and ReactOS) - * boot loaders management. + * PURPOSE: Boot Stores Management functionality, with support for + * NT 5.x family (MS Windows <= 2003, and ReactOS) bootloaders. * COPYRIGHT: Copyright 2017-2018 Hermes Belusca-Maito */ @@ -10,13 +10,13 @@ #pragma once -typedef enum _NTOS_BOOT_LOADER_TYPE // _BOOT_STORE_TYPE +typedef enum _BOOT_STORE_TYPE { FreeLdr, // ReactOS' FreeLoader NtLdr, // Windows <= 2k3 NT "FlexBoot" OS Loader NTLDR // BootMgr, // Vista+ BCD-oriented BOOTMGR BldrTypeMax -} NTOS_BOOT_LOADER_TYPE; +} BOOT_STORE_TYPE; /* * Some references about EFI boot entries: @@ -28,25 +28,25 @@ typedef enum _NTOS_BOOT_LOADER_TYPE // _BOOT_STORE_TYPE * This structure is inspired from the EFI boot entry structure * BOOT_OPTIONS that is defined in ndk/iotypes.h . */ -typedef struct _NTOS_BOOT_OPTIONS // _BOOT_STORE_OPTIONS +typedef struct _BOOT_STORE_OPTIONS { - // ULONG Version; + ULONG Version; // BOOT_STORE_TYPE value // ULONG Length; ULONG Timeout; ULONG_PTR CurrentBootEntryKey; // ULONG_PTR NextBootEntryKey; // WCHAR HeadlessRedirection[1]; -} NTOS_BOOT_OPTIONS, *PNTOS_BOOT_OPTIONS; +} BOOT_STORE_OPTIONS, *PBOOT_STORE_OPTIONS; /* * These macros are used to set a value for the BootEntryKey member of a - * NTOS_BOOT_ENTRY structure, much in the same idea as MAKEINTRESOURCE and + * BOOT_STORE_ENTRY structure, much in the same idea as MAKEINTRESOURCE and * IS_INTRESOURCE macros for Win32 resources. * - * A key consists of either a boot ID number, - * comprised between 0 and MAX_USHORT == 0xFFFF == 65535, or can be a pointer - * to a human-readable string (section name), as in the case of FreeLDR, or - * to a GUID, as in the case of BOOTMGR. + * A key consists of either a boot ID number, comprised between 0 and + * MAX_USHORT == 0xFFFF == 65535, or can be a pointer to a human-readable + * string (section name), as in the case of FreeLDR, or to a GUID, as in the + * case of BOOTMGR. * * If IS_INTKEY(BootEntryKey) == TRUE, i.e. the key is <= 65535, this means * the key is a boot ID number, otherwise it is typically a pointer to a string. @@ -59,10 +59,9 @@ typedef struct _NTOS_BOOT_OPTIONS // _BOOT_STORE_OPTIONS * This structure is inspired from the EFI boot entry structures * BOOT_ENTRY and FILE_PATH that are defined in ndk/iotypes.h . */ -typedef struct _NTOS_BOOT_ENTRY // _BOOT_STORE_ENTRY +typedef struct _BOOT_STORE_ENTRY { - // ULONG Version; // Equivalent of the "BootType" in FreeLdr - PWCHAR Version; // HACK!!! + ULONG Version; // BOOT_STORE_TYPE value // ULONG Length; ULONG_PTR BootEntryKey; // Boot entry "key" PCWSTR FriendlyName; // Human-readable boot entry description // LoadIdentifier @@ -77,7 +76,7 @@ typedef struct _NTOS_BOOT_ENTRY // _BOOT_STORE_ENTRY * WCHAR FriendlyName[ANYSIZE_ARRAY]; * FILE_PATH BootFilePath; */ -} NTOS_BOOT_ENTRY, *PNTOS_BOOT_ENTRY; +} BOOT_STORE_ENTRY, *PBOOT_STORE_ENTRY; /* "NTOS" (aka. ReactOS or MS Windows NT) <= 5.x options */ typedef struct _NTOS_OPTIONS @@ -85,8 +84,8 @@ typedef struct _NTOS_OPTIONS UCHAR Signature[8]; // "NTOS_5\0\0" // ULONG Version; // ULONG Length; - PCWSTR OsLoadPath; // The OS SystemRoot path // OsLoaderFilePath // OsFilePath - PCWSTR OsLoadOptions; // OsLoadOptions + PCWSTR OsLoadPath; // The OS SystemRoot path // OsLoaderFilePath // OsFilePath + PCWSTR OsLoadOptions; // OsLoadOptions /* * In packed form, this structure would contain an offset to the 'OsLoadPath' * string, and the 'OsLoadOptions' member would be: @@ -114,79 +113,79 @@ typedef struct _BOOT_SECTOR_OPTIONS typedef NTSTATUS (NTAPI *PENUM_BOOT_ENTRIES_ROUTINE)( - IN NTOS_BOOT_LOADER_TYPE Type, - IN PNTOS_BOOT_ENTRY BootEntry, + IN BOOT_STORE_TYPE Type, + IN PBOOT_STORE_ENTRY BootEntry, IN PVOID Parameter OPTIONAL); NTSTATUS -FindNTOSBootLoader( // By handle +FindBootStore( // By handle IN HANDLE PartitionDirectoryHandle, // OPTIONAL - IN NTOS_BOOT_LOADER_TYPE Type, - OUT PULONG Version); + IN BOOT_STORE_TYPE Type, + OUT PULONG VersionNumber OPTIONAL); NTSTATUS -OpenNTOSBootLoaderStoreByHandle( +OpenBootStoreByHandle( OUT PVOID* Handle, IN HANDLE PartitionDirectoryHandle, // OPTIONAL - IN NTOS_BOOT_LOADER_TYPE Type, + IN BOOT_STORE_TYPE Type, IN BOOLEAN CreateNew); NTSTATUS -OpenNTOSBootLoaderStore_UStr( +OpenBootStore_UStr( OUT PVOID* Handle, IN PUNICODE_STRING SystemPartitionPath, - IN NTOS_BOOT_LOADER_TYPE Type, + IN BOOT_STORE_TYPE Type, IN BOOLEAN CreateNew); NTSTATUS -OpenNTOSBootLoaderStore( +OpenBootStore( OUT PVOID* Handle, IN PCWSTR SystemPartition, - IN NTOS_BOOT_LOADER_TYPE Type, + IN BOOT_STORE_TYPE Type, IN BOOLEAN CreateNew); NTSTATUS -CloseNTOSBootLoaderStore( +CloseBootStore( IN PVOID Handle); NTSTATUS -AddNTOSBootEntry( +AddBootStoreEntry( IN PVOID Handle, - IN PNTOS_BOOT_ENTRY BootEntry, + IN PBOOT_STORE_ENTRY BootEntry, IN ULONG_PTR BootEntryKey); NTSTATUS -DeleteNTOSBootEntry( +DeleteBootStoreEntry( IN PVOID Handle, IN ULONG_PTR BootEntryKey); NTSTATUS -ModifyNTOSBootEntry( +ModifyBootStoreEntry( IN PVOID Handle, - IN PNTOS_BOOT_ENTRY BootEntry); + IN PBOOT_STORE_ENTRY BootEntry); NTSTATUS -QueryNTOSBootEntry( +QueryBootStoreEntry( IN PVOID Handle, IN ULONG_PTR BootEntryKey, - OUT PNTOS_BOOT_ENTRY BootEntry); // Technically this should be PNTOS_BOOT_ENTRY* + OUT PBOOT_STORE_ENTRY BootEntry); // Technically this should be PBOOT_STORE_ENTRY* NTSTATUS -QueryNTOSBootOptions( +QueryBootStoreOptions( IN PVOID Handle, - IN OUT PNTOS_BOOT_OPTIONS BootOptions + IN OUT PBOOT_STORE_OPTIONS BootOptions /* , IN PULONG BootOptionsLength */ ); NTSTATUS -SetNTOSBootOptions( +SetBootStoreOptions( IN PVOID Handle, - IN PNTOS_BOOT_OPTIONS BootOptions, + IN PBOOT_STORE_OPTIONS BootOptions, IN ULONG FieldsToChange); NTSTATUS -EnumerateNTOSBootEntries( +EnumerateBootStoreEntries( IN PVOID Handle, // IN ULONG Flags, // Determine which data to retrieve IN PENUM_BOOT_ENTRIES_ROUTINE EnumBootEntriesRoutine, diff --git a/base/setup/lib/osdetect.c b/base/setup/lib/osdetect.c index daa98c7ab1..ce71007cb6 100644 --- a/base/setup/lib/osdetect.c +++ b/base/setup/lib/osdetect.c @@ -68,8 +68,8 @@ typedef struct _ENUM_INSTALLS_DATA static NTSTATUS NTAPI EnumerateInstallations( - IN NTOS_BOOT_LOADER_TYPE Type, - IN PNTOS_BOOT_ENTRY BootEntry, + IN BOOT_STORE_TYPE Type, + IN PBOOT_STORE_ENTRY BootEntry, IN PVOID Parameter OPTIONAL) { PENUM_INSTALLS_DATA Data = (PENUM_INSTALLS_DATA)Parameter; @@ -95,8 +95,10 @@ EnumerateInstallations( RTL_FIELD_SIZE(NTOS_OPTIONS, Signature)) { /* This is not a ReactOS entry */ - DPRINT1(" An installation '%S' of unsupported type '%S'\n", - BootEntry->FriendlyName, BootEntry->Version ? BootEntry->Version : L"n/a"); + // DPRINT1(" An installation '%S' of unsupported type '%S'\n", + // BootEntry->FriendlyName, BootEntry->Version ? BootEntry->Version : L"n/a"); + DPRINT1(" An installation '%S' of unsupported type %lu\n", + BootEntry->FriendlyName, BootEntry->OsOptionsLength); /* Continue the enumeration */ return STATUS_SUCCESS; } @@ -641,7 +643,7 @@ FindNTOSInstallations( OBJECT_ATTRIBUTES ObjectAttributes; IO_STATUS_BLOCK IoStatusBlock; UNICODE_STRING PartitionRootPath; - NTOS_BOOT_LOADER_TYPE Type; + BOOT_STORE_TYPE Type; PVOID BootStoreHandle; ENUM_INSTALLS_DATA Data; ULONG Version; @@ -678,7 +680,7 @@ FindNTOSInstallations( /* Try to see whether we recognize some NT boot loaders */ for (Type = FreeLdr; Type < BldrTypeMax; ++Type) { - Status = FindNTOSBootLoader(PartitionDirectoryHandle, Type, &Version); + Status = FindBootStore(PartitionDirectoryHandle, Type, &Version); if (!NT_SUCCESS(Status)) { /* The loader does not exist, continue with another one */ @@ -691,15 +693,15 @@ FindNTOSInstallations( DPRINT1("Analyse the OS installations for loader type '%d' in disk #%d, partition #%d\n", Type, DiskNumber, PartitionNumber); - Status = OpenNTOSBootLoaderStoreByHandle(&BootStoreHandle, PartitionDirectoryHandle, Type, FALSE); + Status = OpenBootStoreByHandle(&BootStoreHandle, PartitionDirectoryHandle, Type, FALSE); if (!NT_SUCCESS(Status)) { DPRINT1("Could not open the NTOS boot store of type '%d' (Status 0x%08lx), continue with another one...\n", Type, Status); continue; } - EnumerateNTOSBootEntries(BootStoreHandle, EnumerateInstallations, &Data); - CloseNTOSBootLoaderStore(BootStoreHandle); + EnumerateBootStoreEntries(BootStoreHandle, EnumerateInstallations, &Data); + CloseBootStore(BootStoreHandle); } /* Close the partition */ diff --git a/base/setup/usetup/bootsup.c b/base/setup/usetup/bootsup.c index 2d978b6364..7969e8bae9 100644 --- a/base/setup/usetup/bootsup.c +++ b/base/setup/usetup/bootsup.c @@ -131,12 +131,12 @@ CreateFreeLoaderReactOSEntries( IN PVOID BootStoreHandle, IN PCWSTR ArcPath) { - UCHAR xxBootEntry[FIELD_OFFSET(NTOS_BOOT_ENTRY, OsOptions) + sizeof(NTOS_OPTIONS)]; - PNTOS_BOOT_ENTRY BootEntry = (PNTOS_BOOT_ENTRY)&xxBootEntry; + UCHAR xxBootEntry[FIELD_OFFSET(BOOT_STORE_ENTRY, OsOptions) + sizeof(NTOS_OPTIONS)]; + PBOOT_STORE_ENTRY BootEntry = (PBOOT_STORE_ENTRY)&xxBootEntry; PNTOS_OPTIONS Options = (PNTOS_OPTIONS)&BootEntry->OsOptions; - NTOS_BOOT_OPTIONS BootOptions; + BOOT_STORE_OPTIONS BootOptions; - BootEntry->Version = L"Windows2003"; + BootEntry->Version = FreeLdr; BootEntry->BootFilePath = NULL; BootEntry->OsOptionsLength = sizeof(NTOS_OPTIONS); @@ -150,20 +150,20 @@ CreateFreeLoaderReactOSEntries( // BootEntry->BootEntryKey = MAKESTRKEY(L"ReactOS"); BootEntry->FriendlyName = L"\"ReactOS\""; Options->OsLoadOptions = NULL; // L""; - AddNTOSBootEntry(BootStoreHandle, BootEntry, MAKESTRKEY(L"ReactOS")); + AddBootStoreEntry(BootStoreHandle, BootEntry, MAKESTRKEY(L"ReactOS")); /* ReactOS_Debug */ // BootEntry->BootEntryKey = MAKESTRKEY(L"ReactOS_Debug"); BootEntry->FriendlyName = L"\"ReactOS (Debug)\""; Options->OsLoadOptions = L"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS"; - AddNTOSBootEntry(BootStoreHandle, BootEntry, MAKESTRKEY(L"ReactOS_Debug")); + AddBootStoreEntry(BootStoreHandle, BootEntry, MAKESTRKEY(L"ReactOS_Debug")); #ifdef _WINKD_ /* ReactOS_VBoxDebug */ // BootEntry->BootEntryKey = MAKESTRKEY(L"ReactOS_VBoxDebug"); BootEntry->FriendlyName = L"\"ReactOS (VBoxDebug)\""; Options->OsLoadOptions = L"/DEBUG /DEBUGPORT=VBOX /SOS"; - AddNTOSBootEntry(BootStoreHandle, BootEntry, MAKESTRKEY(L"ReactOS_VBoxDebug")); + AddBootStoreEntry(BootStoreHandle, BootEntry, MAKESTRKEY(L"ReactOS_VBoxDebug")); #endif #if DBG #ifndef _WINKD_ @@ -171,34 +171,34 @@ CreateFreeLoaderReactOSEntries( // BootEntry->BootEntryKey = MAKESTRKEY(L"ReactOS_KdSerial"); BootEntry->FriendlyName = L"\"ReactOS (RosDbg)\""; Options->OsLoadOptions = L"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS /KDSERIAL"; - AddNTOSBootEntry(BootStoreHandle, BootEntry, MAKESTRKEY(L"ReactOS_KdSerial")); + AddBootStoreEntry(BootStoreHandle, BootEntry, MAKESTRKEY(L"ReactOS_KdSerial")); #endif /* ReactOS_Screen */ // BootEntry->BootEntryKey = MAKESTRKEY(L"ReactOS_Screen"); BootEntry->FriendlyName = L"\"ReactOS (Screen)\""; Options->OsLoadOptions = L"/DEBUG /DEBUGPORT=SCREEN /SOS"; - AddNTOSBootEntry(BootStoreHandle, BootEntry, MAKESTRKEY(L"ReactOS_Screen")); + AddBootStoreEntry(BootStoreHandle, BootEntry, MAKESTRKEY(L"ReactOS_Screen")); /* ReactOS_LogFile */ // BootEntry->BootEntryKey = MAKESTRKEY(L"ReactOS_LogFile"); BootEntry->FriendlyName = L"\"ReactOS (Log file)\""; Options->OsLoadOptions = L"/DEBUG /DEBUGPORT=FILE /SOS"; - AddNTOSBootEntry(BootStoreHandle, BootEntry, MAKESTRKEY(L"ReactOS_LogFile")); + AddBootStoreEntry(BootStoreHandle, BootEntry, MAKESTRKEY(L"ReactOS_LogFile")); /* ReactOS_Ram */ // BootEntry->BootEntryKey = MAKESTRKEY(L"ReactOS_Ram"); BootEntry->FriendlyName = L"\"ReactOS (RAM Disk)\""; Options->OsLoadPath = L"ramdisk(0)\\ReactOS"; Options->OsLoadOptions = L"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS /RDPATH=reactos.img /RDIMAGEOFFSET=32256"; - AddNTOSBootEntry(BootStoreHandle, BootEntry, MAKESTRKEY(L"ReactOS_Ram")); + AddBootStoreEntry(BootStoreHandle, BootEntry, MAKESTRKEY(L"ReactOS_Ram")); /* ReactOS_EMS */ // BootEntry->BootEntryKey = MAKESTRKEY(L"ReactOS_EMS"); BootEntry->FriendlyName = L"\"ReactOS (Emergency Management Services)\""; Options->OsLoadPath = ArcPath; Options->OsLoadOptions = L"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS /redirect=com2 /redirectbaudrate=115200"; - AddNTOSBootEntry(BootStoreHandle, BootEntry, MAKESTRKEY(L"ReactOS_EMS")); + AddBootStoreEntry(BootStoreHandle, BootEntry, MAKESTRKEY(L"ReactOS_EMS")); #endif @@ -234,7 +234,8 @@ CreateFreeLoaderReactOSEntries( } #endif - SetNTOSBootOptions(BootStoreHandle, &BootOptions, 2 | 1); + BootOptions.Version = FreeLdr; + SetBootStoreOptions(BootStoreHandle, &BootOptions, 2 | 1); } static NTSTATUS @@ -246,7 +247,7 @@ CreateFreeLoaderIniForReactOS( PVOID BootStoreHandle; /* Initialize the INI file and create the common FreeLdr sections */ - Status = OpenNTOSBootLoaderStore(&BootStoreHandle, IniPath, FreeLdr, TRUE); + Status = OpenBootStore(&BootStoreHandle, IniPath, FreeLdr, TRUE); if (!NT_SUCCESS(Status)) return Status; @@ -254,7 +255,7 @@ CreateFreeLoaderIniForReactOS( CreateFreeLoaderReactOSEntries(BootStoreHandle, ArcPath); /* Close the INI file */ - CloseNTOSBootLoaderStore(BootStoreHandle); + CloseBootStore(BootStoreHandle); return STATUS_SUCCESS; } @@ -270,19 +271,19 @@ CreateFreeLoaderIniForReactOSAndBootSector( { NTSTATUS Status; PVOID BootStoreHandle; - UCHAR xxBootEntry[FIELD_OFFSET(NTOS_BOOT_ENTRY, OsOptions) + sizeof(BOOT_SECTOR_OPTIONS)]; - PNTOS_BOOT_ENTRY BootEntry = (PNTOS_BOOT_ENTRY)&xxBootEntry; + UCHAR xxBootEntry[FIELD_OFFSET(BOOT_STORE_ENTRY, OsOptions) + sizeof(BOOT_SECTOR_OPTIONS)]; + PBOOT_STORE_ENTRY BootEntry = (PBOOT_STORE_ENTRY)&xxBootEntry; PBOOT_SECTOR_OPTIONS Options = (PBOOT_SECTOR_OPTIONS)&BootEntry->OsOptions; /* Initialize the INI file and create the common FreeLdr sections */ - Status = OpenNTOSBootLoaderStore(&BootStoreHandle, IniPath, FreeLdr, TRUE); + Status = OpenBootStore(&BootStoreHandle, IniPath, FreeLdr, TRUE); if (!NT_SUCCESS(Status)) return Status; /* Add the ReactOS entries */ CreateFreeLoaderReactOSEntries(BootStoreHandle, ArcPath); - /**/BootEntry->Version = L"BootSector";/**/ + BootEntry->Version = FreeLdr; BootEntry->BootFilePath = NULL; BootEntry->OsOptionsLength = sizeof(BOOT_SECTOR_OPTIONS); @@ -296,10 +297,10 @@ CreateFreeLoaderIniForReactOSAndBootSector( // BootEntry->BootEntryKey = MAKESTRKEY(Section); BootEntry->FriendlyName = Description; - AddNTOSBootEntry(BootStoreHandle, BootEntry, MAKESTRKEY(Section)); + AddBootStoreEntry(BootStoreHandle, BootEntry, MAKESTRKEY(Section)); /* Close the INI file */ - CloseNTOSBootLoaderStore(BootStoreHandle); + CloseBootStore(BootStoreHandle); return STATUS_SUCCESS; } @@ -322,8 +323,8 @@ typedef struct _ENUM_REACTOS_ENTRIES_DATA static NTSTATUS NTAPI EnumerateReactOSEntries( - IN NTOS_BOOT_LOADER_TYPE Type, - IN PNTOS_BOOT_ENTRY BootEntry, + IN BOOT_STORE_TYPE Type, + IN PBOOT_STORE_ENTRY BootEntry, IN PVOID Parameter OPTIONAL) { PENUM_REACTOS_ENTRIES_DATA Data = (PENUM_REACTOS_ENTRIES_DATA)Parameter; @@ -340,9 +341,10 @@ EnumerateReactOSEntries( RTL_FIELD_SIZE(NTOS_OPTIONS, Signature)) { /* This is not a ReactOS entry */ - DPRINT1(" An installation '%S' of unsupported type '%S'\n", - BootEntry->FriendlyName, - BootEntry->Version ? BootEntry->Version : L"n/a"); + // DPRINT1(" An installation '%S' of unsupported type '%S'\n", + // BootEntry->FriendlyName, BootEntry->Version ? BootEntry->Version : L"n/a"); + DPRINT1(" An installation '%S' of unsupported type %lu\n", + BootEntry->FriendlyName, BootEntry->OsOptionsLength); /* Continue the enumeration */ goto SkipThisEntry; } @@ -403,12 +405,12 @@ UpdateFreeLoaderIni( NTSTATUS Status; PVOID BootStoreHandle; ENUM_REACTOS_ENTRIES_DATA Data; - UCHAR xxBootEntry[FIELD_OFFSET(NTOS_BOOT_ENTRY, OsOptions) + sizeof(NTOS_OPTIONS)]; - PNTOS_BOOT_ENTRY BootEntry = (PNTOS_BOOT_ENTRY)&xxBootEntry; + UCHAR xxBootEntry[FIELD_OFFSET(BOOT_STORE_ENTRY, OsOptions) + sizeof(NTOS_OPTIONS)]; + PBOOT_STORE_ENTRY BootEntry = (PBOOT_STORE_ENTRY)&xxBootEntry; PNTOS_OPTIONS Options = (PNTOS_OPTIONS)&BootEntry->OsOptions; /* Open the INI file */ - Status = OpenNTOSBootLoaderStore(&BootStoreHandle, IniPath, FreeLdr, /*TRUE*/ FALSE); + Status = OpenBootStore(&BootStoreHandle, IniPath, FreeLdr, /*TRUE*/ FALSE); if (!NT_SUCCESS(Status)) return Status; @@ -420,10 +422,10 @@ UpdateFreeLoaderIni( RtlStringCchCopyW(Data.OsName, ARRAYSIZE(Data.OsName), L"\"ReactOS\""); // - // FIXME: We temporarily use EnumerateNTOSBootEntries, until - // both QueryNTOSBootEntry and ModifyNTOSBootEntry get implemented. + // FIXME: We temporarily use EnumerateBootStoreEntries, until + // both QueryBootStoreEntry and ModifyBootStoreEntry get implemented. // - Status = EnumerateNTOSBootEntries(BootStoreHandle, EnumerateReactOSEntries, &Data); + Status = EnumerateBootStoreEntries(BootStoreHandle, EnumerateReactOSEntries, &Data); /* Create a new "ReactOS" entry if there is none already existing that suits us */ if (!Data.UseExistingEntry) @@ -431,7 +433,7 @@ UpdateFreeLoaderIni( // RtlStringCchPrintfW(Data.SectionName, ARRAYSIZE(Data.SectionName), L"ReactOS_%lu", Data.i); // RtlStringCchPrintfW(Data.OsName, ARRAYSIZE(Data.OsName), L"\"ReactOS %lu\"", Data.i); - BootEntry->Version = L"Windows2003"; + BootEntry->Version = FreeLdr; BootEntry->BootFilePath = NULL; BootEntry->OsOptionsLength = sizeof(NTOS_OPTIONS); @@ -444,11 +446,11 @@ UpdateFreeLoaderIni( // BootEntry->BootEntryKey = MAKESTRKEY(Data.SectionName); BootEntry->FriendlyName = Data.OsName; Options->OsLoadOptions = NULL; // L""; - AddNTOSBootEntry(BootStoreHandle, BootEntry, MAKESTRKEY(Data.SectionName)); + AddBootStoreEntry(BootStoreHandle, BootEntry, MAKESTRKEY(Data.SectionName)); } /* Close the INI file */ - CloseNTOSBootLoaderStore(BootStoreHandle); + CloseBootStore(BootStoreHandle); return STATUS_SUCCESS; } @@ -464,12 +466,12 @@ UpdateBootIni( ENUM_REACTOS_ENTRIES_DATA Data; // NOTE: Technically it would be "BootSector"... - UCHAR xxBootEntry[FIELD_OFFSET(NTOS_BOOT_ENTRY, OsOptions) + sizeof(NTOS_OPTIONS)]; - PNTOS_BOOT_ENTRY BootEntry = (PNTOS_BOOT_ENTRY)&xxBootEntry; + UCHAR xxBootEntry[FIELD_OFFSET(BOOT_STORE_ENTRY, OsOptions) + sizeof(NTOS_OPTIONS)]; + PBOOT_STORE_ENTRY BootEntry = (PBOOT_STORE_ENTRY)&xxBootEntry; PNTOS_OPTIONS Options = (PNTOS_OPTIONS)&BootEntry->OsOptions; /* Open the INI file */ - Status = OpenNTOSBootLoaderStore(&BootStoreHandle, IniPath, NtLdr, FALSE); + Status = OpenBootStore(&BootStoreHandle, IniPath, NtLdr, FALSE); if (!NT_SUCCESS(Status)) return Status; @@ -481,16 +483,16 @@ UpdateBootIni( RtlStringCchCopyW(Data.OsName, ARRAYSIZE(Data.OsName), L"\"ReactOS\""); // - // FIXME: We temporarily use EnumerateNTOSBootEntries, until - // both QueryNTOSBootEntry and ModifyNTOSBootEntry get implemented. + // FIXME: We temporarily use EnumerateBootStoreEntries, until + // both QueryBootStoreEntry and ModifyBootStoreEntry get implemented. // - Status = EnumerateNTOSBootEntries(BootStoreHandle, EnumerateReactOSEntries, &Data); + Status = EnumerateBootStoreEntries(BootStoreHandle, EnumerateReactOSEntries, &Data); /* If either the key was not found, or contains something else, add a new one */ if (!Data.UseExistingEntry /* || ( (Status == STATUS_NO_MORE_ENTRIES) && wcscmp(Data.OsName, EntryValue) ) */) { - BootEntry->Version = L"Windows2003"; // NOTE: See remark above + BootEntry->Version = NtLdr; BootEntry->BootFilePath = NULL; BootEntry->OsOptionsLength = sizeof(NTOS_OPTIONS); @@ -504,11 +506,11 @@ UpdateBootIni( // BootEntry->FriendlyName = Data.OsName; BootEntry->FriendlyName = EntryValue; Options->OsLoadOptions = NULL; // L""; - AddNTOSBootEntry(BootStoreHandle, BootEntry, MAKESTRKEY(0 /*Data.SectionName*/)); + AddBootStoreEntry(BootStoreHandle, BootEntry, MAKESTRKEY(0 /*Data.SectionName*/)); } /* Close the INI file */ - CloseNTOSBootLoaderStore(BootStoreHandle); + CloseBootStore(BootStoreHandle); return STATUS_SUCCESS; // Status; } @@ -1804,8 +1806,8 @@ InstallFatBootcodeToPartition( /* Check for NT and other bootloaders */ // FIXME: Check for Vista+ bootloader! - /*** Status = FindNTOSBootLoader(PartitionHandle, NtLdr, &Version); ***/ - /*** Status = FindNTOSBootLoader(PartitionHandle, BootMgr, &Version); ***/ + /*** Status = FindBootStore(PartitionHandle, NtLdr, &Version); ***/ + /*** Status = FindBootStore(PartitionHandle, BootMgr, &Version); ***/ if (DoesFileExist_2(SystemRootPath->Buffer, L"NTLDR") == TRUE || DoesFileExist_2(SystemRootPath->Buffer, L"BOOT.INI") == TRUE) {
6 years, 2 months
1
0
0
0
01/02: [USETUP] As evoked in 27603a10 (r74943), adapt the code in bootsup.c to abstract the manipulation of freeldr.ini and boot.ini, and make it use the new features of bldrsup.c committed in 27603a10 (r74952).
by Hermès Bélusca-Maïto
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=e589513b468602dd34944…
commit e589513b468602dd34944377d9af1cbc1a09feb0 Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org> AuthorDate: Thu Jun 8 02:43:51 2017 +0000 Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org> CommitDate: Sun Oct 14 23:45:45 2018 +0200 [USETUP] As evoked in 27603a10 (r74943), adapt the code in bootsup.c to abstract the manipulation of freeldr.ini and boot.ini, and make it use the new features of bldrsup.c committed in 27603a10 (r74952). In particular the helper functions CreateCommonFreeLdrSections() and (Un)protectBootIni() are now removed from there (they are used in bldrsup.c only). This should pave the way for future integration with other sorts of NT boot loaders (BootMgr and (u)EFI boot loader). svn path=/branches/setup_improvements/; revision=74954 --- base/setup/usetup/bootsup.c | 947 ++++++++++++++------------------------------ 1 file changed, 296 insertions(+), 651 deletions(-) diff --git a/base/setup/usetup/bootsup.c b/base/setup/usetup/bootsup.c index 469693b56a..2d978b6364 100644 --- a/base/setup/usetup/bootsup.c +++ b/base/setup/usetup/bootsup.c @@ -125,345 +125,140 @@ TrimTrailingPathSeparators_UStr( } } -static -VOID -CreateCommonFreeLoaderSections( - PINICACHE IniCache) + +static VOID +CreateFreeLoaderReactOSEntries( + IN PVOID BootStoreHandle, + IN PCWSTR ArcPath) { - PINICACHESECTION IniSection; + UCHAR xxBootEntry[FIELD_OFFSET(NTOS_BOOT_ENTRY, OsOptions) + sizeof(NTOS_OPTIONS)]; + PNTOS_BOOT_ENTRY BootEntry = (PNTOS_BOOT_ENTRY)&xxBootEntry; + PNTOS_OPTIONS Options = (PNTOS_OPTIONS)&BootEntry->OsOptions; + NTOS_BOOT_OPTIONS BootOptions; + + BootEntry->Version = L"Windows2003"; + BootEntry->BootFilePath = NULL; + + BootEntry->OsOptionsLength = sizeof(NTOS_OPTIONS); + RtlCopyMemory(Options->Signature, + NTOS_OPTIONS_SIGNATURE, + RTL_FIELD_SIZE(NTOS_OPTIONS, Signature)); + + Options->OsLoadPath = ArcPath; + + /* ReactOS */ + // BootEntry->BootEntryKey = MAKESTRKEY(L"ReactOS"); + BootEntry->FriendlyName = L"\"ReactOS\""; + Options->OsLoadOptions = NULL; // L""; + AddNTOSBootEntry(BootStoreHandle, BootEntry, MAKESTRKEY(L"ReactOS")); + + /* ReactOS_Debug */ + // BootEntry->BootEntryKey = MAKESTRKEY(L"ReactOS_Debug"); + BootEntry->FriendlyName = L"\"ReactOS (Debug)\""; + Options->OsLoadOptions = L"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS"; + AddNTOSBootEntry(BootStoreHandle, BootEntry, MAKESTRKEY(L"ReactOS_Debug")); + +#ifdef _WINKD_ + /* ReactOS_VBoxDebug */ + // BootEntry->BootEntryKey = MAKESTRKEY(L"ReactOS_VBoxDebug"); + BootEntry->FriendlyName = L"\"ReactOS (VBoxDebug)\""; + Options->OsLoadOptions = L"/DEBUG /DEBUGPORT=VBOX /SOS"; + AddNTOSBootEntry(BootStoreHandle, BootEntry, MAKESTRKEY(L"ReactOS_VBoxDebug")); +#endif +#if DBG +#ifndef _WINKD_ + /* ReactOS_KdSerial */ + // BootEntry->BootEntryKey = MAKESTRKEY(L"ReactOS_KdSerial"); + BootEntry->FriendlyName = L"\"ReactOS (RosDbg)\""; + Options->OsLoadOptions = L"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS /KDSERIAL"; + AddNTOSBootEntry(BootStoreHandle, BootEntry, MAKESTRKEY(L"ReactOS_KdSerial")); +#endif + + /* ReactOS_Screen */ + // BootEntry->BootEntryKey = MAKESTRKEY(L"ReactOS_Screen"); + BootEntry->FriendlyName = L"\"ReactOS (Screen)\""; + Options->OsLoadOptions = L"/DEBUG /DEBUGPORT=SCREEN /SOS"; + AddNTOSBootEntry(BootStoreHandle, BootEntry, MAKESTRKEY(L"ReactOS_Screen")); + + /* ReactOS_LogFile */ + // BootEntry->BootEntryKey = MAKESTRKEY(L"ReactOS_LogFile"); + BootEntry->FriendlyName = L"\"ReactOS (Log file)\""; + Options->OsLoadOptions = L"/DEBUG /DEBUGPORT=FILE /SOS"; + AddNTOSBootEntry(BootStoreHandle, BootEntry, MAKESTRKEY(L"ReactOS_LogFile")); + + /* ReactOS_Ram */ + // BootEntry->BootEntryKey = MAKESTRKEY(L"ReactOS_Ram"); + BootEntry->FriendlyName = L"\"ReactOS (RAM Disk)\""; + Options->OsLoadPath = L"ramdisk(0)\\ReactOS"; + Options->OsLoadOptions = L"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS /RDPATH=reactos.img /RDIMAGEOFFSET=32256"; + AddNTOSBootEntry(BootStoreHandle, BootEntry, MAKESTRKEY(L"ReactOS_Ram")); + + /* ReactOS_EMS */ + // BootEntry->BootEntryKey = MAKESTRKEY(L"ReactOS_EMS"); + BootEntry->FriendlyName = L"\"ReactOS (Emergency Management Services)\""; + Options->OsLoadPath = ArcPath; + Options->OsLoadOptions = L"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS /redirect=com2 /redirectbaudrate=115200"; + AddNTOSBootEntry(BootStoreHandle, BootEntry, MAKESTRKEY(L"ReactOS_EMS")); +#endif - /* Create "FREELOADER" section */ - IniSection = IniCacheAppendSection(IniCache, L"FREELOADER"); #if DBG if (IsUnattendedSetup) { /* DefaultOS=ReactOS */ - IniCacheInsertKey(IniSection, - NULL, - INSERT_LAST, - L"DefaultOS", #ifndef _WINKD_ - L"ReactOS_KdSerial"); + BootOptions.CurrentBootEntryKey = MAKESTRKEY(L"ReactOS_KdSerial"); #else - L"ReactOS_Debug"); + BootOptions.CurrentBootEntryKey = MAKESTRKEY(L"ReactOS_Debug"); #endif } else #endif { /* DefaultOS=ReactOS */ - IniCacheInsertKey(IniSection, - NULL, - INSERT_LAST, - L"DefaultOS", - L"ReactOS"); + BootOptions.CurrentBootEntryKey = MAKESTRKEY(L"ReactOS"); } #if DBG if (IsUnattendedSetup) #endif { - /* Timeout=0 for unattended or non debug*/ - IniCacheInsertKey(IniSection, - NULL, - INSERT_LAST, - L"TimeOut", - L"0"); + /* Timeout=0 for unattended or non debug */ + BootOptions.Timeout = 0; } #if DBG else { - /* Timeout=0 or 10 */ - IniCacheInsertKey(IniSection, - NULL, - INSERT_LAST, - L"TimeOut", - L"10"); + /* Timeout=10 */ + BootOptions.Timeout = 10; } #endif - /* Create "Display" section */ - IniSection = IniCacheAppendSection(IniCache, L"Display"); - - /* TitleText=ReactOS Boot Manager */ - IniCacheInsertKey(IniSection, - NULL, - INSERT_LAST, - L"TitleText", - L"ReactOS Boot Manager"); - - /* StatusBarColor=Cyan */ - IniCacheInsertKey(IniSection, - NULL, - INSERT_LAST, - L"StatusBarColor", - L"Cyan"); - - /* StatusBarTextColor=Black */ - IniCacheInsertKey(IniSection, - NULL, - INSERT_LAST, - L"StatusBarTextColor", - L"Black"); - - /* BackdropTextColor=White */ - IniCacheInsertKey(IniSection, - NULL, - INSERT_LAST, - L"BackdropTextColor", - L"White"); - - /* BackdropColor=Blue */ - IniCacheInsertKey(IniSection, - NULL, - INSERT_LAST, - L"BackdropColor", - L"Blue"); - - /* BackdropFillStyle=Medium */ - IniCacheInsertKey(IniSection, - NULL, - INSERT_LAST, - L"BackdropFillStyle", - L"Medium"); - - /* TitleBoxTextColor=White */ - IniCacheInsertKey(IniSection, - NULL, - INSERT_LAST, - L"TitleBoxTextColor", - L"White"); - - /* TitleBoxColor=Red */ - IniCacheInsertKey(IniSection, - NULL, - INSERT_LAST, - L"TitleBoxColor", - L"Red"); - - /* MessageBoxTextColor=White */ - IniCacheInsertKey(IniSection, - NULL, - INSERT_LAST, - L"MessageBoxTextColor", - L"White"); - - /* MessageBoxColor=Blue */ - IniCacheInsertKey(IniSection, - NULL, - INSERT_LAST, - L"MessageBoxColor", - L"Blue"); - - /* MenuTextColor=White */ - IniCacheInsertKey(IniSection, - NULL, - INSERT_LAST, - L"MenuTextColor", - L"Gray"); - - /* MenuColor=Blue */ - IniCacheInsertKey(IniSection, - NULL, - INSERT_LAST, - L"MenuColor", - L"Black"); - - /* TextColor=Yellow */ - IniCacheInsertKey(IniSection, - NULL, - INSERT_LAST, - L"TextColor", - L"Gray"); - - /* SelectedTextColor=Black */ - IniCacheInsertKey(IniSection, - NULL, - INSERT_LAST, - L"SelectedTextColor", - L"Black"); - - /* SelectedColor=Gray */ - IniCacheInsertKey(IniSection, - NULL, - INSERT_LAST, - L"SelectedColor", - L"Gray"); - - /* SelectedColor=Gray */ - IniCacheInsertKey(IniSection, - NULL, - INSERT_LAST, - L"ShowTime", - L"No"); - - /* SelectedColor=Gray */ - IniCacheInsertKey(IniSection, - NULL, - INSERT_LAST, - L"MenuBox", - L"No"); - - /* SelectedColor=Gray */ - IniCacheInsertKey(IniSection, - NULL, - INSERT_LAST, - L"CenterMenu", - L"No"); - - /* SelectedColor=Gray */ - IniCacheInsertKey(IniSection, - NULL, - INSERT_LAST, - L"MinimalUI", - L"Yes"); - - /* SelectedColor=Gray */ - IniCacheInsertKey(IniSection, - NULL, - INSERT_LAST, - L"TimeText", - L"Seconds until highlighted choice will be started automatically: "); -} - -static -NTSTATUS -CreateNTOSEntry( - PINICACHE IniCache, - PINICACHESECTION OSSection, - PWCHAR Section, - PWCHAR Description, - PWCHAR BootType, - PWCHAR ArcPath, - PWCHAR Options) -{ - PINICACHESECTION IniSection; - - /* Insert entry into "Operating Systems" section */ - IniCacheInsertKey(OSSection, - NULL, - INSERT_LAST, - Section, - Description); - - /* Create new section */ - IniSection = IniCacheAppendSection(IniCache, Section); - - /* BootType= */ - IniCacheInsertKey(IniSection, - NULL, - INSERT_LAST, - L"BootType", - BootType); - - /* SystemPath= */ - IniCacheInsertKey(IniSection, - NULL, - INSERT_LAST, - L"SystemPath", - ArcPath); - - /* Options= */ - IniCacheInsertKey(IniSection, - NULL, - INSERT_LAST, - L"Options", - Options); - - return STATUS_SUCCESS; -} - -static -VOID -CreateFreeLoaderReactOSEntries( - PINICACHE IniCache, - PWCHAR ArcPath) -{ - PINICACHESECTION IniSection; - - /* Create "Operating Systems" section */ - IniSection = IniCacheAppendSection(IniCache, L"Operating Systems"); - - /* ReactOS */ - CreateNTOSEntry(IniCache, IniSection, - L"ReactOS", L"\"ReactOS\"", - L"Windows2003", ArcPath, - L""); - - /* ReactOS_Debug */ - CreateNTOSEntry(IniCache, IniSection, - L"ReactOS_Debug", L"\"ReactOS (Debug)\"", - L"Windows2003", ArcPath, - L"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS"); -#ifdef _WINKD_ - /* ReactOS_VBoxDebug */ - CreateNTOSEntry(IniCache, IniSection, - L"ReactOS_VBoxDebug", L"\"ReactOS (VBoxDebug)\"", - L"Windows2003", ArcPath, - L"/DEBUG /DEBUGPORT=VBOX /SOS"); -#endif -#if DBG -#ifndef _WINKD_ - /* ReactOS_KdSerial */ - CreateNTOSEntry(IniCache, IniSection, - L"ReactOS_KdSerial", L"\"ReactOS (RosDbg)\"", - L"Windows2003", ArcPath, - L"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS /KDSERIAL"); -#endif - - /* ReactOS_Screen */ - CreateNTOSEntry(IniCache, IniSection, - L"ReactOS_Screen", L"\"ReactOS (Screen)\"", - L"Windows2003", ArcPath, - L"/DEBUG /DEBUGPORT=SCREEN /SOS"); - - /* ReactOS_LogFile */ - CreateNTOSEntry(IniCache, IniSection, - L"ReactOS_LogFile", L"\"ReactOS (Log file)\"", - L"Windows2003", ArcPath, - L"/DEBUG /DEBUGPORT=FILE /SOS"); - - /* ReactOS_Ram */ - CreateNTOSEntry(IniCache, IniSection, - L"ReactOS_Ram", L"\"ReactOS (RAM Disk)\"", - L"Windows2003", L"ramdisk(0)\\ReactOS", - L"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS /RDPATH=reactos.img /RDIMAGEOFFSET=32256"); - - /* ReactOS_EMS */ - CreateNTOSEntry(IniCache, IniSection, - L"ReactOS_EMS", L"\"ReactOS (Emergency Management Services)\"", - L"Windows2003", ArcPath, - L"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS /redirect=com2 /redirectbaudrate=115200"); -#endif + SetNTOSBootOptions(BootStoreHandle, &BootOptions, 2 | 1); } -static -NTSTATUS +static NTSTATUS CreateFreeLoaderIniForReactOS( - PWCHAR IniPath, - PWCHAR ArcPath) + IN PCWSTR IniPath, + IN PCWSTR ArcPath) { - PINICACHE IniCache; - - /* Initialize the INI file */ - IniCache = IniCacheCreate(); + NTSTATUS Status; + PVOID BootStoreHandle; - /* Create the common FreeLdr sections */ - CreateCommonFreeLoaderSections(IniCache); + /* Initialize the INI file and create the common FreeLdr sections */ + Status = OpenNTOSBootLoaderStore(&BootStoreHandle, IniPath, FreeLdr, TRUE); + if (!NT_SUCCESS(Status)) + return Status; /* Add the ReactOS entries */ - CreateFreeLoaderReactOSEntries(IniCache, ArcPath); - - /* Save the INI file */ - IniCacheSave(IniCache, IniPath); - IniCacheDestroy(IniCache); + CreateFreeLoaderReactOSEntries(BootStoreHandle, ArcPath); + /* Close the INI file */ + CloseNTOSBootLoaderStore(BootStoreHandle); return STATUS_SUCCESS; } -static -NTSTATUS +static NTSTATUS CreateFreeLoaderIniForReactOSAndBootSector( IN PCWSTR IniPath, IN PCWSTR ArcPath, @@ -472,385 +267,249 @@ CreateFreeLoaderIniForReactOSAndBootSector( IN PCWSTR BootDrive, IN PCWSTR BootPartition, IN PCWSTR BootSector) -{ - PINICACHE IniCache; - PINICACHESECTION IniSection; - - /* Initialize the INI file */ - IniCache = IniCacheCreate(); - - /* Create the common FreeLdr sections */ - CreateCommonFreeLoaderSections(IniCache); - - /* Add the ReactOS entries */ - CreateFreeLoaderReactOSEntries(IniCache, (PWCHAR)ArcPath); - - /* Get "Operating Systems" section */ - IniSection = IniCacheGetSection(IniCache, L"Operating Systems"); - - /* Insert entry into "Operating Systems" section */ - IniCacheInsertKey(IniSection, - NULL, - INSERT_LAST, - (PWCHAR)Section, - (PWCHAR)Description); - - /* Create new section */ - IniSection = IniCacheAppendSection(IniCache, (PWCHAR)Section); - - /* BootType=BootSector */ - IniCacheInsertKey(IniSection, - NULL, - INSERT_LAST, - L"BootType", - L"BootSector"); - - /* BootDrive= */ - IniCacheInsertKey(IniSection, - NULL, - INSERT_LAST, - L"BootDrive", - (PWCHAR)BootDrive); - - /* BootPartition= */ - IniCacheInsertKey(IniSection, - NULL, - INSERT_LAST, - L"BootPartition", - (PWCHAR)BootPartition); - - /* BootSector= */ - IniCacheInsertKey(IniSection, - NULL, - INSERT_LAST, - L"BootSectorFile", - (PWCHAR)BootSector); - - /* Save the INI file */ - IniCacheSave(IniCache, (PWCHAR)IniPath); - IniCacheDestroy(IniCache); - - return STATUS_SUCCESS; -} - -static -NTSTATUS -UpdateFreeLoaderIni( - PWCHAR IniPath, - PWCHAR ArcPath) { NTSTATUS Status; - PINICACHE IniCache; - PINICACHESECTION IniSection; - PINICACHESECTION OsIniSection; - WCHAR SectionName[80]; - WCHAR OsName[80]; - WCHAR SystemPath[200]; - WCHAR SectionName2[200]; - PWCHAR KeyData; - ULONG i,j; + PVOID BootStoreHandle; + UCHAR xxBootEntry[FIELD_OFFSET(NTOS_BOOT_ENTRY, OsOptions) + sizeof(BOOT_SECTOR_OPTIONS)]; + PNTOS_BOOT_ENTRY BootEntry = (PNTOS_BOOT_ENTRY)&xxBootEntry; + PBOOT_SECTOR_OPTIONS Options = (PBOOT_SECTOR_OPTIONS)&BootEntry->OsOptions; - Status = IniCacheLoad(&IniCache, IniPath, FALSE); + /* Initialize the INI file and create the common FreeLdr sections */ + Status = OpenNTOSBootLoaderStore(&BootStoreHandle, IniPath, FreeLdr, TRUE); if (!NT_SUCCESS(Status)) return Status; - /* Get "Operating Systems" section */ - IniSection = IniCacheGetSection(IniCache, L"Operating Systems"); - if (IniSection == NULL) - { - IniCacheDestroy(IniCache); - return STATUS_UNSUCCESSFUL; - } - - /* Find an existing usable or an unused section name */ - i = 1; - wcscpy(SectionName, L"ReactOS"); - wcscpy(OsName, L"\"ReactOS\""); - while(TRUE) - { - Status = IniCacheGetKey(IniSection, SectionName, &KeyData); - if (!NT_SUCCESS(Status)) - break; - - /* Get operation system section */ - if (KeyData[0] == '"') - { - wcscpy(SectionName2, &KeyData[1]); - j = wcslen(SectionName2); - if (j > 0) - { - SectionName2[j-1] = 0; - } - } - else - { - wcscpy(SectionName2, KeyData); - } - - /* Search for an existing ReactOS entry */ - OsIniSection = IniCacheGetSection(IniCache, SectionName2); - if (OsIniSection != NULL) - { - BOOLEAN UseExistingEntry = TRUE; - - /* Check for boot type "Windows2003" */ - Status = IniCacheGetKey(OsIniSection, L"BootType", &KeyData); - if (NT_SUCCESS(Status)) - { - if ((KeyData == NULL) || - ( (_wcsicmp(KeyData, L"Windows2003") != 0) && - (_wcsicmp(KeyData, L"\"Windows2003\"") != 0) )) - { - /* This is not a ReactOS entry */ - UseExistingEntry = FALSE; - } - } - else - { - UseExistingEntry = FALSE; - } - - if (UseExistingEntry) - { - /* BootType is Windows2003. Now check SystemPath. */ - Status = IniCacheGetKey(OsIniSection, L"SystemPath", &KeyData); - if (NT_SUCCESS(Status)) - { - swprintf(SystemPath, L"\"%s\"", ArcPath); - if ((KeyData == NULL) || - ( (_wcsicmp(KeyData, ArcPath) != 0) && - (_wcsicmp(KeyData, SystemPath) != 0) )) - { - /* This entry is a ReactOS entry, but the SystemRoot - does not match the one we are looking for. */ - UseExistingEntry = FALSE; - } - } - else - { - UseExistingEntry = FALSE; - } - } + /* Add the ReactOS entries */ + CreateFreeLoaderReactOSEntries(BootStoreHandle, ArcPath); - if (UseExistingEntry) - { - IniCacheDestroy(IniCache); - return STATUS_SUCCESS; - } - } + /**/BootEntry->Version = L"BootSector";/**/ + BootEntry->BootFilePath = NULL; - swprintf(SectionName, L"ReactOS_%lu", i); - swprintf(OsName, L"\"ReactOS %lu\"", i); - i++; - } + BootEntry->OsOptionsLength = sizeof(BOOT_SECTOR_OPTIONS); + RtlCopyMemory(Options->Signature, + BOOT_SECTOR_OPTIONS_SIGNATURE, + RTL_FIELD_SIZE(BOOT_SECTOR_OPTIONS, Signature)); - /* Create a new "ReactOS" entry */ - CreateNTOSEntry(IniCache, IniSection, - SectionName, OsName, - L"Windows2003", ArcPath, - L""); + Options->Drive = BootDrive; + Options->Partition = BootPartition; + Options->BootSectorFileName = BootSector; - IniCacheSave(IniCache, IniPath); - IniCacheDestroy(IniCache); + // BootEntry->BootEntryKey = MAKESTRKEY(Section); + BootEntry->FriendlyName = Description; + AddNTOSBootEntry(BootStoreHandle, BootEntry, MAKESTRKEY(Section)); + /* Close the INI file */ + CloseNTOSBootLoaderStore(BootStoreHandle); return STATUS_SUCCESS; } -static -NTSTATUS -UnprotectBootIni( - PWSTR FileName, - PULONG Attributes) -{ - NTSTATUS Status; - UNICODE_STRING Name; - OBJECT_ATTRIBUTES ObjectAttributes; - IO_STATUS_BLOCK IoStatusBlock; - FILE_BASIC_INFORMATION FileInfo; - HANDLE FileHandle; +// +// I think this function can be generalizable as: +// "find the corresponding 'ReactOS' boot entry in this loader config file +// (here abstraction comes there), and if none, add a new one". +// - RtlInitUnicodeString(&Name, FileName); +typedef struct _ENUM_REACTOS_ENTRIES_DATA +{ + ULONG i; + BOOLEAN UseExistingEntry; + PCWSTR ArcPath; + WCHAR SectionName[80]; + WCHAR OsName[80]; +} ENUM_REACTOS_ENTRIES_DATA, *PENUM_REACTOS_ENTRIES_DATA; + +// PENUM_BOOT_ENTRIES_ROUTINE +static NTSTATUS +NTAPI +EnumerateReactOSEntries( + IN NTOS_BOOT_LOADER_TYPE Type, + IN PNTOS_BOOT_ENTRY BootEntry, + IN PVOID Parameter OPTIONAL) +{ + PENUM_REACTOS_ENTRIES_DATA Data = (PENUM_REACTOS_ENTRIES_DATA)Parameter; + PNTOS_OPTIONS Options = (PNTOS_OPTIONS)&BootEntry->OsOptions; + WCHAR SystemPath[MAX_PATH]; - InitializeObjectAttributes(&ObjectAttributes, - &Name, - OBJ_CASE_INSENSITIVE, - NULL, - NULL); + /* We have a boot entry */ - Status = NtOpenFile(&FileHandle, - GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, - &ObjectAttributes, - &IoStatusBlock, - 0, - FILE_SYNCHRONOUS_IO_NONALERT); - if (Status == STATUS_NO_SUCH_FILE) + /* Check for supported boot type "Windows2003" */ + if (BootEntry->OsOptionsLength < sizeof(NTOS_OPTIONS) || + RtlCompareMemory(&BootEntry->OsOptions /* Signature */, + NTOS_OPTIONS_SIGNATURE, + RTL_FIELD_SIZE(NTOS_OPTIONS, Signature)) != + RTL_FIELD_SIZE(NTOS_OPTIONS, Signature)) { - DPRINT1("NtOpenFile() failed (Status %lx)\n", Status); - *Attributes = 0; - return STATUS_SUCCESS; + /* This is not a ReactOS entry */ + DPRINT1(" An installation '%S' of unsupported type '%S'\n", + BootEntry->FriendlyName, + BootEntry->Version ? BootEntry->Version : L"n/a"); + /* Continue the enumeration */ + goto SkipThisEntry; } - if (!NT_SUCCESS(Status)) + + /* BootType is Windows2003, now check OsLoadPath */ + if (!Options->OsLoadPath || !*Options->OsLoadPath) { - DPRINT1("NtOpenFile() failed (Status %lx)\n", Status); - return Status; + /* Certainly not a ReactOS installation */ + DPRINT1(" A Win2k3 install '%S' without an ARC path?!\n", BootEntry->FriendlyName); + /* Continue the enumeration */ + goto SkipThisEntry; } - Status = NtQueryInformationFile(FileHandle, - &IoStatusBlock, - &FileInfo, - sizeof(FILE_BASIC_INFORMATION), - FileBasicInformation); - if (!NT_SUCCESS(Status)) + RtlStringCchPrintfW(SystemPath, ARRAYSIZE(SystemPath), L"\"%s\"", Data->ArcPath); + if ((_wcsicmp(Options->OsLoadPath, Data->ArcPath) != 0) && + (_wcsicmp(Options->OsLoadPath, SystemPath) != 0)) { - DPRINT1("NtQueryInformationFile() failed (Status %lx)\n", Status); - NtClose(FileHandle); - return Status; + /* + * This entry is a ReactOS entry, but the SystemRoot + * does not match the one we are looking for. + */ + /* Continue the enumeration */ + goto SkipThisEntry; } - *Attributes = FileInfo.FileAttributes; + DPRINT1(" Found a candidate Win2k3 install '%S' with ARC path '%S'\n", + BootEntry->FriendlyName, Options->OsLoadPath); + // DPRINT1(" Found a Win2k3 install '%S' with ARC path '%S'\n", + // BootEntry->FriendlyName, Options->OsLoadPath); - /* Delete attributes SYSTEM, HIDDEN and READONLY */ - FileInfo.FileAttributes = FileInfo.FileAttributes & - ~(FILE_ATTRIBUTE_SYSTEM | - FILE_ATTRIBUTE_HIDDEN | - FILE_ATTRIBUTE_READONLY); + DPRINT1("EnumerateReactOSEntries: OsLoadPath: '%S'\n", Options->OsLoadPath); - Status = NtSetInformationFile(FileHandle, - &IoStatusBlock, - &FileInfo, - sizeof(FILE_BASIC_INFORMATION), - FileBasicInformation); - if (!NT_SUCCESS(Status)) + Data->UseExistingEntry = TRUE; + RtlStringCchCopyW(Data->OsName, ARRAYSIZE(Data->OsName), BootEntry->FriendlyName); + + /* We have found our entry, stop the enumeration now! */ + return STATUS_NO_MORE_ENTRIES; + +SkipThisEntry: + Data->UseExistingEntry = FALSE; + if (Type == FreeLdr && wcscmp(Data->SectionName, (PWSTR)BootEntry->BootEntryKey)== 0) { - DPRINT1("NtSetInformationFile() failed (Status %lx)\n", Status); + RtlStringCchPrintfW(Data->SectionName, ARRAYSIZE(Data->SectionName), + L"ReactOS_%lu", Data->i); + RtlStringCchPrintfW(Data->OsName, ARRAYSIZE(Data->OsName), + L"\"ReactOS %lu\"", Data->i); + Data->i++; } - - NtClose(FileHandle); - return Status; + return STATUS_SUCCESS; } static NTSTATUS -ProtectBootIni( - PWSTR FileName, - ULONG Attributes) +UpdateFreeLoaderIni( + IN PCWSTR IniPath, + IN PCWSTR ArcPath) { NTSTATUS Status; - UNICODE_STRING Name; - OBJECT_ATTRIBUTES ObjectAttributes; - IO_STATUS_BLOCK IoStatusBlock; - FILE_BASIC_INFORMATION FileInfo; - HANDLE FileHandle; + PVOID BootStoreHandle; + ENUM_REACTOS_ENTRIES_DATA Data; + UCHAR xxBootEntry[FIELD_OFFSET(NTOS_BOOT_ENTRY, OsOptions) + sizeof(NTOS_OPTIONS)]; + PNTOS_BOOT_ENTRY BootEntry = (PNTOS_BOOT_ENTRY)&xxBootEntry; + PNTOS_OPTIONS Options = (PNTOS_OPTIONS)&BootEntry->OsOptions; + + /* Open the INI file */ + Status = OpenNTOSBootLoaderStore(&BootStoreHandle, IniPath, FreeLdr, /*TRUE*/ FALSE); + if (!NT_SUCCESS(Status)) + return Status; - RtlInitUnicodeString(&Name, FileName); + /* Find an existing usable or an unused section name */ + Data.UseExistingEntry = TRUE; + Data.i = 1; + Data.ArcPath = ArcPath; + RtlStringCchCopyW(Data.SectionName, ARRAYSIZE(Data.SectionName), L"ReactOS"); + RtlStringCchCopyW(Data.OsName, ARRAYSIZE(Data.OsName), L"\"ReactOS\""); - InitializeObjectAttributes(&ObjectAttributes, - &Name, - OBJ_CASE_INSENSITIVE, - NULL, - NULL); + // + // FIXME: We temporarily use EnumerateNTOSBootEntries, until + // both QueryNTOSBootEntry and ModifyNTOSBootEntry get implemented. + // + Status = EnumerateNTOSBootEntries(BootStoreHandle, EnumerateReactOSEntries, &Data); - Status = NtOpenFile(&FileHandle, - GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, - &ObjectAttributes, - &IoStatusBlock, - 0, - FILE_SYNCHRONOUS_IO_NONALERT); - if (!NT_SUCCESS(Status)) + /* Create a new "ReactOS" entry if there is none already existing that suits us */ + if (!Data.UseExistingEntry) { - DPRINT1("NtOpenFile() failed (Status %lx)\n", Status); - return Status; - } + // RtlStringCchPrintfW(Data.SectionName, ARRAYSIZE(Data.SectionName), L"ReactOS_%lu", Data.i); + // RtlStringCchPrintfW(Data.OsName, ARRAYSIZE(Data.OsName), L"\"ReactOS %lu\"", Data.i); - Status = NtQueryInformationFile(FileHandle, - &IoStatusBlock, - &FileInfo, - sizeof(FILE_BASIC_INFORMATION), - FileBasicInformation); - if (!NT_SUCCESS(Status)) - { - DPRINT1("NtQueryInformationFile() failed (Status %lx)\n", Status); - NtClose(FileHandle); - return Status; - } + BootEntry->Version = L"Windows2003"; + BootEntry->BootFilePath = NULL; - FileInfo.FileAttributes = FileInfo.FileAttributes | Attributes; + BootEntry->OsOptionsLength = sizeof(NTOS_OPTIONS); + RtlCopyMemory(Options->Signature, + NTOS_OPTIONS_SIGNATURE, + RTL_FIELD_SIZE(NTOS_OPTIONS, Signature)); - Status = NtSetInformationFile(FileHandle, - &IoStatusBlock, - &FileInfo, - sizeof(FILE_BASIC_INFORMATION), - FileBasicInformation); - if (!NT_SUCCESS(Status)) - { - DPRINT1("NtSetInformationFile() failed (Status %lx)\n", Status); + Options->OsLoadPath = ArcPath; + + // BootEntry->BootEntryKey = MAKESTRKEY(Data.SectionName); + BootEntry->FriendlyName = Data.OsName; + Options->OsLoadOptions = NULL; // L""; + AddNTOSBootEntry(BootStoreHandle, BootEntry, MAKESTRKEY(Data.SectionName)); } - NtClose(FileHandle); - return Status; + /* Close the INI file */ + CloseNTOSBootLoaderStore(BootStoreHandle); + return STATUS_SUCCESS; } static NTSTATUS UpdateBootIni( - PWSTR BootIniPath, - PWSTR EntryName, - PWSTR EntryValue) + IN PCWSTR IniPath, + IN PCWSTR EntryName, // ~= ArcPath + IN PCWSTR EntryValue) { NTSTATUS Status; - PINICACHE Cache = NULL; - PINICACHESECTION Section = NULL; - ULONG FileAttribute; - PWCHAR OldValue = NULL; + PVOID BootStoreHandle; + ENUM_REACTOS_ENTRIES_DATA Data; - Status = IniCacheLoad(&Cache, BootIniPath, FALSE); - if (!NT_SUCCESS(Status)) - { - return Status; - } - - Section = IniCacheGetSection(Cache, - L"operating systems"); - if (Section == NULL) - { - IniCacheDestroy(Cache); - return STATUS_UNSUCCESSFUL; - } - - /* Check - maybe record already exists */ - Status = IniCacheGetKey(Section, EntryName, &OldValue); - - /* If either key was not found, or contains something else - add new one */ - if (!NT_SUCCESS(Status) || wcscmp(OldValue, EntryValue)) - { - IniCacheInsertKey(Section, - NULL, - INSERT_LAST, - EntryName, - EntryValue); - } - - Status = UnprotectBootIni(BootIniPath, - &FileAttribute); - if (!NT_SUCCESS(Status)) - { - IniCacheDestroy(Cache); - return Status; - } + // NOTE: Technically it would be "BootSector"... + UCHAR xxBootEntry[FIELD_OFFSET(NTOS_BOOT_ENTRY, OsOptions) + sizeof(NTOS_OPTIONS)]; + PNTOS_BOOT_ENTRY BootEntry = (PNTOS_BOOT_ENTRY)&xxBootEntry; + PNTOS_OPTIONS Options = (PNTOS_OPTIONS)&BootEntry->OsOptions; - Status = IniCacheSave(Cache, BootIniPath); + /* Open the INI file */ + Status = OpenNTOSBootLoaderStore(&BootStoreHandle, IniPath, NtLdr, FALSE); if (!NT_SUCCESS(Status)) - { - IniCacheDestroy(Cache); return Status; - } - - FileAttribute |= (FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_READONLY); - Status = ProtectBootIni(BootIniPath, FileAttribute); - - IniCacheDestroy(Cache); - return Status; + /* Find an existing usable or an unused section name */ + Data.UseExistingEntry = TRUE; + // Data.i = 1; + Data.ArcPath = EntryName; + // RtlStringCchCopyW(Data.SectionName, ARRAYSIZE(Data.SectionName), L"ReactOS"); + RtlStringCchCopyW(Data.OsName, ARRAYSIZE(Data.OsName), L"\"ReactOS\""); + + // + // FIXME: We temporarily use EnumerateNTOSBootEntries, until + // both QueryNTOSBootEntry and ModifyNTOSBootEntry get implemented. + // + Status = EnumerateNTOSBootEntries(BootStoreHandle, EnumerateReactOSEntries, &Data); + + /* If either the key was not found, or contains something else, add a new one */ + if (!Data.UseExistingEntry /* || + ( (Status == STATUS_NO_MORE_ENTRIES) && wcscmp(Data.OsName, EntryValue) ) */) + { + BootEntry->Version = L"Windows2003"; // NOTE: See remark above + BootEntry->BootFilePath = NULL; + + BootEntry->OsOptionsLength = sizeof(NTOS_OPTIONS); + RtlCopyMemory(Options->Signature, + NTOS_OPTIONS_SIGNATURE, + RTL_FIELD_SIZE(NTOS_OPTIONS, Signature)); + + Options->OsLoadPath = EntryName; + + // BootEntry->BootEntryKey = MAKESTRKEY(Data.SectionName); + // BootEntry->FriendlyName = Data.OsName; + BootEntry->FriendlyName = EntryValue; + Options->OsLoadOptions = NULL; // L""; + AddNTOSBootEntry(BootStoreHandle, BootEntry, MAKESTRKEY(0 /*Data.SectionName*/)); + } + + /* Close the INI file */ + CloseNTOSBootLoaderStore(BootStoreHandle); + return STATUS_SUCCESS; // Status; } @@ -2129,15 +1788,12 @@ InstallFatBootcodeToPartition( } /* Prepare for possibly updating 'freeldr.ini' */ - CombinePaths(DstPath, ARRAYSIZE(DstPath), 2, SystemRootPath->Buffer, L"freeldr.ini"); - - DoesFreeLdrExist = DoesFileExist(NULL, DstPath); + DoesFreeLdrExist = DoesFileExist_2(SystemRootPath->Buffer, L"freeldr.ini"); if (DoesFreeLdrExist) { /* Update existing 'freeldr.ini' */ DPRINT1("Update existing 'freeldr.ini'\n"); - - Status = UpdateFreeLoaderIni(DstPath, DestinationArcPath->Buffer); + Status = UpdateFreeLoaderIni(SystemRootPath->Buffer, DestinationArcPath->Buffer); if (!NT_SUCCESS(Status)) { DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status); @@ -2161,9 +1817,7 @@ InstallFatBootcodeToPartition( { /* Create new 'freeldr.ini' */ DPRINT1("Create new 'freeldr.ini'\n"); - // CombinePaths(DstPath, ARRAYSIZE(DstPath), 2, SystemRootPath->Buffer, L"freeldr.ini"); - - Status = CreateFreeLoaderIniForReactOS(DstPath, DestinationArcPath->Buffer); + Status = CreateFreeLoaderIniForReactOS(SystemRootPath->Buffer, DestinationArcPath->Buffer); if (!NT_SUCCESS(Status)) { DPRINT1("CreateFreeLoaderIniForReactOS() failed (Status %lx)\n", Status); @@ -2205,12 +1859,10 @@ InstallFatBootcodeToPartition( } /* Update 'boot.ini' */ - CombinePaths(DstPath, ARRAYSIZE(DstPath), 2, SystemRootPath->Buffer, L"boot.ini"); - /* Windows' NTLDR loads an external bootsector file when the specified drive letter is C:, otherwise it will interpret it as a boot DOS path specifier. */ - DPRINT1("Update 'boot.ini': %S\n", DstPath); - Status = UpdateBootIni(DstPath, + DPRINT1("Update 'boot.ini'\n"); + Status = UpdateBootIni(SystemRootPath->Buffer, L"C:\\bootsect.ros", L"\"ReactOS\""); if (!NT_SUCCESS(Status)) @@ -2352,12 +2004,11 @@ InstallFatBootcodeToPartition( { /* Create new 'freeldr.ini' */ DPRINT1("Create new 'freeldr.ini'\n"); - // CombinePaths(DstPath, ARRAYSIZE(DstPath), 2, SystemRootPath->Buffer, L"freeldr.ini"); if (IsThereAValidBootSector(SystemRootPath->Buffer)) { Status = CreateFreeLoaderIniForReactOSAndBootSector( - DstPath, DestinationArcPath->Buffer, + SystemRootPath->Buffer, DestinationArcPath->Buffer, Section, Description, BootDrive, BootPartition, BootSector); if (!NT_SUCCESS(Status)) @@ -2379,7 +2030,7 @@ InstallFatBootcodeToPartition( } else { - Status = CreateFreeLoaderIniForReactOS(DstPath, DestinationArcPath->Buffer); + Status = CreateFreeLoaderIniForReactOS(SystemRootPath->Buffer, DestinationArcPath->Buffer); if (!NT_SUCCESS(Status)) { DPRINT1("CreateFreeLoaderIniForReactOS() failed (Status %lx)\n", Status); @@ -2449,16 +2100,13 @@ InstallBtrfsBootcodeToPartition( return Status; } - /* Prepare for possibly copying 'freeldr.ini' */ - CombinePaths(DstPath, ARRAYSIZE(DstPath), 2, SystemRootPath->Buffer, L"freeldr.ini"); - - DoesFreeLdrExist = DoesFileExist(NULL, DstPath); + /* Prepare for possibly updating 'freeldr.ini' */ + DoesFreeLdrExist = DoesFileExist_2(SystemRootPath->Buffer, L"freeldr.ini"); if (DoesFreeLdrExist) { /* Update existing 'freeldr.ini' */ DPRINT1("Update existing 'freeldr.ini'\n"); - - Status = UpdateFreeLoaderIni(DstPath, DestinationArcPath->Buffer); + Status = UpdateFreeLoaderIni(SystemRootPath->Buffer, DestinationArcPath->Buffer); if (!NT_SUCCESS(Status)) { DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status); @@ -2473,7 +2121,6 @@ InstallBtrfsBootcodeToPartition( { /* Create new 'freeldr.ini' */ DPRINT1("Create new 'freeldr.ini'\n"); - CombinePaths(DstPath, ARRAYSIZE(DstPath), 2, SystemRootPath->Buffer, L"\\freeldr.ini"); /* Certainly SysLinux, GRUB, LILO... or an unknown boot loader */ DPRINT1("*nix or unknown boot loader found\n"); @@ -2483,7 +2130,7 @@ InstallBtrfsBootcodeToPartition( PCWSTR BootSector = L"BOOTSECT.OLD"; Status = CreateFreeLoaderIniForReactOSAndBootSector( - DstPath, DestinationArcPath->Buffer, + SystemRootPath->Buffer, DestinationArcPath->Buffer, L"Linux", L"\"Linux\"", L"hd0", L"1", BootSector); if (!NT_SUCCESS(Status)) @@ -2505,7 +2152,7 @@ InstallBtrfsBootcodeToPartition( } else { - Status = CreateFreeLoaderIniForReactOS(DstPath, DestinationArcPath->Buffer); + Status = CreateFreeLoaderIniForReactOS(SystemRootPath->Buffer, DestinationArcPath->Buffer); if (!NT_SUCCESS(Status)) { DPRINT1("CreateFreeLoaderIniForReactOS() failed (Status %lx)\n", Status); @@ -2619,10 +2266,8 @@ InstallFatBootcodeToFloppy( } /* Create new 'freeldr.ini' */ - CombinePaths(DstPath, ARRAYSIZE(DstPath), 2, FloppyDevice.Buffer, L"freeldr.ini"); - DPRINT("Create new 'freeldr.ini'\n"); - Status = CreateFreeLoaderIniForReactOS(DstPath, DestinationArcPath->Buffer); + Status = CreateFreeLoaderIniForReactOS(FloppyDevice.Buffer, DestinationArcPath->Buffer); if (!NT_SUCCESS(Status)) { DPRINT1("CreateFreeLoaderIniForReactOS() failed (Status %lx)\n", Status); @@ -2631,7 +2276,7 @@ InstallFatBootcodeToFloppy( /* Install FAT12 boosector */ CombinePaths(SrcPath, ARRAYSIZE(SrcPath), 2, SourceRootPath->Buffer, L"\\loader\\fat.bin"); - RtlStringCchCopyW(DstPath, ARRAYSIZE(DstPath), FloppyDevice.Buffer); + CombinePaths(DstPath, ARRAYSIZE(DstPath), 1, FloppyDevice.Buffer); DPRINT("Install FAT bootcode: %S ==> %S\n", SrcPath, DstPath); Status = InstallFat12BootCodeToFloppy(SrcPath, DstPath);
6 years, 2 months
1
0
0
0
01/01: [SETUPLIB] Adapt the code in osdetect.c to make it use the new features of bldrsup.c committed in 27603a10 (r74952).
by Hermès Bélusca-Maïto
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=c2f7758e9643ba0799615…
commit c2f7758e9643ba0799615df2cc7db84b25945865 Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org> AuthorDate: Thu Jun 8 02:20:33 2017 +0000 Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org> CommitDate: Sun Oct 14 23:37:44 2018 +0200 [SETUPLIB] Adapt the code in osdetect.c to make it use the new features of bldrsup.c committed in 27603a10 (r74952). svn path=/branches/setup_improvements/; revision=74953 --- base/setup/lib/osdetect.c | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/base/setup/lib/osdetect.c b/base/setup/lib/osdetect.c index 6bdd5ea416..daa98c7ab1 100644 --- a/base/setup/lib/osdetect.c +++ b/base/setup/lib/osdetect.c @@ -73,6 +73,7 @@ EnumerateInstallations( IN PVOID Parameter OPTIONAL) { PENUM_INSTALLS_DATA Data = (PENUM_INSTALLS_DATA)Parameter; + PNTOS_OPTIONS Options = (PNTOS_OPTIONS)&BootEntry->OsOptions; PNTOS_INSTALLATION NtOsInstall; UNICODE_STRING SystemRootPath; @@ -87,10 +88,11 @@ EnumerateInstallations( /* We have a boot entry */ /* Check for supported boot type "Windows2003" */ - // TODO: What to do with "Windows" ; "WindowsNT40" ; "ReactOSSetup" ? - if ((BootEntry->Version == NULL) || - ( (_wcsicmp(BootEntry->Version, L"Windows2003") != 0) && - (_wcsicmp(BootEntry->Version, L"\"Windows2003\"") != 0) )) + if (BootEntry->OsOptionsLength < sizeof(NTOS_OPTIONS) || + RtlCompareMemory(&BootEntry->OsOptions /* Signature */, + NTOS_OPTIONS_SIGNATURE, + RTL_FIELD_SIZE(NTOS_OPTIONS, Signature)) != + RTL_FIELD_SIZE(NTOS_OPTIONS, Signature)) { /* This is not a ReactOS entry */ DPRINT1(" An installation '%S' of unsupported type '%S'\n", @@ -99,7 +101,8 @@ EnumerateInstallations( return STATUS_SUCCESS; } - if (!BootEntry->OsLoadPath || !*BootEntry->OsLoadPath) + /* BootType is Windows2003, now check OsLoadPath */ + if (!Options->OsLoadPath || !*Options->OsLoadPath) { /* Certainly not a ReactOS installation */ DPRINT1(" A Win2k3 install '%S' without an ARC path?!\n", BootEntry->FriendlyName); @@ -108,9 +111,9 @@ EnumerateInstallations( } DPRINT1(" Found a candidate Win2k3 install '%S' with ARC path '%S'\n", - BootEntry->FriendlyName, BootEntry->OsLoadPath); + BootEntry->FriendlyName, Options->OsLoadPath); // DPRINT1(" Found a Win2k3 install '%S' with ARC path '%S'\n", - // BootEntry->FriendlyName, BootEntry->OsLoadPath); + // BootEntry->FriendlyName, Options->OsLoadPath); // TODO: Normalize the ARC path. @@ -118,7 +121,7 @@ EnumerateInstallations( * Check whether we already have an installation with this ARC path. * If this is the case, stop there. */ - NtOsInstall = FindExistingNTOSInstall(Data->List, BootEntry->OsLoadPath, NULL); + NtOsInstall = FindExistingNTOSInstall(Data->List, Options->OsLoadPath, NULL); if (NtOsInstall) { DPRINT1(" An NTOS installation with name \"%S\" already exists in SystemRoot '%wZ'\n", @@ -133,21 +136,21 @@ EnumerateInstallations( * resides, as well verifying whether it is indeed an NTOS installation. */ RtlInitEmptyUnicodeString(&SystemRootPath, SystemRoot, sizeof(SystemRoot)); - if (!ArcPathToNtPath(&SystemRootPath, BootEntry->OsLoadPath, Data->PartList)) + if (!ArcPathToNtPath(&SystemRootPath, Options->OsLoadPath, Data->PartList)) { - DPRINT1("ArcPathToNtPath(%S) failed, skip the installation.\n", BootEntry->OsLoadPath); + DPRINT1("ArcPathToNtPath(%S) failed, skip the installation.\n", Options->OsLoadPath); /* Continue the enumeration */ return STATUS_SUCCESS; } DPRINT1("ArcPathToNtPath() succeeded: '%S' --> '%wZ'\n", - BootEntry->OsLoadPath, &SystemRootPath); + Options->OsLoadPath, &SystemRootPath); /* * Check whether we already have an installation with this NT path. * If this is the case, stop there. */ - NtOsInstall = FindExistingNTOSInstall(Data->List, NULL /*BootEntry->OsLoadPath*/, &SystemRootPath); + NtOsInstall = FindExistingNTOSInstall(Data->List, NULL /*Options->OsLoadPath*/, &SystemRootPath); if (NtOsInstall) { DPRINT1(" An NTOS installation with name \"%S\" already exists in SystemRoot '%wZ'\n", @@ -166,7 +169,7 @@ EnumerateInstallations( } DPRINT1("Found a valid NTOS installation in SystemRoot ARC path '%S', NT path '%wZ'\n", - BootEntry->OsLoadPath, &SystemRootPath); + Options->OsLoadPath, &SystemRootPath); /* From the NT path, compute the disk, partition and path components */ if (NtPathToDiskPartComponents(SystemRootPath.Buffer, &DiskNumber, &PartitionNumber, &PathComponent)) @@ -204,7 +207,7 @@ EnumerateInstallations( &SystemRootPath, BootEntry->FriendlyName); } - AddNTOSInstallation(Data->List, BootEntry->OsLoadPath, + AddNTOSInstallation(Data->List, Options->OsLoadPath, &SystemRootPath, PathComponent, DiskNumber, PartitionNumber, PartEntry, InstallNameW);
6 years, 2 months
1
0
0
0
01/01: [SETUPLIB] Introduce a lot of (Work in progress) functions to manipulate boot entries from different boot "stores".
by Hermès Bélusca-Maïto
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=27603a101cf2a30d06d39…
commit 27603a101cf2a30d06d39b2744504f0c2885e486 Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org> AuthorDate: Wed Jun 7 15:58:44 2017 +0000 Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org> CommitDate: Sun Oct 14 23:27:17 2018 +0200 [SETUPLIB] Introduce a lot of (Work in progress) functions to manipulate boot entries from different boot "stores". This concerns so far, only freeldr.ini and to an extent, boot.ini, but planning in the future to add support for registry-oriented BCD as well as possibly direct (u)EFI entries, using the corresponding NT functions. This code is so far only used in osdetect.c, but will be soon used by usetup's bootsup.c (note that some helper functions: CreateCommonFreeLdrSections() and (Un)protectBootIni() are already taken from it and used in bldrsup.c). - In EnumerateNTOSBootEntries(), continue enumerating the boot entries until the user callback returns an status code that is not successful. - Remove some old code from osdetect.c; use directly BootEntry->FriendlyName when building the display names of the available installations, since now BootEntry->FriendlyName is a PCWSTR (and not a UNICODE_STRING anymore). svn path=/branches/setup_improvements/; revision=74943 [SETUPLIB] Make the NTOS_BOOT_ENTRY structure more generic, so that it can wrap around either actual NTOS boot entry options, or FreeLdr-like boot-sector options. In a sense, the NTOS_BOOT_ENTRY structure now looks much more like the NT structure "BOOT_ENTRY". - Adapt the code in bldrsup.c to these modifications, and re-enable FreeLdr-like boot-sector-file support code that was commented out. More code cleanup will follow later. svn path=/branches/setup_improvements/; revision=74952 --- base/setup/lib/bldrsup.c | 1613 +++++++++++++++++++++++++++++++++++++++------ base/setup/lib/bldrsup.h | 164 ++++- base/setup/lib/osdetect.c | 150 ++--- 3 files changed, 1622 insertions(+), 305 deletions(-) diff --git a/base/setup/lib/bldrsup.c b/base/setup/lib/bldrsup.c index 13a1ed34e8..80a951a6e1 100644 --- a/base/setup/lib/bldrsup.c +++ b/base/setup/lib/bldrsup.c @@ -22,79 +22,180 @@ /* GLOBALS ******************************************************************/ +typedef NTSTATUS +(*POPEN_BOOT_STORE)( + OUT PVOID* Handle, + IN HANDLE PartitionDirectoryHandle, // OPTIONAL + IN NTOS_BOOT_LOADER_TYPE Type, + IN BOOLEAN CreateNew); + +typedef NTSTATUS +(*PCLOSE_BOOT_STORE)( + IN PVOID Handle); + +typedef NTSTATUS +(*PENUM_BOOT_STORE_ENTRIES)( + IN PVOID Handle, +// IN ULONG Flags, // Determine which data to retrieve + IN PENUM_BOOT_ENTRIES_ROUTINE EnumBootEntriesRoutine, + IN PVOID Parameter OPTIONAL); + typedef struct _NTOS_BOOT_LOADER_FILES { NTOS_BOOT_LOADER_TYPE Type; - PCWSTR LoaderExecutable; + PCZZWSTR LoaderExecutables; PCWSTR LoaderConfigurationFile; - // EnumerateInstallations; + POPEN_BOOT_STORE OpenBootStore; + PCLOSE_BOOT_STORE CloseBootStore; + PENUM_BOOT_STORE_ENTRIES EnumBootStoreEntries; } NTOS_BOOT_LOADER_FILES, *PNTOS_BOOT_LOADER_FILES; + +/* + * Header for particular store contexts + */ +typedef struct _BOOT_STORE_CONTEXT +{ + NTOS_BOOT_LOADER_TYPE Type; +// PNTOS_BOOT_LOADER_FILES ?? +/* + PVOID PrivateData; +*/ +} BOOT_STORE_CONTEXT, *PBOOT_STORE_CONTEXT; + +typedef struct _BOOT_STORE_INI_CONTEXT +{ + BOOT_STORE_CONTEXT Header; + + /* + * If all these members are NULL, we know that the store is freshly created + * and is cached in memory only. At file closure we will therefore need to + * create the file proper and save its contents. + */ + HANDLE FileHandle; + HANDLE SectionHandle; + // SIZE_T ViewSize; + ULONG FileSize; + PVOID ViewBase; + + PINICACHE IniCache; + PINICACHESECTION OptionsIniSection; + PINICACHESECTION OsIniSection; +} BOOT_STORE_INI_CONTEXT, *PBOOT_STORE_INI_CONTEXT; + +// TODO! +typedef struct _BOOT_STORE_BCDREG_CONTEXT +{ + BOOT_STORE_CONTEXT Header; + ULONG PlaceHolder; +} BOOT_STORE_BCDREG_CONTEXT, *PBOOT_STORE_BCDREG_CONTEXT; + + +static NTSTATUS +OpenIniBootLoaderStore( + OUT PVOID* Handle, + IN HANDLE PartitionDirectoryHandle, // OPTIONAL + IN NTOS_BOOT_LOADER_TYPE Type, + IN BOOLEAN CreateNew); + +static NTSTATUS +CloseIniBootLoaderStore( + IN PVOID Handle); + +static NTSTATUS +FreeLdrEnumerateBootEntries( + IN PBOOT_STORE_INI_CONTEXT BootStore, +// IN ULONG Flags, // Determine which data to retrieve + IN PENUM_BOOT_ENTRIES_ROUTINE EnumBootEntriesRoutine, + IN PVOID Parameter OPTIONAL); + +static NTSTATUS +NtLdrEnumerateBootEntries( + IN PBOOT_STORE_INI_CONTEXT BootStore, +// IN ULONG Flags, // Determine which data to retrieve + IN PENUM_BOOT_ENTRIES_ROUTINE EnumBootEntriesRoutine, + IN PVOID Parameter OPTIONAL); + + // Question 1: What if config file is optional? // Question 2: What if many config files are possible? NTOS_BOOT_LOADER_FILES NtosBootLoaders[] = { - {FreeLdr, L"freeldr.sys", L"freeldr.ini"}, - {NtLdr , L"ntldr" , L"boot.ini"}, // FIXME: What about osloader.exe, etc...? -// {NtLdr , L"setupldr" , L"txtsetup.sif"}, // FIXME -// {BootMgr, L"bootmgr" , L"BCD"} + {FreeLdr, L"freeldr.sys\0", L"freeldr.ini", + OpenIniBootLoaderStore, CloseIniBootLoaderStore, (PENUM_BOOT_STORE_ENTRIES)FreeLdrEnumerateBootEntries}, + {NtLdr , L"ntldr\0" L"osloader.exe\0", L"boot.ini", + OpenIniBootLoaderStore, CloseIniBootLoaderStore, (PENUM_BOOT_STORE_ENTRIES)NtLdrEnumerateBootEntries }, +// {SetupLdr, L"setupldr\0" L"setupldr.bin\0" L"setupldr.exe\0", L"txtsetup.sif", UNIMPLEMENTED, UNIMPLEMENTED, UNIMPLEMENTED} +// {BootMgr , L"bootmgr", L"BCD", UNIMPLEMENTED, UNIMPLEMENTED, UNIMPLEMENTED} }; +C_ASSERT(_countof(NtosBootLoaders) == BldrTypeMax); /* FUNCTIONS ****************************************************************/ -// -// We need, for each type of bootloader (FreeLdr, NtLdr, Bootmgr): -// 1. A function that detects its presence and its version; -// 2. A function that opens/closes its corresponding configuration file; -// 3. A function that adds a new boot entry. Note that for the first two BLDRs -// this is a .INI file, while in the latter case this is a registry hive... -// - NTSTATUS FindNTOSBootLoader( // By handle - IN HANDLE PartitionHandle, // OPTIONAL + IN HANDLE PartitionDirectoryHandle, // OPTIONAL IN NTOS_BOOT_LOADER_TYPE Type, OUT PULONG Version OPTIONAL) // OUT PHANDLE ConfigFileHande OPTIONAL ???? { + PCWSTR LoaderExecutable; // UINT i; if (Type >= BldrTypeMax) return STATUS_INVALID_PARAMETER; - // FIXME: Unused for now, but should be used later!! - *Version = 0; - // TODO: Check for BLDR version ONLY if Version != NULL + if (Version) + *Version = 0; - /* Check whether the loader executable exists */ - if (!DoesFileExist(PartitionHandle, NtosBootLoaders[Type].LoaderExecutable)) + /* Check whether any of the loader executables exist */ + LoaderExecutable = NtosBootLoaders[Type].LoaderExecutables; + while (*LoaderExecutable) { + if (DoesFileExist(PartitionDirectoryHandle, LoaderExecutable)) + { + /* A loader was found, stop there */ + DPRINT1("Found loader executable '%S'\n", LoaderExecutable); + break; + } + /* The loader does not exist, continue with another one */ - // DPRINT1("Loader executable '%S' does not exist, continue with another one...\n", NtosBootLoaders[Type].LoaderExecutable); - DPRINT1("Loader executable '%S' does not exist\n", NtosBootLoaders[Type].LoaderExecutable); + DPRINT1("Loader executable '%S' does not exist, continue with another one...\n", LoaderExecutable); + LoaderExecutable += wcslen(LoaderExecutable) + 1; + } + if (!*LoaderExecutable) + { + /* No loader was found */ + DPRINT1("No loader executable was found\n"); return STATUS_NOT_FOUND; } + /* Check for loader version if needed */ + if (Version) + { + *Version = 0; + // TODO: Check for BLDR version ONLY if Version != NULL + } + /* Check whether the loader configuration file exists */ - if (!DoesFileExist(PartitionHandle, NtosBootLoaders[Type].LoaderConfigurationFile)) + if (!DoesFileExist(PartitionDirectoryHandle, NtosBootLoaders[Type].LoaderConfigurationFile)) { /* The loader does not exist, continue with another one */ // FIXME: Consider it might be optional?? - // DPRINT1("Loader configuration file '%S' does not exist, continue with another one...\n", NtosBootLoaders[Type].LoaderConfigurationFile); DPRINT1("Loader configuration file '%S' does not exist\n", NtosBootLoaders[Type].LoaderConfigurationFile); return STATUS_NOT_FOUND; } #if 0 /* Check whether the loader configuration file exists */ - Status = OpenAndMapFile(PartitionHandle, NtosBootLoaders[Type].LoaderConfigurationFile, + Status = OpenAndMapFile(PartitionDirectoryHandle, NtosBootLoaders[Type].LoaderConfigurationFile, &FileHandle, &SectionHandle, &ViewBase, &FileSize, FALSE); if (!NT_SUCCESS(Status)) { /* The loader does not exist, continue with another one */ // FIXME: Consider it might be optional?? - DPRINT1("Loader configuration file '%S' does not exist, continue with another one...\n", NtosBootLoaders[Type].LoaderConfigurationFile); + DPRINT1("Loader configuration file '%S' does not exist\n", NtosBootLoaders[Type].LoaderConfigurationFile); return STATUS_NOT_FOUND; } #endif @@ -103,207 +204,541 @@ FindNTOSBootLoader( // By handle } -static NTSTATUS -FreeLdrEnumerateBootEntries( - IN PCHAR FileBuffer, - IN ULONG FileLength, -// IN ULONG Flags, // Determine which data to retrieve - IN PENUM_BOOT_ENTRIES_ROUTINE EnumBootEntriesRoutine, - IN PVOID Parameter OPTIONAL) +static VOID +CreateCommonFreeLdrSections( + IN OUT PBOOT_STORE_INI_CONTEXT BootStore) { - NTSTATUS Status; - PINICACHE IniCache; - PINICACHEITERATOR Iterator; - PINICACHESECTION IniSection, OsIniSection; - PWCHAR SectionName, KeyData; -/**/NTOS_BOOT_ENTRY xxBootEntry;/**/ - PNTOS_BOOT_ENTRY BootEntry = &xxBootEntry; - UNICODE_STRING InstallName; + PINICACHESECTION IniSection; - /* Open an *existing* FreeLdr.ini configuration file */ - Status = IniCacheLoadFromMemory(&IniCache, FileBuffer, FileLength, FALSE); - if (!NT_SUCCESS(Status)) - return Status; + /* + * Cache the "FREELOADER" section for our future usage. + */ + + /* Get the "FREELOADER" section */ + IniSection = IniCacheGetSection(BootStore->IniCache, L"FREELOADER"); + if (!IniSection) + { + /* It does not exist yet, so create it */ + IniSection = IniCacheAppendSection(BootStore->IniCache, L"FREELOADER"); + if (!IniSection) + { + DPRINT1("CreateCommonFreeLdrSections: Failed to create 'FREELOADER' section!\n"); + } + } + + BootStore->OptionsIniSection = IniSection; + + /* Timeout=0 */ + IniCacheInsertKey(BootStore->OptionsIniSection, NULL, INSERT_LAST, + // L"TimeOut", L"0"); // FIXME!! There is a bug in the INI parser where a given key can be inserted twice in the same section... + L"TimeOut", L"10"); + + /* Create "Display" section */ + IniSection = IniCacheAppendSection(BootStore->IniCache, L"Display"); + + /* TitleText=ReactOS Boot Manager */ + IniCacheInsertKey(IniSection, NULL, INSERT_LAST, + L"TitleText", L"ReactOS Boot Manager"); + + /* StatusBarColor=Cyan */ + IniCacheInsertKey(IniSection, NULL, INSERT_LAST, + L"StatusBarColor", L"Cyan"); + + /* StatusBarTextColor=Black */ + IniCacheInsertKey(IniSection, NULL, INSERT_LAST, + L"StatusBarTextColor", L"Black"); + + /* BackdropTextColor=White */ + IniCacheInsertKey(IniSection, NULL, INSERT_LAST, + L"BackdropTextColor", L"White"); + + /* BackdropColor=Blue */ + IniCacheInsertKey(IniSection, NULL, INSERT_LAST, + L"BackdropColor", L"Blue"); + + /* BackdropFillStyle=Medium */ + IniCacheInsertKey(IniSection, NULL, INSERT_LAST, + L"BackdropFillStyle", L"Medium"); + + /* TitleBoxTextColor=White */ + IniCacheInsertKey(IniSection, NULL, INSERT_LAST, + L"TitleBoxTextColor", L"White"); + + /* TitleBoxColor=Red */ + IniCacheInsertKey(IniSection, NULL, INSERT_LAST, + L"TitleBoxColor", L"Red"); + + /* MessageBoxTextColor=White */ + IniCacheInsertKey(IniSection, NULL, INSERT_LAST, + L"MessageBoxTextColor", L"White"); + + /* MessageBoxColor=Blue */ + IniCacheInsertKey(IniSection, NULL, INSERT_LAST, + L"MessageBoxColor", L"Blue"); + + /* MenuTextColor=White */ + IniCacheInsertKey(IniSection, NULL, INSERT_LAST, + L"MenuTextColor", L"Gray"); + + /* MenuColor=Blue */ + IniCacheInsertKey(IniSection, NULL, INSERT_LAST, + L"MenuColor", L"Black"); + + /* TextColor=Yellow */ + IniCacheInsertKey(IniSection, NULL, INSERT_LAST, + L"TextColor", L"Gray"); + + /* SelectedTextColor=Black */ + IniCacheInsertKey(IniSection, NULL, INSERT_LAST, + L"SelectedTextColor", L"Black"); + + /* SelectedColor=Gray */ + IniCacheInsertKey(IniSection, NULL, INSERT_LAST, + L"SelectedColor", L"Gray"); + + /* SelectedColor=Gray */ + IniCacheInsertKey(IniSection, NULL, INSERT_LAST, + L"ShowTime", L"No"); + + /* SelectedColor=Gray */ + IniCacheInsertKey(IniSection, NULL, INSERT_LAST, + L"MenuBox", L"No"); + + /* SelectedColor=Gray */ + IniCacheInsertKey(IniSection, NULL, INSERT_LAST, + L"CenterMenu", L"No"); + + /* SelectedColor=Gray */ + IniCacheInsertKey(IniSection, NULL, INSERT_LAST, + L"MinimalUI", L"Yes"); + + /* SelectedColor=Gray */ + IniCacheInsertKey(IniSection, NULL, INSERT_LAST, + L"TimeText", + L"Seconds until highlighted choice will be started automatically: "); + + /* + * Cache the "Operating Systems" section for our future usage. + */ /* Get the "Operating Systems" section */ - IniSection = IniCacheGetSection(IniCache, L"Operating Systems"); - if (IniSection == NULL) + IniSection = IniCacheGetSection(BootStore->IniCache, L"Operating Systems"); + if (!IniSection) { - IniCacheDestroy(IniCache); - return STATUS_UNSUCCESSFUL; + /* It does not exist yet, so create it */ + IniSection = IniCacheAppendSection(BootStore->IniCache, L"Operating Systems"); + if (!IniSection) + { + DPRINT1("CreateCommonFreeLdrSections: Failed to create 'Operating Systems' section!\n"); + } } - /* Enumerate all the valid installations */ - Iterator = IniCacheFindFirstValue(IniSection, &SectionName, &KeyData); - if (!Iterator) goto Quit; - do + BootStore->OsIniSection = IniSection; +} + +static NTSTATUS +OpenIniBootLoaderStore( + OUT PVOID* Handle, + IN HANDLE PartitionDirectoryHandle, // OPTIONAL + IN NTOS_BOOT_LOADER_TYPE Type, + IN BOOLEAN CreateNew) +{ + NTSTATUS Status; + PBOOT_STORE_INI_CONTEXT BootStore; + + /* Create a boot store structure */ + BootStore = RtlAllocateHeap(ProcessHeap, HEAP_ZERO_MEMORY, sizeof(*BootStore)); + if (!BootStore) + return STATUS_INSUFFICIENT_RESOURCES; + + BootStore->Header.Type = Type; + + if (CreateNew) { - // FIXME: Poor-man quotes removal (improvement over bootsup.c:UpdateFreeLoaderIni). - if (KeyData[0] == L'"') + UNICODE_STRING Name; + OBJECT_ATTRIBUTES ObjectAttributes; + IO_STATUS_BLOCK IoStatusBlock; + + // + // WARNING! We "support" the INI creation *ONLY* for FreeLdr, and not for NTLDR!! + // + if (Type == NtLdr) { - /* Quoted name, copy up to the closing quote */ - PWCHAR Begin = &KeyData[1]; - PWCHAR End = wcschr(Begin, L'"'); - if (!End) - End = Begin + wcslen(Begin); - RtlInitEmptyUnicodeString(&InstallName, Begin, (ULONG_PTR)End - (ULONG_PTR)Begin); - InstallName.Length = InstallName.MaximumLength; + DPRINT1("OpenIniBootLoaderStore() unsupported for NTLDR!\n"); + RtlFreeHeap(ProcessHeap, 0, BootStore); + return STATUS_NOT_SUPPORTED; } - else + + /* Initialize the INI file */ + BootStore->IniCache = IniCacheCreate(); + if (!BootStore->IniCache) { - /* Non-quoted name, copy everything */ - RtlInitUnicodeString(&InstallName, KeyData); + DPRINT1("IniCacheCreate() failed.\n"); + RtlFreeHeap(ProcessHeap, 0, BootStore); + return STATUS_INSUFFICIENT_RESOURCES; } - DPRINT1("Boot entry '%wZ' in OS section '%S'\n", &InstallName, SectionName); + /* + * So far, we only use the INI cache. The file itself is not created + * yet, therefore FileHandle, SectionHandle, ViewBase and FileSize + * are all NULL. We will use this fact to know that the INI file was + * indeed created, and not just opened as an existing file. + */ + // BootStore->FileHandle = NULL; + BootStore->SectionHandle = NULL; + BootStore->ViewBase = NULL; + BootStore->FileSize = 0; - /* Search for an existing ReactOS entry */ - OsIniSection = IniCacheGetSection(IniCache, SectionName); - if (!OsIniSection) - continue; + /* + * The INI file is fresh new, we need to create it now. + */ - /* Check for supported boot type "Windows2003" */ - Status = IniCacheGetKey(OsIniSection, L"BootType", &KeyData); - if (NT_SUCCESS(Status)) + RtlInitUnicodeString(&Name, NtosBootLoaders[Type].LoaderConfigurationFile); + + InitializeObjectAttributes(&ObjectAttributes, + &Name, + OBJ_CASE_INSENSITIVE, + PartitionDirectoryHandle, + NULL); + + Status = NtCreateFile(&BootStore->FileHandle, + FILE_GENERIC_READ | FILE_GENERIC_WRITE, // Contains SYNCHRONIZE + &ObjectAttributes, + &IoStatusBlock, + NULL, + FILE_ATTRIBUTE_NORMAL, + 0, + FILE_SUPERSEDE, + FILE_SYNCHRONOUS_IO_NONALERT | FILE_SEQUENTIAL_ONLY | FILE_NON_DIRECTORY_FILE, + NULL, + 0); + if (!NT_SUCCESS(Status)) { - // TODO: What to do with "Windows" ; "WindowsNT40" ; "ReactOSSetup" ? - if ((KeyData == NULL) || - ( (_wcsicmp(KeyData, L"Windows2003") != 0) && - (_wcsicmp(KeyData, L"\"Windows2003\"") != 0) )) - { - /* This is not a ReactOS entry */ - continue; - } + DPRINT1("NtCreateFile() failed (Status 0x%08lx)\n", Status); + IniCacheDestroy(BootStore->IniCache); + RtlFreeHeap(ProcessHeap, 0, BootStore); + return Status; } - else + + /* Initialize the INI file contents */ + if (Type == FreeLdr) + CreateCommonFreeLdrSections(BootStore); + } + else + { + PINICACHESECTION IniSection; + + /* + * Check whether the loader configuration INI file exists, + * and open it if so. + * TODO: FIXME: What if it doesn't exist yet??? + */ + Status = OpenAndMapFile(PartitionDirectoryHandle, + NtosBootLoaders[Type].LoaderConfigurationFile, + &BootStore->FileHandle, + &BootStore->SectionHandle, + &BootStore->ViewBase, + &BootStore->FileSize, + TRUE); + if (!NT_SUCCESS(Status)) { - /* Certainly not a ReactOS installation */ - continue; + /* The loader configuration file does not exist */ + // FIXME: Consider it might be optional?? + DPRINT1("Loader configuration file '%S' does not exist (Status 0x%08lx)\n", + NtosBootLoaders[Type].LoaderConfigurationFile, Status); + RtlFreeHeap(ProcessHeap, 0, BootStore); + return Status; } - /* BootType is Windows2003. Now check its SystemPath. */ - Status = IniCacheGetKey(OsIniSection, L"SystemPath", &KeyData); + /* Open an *existing* INI configuration file */ + // Status = IniCacheLoad(&BootStore->IniCache, NtosBootLoaders[Type].LoaderConfigurationFile, FALSE); + Status = IniCacheLoadFromMemory(&BootStore->IniCache, + BootStore->ViewBase, + BootStore->FileSize, + FALSE); if (!NT_SUCCESS(Status)) { - DPRINT1(" A Win2k3 install '%wZ' without an ARC path?!\n", &InstallName); - continue; + DPRINT1("IniCacheLoadFromMemory() failed (Status 0x%08lx)\n", Status); + + /* Finally, unmap and close the file */ + UnMapFile(BootStore->SectionHandle, BootStore->ViewBase); + NtClose(BootStore->FileHandle); + + RtlFreeHeap(ProcessHeap, 0, BootStore); + return Status; } - DPRINT1(" Found a candidate Win2k3 install '%wZ' with ARC path '%S'\n", &InstallName, KeyData); - // KeyData == SystemRoot; + if (Type == FreeLdr) + { + /* + * Cache the "FREELOADER" section for our future usage. + */ - BootEntry->FriendlyName = &InstallName; - BootEntry->OsLoadPath = KeyData; - /* Unused stuff (for now...) */ - BootEntry->BootFilePath = NULL; - BootEntry->OsOptions = NULL; - BootEntry->OsLoadOptions = NULL; + /* Get the "FREELOADER" section */ + IniSection = IniCacheGetSection(BootStore->IniCache, L"FREELOADER"); + if (!IniSection) + { + /* It does not exist yet, so create it */ + IniSection = IniCacheAppendSection(BootStore->IniCache, L"FREELOADER"); + if (!IniSection) + { + DPRINT1("OpenIniBootLoaderStore: Failed to retrieve 'FREELOADER' section!\n"); + } + } - Status = EnumBootEntriesRoutine(FreeLdr, BootEntry, Parameter); - // TODO: Stop enumeration if !NT_SUCCESS(Status); - } - while (IniCacheFindNextValue(Iterator, &SectionName, &KeyData)); + BootStore->OptionsIniSection = IniSection; - IniCacheFindClose(Iterator); + /* + * Cache the "Operating Systems" section for our future usage. + */ -Quit: - IniCacheDestroy(IniCache); + /* Get the "Operating Systems" section */ + IniSection = IniCacheGetSection(BootStore->IniCache, L"Operating Systems"); + if (!IniSection) + { + /* It does not exist yet, so create it */ + IniSection = IniCacheAppendSection(BootStore->IniCache, L"Operating Systems"); + if (!IniSection) + { + DPRINT1("OpenIniBootLoaderStore: Failed to retrieve 'Operating Systems' section!\n"); + } + } + + BootStore->OsIniSection = IniSection; + } + else + if (Type == NtLdr) + { + /* + * Cache the "boot loader" section for our future usage. + */ + /* + * HISTORICAL NOTE: + * + * While the "operating systems" section acquired its definitive + * name already when Windows NT was at its very early beta stage + * (NT 3.1 October 1991 Beta, 10-16-1991), this was not the case + * for its general settings section "boot loader". + * + * The following section names were successively introduced: + * + * - In NT 3.1 October 1991 Beta, 10-16-1991, using OS Loader V1.5, + * the section was named "multiboot". + * + * - In the next public beta version NT 3.10.340 Beta, 10-12-1992, + * using OS Loader V2.10, a new name was introduced: "flexboot". + * This is around this time that the NT OS Loader was also + * introduced as the "Windows NT FlexBoot" loader, as shown by + * the Windows NT FAQs that circulated around this time: + *
http://cd.textfiles.com/cica9308/CIS_LIBS/WINNT/1/NTFAQ.TXT
+ *
http://cd.textfiles.com/cica/cica9308/UNZIPPED/NT/NTFAQ/FTP/NEWS/NTFAQ1.TXT
+ * I can only hypothesize that the "FlexBoot" name was chosen + * as a marketing coup, possibly to emphasise its "flexibility" + * as a simple multiboot-aware boot manager. + * + * - A bit later, with NT 3.10.404 Beta, 3-7-1993, using an updated + * version of OS Loader V2.10, the final section name "boot loader" + * was introduced, and was kept since then. + * + * Due to the necessity to be able to boot and / or upgrade any + * Windows NT version at any time, including its NT Loader and the + * associated boot.ini file, all versions of NTLDR and the NT installer + * understand and parse these three section names, the default one + * being "boot loader", and if not present, they successively fall + * back to "flexboot" and then to "multiboot". + */ + + /* Get the "boot loader" section */ + IniSection = IniCacheGetSection(BootStore->IniCache, L"boot loader"); + if (!IniSection) + { + /* Fall back to "flexboot" */ + IniSection = IniCacheGetSection(BootStore->IniCache, L"flexboot"); + if (!IniSection) + { + /* Fall back to "multiboot" */ + IniSection = IniCacheGetSection(BootStore->IniCache, L"multiboot"); + } + } +#if 0 + if (!IniSection) + { + /* It does not exist yet, so create it */ + IniSection = IniCacheAppendSection(BootStore->IniCache, L"boot loader"); + if (!IniSection) + { + DPRINT1("OpenIniBootLoaderStore: Failed to retrieve 'boot loader' section!\n"); + } + } +#endif + + BootStore->OptionsIniSection = IniSection; + + /* + * Cache the "Operating Systems" section for our future usage. + */ + + /* Get the "Operating Systems" section */ + IniSection = IniCacheGetSection(BootStore->IniCache, L"operating systems"); + if (!IniSection) + { +#if 0 + /* It does not exist yet, so create it */ + IniSection = IniCacheAppendSection(BootStore->IniCache, L"operating systems"); + if (!IniSection) + { + DPRINT1("OpenIniBootLoaderStore: Failed to retrieve 'operating systems' section!\n"); + } +#endif + } + + BootStore->OsIniSection = IniSection; + } + } + + *Handle = BootStore; return STATUS_SUCCESS; } static NTSTATUS -NtLdrEnumerateBootEntries( - IN PCHAR FileBuffer, - IN ULONG FileLength, -// IN ULONG Flags, // Determine which data to retrieve - IN PENUM_BOOT_ENTRIES_ROUTINE EnumBootEntriesRoutine, - IN PVOID Parameter OPTIONAL) +UnprotectBootIni( + IN HANDLE FileHandle, + OUT PULONG Attributes) { NTSTATUS Status; - PINICACHE IniCache; - PINICACHEITERATOR Iterator; - PINICACHESECTION IniSection; - PWCHAR SectionName, KeyData; -/**/NTOS_BOOT_ENTRY xxBootEntry;/**/ - PNTOS_BOOT_ENTRY BootEntry = &xxBootEntry; - UNICODE_STRING InstallName; + IO_STATUS_BLOCK IoStatusBlock; + FILE_BASIC_INFORMATION FileInfo; - /* Open an *existing* boot.ini configuration file */ - Status = IniCacheLoadFromMemory(&IniCache, FileBuffer, FileLength, FALSE); + Status = NtQueryInformationFile(FileHandle, + &IoStatusBlock, + &FileInfo, + sizeof(FILE_BASIC_INFORMATION), + FileBasicInformation); if (!NT_SUCCESS(Status)) + { + DPRINT1("NtQueryInformationFile() failed (Status 0x%08lx)\n", Status); return Status; + } - /* Get the "Operating Systems" section */ - IniSection = IniCacheGetSection(IniCache, L"operating systems"); - if (IniSection == NULL) + *Attributes = FileInfo.FileAttributes; + + /* Delete attributes SYSTEM, HIDDEN and READONLY */ + FileInfo.FileAttributes = FileInfo.FileAttributes & + ~(FILE_ATTRIBUTE_SYSTEM | + FILE_ATTRIBUTE_HIDDEN | + FILE_ATTRIBUTE_READONLY); + + Status = NtSetInformationFile(FileHandle, + &IoStatusBlock, + &FileInfo, + sizeof(FILE_BASIC_INFORMATION), + FileBasicInformation); + if (!NT_SUCCESS(Status)) + DPRINT1("NtSetInformationFile() failed (Status 0x%08lx)\n", Status); + + return Status; +} + +static NTSTATUS +ProtectBootIni( + IN HANDLE FileHandle, + IN ULONG Attributes) +{ + NTSTATUS Status; + IO_STATUS_BLOCK IoStatusBlock; + FILE_BASIC_INFORMATION FileInfo; + + Status = NtQueryInformationFile(FileHandle, + &IoStatusBlock, + &FileInfo, + sizeof(FILE_BASIC_INFORMATION), + FileBasicInformation); + if (!NT_SUCCESS(Status)) { - IniCacheDestroy(IniCache); - return STATUS_UNSUCCESSFUL; + DPRINT1("NtQueryInformationFile() failed (Status 0x%08lx)\n", Status); + return Status; } - /* Enumerate all the valid installations */ - Iterator = IniCacheFindFirstValue(IniSection, &SectionName, &KeyData); - if (!Iterator) goto Quit; - do + FileInfo.FileAttributes = FileInfo.FileAttributes | Attributes; + + Status = NtSetInformationFile(FileHandle, + &IoStatusBlock, + &FileInfo, + sizeof(FILE_BASIC_INFORMATION), + FileBasicInformation); + if (!NT_SUCCESS(Status)) + DPRINT1("NtSetInformationFile() failed (Status 0x%08lx)\n", Status); + + return Status; +} + +static NTSTATUS +CloseIniBootLoaderStore( + IN PVOID Handle) +{ + NTSTATUS Status; + PBOOT_STORE_INI_CONTEXT BootStore = (PBOOT_STORE_INI_CONTEXT)Handle; + ULONG FileAttribute = 0; + + // if (!BootStore) + // return STATUS_INVALID_PARAMETER; + + if (BootStore->SectionHandle) { - // FIXME: Poor-man quotes removal (improvement over bootsup.c:UpdateFreeLoaderIni). - if (KeyData[0] == L'"') - { - /* Quoted name, copy up to the closing quote */ - PWCHAR Begin = &KeyData[1]; - PWCHAR End = wcschr(Begin, L'"'); - if (!End) - End = Begin + wcslen(Begin); - RtlInitEmptyUnicodeString(&InstallName, Begin, (ULONG_PTR)End - (ULONG_PTR)Begin); - InstallName.Length = InstallName.MaximumLength; - } - else + /* + * The INI file was already opened because it already existed, + * thus (in the case of NTLDR's boot.ini), unprotect it. + */ + if (BootStore->Header.Type == NtLdr) { - /* Non-quoted name, copy everything */ - RtlInitUnicodeString(&InstallName, KeyData); + Status = UnprotectBootIni(BootStore->FileHandle, &FileAttribute); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Could not unprotect BOOT.INI ! (Status 0x%08lx)\n", Status); + goto Quit; + } } + } - DPRINT1("Boot entry '%wZ' in OS section '%S'\n", &InstallName, SectionName); + IniCacheSaveByHandle(BootStore->IniCache, BootStore->FileHandle); - DPRINT1(" Found a Win2k3 install '%wZ' with ARC path '%S'\n", &InstallName, SectionName); - // SectionName == SystemRoot; + /* In the case of NTLDR's boot.ini, re-protect the INI file */ + if (BootStore->Header.Type == NtLdr) + { + FileAttribute |= (FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_READONLY); + Status = ProtectBootIni(BootStore->FileHandle, FileAttribute); + } - BootEntry->FriendlyName = &InstallName; - BootEntry->OsLoadPath = SectionName; - /* Unused stuff (for now...) */ - BootEntry->BootFilePath = NULL; - BootEntry->OsOptions = NULL; - BootEntry->OsLoadOptions = NULL; +Quit: + IniCacheDestroy(BootStore->IniCache); - Status = EnumBootEntriesRoutine(NtLdr, BootEntry, Parameter); - // TODO: Stop enumeration if !NT_SUCCESS(Status); + if (BootStore->SectionHandle) + { + /* Finally, unmap and close the file */ + UnMapFile(BootStore->SectionHandle, BootStore->ViewBase); + NtClose(BootStore->FileHandle); + } + else // if (BootStore->FileHandle) + { + /* Just close the file we have opened for creation */ + NtClose(BootStore->FileHandle); } - while (IniCacheFindNextValue(Iterator, &SectionName, &KeyData)); - IniCacheFindClose(Iterator); + /* Finally, free the boot store structure */ + RtlFreeHeap(ProcessHeap, 0, BootStore); -Quit: - IniCacheDestroy(IniCache); + // TODO: Use a correct Status based on the return values of the previous functions... return STATUS_SUCCESS; } -// This function may be viewed as being similar to ntos:NtEnumerateBootEntries(). NTSTATUS -EnumerateNTOSBootEntries( - IN HANDLE PartitionHandle, // OPTIONAL +OpenNTOSBootLoaderStoreByHandle( + OUT PVOID* Handle, + IN HANDLE PartitionDirectoryHandle, // OPTIONAL IN NTOS_BOOT_LOADER_TYPE Type, -// IN ULONG Flags, // Determine which data to retrieve - IN PENUM_BOOT_ENTRIES_ROUTINE EnumBootEntriesRoutine, - IN PVOID Parameter OPTIONAL) + IN BOOLEAN CreateNew) { - NTSTATUS Status; - HANDLE FileHandle; - HANDLE SectionHandle; - // SIZE_T ViewSize; - ULONG FileSize; - PVOID ViewBase; - /* * NOTE: Currently we open & map the loader configuration file without * further tests. It's OK as long as we only deal with FreeLdr's freeldr.ini @@ -312,41 +747,821 @@ EnumerateNTOSBootEntries( * hive and then, we'll have instead to mount the hive & open it. */ - /* Check whether the loader configuration file exists */ - Status = OpenAndMapFile(PartitionHandle, NtosBootLoaders[Type].LoaderConfigurationFile, - &FileHandle, &SectionHandle, &ViewBase, &FileSize, FALSE); - if (!NT_SUCCESS(Status)) - { - /* The loader does not exist, continue with another one */ - // FIXME: Consider it might be optional?? - // DPRINT1("Loader configuration file '%S' does not exist, continue with another one...\n", NtosBootLoaders[Type].LoaderConfigurationFile); - DPRINT1("Loader configuration file '%S' does not exist\n", NtosBootLoaders[Type].LoaderConfigurationFile); - return Status; - } - - /* The loader configuration file exists, interpret it to find valid installations */ - switch (NtosBootLoaders[Type].Type) + if (Type >= BldrTypeMax || NtosBootLoaders[Type].Type >= BldrTypeMax) { - case FreeLdr: - Status = FreeLdrEnumerateBootEntries(ViewBase, FileSize, /* Flags, */ - EnumBootEntriesRoutine, Parameter); - break; - - case NtLdr: - Status = NtLdrEnumerateBootEntries(ViewBase, FileSize, /* Flags, */ - EnumBootEntriesRoutine, Parameter); - break; - - default: DPRINT1("Loader type %d is currently unsupported!\n", NtosBootLoaders[Type].Type); - Status = STATUS_SUCCESS; + return STATUS_NOT_SUPPORTED; } - /* Finally, unmap and close the file */ - UnMapFile(SectionHandle, ViewBase); - NtClose(FileHandle); + return NtosBootLoaders[Type].OpenBootStore(Handle, + PartitionDirectoryHandle, + Type, + CreateNew); +} - return Status; +NTSTATUS +OpenNTOSBootLoaderStore_UStr( + OUT PVOID* Handle, + IN PUNICODE_STRING SystemPartitionPath, + IN NTOS_BOOT_LOADER_TYPE Type, + IN BOOLEAN CreateNew) +{ + NTSTATUS Status; + OBJECT_ATTRIBUTES ObjectAttributes; + IO_STATUS_BLOCK IoStatusBlock; + HANDLE PartitionDirectoryHandle; + + /* + * NOTE: Currently we open & map the loader configuration file without + * further tests. It's OK as long as we only deal with FreeLdr's freeldr.ini + * and NTLDR's boot.ini files. But as soon as we'll implement support for + * BOOTMGR detection, the "configuration file" will be the BCD registry + * hive and then, we'll have instead to mount the hive & open it. + */ + + if (Type >= BldrTypeMax || NtosBootLoaders[Type].Type >= BldrTypeMax) + { + DPRINT1("Loader type %d is currently unsupported!\n", NtosBootLoaders[Type].Type); + return STATUS_NOT_SUPPORTED; + } + + /* Open SystemPartition */ + InitializeObjectAttributes(&ObjectAttributes, + SystemPartitionPath, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + Status = NtOpenFile(&PartitionDirectoryHandle, + FILE_LIST_DIRECTORY | FILE_ADD_FILE /* | FILE_ADD_SUBDIRECTORY | FILE_TRAVERSE*/ | SYNCHRONIZE, + &ObjectAttributes, + &IoStatusBlock, + FILE_SHARE_READ | FILE_SHARE_WRITE, + FILE_SYNCHRONOUS_IO_NONALERT | FILE_DIRECTORY_FILE /* | FILE_OPEN_FOR_BACKUP_INTENT */); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to open SystemPartition '%wZ', Status 0x%08lx\n", SystemPartitionPath, Status); + return Status; + } + + Status = OpenNTOSBootLoaderStoreByHandle(Handle, PartitionDirectoryHandle, Type, CreateNew); + + /* Done! */ + NtClose(PartitionDirectoryHandle); + return Status; +} + +NTSTATUS +OpenNTOSBootLoaderStore( + OUT PVOID* Handle, + IN PCWSTR SystemPartition, + IN NTOS_BOOT_LOADER_TYPE Type, + IN BOOLEAN CreateNew) +{ + UNICODE_STRING SystemPartitionPath; + RtlInitUnicodeString(&SystemPartitionPath, SystemPartition); + return OpenNTOSBootLoaderStore_UStr(Handle, &SystemPartitionPath, Type, CreateNew); +} + +NTSTATUS +CloseNTOSBootLoaderStore( + IN PVOID Handle) +{ + PBOOT_STORE_CONTEXT BootStore = (PBOOT_STORE_CONTEXT)Handle; + + if (!BootStore) + return STATUS_INVALID_PARAMETER; + + /* + * NOTE: Currently we open & map the loader configuration file without + * further tests. It's OK as long as we only deal with FreeLdr's freeldr.ini + * and NTLDR's boot.ini files. But as soon as we'll implement support for + * BOOTMGR detection, the "configuration file" will be the BCD registry + * hive and then, we'll have instead to mount the hive & open it. + */ + + if (BootStore->Type >= BldrTypeMax || NtosBootLoaders[BootStore->Type].Type >= BldrTypeMax) + { + DPRINT1("Loader type %d is currently unsupported!\n", NtosBootLoaders[BootStore->Type].Type); + return STATUS_NOT_SUPPORTED; + } + + return NtosBootLoaders[BootStore->Type].CloseBootStore(Handle /* BootStore */); +} + + + +static +NTSTATUS +CreateNTOSEntry( + IN PBOOT_STORE_INI_CONTEXT BootStore, + IN ULONG_PTR BootEntryKey, + IN PNTOS_BOOT_ENTRY BootEntry) +{ + PINICACHESECTION IniSection; + PWCHAR Section = (PWCHAR)BootEntryKey; + + /* Insert the entry into the "Operating Systems" section */ + IniCacheInsertKey(BootStore->OsIniSection, NULL, INSERT_LAST, + Section, (PWSTR)BootEntry->FriendlyName); + + /* Create a new section */ + IniSection = IniCacheAppendSection(BootStore->IniCache, Section); + + // if (_wcsicmp(BootEntry->Version, L"Windows2003") == 0) + if (BootEntry->OsOptionsLength >= sizeof(NTOS_OPTIONS) && + RtlCompareMemory(&BootEntry->OsOptions /* Signature */, + NTOS_OPTIONS_SIGNATURE, + RTL_FIELD_SIZE(NTOS_OPTIONS, Signature)) == + RTL_FIELD_SIZE(NTOS_OPTIONS, Signature)) + { + PNTOS_OPTIONS Options = (PNTOS_OPTIONS)&BootEntry->OsOptions; + + /* BootType= */ + IniCacheInsertKey(IniSection, NULL, INSERT_LAST, + L"BootType", L"Windows2003"); + + /* SystemPath= */ + IniCacheInsertKey(IniSection, NULL, INSERT_LAST, + L"SystemPath", (PWSTR)Options->OsLoadPath); + + /* Options= */ + IniCacheInsertKey(IniSection, NULL, INSERT_LAST, + L"Options", (PWSTR)Options->OsLoadOptions); + } + else + // if (_wcsicmp(BootEntry->Version, L"BootSector") == 0) + if (BootEntry->OsOptionsLength >= sizeof(BOOT_SECTOR_OPTIONS) && + RtlCompareMemory(&BootEntry->OsOptions /* Signature */, + BOOT_SECTOR_OPTIONS_SIGNATURE, + RTL_FIELD_SIZE(BOOT_SECTOR_OPTIONS, Signature)) == + RTL_FIELD_SIZE(BOOT_SECTOR_OPTIONS, Signature)) + { + PBOOT_SECTOR_OPTIONS Options = (PBOOT_SECTOR_OPTIONS)&BootEntry->OsOptions; + + /* BootType= */ + IniCacheInsertKey(IniSection, NULL, INSERT_LAST, + L"BootType", L"BootSector"); + + /* BootDrive= */ + IniCacheInsertKey(IniSection, NULL, INSERT_LAST, + L"BootDrive", (PWSTR)Options->Drive); + + /* BootPartition= */ + IniCacheInsertKey(IniSection, NULL, INSERT_LAST, + L"BootPartition", (PWSTR)Options->Partition); + + /* BootSector= */ + IniCacheInsertKey(IniSection, NULL, INSERT_LAST, + L"BootSectorFile", (PWSTR)Options->BootSectorFileName); + } + else + { + DPRINT1("Unsupported BootType '%S'\n", BootEntry->Version); + } + + return STATUS_SUCCESS; +} + +NTSTATUS +AddNTOSBootEntry( + IN PVOID Handle, + IN PNTOS_BOOT_ENTRY BootEntry, + IN ULONG_PTR BootEntryKey) +{ + PBOOT_STORE_CONTEXT BootStore = (PBOOT_STORE_CONTEXT)Handle; + + if (!BootStore || !BootEntry) + return STATUS_INVALID_PARAMETER; + + /* + * NOTE: Currently we open & map the loader configuration file without + * further tests. It's OK as long as we only deal with FreeLdr's freeldr.ini + * and NTLDR's boot.ini files. But as soon as we'll implement support for + * BOOTMGR detection, the "configuration file" will be the BCD registry + * hive and then, we'll have instead to mount the hive & open it. + */ + + // + // FIXME!! + // + + // if (BootStore->Type >= BldrTypeMax || NtosBootLoaders[BootStore->Type].Type >= BldrTypeMax) + + if (BootStore->Type == FreeLdr) + { + return CreateNTOSEntry((PBOOT_STORE_INI_CONTEXT)BootStore, + BootEntryKey, BootEntry); + } + else + if (BootStore->Type == NtLdr) + { + PNTOS_OPTIONS Options = (PNTOS_OPTIONS)&BootEntry->OsOptions; + PWCHAR Buffer; + ULONG BufferLength; + PCWSTR InstallName, OsOptions; + // ULONG InstallNameLength, OsOptionsLength; + + // if (_wcsicmp(BootEntry->Version, L"Windows2003") != 0) + if (BootEntry->OsOptionsLength < sizeof(NTOS_OPTIONS) || + RtlCompareMemory(&BootEntry->OsOptions /* Signature */, + NTOS_OPTIONS_SIGNATURE, + RTL_FIELD_SIZE(NTOS_OPTIONS, Signature)) != + RTL_FIELD_SIZE(NTOS_OPTIONS, Signature)) + { + DPRINT1("Unsupported BootType '%S'\n", BootEntry->Version); + return STATUS_SUCCESS; // STATUS_NOT_SUPPORTED; + } + + InstallName = BootEntry->FriendlyName; + OsOptions = Options->OsLoadOptions; + + // if (InstallNameLength == 0) InstallName = NULL; + // if (OsOptionsLength == 0) OsOptions = NULL; + + BufferLength = 2 /* Quotes for FriendlyName*/ + wcslen(InstallName); + if (OsOptions) + BufferLength += 1 /* Space between FriendlyName and options */ + wcslen(OsOptions); + BufferLength++; /* NULL-termination */ + + Buffer = RtlAllocateHeap(ProcessHeap, HEAP_ZERO_MEMORY, BufferLength * sizeof(WCHAR)); + if (!Buffer) + return STATUS_INSUFFICIENT_RESOURCES; + + wcscpy(Buffer, L"\""); + wcscat(Buffer, InstallName); + wcscat(Buffer, L"\""); + if (OsOptions) + { + wcscat(Buffer, L" "); + wcscat(Buffer, OsOptions); + } + + /* Insert the entry into the "Operating Systems" section */ + IniCacheInsertKey(((PBOOT_STORE_INI_CONTEXT)BootStore)->OsIniSection, NULL, INSERT_LAST, + (PWSTR)Options->OsLoadPath, Buffer); + + RtlFreeHeap(ProcessHeap, 0, Buffer); + return STATUS_SUCCESS; + } + else + { + DPRINT1("Loader type %d is currently unsupported!\n", NtosBootLoaders[BootStore->Type].Type); + return STATUS_NOT_SUPPORTED; + } +} + +NTSTATUS +DeleteNTOSBootEntry( + IN PVOID Handle, + IN ULONG_PTR BootEntryKey) +{ + PBOOT_STORE_CONTEXT BootStore = (PBOOT_STORE_CONTEXT)Handle; + + if (!BootStore) + return STATUS_INVALID_PARAMETER; + + /* + * NOTE: Currently we open & map the loader configuration file without + * further tests. It's OK as long as we only deal with FreeLdr's freeldr.ini + * and NTLDR's boot.ini files. But as soon as we'll implement support for + * BOOTMGR detection, the "configuration file" will be the BCD registry + * hive and then, we'll have instead to mount the hive & open it. + */ + + // + // FIXME!! + // + + // if (BootStore->Type >= BldrTypeMax || NtosBootLoaders[BootStore->Type].Type >= BldrTypeMax) + if (BootStore->Type != FreeLdr) + { + DPRINT1("Loader type %d is currently unsupported!\n", NtosBootLoaders[BootStore->Type].Type); + return STATUS_NOT_SUPPORTED; + } + + // FIXME! This function needs my INI library rewrite to be implemented!! + UNIMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; +} + +NTSTATUS +ModifyNTOSBootEntry( + IN PVOID Handle, + IN PNTOS_BOOT_ENTRY BootEntry) +{ + PBOOT_STORE_CONTEXT BootStore = (PBOOT_STORE_CONTEXT)Handle; + + if (!BootStore || !BootEntry) + return STATUS_INVALID_PARAMETER; + + /* + * NOTE: Currently we open & map the loader configuration file without + * further tests. It's OK as long as we only deal with FreeLdr's freeldr.ini + * and NTLDR's boot.ini files. But as soon as we'll implement support for + * BOOTMGR detection, the "configuration file" will be the BCD registry + * hive and then, we'll have instead to mount the hive & open it. + */ + + // + // FIXME!! + // + + // if (BootStore->Type >= BldrTypeMax || NtosBootLoaders[BootStore->Type].Type >= BldrTypeMax) + if (BootStore->Type != FreeLdr) + { + DPRINT1("Loader type %d is currently unsupported!\n", NtosBootLoaders[BootStore->Type].Type); + return STATUS_NOT_SUPPORTED; + } + + // FIXME! This function needs my INI library rewrite to operate properly!! + UNIMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; +} + +NTSTATUS +QueryNTOSBootEntry( + IN PVOID Handle, + IN ULONG_PTR BootEntryKey, + OUT PNTOS_BOOT_ENTRY BootEntry) // Technically this should be PNTOS_BOOT_ENTRY* +{ + PBOOT_STORE_CONTEXT BootStore = (PBOOT_STORE_CONTEXT)Handle; + + if (!BootStore) + return STATUS_INVALID_PARAMETER; + + /* + * NOTE: Currently we open & map the loader configuration file without + * further tests. It's OK as long as we only deal with FreeLdr's freeldr.ini + * and NTLDR's boot.ini files. But as soon as we'll implement support for + * BOOTMGR detection, the "configuration file" will be the BCD registry + * hive and then, we'll have instead to mount the hive & open it. + */ + + // + // FIXME!! + // + + // if (BootStore->Type >= BldrTypeMax || NtosBootLoaders[BootStore->Type].Type >= BldrTypeMax) + if (BootStore->Type != FreeLdr) + { + DPRINT1("Loader type %d is currently unsupported!\n", NtosBootLoaders[BootStore->Type].Type); + return STATUS_NOT_SUPPORTED; + } + + // FIXME! This function needs my INI library rewrite to be implemented!! + UNIMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; +} + +NTSTATUS +QueryNTOSBootOptions( + IN PVOID Handle, + IN OUT PNTOS_BOOT_OPTIONS BootOptions +/* , IN PULONG BootOptionsLength */ ) +{ + NTSTATUS Status = STATUS_SUCCESS; + PBOOT_STORE_CONTEXT BootStore = (PBOOT_STORE_CONTEXT)Handle; + PWCHAR TimeoutStr; + + if (!BootStore || !BootOptions) + return STATUS_INVALID_PARAMETER; + + /* + * NOTE: Currently we open & map the loader configuration file without + * further tests. It's OK as long as we only deal with FreeLdr's freeldr.ini + * and NTLDR's boot.ini files. But as soon as we'll implement support for + * BOOTMGR detection, the "configuration file" will be the BCD registry + * hive and then, we'll have instead to mount the hive & open it. + */ + + // + // FIXME!! + // + + // if (BootStore->Type >= BldrTypeMax || NtosBootLoaders[BootStore->Type].Type >= BldrTypeMax) + if (BootStore->Type != FreeLdr || BootStore->Type != NtLdr) + { + DPRINT1("Loader type %d is currently unsupported!\n", NtosBootLoaders[BootStore->Type].Type); + return STATUS_NOT_SUPPORTED; + } + + if (BootStore->Type == FreeLdr) + { + Status = IniCacheGetKey(((PBOOT_STORE_INI_CONTEXT)BootStore)->OptionsIniSection, + L"DefaultOS", (PWCHAR*)&BootOptions->CurrentBootEntryKey); + if (!NT_SUCCESS(Status)) + BootOptions->CurrentBootEntryKey = 0; + + Status = IniCacheGetKey(((PBOOT_STORE_INI_CONTEXT)BootStore)->OptionsIniSection, + L"TimeOut", &TimeoutStr); + if (NT_SUCCESS(Status) && TimeoutStr) + BootOptions->Timeout = _wtoi(TimeoutStr); + else + BootOptions->Timeout = 0; + } + else if (BootStore->Type == NtLdr) + { + Status = IniCacheGetKey(((PBOOT_STORE_INI_CONTEXT)BootStore)->OptionsIniSection, + L"default", (PWCHAR*)&BootOptions->CurrentBootEntryKey); + if (!NT_SUCCESS(Status)) + BootOptions->CurrentBootEntryKey = 0; + + Status = IniCacheGetKey(((PBOOT_STORE_INI_CONTEXT)BootStore)->OptionsIniSection, + L"timeout", &TimeoutStr); + if (NT_SUCCESS(Status) && TimeoutStr) + BootOptions->Timeout = _wtoi(TimeoutStr); + else + BootOptions->Timeout = 0; + } + + return STATUS_SUCCESS; // FIXME: use Status; instead? +} + +NTSTATUS +SetNTOSBootOptions( + IN PVOID Handle, + IN PNTOS_BOOT_OPTIONS BootOptions, + IN ULONG FieldsToChange) +{ + PBOOT_STORE_CONTEXT BootStore = (PBOOT_STORE_CONTEXT)Handle; + WCHAR TimeoutStr[15]; + + if (!BootStore || !BootOptions) + return STATUS_INVALID_PARAMETER; + + /* + * NOTE: Currently we open & map the loader configuration file without + * further tests. It's OK as long as we only deal with FreeLdr's freeldr.ini + * and NTLDR's boot.ini files. But as soon as we'll implement support for + * BOOTMGR detection, the "configuration file" will be the BCD registry + * hive and then, we'll have instead to mount the hive & open it. + */ + + // + // FIXME!! + // + + // if (BootStore->Type >= BldrTypeMax || NtosBootLoaders[BootStore->Type].Type >= BldrTypeMax) + if (BootStore->Type != FreeLdr) + { + DPRINT1("Loader type %d is currently unsupported!\n", NtosBootLoaders[BootStore->Type].Type); + return STATUS_NOT_SUPPORTED; + } + + // + // TODO: Depending on the flags set in 'FieldsToChange', + // change either one or both these bootloader options. + // + IniCacheInsertKey(((PBOOT_STORE_INI_CONTEXT)BootStore)->OptionsIniSection, + NULL, INSERT_LAST, + L"DefaultOS", (PWCHAR)BootOptions->CurrentBootEntryKey); + + StringCchPrintfW(TimeoutStr, ARRAYSIZE(TimeoutStr), L"%d", BootOptions->Timeout); + IniCacheInsertKey(((PBOOT_STORE_INI_CONTEXT)BootStore)->OptionsIniSection, + NULL, INSERT_LAST, + L"TimeOut", TimeoutStr); + + return STATUS_SUCCESS; +} + + + +static NTSTATUS +FreeLdrEnumerateBootEntries( + IN PBOOT_STORE_INI_CONTEXT BootStore, +// IN ULONG Flags, // Determine which data to retrieve + IN PENUM_BOOT_ENTRIES_ROUTINE EnumBootEntriesRoutine, + IN PVOID Parameter OPTIONAL) +{ + NTSTATUS Status = STATUS_SUCCESS; + PINICACHEITERATOR Iterator; + PINICACHESECTION OsIniSection; + PWCHAR SectionName, KeyData; + UCHAR xxBootEntry[FIELD_OFFSET(NTOS_BOOT_ENTRY, OsOptions) + + max(sizeof(NTOS_OPTIONS), sizeof(BOOT_SECTOR_OPTIONS))]; + PNTOS_BOOT_ENTRY BootEntry = (PNTOS_BOOT_ENTRY)&xxBootEntry; + PWCHAR Buffer; + + /* Enumerate all the valid installations listed in the "Operating Systems" section */ + Iterator = IniCacheFindFirstValue(BootStore->OsIniSection, &SectionName, &KeyData); + if (!Iterator) return STATUS_SUCCESS; + do + { + PWCHAR InstallName; + ULONG InstallNameLength; + + /* Poor-man quotes removal (improvement over bootsup.c:UpdateFreeLoaderIni) */ + if (*KeyData == L'"') + { + /* Quoted name, copy up to the closing quote */ + PWCHAR End = wcschr(KeyData + 1, L'"'); + + if (End) + { + /* Skip the first quote */ + InstallName = KeyData + 1; + InstallNameLength = End - InstallName; + } + else // if (!End) + { + /* No corresponding closing quote, so we include the first one in the InstallName */ + InstallName = KeyData; + InstallNameLength = wcslen(InstallName); + } + if (InstallNameLength == 0) InstallName = NULL; + } + else + { + /* Non-quoted name, copy everything */ + InstallName = KeyData; + InstallNameLength = wcslen(InstallName); + if (InstallNameLength == 0) InstallName = NULL; + } + + /* Allocate the temporary buffer */ + Buffer = NULL; + if (InstallNameLength) + Buffer = RtlAllocateHeap(ProcessHeap, HEAP_ZERO_MEMORY, (InstallNameLength + 1) * sizeof(WCHAR)); + if (Buffer) + { + RtlCopyMemory(Buffer, InstallName, InstallNameLength * sizeof(WCHAR)); + Buffer[InstallNameLength] = UNICODE_NULL; + InstallName = Buffer; + } + + DPRINT1("Boot entry '%S' in OS section '%S'\n", InstallName, SectionName); + + BootEntry->Version = NULL; + BootEntry->BootEntryKey = MAKESTRKEY(SectionName); + BootEntry->FriendlyName = InstallName; + BootEntry->BootFilePath = NULL; + BootEntry->OsOptionsLength = 0; + + /* Search for an existing boot entry section */ + OsIniSection = IniCacheGetSection(BootStore->IniCache, SectionName); + if (!OsIniSection) + goto DoEnum; + + /* Check for supported boot type "Windows2003" */ + Status = IniCacheGetKey(OsIniSection, L"BootType", &KeyData); + if (!NT_SUCCESS(Status) || (KeyData == NULL)) + { + /* Certainly not a ReactOS installation */ + DPRINT1("No BootType value present!\n"); + goto DoEnum; + } + + // TODO: What to do with "Windows" ; "WindowsNT40" ; "ReactOSSetup" ? + if ((_wcsicmp(KeyData, L"Windows2003") == 0) || + (_wcsicmp(KeyData, L"\"Windows2003\"") == 0)) + { + /* BootType is Windows2003 */ + PNTOS_OPTIONS Options = (PNTOS_OPTIONS)&BootEntry->OsOptions; + + BootEntry->Version = L"Windows2003"; + DPRINT1("This is a '%S' boot entry\n", BootEntry->Version); + + BootEntry->OsOptionsLength = sizeof(NTOS_OPTIONS); + RtlCopyMemory(Options->Signature, + NTOS_OPTIONS_SIGNATURE, + RTL_FIELD_SIZE(NTOS_OPTIONS, Signature)); + + // BootEntry->BootFilePath = NULL; + + /* Check its SystemPath */ + Status = IniCacheGetKey(OsIniSection, L"SystemPath", &KeyData); + if (!NT_SUCCESS(Status)) + Options->OsLoadPath = NULL; + else + Options->OsLoadPath = KeyData; + // KeyData == SystemRoot; + + /* Check the optional Options */ + Status = IniCacheGetKey(OsIniSection, L"Options", &KeyData); + if (!NT_SUCCESS(Status)) + Options->OsLoadOptions = NULL; + else + Options->OsLoadOptions = KeyData; + } + else + if ((_wcsicmp(KeyData, L"BootSector") == 0) || + (_wcsicmp(KeyData, L"\"BootSector\"") == 0)) + { + /* BootType is BootSector */ + PBOOT_SECTOR_OPTIONS Options = (PBOOT_SECTOR_OPTIONS)&BootEntry->OsOptions; + + BootEntry->Version = L"BootSector"; + DPRINT1("This is a '%S' boot entry\n", BootEntry->Version); + + BootEntry->OsOptionsLength = sizeof(BOOT_SECTOR_OPTIONS); + RtlCopyMemory(Options->Signature, + BOOT_SECTOR_OPTIONS_SIGNATURE, + RTL_FIELD_SIZE(BOOT_SECTOR_OPTIONS, Signature)); + + // BootEntry->BootFilePath = NULL; + + /* Check its BootDrive */ + Status = IniCacheGetKey(OsIniSection, L"BootDrive", &KeyData); + if (!NT_SUCCESS(Status)) + Options->Drive = NULL; + else + Options->Drive = KeyData; + + /* Check its BootPartition */ + Status = IniCacheGetKey(OsIniSection, L"BootPartition", &KeyData); + if (!NT_SUCCESS(Status)) + Options->Partition = NULL; + else + Options->Partition = KeyData; + + /* Check its BootSector */ + Status = IniCacheGetKey(OsIniSection, L"BootSectorFile", &KeyData); + if (!NT_SUCCESS(Status)) + Options->BootSectorFileName = NULL; + else + Options->BootSectorFileName = KeyData; + } + else + { + DPRINT1("Unrecognized BootType value '%S'\n", KeyData); + // BootEntry->Version = KeyData; + // goto DoEnum; + } + +DoEnum: + /* Call the user enumeration routine callback */ + Status = EnumBootEntriesRoutine(FreeLdr, BootEntry, Parameter); + + /* Free temporary buffers */ + if (Buffer) + RtlFreeHeap(ProcessHeap, 0, Buffer); + + /* Stop the enumeration if needed */ + if (!NT_SUCCESS(Status)) + break; + } + while (IniCacheFindNextValue(Iterator, &SectionName, &KeyData)); + + IniCacheFindClose(Iterator); + return Status; +} + +static NTSTATUS +NtLdrEnumerateBootEntries( + IN PBOOT_STORE_INI_CONTEXT BootStore, +// IN ULONG Flags, // Determine which data to retrieve + IN PENUM_BOOT_ENTRIES_ROUTINE EnumBootEntriesRoutine, + IN PVOID Parameter OPTIONAL) +{ + NTSTATUS Status = STATUS_SUCCESS; + PINICACHEITERATOR Iterator; + PWCHAR SectionName, KeyData; + UCHAR xxBootEntry[FIELD_OFFSET(NTOS_BOOT_ENTRY, OsOptions) + sizeof(NTOS_OPTIONS)]; + PNTOS_BOOT_ENTRY BootEntry = (PNTOS_BOOT_ENTRY)&xxBootEntry; + PNTOS_OPTIONS Options = (PNTOS_OPTIONS)&BootEntry->OsOptions; + PWCHAR Buffer; + ULONG BufferLength; + + /* Enumerate all the valid installations */ + Iterator = IniCacheFindFirstValue(BootStore->OsIniSection, &SectionName, &KeyData); + if (!Iterator) return STATUS_SUCCESS; + do + { + PWCHAR InstallName, OsOptions; + ULONG InstallNameLength, OsOptionsLength; + + /* Poor-man quotes removal (improvement over bootsup.c:UpdateFreeLoaderIni) */ + if (*KeyData == L'"') + { + /* Quoted name, copy up to the closing quote */ + OsOptions = wcschr(KeyData + 1, L'"'); + + /* Retrieve the starting point of the installation name and the OS options */ + if (OsOptions) + { + /* Skip the first quote */ + InstallName = KeyData + 1; + InstallNameLength = OsOptions - InstallName; + if (InstallNameLength == 0) InstallName = NULL; + + /* Skip the ending quote (if found) */ + ++OsOptions; + + /* Skip any whitespace */ + while (iswspace(*OsOptions)) ++OsOptions; + /* Get its final length */ + OsOptionsLength = wcslen(OsOptions); + if (OsOptionsLength == 0) OsOptions = NULL; + } + else + { + /* No corresponding closing quote, so we include the first one in the InstallName */ + InstallName = KeyData; + InstallNameLength = wcslen(InstallName); + if (InstallNameLength == 0) InstallName = NULL; + + /* There are no OS options */ + // OsOptions = NULL; + OsOptionsLength = 0; + } + } + else + { + /* Non-quoted name, copy everything */ + + /* Retrieve the starting point of the installation name */ + InstallName = KeyData; + InstallNameLength = wcslen(InstallName); + if (InstallNameLength == 0) InstallName = NULL; + + /* There are no OS options */ + OsOptions = NULL; + OsOptionsLength = 0; + } + + /* Allocate the temporary buffer */ + Buffer = NULL; + BufferLength = (InstallNameLength + OsOptionsLength) * sizeof(WCHAR); + if (BufferLength) + Buffer = RtlAllocateHeap(ProcessHeap, HEAP_ZERO_MEMORY, BufferLength + 2*sizeof(UNICODE_NULL)); + if (Buffer) + { + PWCHAR ptr; + + /* Copy the installation name, and make InstallName point into the buffer */ + if (InstallName && InstallNameLength) + { + ptr = Buffer; + RtlCopyMemory(ptr, InstallName, InstallNameLength * sizeof(WCHAR)); + ptr[InstallNameLength] = UNICODE_NULL; + InstallName = ptr; + } + + /* Copy the OS options, and make OsOptions point into the buffer */ + if (OsOptions && OsOptionsLength) + { + ptr = Buffer + InstallNameLength + 1; + RtlCopyMemory(ptr, OsOptions, OsOptionsLength * sizeof(WCHAR)); + ptr[OsOptionsLength] = UNICODE_NULL; + OsOptions = ptr; + } + } + + DPRINT1("Boot entry '%S' in OS section (path) '%S'\n", InstallName, SectionName); + // SectionName == SystemRoot; + + BootEntry->Version = L"Windows2003"; + BootEntry->BootEntryKey = 0; // FIXME?? + BootEntry->FriendlyName = InstallName; + BootEntry->BootFilePath = NULL; + + BootEntry->OsOptionsLength = sizeof(NTOS_OPTIONS); + RtlCopyMemory(Options->Signature, + NTOS_OPTIONS_SIGNATURE, + RTL_FIELD_SIZE(NTOS_OPTIONS, Signature)); + + Options->OsLoadPath = SectionName; + Options->OsLoadOptions = OsOptions; + + /* Call the user enumeration routine callback */ + Status = EnumBootEntriesRoutine(NtLdr, BootEntry, Parameter); + + /* Free temporary buffers */ + if (Buffer) + RtlFreeHeap(ProcessHeap, 0, Buffer); + + /* Stop the enumeration if needed */ + if (!NT_SUCCESS(Status)) + break; + } + while (IniCacheFindNextValue(Iterator, &SectionName, &KeyData)); + + IniCacheFindClose(Iterator); + return Status; +} + +NTSTATUS +EnumerateNTOSBootEntries( + IN PVOID Handle, +// IN ULONG Flags, // Determine which data to retrieve + IN PENUM_BOOT_ENTRIES_ROUTINE EnumBootEntriesRoutine, + IN PVOID Parameter OPTIONAL) +{ + PBOOT_STORE_CONTEXT BootStore = (PBOOT_STORE_CONTEXT)Handle; + + if (!BootStore) + return STATUS_INVALID_PARAMETER; + + if (BootStore->Type >= BldrTypeMax || NtosBootLoaders[BootStore->Type].Type >= BldrTypeMax) + { + DPRINT1("Loader type %d is currently unsupported!\n", NtosBootLoaders[BootStore->Type].Type); + /**/return STATUS_SUCCESS;/**/ + // return STATUS_INVALID_PARAMETER; + } + + return NtosBootLoaders[BootStore->Type].EnumBootStoreEntries( + (PBOOT_STORE_INI_CONTEXT)BootStore, // Flags, + EnumBootEntriesRoutine, Parameter); } /* EOF */ diff --git a/base/setup/lib/bldrsup.h b/base/setup/lib/bldrsup.h index a0965e88e9..1c34be7e62 100644 --- a/base/setup/lib/bldrsup.h +++ b/base/setup/lib/bldrsup.h @@ -10,7 +10,7 @@ #pragma once -typedef enum _NTOS_BOOT_LOADER_TYPE +typedef enum _NTOS_BOOT_LOADER_TYPE // _BOOT_STORE_TYPE { FreeLdr, // ReactOS' FreeLoader NtLdr, // Windows <= 2k3 NT "FlexBoot" OS Loader NTLDR @@ -18,23 +18,99 @@ typedef enum _NTOS_BOOT_LOADER_TYPE BldrTypeMax } NTOS_BOOT_LOADER_TYPE; +/* + * Some references about EFI boot entries: + *
https://docs.microsoft.com/en-us/windows-hardware/drivers/devtest/overview-…
+ *
https://docs.microsoft.com/en-us/windows-hardware/drivers/devtest/identifyi…
+ */ + +/* + * This structure is inspired from the EFI boot entry structure + * BOOT_OPTIONS that is defined in ndk/iotypes.h . + */ +typedef struct _NTOS_BOOT_OPTIONS // _BOOT_STORE_OPTIONS +{ + // ULONG Version; + // ULONG Length; + ULONG Timeout; + ULONG_PTR CurrentBootEntryKey; + // ULONG_PTR NextBootEntryKey; + // WCHAR HeadlessRedirection[1]; +} NTOS_BOOT_OPTIONS, *PNTOS_BOOT_OPTIONS; + +/* + * These macros are used to set a value for the BootEntryKey member of a + * NTOS_BOOT_ENTRY structure, much in the same idea as MAKEINTRESOURCE and + * IS_INTRESOURCE macros for Win32 resources. + * + * A key consists of either a boot ID number, + * comprised between 0 and MAX_USHORT == 0xFFFF == 65535, or can be a pointer + * to a human-readable string (section name), as in the case of FreeLDR, or + * to a GUID, as in the case of BOOTMGR. + * + * If IS_INTKEY(BootEntryKey) == TRUE, i.e. the key is <= 65535, this means + * the key is a boot ID number, otherwise it is typically a pointer to a string. + */ +#define MAKESTRKEY(i) ((ULONG_PTR)(i)) +#define MAKEINTKEY(i) ((ULONG_PTR)((USHORT)(i))) +#define IS_INTKEY(i) (((ULONG_PTR)(i) >> 16) == 0) + /* * This structure is inspired from the EFI boot entry structures - * BOOT_ENTRY, BOOT_OPTIONS and FILE_PATH that are defined in ndk/iotypes.h . + * BOOT_ENTRY and FILE_PATH that are defined in ndk/iotypes.h . */ -typedef struct _NTOS_BOOT_ENTRY +typedef struct _NTOS_BOOT_ENTRY // _BOOT_STORE_ENTRY { - // ULONG Version; // We might use the ntldr version here?? Or the "BootType" as in freeldr? + // ULONG Version; // Equivalent of the "BootType" in FreeLdr + PWCHAR Version; // HACK!!! // ULONG Length; - // ULONG Id; // Boot entry number (position) in the list -/** PCWSTR FriendlyName; // Human-readable boot entry description **/ - PUNICODE_STRING FriendlyName; - PCWSTR BootFilePath; // Path to e.g. osloader.exe, or winload.efi - PCWSTR OsLoadPath; // The OS SystemRoot path - PCWSTR OsOptions; - PCWSTR OsLoadOptions; + ULONG_PTR BootEntryKey; // Boot entry "key" + PCWSTR FriendlyName; // Human-readable boot entry description // LoadIdentifier + PCWSTR BootFilePath; // Path to e.g. osloader.exe, or winload.efi // EfiOsLoaderFilePath + ULONG OsOptionsLength; // Loader-specific options blob (can be a string, or a binary structure...) + UCHAR OsOptions[ANYSIZE_ARRAY]; +/* + * In packed form, this structure would contain offsets to 'FriendlyName' + * and 'BootFilePath' strings and, after the OsOptions blob, there would + * be the following data: + * + * WCHAR FriendlyName[ANYSIZE_ARRAY]; + * FILE_PATH BootFilePath; + */ } NTOS_BOOT_ENTRY, *PNTOS_BOOT_ENTRY; +/* "NTOS" (aka. ReactOS or MS Windows NT) <= 5.x options */ +typedef struct _NTOS_OPTIONS +{ + UCHAR Signature[8]; // "NTOS_5\0\0" + // ULONG Version; + // ULONG Length; + PCWSTR OsLoadPath; // The OS SystemRoot path // OsLoaderFilePath // OsFilePath + PCWSTR OsLoadOptions; // OsLoadOptions +/* + * In packed form, this structure would contain an offset to the 'OsLoadPath' + * string, and the 'OsLoadOptions' member would be: + * WCHAR OsLoadOptions[ANYSIZE_ARRAY]; + * followed by: + * FILE_PATH OsLoadPath; + */ +} NTOS_OPTIONS, *PNTOS_OPTIONS; + +#define NTOS_OPTIONS_SIGNATURE "NTOS_5\0\0" + +/* Options for boot-sector boot entries */ +typedef struct _BOOT_SECTOR_OPTIONS +{ + UCHAR Signature[8]; // "BootSect" + // ULONG Version; + // ULONG Length; + PCWSTR Drive; + PCWSTR Partition; + PCWSTR BootSectorFileName; +} BOOT_SECTOR_OPTIONS, *PBOOT_SECTOR_OPTIONS; + +#define BOOT_SECTOR_OPTIONS_SIGNATURE "BootSect" + typedef NTSTATUS (NTAPI *PENUM_BOOT_ENTRIES_ROUTINE)( @@ -45,14 +121,74 @@ typedef NTSTATUS NTSTATUS FindNTOSBootLoader( // By handle - IN HANDLE PartitionHandle, // OPTIONAL + IN HANDLE PartitionDirectoryHandle, // OPTIONAL IN NTOS_BOOT_LOADER_TYPE Type, OUT PULONG Version); + NTSTATUS -EnumerateNTOSBootEntries( - IN HANDLE PartitionHandle, // OPTIONAL +OpenNTOSBootLoaderStoreByHandle( + OUT PVOID* Handle, + IN HANDLE PartitionDirectoryHandle, // OPTIONAL IN NTOS_BOOT_LOADER_TYPE Type, + IN BOOLEAN CreateNew); + +NTSTATUS +OpenNTOSBootLoaderStore_UStr( + OUT PVOID* Handle, + IN PUNICODE_STRING SystemPartitionPath, + IN NTOS_BOOT_LOADER_TYPE Type, + IN BOOLEAN CreateNew); + +NTSTATUS +OpenNTOSBootLoaderStore( + OUT PVOID* Handle, + IN PCWSTR SystemPartition, + IN NTOS_BOOT_LOADER_TYPE Type, + IN BOOLEAN CreateNew); + +NTSTATUS +CloseNTOSBootLoaderStore( + IN PVOID Handle); + +NTSTATUS +AddNTOSBootEntry( + IN PVOID Handle, + IN PNTOS_BOOT_ENTRY BootEntry, + IN ULONG_PTR BootEntryKey); + +NTSTATUS +DeleteNTOSBootEntry( + IN PVOID Handle, + IN ULONG_PTR BootEntryKey); + +NTSTATUS +ModifyNTOSBootEntry( + IN PVOID Handle, + IN PNTOS_BOOT_ENTRY BootEntry); + +NTSTATUS +QueryNTOSBootEntry( + IN PVOID Handle, + IN ULONG_PTR BootEntryKey, + OUT PNTOS_BOOT_ENTRY BootEntry); // Technically this should be PNTOS_BOOT_ENTRY* + +NTSTATUS +QueryNTOSBootOptions( + IN PVOID Handle, + IN OUT PNTOS_BOOT_OPTIONS BootOptions +/* , IN PULONG BootOptionsLength */ ); + +NTSTATUS +SetNTOSBootOptions( + IN PVOID Handle, + IN PNTOS_BOOT_OPTIONS BootOptions, + IN ULONG FieldsToChange); + +NTSTATUS +EnumerateNTOSBootEntries( + IN PVOID Handle, +// IN ULONG Flags, // Determine which data to retrieve IN PENUM_BOOT_ENTRIES_ROUTINE EnumBootEntriesRoutine, IN PVOID Parameter OPTIONAL); diff --git a/base/setup/lib/osdetect.c b/base/setup/lib/osdetect.c index 6b16e5624d..6bdd5ea416 100644 --- a/base/setup/lib/osdetect.c +++ b/base/setup/lib/osdetect.c @@ -19,9 +19,6 @@ #include "arcname.h" #include "osdetect.h" -// HACK! -#include <strsafe.h> - #define NDEBUG #include <debug.h> @@ -34,51 +31,6 @@ static const PCWSTR KnownVendors[] = { L"ReactOS", L"Microsoft" }; /* FUNCTIONS ****************************************************************/ -#if 0 - -BOOL IsWindowsOS(VOID) -{ - // TODO? : - // Load the "SystemRoot\System32\Config\SOFTWARE" hive and mount it, - // then go to (SOFTWARE\\)Microsoft\\Windows NT\\CurrentVersion, - // check the REG_SZ value "ProductName" and see whether it's "Windows" - // or "ReactOS". One may also check the REG_SZ "CurrentVersion" value, - // the REG_SZ "SystemRoot" and "PathName" values (what are the differences??). - // - // Optionally, looking at the SYSTEM hive, CurrentControlSet\\Control, - // REG_SZ values "SystemBootDevice" (and "FirmwareBootDevice" ??)... - // - - /* ReactOS reports as Windows NT 5.2 */ - HKEY hKey = NULL; - - if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, - L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", - 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS) - { - LONG ret; - DWORD dwType = 0, dwBufSize = 0; - - ret = RegQueryValueExW(hKey, L"ProductName", NULL, &dwType, NULL, &dwBufSize); - if (ret == ERROR_SUCCESS && dwType == REG_SZ) - { - LPTSTR lpszProductName = (LPTSTR)MemAlloc(0, dwBufSize); - RegQueryValueExW(hKey, L"ProductName", NULL, &dwType, (LPBYTE)lpszProductName, &dwBufSize); - - bIsWindowsOS = (FindSubStrI(lpszProductName, _T("Windows")) != NULL); - - MemFree(lpszProductName); - } - - RegCloseKey(hKey); - } - - return bIsWindowsOS; -} - -#endif - - static BOOLEAN IsValidNTOSInstallation_UStr( IN PUNICODE_STRING SystemRootPath); @@ -134,33 +86,31 @@ EnumerateInstallations( /* We have a boot entry */ - UNICODE_STRING InstallName; - // /**/RtlInitUnicodeString(&InstallName, BootEntry->FriendlyName);/**/ - InstallName = *BootEntry->FriendlyName; - -#if 0 - if (Type == FreeLdr) + /* Check for supported boot type "Windows2003" */ + // TODO: What to do with "Windows" ; "WindowsNT40" ; "ReactOSSetup" ? + if ((BootEntry->Version == NULL) || + ( (_wcsicmp(BootEntry->Version, L"Windows2003") != 0) && + (_wcsicmp(BootEntry->Version, L"\"Windows2003\"") != 0) )) { - /* Check for supported boot type "Windows2003" */ + /* This is not a ReactOS entry */ + DPRINT1(" An installation '%S' of unsupported type '%S'\n", + BootEntry->FriendlyName, BootEntry->Version ? BootEntry->Version : L"n/a"); + /* Continue the enumeration */ + return STATUS_SUCCESS; + } - // TODO: What to do with "Windows" ; "WindowsNT40" ; "ReactOSSetup" ? - if ((BootType == NULL) || - ( (_wcsicmp(BootType, L"Windows2003") != 0) && - (_wcsicmp(BootType, L"\"Windows2003\"") != 0) )) - { - /* This is not a ReactOS entry */ - /* Certainly not a ReactOS installation */ - DPRINT1(" A Win2k3 install '%wZ' without an ARC path?!\n", &InstallName); - /* Continue the enumeration */ - return STATUS_SUCCESS; - } + if (!BootEntry->OsLoadPath || !*BootEntry->OsLoadPath) + { + /* Certainly not a ReactOS installation */ + DPRINT1(" A Win2k3 install '%S' without an ARC path?!\n", BootEntry->FriendlyName); + /* Continue the enumeration */ + return STATUS_SUCCESS; } -#endif - DPRINT1(" Found a candidate Win2k3 install '%wZ' with ARC path '%S'\n", - &InstallName, BootEntry->OsLoadPath); - // DPRINT1(" Found a Win2k3 install '%wZ' with ARC path '%S'\n", - // &InstallName, BootEntry->OsLoadPath); + DPRINT1(" Found a candidate Win2k3 install '%S' with ARC path '%S'\n", + BootEntry->FriendlyName, BootEntry->OsLoadPath); + // DPRINT1(" Found a Win2k3 install '%S' with ARC path '%S'\n", + // BootEntry->FriendlyName, BootEntry->OsLoadPath); // TODO: Normalize the ARC path. @@ -240,14 +190,19 @@ EnumerateInstallations( if (PartEntry && PartEntry->DriveLetter) { /* We have retrieved a partition that is mounted */ - StringCchPrintfW(InstallNameW, ARRAYSIZE(InstallNameW), L"%C:%s \"%wZ\"", - PartEntry->DriveLetter, PathComponent, &InstallName); + RtlStringCchPrintfW(InstallNameW, ARRAYSIZE(InstallNameW), + L"%C:%s \"%s\"", + PartEntry->DriveLetter, + PathComponent, + BootEntry->FriendlyName); } else { /* We failed somewhere, just show the NT path */ - StringCchPrintfW(InstallNameW, ARRAYSIZE(InstallNameW), L"%wZ \"%wZ\"", - &SystemRootPath, &InstallName); + RtlStringCchPrintfW(InstallNameW, ARRAYSIZE(InstallNameW), + L"%wZ \"%s\"", + &SystemRootPath, + BootEntry->FriendlyName); } AddNTOSInstallation(Data->List, BootEntry->OsLoadPath, &SystemRootPath, PathComponent, @@ -347,9 +302,9 @@ CheckForValidPEAndVendor( wCodePage = LOWORD(*(ULONG*)pvData); wLangID = HIWORD(*(ULONG*)pvData); - StringCchPrintfW(FileInfo, ARRAYSIZE(FileInfo), - L"StringFileInfo\\%04X%04X\\CompanyName", - wCodePage, wLangID); + RtlStringCchPrintfW(FileInfo, ARRAYSIZE(FileInfo), + L"StringFileInfo\\%04X%04X\\CompanyName", + wCodePage, wLangID); Status = NtVerQueryValue(VersionBuffer, FileInfo, &pvData, &BufLen); @@ -362,8 +317,8 @@ CheckForValidPEAndVendor( /* BufLen includes the NULL terminator count */ DPRINT1("Found version vendor: \"%S\" for file '%S'\n", pvData, PathNameToFile); - StringCbCopyNW(VendorName->Buffer, VendorName->MaximumLength, - pvData, BufLen * sizeof(WCHAR)); + RtlStringCbCopyNW(VendorName->Buffer, VendorName->MaximumLength, + pvData, BufLen * sizeof(WCHAR)); VendorName->Length = wcslen(VendorName->Buffer) * sizeof(WCHAR); Success = TRUE; @@ -503,7 +458,7 @@ IsValidNTOSInstallation_UStr( NULL, NULL); Status = NtOpenFile(&SystemRootDirectory, - FILE_LIST_DIRECTORY | SYNCHRONIZE, + FILE_LIST_DIRECTORY | FILE_TRAVERSE | SYNCHRONIZE, &ObjectAttributes, &IoStatusBlock, FILE_SHARE_READ | FILE_SHARE_WRITE, @@ -659,10 +614,12 @@ AddNTOSInstallation( NtOsInstall->PathComponent = NtOsInstall->SystemNtPath.Buffer + (PathComponent - SystemRootNtPath->Buffer); - StringCchCopyW(NtOsInstall->InstallationName, ARRAYSIZE(NtOsInstall->InstallationName), InstallationName); + RtlStringCchCopyW(NtOsInstall->InstallationName, + ARRAYSIZE(NtOsInstall->InstallationName), + InstallationName); // Having the GENERIC_LIST storing the display item string plainly sucks... - StringCchPrintfA(InstallNameA, ARRAYSIZE(InstallNameA), "%S", InstallationName); + RtlStringCchPrintfA(InstallNameA, ARRAYSIZE(InstallNameA), "%S", InstallationName); AppendGenericListEntry(List, InstallNameA, NtOsInstall, FALSE); return NtOsInstall; @@ -677,19 +634,20 @@ FindNTOSInstallations( NTSTATUS Status; ULONG DiskNumber = PartEntry->DiskEntry->DiskNumber; ULONG PartitionNumber = PartEntry->PartitionNumber; - HANDLE PartitionHandle; + HANDLE PartitionDirectoryHandle; OBJECT_ATTRIBUTES ObjectAttributes; IO_STATUS_BLOCK IoStatusBlock; UNICODE_STRING PartitionRootPath; NTOS_BOOT_LOADER_TYPE Type; + PVOID BootStoreHandle; ENUM_INSTALLS_DATA Data; ULONG Version; WCHAR PathBuffer[MAX_PATH]; /* Set PartitionRootPath */ - StringCchPrintfW(PathBuffer, ARRAYSIZE(PathBuffer), - L"\\Device\\Harddisk%lu\\Partition%lu\\", - DiskNumber, PartitionNumber); + RtlStringCchPrintfW(PathBuffer, ARRAYSIZE(PathBuffer), + L"\\Device\\Harddisk%lu\\Partition%lu\\", + DiskNumber, PartitionNumber); RtlInitUnicodeString(&PartitionRootPath, PathBuffer); DPRINT1("FindNTOSInstallations: PartitionRootPath: '%wZ'\n", &PartitionRootPath); @@ -699,8 +657,8 @@ FindNTOSInstallations( OBJ_CASE_INSENSITIVE, NULL, NULL); - Status = NtOpenFile(&PartitionHandle, - FILE_LIST_DIRECTORY | SYNCHRONIZE, + Status = NtOpenFile(&PartitionDirectoryHandle, + FILE_LIST_DIRECTORY | FILE_TRAVERSE | SYNCHRONIZE, &ObjectAttributes, &IoStatusBlock, FILE_SHARE_READ | FILE_SHARE_WRITE, @@ -717,7 +675,7 @@ FindNTOSInstallations( /* Try to see whether we recognize some NT boot loaders */ for (Type = FreeLdr; Type < BldrTypeMax; ++Type) { - Status = FindNTOSBootLoader(PartitionHandle, Type, &Version); + Status = FindNTOSBootLoader(PartitionDirectoryHandle, Type, &Version); if (!NT_SUCCESS(Status)) { /* The loader does not exist, continue with another one */ @@ -730,11 +688,19 @@ FindNTOSInstallations( DPRINT1("Analyse the OS installations for loader type '%d' in disk #%d, partition #%d\n", Type, DiskNumber, PartitionNumber); - EnumerateNTOSBootEntries(PartitionHandle, Type, EnumerateInstallations, &Data); + Status = OpenNTOSBootLoaderStoreByHandle(&BootStoreHandle, PartitionDirectoryHandle, Type, FALSE); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Could not open the NTOS boot store of type '%d' (Status 0x%08lx), continue with another one...\n", + Type, Status); + continue; + } + EnumerateNTOSBootEntries(BootStoreHandle, EnumerateInstallations, &Data); + CloseNTOSBootLoaderStore(BootStoreHandle); } /* Close the partition */ - NtClose(PartitionHandle); + NtClose(PartitionDirectoryHandle); } // static
6 years, 2 months
1
0
0
0
04/04: [USETUP] Diverse fixes for path handling.
by Hermès Bélusca-Maïto
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=57402ee91e1a0b74bf589…
commit 57402ee91e1a0b74bf5894942cf3f968db4a8bf8 Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org> AuthorDate: Wed May 31 02:19:08 2017 +0000 Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org> CommitDate: Sun Oct 14 23:22:55 2018 +0200 [USETUP] Diverse fixes for path handling. - Convert almost all swprintf() into StringCchPrintfW() and wcscpy() into StringCchCopyW(); - Explicitly add a trailing path separator to the "\Device\HarddiskX\PartitionY(\)" paths when they refer to FS directories (and not to partition objects); - Remove useless (and half-buggy) "Remove trailing backslash" code. With that, it is possible to install ReactOS in e.g. C:\ReactOS (as usual), C:\ReactOS\dir1\dir2 (as many dirs as you wish), and also in C:\ (yes yes!). But in that latter case, a strange bug related to the registry arises... Additionally: - Adjust some comments; - Add some debugging DPRINTs; - The SetInstallPathValue() is part of the big hack I've mentioned in f51faa4a (r74709). svn path=/branches/setup_improvements/; revision=74717 --- base/setup/usetup/usetup.c | 184 ++++++++++++++++++++++----------------------- base/setup/usetup/usetup.h | 2 - 2 files changed, 92 insertions(+), 94 deletions(-) diff --git a/base/setup/usetup/usetup.c b/base/setup/usetup/usetup.c index 777b62ffef..3c7eb74de5 100644 --- a/base/setup/usetup/usetup.c +++ b/base/setup/usetup/usetup.c @@ -38,13 +38,16 @@ #define NDEBUG #include <debug.h> +// HACK! +#include <strsafe.h> + /* GLOBALS ******************************************************************/ HANDLE ProcessHeap; -UNICODE_STRING SourceRootPath; -UNICODE_STRING SourceRootDir; -UNICODE_STRING SourcePath; +static UNICODE_STRING SourceRootPath; +static UNICODE_STRING SourceRootDir; +/* static */ UNICODE_STRING SourcePath; BOOLEAN IsUnattendedSetup = FALSE; LONG UnattendDestinationDiskNumber; LONG UnattendDestinationPartitionNumber; @@ -427,7 +430,7 @@ CheckUnattendedSetup(VOID) INT IntValue; PWCHAR Value; - CombinePaths(UnattendInfPath, ARRAYSIZE(UnattendInfPath), 2, SourcePath.Buffer, L"\\unattend.inf"); + CombinePaths(UnattendInfPath, ARRAYSIZE(UnattendInfPath), 2, SourcePath.Buffer, L"unattend.inf"); if (DoesFileExist(NULL, UnattendInfPath) == FALSE) { @@ -580,7 +583,7 @@ CheckUnattendedSetup(VOID) if (INF_GetData(&Context, NULL, &Value)) { LONG Id = wcstol(Value, NULL, 16); - swprintf(LocaleID,L"%08lx", Id); + swprintf(LocaleID, L"%08lx", Id); } } @@ -806,24 +809,18 @@ SetupStartPage(PINPUT_RECORD Ir) Status = GetSourcePaths(&SourcePath, &SourceRootPath, &SourceRootDir); - if (!NT_SUCCESS(Status)) { CONSOLE_PrintTextXY(6, 15, "GetSourcePaths() failed (Status 0x%08lx)", Status); MUIDisplayError(ERROR_NO_SOURCE_DRIVE, Ir, POPUP_WAIT_ENTER); return QUIT_PAGE; } -#if 0 - else - { - CONSOLE_PrintTextXY(6, 15, "SourcePath: '%wZ'", &SourcePath); - CONSOLE_PrintTextXY(6, 16, "SourceRootPath: '%wZ'", &SourceRootPath); - CONSOLE_PrintTextXY(6, 17, "SourceRootDir: '%wZ'", &SourceRootDir); - } -#endif + DPRINT1("SourcePath: '%wZ'", &SourcePath); + DPRINT1("SourceRootPath: '%wZ'", &SourceRootPath); + DPRINT1("SourceRootDir: '%wZ'", &SourceRootDir); /* Load txtsetup.sif from install media. */ - CombinePaths(FileNameBuffer, ARRAYSIZE(FileNameBuffer), 2, SourcePath.Buffer, L"\\txtsetup.sif"); + CombinePaths(FileNameBuffer, ARRAYSIZE(FileNameBuffer), 2, SourcePath.Buffer, L"txtsetup.sif"); SetupInf = SetupOpenInfFileW(FileNameBuffer, NULL, INF_STYLE_WIN4, @@ -2639,6 +2636,13 @@ SelectFileSystemPage(PINPUT_RECORD Ir) if (PartitionList->SystemPartition == NULL) { /* FIXME: show an error dialog */ + // + // Error dialog should say that we cannot find a suitable + // system partition and create one on the system. At this point, + // it may be nice to ask the user whether he wants to continue, + // or use an external drive as the system drive/partition + // (e.g. floppy, USB drive, etc...) + // return QUIT_PAGE; } @@ -3026,12 +3030,11 @@ FormatPartitionPage(PINPUT_RECORD Ir) } /* Set PartitionRootPath */ - swprintf(PathBuffer, - L"\\Device\\Harddisk%lu\\Partition%lu", - DiskEntry->DiskNumber, - PartEntry->PartitionNumber); - RtlInitUnicodeString(&PartitionRootPath, - PathBuffer); + StringCchPrintfW(PathBuffer, ARRAYSIZE(PathBuffer), + L"\\Device\\Harddisk%lu\\Partition%lu", + DiskEntry->DiskNumber, + PartEntry->PartitionNumber); + RtlInitUnicodeString(&PartitionRootPath, PathBuffer); DPRINT("PartitionRootPath: %wZ\n", &PartitionRootPath); /* Format the partition */ @@ -3100,10 +3103,10 @@ CheckFileSystemPage(PINPUT_RECORD Ir) } /* Set PartitionRootPath */ - swprintf(PathBuffer, - L"\\Device\\Harddisk%lu\\Partition%lu", - DiskEntry->DiskNumber, - PartEntry->PartitionNumber); + StringCchPrintfW(PathBuffer, ARRAYSIZE(PathBuffer), + L"\\Device\\Harddisk%lu\\Partition%lu", + DiskEntry->DiskNumber, + PartEntry->PartitionNumber); RtlInitUnicodeString(&PartitionRootPath, PathBuffer); DPRINT("PartitionRootPath: %wZ\n", &PartitionRootPath); @@ -3191,10 +3194,10 @@ BuildInstallPaths(PWCHAR InstallDir, /* Create 'DestinationRootPath' string */ RtlFreeUnicodeString(&DestinationRootPath); - swprintf(PathBuffer, - L"\\Device\\Harddisk%lu\\Partition%lu", - DiskEntry->DiskNumber, - PartEntry->PartitionNumber); + StringCchPrintfW(PathBuffer, ARRAYSIZE(PathBuffer), + L"\\Device\\Harddisk%lu\\Partition%lu\\", + DiskEntry->DiskNumber, + PartEntry->PartitionNumber); RtlCreateUnicodeString(&DestinationRootPath, PathBuffer); DPRINT("DestinationRootPath: %wZ\n", &DestinationRootPath); @@ -3206,10 +3209,10 @@ BuildInstallPaths(PWCHAR InstallDir, /* Create 'DestinationArcPath' */ RtlFreeUnicodeString(&DestinationArcPath); - swprintf(PathBuffer, - L"multi(0)disk(0)rdisk(%lu)partition(%lu)", - DiskEntry->BiosDiskNumber, - PartEntry->PartitionNumber); + 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); } @@ -3413,18 +3416,23 @@ AddSectionToCopyQueueCab(HINF InfFile, 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]; + 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. + * Enumerate the files in the section and add them to the file queue. */ do { @@ -3487,24 +3495,27 @@ AddSectionToCopyQueue(HINF InfFile, PWCHAR FileKeyValue; PWCHAR DirKeyValue; PWCHAR TargetFileName; - ULONG Length; - WCHAR CompleteOrigDirName[512]; + 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]; + 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. + * Enumerate the files in the section and add them to the file queue. */ do { @@ -3550,25 +3561,32 @@ AddSectionToCopyQueue(HINF InfFile, if ((DirKeyValue[0] == UNICODE_NULL) || (DirKeyValue[0] == L'\\' && DirKeyValue[1] == UNICODE_NULL)) { /* Installation path */ - wcscpy(CompleteOrigDirName, SourceRootDir.Buffer); + DPRINT("InstallationPath: '%S'\n", DirKeyValue); + + StringCchCopyW(CompleteOrigDirName, ARRAYSIZE(CompleteOrigDirName), + SourceRootDir.Buffer); + + DPRINT("InstallationPath(2): '%S'\n", CompleteOrigDirName); } else if (DirKeyValue[0] == L'\\') { /* Absolute path */ - wcscpy(CompleteOrigDirName, DirKeyValue); + DPRINT("AbsolutePath: '%S'\n", DirKeyValue); + + StringCchCopyW(CompleteOrigDirName, ARRAYSIZE(CompleteOrigDirName), + DirKeyValue); + + DPRINT("AbsolutePath(2): '%S'\n", CompleteOrigDirName); } else // if (DirKeyValue[0] != L'\\') { /* Path relative to the installation path */ + DPRINT("RelativePath: '%S'\n", DirKeyValue); + CombinePaths(CompleteOrigDirName, ARRAYSIZE(CompleteOrigDirName), 2, SourceRootDir.Buffer, DirKeyValue); - } - /* Remove trailing backslash */ - Length = wcslen(CompleteOrigDirName); - if ((Length > 0) && (CompleteOrigDirName[Length - 1] == L'\\')) - { - CompleteOrigDirName[Length - 1] = UNICODE_NULL; + DPRINT("RelativePath(2): '%S'\n", CompleteOrigDirName); } if (!SetupQueueCopy(SetupFileQueue, @@ -3593,12 +3611,11 @@ PrepareCopyPageInfFile(HINF InfFile, PWCHAR SourceCabinet, PINPUT_RECORD Ir) { - WCHAR PathBuffer[MAX_PATH]; + NTSTATUS Status; INFCONTEXT DirContext; PWCHAR AdditionalSectionName = NULL; PWCHAR DirKeyValue; - ULONG Length; - NTSTATUS Status; + WCHAR PathBuffer[MAX_PATH]; /* Add common files */ if (!AddSectionToCopyQueue(InfFile, L"SourceDisksFiles", SourceCabinet, &DestinationPath, Ir)) @@ -3621,22 +3638,16 @@ PrepareCopyPageInfFile(HINF InfFile, /* * FIXME: - * - Install directories like '\reactos\test' are not handled yet. - * - Copying files to DestinationRootPath should be done from within - * the SystemPartitionFiles section. - * At the moment we check whether we specify paths like '\foo' or '\\' for that. - * For installing to DestinationPath specify just '\' . + * Copying files to DestinationRootPath should be done from within + * the SystemPartitionFiles section. + * At the moment we check whether we specify paths like '\foo' or '\\' for that. + * For installing to DestinationPath specify just '\' . */ /* Get destination path */ - wcscpy(PathBuffer, DestinationPath.Buffer); + StringCchCopyW(PathBuffer, ARRAYSIZE(PathBuffer), DestinationPath.Buffer); - /* Remove trailing backslash */ - Length = wcslen(PathBuffer); - if ((Length > 0) && (PathBuffer[Length - 1] == L'\\')) - { - PathBuffer[Length - 1] = UNICODE_NULL; - } + DPRINT("FullPath(1): '%S'\n", PathBuffer); /* Create the install directory */ Status = SetupCreateDirectory(PathBuffer); @@ -3676,26 +3687,20 @@ PrepareCopyPageInfFile(HINF InfFile, /* Installation path */ DPRINT("InstallationPath: '%S'\n", DirKeyValue); - wcscpy(PathBuffer, DestinationPath.Buffer); + StringCchCopyW(PathBuffer, ARRAYSIZE(PathBuffer), + DestinationPath.Buffer); - DPRINT("FullPath: '%S'\n", PathBuffer); + DPRINT("InstallationPath(2): '%S'\n", PathBuffer); } else if (DirKeyValue[0] == L'\\') { /* Absolute path */ - DPRINT("Absolute Path: '%S'\n", DirKeyValue); + DPRINT("AbsolutePath: '%S'\n", DirKeyValue); CombinePaths(PathBuffer, ARRAYSIZE(PathBuffer), 2, DestinationRootPath.Buffer, DirKeyValue); - /* Remove trailing backslash */ - Length = wcslen(PathBuffer); - if ((Length > 0) && (PathBuffer[Length - 1] == L'\\')) - { - PathBuffer[Length - 1] = UNICODE_NULL; - } - - DPRINT("FullPath: '%S'\n", PathBuffer); + DPRINT("AbsolutePath(2): '%S'\n", PathBuffer); Status = SetupCreateDirectory(PathBuffer); if (!NT_SUCCESS(Status) && Status != STATUS_OBJECT_NAME_COLLISION) @@ -3713,14 +3718,7 @@ PrepareCopyPageInfFile(HINF InfFile, CombinePaths(PathBuffer, ARRAYSIZE(PathBuffer), 2, DestinationPath.Buffer, DirKeyValue); - /* Remove trailing backslash */ - Length = wcslen(PathBuffer); - if ((Length > 0) && (PathBuffer[Length - 1] == L'\\')) - { - PathBuffer[Length - 1] = UNICODE_NULL; - } - - DPRINT("FullPath: '%S'\n", PathBuffer); + DPRINT("RelativePath(2): '%S'\n", PathBuffer); Status = SetupCreateDirectory(PathBuffer); if (!NT_SUCCESS(Status) && Status != STATUS_OBJECT_NAME_COLLISION) @@ -4038,12 +4036,14 @@ RegistryPage(PINPUT_RECORD Ir) return SUCCESS_PAGE; } + /************************ HACK!!!!!!!!!!! *********************************/ if (!SetInstallPathValue(&DestinationPath)) { DPRINT1("SetInstallPathValue() failed\n"); MUIDisplayError(ERROR_INITIALIZE_REGISTRY, Ir, POPUP_WAIT_ENTER); return QUIT_PAGE; } + /************************ HACK!!!!!!!!!!! *********************************/ /* Create the default hives */ Status = NtInitializeRegistry(CM_BOOT_FLAG_SETUP); @@ -4193,10 +4193,10 @@ BootLoaderPage(PINPUT_RECORD Ir) CONSOLE_SetStatusText(MUIGetString(STRING_PLEASEWAIT)); RtlFreeUnicodeString(&SystemRootPath); - swprintf(PathBuffer, - L"\\Device\\Harddisk%lu\\Partition%lu", - PartitionList->SystemPartition->DiskEntry->DiskNumber, - PartitionList->SystemPartition->PartitionNumber); + 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); @@ -4438,7 +4438,7 @@ BootLoaderHarddiskVbrPage(PINPUT_RECORD Ir) * * SIDEEFFECTS * Calls InstallVBRToPartition() - * CallsInstallMbrBootCodeToDisk() + * Calls InstallMbrBootCodeToDisk() * * RETURNS * Number of the next page. @@ -4466,16 +4466,16 @@ BootLoaderHarddiskMbrPage(PINPUT_RECORD Ir) } /* Step 2: Write the MBR */ - swprintf(DestinationDevicePathBuffer, - L"\\Device\\Harddisk%d\\Partition0", - PartitionList->SystemPartition->DiskEntry->DiskNumber); + StringCchPrintfW(DestinationDevicePathBuffer, ARRAYSIZE(DestinationDevicePathBuffer), + L"\\Device\\Harddisk%d\\Partition0", + PartitionList->SystemPartition->DiskEntry->DiskNumber); CombinePaths(SourceMbrPathBuffer, ARRAYSIZE(SourceMbrPathBuffer), 2, SourceRootPath.Buffer, L"\\loader\\dosmbr.bin"); if (IsThereAValidBootSector(DestinationDevicePathBuffer)) { /* Save current MBR */ - CombinePaths(DstPath, ARRAYSIZE(DstPath), 2, SystemRootPath.Buffer, L"\\mbr.old"); + CombinePaths(DstPath, ARRAYSIZE(DstPath), 2, SystemRootPath.Buffer, L"mbr.old"); DPRINT1("Save MBR: %S ==> %S\n", DestinationDevicePathBuffer, DstPath); Status = SaveBootSector(DestinationDevicePathBuffer, DstPath, sizeof(PARTITION_SECTOR)); diff --git a/base/setup/usetup/usetup.h b/base/setup/usetup/usetup.h index eeb11545b4..97ac61a63e 100644 --- a/base/setup/usetup/usetup.h +++ b/base/setup/usetup/usetup.h @@ -72,8 +72,6 @@ #include "mui.h" extern HANDLE ProcessHeap; -extern UNICODE_STRING SourceRootPath; -extern UNICODE_STRING SourceRootDir; extern UNICODE_STRING SourcePath; extern BOOLEAN IsUnattendedSetup; extern PWCHAR SelectedLanguageId;
6 years, 2 months
1
0
0
0
03/04: [USETUP] When installing new FreeLDR entries for recognized DOS/OS-2 boot loaders, use distinct OS section names. Also, add detection for the Dell Real-Mode Kernel OS (DRMK).
by Hermès Bélusca-Maïto
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=3cb1392effab614f88b9d…
commit 3cb1392effab614f88b9d044fc09b231aeea8dcd Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org> AuthorDate: Tue Jun 6 23:44:56 2017 +0000 Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org> CommitDate: Sun Oct 14 21:15:55 2018 +0200 [USETUP] When installing new FreeLDR entries for recognized DOS/OS-2 boot loaders, use distinct OS section names. Also, add detection for the Dell Real-Mode Kernel OS (DRMK). svn path=/branches/setup_improvements/; revision=74932 --- base/setup/usetup/bootsup.c | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/base/setup/usetup/bootsup.c b/base/setup/usetup/bootsup.c index 71d0392af9..469693b56a 100644 --- a/base/setup/usetup/bootsup.c +++ b/base/setup/usetup/bootsup.c @@ -2235,7 +2235,7 @@ InstallFatBootcodeToPartition( { DPRINT1("Found COMPAQ MS-DOS 1.x (1.11, 1.12) / MS-DOS 1.25 boot loader\n"); - Section = L"DOS"; + Section = L"CPQDOS"; Description = L"\"COMPAQ MS-DOS 1.x / MS-DOS 1.25\""; BootDrive = L"hd0"; BootPartition = L"1"; @@ -2249,7 +2249,7 @@ InstallFatBootcodeToPartition( { DPRINT1("Found Microsoft DOS or Windows 9x boot loader\n"); - Section = L"DOS"; + Section = L"MSDOS"; Description = L"\"MS-DOS/Windows\""; BootDrive = L"hd0"; BootPartition = L"1"; @@ -2263,7 +2263,7 @@ InstallFatBootcodeToPartition( { DPRINT1("Found IBM PC-DOS or DR-DOS 5.x or IBM OS/2 1.0\n"); - Section = L"DOS"; + Section = L"IBMDOS"; Description = L"\"IBM PC-DOS or DR-DOS 5.x or IBM OS/2 1.0\""; BootDrive = L"hd0"; BootPartition = L"1"; @@ -2276,13 +2276,26 @@ InstallFatBootcodeToPartition( { DPRINT1("Found DR-DOS 3.x\n"); - Section = L"DOS"; + Section = L"DRDOS"; Description = L"\"DR-DOS 3.x\""; BootDrive = L"hd0"; BootPartition = L"1"; BootSector = L"BOOTSECT.DOS"; } else + /* Search for Dell Real-Mode Kernel (DRMK) OS */ + if (DoesFileExist_2(SystemRootPath->Buffer, L"DELLBIO.BIN") == TRUE || + DoesFileExist_2(SystemRootPath->Buffer, L"DELLRMK.BIN") == TRUE) + { + DPRINT1("Found Dell Real-Mode Kernel OS\n"); + + Section = L"DRMK"; + Description = L"\"Dell Real-Mode Kernel OS\""; + BootDrive = L"hd0"; + BootPartition = L"1"; + BootSector = L"BOOTSECT.DOS"; + } + else /* Search for MS OS/2 1.x */ if (DoesFileExist_2(SystemRootPath->Buffer, L"
OS2BOOT.COM
") == TRUE || DoesFileExist_2(SystemRootPath->Buffer, L"
OS2BIO.COM
" ) == TRUE || @@ -2290,7 +2303,7 @@ InstallFatBootcodeToPartition( { DPRINT1("Found MS OS/2 1.x\n"); - Section = L"DOS"; + Section = L"MSOS2"; Description = L"\"MS OS/2 1.x\""; BootDrive = L"hd0"; BootPartition = L"1"; @@ -2304,7 +2317,7 @@ InstallFatBootcodeToPartition( { DPRINT1("Found MS/IBM OS/2\n"); - Section = L"DOS"; + Section = L"IBMOS2"; Description = L"\"MS/IBM OS/2\""; BootDrive = L"hd0"; BootPartition = L"1"; @@ -2316,7 +2329,7 @@ InstallFatBootcodeToPartition( { DPRINT1("Found FreeDOS boot loader\n"); - Section = L"DOS"; + Section = L"FDOS"; Description = L"\"FreeDOS\""; BootDrive = L"hd0"; BootPartition = L"1";
6 years, 2 months
1
0
0
0
02/04: [USETUP] Condense the different InstallFatXYBootSectorToDisk & ToFile functions into a InstallFatXYBootSector() function that is called by both the ToDisk and ToFile flavours.
by Hermès Bélusca-Maïto
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=387e79c92e635f313ab39…
commit 387e79c92e635f313ab39ec7a10cfba1e73818c9 Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org> AuthorDate: Wed May 31 02:03:10 2017 +0000 Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org> CommitDate: Sun Oct 14 21:15:34 2018 +0200 [USETUP] Condense the different InstallFatXYBootSectorToDisk & ToFile functions into a InstallFatXYBootSector() function that is called by both the ToDisk and ToFile flavours. Also, trim any potential trailing path separator from the NT disk partition path before opening the partition object itself for read/write access. svn path=/branches/setup_improvements/; revision=74715 --- base/setup/usetup/bootsup.c | 695 +++++++++++++++++--------------------------- 1 file changed, 260 insertions(+), 435 deletions(-) diff --git a/base/setup/usetup/bootsup.c b/base/setup/usetup/bootsup.c index 0a3e94d54b..71d0392af9 100644 --- a/base/setup/usetup/bootsup.c +++ b/base/setup/usetup/bootsup.c @@ -3,7 +3,8 @@ * PROJECT: ReactOS text-mode setup * FILE: base/setup/usetup/bootsup.c * PURPOSE: Bootloader support functions - * PROGRAMMER: + * PROGRAMMERS: ... + * Hermes Belusca-Maito (hermes.belusca(a)sfr.fr) */ #include "usetup.h" @@ -11,6 +12,20 @@ #define NDEBUG #include <debug.h> +/* + * BIG FIXME!! + * =========== + * + * All that stuff *MUST* go into the fsutil.c module. + * Indeed, all that relates to filesystem formatting details and as such + * *MUST* be abstracted out from this module (bootsup.c). + * However, bootsup.c can still deal with MBR code (actually it'll have + * at some point to share or give it to partlist.c, because when we'll + * support GPT disks, things will change a bit). + * And, bootsup.c can still manage initializing / adding boot entries + * into NTLDR and FREELDR, and installing the latter, and saving the old + * MBR / boot sectors in files. + */ #define SECTORSIZE 512 #include <pshpack1.h> @@ -94,10 +109,21 @@ C_ASSERT(sizeof(BTRFS_BOOTSECTOR) == 3 * 512); #include <poppack.h> -extern PPARTLIST PartitionList; +/* End of BIG FIXME!! */ + /* FUNCTIONS ****************************************************************/ +static VOID +TrimTrailingPathSeparators_UStr( + IN OUT PUNICODE_STRING UnicodeString) +{ + while (UnicodeString->Length >= sizeof(WCHAR) && + UnicodeString->Buffer[UnicodeString->Length / sizeof(WCHAR) - 1] == OBJ_NAME_PATH_SEPARATOR) + { + UnicodeString->Length -= sizeof(WCHAR); + } +} static VOID @@ -829,7 +855,8 @@ UpdateBootIni( BOOLEAN -IsThereAValidBootSector(PWSTR RootPath) +IsThereAValidBootSector( + IN PCWSTR RootPath) { /* * We first demand that the bootsector has a valid signature at its end. @@ -839,9 +866,10 @@ IsThereAValidBootSector(PWSTR RootPath) * non-zero. If both these tests pass, then the bootsector is valid; otherwise * it is invalid and certainly needs to be overwritten. */ + BOOLEAN IsValid = FALSE; NTSTATUS Status; - UNICODE_STRING Name; + UNICODE_STRING RootPartition; OBJECT_ATTRIBUTES ObjectAttributes; IO_STATUS_BLOCK IoStatusBlock; HANDLE FileHandle; @@ -853,12 +881,14 @@ IsThereAValidBootSector(PWSTR RootPath) BootSector = RtlAllocateHeap(ProcessHeap, 0, SECTORSIZE); if (BootSector == NULL) return FALSE; // STATUS_INSUFFICIENT_RESOURCES; + RtlZeroMemory(BootSector, SECTORSIZE); - /* Read current boot sector into buffer */ - RtlInitUnicodeString(&Name, RootPath); + /* Open the root partition - Remove any trailing backslash if needed */ + RtlInitUnicodeString(&RootPartition, RootPath); + TrimTrailingPathSeparators_UStr(&RootPartition); InitializeObjectAttributes(&ObjectAttributes, - &Name, + &RootPartition, OBJ_CASE_INSENSITIVE, NULL, NULL); @@ -872,8 +902,7 @@ IsThereAValidBootSector(PWSTR RootPath) if (!NT_SUCCESS(Status)) goto Quit; - RtlZeroMemory(BootSector, SECTORSIZE); - + /* Read current boot sector into buffer */ FileOffset.QuadPart = 0ULL; Status = NtReadFile(FileHandle, NULL, @@ -903,9 +932,9 @@ Quit: NTSTATUS SaveBootSector( - PWSTR RootPath, - PWSTR DstPath, - ULONG Length) + IN PCWSTR RootPath, + IN PCWSTR DstPath, + IN ULONG Length) { NTSTATUS Status; UNICODE_STRING Name; @@ -920,8 +949,9 @@ SaveBootSector( if (BootSector == NULL) return STATUS_INSUFFICIENT_RESOURCES; - /* Read current boot sector into buffer */ + /* Open the root partition - Remove any trailing backslash if needed */ RtlInitUnicodeString(&Name, RootPath); + TrimTrailingPathSeparators_UStr(&Name); InitializeObjectAttributes(&ObjectAttributes, &Name, @@ -941,6 +971,7 @@ SaveBootSector( return Status; } + /* Read current boot sector into buffer */ FileOffset.QuadPart = 0ULL; Status = NtReadFile(FileHandle, NULL, @@ -1001,11 +1032,10 @@ SaveBootSector( return Status; } - NTSTATUS InstallMbrBootCodeToDisk( - PWSTR SrcPath, - PWSTR RootPath) + IN PCWSTR SrcPath, + IN PCWSTR RootPath) { NTSTATUS Status; UNICODE_STRING Name; @@ -1017,15 +1047,13 @@ InstallMbrBootCodeToDisk( PPARTITION_SECTOR NewBootSector; /* Allocate buffer for original bootsector */ - OrigBootSector = (PPARTITION_SECTOR)RtlAllocateHeap(ProcessHeap, - 0, - sizeof(PARTITION_SECTOR)); + OrigBootSector = RtlAllocateHeap(ProcessHeap, 0, sizeof(PARTITION_SECTOR)); if (OrigBootSector == NULL) return STATUS_INSUFFICIENT_RESOURCES; - /* Read current boot sector into buffer */ - RtlInitUnicodeString(&Name, - RootPath); + /* Open the root partition - Remove any trailing backslash if needed */ + RtlInitUnicodeString(&Name, RootPath); + TrimTrailingPathSeparators_UStr(&Name); InitializeObjectAttributes(&ObjectAttributes, &Name, @@ -1045,6 +1073,7 @@ InstallMbrBootCodeToDisk( return Status; } + /* Read current boot sector into buffer */ FileOffset.QuadPart = 0ULL; Status = NtReadFile(FileHandle, NULL, @@ -1063,9 +1092,7 @@ InstallMbrBootCodeToDisk( } /* Allocate buffer for new bootsector */ - NewBootSector = (PPARTITION_SECTOR)RtlAllocateHeap(ProcessHeap, - 0, - sizeof(PARTITION_SECTOR)); + NewBootSector = RtlAllocateHeap(ProcessHeap, 0, sizeof(PARTITION_SECTOR)); if (NewBootSector == NULL) { RtlFreeHeap(ProcessHeap, 0, OrigBootSector); @@ -1117,7 +1144,8 @@ InstallMbrBootCodeToDisk( */ RtlCopyMemory(&NewBootSector->Signature, &OrigBootSector->Signature, - sizeof(PARTITION_SECTOR) - offsetof(PARTITION_SECTOR, Signature) /* Length of partition table */); + sizeof(PARTITION_SECTOR) - offsetof(PARTITION_SECTOR, Signature) + /* Length of partition table */); /* Free the original boot sector */ RtlFreeHeap(ProcessHeap, 0, OrigBootSector); @@ -1162,11 +1190,12 @@ InstallMbrBootCodeToDisk( return Status; } + static NTSTATUS InstallFat12BootCodeToFloppy( - PWSTR SrcPath, - PWSTR RootPath) + IN PCWSTR SrcPath, + IN PCWSTR RootPath) { NTSTATUS Status; UNICODE_STRING Name; @@ -1182,8 +1211,9 @@ InstallFat12BootCodeToFloppy( if (OrigBootSector == NULL) return STATUS_INSUFFICIENT_RESOURCES; - /* Read current boot sector into buffer */ + /* Open the root partition - Remove any trailing backslash if needed */ RtlInitUnicodeString(&Name, RootPath); + TrimTrailingPathSeparators_UStr(&Name); InitializeObjectAttributes(&ObjectAttributes, &Name, @@ -1203,6 +1233,7 @@ InstallFat12BootCodeToFloppy( return Status; } + /* Read current boot sector into buffer */ FileOffset.QuadPart = 0ULL; Status = NtReadFile(FileHandle, NULL, @@ -1320,10 +1351,10 @@ InstallFat12BootCodeToFloppy( static NTSTATUS -InstallFat16BootCodeToFile( - PWSTR SrcPath, - PWSTR DstPath, - PWSTR RootPath) +InstallFat16BootCode( + IN PCWSTR SrcPath, // FAT16 bootsector source file (on the installation medium) + IN HANDLE DstPath, // Where to save the bootsector built from the source + partition information + IN HANDLE RootPartition) // Partition holding the (old) FAT16 information { NTSTATUS Status; UNICODE_STRING Name; @@ -1334,34 +1365,14 @@ InstallFat16BootCodeToFile( PFAT_BOOTSECTOR OrigBootSector; PFAT_BOOTSECTOR NewBootSector; - /* Allocate buffer for original bootsector */ + /* Allocate a buffer for the original bootsector */ OrigBootSector = RtlAllocateHeap(ProcessHeap, 0, SECTORSIZE); if (OrigBootSector == NULL) return STATUS_INSUFFICIENT_RESOURCES; - /* Read current boot sector into buffer */ - RtlInitUnicodeString(&Name, RootPath); - - InitializeObjectAttributes(&ObjectAttributes, - &Name, - OBJ_CASE_INSENSITIVE, - NULL, - NULL); - - Status = NtOpenFile(&FileHandle, - GENERIC_READ | SYNCHRONIZE, - &ObjectAttributes, - &IoStatusBlock, - 0, - FILE_SYNCHRONOUS_IO_NONALERT); - if (!NT_SUCCESS(Status)) - { - RtlFreeHeap(ProcessHeap, 0, OrigBootSector); - return Status; - } - + /* Read the current partition boot sector into the buffer */ FileOffset.QuadPart = 0ULL; - Status = NtReadFile(FileHandle, + Status = NtReadFile(RootPartition, NULL, NULL, NULL, @@ -1370,14 +1381,13 @@ InstallFat16BootCodeToFile( SECTORSIZE, &FileOffset, NULL); - NtClose(FileHandle); if (!NT_SUCCESS(Status)) { RtlFreeHeap(ProcessHeap, 0, OrigBootSector); return Status; } - /* Allocate buffer for new bootsector */ + /* Allocate a buffer for the new bootsector */ NewBootSector = RtlAllocateHeap(ProcessHeap, 0, SECTORSIZE); if (NewBootSector == NULL) { @@ -1385,15 +1395,13 @@ InstallFat16BootCodeToFile( return STATUS_INSUFFICIENT_RESOURCES; } - /* Read new bootsector from SrcPath */ + /* Read the new bootsector from SrcPath */ RtlInitUnicodeString(&Name, SrcPath); - InitializeObjectAttributes(&ObjectAttributes, &Name, OBJ_CASE_INSENSITIVE, NULL, NULL); - Status = NtOpenFile(&FileHandle, GENERIC_READ | SYNCHRONIZE, &ObjectAttributes, @@ -1425,7 +1433,7 @@ InstallFat16BootCodeToFile( return Status; } - /* Adjust bootsector (copy a part of the FAT BPB) */ + /* Adjust the bootsector (copy a part of the FAT16 BPB) */ memcpy(&NewBootSector->OemName, &OrigBootSector->OemName, FIELD_OFFSET(FAT_BOOTSECTOR, BootCodeAndData) - @@ -1434,43 +1442,17 @@ InstallFat16BootCodeToFile( /* Free the original boot sector */ RtlFreeHeap(ProcessHeap, 0, OrigBootSector); - /* Write new bootsector to DstPath */ - RtlInitUnicodeString(&Name, DstPath); - - InitializeObjectAttributes(&ObjectAttributes, - &Name, - 0, - NULL, - NULL); - - Status = NtCreateFile(&FileHandle, - GENERIC_WRITE | SYNCHRONIZE, - &ObjectAttributes, - &IoStatusBlock, - NULL, - FILE_ATTRIBUTE_NORMAL, - 0, - FILE_OVERWRITE_IF, - FILE_SYNCHRONOUS_IO_NONALERT | FILE_SEQUENTIAL_ONLY, - NULL, - 0); - if (!NT_SUCCESS(Status)) - { - RtlFreeHeap(ProcessHeap, 0, NewBootSector); - return Status; - } - + /* Write the new bootsector to DstPath */ FileOffset.QuadPart = 0ULL; - Status = NtWriteFile(FileHandle, + Status = NtWriteFile(DstPath, NULL, NULL, NULL, &IoStatusBlock, NewBootSector, SECTORSIZE, - NULL, + &FileOffset, NULL); - NtClose(FileHandle); /* Free the new boot sector */ RtlFreeHeap(ProcessHeap, 0, NewBootSector); @@ -1480,164 +1462,124 @@ InstallFat16BootCodeToFile( static NTSTATUS -InstallFat16BootCodeToDisk( - PWSTR SrcPath, - PWSTR RootPath) +InstallFat16BootCodeToFile( + IN PCWSTR SrcPath, + IN PCWSTR DstPath, + IN PCWSTR RootPath) { NTSTATUS Status; UNICODE_STRING Name; OBJECT_ATTRIBUTES ObjectAttributes; IO_STATUS_BLOCK IoStatusBlock; - HANDLE FileHandle; - LARGE_INTEGER FileOffset; - PFAT_BOOTSECTOR OrigBootSector; - PFAT_BOOTSECTOR NewBootSector; - - /* Allocate buffer for original bootsector */ - OrigBootSector = RtlAllocateHeap(ProcessHeap, 0, SECTORSIZE); - if (OrigBootSector == NULL) - return STATUS_INSUFFICIENT_RESOURCES; + HANDLE PartitionHandle, FileHandle; - /* Read current boot sector into buffer */ + /* + * Open the root partition from which the boot sector + * parameters will be obtained. + * Remove any trailing backslash if needed. + */ RtlInitUnicodeString(&Name, RootPath); + TrimTrailingPathSeparators_UStr(&Name); InitializeObjectAttributes(&ObjectAttributes, &Name, OBJ_CASE_INSENSITIVE, NULL, NULL); - - Status = NtOpenFile(&FileHandle, + Status = NtOpenFile(&PartitionHandle, GENERIC_READ | SYNCHRONIZE, &ObjectAttributes, &IoStatusBlock, 0, - FILE_SYNCHRONOUS_IO_NONALERT); + FILE_SYNCHRONOUS_IO_NONALERT /* | FILE_SEQUENTIAL_ONLY */); if (!NT_SUCCESS(Status)) - { - RtlFreeHeap(ProcessHeap, 0, OrigBootSector); - return Status; - } - - FileOffset.QuadPart = 0ULL; - Status = NtReadFile(FileHandle, - NULL, - NULL, - NULL, - &IoStatusBlock, - OrigBootSector, - SECTORSIZE, - &FileOffset, - NULL); - NtClose(FileHandle); - if (!NT_SUCCESS(Status)) - { - RtlFreeHeap(ProcessHeap, 0, OrigBootSector); return Status; - } - - /* Allocate buffer for new bootsector */ - NewBootSector = RtlAllocateHeap(ProcessHeap, 0, SECTORSIZE); - if (NewBootSector == NULL) - { - RtlFreeHeap(ProcessHeap, 0, OrigBootSector); - return STATUS_INSUFFICIENT_RESOURCES; - } - - /* Read new bootsector from SrcPath */ - RtlInitUnicodeString(&Name, SrcPath); + /* Open or create the file where the new bootsector will be saved */ + RtlInitUnicodeString(&Name, DstPath); InitializeObjectAttributes(&ObjectAttributes, &Name, - OBJ_CASE_INSENSITIVE, + 0, // OBJ_CASE_INSENSITIVE, NULL, NULL); - - Status = NtOpenFile(&FileHandle, - GENERIC_READ | SYNCHRONIZE, - &ObjectAttributes, - &IoStatusBlock, - 0, - FILE_SYNCHRONOUS_IO_NONALERT); + Status = NtCreateFile(&FileHandle, + GENERIC_WRITE | SYNCHRONIZE, + &ObjectAttributes, + &IoStatusBlock, + NULL, + FILE_ATTRIBUTE_NORMAL, + 0, + FILE_OVERWRITE_IF, + FILE_SYNCHRONOUS_IO_NONALERT | FILE_SEQUENTIAL_ONLY, + NULL, + 0); if (!NT_SUCCESS(Status)) { - RtlFreeHeap(ProcessHeap, 0, OrigBootSector); - RtlFreeHeap(ProcessHeap, 0, NewBootSector); + DPRINT1("NtCreateFile() failed (Status %lx)\n", Status); + NtClose(PartitionHandle); return Status; } - Status = NtReadFile(FileHandle, - NULL, - NULL, - NULL, - &IoStatusBlock, - NewBootSector, - SECTORSIZE, - NULL, - NULL); + /* Install the FAT16 boot sector */ + Status = InstallFat16BootCode(SrcPath, FileHandle, PartitionHandle); + + /* Close the file and the partition */ NtClose(FileHandle); - if (!NT_SUCCESS(Status)) - { - RtlFreeHeap(ProcessHeap, 0, OrigBootSector); - RtlFreeHeap(ProcessHeap, 0, NewBootSector); - return Status; - } + NtClose(PartitionHandle); - /* Adjust bootsector (copy a part of the FAT16 BPB) */ - memcpy(&NewBootSector->OemName, - &OrigBootSector->OemName, - FIELD_OFFSET(FAT_BOOTSECTOR, BootCodeAndData) - - FIELD_OFFSET(FAT_BOOTSECTOR, OemName)); + return Status; +} - /* Free the original boot sector */ - RtlFreeHeap(ProcessHeap, 0, OrigBootSector); +static +NTSTATUS +InstallFat16BootCodeToDisk( + IN PCWSTR SrcPath, + IN PCWSTR RootPath) +{ + NTSTATUS Status; + UNICODE_STRING Name; + OBJECT_ATTRIBUTES ObjectAttributes; + IO_STATUS_BLOCK IoStatusBlock; + HANDLE PartitionHandle; - /* Write new bootsector to RootPath */ + /* + * Open the root partition from which the boot sector parameters will be + * obtained; this is also where we will write the updated boot sector. + * Remove any trailing backslash if needed. + */ RtlInitUnicodeString(&Name, RootPath); + TrimTrailingPathSeparators_UStr(&Name); InitializeObjectAttributes(&ObjectAttributes, &Name, - 0, + OBJ_CASE_INSENSITIVE, NULL, NULL); - - Status = NtOpenFile(&FileHandle, - GENERIC_WRITE | SYNCHRONIZE, + Status = NtOpenFile(&PartitionHandle, + GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, &ObjectAttributes, &IoStatusBlock, 0, FILE_SYNCHRONOUS_IO_NONALERT | FILE_SEQUENTIAL_ONLY); if (!NT_SUCCESS(Status)) - { - DPRINT1("NtOpenFile() failed (Status %lx)\n", Status); - RtlFreeHeap(ProcessHeap, 0, NewBootSector); return Status; - } - FileOffset.QuadPart = 0ULL; - Status = NtWriteFile(FileHandle, - NULL, - NULL, - NULL, - &IoStatusBlock, - NewBootSector, - SECTORSIZE, - &FileOffset, - NULL); - NtClose(FileHandle); + /* Install the FAT16 boot sector */ + Status = InstallFat16BootCode(SrcPath, PartitionHandle, PartitionHandle); - /* Free the new boot sector */ - RtlFreeHeap(ProcessHeap, 0, NewBootSector); + /* Close the partition */ + NtClose(PartitionHandle); return Status; } + static NTSTATUS -InstallFat32BootCodeToFile( - PWSTR SrcPath, - PWSTR DstPath, - PWSTR RootPath) +InstallFat32BootCode( + IN PCWSTR SrcPath, // FAT32 bootsector source file (on the installation medium) + IN HANDLE DstPath, // Where to save the bootsector built from the source + partition information + IN HANDLE RootPartition) // Partition holding the (old) FAT32 information { NTSTATUS Status; UNICODE_STRING Name; @@ -1647,51 +1589,31 @@ InstallFat32BootCodeToFile( LARGE_INTEGER FileOffset; PFAT32_BOOTSECTOR OrigBootSector; PFAT32_BOOTSECTOR NewBootSector; + USHORT BackupBootSector; - /* Allocate buffer for original bootsector */ + /* Allocate a buffer for the original bootsector */ OrigBootSector = RtlAllocateHeap(ProcessHeap, 0, SECTORSIZE); if (OrigBootSector == NULL) return STATUS_INSUFFICIENT_RESOURCES; - /* Read current boot sector into buffer */ - RtlInitUnicodeString(&Name, RootPath); - - InitializeObjectAttributes(&ObjectAttributes, - &Name, - OBJ_CASE_INSENSITIVE, - NULL, - NULL); - - Status = NtOpenFile(&FileHandle, - GENERIC_READ | SYNCHRONIZE, - &ObjectAttributes, - &IoStatusBlock, - 0, - FILE_SYNCHRONOUS_IO_NONALERT); - if (!NT_SUCCESS(Status)) - { - RtlFreeHeap(ProcessHeap, 0, OrigBootSector); - return Status; - } - + /* Read the current boot sector into the buffer */ FileOffset.QuadPart = 0ULL; - Status = NtReadFile(FileHandle, + Status = NtReadFile(RootPartition, NULL, NULL, NULL, &IoStatusBlock, OrigBootSector, SECTORSIZE, - NULL, + &FileOffset, NULL); - NtClose(FileHandle); if (!NT_SUCCESS(Status)) { RtlFreeHeap(ProcessHeap, 0, OrigBootSector); return Status; } - /* Allocate buffer for new bootsector (2 sectors) */ + /* Allocate a buffer for the new bootsector (2 sectors) */ NewBootSector = RtlAllocateHeap(ProcessHeap, 0, 2 * SECTORSIZE); if (NewBootSector == NULL) { @@ -1699,15 +1621,13 @@ InstallFat32BootCodeToFile( return STATUS_INSUFFICIENT_RESOURCES; } - /* Read new bootsector from SrcPath */ + /* Read the new bootsector from SrcPath */ RtlInitUnicodeString(&Name, SrcPath); - InitializeObjectAttributes(&ObjectAttributes, &Name, OBJ_CASE_INSENSITIVE, NULL, NULL); - Status = NtOpenFile(&FileHandle, GENERIC_READ | SYNCHRONIZE, &ObjectAttributes, @@ -1721,6 +1641,7 @@ InstallFat32BootCodeToFile( return Status; } + FileOffset.QuadPart = 0ULL; Status = NtReadFile(FileHandle, NULL, NULL, @@ -1728,7 +1649,7 @@ InstallFat32BootCodeToFile( &IoStatusBlock, NewBootSector, 2 * SECTORSIZE, - NULL, + &FileOffset, NULL); NtClose(FileHandle); if (!NT_SUCCESS(Status)) @@ -1738,84 +1659,76 @@ InstallFat32BootCodeToFile( return Status; } - /* Adjust bootsector (copy a part of the FAT32 BPB) */ + /* Adjust the bootsector (copy a part of the FAT32 BPB) */ memcpy(&NewBootSector->OemName, &OrigBootSector->OemName, FIELD_OFFSET(FAT32_BOOTSECTOR, BootCodeAndData) - FIELD_OFFSET(FAT32_BOOTSECTOR, OemName)); - /* Disable the backup boot sector */ - NewBootSector->BackupBootSector = 0; + /* + * We know we copy the boot code to a file only when DstPath != RootPartition, + * otherwise the boot code is copied to the specified root partition. + */ + if (DstPath != RootPartition) + { + /* Copy to a file: Disable the backup boot sector */ + NewBootSector->BackupBootSector = 0; + } + else + { + /* Copy to a disk: Get the location of the backup boot sector */ + BackupBootSector = OrigBootSector->BackupBootSector; + } /* Free the original boot sector */ RtlFreeHeap(ProcessHeap, 0, OrigBootSector); - /* Write the first sector of the new bootcode to DstPath */ - RtlInitUnicodeString(&Name, DstPath); - - InitializeObjectAttributes(&ObjectAttributes, - &Name, - 0, - NULL, - NULL); - - Status = NtCreateFile(&FileHandle, - GENERIC_WRITE | SYNCHRONIZE, - &ObjectAttributes, - &IoStatusBlock, - NULL, - FILE_ATTRIBUTE_NORMAL, - 0, - FILE_SUPERSEDE, - FILE_SYNCHRONOUS_IO_NONALERT | FILE_SEQUENTIAL_ONLY, - NULL, - 0); - if (!NT_SUCCESS(Status)) - { - RtlFreeHeap(ProcessHeap, 0, NewBootSector); - return Status; - } - + /* Write the first sector of the new bootcode to DstPath sector 0 */ FileOffset.QuadPart = 0ULL; - Status = NtWriteFile(FileHandle, + Status = NtWriteFile(DstPath, NULL, NULL, NULL, &IoStatusBlock, NewBootSector, SECTORSIZE, - NULL, + &FileOffset, NULL); - NtClose(FileHandle); if (!NT_SUCCESS(Status)) { + DPRINT1("NtWriteFile() failed (Status %lx)\n", Status); RtlFreeHeap(ProcessHeap, 0, NewBootSector); return Status; } - /* Write the second sector of the new bootcode to boot disk sector 14 */ - RtlInitUnicodeString(&Name, RootPath); - - InitializeObjectAttributes(&ObjectAttributes, - &Name, - 0, - NULL, - NULL); - - Status = NtOpenFile(&FileHandle, - GENERIC_WRITE | SYNCHRONIZE, - &ObjectAttributes, - &IoStatusBlock, - 0, - FILE_SYNCHRONOUS_IO_NONALERT); - if (!NT_SUCCESS(Status)) + if (DstPath == RootPartition) { - RtlFreeHeap(ProcessHeap, 0, NewBootSector); - return Status; + /* Copy to a disk: Write the backup boot sector */ + if ((BackupBootSector != 0x0000) && (BackupBootSector != 0xFFFF)) + { + FileOffset.QuadPart = (ULONGLONG)((ULONG)BackupBootSector * SECTORSIZE); + Status = NtWriteFile(DstPath, + NULL, + NULL, + NULL, + &IoStatusBlock, + NewBootSector, + SECTORSIZE, + &FileOffset, + NULL); + if (!NT_SUCCESS(Status)) + { + DPRINT1("NtWriteFile() failed (Status %lx)\n", Status); + RtlFreeHeap(ProcessHeap, 0, NewBootSector); + return Status; + } + } } - FileOffset.QuadPart = (ULONGLONG)(14 * SECTORSIZE); - Status = NtWriteFile(FileHandle, + /* Write the second sector of the new bootcode to boot disk sector 14 */ + // FileOffset.QuadPart = (ULONGLONG)(14 * SECTORSIZE); + FileOffset.QuadPart = 14 * SECTORSIZE; + Status = NtWriteFile(DstPath, // or really RootPartition ??? NULL, NULL, NULL, @@ -1826,8 +1739,8 @@ InstallFat32BootCodeToFile( NULL); if (!NT_SUCCESS(Status)) { + DPRINT1("NtWriteFile() failed (Status %lx)\n", Status); } - NtClose(FileHandle); /* Free the new boot sector */ RtlFreeHeap(ProcessHeap, 0, NewBootSector); @@ -1837,205 +1750,117 @@ InstallFat32BootCodeToFile( static NTSTATUS -InstallFat32BootCodeToDisk( - PWSTR SrcPath, - PWSTR RootPath) +InstallFat32BootCodeToFile( + IN PCWSTR SrcPath, + IN PCWSTR DstPath, + IN PCWSTR RootPath) { NTSTATUS Status; UNICODE_STRING Name; OBJECT_ATTRIBUTES ObjectAttributes; IO_STATUS_BLOCK IoStatusBlock; - HANDLE FileHandle; - LARGE_INTEGER FileOffset; - PFAT32_BOOTSECTOR OrigBootSector; - PFAT32_BOOTSECTOR NewBootSector; - USHORT BackupBootSector; - - /* Allocate buffer for original bootsector */ - OrigBootSector = RtlAllocateHeap(ProcessHeap, 0, SECTORSIZE); - if (OrigBootSector == NULL) - return STATUS_INSUFFICIENT_RESOURCES; + HANDLE PartitionHandle, FileHandle; - /* Read current boot sector into buffer */ + /* + * Open the root partition from which the boot sector parameters + * will be obtained. + * FIXME? It might be possible that we need to also open it for writing + * access in case we really need to still write the second portion of + * the boot sector ???? + * + * Remove any trailing backslash if needed. + */ RtlInitUnicodeString(&Name, RootPath); + TrimTrailingPathSeparators_UStr(&Name); InitializeObjectAttributes(&ObjectAttributes, &Name, OBJ_CASE_INSENSITIVE, NULL, NULL); - - Status = NtOpenFile(&FileHandle, + Status = NtOpenFile(&PartitionHandle, GENERIC_READ | SYNCHRONIZE, &ObjectAttributes, &IoStatusBlock, 0, - FILE_SYNCHRONOUS_IO_NONALERT); + FILE_SYNCHRONOUS_IO_NONALERT /* | FILE_SEQUENTIAL_ONLY */); if (!NT_SUCCESS(Status)) - { - RtlFreeHeap(ProcessHeap, 0, OrigBootSector); return Status; - } - - FileOffset.QuadPart = 0ULL; - Status = NtReadFile(FileHandle, - NULL, - NULL, - NULL, - &IoStatusBlock, - OrigBootSector, - SECTORSIZE, - &FileOffset, - NULL); - NtClose(FileHandle); - if (!NT_SUCCESS(Status)) - { - RtlFreeHeap(ProcessHeap, 0, OrigBootSector); - return Status; - } - - - /* Allocate buffer for new bootsector (2 sectors) */ - NewBootSector = RtlAllocateHeap(ProcessHeap, 0, 2 * SECTORSIZE); - if (NewBootSector == NULL) - { - RtlFreeHeap(ProcessHeap, 0, OrigBootSector); - return STATUS_INSUFFICIENT_RESOURCES; - } - - /* Read new bootsector from SrcPath */ - RtlInitUnicodeString(&Name, SrcPath); + /* Open or create the file where (the first sector of ????) the new bootsector will be saved */ + RtlInitUnicodeString(&Name, DstPath); InitializeObjectAttributes(&ObjectAttributes, &Name, - OBJ_CASE_INSENSITIVE, + 0, // OBJ_CASE_INSENSITIVE, NULL, NULL); - - Status = NtOpenFile(&FileHandle, - GENERIC_READ | SYNCHRONIZE, - &ObjectAttributes, - &IoStatusBlock, - 0, - FILE_SYNCHRONOUS_IO_NONALERT); + Status = NtCreateFile(&FileHandle, + GENERIC_WRITE | SYNCHRONIZE, + &ObjectAttributes, + &IoStatusBlock, + NULL, + FILE_ATTRIBUTE_NORMAL, + 0, + FILE_SUPERSEDE, // FILE_OVERWRITE_IF, <- is used for FAT16 + FILE_SYNCHRONOUS_IO_NONALERT | FILE_SEQUENTIAL_ONLY, + NULL, + 0); if (!NT_SUCCESS(Status)) { - RtlFreeHeap(ProcessHeap, 0, OrigBootSector); - RtlFreeHeap(ProcessHeap, 0, NewBootSector); + DPRINT1("NtCreateFile() failed (Status %lx)\n", Status); + NtClose(PartitionHandle); return Status; } - Status = NtReadFile(FileHandle, - NULL, - NULL, - NULL, - &IoStatusBlock, - NewBootSector, - 2 * SECTORSIZE, - NULL, - NULL); - NtClose(FileHandle); - if (!NT_SUCCESS(Status)) - { - RtlFreeHeap(ProcessHeap, 0, OrigBootSector); - RtlFreeHeap(ProcessHeap, 0, NewBootSector); - return Status; - } + /* Install the FAT32 boot sector */ + Status = InstallFat32BootCode(SrcPath, FileHandle, PartitionHandle); - /* Adjust bootsector (copy a part of the FAT32 BPB) */ - memcpy(&NewBootSector->OemName, - &OrigBootSector->OemName, - FIELD_OFFSET(FAT32_BOOTSECTOR, BootCodeAndData) - - FIELD_OFFSET(FAT32_BOOTSECTOR, OemName)); + /* Close the file and the partition */ + NtClose(FileHandle); + NtClose(PartitionHandle); - /* Get the location of the backup boot sector */ - BackupBootSector = OrigBootSector->BackupBootSector; + return Status; +} - /* Free the original boot sector */ - RtlFreeHeap(ProcessHeap, 0, OrigBootSector); +static +NTSTATUS +InstallFat32BootCodeToDisk( + IN PCWSTR SrcPath, + IN PCWSTR RootPath) +{ + NTSTATUS Status; + UNICODE_STRING Name; + OBJECT_ATTRIBUTES ObjectAttributes; + IO_STATUS_BLOCK IoStatusBlock; + HANDLE PartitionHandle; - /* Write the first sector of the new bootcode to DstPath */ + /* + * Open the root partition from which the boot sector parameters will be + * obtained; this is also where we will write the updated boot sector. + * Remove any trailing backslash if needed. + */ RtlInitUnicodeString(&Name, RootPath); + TrimTrailingPathSeparators_UStr(&Name); InitializeObjectAttributes(&ObjectAttributes, &Name, - 0, + OBJ_CASE_INSENSITIVE, NULL, NULL); - - Status = NtOpenFile(&FileHandle, - GENERIC_WRITE | SYNCHRONIZE, + Status = NtOpenFile(&PartitionHandle, + GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, &ObjectAttributes, &IoStatusBlock, 0, - FILE_SYNCHRONOUS_IO_NONALERT | FILE_SEQUENTIAL_ONLY); - if (!NT_SUCCESS(Status)) - { - DPRINT1("NtOpenFile() failed (Status %lx)\n", Status); - RtlFreeHeap(ProcessHeap, 0, NewBootSector); - return Status; - } - - /* Write sector 0 */ - FileOffset.QuadPart = 0ULL; - Status = NtWriteFile(FileHandle, - NULL, - NULL, - NULL, - &IoStatusBlock, - NewBootSector, - SECTORSIZE, - &FileOffset, - NULL); + FILE_SYNCHRONOUS_IO_NONALERT /* | FILE_SEQUENTIAL_ONLY */); if (!NT_SUCCESS(Status)) - { - DPRINT1("NtWriteFile() failed (Status %lx)\n", Status); - NtClose(FileHandle); - RtlFreeHeap(ProcessHeap, 0, NewBootSector); return Status; - } - /* Write backup boot sector */ - if ((BackupBootSector != 0x0000) && (BackupBootSector != 0xFFFF)) - { - FileOffset.QuadPart = (ULONGLONG)((ULONG)BackupBootSector * SECTORSIZE); - Status = NtWriteFile(FileHandle, - NULL, - NULL, - NULL, - &IoStatusBlock, - NewBootSector, - SECTORSIZE, - &FileOffset, - NULL); - if (!NT_SUCCESS(Status)) - { - DPRINT1("NtWriteFile() failed (Status %lx)\n", Status); - NtClose(FileHandle); - RtlFreeHeap(ProcessHeap, 0, NewBootSector); - return Status; - } - } + /* Install the FAT32 boot sector */ + Status = InstallFat32BootCode(SrcPath, PartitionHandle, PartitionHandle); - /* Write sector 14 */ - FileOffset.QuadPart = 14 * SECTORSIZE; - Status = NtWriteFile(FileHandle, - NULL, - NULL, - NULL, - &IoStatusBlock, - ((PUCHAR)NewBootSector + SECTORSIZE), - SECTORSIZE, - &FileOffset, - NULL); - if (!NT_SUCCESS(Status)) - { - DPRINT1("NtWriteFile() failed (Status %lx)\n", Status); - } - NtClose(FileHandle); - - /* Free the new boot sector */ - RtlFreeHeap(ProcessHeap, 0, NewBootSector); + /* Close the partition */ + NtClose(PartitionHandle); return Status; } @@ -2063,8 +1888,9 @@ InstallBtrfsBootCodeToDisk( if (OrigBootSector == NULL) return STATUS_INSUFFICIENT_RESOURCES; - /* Read current boot sector into buffer */ + /* Open the root partition - Remove any trailing backslash if needed */ RtlInitUnicodeString(&Name, RootPath); + TrimTrailingPathSeparators_UStr(&Name); InitializeObjectAttributes(&ObjectAttributes, &Name, @@ -2084,6 +1910,7 @@ InstallBtrfsBootCodeToDisk( return Status; } + /* Read current boot sector into buffer */ FileOffset.QuadPart = 0ULL; Status = NtReadFile(FileHandle, NULL, @@ -2156,8 +1983,6 @@ InstallBtrfsBootCodeToDisk( FIELD_OFFSET(FAT32_BOOTSECTOR, BootCodeAndData) - FIELD_OFFSET(FAT32_BOOTSECTOR, OemName)); - NewBootSector->HiddenSectors = PartitionList->CurrentDisk->SectorsPerTrack; - /* Get the location of the backup boot sector */ BackupBootSector = OrigBootSector->BackupBootSector;
6 years, 2 months
1
0
0
0
01/04: [USETUP] Move some functions around, but no functional code changes otherwise.
by Hermès Bélusca-Maïto
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=f13a379153e3b42a49ee2…
commit f13a379153e3b42a49ee22c4d21102db5329d064 Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org> AuthorDate: Wed May 31 01:47:39 2017 +0000 Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org> CommitDate: Sun Oct 14 21:14:31 2018 +0200 [USETUP] Move some functions around, but no functional code changes otherwise. svn path=/branches/setup_improvements/; revision=74714 --- base/setup/usetup/bootsup.c | 736 ++++++++++++++++++++++---------------------- 1 file changed, 370 insertions(+), 366 deletions(-) diff --git a/base/setup/usetup/bootsup.c b/base/setup/usetup/bootsup.c index 37cd680029..0a3e94d54b 100644 --- a/base/setup/usetup/bootsup.c +++ b/base/setup/usetup/bootsup.c @@ -630,6 +630,204 @@ UpdateFreeLoaderIni( return STATUS_SUCCESS; } +static +NTSTATUS +UnprotectBootIni( + PWSTR FileName, + PULONG Attributes) +{ + NTSTATUS Status; + UNICODE_STRING Name; + OBJECT_ATTRIBUTES ObjectAttributes; + IO_STATUS_BLOCK IoStatusBlock; + FILE_BASIC_INFORMATION FileInfo; + HANDLE FileHandle; + + RtlInitUnicodeString(&Name, FileName); + + InitializeObjectAttributes(&ObjectAttributes, + &Name, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + + Status = NtOpenFile(&FileHandle, + GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, + &ObjectAttributes, + &IoStatusBlock, + 0, + FILE_SYNCHRONOUS_IO_NONALERT); + if (Status == STATUS_NO_SUCH_FILE) + { + DPRINT1("NtOpenFile() failed (Status %lx)\n", Status); + *Attributes = 0; + return STATUS_SUCCESS; + } + if (!NT_SUCCESS(Status)) + { + DPRINT1("NtOpenFile() failed (Status %lx)\n", Status); + return Status; + } + + Status = NtQueryInformationFile(FileHandle, + &IoStatusBlock, + &FileInfo, + sizeof(FILE_BASIC_INFORMATION), + FileBasicInformation); + if (!NT_SUCCESS(Status)) + { + DPRINT1("NtQueryInformationFile() failed (Status %lx)\n", Status); + NtClose(FileHandle); + return Status; + } + + *Attributes = FileInfo.FileAttributes; + + /* Delete attributes SYSTEM, HIDDEN and READONLY */ + FileInfo.FileAttributes = FileInfo.FileAttributes & + ~(FILE_ATTRIBUTE_SYSTEM | + FILE_ATTRIBUTE_HIDDEN | + FILE_ATTRIBUTE_READONLY); + + Status = NtSetInformationFile(FileHandle, + &IoStatusBlock, + &FileInfo, + sizeof(FILE_BASIC_INFORMATION), + FileBasicInformation); + if (!NT_SUCCESS(Status)) + { + DPRINT1("NtSetInformationFile() failed (Status %lx)\n", Status); + } + + NtClose(FileHandle); + return Status; +} + +static +NTSTATUS +ProtectBootIni( + PWSTR FileName, + ULONG Attributes) +{ + NTSTATUS Status; + UNICODE_STRING Name; + OBJECT_ATTRIBUTES ObjectAttributes; + IO_STATUS_BLOCK IoStatusBlock; + FILE_BASIC_INFORMATION FileInfo; + HANDLE FileHandle; + + RtlInitUnicodeString(&Name, FileName); + + InitializeObjectAttributes(&ObjectAttributes, + &Name, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + + Status = NtOpenFile(&FileHandle, + GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, + &ObjectAttributes, + &IoStatusBlock, + 0, + FILE_SYNCHRONOUS_IO_NONALERT); + if (!NT_SUCCESS(Status)) + { + DPRINT1("NtOpenFile() failed (Status %lx)\n", Status); + return Status; + } + + Status = NtQueryInformationFile(FileHandle, + &IoStatusBlock, + &FileInfo, + sizeof(FILE_BASIC_INFORMATION), + FileBasicInformation); + if (!NT_SUCCESS(Status)) + { + DPRINT1("NtQueryInformationFile() failed (Status %lx)\n", Status); + NtClose(FileHandle); + return Status; + } + + FileInfo.FileAttributes = FileInfo.FileAttributes | Attributes; + + Status = NtSetInformationFile(FileHandle, + &IoStatusBlock, + &FileInfo, + sizeof(FILE_BASIC_INFORMATION), + FileBasicInformation); + if (!NT_SUCCESS(Status)) + { + DPRINT1("NtSetInformationFile() failed (Status %lx)\n", Status); + } + + NtClose(FileHandle); + return Status; +} + +static +NTSTATUS +UpdateBootIni( + PWSTR BootIniPath, + PWSTR EntryName, + PWSTR EntryValue) +{ + NTSTATUS Status; + PINICACHE Cache = NULL; + PINICACHESECTION Section = NULL; + ULONG FileAttribute; + PWCHAR OldValue = NULL; + + Status = IniCacheLoad(&Cache, BootIniPath, FALSE); + if (!NT_SUCCESS(Status)) + { + return Status; + } + + Section = IniCacheGetSection(Cache, + L"operating systems"); + if (Section == NULL) + { + IniCacheDestroy(Cache); + return STATUS_UNSUCCESSFUL; + } + + /* Check - maybe record already exists */ + Status = IniCacheGetKey(Section, EntryName, &OldValue); + + /* If either key was not found, or contains something else - add new one */ + if (!NT_SUCCESS(Status) || wcscmp(OldValue, EntryValue)) + { + IniCacheInsertKey(Section, + NULL, + INSERT_LAST, + EntryName, + EntryValue); + } + + Status = UnprotectBootIni(BootIniPath, + &FileAttribute); + if (!NT_SUCCESS(Status)) + { + IniCacheDestroy(Cache); + return Status; + } + + Status = IniCacheSave(Cache, BootIniPath); + if (!NT_SUCCESS(Status)) + { + IniCacheDestroy(Cache); + return Status; + } + + FileAttribute |= (FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_READONLY); + Status = ProtectBootIni(BootIniPath, FileAttribute); + + IniCacheDestroy(Cache); + + return Status; +} + + BOOLEAN IsThereAValidBootSector(PWSTR RootPath) { @@ -803,11 +1001,10 @@ SaveBootSector( return Status; } -static + NTSTATUS -InstallFat16BootCodeToFile( +InstallMbrBootCodeToDisk( PWSTR SrcPath, - PWSTR DstPath, PWSTR RootPath) { NTSTATUS Status; @@ -816,16 +1013,19 @@ InstallFat16BootCodeToFile( IO_STATUS_BLOCK IoStatusBlock; HANDLE FileHandle; LARGE_INTEGER FileOffset; - PFAT_BOOTSECTOR OrigBootSector; - PFAT_BOOTSECTOR NewBootSector; + PPARTITION_SECTOR OrigBootSector; + PPARTITION_SECTOR NewBootSector; /* Allocate buffer for original bootsector */ - OrigBootSector = RtlAllocateHeap(ProcessHeap, 0, SECTORSIZE); + OrigBootSector = (PPARTITION_SECTOR)RtlAllocateHeap(ProcessHeap, + 0, + sizeof(PARTITION_SECTOR)); if (OrigBootSector == NULL) return STATUS_INSUFFICIENT_RESOURCES; /* Read current boot sector into buffer */ - RtlInitUnicodeString(&Name, RootPath); + RtlInitUnicodeString(&Name, + RootPath); InitializeObjectAttributes(&ObjectAttributes, &Name, @@ -852,7 +1052,7 @@ InstallFat16BootCodeToFile( NULL, &IoStatusBlock, OrigBootSector, - SECTORSIZE, + sizeof(PARTITION_SECTOR), &FileOffset, NULL); NtClose(FileHandle); @@ -863,7 +1063,9 @@ InstallFat16BootCodeToFile( } /* Allocate buffer for new bootsector */ - NewBootSector = RtlAllocateHeap(ProcessHeap, 0, SECTORSIZE); + NewBootSector = (PPARTITION_SECTOR)RtlAllocateHeap(ProcessHeap, + 0, + sizeof(PARTITION_SECTOR)); if (NewBootSector == NULL) { RtlFreeHeap(ProcessHeap, 0, OrigBootSector); @@ -892,15 +1094,14 @@ InstallFat16BootCodeToFile( return Status; } - FileOffset.QuadPart = 0ULL; Status = NtReadFile(FileHandle, NULL, NULL, NULL, &IoStatusBlock, NewBootSector, - SECTORSIZE, - &FileOffset, + sizeof(PARTITION_SECTOR), + NULL, NULL); NtClose(FileHandle); if (!NT_SUCCESS(Status)) @@ -910,17 +1111,19 @@ InstallFat16BootCodeToFile( return Status; } - /* Adjust bootsector (copy a part of the FAT BPB) */ - memcpy(&NewBootSector->OemName, - &OrigBootSector->OemName, - FIELD_OFFSET(FAT_BOOTSECTOR, BootCodeAndData) - - FIELD_OFFSET(FAT_BOOTSECTOR, OemName)); + /* + * Copy the disk signature, the reserved fields and + * the partition table from the old MBR to the new one. + */ + RtlCopyMemory(&NewBootSector->Signature, + &OrigBootSector->Signature, + sizeof(PARTITION_SECTOR) - offsetof(PARTITION_SECTOR, Signature) /* Length of partition table */); /* Free the original boot sector */ RtlFreeHeap(ProcessHeap, 0, OrigBootSector); - /* Write new bootsector to DstPath */ - RtlInitUnicodeString(&Name, DstPath); + /* Write new bootsector to RootPath */ + RtlInitUnicodeString(&Name, RootPath); InitializeObjectAttributes(&ObjectAttributes, &Name, @@ -928,31 +1131,28 @@ InstallFat16BootCodeToFile( NULL, NULL); - Status = NtCreateFile(&FileHandle, - GENERIC_WRITE | SYNCHRONIZE, - &ObjectAttributes, - &IoStatusBlock, - NULL, - FILE_ATTRIBUTE_NORMAL, - 0, - FILE_OVERWRITE_IF, - FILE_SYNCHRONOUS_IO_NONALERT | FILE_SEQUENTIAL_ONLY, - NULL, - 0); + Status = NtOpenFile(&FileHandle, + GENERIC_WRITE | SYNCHRONIZE, + &ObjectAttributes, + &IoStatusBlock, + 0, + FILE_SYNCHRONOUS_IO_NONALERT | FILE_SEQUENTIAL_ONLY); if (!NT_SUCCESS(Status)) { + DPRINT1("NtOpenFile() failed (Status %lx)\n", Status); RtlFreeHeap(ProcessHeap, 0, NewBootSector); return Status; } + FileOffset.QuadPart = 0ULL; Status = NtWriteFile(FileHandle, NULL, NULL, NULL, &IoStatusBlock, NewBootSector, - SECTORSIZE, - NULL, + sizeof(PARTITION_SECTOR), + &FileOffset, NULL); NtClose(FileHandle); @@ -964,9 +1164,8 @@ InstallFat16BootCodeToFile( static NTSTATUS -InstallFat32BootCodeToFile( +InstallFat12BootCodeToFloppy( PWSTR SrcPath, - PWSTR DstPath, PWSTR RootPath) { NTSTATUS Status; @@ -975,8 +1174,8 @@ InstallFat32BootCodeToFile( IO_STATUS_BLOCK IoStatusBlock; HANDLE FileHandle; LARGE_INTEGER FileOffset; - PFAT32_BOOTSECTOR OrigBootSector; - PFAT32_BOOTSECTOR NewBootSector; + PFAT_BOOTSECTOR OrigBootSector; + PFAT_BOOTSECTOR NewBootSector; /* Allocate buffer for original bootsector */ OrigBootSector = RtlAllocateHeap(ProcessHeap, 0, SECTORSIZE); @@ -1004,6 +1203,7 @@ InstallFat32BootCodeToFile( return Status; } + FileOffset.QuadPart = 0ULL; Status = NtReadFile(FileHandle, NULL, NULL, @@ -1011,7 +1211,7 @@ InstallFat32BootCodeToFile( &IoStatusBlock, OrigBootSector, SECTORSIZE, - NULL, + &FileOffset, NULL); NtClose(FileHandle); if (!NT_SUCCESS(Status)) @@ -1020,8 +1220,10 @@ InstallFat32BootCodeToFile( return Status; } - /* Allocate buffer for new bootsector (2 sectors) */ - NewBootSector = RtlAllocateHeap(ProcessHeap, 0, 2 * SECTORSIZE); + /* Allocate buffer for new bootsector */ + NewBootSector = RtlAllocateHeap(ProcessHeap, + 0, + SECTORSIZE); if (NewBootSector == NULL) { RtlFreeHeap(ProcessHeap, 0, OrigBootSector); @@ -1056,7 +1258,7 @@ InstallFat32BootCodeToFile( NULL, &IoStatusBlock, NewBootSector, - 2 * SECTORSIZE, + SECTORSIZE, NULL, NULL); NtClose(FileHandle); @@ -1067,61 +1269,16 @@ InstallFat32BootCodeToFile( return Status; } - /* Adjust bootsector (copy a part of the FAT32 BPB) */ + /* Adjust bootsector (copy a part of the FAT16 BPB) */ memcpy(&NewBootSector->OemName, &OrigBootSector->OemName, - FIELD_OFFSET(FAT32_BOOTSECTOR, BootCodeAndData) - - FIELD_OFFSET(FAT32_BOOTSECTOR, OemName)); - - /* Disable the backup boot sector */ - NewBootSector->BackupBootSector = 0; + FIELD_OFFSET(FAT_BOOTSECTOR, BootCodeAndData) - + FIELD_OFFSET(FAT_BOOTSECTOR, OemName)); /* Free the original boot sector */ RtlFreeHeap(ProcessHeap, 0, OrigBootSector); - /* Write the first sector of the new bootcode to DstPath */ - RtlInitUnicodeString(&Name, DstPath); - - InitializeObjectAttributes(&ObjectAttributes, - &Name, - 0, - NULL, - NULL); - - Status = NtCreateFile(&FileHandle, - GENERIC_WRITE | SYNCHRONIZE, - &ObjectAttributes, - &IoStatusBlock, - NULL, - FILE_ATTRIBUTE_NORMAL, - 0, - FILE_SUPERSEDE, - FILE_SYNCHRONOUS_IO_NONALERT | FILE_SEQUENTIAL_ONLY, - NULL, - 0); - if (!NT_SUCCESS(Status)) - { - RtlFreeHeap(ProcessHeap, 0, NewBootSector); - return Status; - } - - Status = NtWriteFile(FileHandle, - NULL, - NULL, - NULL, - &IoStatusBlock, - NewBootSector, - SECTORSIZE, - NULL, - NULL); - NtClose(FileHandle); - if (!NT_SUCCESS(Status)) - { - RtlFreeHeap(ProcessHeap, 0, NewBootSector); - return Status; - } - - /* Write the second sector of the new bootcode to boot disk sector 14 */ + /* Write new bootsector to RootPath */ RtlInitUnicodeString(&Name, RootPath); InitializeObjectAttributes(&ObjectAttributes, @@ -1135,26 +1292,24 @@ InstallFat32BootCodeToFile( &ObjectAttributes, &IoStatusBlock, 0, - FILE_SYNCHRONOUS_IO_NONALERT); + FILE_SYNCHRONOUS_IO_NONALERT | FILE_SEQUENTIAL_ONLY); if (!NT_SUCCESS(Status)) { + DPRINT1("NtOpenFile() failed (Status %lx)\n", Status); RtlFreeHeap(ProcessHeap, 0, NewBootSector); return Status; } - FileOffset.QuadPart = (ULONGLONG)(14 * SECTORSIZE); + FileOffset.QuadPart = 0ULL; Status = NtWriteFile(FileHandle, NULL, NULL, NULL, &IoStatusBlock, - ((PUCHAR)NewBootSector + SECTORSIZE), + NewBootSector, SECTORSIZE, &FileOffset, NULL); - if (!NT_SUCCESS(Status)) - { - } NtClose(FileHandle); /* Free the new boot sector */ @@ -1163,10 +1318,11 @@ InstallFat32BootCodeToFile( return Status; } - +static NTSTATUS -InstallMbrBootCodeToDisk( +InstallFat16BootCodeToFile( PWSTR SrcPath, + PWSTR DstPath, PWSTR RootPath) { NTSTATUS Status; @@ -1175,19 +1331,16 @@ InstallMbrBootCodeToDisk( IO_STATUS_BLOCK IoStatusBlock; HANDLE FileHandle; LARGE_INTEGER FileOffset; - PPARTITION_SECTOR OrigBootSector; - PPARTITION_SECTOR NewBootSector; + PFAT_BOOTSECTOR OrigBootSector; + PFAT_BOOTSECTOR NewBootSector; /* Allocate buffer for original bootsector */ - OrigBootSector = (PPARTITION_SECTOR)RtlAllocateHeap(ProcessHeap, - 0, - sizeof(PARTITION_SECTOR)); + OrigBootSector = RtlAllocateHeap(ProcessHeap, 0, SECTORSIZE); if (OrigBootSector == NULL) return STATUS_INSUFFICIENT_RESOURCES; /* Read current boot sector into buffer */ - RtlInitUnicodeString(&Name, - RootPath); + RtlInitUnicodeString(&Name, RootPath); InitializeObjectAttributes(&ObjectAttributes, &Name, @@ -1214,7 +1367,7 @@ InstallMbrBootCodeToDisk( NULL, &IoStatusBlock, OrigBootSector, - sizeof(PARTITION_SECTOR), + SECTORSIZE, &FileOffset, NULL); NtClose(FileHandle); @@ -1225,9 +1378,7 @@ InstallMbrBootCodeToDisk( } /* Allocate buffer for new bootsector */ - NewBootSector = (PPARTITION_SECTOR)RtlAllocateHeap(ProcessHeap, - 0, - sizeof(PARTITION_SECTOR)); + NewBootSector = RtlAllocateHeap(ProcessHeap, 0, SECTORSIZE); if (NewBootSector == NULL) { RtlFreeHeap(ProcessHeap, 0, OrigBootSector); @@ -1256,14 +1407,15 @@ InstallMbrBootCodeToDisk( return Status; } + FileOffset.QuadPart = 0ULL; Status = NtReadFile(FileHandle, NULL, NULL, NULL, &IoStatusBlock, NewBootSector, - sizeof(PARTITION_SECTOR), - NULL, + SECTORSIZE, + &FileOffset, NULL); NtClose(FileHandle); if (!NT_SUCCESS(Status)) @@ -1273,19 +1425,17 @@ InstallMbrBootCodeToDisk( return Status; } - /* - * Copy the disk signature, the reserved fields and - * the partition table from the old MBR to the new one. - */ - RtlCopyMemory(&NewBootSector->Signature, - &OrigBootSector->Signature, - sizeof(PARTITION_SECTOR) - offsetof(PARTITION_SECTOR, Signature) /* Length of partition table */); + /* Adjust bootsector (copy a part of the FAT BPB) */ + memcpy(&NewBootSector->OemName, + &OrigBootSector->OemName, + FIELD_OFFSET(FAT_BOOTSECTOR, BootCodeAndData) - + FIELD_OFFSET(FAT_BOOTSECTOR, OemName)); /* Free the original boot sector */ RtlFreeHeap(ProcessHeap, 0, OrigBootSector); - /* Write new bootsector to RootPath */ - RtlInitUnicodeString(&Name, RootPath); + /* Write new bootsector to DstPath */ + RtlInitUnicodeString(&Name, DstPath); InitializeObjectAttributes(&ObjectAttributes, &Name, @@ -1293,15 +1443,19 @@ InstallMbrBootCodeToDisk( NULL, NULL); - Status = NtOpenFile(&FileHandle, - GENERIC_WRITE | SYNCHRONIZE, - &ObjectAttributes, - &IoStatusBlock, - 0, - FILE_SYNCHRONOUS_IO_NONALERT | FILE_SEQUENTIAL_ONLY); + Status = NtCreateFile(&FileHandle, + GENERIC_WRITE | SYNCHRONIZE, + &ObjectAttributes, + &IoStatusBlock, + NULL, + FILE_ATTRIBUTE_NORMAL, + 0, + FILE_OVERWRITE_IF, + FILE_SYNCHRONOUS_IO_NONALERT | FILE_SEQUENTIAL_ONLY, + NULL, + 0); if (!NT_SUCCESS(Status)) { - DPRINT1("NtOpenFile() failed (Status %lx)\n", Status); RtlFreeHeap(ProcessHeap, 0, NewBootSector); return Status; } @@ -1313,8 +1467,8 @@ InstallMbrBootCodeToDisk( NULL, &IoStatusBlock, NewBootSector, - sizeof(PARTITION_SECTOR), - &FileOffset, + SECTORSIZE, + NULL, NULL); NtClose(FileHandle); @@ -1326,7 +1480,7 @@ InstallMbrBootCodeToDisk( static NTSTATUS -InstallFat12BootCodeToFloppy( +InstallFat16BootCodeToDisk( PWSTR SrcPath, PWSTR RootPath) { @@ -1383,9 +1537,7 @@ InstallFat12BootCodeToFloppy( } /* Allocate buffer for new bootsector */ - NewBootSector = RtlAllocateHeap(ProcessHeap, - 0, - SECTORSIZE); + NewBootSector = RtlAllocateHeap(ProcessHeap, 0, SECTORSIZE); if (NewBootSector == NULL) { RtlFreeHeap(ProcessHeap, 0, OrigBootSector); @@ -1482,8 +1634,9 @@ InstallFat12BootCodeToFloppy( static NTSTATUS -InstallFat16BootCodeToDisk( +InstallFat32BootCodeToFile( PWSTR SrcPath, + PWSTR DstPath, PWSTR RootPath) { NTSTATUS Status; @@ -1492,8 +1645,8 @@ InstallFat16BootCodeToDisk( IO_STATUS_BLOCK IoStatusBlock; HANDLE FileHandle; LARGE_INTEGER FileOffset; - PFAT_BOOTSECTOR OrigBootSector; - PFAT_BOOTSECTOR NewBootSector; + PFAT32_BOOTSECTOR OrigBootSector; + PFAT32_BOOTSECTOR NewBootSector; /* Allocate buffer for original bootsector */ OrigBootSector = RtlAllocateHeap(ProcessHeap, 0, SECTORSIZE); @@ -1529,7 +1682,7 @@ InstallFat16BootCodeToDisk( &IoStatusBlock, OrigBootSector, SECTORSIZE, - &FileOffset, + NULL, NULL); NtClose(FileHandle); if (!NT_SUCCESS(Status)) @@ -1538,8 +1691,8 @@ InstallFat16BootCodeToDisk( return Status; } - /* Allocate buffer for new bootsector */ - NewBootSector = RtlAllocateHeap(ProcessHeap, 0, SECTORSIZE); + /* Allocate buffer for new bootsector (2 sectors) */ + NewBootSector = RtlAllocateHeap(ProcessHeap, 0, 2 * SECTORSIZE); if (NewBootSector == NULL) { RtlFreeHeap(ProcessHeap, 0, OrigBootSector); @@ -1555,46 +1708,92 @@ InstallFat16BootCodeToDisk( NULL, NULL); - Status = NtOpenFile(&FileHandle, - GENERIC_READ | SYNCHRONIZE, - &ObjectAttributes, - &IoStatusBlock, - 0, - FILE_SYNCHRONOUS_IO_NONALERT); + Status = NtOpenFile(&FileHandle, + GENERIC_READ | SYNCHRONIZE, + &ObjectAttributes, + &IoStatusBlock, + 0, + FILE_SYNCHRONOUS_IO_NONALERT); + if (!NT_SUCCESS(Status)) + { + RtlFreeHeap(ProcessHeap, 0, OrigBootSector); + RtlFreeHeap(ProcessHeap, 0, NewBootSector); + return Status; + } + + Status = NtReadFile(FileHandle, + NULL, + NULL, + NULL, + &IoStatusBlock, + NewBootSector, + 2 * SECTORSIZE, + NULL, + NULL); + NtClose(FileHandle); + if (!NT_SUCCESS(Status)) + { + RtlFreeHeap(ProcessHeap, 0, OrigBootSector); + RtlFreeHeap(ProcessHeap, 0, NewBootSector); + return Status; + } + + /* Adjust bootsector (copy a part of the FAT32 BPB) */ + memcpy(&NewBootSector->OemName, + &OrigBootSector->OemName, + FIELD_OFFSET(FAT32_BOOTSECTOR, BootCodeAndData) - + FIELD_OFFSET(FAT32_BOOTSECTOR, OemName)); + + /* Disable the backup boot sector */ + NewBootSector->BackupBootSector = 0; + + /* Free the original boot sector */ + RtlFreeHeap(ProcessHeap, 0, OrigBootSector); + + /* Write the first sector of the new bootcode to DstPath */ + RtlInitUnicodeString(&Name, DstPath); + + InitializeObjectAttributes(&ObjectAttributes, + &Name, + 0, + NULL, + NULL); + + Status = NtCreateFile(&FileHandle, + GENERIC_WRITE | SYNCHRONIZE, + &ObjectAttributes, + &IoStatusBlock, + NULL, + FILE_ATTRIBUTE_NORMAL, + 0, + FILE_SUPERSEDE, + FILE_SYNCHRONOUS_IO_NONALERT | FILE_SEQUENTIAL_ONLY, + NULL, + 0); if (!NT_SUCCESS(Status)) { - RtlFreeHeap(ProcessHeap, 0, OrigBootSector); RtlFreeHeap(ProcessHeap, 0, NewBootSector); return Status; } - Status = NtReadFile(FileHandle, - NULL, - NULL, - NULL, - &IoStatusBlock, - NewBootSector, - SECTORSIZE, - NULL, - NULL); + FileOffset.QuadPart = 0ULL; + Status = NtWriteFile(FileHandle, + NULL, + NULL, + NULL, + &IoStatusBlock, + NewBootSector, + SECTORSIZE, + NULL, + NULL); NtClose(FileHandle); if (!NT_SUCCESS(Status)) { - RtlFreeHeap(ProcessHeap, 0, OrigBootSector); RtlFreeHeap(ProcessHeap, 0, NewBootSector); return Status; } - /* Adjust bootsector (copy a part of the FAT16 BPB) */ - memcpy(&NewBootSector->OemName, - &OrigBootSector->OemName, - FIELD_OFFSET(FAT_BOOTSECTOR, BootCodeAndData) - - FIELD_OFFSET(FAT_BOOTSECTOR, OemName)); - - /* Free the original boot sector */ - RtlFreeHeap(ProcessHeap, 0, OrigBootSector); - - /* Write new bootsector to RootPath */ + /* Write the second sector of the new bootcode to boot disk sector 14 */ RtlInitUnicodeString(&Name, RootPath); InitializeObjectAttributes(&ObjectAttributes, @@ -1608,24 +1807,26 @@ InstallFat16BootCodeToDisk( &ObjectAttributes, &IoStatusBlock, 0, - FILE_SYNCHRONOUS_IO_NONALERT | FILE_SEQUENTIAL_ONLY); + FILE_SYNCHRONOUS_IO_NONALERT); if (!NT_SUCCESS(Status)) { - DPRINT1("NtOpenFile() failed (Status %lx)\n", Status); RtlFreeHeap(ProcessHeap, 0, NewBootSector); return Status; } - FileOffset.QuadPart = 0ULL; + FileOffset.QuadPart = (ULONGLONG)(14 * SECTORSIZE); Status = NtWriteFile(FileHandle, NULL, NULL, NULL, &IoStatusBlock, - NewBootSector, + ((PUCHAR)NewBootSector + SECTORSIZE), SECTORSIZE, &FileOffset, NULL); + if (!NT_SUCCESS(Status)) + { + } NtClose(FileHandle); /* Free the new boot sector */ @@ -2074,203 +2275,6 @@ InstallBtrfsBootCodeToDisk( return Status; } -static -NTSTATUS -UnprotectBootIni( - PWSTR FileName, - PULONG Attributes) -{ - NTSTATUS Status; - UNICODE_STRING Name; - OBJECT_ATTRIBUTES ObjectAttributes; - IO_STATUS_BLOCK IoStatusBlock; - FILE_BASIC_INFORMATION FileInfo; - HANDLE FileHandle; - - RtlInitUnicodeString(&Name, FileName); - - InitializeObjectAttributes(&ObjectAttributes, - &Name, - OBJ_CASE_INSENSITIVE, - NULL, - NULL); - - Status = NtOpenFile(&FileHandle, - GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, - &ObjectAttributes, - &IoStatusBlock, - 0, - FILE_SYNCHRONOUS_IO_NONALERT); - if (Status == STATUS_NO_SUCH_FILE) - { - DPRINT1("NtOpenFile() failed (Status %lx)\n", Status); - *Attributes = 0; - return STATUS_SUCCESS; - } - if (!NT_SUCCESS(Status)) - { - DPRINT1("NtOpenFile() failed (Status %lx)\n", Status); - return Status; - } - - Status = NtQueryInformationFile(FileHandle, - &IoStatusBlock, - &FileInfo, - sizeof(FILE_BASIC_INFORMATION), - FileBasicInformation); - if (!NT_SUCCESS(Status)) - { - DPRINT1("NtQueryInformationFile() failed (Status %lx)\n", Status); - NtClose(FileHandle); - return Status; - } - - *Attributes = FileInfo.FileAttributes; - - /* Delete attributes SYSTEM, HIDDEN and READONLY */ - FileInfo.FileAttributes = FileInfo.FileAttributes & - ~(FILE_ATTRIBUTE_SYSTEM | - FILE_ATTRIBUTE_HIDDEN | - FILE_ATTRIBUTE_READONLY); - - Status = NtSetInformationFile(FileHandle, - &IoStatusBlock, - &FileInfo, - sizeof(FILE_BASIC_INFORMATION), - FileBasicInformation); - if (!NT_SUCCESS(Status)) - { - DPRINT1("NtSetInformationFile() failed (Status %lx)\n", Status); - } - - NtClose(FileHandle); - return Status; -} - -static -NTSTATUS -ProtectBootIni( - PWSTR FileName, - ULONG Attributes) -{ - NTSTATUS Status; - UNICODE_STRING Name; - OBJECT_ATTRIBUTES ObjectAttributes; - IO_STATUS_BLOCK IoStatusBlock; - FILE_BASIC_INFORMATION FileInfo; - HANDLE FileHandle; - - RtlInitUnicodeString(&Name, FileName); - - InitializeObjectAttributes(&ObjectAttributes, - &Name, - OBJ_CASE_INSENSITIVE, - NULL, - NULL); - - Status = NtOpenFile(&FileHandle, - GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, - &ObjectAttributes, - &IoStatusBlock, - 0, - FILE_SYNCHRONOUS_IO_NONALERT); - if (!NT_SUCCESS(Status)) - { - DPRINT1("NtOpenFile() failed (Status %lx)\n", Status); - return Status; - } - - Status = NtQueryInformationFile(FileHandle, - &IoStatusBlock, - &FileInfo, - sizeof(FILE_BASIC_INFORMATION), - FileBasicInformation); - if (!NT_SUCCESS(Status)) - { - DPRINT1("NtQueryInformationFile() failed (Status %lx)\n", Status); - NtClose(FileHandle); - return Status; - } - - FileInfo.FileAttributes = FileInfo.FileAttributes | Attributes; - - Status = NtSetInformationFile(FileHandle, - &IoStatusBlock, - &FileInfo, - sizeof(FILE_BASIC_INFORMATION), - FileBasicInformation); - if (!NT_SUCCESS(Status)) - { - DPRINT1("NtSetInformationFile() failed (Status %lx)\n", Status); - } - - NtClose(FileHandle); - return Status; -} - -static -NTSTATUS -UpdateBootIni( - PWSTR BootIniPath, - PWSTR EntryName, - PWSTR EntryValue) -{ - NTSTATUS Status; - PINICACHE Cache = NULL; - PINICACHESECTION Section = NULL; - ULONG FileAttribute; - PWCHAR OldValue = NULL; - - Status = IniCacheLoad(&Cache, BootIniPath, FALSE); - if (!NT_SUCCESS(Status)) - { - return Status; - } - - Section = IniCacheGetSection(Cache, - L"operating systems"); - if (Section == NULL) - { - IniCacheDestroy(Cache); - return STATUS_UNSUCCESSFUL; - } - - /* Check - maybe record already exists */ - Status = IniCacheGetKey(Section, EntryName, &OldValue); - - /* If either key was not found, or contains something else - add new one */ - if (!NT_SUCCESS(Status) || wcscmp(OldValue, EntryValue)) - { - IniCacheInsertKey(Section, - NULL, - INSERT_LAST, - EntryName, - EntryValue); - } - - Status = UnprotectBootIni(BootIniPath, - &FileAttribute); - if (!NT_SUCCESS(Status)) - { - IniCacheDestroy(Cache); - return Status; - } - - Status = IniCacheSave(Cache, BootIniPath); - if (!NT_SUCCESS(Status)) - { - IniCacheDestroy(Cache); - return Status; - } - - FileAttribute |= (FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_READONLY); - Status = ProtectBootIni(BootIniPath, FileAttribute); - - IniCacheDestroy(Cache); - - return Status; -} - static NTSTATUS InstallFatBootcodeToPartition(
6 years, 2 months
1
0
0
0
← Newer
1
...
18
19
20
21
22
23
24
...
36
Older →
Jump to page:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
Results per page:
10
25
50
100
200