ReactOS 0.4.16-dev-297-gc569aee
bootmgr.h File Reference
#include <stdlib.h>
#include <stdio.h>
#include <wchar.h>
#include <initguid.h>
#include <ntifs.h>
#include <Uefi.h>
#include <bl.h>
#include <bcd.h>
#include <bootmsg.h>
Include dependency graph for bootmgr.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  _BL_BOOT_ERROR
 
struct  _BL_PACKED_BOOT_ERROR
 

Macros

#define BL_FATAL_ERROR_BCD_READ   0x01
 
#define BL_FATAL_ERROR_APP_LOAD   0x02
 
#define BL_FATAL_ERROR_BCD_ENTRIES   0x03
 
#define BL_FATAL_ERROR_GENERIC   0x04
 
#define BL_FATAL_ERROR_BCD_PARSE   0x07
 
#define BL_FATAL_ERROR_NO_PAE   0x0B
 

Typedefs

typedef struct _BL_BOOT_ERROR BL_BOOT_ERROR
 
typedef struct _BL_BOOT_ERRORPBL_BOOT_ERROR
 
typedef struct _BL_PACKED_BOOT_ERROR BL_PACKED_BOOT_ERROR
 
typedef struct _BL_PACKED_BOOT_ERRORPBL_PACKED_BOOT_ERROR
 

Functions

NTSTATUS NTAPI BmMain (_In_ PBOOT_APPLICATION_PARAMETER_BLOCK BootParameters)
 
NTSTATUS BmpLaunchBootEntry (_In_ PBL_LOADED_APPLICATION_ENTRY BootEntry, _Out_ PULONG EntryIndex, _In_ ULONG LaunchCode, _In_ BOOLEAN LaunchWinRe)
 

Macro Definition Documentation

◆ BL_FATAL_ERROR_APP_LOAD

#define BL_FATAL_ERROR_APP_LOAD   0x02

Definition at line 56 of file bootmgr.h.

◆ BL_FATAL_ERROR_BCD_ENTRIES

#define BL_FATAL_ERROR_BCD_ENTRIES   0x03

Definition at line 57 of file bootmgr.h.

◆ BL_FATAL_ERROR_BCD_PARSE

#define BL_FATAL_ERROR_BCD_PARSE   0x07

Definition at line 59 of file bootmgr.h.

◆ BL_FATAL_ERROR_BCD_READ

#define BL_FATAL_ERROR_BCD_READ   0x01

Definition at line 55 of file bootmgr.h.

◆ BL_FATAL_ERROR_GENERIC

#define BL_FATAL_ERROR_GENERIC   0x04

Definition at line 58 of file bootmgr.h.

◆ BL_FATAL_ERROR_NO_PAE

#define BL_FATAL_ERROR_NO_PAE   0x0B

Definition at line 60 of file bootmgr.h.

Typedef Documentation

◆ BL_BOOT_ERROR

◆ BL_PACKED_BOOT_ERROR

◆ PBL_BOOT_ERROR

◆ PBL_PACKED_BOOT_ERROR

Function Documentation

◆ BmMain()

Definition at line 2736 of file bootmgr.c.

