mirror of
https://github.com/reactos/reactos.git
synced 2026-06-09 17:33:50 +08:00
Detect whether we run on XBOX or PC98 (on x86 builds), or on (U)EFI or on a BIOS-based PC, or whether a generic linear framebuffer mode is used, in order to choose the correct bootvid module to load, based from a predefined file names list (ideally it should be derived from txtsetup.sif...). Supersedes PR #8701. Use `KeFindConfiguration*Entry()` to spelunk the hardware configuration tree in the NT loader module. Alternatively, allow the user to override the choice with a new `BOOTVID=` boot option. In any case, if the selected bootvid module failed to be loaded, silently fall back to the default bootvid.dll file. The fallback is done by just letting the PE loader resolve the necessary exports from hal.dll and ntoskrnl.exe.
123 lines
3.7 KiB
C
123 lines
3.7 KiB
C
/*
|
|
* PROJECT: ReactOS Kernel
|
|
* LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
|
|
* PURPOSE: Configuration Tree Routines
|
|
* COPYRIGHT: Copyright 2005-2006 Alex Ionescu <alex.ionescu@reactos.org>
|
|
*
|
|
* NOTE: This module is shared by both the kernel and the bootloader.
|
|
*/
|
|
|
|
/* INCLUDES ******************************************************************/
|
|
|
|
#include <ntoskrnl.h>
|
|
|
|
/* FUNCTIONS *****************************************************************/
|
|
|
|
/*
|
|
* @implemented
|
|
*/
|
|
PCONFIGURATION_COMPONENT_DATA
|
|
NTAPI
|
|
KeFindConfigurationNextEntry(
|
|
_In_ PCONFIGURATION_COMPONENT_DATA Child,
|
|
_In_ CONFIGURATION_CLASS Class,
|
|
_In_ CONFIGURATION_TYPE Type,
|
|
_In_opt_ PULONG ComponentKey,
|
|
_Inout_ PCONFIGURATION_COMPONENT_DATA *NextLink)
|
|
{
|
|
ULONG Key = 0;
|
|
ULONG Mask = 0;
|
|
PCONFIGURATION_COMPONENT_DATA Sibling;
|
|
PCONFIGURATION_COMPONENT_DATA ReturnEntry;
|
|
|
|
/* If we did get a key, then use it instead */
|
|
if (ComponentKey)
|
|
{
|
|
Key = *ComponentKey;
|
|
Mask = -1;
|
|
}
|
|
|
|
/* Loop the components until we find a a match */
|
|
for (; Child; Child = Child->Child)
|
|
{
|
|
/* Check if we are starting somewhere already */
|
|
if (*NextLink)
|
|
{
|
|
/* If we've found the place where we started, clear and continue */
|
|
if (Child == *NextLink)
|
|
*NextLink = NULL;
|
|
}
|
|
else
|
|
{
|
|
/* Try to get a match */
|
|
if ((Child->ComponentEntry.Class) == Class &&
|
|
(Child->ComponentEntry.Type) == Type &&
|
|
(Child->ComponentEntry.Key & Mask) == Key)
|
|
{
|
|
/* Match found */
|
|
return Child;
|
|
}
|
|
}
|
|
|
|
/* Now we've also got to lookup the siblings */
|
|
for (Sibling = Child->Sibling; Sibling; Sibling = Sibling->Sibling)
|
|
{
|
|
/* Check if we are starting somewhere already */
|
|
if (*NextLink)
|
|
{
|
|
/* If we've found the place where we started, clear and continue */
|
|
if (Sibling == *NextLink)
|
|
*NextLink = NULL;
|
|
}
|
|
else
|
|
{
|
|
/* Try to get a match */
|
|
if ((Sibling->ComponentEntry.Class == Class) &&
|
|
(Sibling->ComponentEntry.Type == Type) &&
|
|
(Sibling->ComponentEntry.Key & Mask) == Key)
|
|
{
|
|
/* Match found */
|
|
return Sibling;
|
|
}
|
|
}
|
|
|
|
/* We've got to check if the sibling has a child as well */
|
|
if (Sibling->Child)
|
|
{
|
|
/* We're just going to call ourselves again */
|
|
ReturnEntry = KeFindConfigurationNextEntry(Sibling->Child,
|
|
Class,
|
|
Type,
|
|
ComponentKey,
|
|
NextLink);
|
|
if (ReturnEntry)
|
|
return ReturnEntry;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* If we got here, nothing was found */
|
|
return NULL;
|
|
}
|
|
|
|
/*
|
|
* @implemented
|
|
*/
|
|
PCONFIGURATION_COMPONENT_DATA
|
|
NTAPI
|
|
KeFindConfigurationEntry(
|
|
_In_ PCONFIGURATION_COMPONENT_DATA Child,
|
|
_In_ CONFIGURATION_CLASS Class,
|
|
_In_ CONFIGURATION_TYPE Type,
|
|
_In_opt_ PULONG ComponentKey)
|
|
{
|
|
PCONFIGURATION_COMPONENT_DATA NextLink = NULL;
|
|
|
|
/* Start search at the root */
|
|
return KeFindConfigurationNextEntry(Child,
|
|
Class,
|
|
Type,
|
|
ComponentKey,
|
|
&NextLink);
|
|
}
|