[SETUPLIB] Improve a bit the management of boot-store options

- QueryBootStoreOptions(): De-duplicate code.
- SetBootStoreOpt(): Respect the FieldsToChange flag.
- BOOT_STORE_OPTIONS: Remove unused Version field and distinguish
  between "Current" and "Next" BootEntryKey.
This commit is contained in:
Hermès Bélusca-Maïto 2024-05-04 12:47:13 +02:00
parent 68c2a28973
commit 9b563d32d2
No known key found for this signature in database
GPG key ID: 3B2539C65E7B93D0
3 changed files with 68 additions and 54 deletions

View file

@ -130,15 +130,15 @@ CreateFreeLoaderReactOSEntries(
#if DBG && !defined(_WINKD_)
if (IsUnattendedSetup)
{
BootOptions.CurrentBootEntryKey = MAKESTRKEY(L"ReactOS_KdSerial");
BootOptions.NextBootEntryKey = MAKESTRKEY(L"ReactOS_KdSerial");
}
else
#endif
{
#if DBG
BootOptions.CurrentBootEntryKey = MAKESTRKEY(L"ReactOS_Debug");
BootOptions.NextBootEntryKey = MAKESTRKEY(L"ReactOS_Debug");
#else
BootOptions.CurrentBootEntryKey = MAKESTRKEY(L"ReactOS");
BootOptions.NextBootEntryKey = MAKESTRKEY(L"ReactOS");
#endif
}
@ -157,8 +157,8 @@ CreateFreeLoaderReactOSEntries(
}
#endif
BootOptions.Version = FreeLdr;
SetBootStoreOptions(BootStoreHandle, &BootOptions, 2 | 1);
SetBootStoreOptions(BootStoreHandle, &BootOptions,
BOOT_OPTIONS_TIMEOUT | BOOT_OPTIONS_NEXT_BOOTENTRY_KEY);
}
static NTSTATUS

View file