2739{
2740 NTSTATUS Status, LibraryStatus;
2741 BL_LIBRARY_PARAMETERS LibraryParameters;
2742 PBL_RETURN_ARGUMENTS ReturnArguments;
2743 PGUID AppIdentifier;
2744 HANDLE BcdHandle, ResumeBcdHandle;
2745 PBL_BCD_OPTION EarlyOptions;
2746 PWCHAR Stylesheet;
2747 BOOLEAN XmlLoaded, DisableIntegrity, TestSigning, PersistBootSequence;
2748 BOOLEAN RebootOnError, CustomActions;
2749 ULONG SequenceId;
2751 PGUID SequenceList;
2752 ULONG SequenceListCount;
2753 PBL_LOADED_APPLICATION_ENTRY* BootSequence;
2754 ULONG BootIndex;
2755 BOOLEAN ExitBootManager;
2756 BOOLEAN BootFailed;
2757 BOOLEAN BootOk;
2758 ULONG SequenceCount;
2759 BOOLEAN GetEntry;
2760 EfiPrintf(L"ReactOS UEFI Boot Manager Initializing...\r\n");
2761
2762 /* Reading the BCD can change this later on */
2763 RebootOnError = FALSE;
2764
2765 /* Save the start/end-of-POST time */
2766#if defined(_M_IX86) || defined(_M_X64)
2768#else
2769 EfiPrintf(L"No time source defined for this platform\r\n");
2771#endif
2773
2774 /* Setup the boot library parameters for this application */
2775 BlSetupDefaultParameters(&LibraryParameters);
2776 LibraryParameters.TranslationType = BlNone;
2777 LibraryParameters.LibraryFlags = 0x400 | 0x8;
2778 LibraryParameters.MinimumAllocationCount = 16;
2779 LibraryParameters.MinimumHeapSize = 512 * 1024;
2780
2781 /* Initialize the boot library */
2782 Status = BlInitializeLibrary(BootParameters, &LibraryParameters);
2783 if (!NT_SUCCESS(Status))
2784 {
2785 /* Check for failure due to invalid application entry */
2787 {
2788 /* Specifically print out what happened */
2789 EfiPrintf(L"BlInitializeLibrary failed 0x%x\r\n", Status);
2790 }
2791
2792 /* Go to exit path */
2793 goto Quickie;
2794 }
2795
2796 /* Get the application identifier */
2797 AppIdentifier = BlGetApplicationIdentifier();
2798 if (!AppIdentifier)
2799 {
2800 /* None was given, so set our default one */
2801 AppIdentifier = (PGUID)&GUID_WINDOWS_BOOTMGR;
2802 }
2803
2804 /* Save our identifier */
2805 BmApplicationIdentifier = *AppIdentifier;
2806
2807 /* Initialize the file system to open a handle to our root boot directory */
2809
2810 /* Load and initialize the boot configuration database (BCD) */
2811 Status = BmOpenDataStore(&BcdHandle);
2812 if (NT_SUCCESS(Status))
2813 {
2814 /* Copy the boot options */
2816 if (NT_SUCCESS(Status))
2817 {
2818 /* Update them */
2820 if (!NT_SUCCESS(Status))
2821 {
2822 /* Log a fatal error */
2824 (ULONG_PTR)L"\\BCD",
2825 Status,
2826 0,
2827 0);
2828 }
2829 }
2830 }
2831
2832#ifdef _SECURE_BOOT
2833 /* Initialize the secure boot machine policy */
2834 Status = BmSecureBootInitializeMachinePolicy();
2835 if (!NT_SUCCESS(Status))
2836 {
2837 BmFatalErrorEx(BL_FATAL_ERROR_SECURE_BOOT, Status, 0, 0, 0);
2838 }
2839#endif
2840
2841 /* Copy the library parameters and add the re-initialization flag */
2842 RtlCopyMemory(&LibraryParameters,
2844 sizeof(LibraryParameters));
2845 LibraryParameters.LibraryFlags |= (BL_LIBRARY_FLAG_REINITIALIZE_ALL |
2847
2848 /* Now that we've parsed the BCD, re-initialize the library */
2849 LibraryStatus = BlInitializeLibrary(BootParameters, &LibraryParameters);
2850 if (!NT_SUCCESS(LibraryStatus) && (NT_SUCCESS(Status)))
2851 {
2852 Status = LibraryStatus;
2853 }
2854
2855 /* Initialize firmware-specific memory regions */
2857
2858 /* Initialize the boot status data log (BSD) */
2860
2861 /* Find our XSL stylesheet */
2862 Stylesheet = BlResourceFindHtml();
2863 if (!Stylesheet)
2864 {
2865 /* Awe, no XML. This is actually fatal lol. Can't boot without XML. */
2867 EfiPrintf(L"BlResourceFindMessage failed 0x%x\r\n", STATUS_NOT_FOUND);
2868 goto Quickie;
2869 }
2870
2871 /* Initialize the XML Engine (as a side-effect, resets cursor) */
2872 Status = BlXmiInitialize(Stylesheet);
2873 if (!NT_SUCCESS(Status))
2874 {
2875 EfiPrintf(L"\r\nBlXmiInitialize failed 0x%x\r\n", Status);
2876 goto Failure;
2877 }
2878 XmlLoaded = TRUE;
2879
2880 /* Check if there's an active bitmap visible */
2882 {
2883 /* Nope, make the screen black using BGFX */
2884 if (!NT_SUCCESS(BmpBgDisplayClearScreen(0xFF000000)))
2885 {
2886 /* BGFX isn't active, use standard display */
2888 }
2889 }
2890
2891#ifdef _BIT_LOCKER_
2892 /* Bitlocker will take over screen UI if enabled */
2893 FveDisplayScreen = BmFveDisplayScreen;
2894#endif
2895
2896 /* Check if any bypass options are enabled */
2898 &DisableIntegrity,
2899 &TestSigning);
2900 if (!DisableIntegrity)
2901 {
2902 /* Integrity checks are enabled, so validate our signature */
2904 if (!NT_SUCCESS(Status))
2905 {
2906 /* Signature invalid, fail boot */
2907 goto Failure;
2908 }
2909 }
2910
2911
2912 /* TEST MODE */
2913 EfiPrintf(L"Performing memory allocator tests...\r\n");
2914 {
2916 PHYSICAL_ADDRESS PhysicalAddress, PhysicalAddress2;
2917
2918 /* Allocate 1 physical page */
2921 if (Status != STATUS_SUCCESS)
2922 {
2923 EfiPrintf(L"FAIL: Allocation status: %lx at address: %llx\r\n", Status, PhysicalAddress.QuadPart);
2924 EfiStall(100000000);
2925 }
2926
2927 /* Write some data */
2928 *(PULONG)((ULONG_PTR)PhysicalAddress.QuadPart) = 0x55555151;
2929
2930 /* Free it */
2932 if (Status != STATUS_SUCCESS)
2933 {
2934 EfiPrintf(L"FAIL: Memory free status: %lx\r\n", Status);
2935 EfiStall(100000000);
2936 }
2937
2938 /* Allocate a page again */
2939 PhysicalAddress2.QuadPart = 0;
2940 Status = BlMmAllocatePhysicalPages(&PhysicalAddress2, BlLoaderData, 1, 0, 1);
2941 if (Status != STATUS_SUCCESS)
2942 {
2943 EfiPrintf(L"FAIL: Allocation status: %lx at address: %llx\r\n", Status, PhysicalAddress2.QuadPart);
2944 EfiStall(100000000);
2945 }
2946
2947 /* It should've given us the same page, since we freed it */
2948 if (PhysicalAddress.QuadPart != PhysicalAddress2.QuadPart)
2949 {
2950 EfiPrintf(L"FAIL: Non-matching addresses: %llx %llx\r\n", PhysicalAddress.QuadPart, PhysicalAddress2.QuadPart);
2951 EfiStall(100000000);
2952 }
2953
2954 /* The data should still be there, since zero-ing is not on for bootmgr */
2955 if (*(PULONG)((ULONG_PTR)PhysicalAddress2.QuadPart) != 0x55555151)
2956 {
2957 EfiPrintf(L"FAIL: Non-matching data: %lx %lx\r\n", 0x55555151, *(PULONG)((ULONG_PTR)PhysicalAddress2.QuadPart));
2958 EfiStall(100000000);
2959 }
2960
2961 /* And free the second page again */
2963 if (Status != STATUS_SUCCESS)
2964 {
2965 EfiPrintf(L"FAIL: Memory free status: %lx\r\n", Status);
2966 EfiStall(100000000);
2967 }
2968 }
2969
2970 /* Write out the first XML tag */
2971 BlXmiWrite(L"<bootmgr/>");
2972
2973 /* Check for factory reset */
2975
2976 /* Load the revocation list */
2978 if (!NT_SUCCESS(Status))
2979 {
2980 goto Failure;
2981 }
2982
2983 /* Register our custom progress routine */
2985
2986 /* Display state is not currently cached */
2988
2989 /* Check if we need to resume from hibernate */
2990 Status = BmResumeFromHibernate(&ResumeBcdHandle);
2991 if (!NT_SUCCESS(Status))
2992 {
2993 goto Failure;
2994 }
2995
2996#ifdef BL_NET_SUPPORT
2997 /* Register multicast printing routine */
2998 BlUtlRegisterMulticastRoutine();
2999#endif
3000
3001 /* Check if restart on failure is enabled */
3004 &RebootOnError);
3005
3006 /* Check if the boot sequence is persisted */
3009 &PersistBootSequence);
3010 if (!NT_SUCCESS(Status))
3011 {
3012 /* It usually is */
3013 PersistBootSequence = TRUE;
3014 }
3015
3016 /* Check if there's custom actions to take */
3019 &CustomActions);
3020 if ((NT_SUCCESS(Status)) && (CustomActions))
3021 {
3022 /* We don't support this yet */
3023 EfiPrintf(L"Not implemented\r\n");
3025 goto Failure;
3026 }
3027
3028 //BlResourceFindMessage(BM_MSG_TEST);
3029
3030 /* At last, enter the boot selection stage */
3031 SequenceId = 0;
3032 GetEntry = FALSE;
3033 BootFailed = FALSE;
3034 SequenceList = NULL;
3035 BootSequence = NULL;
3036 SequenceCount = 0;
3037 while (1)
3038 {
3039 /* We don't have a boot entry nor a sequence ID */
3040 BootEntry = NULL;
3041 BootOk = FALSE;
3042
3043 /* Do we have a hardcoded boot sequence set? */
3044 if (!(BootSequence) && !(GetEntry))
3045 {
3046 /* Not yet, read the BCD to see if one is there */
3049 &SequenceList,
3050 &SequenceListCount);
3051 if (NT_SUCCESS(Status))
3052 {
3053 /* A GUID list for the boot sequence is set. Extract it */
3054 Status = BmGetBootSequence(BcdHandle,
3055 SequenceList,
3056 SequenceListCount,
3058 &BootSequence,
3059 &SequenceCount);
3060 if (NT_SUCCESS(Status))
3061 {
3062 /* Don't get stuck in a loop repeating this sequence */
3065
3066 /* But do check if we should persist it */
3067 if (PersistBootSequence)
3068 {
3069 /* Yes -- so go select an entry now */
3070 GetEntry = TRUE;
3071 }
3072 else
3073 {
3074 /* We shouldn't, so wipe it from the BCD too */
3075 Status = BmPurgeOption(BcdHandle,
3078 if (!NT_SUCCESS(Status))
3079 {
3080 /* Well that failed */
3081 goto LoopQuickie;
3082 }
3083 }
3084 }
3085 }
3086 else
3087 {
3088 /* No boot entry sequence for us */
3089 BootSequence = NULL;
3090 }
3091 }
3092
3093 /* Do we have a sequence active, and are we still processing it? */
3094 if ((BootSequence) && ((GetEntry) || (SequenceId < SequenceCount)))
3095 {
3096 /* Extract the next entry in the sequence */
3097 BootEntry = BootSequence[SequenceId];
3098 BootSequence[SequenceId] = NULL;
3099
3100 /* Move to the next entry for next time */
3101 SequenceId++;
3102
3103 /* Unless there won't be a a next time? */
3104 if (SequenceId == SequenceCount)
3105 {
3106 /* Clean up, it's the last entry */
3107 BlMmFreeHeap(BootSequence);
3108 BootSequence = NULL;
3109 }
3110 }
3111 else
3112 {
3113 /* Get the selected boot entry from the user */
3114 ExitBootManager = FALSE;
3115 Status = BmpGetSelectedBootEntry(BcdHandle,
3116 &BootEntry,
3117 &BootIndex,
3118 &ExitBootManager);
3119 if (!(NT_SUCCESS(Status)) || (ExitBootManager))
3120 {
3121 /* Selection failed, or user wants to exit */
3122 goto LoopQuickie;
3123 }
3124 }
3125
3126 /* Did we have a BCD open? */
3127 if (BcdHandle)
3128 {
3129 /* Close it, we'll be opening a new one */
3130 BmCloseDataStore(BcdHandle);
3131 BcdHandle = NULL;
3132 }
3133
3134 /* Launch the selected entry */
3135 Status = BmpLaunchBootEntry(BootEntry, &BootIndex, 0, TRUE);
3136 if (NT_SUCCESS(Status))
3137 {
3138 /* Boot worked, uncache display and process the bad memory list */
3141 }
3142 else
3143 {
3144 /* Boot failed -- was it user driven? */
3145 if (Status != STATUS_CANCELLED)
3146 {
3147 /* Nope, remember that booting failed */
3148 BootFailed = TRUE;
3149 goto LoopQuickie;
3150 }
3151
3152 /* Yes -- the display is still valid */
3154 }
3155
3156 /* Reopen the BCD */
3157 Status = BmOpenDataStore(&BcdHandle);
3158 if (!NT_SUCCESS(Status))
3159 {
3160 break;
3161 }
3162
3163 /* Put the BCD options back into our entry */
3165
3166 /* Update our options one more time */
3168 if (NT_SUCCESS(Status))
3169 {
3170 /* Boot was 100% OK */
3171 BootOk = TRUE;
3172 }
3173
3174LoopQuickie:
3175 /* Did we have a boot entry? */
3176 if (BootEntry)
3177 {
3178 /* We can destroy it now */
3179 BlDestroyBootEntry(BootEntry);
3180 }
3181
3182 /* Is this the success path? */
3183 if (NT_SUCCESS(Status))
3184 {
3185 /* Did we actually boot something? */
3186 if (!BootOk)
3187 {
3188 /* Bope, fail out */
3189 break;
3190 }
3191 }
3192
3193 /* This is the failure path... should we reboot? */
3194 if (RebootOnError)
3195 {
3196 break;
3197 }
3198 };
3199
3200Failure:
3201 if (!BootFailed)
3202 {
3203 /* Check if we got here due to an internal error */
3205 {
3206 /* If XML is available, display the error */
3207 if (XmlLoaded)
3208 {
3209 //BmDisplayDumpError(0, 0);
3210 //BmErrorPurge();
3211 }
3212
3213 /* Don't do a fatal error -- return back to firmware */
3214 goto Quickie;
3215 }
3216 }
3217
3218 /* Log a general fatal error once we're here */
3220
3221Quickie:
3222 /* Check if we should reboot */
3223 if ((RebootOnError) ||
3225 {
3226 /* Reboot the box */
3227 BlFwReboot();
3229 }
3230 else
3231 {
3232 /* Return back to the caller with the error argument encoded */
3233 ReturnArguments = (PVOID)((ULONG_PTR)BootParameters + BootParameters->ReturnArgumentsOffset);
3234 ReturnArguments->Version = BL_RETURN_ARGUMENTS_VERSION;
3235 ReturnArguments->Status = Status;
3236
3237 /* Tear down the boot library */
3239 }
3240
3241 /* Return back status */
3242 return Status;
3243}
unsigned char BOOLEAN
LONG NTSTATUS
Definition: precomp.h:26
@ BcdBootMgrBoolean_ProcessCustomActionsFirst
Definition: bcd.h:194
@ BcdBootMgrBoolean_PersistBootSequence
Definition: bcd.h:196
@ BcdBootMgrObjectList_BootSequence
Definition: bcd.h:184
@ BcdLibraryBoolean_RestartOnFailure
Definition: bcd.h:98
GUID * PGUID
Definition: bdasup.h:12
NTSTATUS BlGetBootOptionBoolean(_In_ PBL_BCD_OPTION List, _In_ ULONG Type, _Out_ PBOOLEAN Value)
Definition: bcdopt.c:504
#define BL_APPLICATION_ENTRY_FIXED_SEQUENCE
Definition: bl.h:80
NTSTATUS BlMmAllocatePhysicalPages(_Inout_ PPHYSICAL_ADDRESS Address, _In_ BL_MEMORY_TYPE MemoryType, _In_ ULONGLONG PageCount, _In_ ULONG Attributes, _In_ ULONG Alignment)
VOID BlImgQueryCodeIntegrityBootOptions(_In_ PBL_LOADED_APPLICATION_ENTRY ApplicationEntry, _Out_ PBOOLEAN IntegrityChecksDisabled, _Out_ PBOOLEAN TestSigning)
Definition: image.c:651
@ BlLoaderData
Definition: bl.h:313
VOID BlDestroyBootEntry(_In_ PBL_LOADED_APPLICATION_ENTRY AppEntry)
Definition: bootlib.c:442
NTSTATUS BlInitializeLibrary(_In_ PBOOT_APPLICATION_PARAMETER_BLOCK BootAppParameters, _In_ PBL_LIBRARY_PARAMETERS LibraryParameters)
Definition: bootlib.c:355
VOID EfiPrintf(_In_ PWCHAR Format,...)
Definition: firmware.c:126
NTSTATUS BlUtlRegisterProgressRoutine(VOID)
Definition: util.c:244
NTSTATUS BlGetBootOptionGuidList(_In_ PBL_BCD_OPTION List, _In_ ULONG Type, _Out_ PGUID *Value, _In_ PULONG Count)
Definition: bcdopt.c:266
@ BlNone
Definition: bl.h:230
NTSTATUS BlReplaceBootOptions(_In_ PBL_LOADED_APPLICATION_ENTRY AppEntry, _In_ PBL_BCD_OPTION NewOptions)
Definition: bcdopt.c:824
NTSTATUS BlMmFreePhysicalPages(_In_ PHYSICAL_ADDRESS Address)
Definition: pagealloc.c:1187
#define BL_LIBRARY_FLAG_REINITIALIZE
Definition: bl.h:128
PWCHAR BlResourceFindHtml(VOID)
Definition: resource.c:305
NTSTATUS BlSecureBootCheckForFactoryReset(VOID)
Definition: firmware.c:759
NTSTATUS EfiStall(_In_ ULONG StallTime)
Definition: firmware.c:1003
VOID BlRemoveBootOption(_In_ PBL_BCD_OPTION List, _In_ ULONG Type)
Definition: bcdopt.c:801
PGUID BlGetApplicationIdentifier(VOID)
Definition: bootlib.c:414
FORCEINLINE VOID BlSetupDefaultParameters(_Out_ PBL_LIBRARY_PARAMETERS LibraryParameters)
Definition: bl.h:1354
BL_LIBRARY_PARAMETERS BlpLibraryParameters
Definition: bootlib.c:15
VOID BlDestroyLibrary(VOID)
Definition: bootlib.c:405
BOOLEAN BlDisplayValidOemBitmap(VOID)
Definition: display.c:880
#define BL_LIBRARY_FLAG_REINITIALIZE_ALL
Definition: bl.h:129
NTSTATUS BlCopyBootOptions(_In_ PBL_BCD_OPTION OptionList, _Out_ PBL_BCD_OPTION *CopiedOptions)
Definition: bcdopt.c:597
VOID BlFwReboot(VOID)
Definition: fwutil.c:14
BL_LOADED_APPLICATION_ENTRY BlpApplicationEntry
Definition: bootlib.c:19
NTSTATUS BlMmFreeHeap(_In_ PVOID Buffer)
Definition: heapalloc.c:663
NTSTATUS BlDisplayClearScreen(VOID)
Definition: display.c:943
#define BL_RETURN_ARGUMENTS_VERSION
Definition: bl.h:63
#define BL_APPLICATION_ENTRY_REBOOT_ON_ERROR
Definition: bl.h:72
#define BL_FATAL_ERROR_GENERIC
Definition: bootmgr.h:58
#define BL_FATAL_ERROR_BCD_PARSE
Definition: bootmgr.h:59
#define STATUS_NOT_IMPLEMENTED
Definition: d3dkmdt.h:42
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
VOID BmpInitializeBootStatusDataLog(VOID)
Definition: bootmgr.c:951
NTSTATUS BmpProcessBadMemory(VOID)
Definition: bootmgr.c:1163
NTSTATUS BmpBgDisplayClearScreen(_In_ ULONG Color)
Definition: bootmgr.c:1056
NTSTATUS BlXmiWrite(_In_ PWCHAR XmlTag)
Definition: bootmgr.c:1065
NTSTATUS BmGetBootSequence(_In_ HANDLE BcdHandle, _In_ PGUID SequenceList, _In_ ULONG SequenceListCount, _In_ ULONG Flags, _Out_ PBL_LOADED_APPLICATION_ENTRY **BootSequence, _Out_ PULONG SequenceCount)
Definition: bootmgr.c:1465
NTSTATUS BmFwVerifySelfIntegrity(VOID)
Definition: bootmgr.c:1087
NTSTATUS BmFwInitializeBootDirectoryPath(VOID)
Definition: bootmgr.c:301
VOID BmCloseDataStore(_In_ HANDLE Handle)
Definition: bootmgr.c:695
NTSTATUS BlXmiInitialize(_In_ PWCHAR Stylesheet)
Definition: bootmgr.c:1075
VOID BmFatalErrorEx(_In_ ULONG ErrorCode, _In_ ULONG_PTR Parameter1, _In_ ULONG_PTR Parameter2, _In_ ULONG_PTR Parameter3, _In_ ULONG_PTR Parameter4)
Definition: bootmgr.c:498
NTSTATUS BmpLaunchBootEntry(_In_ PBL_LOADED_APPLICATION_ENTRY BootEntry, _Out_ PULONG EntryIndex, _In_ ULONG LaunchCode, _In_ BOOLEAN LaunchWinRe)
Definition: bootmgr.c:2426
NTSTATUS BmOpenDataStore(_Out_ PHANDLE Handle)
Definition: bootmgr.c:711
NTSTATUS BmFwRegisterRevocationList(VOID)
Definition: bootmgr.c:1105
BOOLEAN BmDisplayStateCached
Definition: bootmgr.c:34
NTSTATUS BmPurgeOption(_In_ HANDLE BcdHandle, _In_ PGUID ObjectId, _In_ ULONG Type)
Definition: bootmgr.c:1187
ULONGLONG ApplicationStartTime
Definition: bootmgr.c:21
NTSTATUS BmpUpdateApplicationOptions(_In_ HANDLE BcdHandle)
Definition: bootmgr.c:208
ULONGLONG PostTime
Definition: bootmgr.c:22
NTSTATUS BmResumeFromHibernate(_Out_ PHANDLE BcdResumeHandle)
Definition: bootmgr.c:1130
GUID BmApplicationIdentifier
Definition: bootmgr.c:23
VOID BmFwMemoryInitialize(VOID)
Definition: bootmgr.c:1026
NTSTATUS BmpGetSelectedBootEntry(_In_ HANDLE BcdHandle, _Out_ PBL_LOADED_APPLICATION_ENTRY *SelectedBootEntry, _Out_ PULONG EntryIndex, _Out_ PBOOLEAN ExitBootManager)
Definition: bootmgr.c:1814
PBL_BOOT_ERROR BmpInternalBootError
Definition: bootmgr.c:27
Status
Definition: gdiplustypes.h:25
PPC_QUAL unsigned long long __rdtsc(void)
Definition: intrin_ppc.h:688
#define STATUS_INVALID_PARAMETER_9
Definition: ntstatus.h:483
#define L(x)
Definition: ntvdm.h:50
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_NOT_FOUND
Definition: shellext.h:72
ULONG MinimumHeapSize
Definition: bl.h:760
ULONG LibraryFlags
Definition: bl.h:757
ULONG MinimumAllocationCount
Definition: bl.h:759
ULONG TranslationType
Definition: bl.h:758
Definition: bl.h:864
ULONG Flags
Definition: bl.h:865
PBL_BCD_OPTION BcdData
Definition: bl.h:867
ULONG Version
Definition: bl.h:816
NTSTATUS Status
Definition: bl.h:817
uint32_t * PULONG
Definition: typedefs.h:59
void * PVOID
Definition: typedefs.h:50
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
uint32_t ULONG_PTR
Definition: typedefs.h:65
uint16_t * PWCHAR
Definition: typedefs.h:56
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_CANCELLED
Definition: udferr_usr.h:170
LONGLONG QuadPart
Definition: typedefs.h:114
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS PhysicalAddress
Definition: iotypes.h:1098

