Skip to content

Commit ac25cde

Browse files
committed
[BOOTMGR]: Implement support for getting the default boot entry, the current boot menu policy, and finish implementation of getting the selected boot entry.
[BOOTMGR]: Stubplement support for catching keystrokes right before boot (such as F8, F10). No key input is actually read. Boot Manager now attempts to load the winload entry as part of BmpLaunchBootEntry. svn path=/trunk/; revision=70615
1 parent 12f04d8 commit ac25cde

File tree

3 files changed

+341
-3
lines changed

3 files changed

+341
-3
lines changed

reactos/boot/environ/app/bootmgr/bootmgr.c

Lines changed: 307 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ WCHAR BmpFileNameBuffer[128];
3232
PWCHAR ParentFileName = L"";
3333

3434
BOOLEAN BmDisplayStateCached;
35+
PBL_LOADED_APPLICATION_ENTRY* BmpFailedBootEntries;
36+
PBL_LOADED_APPLICATION_ENTRY BmpSelectedBootEntry;
37+
BOOLEAN BmBootEntryOverridePresent;
38+
BOOLEAN BmpDisplayBootMenu;
3539

3640
/* FUNCTIONS *****************************************************************/
3741

@@ -1652,18 +1656,196 @@ BmEnumerateBootEntries (
16521656
return Status;
16531657
}
16541658

