ReactOS  0.4.14-dev-368-gfa26425
bootmgr.c
Go to the documentation of this file.
1 /*
2  * COPYRIGHT: See COPYING.ARM in the top level directory
3  * PROJECT: ReactOS UEFI Boot Manager
4  * FILE: boot/environ/app/bootmgr/bootmgr.cla
5  * PURPOSE: Boot Manager Entrypoint
6  * PROGRAMMER: Alex Ionescu (alex.ionescu@reactos.org)
7  */
8 
9 /* INCLUDES ******************************************************************/
10 
11 #include "bootmgr.h"
12 
13 /* DATA VARIABLES ************************************************************/
14 
15 DEFINE_GUID(GUID_WINDOWS_BOOTMGR,
16  0x9DEA862C,
17  0x5CDD,
18  0x4E70,
19  0xAC, 0xC1, 0xF3, 0x2B, 0x34, 0x4D, 0x47, 0x95);
20 
25 
29 
33 
39 
40 /* FUNCTIONS *****************************************************************/
41 
44  _In_ HANDLE BcdHandle,
45  _In_ PGUID ObjectId,
46  _In_ PBL_BCD_OPTION *OptionList
47  )
48 {
50  HANDLE ObjectHandle;
51  ULONG ElementSize, ElementCount, i, OptionsSize;
54  PBCD_ELEMENT BcdElements;
55  PBL_BCD_OPTION Options, Option, PreviousOption, DeviceOptions;
56  PBCD_DEVICE_OPTION DeviceOption;
57  GUID DeviceId;
59 
60  /* Open the BCD object requested */
61  ObjectHandle = NULL;
62  BcdElements = NULL;
63  Status = BcdOpenObject(BcdHandle, ObjectId, &ObjectHandle);
64  if (!NT_SUCCESS(Status))
65  {
66  goto Quickie;
67  }
68 
69  /* Do the initial enumeration to get the size needed */
70  ElementSize = 0;
72  ObjectHandle,
73  NULL,
74  &ElementSize,
75  &ElementCount);
77  {
78  /* If we got success, that doesn't make any sense */
79  if (NT_SUCCESS(Status))
80  {
82  }
83 
84  /* Bail out */
85  goto Quickie;
86  }
87 
88  /* Allocate a large-enough buffer */
89  BcdElements = BlMmAllocateHeap(ElementSize);
90  if (!BcdElements)
91  {
93  goto Quickie;
94  }
95 
96  /* Now do the real enumeration to fill out the elements buffer */
98  ObjectHandle,
99  BcdElements,
100  &ElementSize,
101  &ElementCount);
102  if (!NT_SUCCESS(Status))
103  {
104  goto Quickie;
105  }
106 
107  /* Go through each BCD option to add the sizes up */
108  OptionsSize = 0;
109  for (i = 0; i < ElementCount; i++)
110  {
111  OptionsSize += BcdElements[i].Header->Size + sizeof(BL_BCD_OPTION);
112  }
113 
114  /* Allocate the required BCD option list */
115  Options = BlMmAllocateHeap(OptionsSize);
116  if (!Options)
117  {
119  goto Quickie;
120  }
121 
122  /* Zero it out */
123  RtlZeroMemory(Options, OptionsSize);
124 
125  /* Start going through each option */
126  PreviousOption = NULL;
127  Option = Options;
128  for (i = 0; i < ElementCount; i++)
129  {
130  /* Read the header and type */
131  Header = BcdElements[i].Header;
132  Type.PackedValue = Header->Type;
133 
134  /* Check if this option isn't already present */
135  if (!MiscGetBootOption(Options, Type.PackedValue))
136  {
137  /* It's a new option. Did we have an existing one? */
138  if (PreviousOption)
139  {
140  /* Link it to this new one */
141  PreviousOption->NextEntryOffset = (ULONG_PTR)Option -
143  }
144 
145  /* Capture the type, size, data, and offset */
146  Option->Type = Type.PackedValue;
147  Option->DataSize = Header->Size;
148  RtlCopyMemory(Option + 1, BcdElements[i].Body, Header->Size);
149  Option->DataOffset = sizeof(BL_BCD_OPTION);
150 
151  /* Check if this was a device */
152  if (Type.Format == BCD_TYPE_DEVICE)
153  {
154  /* Grab its GUID */
155  DeviceOption = (PBCD_DEVICE_OPTION)(Option + 1);
156  DeviceId = DeviceOption->AssociatedEntry;
157 
158  /* Look up the options for that GUID */
159  Status = BmGetOptionList(BcdHandle, &DeviceId, &DeviceOptions);
160  if (NT_SUCCESS(Status))
161  {
162  /* Device data is after the device option */
163  DeviceData = (PVOID)((ULONG_PTR)DeviceOption + Header->Size);
164 
165  /* Copy it */
167  DeviceOptions,
168  BlGetBootOptionListSize(DeviceOptions));
169 
170  /* Don't need this anymore */
171  BlMmFreeHeap(DeviceOptions);
172 
173  /* Write the offset of the device options */
174  Option->ListOffset = (ULONG_PTR)DeviceData -
175  (ULONG_PTR)Option;
176  }
177  }
178 
179  /* Save the previous option and go to the next one */
180  PreviousOption = Option;
181  Option = (PBL_BCD_OPTION)((ULONG_PTR)Option +
182  BlGetBootOptionSize(Option));
183  }
184  }
185 
186  /* Return the pointer back, we've made it! */
187  *OptionList = Options;
189 
190 Quickie:
191  /* Did we allocate a local buffer? Free it if so */
192  if (BcdElements)
193  {
194  BlMmFreeHeap(BcdElements);
195  }
196 
197  /* Was the key open? Close it if so */
198  if (ObjectHandle)
199  {
200  BiCloseKey(ObjectHandle);
201  }
202 
203  /* Return the option list parsing status */
204  return Status;
205 }
206 
207 NTSTATUS
209  _In_ HANDLE BcdHandle
210  )
211 {
214 
215  /* Get the boot option list */
217  if (!NT_SUCCESS(Status))
218  {
219  return Status;
220  }
221 
222  /* Append the options, free the local buffer, and return success */
225  return STATUS_SUCCESS;
226 }
227 
228 NTSTATUS
230  _In_ PUNICODE_STRING ApplicationDirectoryPath
231  )
232 {
234  SIZE_T i, AppPathLength;
235  PWCHAR ApplicationPath, PathCopy;
236 
237  /* Clear the incoming string */
238  ApplicationDirectoryPath->Length = 0;
239  ApplicationDirectoryPath->MaximumLength = 0;
240  ApplicationDirectoryPath->Buffer = 0;
241 
242  /* Get the boot application path */
243  ApplicationPath = NULL;
246  &ApplicationPath);
247  if (NT_SUCCESS(Status))
248  {
249  /* Calculate the length of the application path */
250  for (i = wcslen(ApplicationPath) - 1; i > 0; i--)
251  {
252  /* Keep going until the path separator */
253  if (ApplicationPath[i] == OBJ_NAME_PATH_SEPARATOR)
254  {
255  break;
256  }
257  }
258 
259  /* Check if we have space for one more character */
260  Status = RtlSIZETAdd(i, 1, &AppPathLength);
261  if (NT_SUCCESS(Status))
262  {
263  /* Check if it's safe to multiply by two */
264  Status = RtlSIZETMult(AppPathLength, sizeof(WCHAR), &AppPathLength);
265  if (NT_SUCCESS(Status))
266  {
267  /* Allocate a copy for the string */
268  PathCopy = BlMmAllocateHeap(AppPathLength);
269  if (PathCopy)
270  {
271  /* NULL-terminate it */
272  RtlCopyMemory(PathCopy,
273  ApplicationPath,
274  AppPathLength - sizeof(UNICODE_NULL));
275  PathCopy[AppPathLength] = UNICODE_NULL;
276 
277  /* Finally, initialize the outgoing string */
278  RtlInitUnicodeString(ApplicationDirectoryPath, PathCopy);
279  }
280  else
281  {
282  /* No memory, fail */
284  }
285  }
286  }
287  }
288 
289  /* Check if we had an application path */
290  if (ApplicationPath)
291  {
292  /* No longer need this, free it */
293  BlMmFreeHeap(ApplicationPath);
294  }
295 
296  /* All done! */
297  return Status;
298 }
299 
300 NTSTATUS
302  VOID
303  )
304 {
305  PWCHAR FinalPath;
307  PWCHAR BcdDirectory;
308  UNICODE_STRING BcdPath;
309  ULONG FinalSize;
311 
312  /* Initialize everything for failure */
313  BcdPath.MaximumLength = 0;
314  BcdPath.Buffer = NULL;
315  BcdDirectory = NULL;
316  FinalPath = NULL;
317  FileHandle = -1;
318  DeviceHandle = -1;
319 
320  /* Try to open the boot device */
323  0,
324  &DeviceHandle);
325  if (!NT_SUCCESS(Status))
326  {
327  EfiPrintf(L"Device open failed: %lx\r\n", Status);
328  goto Quickie;
329  }
330 
331  /* Get the directory path */
333  BcdDirectory = BcdPath.Buffer;
334  if (!NT_SUCCESS(Status))
335  {
336  goto Quickie;
337  }
338 
339  /* Add the BCD file name to it */
340  FinalSize = BcdPath.MaximumLength + sizeof(L"\\BCD") - sizeof(UNICODE_NULL);
341  if (FinalSize < BcdPath.MaximumLength)
342  {
343  goto Quickie;
344  }
345 
346  /* Allocate space for the final path */
347  FinalPath = BlMmAllocateHeap(FinalSize);
348  if (!FinalPath)
349  {
350  goto Quickie;
351  }
352 
353  /* Build it */
354  RtlZeroMemory(FinalPath, FinalSize);
355  RtlCopyMemory(FinalPath, BcdDirectory, BcdPath.MaximumLength);
356  wcsncat(FinalPath, L"\\BCD", FinalSize / sizeof(WCHAR));
357 
358  /* Try to open the file */
360  FinalPath,
362  &FileHandle);
363  if (!NT_SUCCESS(Status))
364  {
365  BootDirectory = BcdDirectory;
366  goto Quickie;
367  }
368 
369  /* Save the boot directory */
370  BootDirectory = L"\\EFI\\Boot"; /* Should be EFI\\ReactOS\\Boot */
371 
372 Quickie:
373  /* Free all the allocations we made */
374  if (BcdDirectory)
375  {
376  Status = BlMmFreeHeap(BcdDirectory);
377  }
378  if (FinalPath)
379  {
380  Status = BlMmFreeHeap(FinalPath);
381  }
382 
383  /* Close the BCD file */
384  if (FileHandle != -1)
385  {
387  }
388 
389  /* Close the boot device */
390  if (DeviceHandle != -1)
391  {
393  }
394 
395  /* Return back to the caller */
396  return Status;
397 }
398 
399 NTSTATUS
401  VOID
402  )
403 {
404  /* Don't yet handled boot.ini */
405  return STATUS_NOT_FOUND;
406 }
407 
408 ULONG
410  _In_ NTSTATUS ErrorStatus,
411  _Out_ PULONG ErrorResourceId
412  )
413 {
414  ULONG Result;
415 
416  /* Assume no message for now, check for known status message */
417  Result = 0;
418  switch (ErrorStatus)
419  {
420  /* Convert each status to a resource ID */
422  *ErrorResourceId = 9017;
423  Result = 1;
424  break;
426  *ErrorResourceId = 9018;
427  break;
429  *ErrorResourceId = 9016;
430  break;
431  case 0xC0000428:
432  *ErrorResourceId = 9019;
433  Result = 2;
434  break;
435  case 0xC0210000:
436  *ErrorResourceId = 9013;
437  break;
438  }
439 
440  /* Return the type of message */
441  return Result;
442 }
443 
444 VOID
446  VOID
447  )
448 {
449  /* Check if a boot error is present */
451  {
452  /* Purge it */
455  }
456 
457  /* Zero out the packed buffer */
461 }
462 
463 VOID
466  _In_ NTSTATUS ErrorStatus,
467  _In_ ULONG ErrorMsgId,
469  _In_ ULONG HelpMsgId
470  )
471 {
472  PWCHAR ErrorMsgString;
473 
474  /* Check if we already had an error */
476  {
477  /* Purge it */
478  BmErrorPurge();
479  }
480 
481  /* Find the string for this error ID */
482  ErrorMsgString = BlResourceFindMessage(ErrorMsgId);
483  if (ErrorMsgString)
484  {
485  /* Fill out the error buffer */
488  BmpErrorBuffer.ErrorString = ErrorMsgString;
491  BmpErrorBuffer.ErrorStatus = ErrorStatus;
492  BmpErrorBuffer.HelpMsgId = HelpMsgId;
494  }
495 }
496 
497 VOID
500  _In_ ULONG_PTR Parameter1,
501  _In_ ULONG_PTR Parameter2,
502  _In_ ULONG_PTR Parameter3,
503  _In_ ULONG_PTR Parameter4
504  )
505 {
507  NTSTATUS ErrorStatus;
508  WCHAR FormatString[256];
509  ULONG ErrorResourceId, ErrorHelpId;
510  BOOLEAN Restart, NoError;
511 
512  /* Assume no buffer for now */
513  Buffer = NULL;
514 
515  /* Check what error code is being raised */
516  switch (ErrorCode)
517  {
518  /* Error reading the BCD */
520 
521  /* Check if we have a name for the BCD file */
522  if (Parameter1)
523  {
524  /* Check if the name fits into our buffer */
525  FileName = (PWCHAR)Parameter1;
526  if (wcslen(FileName) < sizeof(BmpFileNameBuffer))
527  {
528  /* Copy it in there */
531  FileName,
533  }
534  }
535 
536  /* If we don't have a buffer, use an empty one */
537  if (!Buffer)
538  {
540  }
541 
542  /* The NTSTATUS code is in parameter 2*/
543  ErrorStatus = (NTSTATUS)Parameter2;
544 
545  /* Build the error string */
547  L"\nAn error occurred (%08x) while attempting "
548  L"to read the boot configuration data file %s\n",
549  ErrorStatus,
550  Buffer);
551 
552  /* Select the resource ID message */
553  ErrorResourceId = 9002;
554  break;
555 
557 
558  /* File name is in parameter 1 */
559  FileName = (PWCHAR)Parameter1;
560 
561  /* The NTSTATUS code is in parameter 2*/
562  ErrorStatus = (NTSTATUS)Parameter2;
563 
564  /* Build the error string */
566  L"\nNo valid entries found in the boot configuration data file %s\n",
567  FileName);
568 
569  /* Select the resource ID message */
570  ErrorResourceId = 9007;
571  break;
572 
574 
575  /* File name isin parameter 1 */
576  FileName = (PWCHAR)Parameter1;
577 
578  /* The NTSTATUS code is in parameter 2*/
579  ErrorStatus = (NTSTATUS)Parameter2;
580 
581  /* Build the error string */
583  L"\nThe boot configuration file %s is invalid (%08x).\n",
584  FileName,
585  ErrorStatus);
586 
587  /* Select the resource ID message */
588  ErrorResourceId = 9015;
589  break;
590 
592 
593  /* The NTSTATUS code is in parameter 1*/
594  ErrorStatus = (NTSTATUS)Parameter1;
595 
596  /* Build the error string */
598  L"\nThe boot manager experienced an error (%08x).\n",
599  ErrorStatus);
600 
601  /* Select the resource ID message */
602  ErrorResourceId = 9005;
603  break;
604 
605  default:
606 
607  /* The rest is not yet handled */
608  EfiPrintf(L"Unexpected fatal error: %lx\r\n", ErrorCode);
609  while (1);
610  break;
611  }
612 
613  /* Check if the BCD option for restart is set */
616  &Restart);
617  if (Restart)
618  {
619  /* Yes, so no error should be shown since we'll auto-restart */
620  NoError = TRUE;
621  }
622  else
623  {
624  /* Check if the option for not showing errors is set in the BCD */
627  &NoError);
628  }
629 
630  /* Do we want an error? */
631  if (!NoError)
632  {
633  /* Yep, print it and then raise an error */
635  BlStatusError(1, ErrorCode, Parameter1, Parameter2, Parameter3);
636  }
637 
638  /* Get the help message ID */
639  ErrorHelpId = BmpFatalErrorMessageFilter(ErrorStatus, &ErrorResourceId);
640  BmpErrorLog(ErrorCode, ErrorStatus, ErrorResourceId, Buffer, ErrorHelpId);
641 }
642 
643 NTSTATUS
646  _Out_ PWCHAR* FullPath
647  )
648 {
650  SIZE_T BootDirLength, PathLength;
651 
652  /* Compute the length of the directory, and add a NUL */
653  BootDirLength = wcslen(BootDirectory);
654  Status = RtlSIZETAdd(BootDirLength, 1, &BootDirLength);
655  if (!NT_SUCCESS(Status))
656  {
657  goto Quickie;
658  }
659 
660  /* Add the length of the file, make sure it fits */
662  Status = RtlSIZETAdd(PathLength, BootDirLength, &PathLength);
663  if (!NT_SUCCESS(Status))
664  {
665  goto Quickie;
666  }
667 
668  /* Convert to bytes */
669  Status = RtlSIZETMult(PathLength, sizeof(WCHAR), &PathLength);
670  if (!NT_SUCCESS(Status))
671  {
672  goto Quickie;
673  }
674 
675  /* Allocate the full path */
676  *FullPath = BlMmAllocateHeap(PathLength);
677  if (*FullPath)
678  {
679  /* Copy the directory followed by the file name */
680  wcsncpy(*FullPath, BootDirectory, PathLength / sizeof(WCHAR));
681  wcsncat(*FullPath, FileName, PathLength / sizeof(WCHAR));
682  }
683  else
684  {
685  /* Bail out since we have no memory */
687  }
688 
689 Quickie:
690  /* Return to caller */
691  return Status;
692 }
693 
694 VOID
697  )
698 {
699  /* Check if boot.ini data needs to be freed */
700  if (BmBootIniUsed)
701  {
702  EfiPrintf(L"Boot.ini not handled\r\n");
703  }
704 
705  /* Dereference the hive and close the key */
708 }
709 
710 NTSTATUS
713  )
714 {
716  PBL_DEVICE_DESCRIPTOR BcdDevice;
717  PWCHAR BcdPath, FullPath, PathBuffer;
718  BOOLEAN HavePath;
719  SIZE_T PathLength, FullSize;
720  PVOID FinalBuffer;
721  UNICODE_STRING BcdString;
722 
723  /* Initialize variables */
724  PathBuffer = NULL;
725  BcdDevice = NULL;
726  BcdPath = NULL;
727  HavePath = FALSE;
728 
729  /* Check if a boot.ini file exists */
730  Status = BmOpenBootIni();
731  if (NT_SUCCESS(Status))
732  {
734  }
735 
736  /* Check on which device the BCD is */
739  &BcdDevice,
740  NULL);
741  if (!NT_SUCCESS(Status))
742  {
743  /* It's not on a custom device, so it must be where we are */
746  &BcdDevice,
747  NULL);
748  if (!NT_SUCCESS(Status))
749  {
750  /* This BCD option is required */
751  goto Quickie;
752  }
753  }
754 
755  /* Next, check what file contains the BCD */
758  &BcdPath);
759  if (NT_SUCCESS(Status))
760  {
761  /* We don't handle custom BCDs yet */
762  EfiPrintf(L"Custom BCD Not handled: %s\r\n", BcdPath);
764  goto Quickie;
765  }
766 
767  /* Now check if the BCD is on a remote share */
768  if (BcdDevice->DeviceType == UdpDevice)
769  {
770  /* Nope. Nope. Nope */
771  EfiPrintf(L"UDP device Not handled\r\n");
773  goto Quickie;
774  }
775 
776  /* Otherwise, compute the hardcoded path of the BCD */
777  Status = BmpFwGetFullPath(L"\\BCD", &FullPath);
778  if (!NT_SUCCESS(Status))
779  {
780  /* User the raw path */
781  PathBuffer = BcdPath;
782  }
783  else
784  {
785  /* Use the path we got */
786  PathBuffer = FullPath;
787  HavePath = TRUE;
788  }
789 
790  /* Check if we failed to get the BCD path */
791  if (!NT_SUCCESS(Status))
792  {
793  goto Quickie;
794  }
795 
796  /* Add a NUL to the path, make sure it'll fit */
797  PathLength = wcslen(PathBuffer);
798  Status = RtlSIZETAdd(PathLength, 1, &PathLength);
799  if (!NT_SUCCESS(Status))
800  {
801  goto Quickie;
802  }
803 
804  /* Convert to bytes */
805  Status = RtlSIZETMult(PathLength, sizeof(WCHAR), &PathLength);
806  if (!NT_SUCCESS(Status))
807  {
808  goto Quickie;
809  }
810 
811  /* Now add the size of the path to the device path, check if it fits */
812  Status = RtlSIZETAdd(PathLength, BcdDevice->Size, &FullSize);
813  if (!NT_SUCCESS(Status))
814  {
815  goto Quickie;
816  }
817 
818  /* Allocate a final structure to hold both entities */
819  FinalBuffer = BlMmAllocateHeap(FullSize);
820  if (!FinalBuffer)
821  {
823  goto Quickie;
824  }
825 
826  /* Copy the device path and file path into the final buffer */
827  RtlCopyMemory(FinalBuffer, BcdDevice, BcdDevice->Size);
828  RtlCopyMemory((PVOID)((ULONG_PTR)FinalBuffer + BcdDevice->Size),
829  PathBuffer,
830  PathLength);
831 
832  /* Now tell the BCD engine to open the store */
833  BcdString.Length = FullSize;
834  BcdString.MaximumLength = FullSize;
835  BcdString.Buffer = FinalBuffer;
836  Status = BcdOpenStoreFromFile(&BcdString, Handle);
837 
838  /* Free our final buffer */
839  BlMmFreeHeap(FinalBuffer);
840 
841 Quickie:
842  /* Did we allocate a device? */
843  if (BcdDevice)
844  {
845  /* Free it */
846  BlMmFreeHeap(BcdDevice);
847  }
848 
849  /* Is this the failure path? */
850  if (!NT_SUCCESS(Status))
851  {
852  /* Raise a fatal error */
854  (ULONG_PTR)PathBuffer,
855  Status,
856  0,
857  0);
858  }
859 
860  /* Did we get an allocated path? */
861  if ((PathBuffer) && (HavePath))
862  {
863  /* Free it */
864  BlMmFreeHeap(PathBuffer);
865  }
866 
867  /* Return back to the caller */
868  return Status;
869 }
870 
871 typedef struct _BL_BSD_LOG_OBJECT
872 {
879 
882 
883 VOID
885  _In_ PBL_DEVICE_DESCRIPTOR LogDevice,
886  _In_ PWCHAR LogPath,
888  )
889 {
891 
892  /* Don't initialize twice */
894  {
895  return;
896  }
897 
898  /* Set invalid IDs for now */
899  BsdpLogObject.DeviceId = -1;
900  BsdpLogObject.FileId = -1;
901 
902  /* Open the BSD device */
903  Status = BlpDeviceOpen(LogDevice,
905  0,
907  if (!NT_SUCCESS(Status))
908  {
909  /* Welp that didn't work */
910  goto FailurePath;
911  }
912 
913  /* Now open the BSD itself */
915  LogPath,
918  if (!NT_SUCCESS(Status))
919  {
920  /* D'oh */
921  goto FailurePath;
922  }
923 
924  /* The BSD is open. Start doing stuff to it */
925  EfiPrintf(L"Unimplemented BSD path\r\n");
927 
928 FailurePath:
929  /* Close the BSD if we had it open */
930  if (BsdpLogObject.FileId != -1)
931  {
933  }
934 
935  /* Close the device if we had it open */
936  if (BsdpLogObject.DeviceId != -1)
937  {
939  }
940 
941  /* Set BSD object to its uninitialized state */
943  BsdpLogObject.FileId = 0;
945  BsdpLogObject.Flags = 0;
947  BsdpLogObject.Size = 0;
948 }
949 
950 VOID
952  VOID
953  )
954 {
956  PBL_DEVICE_DESCRIPTOR BsdDevice;
957  PWCHAR BsdPath;
958  ULONG Flags;
959  BOOLEAN PreserveBsd;
960 
961  /* Initialize locals */
962  BsdPath = NULL;
963  BsdDevice = NULL;
964  Flags = 0;
965 
966  /* Check if the BSD is stored in a custom device */
969  &BsdDevice,
970  NULL);
971  if (!NT_SUCCESS(Status))
972  {
973  /* Nope, use the boot device */
974  BsdDevice = BlpBootDevice;
975  }
976 
977  /* Check if the path is custom as well */
980  &BsdPath);
981  if (!NT_SUCCESS(Status))
982  {
983  /* Nope, use our default path */
984  Status = BmpFwGetFullPath(L"\\bootstat.dat", &BsdPath);
985  if (!NT_SUCCESS(Status))
986  {
987  BsdPath = NULL;
988  }
989 
990  /* Set preserve flag */
991  Flags = 1;
992  }
993  else
994  {
995  /* Set preserve flag */
996  Flags = 1;
997  }
998 
999  /* Finally, check if the BSD should be preserved */
1002  &PreserveBsd);
1003  if (!(NT_SUCCESS(Status)) || !(PreserveBsd))
1004  {
1005  /* We failed to read, or we were asked not to preserve it */
1006  Flags = 0;
1007  }
1008 
1009  /* Initialize the log */
1010  BlBsdInitializeLog(BsdDevice, BsdPath, Flags);
1011 
1012  /* Free the BSD device descriptor if we had one */
1013  if (BsdDevice)
1014  {
1015  BlMmFreeHeap(BsdDevice);
1016  }
1017 
1018  /* Free the BSD path if we had one */
1019  if ((Flags) && (BsdPath))
1020  {
1021  BlMmFreeHeap(BsdPath);
1022  }
1023 }
1024 
1025 VOID
1027  VOID
1028  )
1029 {
1030  NTSTATUS Status;
1032  BL_ADDRESS_RANGE AddressRange;
1033 
1034  /* Select the range below 1MB */
1035  AddressRange.Maximum = 0xFFFFF;
1036  AddressRange.Minimum = 0;
1037 
1038  /* Allocate one reserved page with the "below 1MB" attribute */
1041  1,
1043  0,
1045  &AddressRange,
1047  if (!NT_SUCCESS(Status))
1048  {
1049  /* Print a message on error, but keep going */
1050  BlStatusPrint(L"BmFwMemoryInitialize: Failed to allocate a page below 1MB. Status: 0x%08x\r\n",
1051  Status);
1052  }
1053 }
1054 
1055 NTSTATUS
1057  _In_ ULONG Color
1058  )
1059 {
1060  /* Not yet supported */
1061  return STATUS_NOT_IMPLEMENTED;
1062 }
1063 
1064 NTSTATUS
1066  _In_ PWCHAR XmlTag
1067  )
1068 {
1069  /* Sigh */
1070  EfiPrintf(L"XML: %s\r\n", XmlTag);
1071  return STATUS_NOT_IMPLEMENTED;
1072 }
1073 
1074 NTSTATUS
1076  _In_ PWCHAR Stylesheet
1077  )
1078 {
1079  /* Reset the cursor type */
1081 
1082  /* Nope, not doing any XML stuff */
1083  return STATUS_SUCCESS;
1084 }
1085 
1086 NTSTATUS
1088  VOID
1089  )
1090 {
1091  /* Check if we're booted by UEFI off the DVD directly */
1092  if ((BlpBootDevice->DeviceType == LocalDevice) &&
1095  {
1096  /* Windows actually bypasses integrity checks in this case. Works for us */
1097  return STATUS_SUCCESS;
1098  }
1099 
1100  /* Our binaries aren't signed, so always return failure */
1101  return 0xC0000428;
1102 }
1103 
1104 NTSTATUS
1106  VOID
1107  )
1108 {
1109  NTSTATUS Status;
1110  BOOLEAN SecureBootEnabled;
1111 
1112  /* Is SecureBoot enabled? */
1113  Status = BlSecureBootIsEnabled(&SecureBootEnabled);
1114  if ((NT_SUCCESS(Status)) && (SecureBootEnabled))
1115  {
1116  EfiPrintf(L"SB not implemented revok\r\n");
1117  return STATUS_NOT_IMPLEMENTED;
1118  }
1119  else
1120  {
1121  /* Nothing to do without SecureBoot */
1123  }
1124 
1125  /* Return revocation result back to caller */
1126  return Status;
1127 }
1128 
1129 NTSTATUS
1131  _Out_ PHANDLE BcdResumeHandle
1132  )
1133 {
1134  NTSTATUS Status;
1135  BOOLEAN AttemptResume;
1136 
1137  /* Should we attempt to resume from hibernation? */
1140  &AttemptResume);
1141  if (!NT_SUCCESS(Status))
1142  {
1143  /* Nope. Is automatic restart on crash enabled? */
1144  AttemptResume = FALSE;
1147  &AttemptResume);
1148  AttemptResume = (NT_SUCCESS(Status) && (AttemptResume));
1149  }
1150 
1151  /* Don't do anything if there's no need to resume anything */
1152  if (!AttemptResume)
1153  {
1154  return STATUS_SUCCESS;
1155  }
1156 
1157  /* Not yet implemented */
1158  EfiPrintf(L"Resume not supported\r\n");
1159  return STATUS_NOT_IMPLEMENTED;
1160 }
1161 
1162 NTSTATUS
1164  VOID
1165  )
1166 {
1167  BL_PD_DATA_BLOB BadMemoryData;
1168  NTSTATUS Status;
1169 
1170  /* Try to get the memory data from the memtest application */
1171  BadMemoryData.BlobSize = 0;
1172  BadMemoryData.Data = NULL;
1173  BadMemoryData.DataSize = 0;
1174  Status = BlPdQueryData(&BadMemoryGuid, NULL, &BadMemoryData);
1176  {
1177  /* No results, or some other error */
1178  return Status;
1179  }
1180 
1181  /* Not yet implemented */
1182  EfiPrintf(L"Bad page list persistence not implemented\r\n");
1183  return STATUS_NOT_IMPLEMENTED;
1184 }
1185 
1186 NTSTATUS
1188  _In_ HANDLE BcdHandle,
1189  _In_ PGUID ObjectId,
1190  _In_ ULONG Type
1191  )
1192 {
1193  HANDLE ObjectHandle;
1194  NTSTATUS Status;
1195 
1196  /* Open the object */
1197  Status = BcdOpenObject(BcdHandle, ObjectId, &ObjectHandle);
1198  if (NT_SUCCESS(Status))
1199  {
1200  /* Delete the element */
1201  BcdDeleteElement(ObjectHandle, Type);
1202 
1203  /* Close the object and set success */
1204  BiCloseKey(ObjectHandle);
1206  }
1207 
1208  /* Return the result */
1209  return Status;
1210 }
1211 
1212 NTSTATUS
1214  _In_ HANDLE BcdHandle,
1215  _In_ PGUID ObjectId,
1217  )
1218 {
1219  NTSTATUS Status;
1220  HANDLE ObjectHandle;
1221 
1222  /* Open the BCD object */
1223  Status = BcdOpenObject(BcdHandle, ObjectId, &ObjectHandle);
1224  if (NT_SUCCESS(Status))
1225  {
1226  /* Make sure the caller passed this argument in */
1227  if (!Description)
1228  {
1229  /* Fail otherwise */
1231  }
1232  else
1233  {
1234  /* Query the description from the BCD interface */
1235  Status = BiGetObjectDescription(ObjectHandle, Description);
1236  }
1237 
1238  /* Close the object key */
1239  BiCloseKey(ObjectHandle);
1240  }
1241 
1242  /* Return the result back */
1243  return Status;
1244 }
1245 
1246 NTSTATUS
1248  _In_ HANDLE BcdHandle,
1249  _In_ PGUID SequenceList,
1250  _In_ ULONG Flags,
1251  _Out_ PBL_LOADED_APPLICATION_ENTRY* BootSequence,
1252  _Out_ PULONG SequenceCount
1253  )
1254 {
1255  NTSTATUS Status;
1256  ULONG BootIndex, i, OptionSize;
1257  PBL_LOADED_APPLICATION_ENTRY BootEntry;
1261  BOOLEAN HavePath, IsWinPe, SoftReboot;
1262  PWCHAR LoaderPath;
1263 
1264  /* Initialize locals */
1265  Options = NULL;
1266  BootIndex = 0;
1268 
1269  /* Loop through every element in the sequence */
1270  for (i = 0; i < *SequenceCount; i++)
1271  {
1272  /* Assume failure */
1273  BootEntry = NULL;
1274 
1275  /* Get the options for the sequence element */
1276  Status = BmGetOptionList(BcdHandle, SequenceList, &Options);
1277  if (!NT_SUCCESS(Status))
1278  {
1279  EfiPrintf(L"option list failed: %lx\r\n", Status);
1280  goto LoopQuickie;
1281  }
1282 
1283  /* Make sure there's at least a path and description */
1286  {
1288  EfiPrintf(L"missing list failed: %lx\r\n", Status);
1289  goto LoopQuickie;
1290  }
1291 
1292  /* Get the size of the BCD options and allocate a large enough entry */
1293  OptionSize = BlGetBootOptionListSize(Options);
1294  BootEntry = BlMmAllocateHeap(sizeof(*BootEntry) + OptionSize);
1295  if (!BootEntry)
1296  {
1298  goto Quickie;
1299  }
1300 
1301  /* Save it as part of the sequence */
1302  BootSequence[BootIndex] = BootEntry;
1303 
1304  /* Initialize it, and copy the BCD data */
1305  RtlZeroMemory(BootEntry, sizeof(*BootEntry));
1306  BootEntry->Guid = *SequenceList;
1307  BootEntry->BcdData = (PBL_BCD_OPTION)(BootEntry + 1);
1308  BootEntry->Flags = Flags;
1309  RtlCopyMemory(BootEntry->BcdData, Options, OptionSize);
1310 
1311  /* Get the object descriptor to find out what kind of entry it is */
1312  Status = BmGetEntryDescription(BcdHandle,
1313  &BootEntry->Guid,
1314  &Description);
1315  if (!NT_SUCCESS(Status))
1316  {
1317  EfiPrintf(L"missing desc failed: %lx\r\n", Status);
1318  goto LoopQuickie;
1319  }
1320 
1321  /* Check if a path was given or not */
1323  TRUE : FALSE;
1324 
1325  /* Now select based on what type of object this is -- must be an app */
1326  ObjectType.PackedValue = Description.Type;
1327  if (ObjectType.Application.ObjectCode == BCD_OBJECT_TYPE_APPLICATION)
1328  {
1329  /* Then select based on what kind of app it is */
1330  switch (ObjectType.Application.ApplicationCode)
1331  {
1332  /* Another boot manager */
1334  BootEntry->Flags |= BCD_APPLICATION_TYPE_BOOTMGR;
1335  break;
1336 
1337  /* An OS loader */
1339  BootEntry->Flags |= BL_APPLICATION_ENTRY_WINLOAD;
1340 
1341  /* Do we have a path for it? */
1342  if (!HavePath)
1343  {
1344  /* We'll try to make one up. Is this WinPE? */
1345  IsWinPe = FALSE;
1348  &IsWinPe);
1349  if (!(NT_SUCCESS(Status)) && (Status != STATUS_NOT_FOUND))
1350  {
1351  goto Quickie;
1352  }
1353 
1354  /* Use the appropriate path for WinPE or local install */
1355  LoaderPath = IsWinPe ?
1356  L"\\Windows\\System32\\boot\\winload.efi" :
1357  L"\\Windows\\System32\\winload.efi";
1358 
1359  /* Add the path to the boot entry */
1360  Status = BlAppendBootOptionString(BootEntry,
1362  LoaderPath);
1363  if (!NT_SUCCESS(Status))
1364  {
1365  goto Quickie;
1366  }
1367 
1368  /* We have a path now */
1369  HavePath = TRUE;
1370  }
1371  break;
1372 
1373  /* A hibernate-resume application */
1375  BootEntry->Flags |= BL_APPLICATION_ENTRY_WINRESUME;
1376  break;
1377 
1378  /* An older OS NTLDR */
1380  BootEntry->Flags |= BL_APPLICATION_ENTRY_NTLDR;
1381  break;
1382 
1383  /* An older OS SETUPLDR */
1385  BootEntry->Flags |= BL_APPLICATION_ENTRY_SETUPLDR;
1386  break;
1387 
1388  /* A 3rd party/Win9x boot sector */
1390  BootEntry->Flags |= BL_APPLICATION_ENTRY_BOOTSECTOR;
1391  break;
1392 
1393  /* Something else entirely */
1394  default:
1395  break;
1396  }
1397  }
1398 
1399  /* We better have a path by now */
1400  if (!HavePath)
1401  {
1403  goto LoopQuickie;
1404  }
1405 
1406  /* Check if this is a real mode startup.com */
1407  if ((ObjectType.Application.ObjectCode == BCD_OBJECT_TYPE_APPLICATION) &&
1408  (ObjectType.Application.ImageCode == BCD_IMAGE_TYPE_REAL_MODE) &&
1409  (ObjectType.Application.ApplicationCode == BCD_APPLICATION_TYPE_STARTUPCOM))
1410  {
1411  /* Check if PXE soft reboot will occur */
1414  &SoftReboot);
1415  if ((NT_SUCCESS(Status)) && (SoftReboot))
1416  {
1417  /* Then it's a valid startup.com entry */
1418  BootEntry->Flags |= BL_APPLICATION_ENTRY_STARTUP;
1419  }
1420  }
1421 
1422 LoopQuickie:
1423  /* All done with this entry -- did we have BCD options? */
1424  if (Options)
1425  {
1426  /* Free them, they're part of the entry now */
1428  Options = NULL;
1429  }
1430 
1431  /* Did we fail anywhere? */
1432  if (!NT_SUCCESS(Status))
1433  {
1434  /* Yep -- did we fail with an active boot entry? */
1435  if (BootEntry)
1436  {
1437  /* Destroy it */
1438  BlDestroyBootEntry(BootEntry);
1439  BootSequence[BootIndex] = NULL;
1440  }
1441  }
1442  else
1443  {
1444  /* It worked, so populate the next index now */
1445  BootIndex++;
1446  }
1447 
1448  /* And move to the next GUID in the sequence list */
1449  SequenceList++;
1450  }
1451 
1452 Quickie:
1453  /* All done now -- did we have any BCD options? */
1454  if (Options)
1455  {
1456  /* Free them */
1458  }
1459 
1460  /* Return the status */
1461  return Status;
1462 }
1463 
1464 NTSTATUS
1466  _In_ HANDLE BcdHandle,
1467  _In_ PGUID SequenceList,
1468  _In_ ULONG SequenceListCount,
1469  _In_ ULONG Flags,
1470  _Out_ PBL_LOADED_APPLICATION_ENTRY** BootSequence,
1471  _Out_ PULONG SequenceCount
1472  )
1473 {
1474  PBL_LOADED_APPLICATION_ENTRY* Sequence;
1475  ULONG Count = SequenceListCount;
1476  NTSTATUS Status;
1477 
1478  /* Allocate the sequence list */
1479  Sequence = BlMmAllocateHeap(SequenceListCount * sizeof(*Sequence));
1480  if (!Sequence)
1481  {
1482  return STATUS_NO_MEMORY;
1483  }
1484 
1485  /* Populate the sequence list */
1486  Status = BmpPopulateBootEntryList(BcdHandle,
1487  SequenceList,
1488  Flags,
1489  Sequence,
1490  &Count);
1491  if (!NT_SUCCESS(Status))
1492  {
1493  /* Free the list on failure */
1494  BlMmFreeHeap(Sequence);
1495  }
1496  else
1497  {
1498  /* Otherwise, set success and return the list and count */
1500  *BootSequence = Sequence;
1501  *SequenceCount = Count;
1502  }
1503 
1504  /* All done */
1505  return Status;
1506 }
1507 
1508 NTSTATUS
1510  _In_ HANDLE BcdHandle,
1511  _Out_ PBL_LOADED_APPLICATION_ENTRY **BootSequence,
1512  _Out_ PULONG SequenceCount
1513  )
1514 {
1515  NTSTATUS Status;
1516  ULONG BootIndex, BootIniCount, BootEntryCount, BcdCount;
1517  PBL_LOADED_APPLICATION_ENTRY* Sequence;
1518  PGUID DisplayOrder;
1519  GUID DefaultObject;
1520  BOOLEAN UseDisplayList;
1521 
1522  /* Initialize locals */
1523  BootIndex = 0;
1524 
1525  /* First try to get the display list, if any */
1526  UseDisplayList = TRUE;
1529  &DisplayOrder,
1530  &BcdCount);
1531  if (!NT_SUCCESS(Status))
1532  {
1533  /* No list, get the default entry instead */
1536  &DefaultObject);
1537  if (NT_SUCCESS(Status))
1538  {
1539  /* Set the array to just our entry */
1540  UseDisplayList = FALSE;
1541  BcdCount = 1;
1542  DisplayOrder = &DefaultObject;
1543  }
1544  else
1545  {
1546  /* No default list either, return success but no entries */
1547  *BootSequence = NULL;
1548  *SequenceCount = 0;
1550  DisplayOrder = NULL;
1551  goto Quickie;
1552  }
1553  }
1554 
1555  /* Check if boot.ini was used */
1556  BootIniCount = 0;
1557  if (BmBootIniUsed)
1558  {
1559  /* Get the entries from it */
1560  EfiPrintf(L"Boot.ini not supported\r\n");
1561  BootIniCount = 0;//BmBootIniGetEntryCount();
1562  }
1563 
1564  /* Allocate an array large enough for the combined boot entries */
1565  BootEntryCount = BootIniCount + BcdCount;
1566  Sequence = BlMmAllocateHeap(BootEntryCount * sizeof(*Sequence));
1567  if (!Sequence)
1568  {
1570  goto Quickie;
1571  }
1572 
1573  /* Zero it out */
1574  RtlZeroMemory(Sequence, BootEntryCount * sizeof(*Sequence));
1575 
1576  /* Check if we had BCD entries */
1577  if (BcdCount)
1578  {
1579  /* Populate the list of bootable entries */
1580  Status = BmpPopulateBootEntryList(BcdHandle,
1581  DisplayOrder,
1583  Sequence,
1584  &BcdCount);
1585  if (!NT_SUCCESS(Status))
1586  {
1587  /* Bail out */
1588  goto Quickie;
1589  }
1590  }
1591 
1592  /* Check if we had boot.ini entries */
1593  if (BootIniCount)
1594  {
1595  /* TODO */
1596  EfiPrintf(L"Boot.ini not supported\r\n");
1597  }
1598 
1599  /* Return success and the sequence + count populated */
1601  *BootSequence = Sequence;
1602  *SequenceCount = BootIniCount + BcdCount;
1603 
1604 Quickie:
1605  /* Check if we had allocated a GUID list */
1606  if ((UseDisplayList) && (DisplayOrder))
1607  {
1608  /* Free it */
1609  BlMmFreeHeap(DisplayOrder);
1610  }
1611 
1612  /* Check if this is the failure path */
1613  if (!(NT_SUCCESS(Status)) && (Sequence))
1614  {
1615  /* Loop the remaining boot entries */
1616  while (BootIndex < BootEntryCount)
1617  {
1618  /* Check if it had been allocated */
1619  if (Sequence[BootIndex])
1620  {
1621  /* Free it */
1622  BlMmFreeHeap(Sequence[BootIndex]);
1623  }
1624 
1625  /* Next*/
1626  BootIndex++;
1627  }
1628 
1629  /* Free the whole sequence now */
1630  BlMmFreeHeap(Sequence);
1631  }
1632 
1633  /* All done, return the result */
1634  return Status;
1635 }
1636 
1637 VOID
1640  _In_ ULONG Count,
1641  _Out_ PBL_LOADED_APPLICATION_ENTRY* DefaultEntry,
1642  _Out_ PULONG DefaultIndex
1643  )
1644 {
1645  GUID DefaultObject;
1646  NTSTATUS Status;
1647  ULONG BootIndex;
1648 
1649  /* Assume no default */
1650  *DefaultEntry = *Sequence;
1651  *DefaultIndex = 0;
1652 
1653  /* Nothing to do if there's just one entry */
1654  if (Count == 1)
1655  {
1656  return;
1657  }
1658 
1659  /* Get the default object, bail out if there isn't one */
1662  &DefaultObject);
1663  if (!(NT_SUCCESS(Status)) || !(Count))
1664  {
1665  return;
1666  }
1667 
1668  /* Scan the boot sequence */
1669  for (BootIndex = 0; BootIndex < Count; BootIndex++)
1670  {
1671  /* Find one that matches the default */
1672  if (RtlEqualMemory(&Sequence[BootIndex]->Guid,
1673  &DefaultObject,
1674  sizeof(GUID)))
1675  {
1676  /* Return it */
1677  *DefaultEntry = Sequence[BootIndex];
1678  *DefaultIndex = BootIndex;
1679  return;
1680  }
1681  }
1682 }
1683 
1687  )
1688 {
1689  NTSTATUS Status;
1690  BOOLEAN EmsEnabled;
1691  ULONGLONG BootMenuPolicy;
1692  ULONG OptionId;
1693 
1694  /* Check if EMS is enabled */
1697  &EmsEnabled);
1698  if ((NT_SUCCESS(Status)) && (EmsEnabled))
1699  {
1700  /* No boot menu */
1701  return MenuPolicyLegacy;
1702  }
1703 
1704  /* Check what entry we are looking at */
1705  if (!BootEntry)
1706  {
1707  /* No entry, pick the selected one */
1708  BootEntry = BmpSelectedBootEntry;
1709  }
1710 
1711  /* Do we still not have an entry? */
1712  if (!BootEntry)
1713  {
1714  /* Show the menu */
1715  return MenuPolicyStandard;
1716  }
1717 
1718  /* Check if this is an OS loader */
1719  BootMenuPolicy = 0;
1720  if (BootEntry->Flags & BL_APPLICATION_ENTRY_WINLOAD)
1721  {
1722  /* Use the correct option ID */
1724  }
1725  else
1726  {
1727  /* Check if this is an OS resumer */
1728  if (!(BootEntry->Flags & BL_APPLICATION_ENTRY_WINRESUME))
1729  {
1730  /* Nope, so no reason for a menu */
1731  return MenuPolicyLegacy;
1732  }
1733 
1734  /* Use the correct option ID */
1736  }
1737 
1738  /* Check the option ID for the boot menu policy */
1739  Status = BlGetBootOptionInteger(BootEntry->BcdData,
1740  OptionId,
1741  &BootMenuPolicy);
1742  if (NT_SUCCESS(Status))
1743  {
1744  /* We have one, return it */
1745  return BootMenuPolicy;
1746  }
1747 
1748  /* No policy, so assume no menu */
1749  return MenuPolicyLegacy;
1750 }
1751 
1752 VOID
1754  _Out_ PL_MENU_STATUS MenuStatus
1755  )
1756 {
1757  /* For now, don't support key input at all */
1758  MenuStatus->AsULong = 0;
1759  MenuStatus->OemKey = UNICODE_NULL;
1760  MenuStatus->BootIndex = -1;
1761 }
1762 
1763 NTSTATUS
1765  _In_ HANDLE BcdHandle,
1766  _In_ PWCHAR ActionKey
1767  )
1768 {
1769  EfiPrintf(L"Custom actions not yet handled\r\n");
1770  return STATUS_NOT_IMPLEMENTED;
1771 }
1772 
1773 VOID
1775  _In_ HANDLE BcdHandle,
1777  _Out_ PBOOLEAN ExitBootManager
1778  )
1779 {
1780  BL_MENU_STATUS MenuStatus;
1781 
1782  /* Don't exit */
1783  *ExitBootManager = FALSE;
1784 
1785  /* If the legacy menu must be shown, or if we have a boot entry */
1786  if ((BmGetBootMenuPolicy(BootEntry) != MenuPolicyStandard) || (BootEntry))
1787  {
1788  /* Check if any key has been pressed */
1789  BmDisplayGetBootMenuStatus(&MenuStatus);
1790  if (MenuStatus.AnyKey)
1791  {
1792  /* Was the exit key pressed? */
1793  if (MenuStatus.Exit)
1794  {
1795  /* Don't display a menu, and exit */
1796  *ExitBootManager = TRUE;
1798  }
1799  else if (MenuStatus.OemKey)
1800  {
1801  /* Process the OEM key action */
1802  BmProcessCustomAction(BcdHandle, &MenuStatus.KeyValue);
1803  }
1804  else
1805  {
1806  /* Process other keys */
1807  EfiPrintf(L"TODO\r\n");
1808  }
1809  }
1810  }
1811 }
1812 
1813 NTSTATUS
1815  _In_ HANDLE BcdHandle,
1816  _Out_ PBL_LOADED_APPLICATION_ENTRY* SelectedBootEntry,
1817  _Out_ PULONG EntryIndex,
1818  _Out_ PBOOLEAN ExitBootManager
1819  )
1820 {
1821  NTSTATUS Status;
1822  PBL_LOADED_APPLICATION_ENTRY* Sequence;
1823  PBL_LOADED_APPLICATION_ENTRY Entry, SelectedEntry;
1824  ULONG Count, BootIndex, SelectedIndex;
1825  // BOOLEAN FoundFailedEntry;
1827 
1828  /* Initialize locals */
1829  BootIndex = 0;
1830  Count = 0;
1831  Sequence = NULL;
1832  SelectedEntry = NULL;
1833 
1834  /* Enumerate all the boot entries */
1835  Status = BmEnumerateBootEntries(BcdHandle, &Sequence, &Count);
1836  if (!NT_SUCCESS(Status))
1837  {
1838  /* Bail out if we failed */
1839  goto Quickie;
1840  }
1841 
1842  /* Check if there are no entries */
1843  if (!Count)
1844  {
1845  /* This is fatal -- kill the system */
1848  goto Quickie;
1849  }
1850 
1851  /* Check if we don't yet have an array of failed boot entries */
1852  if (!BmpFailedBootEntries)
1853  {
1854  /* Allocate it */
1857  {
1858  /* Zero it out */
1860  }
1861  }
1862 
1863  /* Check if we have a hardcoded boot override */
1865  {
1866  EfiPrintf(L"Hard-coded boot override mode not supported\r\n");
1867  }
1868 
1869  /* Log the OS count */
1870  //BlLogEtwWrite(BOOT_BOOTMGR_MULTI_OS_COUNT);
1871 
1872  /* Check if the display is already active and cached */
1873  if (!BmDisplayStateCached)
1874  {
1875  /* Check if we should display a boot menu */
1879  if (!NT_SUCCESS(Status))
1880  {
1881  /* Assume not */
1883  }
1884  }
1885 
1886  /* Check if there's only one entry to boot anyway */
1887  if (Count == 1)
1888  {
1889  /* Read it */
1890  SelectedEntry = *Sequence;
1891 
1892  /* Process it */
1893  BmpProcessBootEntry(BcdHandle, SelectedEntry, ExitBootManager);
1894 
1895  /* Check if we're not displaying a boot menu */
1896  if (!BmpDisplayBootMenu)
1897  {
1898  /* Now we are */
1900 
1901  /* Return the entry and its index back */
1902  *EntryIndex = 0;
1903  *SelectedBootEntry = SelectedEntry;
1905  goto Quickie;
1906  }
1907  }
1908  else
1909  {
1910  /* Get the default boot entry */
1911  BmpGetDefaultBootEntry(Sequence, Count, &SelectedEntry, &SelectedIndex);
1912 
1913  /* Check if we have a failed boot entry array allocated */
1914  //FoundFailedEntry = FALSE;
1916  {
1917  /* Check if the default entry failed to boot */
1918  if (BmpFailedBootEntries[SelectedIndex])
1919  {
1920  /* Loop through the current boot sequence */
1921  for (SelectedIndex = 0; SelectedIndex < Count; SelectedIndex++)
1922  {
1923  /* Check if there's no sequence for this index, or it failed */
1924  while (!(Sequence[SelectedIndex]) ||
1925  (BmpFailedBootEntries[SelectedIndex]))
1926  {
1927  /* Remember that this is a failed entry */
1928  SelectedEntry = Sequence[SelectedIndex];
1929  //FoundFailedEntry = TRUE;
1931  }
1932  }
1933  }
1934  }
1935 
1936  /* Check if the entry is an OS loader */
1937  if (SelectedEntry->Flags & BL_APPLICATION_ENTRY_WINLOAD)
1938  {
1939  // todo
1940  EfiPrintf(L"todo path\r\n");
1941  }
1942 
1943  /* Check if there's no timeout */
1946  &Timeout);
1947  if ((NT_SUCCESS(Status) && !(Timeout)))
1948  {
1949  /* There isn't, so just process the default entry right away */
1950  BmpProcessBootEntry(BcdHandle, SelectedEntry, ExitBootManager);
1951 
1952  /* Check if we're not displaying a boot menu */
1953  if (!BmpDisplayBootMenu)
1954  {
1955  /* Now we are */
1957 
1958  /* Return the entry and its index back */
1959  *EntryIndex = 0;
1960  *SelectedBootEntry = SelectedEntry;
1962  goto Quickie;
1963  }
1964 
1965  /* Remove the timeout for this boot instance */
1968  }
1969  }
1970 
1971  /* Here is where we display the menu and list of tools */
1972  EfiPrintf(L"Tool selection not yet implemented\r\n");
1973  EfiStall(10000000);
1974  *SelectedBootEntry = NULL;
1975 
1976 Quickie:
1977  /* We are done -- did we have a sequence? */
1978  if (Sequence)
1979  {
1980  /* Do we have any boot entries we parsed? */
1981  while (BootIndex < Count)
1982  {
1983  /* Get the current boot entry */
1984  Entry = Sequence[BootIndex];
1985 
1986  /* Did we fail, or is is not the selected one? */
1987  if ((Entry) && ((Entry != SelectedEntry) || !(NT_SUCCESS(Status))))
1988  {
1989  /* Destroy it, as it won't be needed */
1991  }
1992  else if (Entry == SelectedEntry)
1993  {
1994  /* It's the selected one, return its index */
1995  *EntryIndex = BootIndex;
1996  }
1997 
1998  /* Move to the next entry */
1999  BootIndex++;
2000  }
2001 
2002  /* Free the sequence of entries */
2003  BlMmFreeHeap(Sequence);
2004  }
2005 
2006  /* Return the selection result */
2007  return Status;
2008 }
2009 
2010 NTSTATUS
2013  _In_ ULONG LaunchCode
2014  )
2015 {
2016  NTSTATUS Status;
2017  PBL_LOADED_APPLICATION_ENTRY RecoveryEntry;
2018  HANDLE BcdHandle;
2019  PGUID RecoverySequence;
2020  ULONG Count, i, RecoveryIndex, SequenceCount;
2021  PBL_LOADED_APPLICATION_ENTRY* Sequence;
2022 
2023  /* Initialize locals */
2024  RecoveryIndex = 0;
2025  Sequence = NULL;
2026  RecoverySequence = NULL;
2027  Count = 0;
2028  BcdHandle = NULL;
2029 
2030  /* Open the BCD*/
2031  Status = BmOpenDataStore(&BcdHandle);
2032  if (!NT_SUCCESS(Status))
2033  {
2034  goto Quickie;
2035  }
2036 
2037  /* Get the recovery sequence list */
2038  Status = BlGetBootOptionGuidList(BootEntry->BcdData,
2040  &RecoverySequence,
2041  &SequenceCount);
2042  if (!NT_SUCCESS(Status))
2043  {
2044  goto Quickie;
2045  }
2046 
2047  /* Get the sequence of boot entries out of it */
2048  Status = BmGetBootSequence(BcdHandle,
2049  RecoverySequence,
2050  SequenceCount,
2052  &Sequence,
2053  &Count);
2054  if (!NT_SUCCESS(Status))
2055  {
2056  goto Quickie;
2057  }
2058 
2059  /* Was the BCD open? */
2060  if (BcdHandle)
2061  {
2062  /* Close it */
2063  BmCloseDataStore(BcdHandle);
2064  }
2065 
2066  /* Now go over every entry in the sequence */
2067  for (i = 0; i < Count; ++i)
2068  {
2069  /* Check the code for this recovery launch */
2070  if (LaunchCode == 2 || LaunchCode == 5)
2071  {
2072  /* Remove the override if there is one, and set it to 4 */
2074  BlAppendBootOptionInteger(Sequence[i],
2076  4);
2077  }
2078  else if (LaunchCode == 3)
2079  {
2080  /* Remove the override if there is one, and set it to 10 */
2082  BlAppendBootOptionInteger(Sequence[i],
2084  10);
2085  }
2086 
2087  /* Launch the boot entry for this part of the recovery sequence */
2088  Status = BmpLaunchBootEntry(Sequence[i], NULL, LaunchCode, FALSE);
2089  if (!NT_SUCCESS(Status))
2090  {
2091  break;
2092  }
2093  }
2094 
2095 Quickie:
2096  /* Did we have a sequence of entries? */
2097  if (Sequence)
2098  {
2099  /* Loop through each one */
2100  for (RecoveryIndex = 0; RecoveryIndex < Count; RecoveryIndex++)
2101  {
2102  /* Does this index have an allocated boot entry? */
2103  RecoveryEntry = Sequence[RecoveryIndex];
2104  if (RecoveryEntry)
2105  {
2106  /* Destroy it */
2107  BlDestroyBootEntry(RecoveryEntry);
2108  }
2109  }
2110 
2111  /* Free the sequence itself */
2112  BlMmFreeHeap(Sequence);
2113  }
2114 
2115  /* Was there a sequence list? */
2116  if (RecoverySequence)
2117  {
2118  /* Free it */
2119  BlMmFreeHeap(RecoverySequence);
2120  }
2121 
2122  /* Return back to caller */
2123  return Status;
2124 }
2125 
2126 ULONG
2129  _In_ ULONG LaunchCode
2130  )
2131 {
2132  ULONG BootError;
2133  NTSTATUS Status;
2134  BOOLEAN Restart, NoError;
2135 
2136  /* Assume we'll just reboot */
2137  BootError = Reboot;
2138 
2139  /* Should we reboot? */
2142  &Restart);
2143  if ((NT_SUCCESS(Status)) && (Restart))
2144  {
2145  return BootError;
2146  }
2147 
2148  /* Should we not show errors, and thus, reboot? */
2151  &NoError);
2152  if ((NT_SUCCESS(Status)) && (NoError))
2153  {
2154  return BootError;
2155  }
2156 
2157  /* Is there an internal boot error? */
2159  {
2160  /* Return it -- but it's a pointer? */
2161  return (ULONG_PTR)BmpInternalBootError; // ???
2162  }
2163 
2164  /* Otherwise, show the menu to see what to do */
2165  EfiPrintf(L"Error menu not yet implemented\r\n");
2166  return BootError;
2167 }
2168 
2169 NTSTATUS
2172  )
2173 {
2174  ULONG NextOffset, DataOffset, ListOffset;
2175  PBL_BCD_OPTION Option, ListOption;
2176  BcdElementType ElementType;
2177  PBCD_DEVICE_OPTION BcdDevice;
2178 
2179  /* Starting at offset 0, loop every BCD option */
2180  NextOffset = 0;
2181  do
2182  {
2183  /* Get the current option, and its offset */
2184  Option = (PBL_BCD_OPTION)((ULONG_PTR)BootEntry->BcdData + NextOffset);
2185  NextOffset = Option->NextEntryOffset;
2186 
2187  /* If it's empty, ignore it */
2188  if (Option->Empty)
2189  {
2190  continue;
2191  }
2192 
2193  /* If it's not a device option, ignore it */
2194  ElementType.PackedValue = Option->Type;
2195  if (ElementType.Format != BCD_TYPE_DEVICE)
2196  {
2197  continue;
2198  }
2199 
2200  /* Get the data offset */
2201  DataOffset = Option->DataOffset;
2202 
2203  /* Extract the device out of it */
2204  BcdDevice = (PBCD_DEVICE_OPTION)((ULONG_PTR)BootEntry->BcdData + DataOffset);
2205 
2206  /* If the device is already fully specified, no need to build it */
2207  if (!(BcdDevice->DeviceDescriptor.Flags & 1))
2208  {
2209  continue;
2210  }
2211 
2212  /* Otherwise, check if there's any list options as well */
2213  ListOption = NULL;
2214  ListOffset = Option->ListOffset;
2215  if (Option->ListOffset)
2216  {
2217  ListOption = (PBL_BCD_OPTION)((ULONG_PTR)BootEntry->BcdData + ListOffset);
2218  }
2219 
2220  /* And now call BlCreateDevice to build the full device descriptor */
2221  EfiPrintf(L"Unspecified devices not yet supported: %p\r\n", ListOption);
2222  return STATUS_NOT_SUPPORTED;
2223  } while (NextOffset != 0);
2224 
2225  /* Devices created successfully */
2226  return STATUS_SUCCESS;
2227 }
2228 
2229 NTSTATUS
2232  _Out_ PULONG LaunchCode,
2234  )
2235 {
2236  PWCHAR AppPath;
2237  NTSTATUS Status;
2238  PBL_DEVICE_DESCRIPTOR AppDevice;
2239  BL_RETURN_ARGUMENTS ReturnArgs;
2241  ULONG AppHandle;
2242 
2243  /* Get the application path */
2244  Status = BlGetBootOptionString(BootEntry->BcdData,
2246  &AppPath);
2247  if (!NT_SUCCESS(Status))
2248  {
2249  /* If we couldn't find one, set this to NULL */
2250  AppPath = NULL;
2251  }
2252 
2253  /* Check if this is a PXE startup.com */
2254  if (BootEntry->Flags & BL_APPLICATION_ENTRY_STARTUP)
2255  {
2256 #if BL_NET_SUPPORT
2257  /* Do soft reboot to launch it */
2258  Status = BlNetSoftReboot(BootEntry);
2259 #else
2260  EfiPrintf(L"Net boot not supported\r\n");
2262 #endif
2263  /* Nothing else for us to do */
2264  goto Quickie;
2265  }
2266 
2267  /* Loop as long as boot was not cancelled */
2268  do
2269  {
2270  /* Load the boot application */
2271  Status = BlImgLoadBootApplication(BootEntry, &AppHandle);
2272 
2273  /* Did we not find it? */
2274  if (Status == STATUS_NOT_FOUND)
2275  {
2276  /* Get the device for the boot application */
2277  Status = BlGetBootOptionDevice(BootEntry->BcdData,
2279  &AppDevice,
2280  NULL);
2281  if (!NT_SUCCESS(Status))
2282  {
2283  /* Force re-enumeration */
2284  Status = BlFwEnumerateDevice(AppDevice);
2285  }
2286 
2287  /* Did re-enumeration work? */
2288  if (!NT_SUCCESS(Status))
2289  {
2290  /* Nope, raise a fatal error */
2292  (ULONG_PTR)AppPath,
2293  Status,
2294  0,
2295  0);
2296  goto Quickie;
2297  }
2298 
2299  /* Yes, try booting it again */
2300  Status = BlImgLoadBootApplication(BootEntry, &AppHandle);
2301  }
2302 
2303  /* Was boot cancelled?*/
2304  if (Status == STATUS_CANCELLED)
2305  {
2306  /* Should we display the menu, or is there no launch sequence? */
2307  if ((BmGetBootMenuPolicy(BootEntry) != MenuPolicyStandard) ||
2308  !(MiscGetBootOption(BootEntry->BcdData,
2310  {
2311  /* Bail out, the menu will take care of it */
2312  goto Quickie;
2313  }
2314 
2315  /* No menu and there's a sequence, launch it */
2316  *LaunchCode = 4;
2317  *Recover = TRUE;
2318  goto Quickie;
2319  }
2320 
2321  /* STATUS_FVE_LOCKED_VOLUME -- bitlocker volume is locked */
2322  if (Status == 0xC0210000)
2323  {
2324  /* Launch recovery mode */
2325  *LaunchCode = 4;
2326  *Recover = TRUE;
2327  goto Quickie;
2328  }
2329 
2330  /* Was there some other error launching the boot application? */
2331  if (!NT_SUCCESS(Status))
2332  {
2333  /* Raise a fatal error */
2335  (ULONG_PTR)AppPath,
2336  Status,
2337  0,
2338  0);
2339  goto Quickie;
2340  }
2341 
2342  /* Zero out the return arguments */
2343  RtlZeroMemory(&ReturnArgs, sizeof(ReturnArgs));
2344 
2345  /* Log to ETW this launch */
2346  //BmpLogApplicationLaunchEvent(&BootEntry->Guid, AppPath);
2347 
2348  /* Launch the boot application*/
2349  Status = BlImgStartBootApplication(AppHandle, &ReturnArgs);
2350 
2351 #if BL_BITLOCKER_SUPPORT
2352  /* Bitlocker stuff */
2353  BlFveSecureBootCheckpointAppReturn(BootEntry, &ReturnArgs);
2354 #endif
2355 
2356  /* Log in the boot status log the launch */
2357  //BlBsdLogEntry(1, 0x12, &BootEntry->Guid, 0x14);
2358 
2359  /* Unloac the boot application if we've returned */
2360  BlImgUnloadBootApplication(AppHandle);
2361 
2362  /* Keep going unless STATUS_RESTART_BOOT_APPLICATION */
2363  } while (Status != 0xC0000453);
2364 
2365  /* We've come back. Assume we need to launch the recovery sequence */
2366  *Recover = TRUE;
2367 
2368  /* Why did we get back? */
2369  if (ReturnArgs.Flags & 1)
2370  {
2371  /* Flag 1 -- should we display advanced options? */
2372  Status = BlGetBootOptionBoolean(BootEntry->BcdData,
2374  &AdvancedOptions);
2375  if ((NT_SUCCESS(Status)) && (AdvancedOptions))
2376  {
2377  /* Yes, so return with code 2 */
2378  *LaunchCode = 2;
2379  }
2380  else
2381  {
2382  /* No, return with code 1 */
2383  *LaunchCode = 1;
2384  }
2385  }
2386  else if (ReturnArgs.Flags & 4)
2387  {
2388  /* Flag 4 -- unknown */
2389  *LaunchCode = 1;
2390  }
2391  else if (ReturnArgs.Flags & 8)
2392  {
2393  /* Flag 5 -- unknown */
2394  *LaunchCode = 5;
2395  }
2396  else if (ReturnArgs.Flags & 0x10)
2397  {
2398  /* Flag 6 -- unknown */
2399  *LaunchCode = 6;
2400  }
2401  else if (ReturnArgs.Flags & 0x20)
2402  {
2403  /* Flag 7 -- unknown */
2404  *LaunchCode = 7;
2405  }
2406  else if (ReturnArgs.Flags & BL_RETURN_ARGUMENTS_NO_PAE_FLAG)
2407  {
2408  /* PAE is not supported -- refuse to boot */
2409  *Recover = FALSE;
2411  }
2412 
2413 Quickie:
2414  /* All done, did we have an application path? */
2415  if (AppPath)
2416  {
2417  /* Free it */
2418  BlMmFreeHeap(AppPath);
2419  }
2420 
2421  /* Back to the caller now */
2422  return Status;
2423 }
2424 
2425 NTSTATUS
2428  _Out_ PULONG EntryIndex,
2429  _In_ ULONG LaunchCode,
2430  _In_ BOOLEAN LaunchWinRe
2431  )
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 }
2720 
2721 /*++
2722  * @name BmMain
2723  *
2724  * The BmMain function implements the Windows Boot Application entrypoint for
2725  * the Boot Manager.
2726  *
2727  * @param BootParameters
2728  * Pointer to the Boot Application Parameter Block.
2729  *
2730  * @return NT_SUCCESS if the image was loaded correctly, relevant error code
2731  * otherwise.
2732  *
2733  *--*/
2734 NTSTATUS
2735 NTAPI
2738  )
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 }
3244 
#define BL_APPLICATION_ENTRY_REBOOT_ON_ERROR
Definition: bl.h:73
#define BL_APPLICATION_FLAG_CONVERTED_FROM_EFI
Definition: bl.h:52
#define BCD_APPLICATION_TYPE_SETUPLDR
Definition: bcd.h:40
BL_MENU_POLICY BmGetBootMenuPolicy(_In_ PBL_LOADED_APPLICATION_ENTRY BootEntry)
Definition: bootmgr.c:1685
NTSTATUS NTAPI BmMain(_In_ PBOOT_APPLICATION_PARAMETER_BLOCK BootParameters)
Definition: bootmgr.c:2736
PBL_DEVICE_DESCRIPTOR BlpBootDevice
Definition: bootlib.c:16
ObjectType
Definition: metafile.c:80
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
#define STATUS_INVALID_IMAGE_WIN_64
Definition: ntstatus.h:887
GUID * PGUID
Definition: bdasup.h:12
BOOLEAN BmBootIniUsed
Definition: bootmgr.c:30
VOID BiCloseKey(_In_ HANDLE KeyHandle)
Definition: bootreg.c:141
BL_LIBRARY_PARAMETERS BlpLibraryParameters
Definition: bootlib.c:15
BL_BOOT_ERROR BmpErrorBuffer
Definition: bootmgr.c:26
BL_BSD_LOG_OBJECT BsdpLogObject
Definition: bootmgr.c:880
#define BL_LIBRARY_FLAG_REINITIALIZE
Definition: bl.h:129
#define BL_APPLICATION_ENTRY_DISPLAY_ORDER
Definition: bl.h:80
ULONG BlGetBootOptionListSize(_In_ PBL_BCD_OPTION BcdOption)
Definition: bcdopt.c:79
#define TRUE
Definition: types.h:120
NTSTATUS BmpFwGetApplicationDirectoryPath(_In_ PUNICODE_STRING ApplicationDirectoryPath)
Definition: bootmgr.c:229
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
_In_ NDIS_ERROR_CODE ErrorCode
Definition: ndis.h:4436
NTSTATUS BlFileOpen(_In_ ULONG DeviceId, _In_ PWCHAR FileName, _In_ ULONG Flags, _Out_ PULONG FileId)
Definition: file.c:477
_Inout_ PUSB_DEVICE_HANDLE DeviceHandle
Definition: hubbusif.h:121
NTSTATUS BlDeviceClose(_In_ ULONG DeviceId)
Definition: device.c:2073
NTSTATUS BmResumeFromHibernate(_Out_ PHANDLE BcdResumeHandle)
Definition: bootmgr.c:1130
NTSTATUS BmPurgeOption(_In_ HANDLE BcdHandle, _In_ PGUID ObjectId, _In_ ULONG Type)
Definition: bootmgr.c:1187
Type
Definition: Type.h:6
struct _BL_BCD_OPTION * PBL_BCD_OPTION
VOID BlDestroyLibrary(VOID)
Definition: bootlib.c:405
DEFINE_GUID(GUID_WINDOWS_BOOTMGR, 0x9DEA862C, 0x5CDD, 0x4E70, 0xAC, 0xC1, 0xF3, 0x2B, 0x34, 0x4D, 0x47, 0x95)
struct _Entry Entry
Definition: kefuncs.h:640
NTSTATUS BlGetBootOptionGuid(_In_ PBL_BCD_OPTION List, _In_ ULONG Type, _Out_ PGUID Value)
Definition: bcdopt.c:228
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
NTSTATUS BmpFwGetFullPath(_In_ PWCHAR FileName, _Out_ PWCHAR *FullPath)
Definition: bootmgr.c:644
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:225
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define BL_DEVICE_WRITE_ACCESS
Definition: bl.h:154
NTSTATUS BmFwVerifySelfIntegrity(VOID)
Definition: bootmgr.c:1087
ULONG BmpFatalErrorMessageFilter(_In_ NTSTATUS ErrorStatus, _Out_ PULONG ErrorResourceId)
Definition: bootmgr.c:409
PWCHAR ErrorString
Definition: bootmgr.h:42
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
NTSTATUS BmpBgDisplayClearScreen(_In_ ULONG Color)
Definition: bootmgr.c:1056
#define BL_APPLICATION_ENTRY_NTLDR
Definition: bl.h:74
VOID BmErrorPurge(VOID)
Definition: bootmgr.c:445
ULONG Version
Definition: bl.h:817
WCHAR KeyValue
Definition: bl.h:887
ULONG DataSize
Definition: bl.h:849
#define BL_FATAL_ERROR_BCD_READ
Definition: bootmgr.h:55
#define BL_FATAL_ERROR_APP_LOAD
Definition: bootmgr.h:56
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS BcdOpenStoreFromFile(_In_ PUNICODE_STRING FileName, _In_ PHANDLE StoreHandle)
Definition: bcd.c:1322
ULONG Unknown1
Definition: bootmgr.h:41
NTSTATUS BmpLaunchBootEntry(_In_ PBL_LOADED_APPLICATION_ENTRY BootEntry, _Out_ PULONG EntryIndex, _In_ ULONG LaunchCode, _In_ BOOLEAN LaunchWinRe)
Definition: bootmgr.c:2426
NTSTATUS BlPdQueryData(_In_ const GUID *DataGuid, _In_ PVOID Unknown, _Inout_ PBL_PD_DATA_BLOB DataBlob)
Definition: bootlib.c:457
#define STATUS_INVALID_PARAMETER_9
Definition: ntstatus.h:469
#define BL_APPLICATION_ENTRY_BOOTSECTOR
Definition: bl.h:78
NTSTATUS BlDisplayClearScreen(VOID)
Definition: display.c:942
ULONG NextEntryOffset
Definition: bl.h:851
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
_Inout_ __drv_aliasesMem PSLIST_ENTRY _Inout_ PSLIST_ENTRY _In_ ULONG Count
Definition: exfuncs.h:1015
#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
VOID BlStatusError(_In_ ULONG ErrorCode, _In_ ULONG Parameter1, _In_ ULONG_PTR Parameter2, _In_ ULONG_PTR Parameter3, _In_ ULONG_PTR Parameter4)
Definition: debug.c:121
NTSTATUS BcdOpenObject(_In_ HANDLE BcdHandle, _In_ PGUID ObjectId, _Out_ PHANDLE ObjectHandle)
Definition: bcd.c:506
NTSTATUS BlMmFreePhysicalPages(_In_ PHYSICAL_ADDRESS Address)
Definition: pagealloc.c:1187
static const WCHAR Description[]
Definition: oid.c:1266
uint16_t * PWCHAR
Definition: typedefs.h:54
#define STATUS_FILE_INVALID
Definition: ntstatus.h:374
NTSTATUS BmpPopulateBootEntryList(_In_ HANDLE BcdHandle, _In_ PGUID SequenceList, _In_ ULONG Flags, _Out_ PBL_LOADED_APPLICATION_ENTRY *BootSequence, _Out_ PULONG SequenceCount)
Definition: bootmgr.c:1247
DWORD FormatString(DWORD dwFlags, HINSTANCE hInstance, DWORD dwStringId, DWORD dwLanguageId, LPWSTR lpBuffer, DWORD nSize, va_list *Arguments)
Definition: fontview.c:49
#define BL_APPLICATION_ENTRY_SETUPLDR
Definition: bl.h:77
enum OPTION_FLAGS Options
Definition: stats.c:44
BOOLEAN BsdpLogObjectInitialized
Definition: bootmgr.c:881
static USHORT PathLength
NTSTATUS BlMmFreeHeap(_In_ PVOID Buffer)
Definition: heapalloc.c:663
ULONG Exit
Definition: bl.h:881
ULONG DataSize
Definition: bl.h:1347
NTSTATUS BlGetBootOptionInteger(_In_ PBL_BCD_OPTION List, _In_ ULONG Type, _Out_ PULONGLONG Value)
Definition: bcdopt.c:467
NTSTATUS BlFwEnumerateDevice(_In_ PBL_DEVICE_DESCRIPTOR Device)
Definition: firmware.c:2375
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
BL_PACKED_BOOT_ERROR BmpPackedBootError
Definition: bootmgr.c:28
NTSTATUS BmLaunchRecoverySequence(_In_ PBL_LOADED_APPLICATION_ENTRY BootEntry, _In_ ULONG LaunchCode)
Definition: bootmgr.c:2011
BL_LOADED_APPLICATION_ENTRY BlpApplicationEntry
Definition: bootlib.c:19
NTSTATUS BcdEnumerateAndUnpackElements(_In_ HANDLE BcdHandle, _In_ HANDLE ObjectHandle, _Out_opt_ PBCD_ELEMENT Elements, _Inout_ PULONG ElementSize, _Out_ PULONG ElementCount)
Definition: bcd.c:1241
uint32_t ULONG_PTR
Definition: typedefs.h:63
ULONG DataOffset
Definition: bl.h:848
HANDLE FileHandle
Definition: stats.c:38
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
PWCHAR ParentFileName
Definition: bootmgr.c:32
BL_LOCAL_DEVICE Local
Definition: bl.h:957
GUID BmApplicationIdentifier
Definition: bootmgr.c:23
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
NTSTATUS BlDisplaySetCursorType(_In_ ULONG Type)
Definition: display.c:968
#define UNICODE_NULL
ULONG HelpMsgId
Definition: bootmgr.h:44
ULONG ErrorCode
Definition: bootmgr.h:39
#define BCD_IMAGE_TYPE_REAL_MODE
Definition: bcd.h:32
Definition: Header.h:8
#define BCD_OBJECT_TYPE_APPLICATION
Definition: bcd.h:44
#define OBJ_NAME_PATH_SEPARATOR
Definition: arcname_tests.c:25
ULONG Unknown2
Definition: bootmgr.h:45
#define BL_APPLICATION_ENTRY_WINRESUME
Definition: bl.h:76
enum _BL_MENU_POLICY BL_MENU_POLICY
VOID BmpInitializeBootStatusDataLog(VOID)
Definition: bootmgr.c:951
PBL_BCD_OPTION BcdData
Definition: bl.h:868
ULONG LibraryFlags
Definition: bl.h:758
NTSTATUS BmpCreateDevices(_In_ PBL_LOADED_APPLICATION_ENTRY BootEntry)
Definition: bootmgr.c:2170
ULONG OemKey
Definition: bl.h:880
NTSTATUS BmFwInitializeBootDirectoryPath(VOID)
Definition: bootmgr.c:301
NTSTATUS MmPapAllocatePhysicalPagesInRange(_Inout_ PPHYSICAL_ADDRESS BaseAddress, _In_ BL_MEMORY_TYPE MemoryType, _In_ ULONGLONG Pages, _In_ ULONG Attributes, _In_ ULONG Alignment, _In_ PBL_MEMORY_DESCRIPTOR_LIST NewList, _In_opt_ PBL_ADDRESS_RANGE Range, _In_ ULONG RangeType)
Definition: pagealloc.c:438
BOOLEAN BlDisplayValidOemBitmap(VOID)
Definition: display.c:879
ULONGLONG PostTime
Definition: bootmgr.c:22
NTSTATUS BmGetOptionList(_In_ HANDLE BcdHandle, _In_ PGUID ObjectId, _In_ PBL_BCD_OPTION *OptionList)
Definition: bootmgr.c:43
#define BL_APPLICATION_ENTRY_FIXED_SEQUENCE
Definition: bl.h:81
Definition: bl.h:897
Definition: bl.h:892
unsigned char BOOLEAN
DEVICE_TYPE DeviceType
Definition: bl.h:951
static GUID * Guid
Definition: apphelp.c:93
smooth NULL
Definition: ftsmooth.c:416
NTSTATUS BlGetBootOptionBoolean(_In_ PBL_BCD_OPTION List, _In_ ULONG Type, _Out_ PBOOLEAN Value)
Definition: bcdopt.c:504
VOID BlBsdInitializeLog(_In_ PBL_DEVICE_DESCRIPTOR LogDevice, _In_ PWCHAR LogPath, _In_ ULONG Flags)
Definition: bootmgr.c:884
#define BL_APPLICATION_ENTRY_RECOVERY
Definition: bl.h:82
PVOID BlMmAllocateHeap(_In_ SIZE_T Size)
Definition: heapalloc.c:569
NTSTATUS BlImgStartBootApplication(_In_ ULONG AppHandle, _Inout_ PBL_RETURN_ARGUMENTS ReturnArguments)
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:426
#define _Out_
Definition: no_sal2.h:323
PBL_LOADED_APPLICATION_ENTRY BmpSelectedBootEntry
Definition: bootmgr.c:36
NTSTATUS BmGetEntryDescription(_In_ HANDLE BcdHandle, _In_ PGUID ObjectId, _Out_ PBCD_OBJECT_DESCRIPTION Description)
Definition: bootmgr.c:1213
Definition: bufpool.h:45
Definition: bl.h:864
BL_DEVICE_DESCRIPTOR DeviceDescriptor
Definition: bcd.h:298
void * PVOID
Definition: retypes.h:9
PWCHAR BlResourceFindMessage(_In_ ULONG MsgId)
Definition: resource.c:349
PBCD_ELEMENT_HEADER Header
Definition: bcd.h:291
NTSTATUS BlSecureBootIsEnabled(_Out_ PBOOLEAN SecureBootEnabled)
Definition: firmware.c:732
BOOLEAN BmBootEntryOverridePresent
Definition: bootmgr.c:37
#define STATUS_IMAGE_CHECKSUM_MISMATCH
Definition: ntstatus.h:663
Definition: bl.h:251
VOID BmFwMemoryInitialize(VOID)
Definition: bootmgr.c:1026
PWCHAR FileName
Definition: bootmgr.h:43
VOID BmpGetDefaultBootEntry(_In_ PBL_LOADED_APPLICATION_ENTRY *Sequence, _In_ ULONG Count, _Out_ PBL_LOADED_APPLICATION_ENTRY *DefaultEntry, _Out_ PULONG DefaultIndex)
Definition: bootmgr.c:1638
VOID BmpErrorLog(_In_ ULONG ErrorCode, _In_ NTSTATUS ErrorStatus, _In_ ULONG ErrorMsgId, _In_ PWCHAR FileName, _In_ ULONG HelpMsgId)
Definition: bootmgr.c:464
Definition: bl.h:893
_In_ HANDLE Handle
Definition: extypes.h:390
PBL_BCD_OPTION MiscGetBootOption(_In_ PBL_BCD_OPTION List, _In_ ULONG Type)
Definition: bcdopt.c:17
#define STATUS_NOT_FOUND
Definition: shellext.h:72
VOID BlDestroyBootEntry(_In_ PBL_LOADED_APPLICATION_ENTRY AppEntry)
Definition: bootlib.c:442
#define BL_FILE_WRITE_ACCESS
Definition: bl.h:149
ULONGLONG Maximum
Definition: bl.h:1016
ULONG Format
Definition: bcd.h:238
NTSTATUS BlReplaceBootOptions(_In_ PBL_LOADED_APPLICATION_ENTRY AppEntry, _In_ PBL_BCD_OPTION NewOptions)
Definition: bcdopt.c:824
NTSYSAPI ULONG NTAPI RtlEqualMemory(CONST VOID *Source1, CONST VOID *Source2, ULONG Length)
#define BL_APPLICATION_ENTRY_STARTUP
Definition: bl.h:72
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSTATUS BiGetObjectDescription(_In_ HANDLE ObjectHandle, _Out_ PBCD_OBJECT_DESCRIPTION Description)
Definition: bcd.c:1178
Definition: bl.h:231
NTSTATUS BlCopyBootOptions(_In_ PBL_BCD_OPTION OptionList, _Out_ PBL_BCD_OPTION *CopiedOptions)
Definition: bcdopt.c:597
uint64_t ULONGLONG
Definition: typedefs.h:65
ULONG BmDisplayDumpError(_In_ PBL_LOADED_APPLICATION_ENTRY BootEntry, _In_ ULONG LaunchCode)
Definition: bootmgr.c:2127
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 swprintf(buf, format,...)
Definition: sprintf.c:56
#define STATUS_CANCELLED
Definition: udferr_usr.h:170
NTSTATUS BmpProcessBadMemory(VOID)
Definition: bootmgr.c:1163
NTSTATUS BlImgUnloadBootApplication(_In_ ULONG AppHandle)
Definition: image.c:2021
VOID BmpProcessBootEntry(_In_ HANDLE BcdHandle, _In_ PBL_LOADED_APPLICATION_ENTRY BootEntry, _Out_ PBOOLEAN ExitBootManager)
Definition: bootmgr.c:1774
NTSTATUS ErrorStatus
Definition: bootmgr.h:40
FORCEINLINE VOID BlSetupDefaultParameters(_Out_ PBL_LIBRARY_PARAMETERS LibraryParameters)
Definition: bl.h:1355
BL_LOCAL_DEVICE_TYPE Type
Definition: bl.h:926
NTSTATUS BlAppendBootOptions(_In_ PBL_LOADED_APPLICATION_ENTRY AppEntry, _In_ PBL_BCD_OPTION Options)
Definition: bcdopt.c:737
PGUID BlGetApplicationIdentifier(VOID)
Definition: bootlib.c:414
ULONG Type
Definition: bl.h:847
struct _BL_BCD_OPTION BL_BCD_OPTION
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS PhysicalAddress
Definition: iotypes.h:1061
char * PBOOLEAN
Definition: retypes.h:11
ULONG BlobSize
Definition: bl.h:1348
VOID BmCloseDataStore(_In_ HANDLE Handle)
Definition: bootmgr.c:695
ULONG MinimumHeapSize
Definition: bl.h:761
static const WCHAR L[]
Definition: oid.c:1250
NTSTATUS BmOpenBootIni(VOID)
Definition: bootmgr.c:400
NTSTATUS BlGetBootOptionString(_In_ PBL_BCD_OPTION List, _In_ ULONG Type, _Out_ PWCHAR *Value)
Definition: bcdopt.c:146
#define NTSTATUS
Definition: precomp.h:20
#define BL_FATAL_ERROR_BCD_ENTRIES
Definition: bootmgr.h:57
NTSTATUS BmOpenDataStore(_Out_ PHANDLE Handle)
Definition: bootmgr.c:711
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:414
#define BL_FATAL_ERROR_BCD_PARSE
Definition: bootmgr.h:59
NTSTATUS BmProcessCustomAction(_In_ HANDLE BcdHandle, _In_ PWCHAR ActionKey)
Definition: bootmgr.c:1764
_CRTIMP wchar_t *__cdecl wcsncat(wchar_t *_Dest, const wchar_t *_Source, size_t _Count)
PBL_LOADED_APPLICATION_ENTRY * BmpFailedBootEntries
Definition: bootmgr.c:35
#define BCD_APPLICATION_TYPE_RESUME
Definition: bcd.h:37
ULONGLONG Minimum
Definition: bl.h:1015
NTSTATUS BlAppendBootOptionString(_In_ PBL_LOADED_APPLICATION_ENTRY AppEntry, _In_ ULONG OptionId, _In_ PWCHAR OptionString)
Definition: bcdopt.c:689
VOID BlImgQueryCodeIntegrityBootOptions(_In_ PBL_LOADED_APPLICATION_ENTRY ApplicationEntry, _Out_ PBOOLEAN IntegrityChecksDisabled, _Out_ PBOOLEAN TestSigning)
Definition: image.c:651
ULONG BlpApplicationFlags
Definition: bootlib.c:21
Status
Definition: gdiplustypes.h:24
GUID Guid
Definition: bl.h:867
NTSTATUS BlFileClose(_In_ ULONG FileId)
Definition: file.c:220
Definition: bl.h:896
ULONG TranslationType
Definition: bl.h:759
#define _In_
Definition: no_sal2.h:204
#define BL_DEVICE_READ_ACCESS
Definition: bl.h:153
ULONG_PTR SIZE_T
Definition: typedefs.h:78
NTSTATUS BlGetBootOptionDevice(_In_ PBL_BCD_OPTION List, _In_ ULONG Type, _Out_ PBL_DEVICE_DESCRIPTOR *Value, _In_opt_ PBL_BCD_OPTION *ExtraOptions)
Definition: bcdopt.c:321
#define BCD_APPLICATION_TYPE_STARTUPCOM
Definition: bcd.h:42
struct _FileName FileName
Definition: fatprocs.h:884
NTSTATUS BmpUpdateApplicationOptions(_In_ HANDLE BcdHandle)
Definition: bootmgr.c:208
WCHAR BmpFileNameBuffer[128]
Definition: bootmgr.c:31
static ULONG Timeout
Definition: ping.c:61
GUID AssociatedEntry
Definition: bcd.h:297
ULONG BlGetBootOptionSize(_In_ PBL_BCD_OPTION BcdOption)
Definition: bcdopt.c:115
_CRTIMP wchar_t *__cdecl wcsncpy(wchar_t *_Dest, const wchar_t *_Source, size_t _Count)
#define BL_FILE_READ_ACCESS
Definition: bl.h:148
#define BCD_APPLICATION_TYPE_BOOTMGR
Definition: bcd.h:35
#define RTL_NUMBER_OF(x)
Definition: RtlRegistry.c:12
#define BCD_APPLICATION_TYPE_BOOTSECTOR
Definition: bcd.h:41
NTSTATUS BcdDeleteElement(_In_ HANDLE ObjectHandle, _In_ ULONG Type)
Definition: bcd.c:560
VOID BiDereferenceHive(_In_ HANDLE KeyHandle)
Definition: bootreg.c:117
#define STATUS_NO_MEMORY
Definition: ntstatus.h:246
#define BL_FATAL_ERROR_NO_PAE
Definition: bootmgr.h:60
#define BCD_TYPE_DEVICE
Definition: bcd.h:21
unsigned int * PULONG
Definition: retypes.h:1
NTSTATUS BlUtlRegisterProgressRoutine(VOID)
Definition: util.c:244
NTSTATUS BmEnumerateBootEntries(_In_ HANDLE BcdHandle, _Out_ PBL_LOADED_APPLICATION_ENTRY **BootSequence, _Out_ PULONG SequenceCount)
Definition: bootmgr.c:1509
ULONG PackedValue
Definition: bcd.h:234
VOID EfiPrintf(_In_ PWCHAR Format,...)
Definition: firmware.c:126
#define BL_LIBRARY_FLAG_REINITIALIZE_ALL
Definition: bl.h:130
#define BL_MM_REQUEST_DEFAULT_TYPE
Definition: bl.h:122
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
#define BL_RETURN_ARGUMENTS_NO_PAE_FLAG
Definition: bl.h:67
struct _BCD_DEVICE_OPTION * PBCD_DEVICE_OPTION
#define STATUS_UNEXPECTED_IO_ERROR
Definition: ntstatus.h:455
NTSTATUS BlImgLoadBootApplication(_In_ PBL_LOADED_APPLICATION_ENTRY BootEntry, _Out_ PULONG AppHandle)
Definition: image.c:1324
VOID BlStatusPrint(_In_ PCWCH Format,...)
Definition: debug.c:75
NTSTATUS BmFwRegisterRevocationList(VOID)
Definition: bootmgr.c:1105
ULONG MinimumAllocationCount
Definition: bl.h:760
Definition: bl.h:894
ULONG Flags
Definition: bl.h:866
BL_MEMORY_DESCRIPTOR_LIST MmMdlUnmappedAllocated
Definition: pagealloc.c:38
#define STATUS_NOT_SUPPORTED
Definition: ntstatus.h:409
unsigned int ULONG
Definition: retypes.h:1
PWCHAR BootDirectory
Definition: bootmgr.c:24
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#define ULONG_PTR
Definition: config.h:101
VOID BmDisplayGetBootMenuStatus(_Out_ PL_MENU_STATUS MenuStatus)
Definition: bootmgr.c:1753
#define BCD_APPLICATION_TYPE_OSLOADER
Definition: bcd.h:36
ULONG ListOffset
Definition: bl.h:850
#define BL_RETURN_ARGUMENTS_VERSION
Definition: bl.h:64
NTSTATUS BlpDeviceOpen(_In_ PBL_DEVICE_DESCRIPTOR Device, _In_ ULONG Flags, _In_ ULONG Unknown, _Out_ PULONG DeviceId)
Definition: device.c:2111
ULONG AnyKey
Definition: bl.h:877
struct _BL_BSD_LOG_OBJECT * PBL_BSD_LOG_OBJECT
ULONG Empty
Definition: bl.h:852
BOOLEAN BmDisplayStateCached
Definition: bootmgr.c:34
PBL_BOOT_ERROR BmpInternalBootError
Definition: bootmgr.c:27
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
return STATUS_SUCCESS
Definition: btrfs.c:2938
PWCHAR BlResourceFindHtml(VOID)
Definition: resource.c:305
PBL_BOOT_ERROR BootError
Definition: bootmgr.h:50
NTSTATUS BlAppendBootOptionInteger(_In_ PBL_LOADED_APPLICATION_ENTRY AppEntry, _In_ ULONG OptionId, _In_ ULONGLONG Value)
Definition: bcdopt.c:657
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
PVOID Data
Definition: bl.h:1346
NTSTATUS Status
Definition: bl.h:818
base of all file and directory entries
Definition: entries.h:82
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
LONGLONG QuadPart
Definition: typedefs.h:112
NTSTATUS BlXmiWrite(_In_ PWCHAR XmlTag)
Definition: bootmgr.c:1065
BOOLEAN BmpDisplayBootMenu
Definition: bootmgr.c:38
struct _BL_BSD_LOG_OBJECT BL_BSD_LOG_OBJECT
NTSTATUS BmpGetSelectedBootEntry(_In_ HANDLE BcdHandle, _Out_ PBL_LOADED_APPLICATION_ENTRY *SelectedBootEntry, _Out_ PULONG EntryIndex, _Out_ PBOOLEAN ExitBootManager)
Definition: bootmgr.c:1814
#define BCD_APPLICATION_TYPE_NTLDR
Definition: bcd.h:39