Referenced by EfiEntry().

◆ BmpLaunchBootEntry()

NTSTATUS BmpLaunchBootEntry ( _In_ PBL_LOADED_APPLICATION_ENTRY  BootEntry,
_Out_ PULONG  EntryIndex,
_In_ ULONG  LaunchCode,
_In_ BOOLEAN  LaunchWinRe 
)

Definition at line 2426 of file bootmgr.c.

2432{
2433 HANDLE BcdHandle;
2435 GUID ObjectId;
2436 BOOLEAN DoRecovery, AutoRecovery, DoSequence, RestartOnFailure;
2438 BOOLEAN AdvancedOneTime, EditOneTime;
2439
2440 /* Check if this is the OS loader */
2441 if (BootEntry->Flags & BL_APPLICATION_ENTRY_WINLOAD)
2442 {
2443 /* Check if one-time advanced options should be shown */
2444 if (MiscGetBootOption(BootEntry->BcdData,
2446 {
2447 /* Open the BCD */
2448 BcdHandle = NULL;
2449 Status = BmOpenDataStore(BcdHandle);
2450 if (NT_SUCCESS(Status))
2451 {
2452 /* Delete the option from the BCD, so it doesn't happen again */
2453 ObjectId = BootEntry->Guid;
2454 BmPurgeOption(BcdHandle,
2455 &ObjectId,
2457 BmCloseDataStore(BcdHandle);
2458 }
2459 }
2460
2461 /* Check if one-time options editor should be shown */
2462 if (MiscGetBootOption(BootEntry->BcdData,
2464 {
2465 /* Open the BCD */
2466 BcdHandle = NULL;
2467 Status = BmOpenDataStore(BcdHandle);
2468 if (NT_SUCCESS(Status))
2469 {
2470 /* Delete the option from the BCD, so it doesn't happen again */
2471 ObjectId = BootEntry->Guid;
2472 BmPurgeOption(BcdHandle,
2473 &ObjectId,
2475 BmCloseDataStore(BcdHandle);
2476 }
2477 }
2478 }
2479
2480TryAgain:
2481 /* Disable recovery mode */
2482 DoRecovery = FALSE;
2483
2484 /* Store globally which entry we are trying to boot */
2485 BmpSelectedBootEntry = BootEntry;
2486
2487 /* Create any devices that aren't yet fully defined for this boot entry */
2488 Status = BmpCreateDevices(BootEntry);
2489 if (!NT_SUCCESS(Status))
2490 {
2491 /* That failed -- can we launch the recovery environment? */
2492 if (!LaunchWinRe)
2493 {
2494 return Status;
2495 }
2496
2497 /* Yes, so return with the WinRe launch code */
2498 LaunchCode = 2;
2499 goto Quickie;
2500 }
2501
2502 /* Is this an OS loader/ */
2503 if (BootEntry->Flags & BL_APPLICATION_ENTRY_WINLOAD)
2504 {
2505 /* Is the one-time advanced options menu option present? */
2506 Status = BlGetBootOptionBoolean(BootEntry->BcdData,
2508 &AdvancedOneTime);
2509 if (NT_SUCCESS(Status))
2510 {
2511 /* Is it turned on? */
2512 if (AdvancedOneTime)
2513 {
2514 /* Set the option this once */
2515 BlAppendBootOptionBoolean(BootEntry,
2517 TRUE);
2518 }
2519 else
2520 {
2521 /* It's not, so disable the option if active */
2522 BlRemoveBootOption(BootEntry->BcdData,
2524 }
2525
2526 /* Remove the one-time option. We've already purged it earlier */
2527 BlRemoveBootOption(BootEntry->BcdData,
2529 }
2530
2531 /* Is the one-time options editor menu option present? */
2532 Status = BlGetBootOptionBoolean(BootEntry->BcdData,
2534 &EditOneTime);
2535 if (NT_SUCCESS(Status))
2536 {
2537 /* Is it turned on? */
2538 if (EditOneTime)
2539 {
2540 /* Set the option this once */
2541 BlAppendBootOptionBoolean(BootEntry,
2543 TRUE);
2544 }
2545 else
2546 {
2547 /* It's not, so disable the option if active */
2548 BlRemoveBootOption(BootEntry->BcdData,
2550 }
2551
2552 /* Remove the one-time option. We've already purged it earlier */
2553 BlRemoveBootOption(BootEntry->BcdData,
2555 }
2556 }
2557
2558 /* BCD handling done, transfer execution to this entry */
2559 Status = BmpTransferExecution(BootEntry, &LaunchCode, &DoRecovery);
2560 if (!LaunchWinRe)
2561 {
2562 return Status;
2563 }
2564
2565 /* Check if boot was successful, or cancelled and we're not doing WinRE */
2566 if (((NT_SUCCESS(Status)) || (Status == STATUS_CANCELLED)) && !(DoRecovery))
2567 {
2568 return Status;
2569 }
2570
2571 /* Boot failed -- are we doing recovery? */
2572 if (!DoRecovery)
2573 {
2574 /* Nope, bail out */
2575 LaunchCode = 2;
2576 goto Quickie;
2577 }
2578
2579Quickie:
2580 /* Get the recovery sequence */
2582 {
2583 /* Check if the launch depends on auto-recovery being enabled or not */
2584 if ((LaunchCode == 3) || (LaunchCode == 5) || (LaunchCode == 6))
2585 {
2586 Status = BlGetBootOptionBoolean(BootEntry->BcdData,
2588 &AutoRecovery);
2589 if (NT_SUCCESS(Status))
2590 {
2591 /* Override the setting */
2592 DoRecovery = AutoRecovery;
2593 }
2594 }
2595 }
2596 else
2597 {
2598 /* There's no recovery setting */
2599 DoRecovery = FALSE;
2600 }
2601
2602 /* Check if we should restart on failure */
2603 RestartOnFailure = FALSE;
2606 &RestartOnFailure);
2607
2608 /* Do the sequence if recovery is on, unless we should restart instead */
2609 DoSequence = RestartOnFailure ? FALSE : DoRecovery;
2610 while (1)
2611 {
2612 /* Are we doing the recovery sequence? */
2613 if (DoSequence)
2614 {
2615 /* Because of automatic recovery? */
2616 if (AutoRecovery)
2617 {
2618#if BL_BITLOCKER_SUPPORT
2619 /* Do bitlocker stuff */
2620 BlFveRegisterBootEntryForTrustedWimBoot(BootEntry, TRUE);
2621#endif
2622 }
2623
2624 /* Launch the recovery sequence*/
2625 Status = BmLaunchRecoverySequence(BootEntry, LaunchCode);
2626
2627 /* Was it launched automatically? */
2628 if (AutoRecovery)
2629 {
2630#if BL_BITLOCKER_SUPPORT
2631 /* Do bitlocker stuff */
2632 BlFveRegisterBootEntryForTrustedWimBoot(BootEntry, FALSE);
2633#endif
2634
2635 /* No need to do this again */
2636 AutoRecovery = FALSE;
2637 }
2638
2639 /* Did the recovery sequence work? */
2640 if (NT_SUCCESS(Status))
2641 {
2642 /* All good */
2643 return STATUS_SUCCESS;
2644 }
2645
2646 /* Remove the sequence, don't do it again */
2648 }
2649
2650 /* Recovery sequence also failed, show fatal error */
2652 {
2654 }
2655
2656 /* Display the error menu */
2657 ErrorCode = BmDisplayDumpError(BootEntry, LaunchCode);
2658 BmErrorPurge();
2659
2660 /* See what the user wants to do */
2661 switch (ErrorCode)
2662 {
2663 case TryAgain:
2664 /* Try again */
2665 goto TryAgain;
2666
2667 case NextOs:
2668 /* Boot the next entry*/
2669 break;
2670
2671 case OsSelection:
2672 /* Cancel the boot*/
2673 return STATUS_CANCELLED;
2674
2675 case RecoverOem:
2676 /* Custom OEM recovery -- open the BCD */
2677 Status = BmOpenDataStore(BcdHandle);
2678 if (NT_SUCCESS(Status))
2679 {
2680 /* See what the custom sequence is */
2681 Status = BmProcessCustomAction(BcdHandle, NULL);
2682 }
2683
2684 /* All done, close the BCD */
2685 if (BcdHandle)
2686 {
2687 BmCloseDataStore(BcdHandle);
2688 }
2689 return Status;
2690
2691 case AdvancedOptions:
2692 /* Show the advanced options next iteration */
2693 BlAppendBootOptionBoolean(BootEntry,
2695 TRUE);
2696 goto TryAgain;
2697
2698 case BootOptions:
2699 /* Show the options editor next iteration */
2700 BlAppendBootOptionBoolean(BootEntry,
2702 TRUE);
2703 goto TryAgain;
2704
2705 case Recover:
2706 /* Try the recovery sequence next time*/
2707 DoSequence = TRUE;
2708 LaunchCode = 1;
2709 goto TryAgain;
2710
2711 default:
2712 /* Something unknown */
2713 return STATUS_CANCELLED;
2714 }
2715 }
2716
2717 /* We are booting the next OS, so return success as to not kill the boot */
2718 return STATUS_SUCCESS;
2719}
@ BcdOSLoaderBoolean_OptionsEditOneTime
Definition: bcd.h:158
@ BcdOSLoaderBoolean_AdvancedOptionsOneTime
Definition: bcd.h:157
@ BcdLibraryBoolean_AutoRecoveryEnabled
Definition: bcd.h:57
@ BcdLibraryBoolean_DisplayOptionsEdit
Definition: bcd.h:82
@ BcdLibraryObjectList_RecoverySequence
Definition: bcd.h:56
@ BcdLibraryBoolean_DisplayAdvancedOptions
Definition: bcd.h:81
@ BootOptions
Definition: bl.h:898
@ Recover
Definition: bl.h:892
@ RecoverOem
Definition: bl.h:893
@ AdvancedOptions
Definition: bl.h:897
@ NextOs
Definition: bl.h:895
@ TryAgain
Definition: bl.h:896
@ OsSelection
Definition: bl.h:894
PBL_BCD_OPTION MiscGetBootOption(_In_ PBL_BCD_OPTION List, _In_ ULONG Type)
Definition: bcdopt.c:17
#define BL_APPLICATION_ENTRY_WINLOAD
Definition: bl.h:70
NTSTATUS BlAppendBootOptionBoolean(_In_ PBL_LOADED_APPLICATION_ENTRY AppEntry, _In_ ULONG OptionId, _In_ BOOLEAN Value)
Definition: bcdopt.c:625
VOID BmErrorPurge(VOID)
Definition: bootmgr.c:445
NTSTATUS BmpCreateDevices(_In_ PBL_LOADED_APPLICATION_ENTRY BootEntry)
Definition: bootmgr.c:2170
PBL_LOADED_APPLICATION_ENTRY BmpSelectedBootEntry
Definition: bootmgr.c:36
NTSTATUS BmpTransferExecution(_In_ PBL_LOADED_APPLICATION_ENTRY BootEntry, _Out_ PULONG LaunchCode, _Out_ PBOOLEAN Recover)
Definition: bootmgr.c:2230
ULONG BmDisplayDumpError(_In_ PBL_LOADED_APPLICATION_ENTRY BootEntry, _In_ ULONG LaunchCode)
Definition: bootmgr.c:2127
NTSTATUS BmProcessCustomAction(_In_ HANDLE BcdHandle, _In_ PWCHAR ActionKey)
Definition: bootmgr.c:1764
NTSTATUS BmLaunchRecoverySequence(_In_ PBL_LOADED_APPLICATION_ENTRY BootEntry, _In_ ULONG LaunchCode)
Definition: bootmgr.c:2011
_In_ NDIS_ERROR_CODE ErrorCode
Definition: ndis.h:4436

Referenced by BmLaunchRecoverySequence(), and BmMain().