1659+
VOID
1660+
BmpGetDefaultBootEntry (
1661+
_In_ PBL_LOADED_APPLICATION_ENTRY* Sequence,
1662+
_In_ ULONG Count,
1663+
_Out_ PBL_LOADED_APPLICATION_ENTRY* DefaultEntry,
1664+
_Out_ PULONG DefaultIndex
1665+
)
1666+
{
1667+
GUID DefaultObject;
1668+
NTSTATUS Status;
1669+
ULONG BootIndex;
1670+
1671+
/* Assume no default */
1672+
*DefaultEntry = *Sequence;
1673+
*DefaultIndex = 0;
1674+
1675+
/* Nothing to do if there's just one entry */
1676+
if (Count == 1)
1677+
{
1678+
return;
1679+
}
1680+
1681+
/* Get the default object, bail out if there isn't one */
1682+
Status = BlGetBootOptionGuid(BlpApplicationEntry.BcdData,
1683+
BcdBootMgrObject_DefaultObject,
1684+
&DefaultObject);
1685+
if (!(NT_SUCCESS(Status)) || !(Count))
1686+
{
1687+
return;
1688+
}
1689+
1690+
/* Scan the boot sequence */
1691+
for (BootIndex = 0; BootIndex < Count; BootIndex++)
1692+
{
1693+
/* Find one that matches the default */
1694+
if (RtlEqualMemory(&Sequence[BootIndex]->Guid,
1695+
&DefaultObject,
1696+
sizeof(GUID)))
1697+
{
1698+
/* Return it */
1699+
*DefaultEntry = Sequence[BootIndex];
1700+
*DefaultIndex = BootIndex;
1701+
return;
1702+
}
1703+
}
1704+
}
1705+
1706+
BL_MENU_POLICY
1707+
BmGetBootMenuPolicy (
1708+
_In_ PBL_LOADED_APPLICATION_ENTRY BootEntry
1709+
)
1710+
{
1711+
NTSTATUS Status;
1712+
BOOLEAN EmsEnabled;
1713+
ULONGLONG BootMenuPolicy;
1714+
ULONG OptionId;
1715+
1716+
/* Check if EMS is enabled */
1717+
Status = BlGetBootOptionBoolean(BlpApplicationEntry.BcdData,
1718+
BcdOSLoaderBoolean_EmsEnabled,
1719+
&EmsEnabled);
1720+
if ((NT_SUCCESS(Status)) && (EmsEnabled))
1721+
{
1722+
/* No boot menu */
1723+
return MenuPolicyLegacy;
1724+
}
1725+
1726+
/* Check what entry we are looking at */
1727+
if (!BootEntry)
1728+
{
1729+
/* No entry, pick the selected one */
1730+
BootEntry = BmpSelectedBootEntry;
1731+
}
1732+
1733+
/* Do we still not have an entry? */
1734+
if (!BootEntry)
1735+
{
1736+
/* Show the menu */
1737+
return MenuPolicyStandard;
1738+
}
1739+
1740+
/* Check if this is an OS loader */
1741+
BootMenuPolicy = 0;
1742+
if (BootEntry->Flags & BL_APPLICATION_ENTRY_WINLOAD)
1743+
{
1744+
/* Use the correct option ID */
1745+
OptionId = BcdOSLoaderInteger_BootMenuPolicy;
1746+
}
1747+
else
1748+
{
1749+
/* Check if this is an OS resumer */
1750+
if (!(BootEntry->Flags & BL_APPLICATION_ENTRY_WINRESUME))
1751+
{
1752+
/* Nope, so no reason for a menu */
1753+
return MenuPolicyLegacy;
1754+
}
1755+
1756+
/* Use the correct opetion ID */
1757+
OptionId = BcdResumeInteger_BootMenuPolicy;
1758+
}
1759+
1760+
/* Check the option ID for the boot menu policy */
1761+
Status = BlGetBootOptionInteger(BootEntry->BcdData,
1762+
OptionId,
1763+
&BootMenuPolicy);
1764+
if (NT_SUCCESS(Status))
1765+
{
1766+
/* We have one, return it */
1767+
return BootMenuPolicy;
1768+
}
1769+
1770+
/* No policy, so assume no menu */
1771+
return MenuPolicyLegacy;
1772+
}
1773+
1774+
VOID
1775+
BmDisplayGetBootMenuStatus (
1776+
_Out_ PL_MENU_STATUS MenuStatus
1777+
)
1778+
{
1779+
/* For now, don't support key input at all */
1780+
MenuStatus->AsULong = 0;
1781+
MenuStatus->OemKey = UNICODE_NULL;
1782+
MenuStatus->BootIndex = -1;
1783+
}
1784+
1785+
NTSTATUS
1786+
BmProcessCustomAction (
1787+
_In_ HANDLE BcdHandle,
1788+
_In_ PWCHAR ActionKey
1789+
)
1790+
{
1791+
EfiPrintf(L"Custom actions not yet handled\r\n");
1792+
return STATUS_NOT_IMPLEMENTED;
1793+
}
1794+
1795+
VOID
1796+
BmpProcessBootEntry (
1797+
_In_ HANDLE BcdHandle,
1798+
_In_ PBL_LOADED_APPLICATION_ENTRY BootEntry,
1799+
_Out_ PBOOLEAN ExitBootManager
1800+
)
1801+
{
1802+
BL_MENU_STATUS MenuStatus;
1803+
1804+
/* Don't exit */
1805+
*ExitBootManager = FALSE;
1806+
1807+
/* If the legacy menu must be shown, or if we have a boot entry */
1808+
if ((BmGetBootMenuPolicy(BootEntry) != MenuPolicyStandard) || (BootEntry))
1809+
{
1810+
/* Check if any key has been presseed */
1811+
BmDisplayGetBootMenuStatus(&MenuStatus);
1812+
if (MenuStatus.AnyKey)
1813+
{
1814+
/* Was the exit key pressed? */
1815+
if (MenuStatus.Exit)
1816+
{
1817+
/* Don't display a menu, and exit */
1818+
*ExitBootManager = TRUE;
1819+
BmpDisplayBootMenu = FALSE;
1820+
}
1821+
else if (MenuStatus.OemKey)
1822+
{
1823+
/* Process the OEM key action */
1824+
BmProcessCustomAction(BcdHandle, &MenuStatus.KeyValue);
1825+
}
1826+
else
1827+
{
1828+
/* Process other keys */
1829+
EfiPrintf(L"TODO\r\n");
1830+
}
1831+
}
1832+
}
1833+
}
1834+
16551835
NTSTATUS
16561836
BmpGetSelectedBootEntry (
16571837
_In_ HANDLE BcdHandle,
1658-
_Out_ PBL_LOADED_APPLICATION_ENTRY *SelectedBootEntry,
1838+
_Out_ PBL_LOADED_APPLICATION_ENTRY* SelectedBootEntry,
16591839
_Out_ PULONG EntryIndex,
16601840
_Out_ PBOOLEAN ExitBootManager
16611841
)
16621842
{
16631843
NTSTATUS Status;
16641844
PBL_LOADED_APPLICATION_ENTRY* Sequence;
16651845
PBL_LOADED_APPLICATION_ENTRY Entry, SelectedEntry;
1666-
ULONG Count, BootIndex;
1846+
ULONG Count, BootIndex, SelectedIndex;
1847+
// BOOLEAN FoundFailedEntry;
1848+
ULONGLONG Timeout;
16671849

16681850
/* Initialize locals */
16691851
BootIndex = 0;
@@ -1688,7 +1870,128 @@ BmpGetSelectedBootEntry (
16881870
goto Quickie;
16891871
}
16901872

1691-
EfiPrintf(L"Boot selection not yet implemented. %d entries found\r\n", Count);
1873+
/* Check if we don't yet have an array of failed boot entries */
1874+
if (!BmpFailedBootEntries)
1875+
{
1876+
/* Allocate it */
1877+
BmpFailedBootEntries = BlMmAllocateHeap(Count);
1878+
if (BmpFailedBootEntries)
1879+
{
1880+
/* Zero it out */
1881+
RtlZeroMemory(BmpFailedBootEntries, Count);
1882+
}
1883+
}
1884+
1885+
/* Check if we have a hardcoded boot override */
1886+
if (BmBootEntryOverridePresent)
1887+
{
1888+
EfiPrintf(L"Hard-coded boot override mode not supported\r\n");
1889+
}
1890+
1891+
/* Log the OS count */
1892+
//BlLogEtwWrite(BOOT_BOOTMGR_MULTI_OS_COUNT);
1893+
1894+
/* Check if the display is already active and cached */
1895+
if (!BmDisplayStateCached)
1896+
{
1897+
/* Check if we should display a boot menu */
1898+
Status = BlGetBootOptionBoolean(BlpApplicationEntry.BcdData,
1899+
BcdBootMgrBoolean_DisplayBootMenu,
1900+
&BmpDisplayBootMenu);
1901+
if (!NT_SUCCESS(Status))
1902+
{
1903+
/* Assume not */
1904+
BmpDisplayBootMenu = FALSE;
1905+
}
1906+
}
1907+
1908+
/* Check if there's only one entry to boot anyway */
1909+
if (Count == 1)
1910+
{
1911+
/* Read it */
1912+
SelectedEntry = *Sequence;
1913+
1914+
/* Process it */
1915+
BmpProcessBootEntry(BcdHandle, SelectedEntry, ExitBootManager);
1916+
1917+
/* Check if we're not displaying a boot menu */
1918+
if (!BmpDisplayBootMenu)
1919+
{
1920+
/* Now we are */
1921+
BmpDisplayBootMenu = TRUE;
1922+
1923+
/* Return the entry and its index back */
1924+
*EntryIndex = 0;
1925+
*SelectedBootEntry = SelectedEntry;
1926+
Status = STATUS_SUCCESS;
1927+
goto Quickie;
1928+
}
1929+
}
1930+
else
1931+
{
1932+
/* Get the default boot entry */
1933+
BmpGetDefaultBootEntry(Sequence, Count, &SelectedEntry, &SelectedIndex);
1934+
1935+
/* Check if we have a failed boot entry array allocated */
1936+
//FoundFailedEntry = FALSE;
1937+
if (BmpFailedBootEntries)
1938+
{
1939+
/* Check if the default entry failed to boot */
1940+
if (BmpFailedBootEntries[SelectedIndex])
1941+
{
1942+
/* Loop through the current boot sequence */
1943+
for (SelectedIndex = 0; SelectedIndex < Count; SelectedIndex++)
1944+
{
1945+
/* Check if there's no sequence for this index, or it failed */
1946+
while (!(Sequence[SelectedIndex]) ||
1947+
(BmpFailedBootEntries[SelectedIndex]))
1948+
{
1949+
/* Remember that this is a failed entry */
1950+
SelectedEntry = Sequence[SelectedIndex];
1951+
//FoundFailedEntry = TRUE;
1952+
BmpDisplayBootMenu = FALSE;
1953+
}
1954+
}
1955+
}
1956+
}
1957+
1958+
/* Check if the entry is an OS loader */
1959+
if (SelectedEntry->Flags & BL_APPLICATION_ENTRY_WINLOAD)
1960+
{
1961+
// todo
1962+
EfiPrintf(L"todo path\r\n");
1963+
}
1964+
1965+
/* Check if there's no timeout */
1966+
Status = BlGetBootOptionInteger(BlpApplicationEntry.BcdData,
1967+
BcdBootMgrInteger_Timeout,
1968+
&Timeout);
1969+
if ((NT_SUCCESS(Status) && !(Timeout)))
1970+
{
1971+
/* There isn't, so just process the default entry right away */
1972+
BmpProcessBootEntry(BcdHandle, SelectedEntry, ExitBootManager);
1973+
1974+
/* Check if we're not displaying a boot menu */
1975+
if (!BmpDisplayBootMenu)
1976+
{
1977+
/* Now we are */
1978+
BmpDisplayBootMenu = TRUE;
1979+
1980+
/* Return the entry and its index back */
1981+
*EntryIndex = 0;
1982+
*SelectedBootEntry = SelectedEntry;
1983+
Status = STATUS_SUCCESS;
1984+
goto Quickie;
1985+
}
1986+
1987+
/* Remove the timeout for this boot instance */
1988+
BlRemoveBootOption(BlpApplicationEntry.BcdData,
1989+
BcdBootMgrInteger_Timeout);
1990+
}
1991+
}
1992+
1993+
/* Here is where we display the menu and list of tools */
1994+
EfiPrintf(L"Tool selection not yet implemented\r\n");
16921995
EfiStall(10000000);
16931996
*SelectedBootEntry = NULL;
16941997

@@ -1735,6 +2038,7 @@ BmpLaunchBootEntry (
17352038
)
17362039
{
17372040
EfiPrintf(L"Boot launch not yet implemented\r\n");
2041+
EfiStall(1000000000);
17382042
return STATUS_NOT_IMPLEMENTED;
17392043
}
17402044

reactos/boot/environ/include/bcd.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,15 @@ typedef enum BcdBootMgrElementTypes
191191
BcdBootMgrBoolean_PersistBootSequence = 0x26000031
192192
} BcdBootMgrElementTypes;
193193

194+
typedef enum _BcdResumeElementTypes {
195+
Reserved1 = 0x21000001,
196+
Reserved2 = 0x22000002,
197+
BcdResumeBoolean_UseCustomSettings = 0x26000003,
198+
BcdResumeDevice_AssociatedOsDevice = 0x21000005,
199+
BcdResumeBoolean_DebugOptionEnabled = 0x26000006,
200+
BcdResumeInteger_BootMenuPolicy = 0x25000008
201+
} BcdResumeElementTypes;
202+
194203
/* Undocumented */
195204
typedef enum BcdStartupElementTypes
196205
{

0 commit comments

Comments
 (0)