ReactOS  0.4.14-dev-41-g31d7680
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;
2750  PBL_LOADED_APPLICATION_ENTRY BootEntry;
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 */
2819  Status = BmpUpdateApplicationOptions(BcdHandle);
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 */
2881  if (!BlDisplayValidOemBitmap())
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  {
2915  NTSTATUS Status;
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 */
3164  BlReplaceBootOptions(&BlpApplicationEntry, EarlyOptions);
3165 
3166  /* Update our options one more time */
3167  Status = BmpUpdateApplicationOptions(BcdHandle);
3168  if (NT_SUCCESS(Status))
3169  {
3170  /* Boot was 100% OK */
3171  BootOk = TRUE;
3172  }
3173 
3174 LoopQuickie:
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 
3200 Failure:
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 
3221 Quickie:
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 */
3238  BlDestroyLibrary();
3239  }
3240 
3241  /* Return back status */
3242  return Status;
3243 }
#define BL_APPLICATION_ENTRY_REBOOT_ON_ERROR
Definition: bl.h:73
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
GUID * PGUID
Definition: bdasup.h:12
BL_LIBRARY_PARAMETERS BlpLibraryParameters
Definition: bootlib.c:15
#define BL_LIBRARY_FLAG_REINITIALIZE
Definition: bl.h:129
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
NTSTATUS BmResumeFromHibernate(_Out_ PHANDLE BcdResumeHandle)
Definition: bootmgr.c:1130
NTSTATUS BmPurgeOption(_In_ HANDLE BcdHandle, _In_ PGUID ObjectId, _In_ ULONG Type)
Definition: bootmgr.c:1187
VOID BlDestroyLibrary(VOID)
Definition: bootlib.c:405
NTSTATUS BlGetBootOptionGuidList(_In_ PBL_BCD_OPTION List, _In_ ULONG Type, _Out_ PGUID *Value, _In_ PULONG Count)
Definition: bcdopt.c:266
NTSTATUS EfiStall(_In_ ULONG StallTime)
Definition: firmware.c:1003
VOID BlFwReboot(VOID)
Definition: fwutil.c:14
ULONGLONG ApplicationStartTime
Definition: bootmgr.c:21
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:225
NTSTATUS BmFwVerifySelfIntegrity(VOID)
Definition: bootmgr.c:1087
NTSTATUS BmpBgDisplayClearScreen(_In_ ULONG Color)
Definition: bootmgr.c:1056
ULONG Version
Definition: bl.h:817
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS BmpLaunchBootEntry(_In_ PBL_LOADED_APPLICATION_ENTRY BootEntry, _Out_ PULONG EntryIndex, _In_ ULONG LaunchCode, _In_ BOOLEAN LaunchWinRe)
Definition: bootmgr.c:2426
#define STATUS_INVALID_PARAMETER_9
Definition: ntstatus.h:469
NTSTATUS BlDisplayClearScreen(VOID)
Definition: display.c:942
VOID BlRemoveBootOption(_In_ PBL_BCD_OPTION List, _In_ ULONG Type)
Definition: bcdopt.c:801
PPC_QUAL unsigned long long __rdtsc(void)
Definition: intrin_ppc.h:688
#define BL_FATAL_ERROR_GENERIC
Definition: bootmgr.h:58
NTSTATUS BlMmAllocatePhysicalPages(_Inout_ PPHYSICAL_ADDRESS Address, _In_ BL_MEMORY_TYPE MemoryType, _In_ ULONGLONG PageCount, _In_ ULONG Attributes, _In_ ULONG Alignment)
NTSTATUS BlXmiInitialize(_In_ PWCHAR Stylesheet)
Definition: bootmgr.c:1075
NTSTATUS BlMmFreePhysicalPages(_In_ PHYSICAL_ADDRESS Address)
Definition: pagealloc.c:1187
uint16_t * PWCHAR
Definition: typedefs.h:54
NTSTATUS BlMmFreeHeap(_In_ PVOID Buffer)
Definition: heapalloc.c:663
BL_LOADED_APPLICATION_ENTRY BlpApplicationEntry
Definition: bootlib.c:19
uint32_t ULONG_PTR
Definition: typedefs.h:63
GUID BmApplicationIdentifier
Definition: bootmgr.c:23
VOID BmpInitializeBootStatusDataLog(VOID)
Definition: bootmgr.c:951
PBL_BCD_OPTION BcdData
Definition: bl.h:868
ULONG LibraryFlags
Definition: bl.h:758
NTSTATUS BmFwInitializeBootDirectoryPath(VOID)
Definition: bootmgr.c:301
BOOLEAN BlDisplayValidOemBitmap(VOID)
Definition: display.c:879
ULONGLONG PostTime
Definition: bootmgr.c:22
#define BL_APPLICATION_ENTRY_FIXED_SEQUENCE
Definition: bl.h:81
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
NTSTATUS BlGetBootOptionBoolean(_In_ PBL_BCD_OPTION List, _In_ ULONG Type, _Out_ PBOOLEAN Value)
Definition: bcdopt.c:504
Definition: bl.h:864
void * PVOID
Definition: retypes.h:9
VOID BmFwMemoryInitialize(VOID)
Definition: bootmgr.c:1026
#define STATUS_NOT_FOUND
Definition: shellext.h:67
VOID BlDestroyBootEntry(_In_ PBL_LOADED_APPLICATION_ENTRY AppEntry)
Definition: bootlib.c:442
NTSTATUS BlReplaceBootOptions(_In_ PBL_LOADED_APPLICATION_ENTRY AppEntry, _In_ PBL_BCD_OPTION NewOptions)
Definition: bcdopt.c:824
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
Definition: bl.h:231
NTSTATUS BlCopyBootOptions(_In_ PBL_BCD_OPTION OptionList, _Out_ PBL_BCD_OPTION *CopiedOptions)
Definition: bcdopt.c:597
NTSTATUS BlSecureBootCheckForFactoryReset(VOID)
Definition: firmware.c:759
NTSTATUS BlInitializeLibrary(_In_ PBOOT_APPLICATION_PARAMETER_BLOCK BootAppParameters, _In_ PBL_LIBRARY_PARAMETERS LibraryParameters)
Definition: bootlib.c:355
#define STATUS_CANCELLED
Definition: udferr_usr.h:170
NTSTATUS BmpProcessBadMemory(VOID)
Definition: bootmgr.c:1163
FORCEINLINE VOID BlSetupDefaultParameters(_Out_ PBL_LIBRARY_PARAMETERS LibraryParameters)
Definition: bl.h:1355
PGUID BlGetApplicationIdentifier(VOID)
Definition: bootlib.c:414
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS PhysicalAddress
Definition: iotypes.h:1061
VOID BmCloseDataStore(_In_ HANDLE Handle)
Definition: bootmgr.c:695
ULONG MinimumHeapSize
Definition: bl.h:761
static const WCHAR L[]
Definition: oid.c:1250
NTSTATUS BmOpenDataStore(_Out_ PHANDLE Handle)
Definition: bootmgr.c:711
#define BL_FATAL_ERROR_BCD_PARSE
Definition: bootmgr.h:59
VOID BlImgQueryCodeIntegrityBootOptions(_In_ PBL_LOADED_APPLICATION_ENTRY ApplicationEntry, _Out_ PBOOLEAN IntegrityChecksDisabled, _Out_ PBOOLEAN TestSigning)
Definition: image.c:651
Status
Definition: gdiplustypes.h:24
ULONG TranslationType
Definition: bl.h:759
NTSTATUS BmpUpdateApplicationOptions(_In_ HANDLE BcdHandle)
Definition: bootmgr.c:208
unsigned int * PULONG
Definition: retypes.h:1
NTSTATUS BlUtlRegisterProgressRoutine(VOID)
Definition: util.c:244
VOID EfiPrintf(_In_ PWCHAR Format,...)
Definition: firmware.c:126
#define BL_LIBRARY_FLAG_REINITIALIZE_ALL
Definition: bl.h:130
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 BmFwRegisterRevocationList(VOID)
Definition: bootmgr.c:1105
ULONG MinimumAllocationCount
Definition: bl.h:760
ULONG Flags
Definition: bl.h:866
unsigned int ULONG
Definition: retypes.h:1
#define BL_RETURN_ARGUMENTS_VERSION
Definition: bl.h:64
BOOLEAN BmDisplayStateCached
Definition: bootmgr.c:34
PBL_BOOT_ERROR BmpInternalBootError
Definition: bootmgr.c:27
return STATUS_SUCCESS
Definition: btrfs.c:2966
PWCHAR BlResourceFindHtml(VOID)
Definition: resource.c:305
NTSTATUS Status
Definition: bl.h:818
LONGLONG QuadPart
Definition: typedefs.h:112
NTSTATUS BlXmiWrite(_In_ PWCHAR XmlTag)
Definition: bootmgr.c:1065
NTSTATUS BmpGetSelectedBootEntry(_In_ HANDLE BcdHandle, _Out_ PBL_LOADED_APPLICATION_ENTRY *SelectedBootEntry, _Out_ PULONG EntryIndex, _Out_ PBOOLEAN ExitBootManager)
Definition: bootmgr.c:1814

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;
2434  NTSTATUS Status;
2435  GUID ObjectId;
2436  BOOLEAN DoRecovery, AutoRecovery, DoSequence, RestartOnFailure;
2437  ULONG ErrorCode;
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 
2480 TryAgain:
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 
2579 Quickie:
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 */
2651  if (!BmpInternalBootError)
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 }
#define TRUE
Definition: types.h:120
_In_ NDIS_ERROR_CODE ErrorCode
Definition: ndis.h:4436
NTSTATUS BmPurgeOption(_In_ HANDLE BcdHandle, _In_ PGUID ObjectId, _In_ ULONG Type)
Definition: bootmgr.c:1187
VOID BmErrorPurge(VOID)
Definition: bootmgr.c:445
LONG NTSTATUS
Definition: precomp.h:26
VOID BlRemoveBootOption(_In_ PBL_BCD_OPTION List, _In_ ULONG Type)
Definition: bcdopt.c:801
#define BL_FATAL_ERROR_GENERIC
Definition: bootmgr.h:58
NTSTATUS BmLaunchRecoverySequence(_In_ PBL_LOADED_APPLICATION_ENTRY BootEntry, _In_ ULONG LaunchCode)
Definition: bootmgr.c:2011
BL_LOADED_APPLICATION_ENTRY BlpApplicationEntry
Definition: bootlib.c:19
PBL_BCD_OPTION BcdData
Definition: bl.h:868
NTSTATUS BmpCreateDevices(_In_ PBL_LOADED_APPLICATION_ENTRY BootEntry)
Definition: bootmgr.c:2170
Definition: bl.h:897
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
NTSTATUS BlGetBootOptionBoolean(_In_ PBL_BCD_OPTION List, _In_ ULONG Type, _Out_ PBOOLEAN Value)
Definition: bcdopt.c:504
PBL_LOADED_APPLICATION_ENTRY BmpSelectedBootEntry
Definition: bootmgr.c:36
Definition: bl.h:893
PBL_BCD_OPTION MiscGetBootOption(_In_ PBL_BCD_OPTION List, _In_ ULONG Type)
Definition: bcdopt.c:17
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
ULONG BmDisplayDumpError(_In_ PBL_LOADED_APPLICATION_ENTRY BootEntry, _In_ ULONG LaunchCode)
Definition: bootmgr.c:2127
#define STATUS_CANCELLED
Definition: udferr_usr.h:170
VOID BmCloseDataStore(_In_ HANDLE Handle)
Definition: bootmgr.c:695
NTSTATUS BmOpenDataStore(_Out_ PHANDLE Handle)
Definition: bootmgr.c:711
NTSTATUS BmProcessCustomAction(_In_ HANDLE BcdHandle, _In_ PWCHAR ActionKey)
Definition: bootmgr.c:1764
Status
Definition: gdiplustypes.h:24
Definition: bl.h:896
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
Definition: bl.h:894
unsigned int ULONG
Definition: retypes.h:1
PBL_BOOT_ERROR BmpInternalBootError
Definition: bootmgr.c:27
return STATUS_SUCCESS
Definition: btrfs.c:2966
NTSTATUS BmpTransferExecution(_In_ PBL_LOADED_APPLICATION_ENTRY BootEntry, _Out_ PULONG LaunchCode, _Out_ PBOOLEAN Recover)
Definition: bootmgr.c:2230
#define BL_APPLICATION_ENTRY_WINLOAD
Definition: bl.h:71
NTSTATUS BlAppendBootOptionBoolean(_In_ PBL_LOADED_APPLICATION_ENTRY AppEntry, _In_ ULONG OptionId, _In_ BOOLEAN Value)
Definition: bcdopt.c:625

Referenced by BmLaunchRecoverySequence(), and BmMain().