@ -130,6 +130,17 @@ NTOS_BOOT_LOADER_FILES NtosBootLoaders[] =
};
C_ASSERT(_countof(NtosBootLoaders) == BldrTypeMax);
enum BOOT_OPTION
{
BO_TimeOut,
BO_DefaultOS,
};
static const PCWSTR BootOptionNames[][2] =
{
{L"TimeOut", L"DefaultOS"}, // FreeLdr
{L"timeout", L"default" } // NtLdr
};
/* FUNCTIONS ****************************************************************/
@ -1031,36 +1042,32 @@ QueryBootStoreOptions(
return STATUS_NOT_SUPPORTED;
}
if (BootStore->Type == FreeLdr)
BootOptions->Timeout = 0;
BootOptions->CurrentBootEntryKey = 0;
BootOptions->NextBootEntryKey = 0;
if (IniGetKey(((PBOOT_STORE_INI_CONTEXT)BootStore)->OptionsIniSection,
BootOptionNames[BootStore->Type][BO_TimeOut],
&TimeoutStr) && TimeoutStr)
{
BootOptions->Version = FreeLdr;
BootOptions->CurrentBootEntryKey = 0;
IniGetKey(((PBOOT_STORE_INI_CONTEXT)BootStore)->OptionsIniSection,
L"DefaultOS", (PCWSTR*)&BootOptions->CurrentBootEntryKey);
BootOptions->Timeout = 0;
if (IniGetKey(((PBOOT_STORE_INI_CONTEXT)BootStore)->OptionsIniSection,
L"TimeOut", &TimeoutStr) && TimeoutStr)
{
BootOptions->Timeout = _wtoi(TimeoutStr);
}
BootOptions->Timeout = _wtoi(TimeoutStr);
}
else if (BootStore->Type == NtLdr)
{
BootOptions->Version = NtLdr;
BootOptions->CurrentBootEntryKey = 0;
IniGetKey(((PBOOT_STORE_INI_CONTEXT)BootStore)->OptionsIniSection,
L"default", (PCWSTR*)&BootOptions->CurrentBootEntryKey);
IniGetKey(((PBOOT_STORE_INI_CONTEXT)BootStore)->OptionsIniSection,
BootOptionNames[BootStore->Type][BO_DefaultOS],
(PCWSTR*)&BootOptions->NextBootEntryKey);
BootOptions->Timeout = 0;
if (IniGetKey(((PBOOT_STORE_INI_CONTEXT)BootStore)->OptionsIniSection,
L"timeout", &TimeoutStr) && TimeoutStr)
{
BootOptions->Timeout = _wtoi(TimeoutStr);
}
}
/*
* NOTE: BootOptions->CurrentBootEntryKey is an informative field only.
* It indicates which boot entry has been selected for starting the
* current OS instance. Such information is NOT stored in the INI file,
* but has to be determined via other means. On UEFI the 'BootCurrent'
* environment variable does that. Otherwise, one could heuristically
* determine it by comparing the boot path and options of each entry
* with those used by the current OS instance.
* Since we currently do not need this information (and it can be costly
* to determine), BootOptions->CurrentBootEntryKey is not evaluated.
*/
return STATUS_SUCCESS;
}
@ -1072,7 +1079,6 @@ SetBootStoreOptions(
IN ULONG FieldsToChange)
{
PBOOT_STORE_CONTEXT BootStore = (PBOOT_STORE_CONTEXT)Handle;
WCHAR TimeoutStr[15];
if (!BootStore || !BootOptions)
return STATUS_INVALID_PARAMETER;
@ -1090,25 +1096,29 @@ SetBootStoreOptions(
//
// if (BootStore->Type >= BldrTypeMax || NtosBootLoaders[BootStore->Type].Type >= BldrTypeMax)
if (BootStore->Type != FreeLdr)
if (BootStore->Type != FreeLdr && BootStore->Type != NtLdr)
{
DPRINT1("Loader type %d is currently unsupported!\n", NtosBootLoaders[BootStore->Type].Type);
return STATUS_NOT_SUPPORTED;
}
if (BootOptions->Version != FreeLdr)
return STATUS_INVALID_PARAMETER;
// if (BootOptions->Length < sizeof(*BootOptions))
// return STATUS_INVALID_PARAMETER;
//
// TODO: Depending on the flags set in 'FieldsToChange',
// change either one or both these bootloader options.
//
IniAddKey(((PBOOT_STORE_INI_CONTEXT)BootStore)->OptionsIniSection,
L"DefaultOS", (PCWSTR)BootOptions->CurrentBootEntryKey);
RtlStringCchPrintfW(TimeoutStr, ARRAYSIZE(TimeoutStr), L"%d", BootOptions->Timeout);
IniAddKey(((PBOOT_STORE_INI_CONTEXT)BootStore)->OptionsIniSection,
L"TimeOut", TimeoutStr);
if (FieldsToChange & BOOT_OPTIONS_TIMEOUT)
{
WCHAR TimeoutStr[15];
RtlStringCchPrintfW(TimeoutStr, ARRAYSIZE(TimeoutStr), L"%d", BootOptions->Timeout);
IniAddKey(((PBOOT_STORE_INI_CONTEXT)BootStore)->OptionsIniSection,
BootOptionNames[BootStore->Type][BO_TimeOut],
TimeoutStr);
}
if (FieldsToChange & BOOT_OPTIONS_NEXT_BOOTENTRY_KEY)
{
IniAddKey(((PBOOT_STORE_INI_CONTEXT)BootStore)->OptionsIniSection,
BootOptionNames[BootStore->Type][BO_DefaultOS],
(PCWSTR)BootOptions->NextBootEntryKey);
}
return STATUS_SUCCESS;
}

View file

@ -30,14 +30,18 @@ typedef enum _BOOT_STORE_TYPE
*/
typedef struct _BOOT_STORE_OPTIONS
{
ULONG Version; // BOOT_STORE_TYPE value
// ULONG Length;
ULONG Timeout;
ULONG_PTR CurrentBootEntryKey;
// ULONG_PTR NextBootEntryKey;
// WCHAR HeadlessRedirection[1];
ULONG Timeout; //< Timeout in seconds before the default boot entry is started.
ULONG_PTR CurrentBootEntryKey; //< Selected boot entry for the current boot (informative only).
ULONG_PTR NextBootEntryKey; //< The boot entry for the next boot.
// WCHAR HeadlessRedirection[ANYSIZE_ARRAY];
} BOOT_STORE_OPTIONS, *PBOOT_STORE_OPTIONS;
/* FieldsToChange flags for SetBootStoreOptions() */
#define BOOT_OPTIONS_TIMEOUT 1
#define BOOT_OPTIONS_NEXT_BOOTENTRY_KEY 2
// #define BOOT_OPTIONS_HEADLESS_REDIRECTION 4
/*
* These macros are used to set a value for the BootEntryKey member of a
* BOOT_STORE_ENTRY structure, much in the same idea as MAKEINTRESOURCE and
@ -63,10 +67,10 @@ typedef struct _BOOT_STORE_ENTRY
{
ULONG Version; // BOOT_STORE_TYPE value
// ULONG Length;
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...)
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'