@@ -32,6 +32,10 @@ WCHAR BmpFileNameBuffer[128];
32
32
PWCHAR ParentFileName = L"" ;
33
33
34
34
BOOLEAN BmDisplayStateCached ;
35
+ PBL_LOADED_APPLICATION_ENTRY * BmpFailedBootEntries ;
36
+ PBL_LOADED_APPLICATION_ENTRY BmpSelectedBootEntry ;
37
+ BOOLEAN BmBootEntryOverridePresent ;
38
+ BOOLEAN BmpDisplayBootMenu ;
35
39
36
40
/* FUNCTIONS *****************************************************************/
37
41
@@ -1652,18 +1656,196 @@ BmEnumerateBootEntries (
1652
1656
return Status ;
1653
1657
}
1654
1658
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
+
1655
1835
NTSTATUS
1656
1836
BmpGetSelectedBootEntry (
1657
1837
_In_ HANDLE BcdHandle ,
1658
- _Out_ PBL_LOADED_APPLICATION_ENTRY * SelectedBootEntry ,
1838
+ _Out_ PBL_LOADED_APPLICATION_ENTRY * SelectedBootEntry ,
1659
1839
_Out_ PULONG EntryIndex ,
1660
1840
_Out_ PBOOLEAN ExitBootManager
1661
1841
)
1662
1842
{
1663
1843
NTSTATUS Status ;
1664
1844
PBL_LOADED_APPLICATION_ENTRY * Sequence ;
1665
1845
PBL_LOADED_APPLICATION_ENTRY Entry , SelectedEntry ;
1666
- ULONG Count , BootIndex ;
1846
+ ULONG Count , BootIndex , SelectedIndex ;
1847
+ // BOOLEAN FoundFailedEntry;
1848
+ ULONGLONG Timeout ;
1667
1849
1668
1850
/* Initialize locals */
1669
1851
BootIndex = 0 ;
@@ -1688,7 +1870,128 @@ BmpGetSelectedBootEntry (
1688
1870
goto Quickie ;
1689
1871
}
1690
1872
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" );
1692
1995
EfiStall (10000000 );
1693
1996
* SelectedBootEntry = NULL ;
1694
1997
@@ -1735,6 +2038,7 @@ BmpLaunchBootEntry (
1735
2038
)
1736
2039
{
1737
2040
EfiPrintf (L"Boot launch not yet implemented\r\n" );
2041
+ EfiStall (1000000000 );
1738
2042
return STATUS_NOT_IMPLEMENTED ;
1739
2043
}
1740
2044
0 commit comments