2015-09-04 14:16:56 +00:00
|
|
|
/*
|
|
|
|
* COPYRIGHT: See COPYING.ARM in the top level directory
|
|
|
|
* PROJECT: ReactOS UEFI Boot Manager
|
2016-01-19 18:21:54 +00:00
|
|
|
* FILE: boot/environ/app/bootmgr/bootmgr.cla
|
2015-09-04 14:16:56 +00:00
|
|
|
* PURPOSE: Boot Manager Entrypoint
|
|
|
|
* PROGRAMMER: Alex Ionescu (alex.ionescu@reactos.org)
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* INCLUDES ******************************************************************/
|
|
|
|
|
|
|
|
#include "bootmgr.h"
|
|
|
|
|
2015-09-06 03:02:56 +00:00
|
|
|
/* DATA VARIABLES ************************************************************/
|
|
|
|
|
2015-09-07 23:48:21 +00:00
|
|
|
DEFINE_GUID(GUID_WINDOWS_BOOTMGR,
|
|
|
|
0x9DEA862C,
|
|
|
|
0x5CDD,
|
|
|
|
0x4E70,
|
|
|
|
0xAC, 0xC1, 0xF3, 0x2B, 0x34, 0x4D, 0x47, 0x95);
|
|
|
|
|
2015-09-06 03:02:56 +00:00
|
|
|
ULONGLONG ApplicationStartTime;
|
|
|
|
ULONGLONG PostTime;
|
2015-09-07 23:48:21 +00:00
|
|
|
GUID BmApplicationIdentifier;
|
2015-09-09 05:48:50 +00:00
|
|
|
PWCHAR BootDirectory;
|
2015-09-06 03:02:56 +00:00
|
|
|
|
[BOOTLIB]:
- WIP work to begin reading, parsing, mounting and loading the BCD hive into a data store. Untested, has missing pieces.
- Implement BlFileSet/GetInformation, BlFileReadEx, BlFileReadAtOffsetEx and helper structures/functions. Document multiple previously unknown/magic flags.
- Implement BlMmAllocatePhysicalPages. Stub BlMmFreePhysicalPages.
- Implement MmUnmapVirtualAddress, BlMmUnmapVirtualAddressEx when operating in real mode.
- Implement ImgpGetFileSize, ImgpReadFileAtOffset, ImgpOpenFile, ImgpCloseFile, BlImgAllocateImageBuffer, BlImgLoadImageWithProgress2.
- Implement BdDebuggerInitialized, BlBdDebuggerEnabled, BlStatusPrint, BlStatuserror. Stub BlBdPullRemoteFile.
- Implement BlGetBootOptionDevice.
- Implement BiReferenceHive, BiDereferenceHive, BiCloseKey, BiOpenKey. Stub BiFlushKey, BiLoadHive.
- Implement BiAddStoreFromFile, BcdOpenStoreFromFile.
- Stub BlUtlUpdateProcess and BlResourceFindMessage.
- Other misc. cleanups.
[BOOTMGR]:
- Implement BmpFatalErrorMessageFilter, BmErrorPurge, BmpErrorLog, BmFatalErrorEx.
- Implement BmpFwGetFullPath.
- Implement BmOpenDataStore.
- Stub BmOpenBootIni
svn path=/trunk/; revision=69447
2015-10-04 21:07:12 +00:00
|
|
|
BL_BOOT_ERROR BmpErrorBuffer;
|
|
|
|
PBL_BOOT_ERROR BmpInternalBootError;
|
|
|
|
BL_PACKED_BOOT_ERROR BmpPackedBootError;
|
|
|
|
|
|
|
|
BOOLEAN BmBootIniUsed;
|
|
|
|
WCHAR BmpFileNameBuffer[128];
|
|
|
|
PWCHAR ParentFileName = L"";
|
|
|
|
|
2016-01-05 06:09:22 +00:00
|
|
|
BOOLEAN BmDisplayStateCached;
|
2016-01-18 18:16:49 +00:00
|
|
|
PBL_LOADED_APPLICATION_ENTRY* BmpFailedBootEntries;
|
|
|
|
PBL_LOADED_APPLICATION_ENTRY BmpSelectedBootEntry;
|
|
|
|
BOOLEAN BmBootEntryOverridePresent;
|
|
|
|
BOOLEAN BmpDisplayBootMenu;
|
2016-01-05 06:09:22 +00:00
|
|
|
|
2015-09-04 14:16:56 +00:00
|
|
|
/* FUNCTIONS *****************************************************************/
|
|
|
|
|
2016-01-05 06:09:22 +00:00
|
|
|
NTSTATUS
|
|
|
|
BmGetOptionList (
|
|
|
|
_In_ HANDLE BcdHandle,
|
|
|
|
_In_ PGUID ObjectId,
|
|
|
|
_In_ PBL_BCD_OPTION *OptionList
|
|
|
|
)
|
|
|
|
{
|
|
|
|
NTSTATUS Status;
|
|
|
|
HANDLE ObjectHandle;
|
|
|
|
ULONG ElementSize, ElementCount, i, OptionsSize;
|
|
|
|
BcdElementType Type;
|
|
|
|
PBCD_ELEMENT_HEADER Header;
|
|
|
|
PBCD_ELEMENT BcdElements;
|
|
|
|
PBL_BCD_OPTION Options, Option, PreviousOption, DeviceOptions;
|
|
|
|
PBCD_DEVICE_OPTION DeviceOption;
|
|
|
|
GUID DeviceId;
|
|
|
|
PVOID DeviceData;
|
|
|
|
|
|
|
|
/* Open the BCD object requested */
|
|
|
|
ObjectHandle = NULL;
|
|
|
|
BcdElements = NULL;
|
|
|
|
Status = BcdOpenObject(BcdHandle, ObjectId, &ObjectHandle);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
goto Quickie;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Do the initial enumeration to get the size needed */
|
|
|
|
ElementSize = 0;
|
|
|
|
Status = BcdEnumerateAndUnpackElements(BcdHandle,
|
|
|
|
ObjectHandle,
|
|
|
|
NULL,
|
|
|
|
&ElementSize,
|
|
|
|
&ElementCount);
|
|
|
|
if (Status != STATUS_BUFFER_TOO_SMALL)
|
|
|
|
{
|
|
|
|
/* If we got success, that doesn't make any sense */
|
|
|
|
if (NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
Status = STATUS_INVALID_PARAMETER;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Bail out */
|
|
|
|
goto Quickie;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Allocate a large-enough buffer */
|
|
|
|
BcdElements = BlMmAllocateHeap(ElementSize);
|
|
|
|
if (!BcdElements)
|
|
|
|
{
|
|
|
|
Status = STATUS_NO_MEMORY;
|
|
|
|
goto Quickie;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Now do the real enumeration to fill out the elements buffer */
|
|
|
|
Status = BcdEnumerateAndUnpackElements(BcdHandle,
|
|
|
|
ObjectHandle,
|
|
|
|
BcdElements,
|
|
|
|
&ElementSize,
|
|
|
|
&ElementCount);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
goto Quickie;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Go through each BCD option to add the sizes up */
|
|
|
|
OptionsSize = 0;
|
|
|
|
for (i = 0; i < ElementCount; i++)
|
|
|
|
{
|
|
|
|
OptionsSize += BcdElements[i].Header->Size + sizeof(BL_BCD_OPTION);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Allocate the required BCD option list */
|
|
|
|
Options = BlMmAllocateHeap(OptionsSize);
|
|
|
|
if (!Options)
|
|
|
|
{
|
|
|
|
Status = STATUS_NO_MEMORY;
|
|
|
|
goto Quickie;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Zero it out */
|
|
|
|
RtlZeroMemory(Options, OptionsSize);
|
|
|
|
|
|
|
|
/* Start going through each option */
|
|
|
|
PreviousOption = NULL;
|
|
|
|
Option = Options;
|
|
|
|
for (i = 0; i < ElementCount; i++)
|
|
|
|
{
|
|
|
|
/* Read the header and type */
|
|
|
|
Header = BcdElements[i].Header;
|
|
|
|
Type.PackedValue = Header->Type;
|
|
|
|
|
|
|
|
/* Check if this option isn't already present */
|
|
|
|
if (!MiscGetBootOption(Options, Type.PackedValue))
|
|
|
|
{
|
|
|
|
/* It's a new option. Did we have an existing one? */
|
|
|
|
if (PreviousOption)
|
|
|
|
{
|
|
|
|
/* Link it to this new one */
|
|
|
|
PreviousOption->NextEntryOffset = (ULONG_PTR)Option -
|
|
|
|
(ULONG_PTR)Options;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Capture the type, size, data, and offset */
|
|
|
|
Option->Type = Type.PackedValue;
|
|
|
|
Option->DataSize = Header->Size;
|
|
|
|
RtlCopyMemory(Option + 1, BcdElements[i].Body, Header->Size);
|
|
|
|
Option->DataOffset = sizeof(BL_BCD_OPTION);
|
|
|
|
|
|
|
|
/* Check if this was a device */
|
|
|
|
if (Type.Format == BCD_TYPE_DEVICE)
|
|
|
|
{
|
|
|
|
/* Grab its GUID */
|
|
|
|
DeviceOption = (PBCD_DEVICE_OPTION)(Option + 1);
|
|
|
|
DeviceId = DeviceOption->AssociatedEntry;
|
|
|
|
|
|
|
|
/* Look up the options for that GUID */
|
|
|
|
Status = BmGetOptionList(BcdHandle, &DeviceId, &DeviceOptions);
|
|
|
|
if (NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
/* Device data is after the device option */
|
|
|
|
DeviceData = (PVOID)((ULONG_PTR)DeviceOption + Header->Size);
|
|
|
|
|
|
|
|
/* Copy it */
|
|
|
|
RtlCopyMemory(DeviceData,
|
|
|
|
DeviceOptions,
|
|
|
|
BlGetBootOptionListSize(DeviceOptions));
|
|
|
|
|
|
|
|
/* Don't need this anymore */
|
|
|
|
BlMmFreeHeap(DeviceOptions);
|
|
|
|
|
|
|
|
/* Write the offset of the device options */
|
|
|
|
Option->ListOffset = (ULONG_PTR)DeviceData -
|
|
|
|
(ULONG_PTR)Option;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Save the previous option and go to the next one */
|
|
|
|
PreviousOption = Option;
|
|
|
|
Option = (PBL_BCD_OPTION)((ULONG_PTR)Option +
|
|
|
|
BlGetBootOptionSize(Option));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Return the pointer back, we've made it! */
|
|
|
|
*OptionList = Options;
|
|
|
|
Status = STATUS_SUCCESS;
|
|
|
|
|
|
|
|
Quickie:
|
|
|
|
/* Did we allocate a local buffer? Free it if so */
|
|
|
|
if (BcdElements)
|
|
|
|
{
|
|
|
|
BlMmFreeHeap(BcdElements);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Was the key open? Close it if so */
|
|
|
|
if (ObjectHandle)
|
|
|
|
{
|
|
|
|
BiCloseKey(ObjectHandle);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Return the option list parsing status */
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
NTSTATUS
|
|
|
|
BmpUpdateApplicationOptions (
|
|
|
|
_In_ HANDLE BcdHandle
|
|
|
|
)
|
|
|
|
{
|
|
|
|
NTSTATUS Status;
|
|
|
|
PBL_BCD_OPTION Options;
|
|
|
|
|
|
|
|
/* Get the boot option list */
|
|
|
|
Status = BmGetOptionList(BcdHandle, &BmApplicationIdentifier, &Options);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Append the options, free the local buffer, and return success */
|
|
|
|
BlAppendBootOptions(&BlpApplicationEntry, Options);
|
|
|
|
BlMmFreeHeap(Options);
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2015-09-09 18:09:04 +00:00
|
|
|
NTSTATUS
|
|
|
|
BmpFwGetApplicationDirectoryPath (
|
|
|
|
_In_ PUNICODE_STRING ApplicationDirectoryPath
|
|
|
|
)
|
|
|
|
{
|
|
|
|
NTSTATUS Status;
|
2018-03-18 15:10:41 +00:00
|
|
|
SIZE_T i, AppPathLength;
|
2015-09-09 18:09:04 +00:00
|
|
|
PWCHAR ApplicationPath, PathCopy;
|
|
|
|
|
|
|
|
/* Clear the incoming string */
|
|
|
|
ApplicationDirectoryPath->Length = 0;
|
|
|
|
ApplicationDirectoryPath->MaximumLength = 0;
|
|
|
|
ApplicationDirectoryPath->Buffer = 0;
|
|
|
|
|
|
|
|
/* Get the boot application path */
|
|
|
|
ApplicationPath = NULL;
|
|
|
|
Status = BlGetBootOptionString(BlpApplicationEntry.BcdData,
|
|
|
|
BcdLibraryString_ApplicationPath,
|
|
|
|
&ApplicationPath);
|
|
|
|
if (NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
/* Calculate the length of the application path */
|
|
|
|
for (i = wcslen(ApplicationPath) - 1; i > 0; i--)
|
|
|
|
{
|
|
|
|
/* Keep going until the path separator */
|
|
|
|
if (ApplicationPath[i] == OBJ_NAME_PATH_SEPARATOR)
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Check if we have space for one more character */
|
2018-03-18 15:10:41 +00:00
|
|
|
Status = RtlSIZETAdd(i, 1, &AppPathLength);
|
2015-09-09 18:09:04 +00:00
|
|
|
if (NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
/* Check if it's safe to multiply by two */
|
2018-03-18 15:10:41 +00:00
|
|
|
Status = RtlSIZETMult(AppPathLength, sizeof(WCHAR), &AppPathLength);
|
2015-09-09 18:09:04 +00:00
|
|
|
if (NT_SUCCESS(Status))
|
|
|
|
{
|
2016-01-05 06:09:22 +00:00
|
|
|
/* Allocate a copy for the string */
|
2015-09-09 18:09:04 +00:00
|
|
|
PathCopy = BlMmAllocateHeap(AppPathLength);
|
|
|
|
if (PathCopy)
|
|
|
|
{
|
|
|
|
/* NULL-terminate it */
|
|
|
|
RtlCopyMemory(PathCopy,
|
|
|
|
ApplicationPath,
|
|
|
|
AppPathLength - sizeof(UNICODE_NULL));
|
|
|
|
PathCopy[AppPathLength] = UNICODE_NULL;
|
|
|
|
|
2016-11-12 20:53:49 +00:00
|
|
|
/* Finally, initialize the outgoing string */
|
2015-09-09 18:09:04 +00:00
|
|
|
RtlInitUnicodeString(ApplicationDirectoryPath, PathCopy);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* No memory, fail */
|
|
|
|
Status = STATUS_NO_MEMORY;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Check if we had an application path */
|
|
|
|
if (ApplicationPath)
|
|
|
|
{
|
|
|
|
/* No longer need this, free it */
|
|
|
|
BlMmFreeHeap(ApplicationPath);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* All done! */
|
|
|
|
return Status;
|
|
|
|
}
|
[BOOTLIB]:
- WIP work to begin reading, parsing, mounting and loading the BCD hive into a data store. Untested, has missing pieces.
- Implement BlFileSet/GetInformation, BlFileReadEx, BlFileReadAtOffsetEx and helper structures/functions. Document multiple previously unknown/magic flags.
- Implement BlMmAllocatePhysicalPages. Stub BlMmFreePhysicalPages.
- Implement MmUnmapVirtualAddress, BlMmUnmapVirtualAddressEx when operating in real mode.
- Implement ImgpGetFileSize, ImgpReadFileAtOffset, ImgpOpenFile, ImgpCloseFile, BlImgAllocateImageBuffer, BlImgLoadImageWithProgress2.
- Implement BdDebuggerInitialized, BlBdDebuggerEnabled, BlStatusPrint, BlStatuserror. Stub BlBdPullRemoteFile.
- Implement BlGetBootOptionDevice.
- Implement BiReferenceHive, BiDereferenceHive, BiCloseKey, BiOpenKey. Stub BiFlushKey, BiLoadHive.
- Implement BiAddStoreFromFile, BcdOpenStoreFromFile.
- Stub BlUtlUpdateProcess and BlResourceFindMessage.
- Other misc. cleanups.
[BOOTMGR]:
- Implement BmpFatalErrorMessageFilter, BmErrorPurge, BmpErrorLog, BmFatalErrorEx.
- Implement BmpFwGetFullPath.
- Implement BmOpenDataStore.
- Stub BmOpenBootIni
svn path=/trunk/; revision=69447
2015-10-04 21:07:12 +00:00
|
|
|
|
2015-09-09 05:48:50 +00:00
|
|
|
NTSTATUS
|
|
|
|
BmFwInitializeBootDirectoryPath (
|
2015-09-07 23:48:21 +00:00
|
|
|
VOID
|
|
|
|
)
|
|
|
|
{
|
|
|
|
PWCHAR FinalPath;
|
|
|
|
NTSTATUS Status;
|
|
|
|
PWCHAR BcdDirectory;
|
2015-09-09 18:09:04 +00:00
|
|
|
UNICODE_STRING BcdPath;
|
|
|
|
ULONG FinalSize;
|
2015-09-09 05:48:50 +00:00
|
|
|
ULONG FileHandle, DeviceHandle;
|
|
|
|
|
|
|
|
/* Initialize everything for failure */
|
2015-09-09 18:09:04 +00:00
|
|
|
BcdPath.MaximumLength = 0;
|
|
|
|
BcdPath.Buffer = NULL;
|
2015-09-09 05:48:50 +00:00
|
|
|
BcdDirectory = NULL;
|
2015-09-07 23:48:21 +00:00
|
|
|
FinalPath = NULL;
|
|
|
|
FileHandle = -1;
|
|
|
|
DeviceHandle = -1;
|
|
|
|
|
2015-09-09 05:48:50 +00:00
|
|
|
/* Try to open the boot device */
|
2016-01-07 05:14:26 +00:00
|
|
|
Status = BlpDeviceOpen(BlpBootDevice,
|
|
|
|
BL_DEVICE_READ_ACCESS,
|
|
|
|
0,
|
|
|
|
&DeviceHandle);
|
2015-09-07 23:48:21 +00:00
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
2015-09-09 16:50:05 +00:00
|
|
|
EfiPrintf(L"Device open failed: %lx\r\n", Status);
|
2015-09-07 23:48:21 +00:00
|
|
|
goto Quickie;
|
|
|
|
}
|
|
|
|
|
2015-09-09 18:09:04 +00:00
|
|
|
/* Get the directory path */
|
2015-09-07 23:48:21 +00:00
|
|
|
Status = BmpFwGetApplicationDirectoryPath(&BcdPath);
|
|
|
|
BcdDirectory = BcdPath.Buffer;
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
goto Quickie;
|
|
|
|
}
|
|
|
|
|
2015-09-09 18:09:04 +00:00
|
|
|
/* Add the BCD file name to it */
|
2015-09-07 23:48:21 +00:00
|
|
|
FinalSize = BcdPath.MaximumLength + sizeof(L"\\BCD") - sizeof(UNICODE_NULL);
|
|
|
|
if (FinalSize < BcdPath.MaximumLength)
|
|
|
|
{
|
|
|
|
goto Quickie;
|
|
|
|
}
|
|
|
|
|
2015-09-09 18:09:04 +00:00
|
|
|
/* Allocate space for the final path */
|
2015-09-07 23:48:21 +00:00
|
|
|
FinalPath = BlMmAllocateHeap(FinalSize);
|
|
|
|
if (!FinalPath)
|
|
|
|
{
|
|
|
|
goto Quickie;
|
|
|
|
}
|
|
|
|
|
2015-09-09 18:09:04 +00:00
|
|
|
/* Build it */
|
2015-09-07 23:48:21 +00:00
|
|
|
RtlZeroMemory(FinalPath, FinalSize);
|
|
|
|
RtlCopyMemory(FinalPath, BcdDirectory, BcdPath.MaximumLength);
|
|
|
|
wcsncat(FinalPath, L"\\BCD", FinalSize / sizeof(WCHAR));
|
|
|
|
|
2015-09-09 18:09:04 +00:00
|
|
|
/* Try to open the file */
|
2016-01-07 05:14:26 +00:00
|
|
|
Status = BlFileOpen(DeviceHandle,
|
|
|
|
FinalPath,
|
|
|
|
BL_FILE_READ_ACCESS,
|
|
|
|
&FileHandle);
|
2015-09-07 23:48:21 +00:00
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
BootDirectory = BcdDirectory;
|
|
|
|
goto Quickie;
|
|
|
|
}
|
|
|
|
|
[BOOTLIB]:
- WIP work to begin reading, parsing, mounting and loading the BCD hive into a data store. Untested, has missing pieces.
- Implement BlFileSet/GetInformation, BlFileReadEx, BlFileReadAtOffsetEx and helper structures/functions. Document multiple previously unknown/magic flags.
- Implement BlMmAllocatePhysicalPages. Stub BlMmFreePhysicalPages.
- Implement MmUnmapVirtualAddress, BlMmUnmapVirtualAddressEx when operating in real mode.
- Implement ImgpGetFileSize, ImgpReadFileAtOffset, ImgpOpenFile, ImgpCloseFile, BlImgAllocateImageBuffer, BlImgLoadImageWithProgress2.
- Implement BdDebuggerInitialized, BlBdDebuggerEnabled, BlStatusPrint, BlStatuserror. Stub BlBdPullRemoteFile.
- Implement BlGetBootOptionDevice.
- Implement BiReferenceHive, BiDereferenceHive, BiCloseKey, BiOpenKey. Stub BiFlushKey, BiLoadHive.
- Implement BiAddStoreFromFile, BcdOpenStoreFromFile.
- Stub BlUtlUpdateProcess and BlResourceFindMessage.
- Other misc. cleanups.
[BOOTMGR]:
- Implement BmpFatalErrorMessageFilter, BmErrorPurge, BmpErrorLog, BmFatalErrorEx.
- Implement BmpFwGetFullPath.
- Implement BmOpenDataStore.
- Stub BmOpenBootIni
svn path=/trunk/; revision=69447
2015-10-04 21:07:12 +00:00
|
|
|
/* Save the boot directory */
|
2015-10-05 04:51:32 +00:00
|
|
|
BootDirectory = L"\\EFI\\Boot"; /* Should be EFI\\ReactOS\\Boot */
|
2015-09-07 23:48:21 +00:00
|
|
|
|
|
|
|
Quickie:
|
2015-09-09 05:48:50 +00:00
|
|
|
/* Free all the allocations we made */
|
2015-09-07 23:48:21 +00:00
|
|
|
if (BcdDirectory)
|
|
|
|
{
|
|
|
|
Status = BlMmFreeHeap(BcdDirectory);
|
|
|
|
}
|
|
|
|
if (FinalPath)
|
|
|
|
{
|
|
|
|
Status = BlMmFreeHeap(FinalPath);
|
|
|
|
}
|
2015-09-09 05:48:50 +00:00
|
|
|
|
|
|
|
/* Close the BCD file */
|
2015-09-07 23:48:21 +00:00
|
|
|
if (FileHandle != -1)
|
|
|
|
{
|
2015-09-10 04:01:41 +00:00
|
|
|
Status = BlFileClose(FileHandle);
|
2015-09-07 23:48:21 +00:00
|
|
|
}
|
2015-09-09 05:48:50 +00:00
|
|
|
|
|
|
|
/* Close the boot device */
|
2015-09-07 23:48:21 +00:00
|
|
|
if (DeviceHandle != -1)
|
|
|
|
{
|
|
|
|
Status = BlDeviceClose(DeviceHandle);
|
|
|
|
}
|
2015-09-09 05:48:50 +00:00
|
|
|
|
|
|
|
/* Return back to the caller */
|
2015-09-07 23:48:21 +00:00
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
[BOOTLIB]:
- WIP work to begin reading, parsing, mounting and loading the BCD hive into a data store. Untested, has missing pieces.
- Implement BlFileSet/GetInformation, BlFileReadEx, BlFileReadAtOffsetEx and helper structures/functions. Document multiple previously unknown/magic flags.
- Implement BlMmAllocatePhysicalPages. Stub BlMmFreePhysicalPages.
- Implement MmUnmapVirtualAddress, BlMmUnmapVirtualAddressEx when operating in real mode.
- Implement ImgpGetFileSize, ImgpReadFileAtOffset, ImgpOpenFile, ImgpCloseFile, BlImgAllocateImageBuffer, BlImgLoadImageWithProgress2.
- Implement BdDebuggerInitialized, BlBdDebuggerEnabled, BlStatusPrint, BlStatuserror. Stub BlBdPullRemoteFile.
- Implement BlGetBootOptionDevice.
- Implement BiReferenceHive, BiDereferenceHive, BiCloseKey, BiOpenKey. Stub BiFlushKey, BiLoadHive.
- Implement BiAddStoreFromFile, BcdOpenStoreFromFile.
- Stub BlUtlUpdateProcess and BlResourceFindMessage.
- Other misc. cleanups.
[BOOTMGR]:
- Implement BmpFatalErrorMessageFilter, BmErrorPurge, BmpErrorLog, BmFatalErrorEx.
- Implement BmpFwGetFullPath.
- Implement BmOpenDataStore.
- Stub BmOpenBootIni
svn path=/trunk/; revision=69447
2015-10-04 21:07:12 +00:00
|
|
|
NTSTATUS
|
|
|
|
BmOpenBootIni (
|
|
|
|
VOID
|
|
|
|
)
|
|
|
|
{
|
|
|
|
/* Don't yet handled boot.ini */
|
|
|
|
return STATUS_NOT_FOUND;
|
|
|
|
}
|
|
|
|
|
|
|
|
ULONG
|
|
|
|
BmpFatalErrorMessageFilter (
|
|
|
|
_In_ NTSTATUS ErrorStatus,
|
|
|
|
_Out_ PULONG ErrorResourceId
|
|
|
|
)
|
|
|
|
{
|
|
|
|
ULONG Result;
|
|
|
|
|
|
|
|
/* Assume no message for now, check for known status message */
|
|
|
|
Result = 0;
|
|
|
|
switch (ErrorStatus)
|
|
|
|
{
|
|
|
|
/* Convert each status to a resource ID */
|
|
|
|
case STATUS_UNEXPECTED_IO_ERROR:
|
|
|
|
*ErrorResourceId = 9017;
|
|
|
|
Result = 1;
|
|
|
|
break;
|
|
|
|
case STATUS_IMAGE_CHECKSUM_MISMATCH:
|
|
|
|
*ErrorResourceId = 9018;
|
|
|
|
break;
|
|
|
|
case STATUS_INVALID_IMAGE_WIN_64:
|
|
|
|
*ErrorResourceId = 9016;
|
|
|
|
break;
|
|
|
|
case 0xC0000428:
|
|
|
|
*ErrorResourceId = 9019;
|
|
|
|
Result = 2;
|
|
|
|
break;
|
|
|
|
case 0xC0210000:
|
|
|
|
*ErrorResourceId = 9013;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Return the type of message */
|
|
|
|
return Result;
|
|
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
|
|
BmErrorPurge (
|
|
|
|
VOID
|
|
|
|
)
|
|
|
|
{
|
|
|
|
/* Check if a boot error is present */
|
|
|
|
if (BmpPackedBootError.BootError)
|
|
|
|
{
|
|
|
|
/* Purge it */
|
|
|
|
BlMmFreeHeap(BmpPackedBootError.BootError);
|
|
|
|
BmpPackedBootError.BootError = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Zero out the packed buffer */
|
|
|
|
BmpPackedBootError.Size = 0;
|
|
|
|
BmpInternalBootError = NULL;
|
|
|
|
RtlZeroMemory(&BmpErrorBuffer, sizeof(BmpErrorBuffer));
|
|
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
|
|
BmpErrorLog (
|
|
|
|
_In_ ULONG ErrorCode,
|
|
|
|
_In_ NTSTATUS ErrorStatus,
|
|
|
|
_In_ ULONG ErrorMsgId,
|
|
|
|
_In_ PWCHAR FileName,
|
|
|
|
_In_ ULONG HelpMsgId
|
|
|
|
)
|
|
|
|
{
|
|
|
|
PWCHAR ErrorMsgString;
|
|
|
|
|
|
|
|
/* Check if we already had an error */
|
|
|
|
if (BmpInternalBootError)
|
|
|
|
{
|
|
|
|
/* Purge it */
|
|
|
|
BmErrorPurge();
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Find the string for this error ID */
|
|
|
|
ErrorMsgString = BlResourceFindMessage(ErrorMsgId);
|
|
|
|
if (ErrorMsgString)
|
|
|
|
{
|
|
|
|
/* Fill out the error buffer */
|
|
|
|
BmpErrorBuffer.Unknown1 = 0;
|
|
|
|
BmpErrorBuffer.Unknown2 = 0;
|
|
|
|
BmpErrorBuffer.ErrorString = ErrorMsgString;
|
|
|
|
BmpErrorBuffer.FileName = FileName;
|
|
|
|
BmpErrorBuffer.ErrorCode = ErrorCode;
|
|
|
|
BmpErrorBuffer.ErrorStatus = ErrorStatus;
|
|
|
|
BmpErrorBuffer.HelpMsgId = HelpMsgId;
|
|
|
|
BmpInternalBootError = &BmpErrorBuffer;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
|
|
BmFatalErrorEx (
|
|
|
|
_In_ ULONG ErrorCode,
|
|
|
|
_In_ ULONG_PTR Parameter1,
|
|
|
|
_In_ ULONG_PTR Parameter2,
|
|
|
|
_In_ ULONG_PTR Parameter3,
|
|
|
|
_In_ ULONG_PTR Parameter4
|
|
|
|
)
|
|
|
|
{
|
|
|
|
PWCHAR FileName, Buffer;
|
|
|
|
NTSTATUS ErrorStatus;
|
|
|
|
WCHAR FormatString[256];
|
|
|
|
ULONG ErrorResourceId, ErrorHelpId;
|
|
|
|
BOOLEAN Restart, NoError;
|
|
|
|
|
|
|
|
/* Assume no buffer for now */
|
|
|
|
Buffer = NULL;
|
|
|
|
|
|
|
|
/* Check what error code is being raised */
|
|
|
|
switch (ErrorCode)
|
|
|
|
{
|
|
|
|
/* Error reading the BCD */
|
|
|
|
case BL_FATAL_ERROR_BCD_READ:
|
|
|
|
|
|
|
|
/* Check if we have a name for the BCD file */
|
|
|
|
if (Parameter1)
|
|
|
|
{
|
|
|
|
/* Check if the name fits into our buffer */
|
|
|
|
FileName = (PWCHAR)Parameter1;
|
|
|
|
if (wcslen(FileName) < sizeof(BmpFileNameBuffer))
|
|
|
|
{
|
|
|
|
/* Copy it in there */
|
|
|
|
Buffer = BmpFileNameBuffer;
|
|
|
|
wcsncpy(BmpFileNameBuffer,
|
|
|
|
FileName,
|
|
|
|
RTL_NUMBER_OF(BmpFileNameBuffer));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* If we don't have a buffer, use an empty one */
|
|
|
|
if (!Buffer)
|
|
|
|
{
|
|
|
|
Buffer = ParentFileName;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* The NTSTATUS code is in parameter 2*/
|
|
|
|
ErrorStatus = (NTSTATUS)Parameter2;
|
|
|
|
|
|
|
|
/* Build the error string */
|
|
|
|
swprintf(FormatString,
|
2015-10-05 07:25:27 +00:00
|
|
|
L"\nAn error occurred (%08x) while attempting "
|
[BOOTLIB]:
- WIP work to begin reading, parsing, mounting and loading the BCD hive into a data store. Untested, has missing pieces.
- Implement BlFileSet/GetInformation, BlFileReadEx, BlFileReadAtOffsetEx and helper structures/functions. Document multiple previously unknown/magic flags.
- Implement BlMmAllocatePhysicalPages. Stub BlMmFreePhysicalPages.
- Implement MmUnmapVirtualAddress, BlMmUnmapVirtualAddressEx when operating in real mode.
- Implement ImgpGetFileSize, ImgpReadFileAtOffset, ImgpOpenFile, ImgpCloseFile, BlImgAllocateImageBuffer, BlImgLoadImageWithProgress2.
- Implement BdDebuggerInitialized, BlBdDebuggerEnabled, BlStatusPrint, BlStatuserror. Stub BlBdPullRemoteFile.
- Implement BlGetBootOptionDevice.
- Implement BiReferenceHive, BiDereferenceHive, BiCloseKey, BiOpenKey. Stub BiFlushKey, BiLoadHive.
- Implement BiAddStoreFromFile, BcdOpenStoreFromFile.
- Stub BlUtlUpdateProcess and BlResourceFindMessage.
- Other misc. cleanups.
[BOOTMGR]:
- Implement BmpFatalErrorMessageFilter, BmErrorPurge, BmpErrorLog, BmFatalErrorEx.
- Implement BmpFwGetFullPath.
- Implement BmOpenDataStore.
- Stub BmOpenBootIni
svn path=/trunk/; revision=69447
2015-10-04 21:07:12 +00:00
|
|
|
L"to read the boot configuration data file %s\n",
|
|
|
|
ErrorStatus,
|
|
|
|
Buffer);
|
|
|
|
|
|
|
|
/* Select the resource ID message */
|
|
|
|
ErrorResourceId = 9002;
|
|
|
|
break;
|
|
|
|
|
2016-01-17 21:48:00 +00:00
|
|
|
case BL_FATAL_ERROR_BCD_ENTRIES:
|
|
|
|
|
|
|
|
/* File name is in parameter 1 */
|
|
|
|
FileName = (PWCHAR)Parameter1;
|
|
|
|
|
|
|
|
/* The NTSTATUS code is in parameter 2*/
|
|
|
|
ErrorStatus = (NTSTATUS)Parameter2;
|
|
|
|
|
|
|
|
/* Build the error string */
|
|
|
|
swprintf(FormatString,
|
|
|
|
L"\nNo valid entries found in the boot configuration data file %s\n",
|
|
|
|
FileName);
|
|
|
|
|
|
|
|
/* Select the resource ID message */
|
|
|
|
ErrorResourceId = 9007;
|
|
|
|
break;
|
|
|
|
|
2016-01-05 06:09:22 +00:00
|
|
|
case BL_FATAL_ERROR_BCD_PARSE:
|
|
|
|
|
|
|
|
/* File name isin parameter 1 */
|
|
|
|
FileName = (PWCHAR)Parameter1;
|
|
|
|
|
|
|
|
/* The NTSTATUS code is in parameter 2*/
|
|
|
|
ErrorStatus = (NTSTATUS)Parameter2;
|
|
|
|
|
|
|
|
/* Build the error string */
|
|
|
|
swprintf(FormatString,
|
|
|
|
L"\nThe boot configuration file %s is invalid (%08x).\n",
|
|
|
|
FileName,
|
|
|
|
ErrorStatus);
|
|
|
|
|
|
|
|
/* Select the resource ID message */
|
|
|
|
ErrorResourceId = 9015;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case BL_FATAL_ERROR_GENERIC:
|
|
|
|
|
|
|
|
/* The NTSTATUS code is in parameter 1*/
|
|
|
|
ErrorStatus = (NTSTATUS)Parameter1;
|
|
|
|
|
|
|
|
/* Build the error string */
|
|
|
|
swprintf(FormatString,
|
|
|
|
L"\nThe boot manager experienced an error (%08x).\n",
|
|
|
|
ErrorStatus);
|
|
|
|
|
|
|
|
/* Select the resource ID message */
|
|
|
|
ErrorResourceId = 9005;
|
|
|
|
break;
|
|
|
|
|
[BOOTLIB]:
- WIP work to begin reading, parsing, mounting and loading the BCD hive into a data store. Untested, has missing pieces.
- Implement BlFileSet/GetInformation, BlFileReadEx, BlFileReadAtOffsetEx and helper structures/functions. Document multiple previously unknown/magic flags.
- Implement BlMmAllocatePhysicalPages. Stub BlMmFreePhysicalPages.
- Implement MmUnmapVirtualAddress, BlMmUnmapVirtualAddressEx when operating in real mode.
- Implement ImgpGetFileSize, ImgpReadFileAtOffset, ImgpOpenFile, ImgpCloseFile, BlImgAllocateImageBuffer, BlImgLoadImageWithProgress2.
- Implement BdDebuggerInitialized, BlBdDebuggerEnabled, BlStatusPrint, BlStatuserror. Stub BlBdPullRemoteFile.
- Implement BlGetBootOptionDevice.
- Implement BiReferenceHive, BiDereferenceHive, BiCloseKey, BiOpenKey. Stub BiFlushKey, BiLoadHive.
- Implement BiAddStoreFromFile, BcdOpenStoreFromFile.
- Stub BlUtlUpdateProcess and BlResourceFindMessage.
- Other misc. cleanups.
[BOOTMGR]:
- Implement BmpFatalErrorMessageFilter, BmErrorPurge, BmpErrorLog, BmFatalErrorEx.
- Implement BmpFwGetFullPath.
- Implement BmOpenDataStore.
- Stub BmOpenBootIni
svn path=/trunk/; revision=69447
2015-10-04 21:07:12 +00:00
|
|
|
default:
|
|
|
|
|
|
|
|
/* The rest is not yet handled */
|
2016-01-08 15:01:11 +00:00
|
|
|
EfiPrintf(L"Unexpected fatal error: %lx\r\n", ErrorCode);
|
[BOOTLIB]:
- WIP work to begin reading, parsing, mounting and loading the BCD hive into a data store. Untested, has missing pieces.
- Implement BlFileSet/GetInformation, BlFileReadEx, BlFileReadAtOffsetEx and helper structures/functions. Document multiple previously unknown/magic flags.
- Implement BlMmAllocatePhysicalPages. Stub BlMmFreePhysicalPages.
- Implement MmUnmapVirtualAddress, BlMmUnmapVirtualAddressEx when operating in real mode.
- Implement ImgpGetFileSize, ImgpReadFileAtOffset, ImgpOpenFile, ImgpCloseFile, BlImgAllocateImageBuffer, BlImgLoadImageWithProgress2.
- Implement BdDebuggerInitialized, BlBdDebuggerEnabled, BlStatusPrint, BlStatuserror. Stub BlBdPullRemoteFile.
- Implement BlGetBootOptionDevice.
- Implement BiReferenceHive, BiDereferenceHive, BiCloseKey, BiOpenKey. Stub BiFlushKey, BiLoadHive.
- Implement BiAddStoreFromFile, BcdOpenStoreFromFile.
- Stub BlUtlUpdateProcess and BlResourceFindMessage.
- Other misc. cleanups.
[BOOTMGR]:
- Implement BmpFatalErrorMessageFilter, BmErrorPurge, BmpErrorLog, BmFatalErrorEx.
- Implement BmpFwGetFullPath.
- Implement BmOpenDataStore.
- Stub BmOpenBootIni
svn path=/trunk/; revision=69447
2015-10-04 21:07:12 +00:00
|
|
|
while (1);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Check if the BCD option for restart is set */
|
|
|
|
BlGetBootOptionBoolean(BlpApplicationEntry.BcdData,
|
|
|
|
BcdLibraryBoolean_RestartOnFailure,
|
|
|
|
&Restart);
|
|
|
|
if (Restart)
|
|
|
|
{
|
|
|
|
/* Yes, so no error should be shown since we'll auto-restart */
|
|
|
|
NoError = TRUE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Check if the option for not showing errors is set in the BCD */
|
|
|
|
BlGetBootOptionBoolean(BlpApplicationEntry.BcdData,
|
|
|
|
BcdBootMgrBoolean_NoErrorDisplay,
|
|
|
|
&NoError);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Do we want an error? */
|
|
|
|
if (!NoError)
|
|
|
|
{
|
|
|
|
/* Yep, print it and then raise an error */
|
|
|
|
BlStatusPrint(FormatString);
|
|
|
|
BlStatusError(1, ErrorCode, Parameter1, Parameter2, Parameter3);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Get the help message ID */
|
|
|
|
ErrorHelpId = BmpFatalErrorMessageFilter(ErrorStatus, &ErrorResourceId);
|
|
|
|
BmpErrorLog(ErrorCode, ErrorStatus, ErrorResourceId, Buffer, ErrorHelpId);
|
|
|
|
}
|
|
|
|
|
|
|
|
NTSTATUS
|
|
|
|
BmpFwGetFullPath (
|
|
|
|
_In_ PWCHAR FileName,
|
|
|
|
_Out_ PWCHAR* FullPath
|
|
|
|
)
|
|
|
|
{
|
|
|
|
NTSTATUS Status;
|
2018-03-18 15:10:41 +00:00
|
|
|
SIZE_T BootDirLength, PathLength;
|
[BOOTLIB]:
- WIP work to begin reading, parsing, mounting and loading the BCD hive into a data store. Untested, has missing pieces.
- Implement BlFileSet/GetInformation, BlFileReadEx, BlFileReadAtOffsetEx and helper structures/functions. Document multiple previously unknown/magic flags.
- Implement BlMmAllocatePhysicalPages. Stub BlMmFreePhysicalPages.
- Implement MmUnmapVirtualAddress, BlMmUnmapVirtualAddressEx when operating in real mode.
- Implement ImgpGetFileSize, ImgpReadFileAtOffset, ImgpOpenFile, ImgpCloseFile, BlImgAllocateImageBuffer, BlImgLoadImageWithProgress2.
- Implement BdDebuggerInitialized, BlBdDebuggerEnabled, BlStatusPrint, BlStatuserror. Stub BlBdPullRemoteFile.
- Implement BlGetBootOptionDevice.
- Implement BiReferenceHive, BiDereferenceHive, BiCloseKey, BiOpenKey. Stub BiFlushKey, BiLoadHive.
- Implement BiAddStoreFromFile, BcdOpenStoreFromFile.
- Stub BlUtlUpdateProcess and BlResourceFindMessage.
- Other misc. cleanups.
[BOOTMGR]:
- Implement BmpFatalErrorMessageFilter, BmErrorPurge, BmpErrorLog, BmFatalErrorEx.
- Implement BmpFwGetFullPath.
- Implement BmOpenDataStore.
- Stub BmOpenBootIni
svn path=/trunk/; revision=69447
2015-10-04 21:07:12 +00:00
|
|
|
|
|
|
|
/* Compute the length of the directory, and add a NUL */
|
|
|
|
BootDirLength = wcslen(BootDirectory);
|
2018-03-18 15:10:41 +00:00
|
|
|
Status = RtlSIZETAdd(BootDirLength, 1, &BootDirLength);
|
[BOOTLIB]:
- WIP work to begin reading, parsing, mounting and loading the BCD hive into a data store. Untested, has missing pieces.
- Implement BlFileSet/GetInformation, BlFileReadEx, BlFileReadAtOffsetEx and helper structures/functions. Document multiple previously unknown/magic flags.
- Implement BlMmAllocatePhysicalPages. Stub BlMmFreePhysicalPages.
- Implement MmUnmapVirtualAddress, BlMmUnmapVirtualAddressEx when operating in real mode.
- Implement ImgpGetFileSize, ImgpReadFileAtOffset, ImgpOpenFile, ImgpCloseFile, BlImgAllocateImageBuffer, BlImgLoadImageWithProgress2.
- Implement BdDebuggerInitialized, BlBdDebuggerEnabled, BlStatusPrint, BlStatuserror. Stub BlBdPullRemoteFile.
- Implement BlGetBootOptionDevice.
- Implement BiReferenceHive, BiDereferenceHive, BiCloseKey, BiOpenKey. Stub BiFlushKey, BiLoadHive.
- Implement BiAddStoreFromFile, BcdOpenStoreFromFile.
- Stub BlUtlUpdateProcess and BlResourceFindMessage.
- Other misc. cleanups.
[BOOTMGR]:
- Implement BmpFatalErrorMessageFilter, BmErrorPurge, BmpErrorLog, BmFatalErrorEx.
- Implement BmpFwGetFullPath.
- Implement BmOpenDataStore.
- Stub BmOpenBootIni
svn path=/trunk/; revision=69447
2015-10-04 21:07:12 +00:00
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
goto Quickie;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Add the length of the file, make sure it fits */
|
|
|
|
PathLength = wcslen(FileName);
|
2018-03-18 15:10:41 +00:00
|
|
|
Status = RtlSIZETAdd(PathLength, BootDirLength, &PathLength);
|
2016-01-05 06:09:22 +00:00
|
|
|
if (!NT_SUCCESS(Status))
|
[BOOTLIB]:
- WIP work to begin reading, parsing, mounting and loading the BCD hive into a data store. Untested, has missing pieces.
- Implement BlFileSet/GetInformation, BlFileReadEx, BlFileReadAtOffsetEx and helper structures/functions. Document multiple previously unknown/magic flags.
- Implement BlMmAllocatePhysicalPages. Stub BlMmFreePhysicalPages.
- Implement MmUnmapVirtualAddress, BlMmUnmapVirtualAddressEx when operating in real mode.
- Implement ImgpGetFileSize, ImgpReadFileAtOffset, ImgpOpenFile, ImgpCloseFile, BlImgAllocateImageBuffer, BlImgLoadImageWithProgress2.
- Implement BdDebuggerInitialized, BlBdDebuggerEnabled, BlStatusPrint, BlStatuserror. Stub BlBdPullRemoteFile.
- Implement BlGetBootOptionDevice.
- Implement BiReferenceHive, BiDereferenceHive, BiCloseKey, BiOpenKey. Stub BiFlushKey, BiLoadHive.
- Implement BiAddStoreFromFile, BcdOpenStoreFromFile.
- Stub BlUtlUpdateProcess and BlResourceFindMessage.
- Other misc. cleanups.
[BOOTMGR]:
- Implement BmpFatalErrorMessageFilter, BmErrorPurge, BmpErrorLog, BmFatalErrorEx.
- Implement BmpFwGetFullPath.
- Implement BmOpenDataStore.
- Stub BmOpenBootIni
svn path=/trunk/; revision=69447
2015-10-04 21:07:12 +00:00
|
|
|
{
|
2016-01-05 06:09:22 +00:00
|
|
|
goto Quickie;
|
[BOOTLIB]:
- WIP work to begin reading, parsing, mounting and loading the BCD hive into a data store. Untested, has missing pieces.
- Implement BlFileSet/GetInformation, BlFileReadEx, BlFileReadAtOffsetEx and helper structures/functions. Document multiple previously unknown/magic flags.
- Implement BlMmAllocatePhysicalPages. Stub BlMmFreePhysicalPages.
- Implement MmUnmapVirtualAddress, BlMmUnmapVirtualAddressEx when operating in real mode.
- Implement ImgpGetFileSize, ImgpReadFileAtOffset, ImgpOpenFile, ImgpCloseFile, BlImgAllocateImageBuffer, BlImgLoadImageWithProgress2.
- Implement BdDebuggerInitialized, BlBdDebuggerEnabled, BlStatusPrint, BlStatuserror. Stub BlBdPullRemoteFile.
- Implement BlGetBootOptionDevice.
- Implement BiReferenceHive, BiDereferenceHive, BiCloseKey, BiOpenKey. Stub BiFlushKey, BiLoadHive.
- Implement BiAddStoreFromFile, BcdOpenStoreFromFile.
- Stub BlUtlUpdateProcess and BlResourceFindMessage.
- Other misc. cleanups.
[BOOTMGR]:
- Implement BmpFatalErrorMessageFilter, BmErrorPurge, BmpErrorLog, BmFatalErrorEx.
- Implement BmpFwGetFullPath.
- Implement BmOpenDataStore.
- Stub BmOpenBootIni
svn path=/trunk/; revision=69447
2015-10-04 21:07:12 +00:00
|
|
|
}
|
|
|
|
|
2016-01-05 06:09:22 +00:00
|
|
|
/* Convert to bytes */
|
2018-03-18 15:10:41 +00:00
|
|
|
Status = RtlSIZETMult(PathLength, sizeof(WCHAR), &PathLength);
|
[BOOTLIB]:
- WIP work to begin reading, parsing, mounting and loading the BCD hive into a data store. Untested, has missing pieces.
- Implement BlFileSet/GetInformation, BlFileReadEx, BlFileReadAtOffsetEx and helper structures/functions. Document multiple previously unknown/magic flags.
- Implement BlMmAllocatePhysicalPages. Stub BlMmFreePhysicalPages.
- Implement MmUnmapVirtualAddress, BlMmUnmapVirtualAddressEx when operating in real mode.
- Implement ImgpGetFileSize, ImgpReadFileAtOffset, ImgpOpenFile, ImgpCloseFile, BlImgAllocateImageBuffer, BlImgLoadImageWithProgress2.
- Implement BdDebuggerInitialized, BlBdDebuggerEnabled, BlStatusPrint, BlStatuserror. Stub BlBdPullRemoteFile.
- Implement BlGetBootOptionDevice.
- Implement BiReferenceHive, BiDereferenceHive, BiCloseKey, BiOpenKey. Stub BiFlushKey, BiLoadHive.
- Implement BiAddStoreFromFile, BcdOpenStoreFromFile.
- Stub BlUtlUpdateProcess and BlResourceFindMessage.
- Other misc. cleanups.
[BOOTMGR]:
- Implement BmpFatalErrorMessageFilter, BmErrorPurge, BmpErrorLog, BmFatalErrorEx.
- Implement BmpFwGetFullPath.
- Implement BmOpenDataStore.
- Stub BmOpenBootIni
svn path=/trunk/; revision=69447
2015-10-04 21:07:12 +00:00
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
goto Quickie;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Allocate the full path */
|
2016-01-05 06:09:22 +00:00
|
|
|
*FullPath = BlMmAllocateHeap(PathLength);
|
[BOOTLIB]:
- WIP work to begin reading, parsing, mounting and loading the BCD hive into a data store. Untested, has missing pieces.
- Implement BlFileSet/GetInformation, BlFileReadEx, BlFileReadAtOffsetEx and helper structures/functions. Document multiple previously unknown/magic flags.
- Implement BlMmAllocatePhysicalPages. Stub BlMmFreePhysicalPages.
- Implement MmUnmapVirtualAddress, BlMmUnmapVirtualAddressEx when operating in real mode.
- Implement ImgpGetFileSize, ImgpReadFileAtOffset, ImgpOpenFile, ImgpCloseFile, BlImgAllocateImageBuffer, BlImgLoadImageWithProgress2.
- Implement BdDebuggerInitialized, BlBdDebuggerEnabled, BlStatusPrint, BlStatuserror. Stub BlBdPullRemoteFile.
- Implement BlGetBootOptionDevice.
- Implement BiReferenceHive, BiDereferenceHive, BiCloseKey, BiOpenKey. Stub BiFlushKey, BiLoadHive.
- Implement BiAddStoreFromFile, BcdOpenStoreFromFile.
- Stub BlUtlUpdateProcess and BlResourceFindMessage.
- Other misc. cleanups.
[BOOTMGR]:
- Implement BmpFatalErrorMessageFilter, BmErrorPurge, BmpErrorLog, BmFatalErrorEx.
- Implement BmpFwGetFullPath.
- Implement BmOpenDataStore.
- Stub BmOpenBootIni
svn path=/trunk/; revision=69447
2015-10-04 21:07:12 +00:00
|
|
|
if (*FullPath)
|
|
|
|
{
|
|
|
|
/* Copy the directory followed by the file name */
|
2016-01-05 06:09:22 +00:00
|
|
|
wcsncpy(*FullPath, BootDirectory, PathLength / sizeof(WCHAR));
|
|
|
|
wcsncat(*FullPath, FileName, PathLength / sizeof(WCHAR));
|
[BOOTLIB]:
- WIP work to begin reading, parsing, mounting and loading the BCD hive into a data store. Untested, has missing pieces.
- Implement BlFileSet/GetInformation, BlFileReadEx, BlFileReadAtOffsetEx and helper structures/functions. Document multiple previously unknown/magic flags.
- Implement BlMmAllocatePhysicalPages. Stub BlMmFreePhysicalPages.
- Implement MmUnmapVirtualAddress, BlMmUnmapVirtualAddressEx when operating in real mode.
- Implement ImgpGetFileSize, ImgpReadFileAtOffset, ImgpOpenFile, ImgpCloseFile, BlImgAllocateImageBuffer, BlImgLoadImageWithProgress2.
- Implement BdDebuggerInitialized, BlBdDebuggerEnabled, BlStatusPrint, BlStatuserror. Stub BlBdPullRemoteFile.
- Implement BlGetBootOptionDevice.
- Implement BiReferenceHive, BiDereferenceHive, BiCloseKey, BiOpenKey. Stub BiFlushKey, BiLoadHive.
- Implement BiAddStoreFromFile, BcdOpenStoreFromFile.
- Stub BlUtlUpdateProcess and BlResourceFindMessage.
- Other misc. cleanups.
[BOOTMGR]:
- Implement BmpFatalErrorMessageFilter, BmErrorPurge, BmpErrorLog, BmFatalErrorEx.
- Implement BmpFwGetFullPath.
- Implement BmOpenDataStore.
- Stub BmOpenBootIni
svn path=/trunk/; revision=69447
2015-10-04 21:07:12 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Bail out since we have no memory */
|
|
|
|
Status = STATUS_NO_MEMORY;
|
|
|
|
}
|
|
|
|
|
|
|
|
Quickie:
|
|
|
|
/* Return to caller */
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
2016-01-05 06:09:22 +00:00
|
|
|
VOID
|
|
|
|
BmCloseDataStore (
|
|
|
|
_In_ HANDLE Handle
|
|
|
|
)
|
|
|
|
{
|
|
|
|
/* Check if boot.ini data needs to be freed */
|
|
|
|
if (BmBootIniUsed)
|
|
|
|
{
|
2016-01-18 05:26:10 +00:00
|
|
|
EfiPrintf(L"Boot.ini not handled\r\n");
|
2016-01-05 06:09:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Dereference the hive and close the key */
|
|
|
|
BiDereferenceHive(Handle);
|
|
|
|
BiCloseKey(Handle);
|
|
|
|
}
|
|
|
|
|
[BOOTLIB]:
- WIP work to begin reading, parsing, mounting and loading the BCD hive into a data store. Untested, has missing pieces.
- Implement BlFileSet/GetInformation, BlFileReadEx, BlFileReadAtOffsetEx and helper structures/functions. Document multiple previously unknown/magic flags.
- Implement BlMmAllocatePhysicalPages. Stub BlMmFreePhysicalPages.
- Implement MmUnmapVirtualAddress, BlMmUnmapVirtualAddressEx when operating in real mode.
- Implement ImgpGetFileSize, ImgpReadFileAtOffset, ImgpOpenFile, ImgpCloseFile, BlImgAllocateImageBuffer, BlImgLoadImageWithProgress2.
- Implement BdDebuggerInitialized, BlBdDebuggerEnabled, BlStatusPrint, BlStatuserror. Stub BlBdPullRemoteFile.
- Implement BlGetBootOptionDevice.
- Implement BiReferenceHive, BiDereferenceHive, BiCloseKey, BiOpenKey. Stub BiFlushKey, BiLoadHive.
- Implement BiAddStoreFromFile, BcdOpenStoreFromFile.
- Stub BlUtlUpdateProcess and BlResourceFindMessage.
- Other misc. cleanups.
[BOOTMGR]:
- Implement BmpFatalErrorMessageFilter, BmErrorPurge, BmpErrorLog, BmFatalErrorEx.
- Implement BmpFwGetFullPath.
- Implement BmOpenDataStore.
- Stub BmOpenBootIni
svn path=/trunk/; revision=69447
2015-10-04 21:07:12 +00:00
|
|
|
NTSTATUS
|
|
|
|
BmOpenDataStore (
|
|
|
|
_Out_ PHANDLE Handle
|
|
|
|
)
|
|
|
|
{
|
|
|
|
NTSTATUS Status;
|
|
|
|
PBL_DEVICE_DESCRIPTOR BcdDevice;
|
|
|
|
PWCHAR BcdPath, FullPath, PathBuffer;
|
|
|
|
BOOLEAN HavePath;
|
2018-03-18 15:10:41 +00:00
|
|
|
SIZE_T PathLength, FullSize;
|
[BOOTLIB]:
- WIP work to begin reading, parsing, mounting and loading the BCD hive into a data store. Untested, has missing pieces.
- Implement BlFileSet/GetInformation, BlFileReadEx, BlFileReadAtOffsetEx and helper structures/functions. Document multiple previously unknown/magic flags.
- Implement BlMmAllocatePhysicalPages. Stub BlMmFreePhysicalPages.
- Implement MmUnmapVirtualAddress, BlMmUnmapVirtualAddressEx when operating in real mode.
- Implement ImgpGetFileSize, ImgpReadFileAtOffset, ImgpOpenFile, ImgpCloseFile, BlImgAllocateImageBuffer, BlImgLoadImageWithProgress2.
- Implement BdDebuggerInitialized, BlBdDebuggerEnabled, BlStatusPrint, BlStatuserror. Stub BlBdPullRemoteFile.
- Implement BlGetBootOptionDevice.
- Implement BiReferenceHive, BiDereferenceHive, BiCloseKey, BiOpenKey. Stub BiFlushKey, BiLoadHive.
- Implement BiAddStoreFromFile, BcdOpenStoreFromFile.
- Stub BlUtlUpdateProcess and BlResourceFindMessage.
- Other misc. cleanups.
[BOOTMGR]:
- Implement BmpFatalErrorMessageFilter, BmErrorPurge, BmpErrorLog, BmFatalErrorEx.
- Implement BmpFwGetFullPath.
- Implement BmOpenDataStore.
- Stub BmOpenBootIni
svn path=/trunk/; revision=69447
2015-10-04 21:07:12 +00:00
|
|
|
PVOID FinalBuffer;
|
|
|
|
UNICODE_STRING BcdString;
|
|
|
|
|
2015-10-05 01:02:56 +00:00
|
|
|
/* Initialize variables */
|
[BOOTLIB]:
- WIP work to begin reading, parsing, mounting and loading the BCD hive into a data store. Untested, has missing pieces.
- Implement BlFileSet/GetInformation, BlFileReadEx, BlFileReadAtOffsetEx and helper structures/functions. Document multiple previously unknown/magic flags.
- Implement BlMmAllocatePhysicalPages. Stub BlMmFreePhysicalPages.
- Implement MmUnmapVirtualAddress, BlMmUnmapVirtualAddressEx when operating in real mode.
- Implement ImgpGetFileSize, ImgpReadFileAtOffset, ImgpOpenFile, ImgpCloseFile, BlImgAllocateImageBuffer, BlImgLoadImageWithProgress2.
- Implement BdDebuggerInitialized, BlBdDebuggerEnabled, BlStatusPrint, BlStatuserror. Stub BlBdPullRemoteFile.
- Implement BlGetBootOptionDevice.
- Implement BiReferenceHive, BiDereferenceHive, BiCloseKey, BiOpenKey. Stub BiFlushKey, BiLoadHive.
- Implement BiAddStoreFromFile, BcdOpenStoreFromFile.
- Stub BlUtlUpdateProcess and BlResourceFindMessage.
- Other misc. cleanups.
[BOOTMGR]:
- Implement BmpFatalErrorMessageFilter, BmErrorPurge, BmpErrorLog, BmFatalErrorEx.
- Implement BmpFwGetFullPath.
- Implement BmOpenDataStore.
- Stub BmOpenBootIni
svn path=/trunk/; revision=69447
2015-10-04 21:07:12 +00:00
|
|
|
PathBuffer = NULL;
|
|
|
|
BcdDevice = NULL;
|
|
|
|
BcdPath = NULL;
|
|
|
|
HavePath = FALSE;
|
|
|
|
|
|
|
|
/* Check if a boot.ini file exists */
|
|
|
|
Status = BmOpenBootIni();
|
|
|
|
if (NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
BmBootIniUsed = TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Check on which device the BCD is */
|
|
|
|
Status = BlGetBootOptionDevice(BlpApplicationEntry.BcdData,
|
|
|
|
BcdBootMgrDevice_BcdDevice,
|
|
|
|
&BcdDevice,
|
|
|
|
NULL);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
/* It's not on a custom device, so it must be where we are */
|
|
|
|
Status = BlGetBootOptionDevice(BlpApplicationEntry.BcdData,
|
|
|
|
BcdLibraryDevice_ApplicationDevice,
|
|
|
|
&BcdDevice,
|
|
|
|
NULL);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
/* This BCD option is required */
|
|
|
|
goto Quickie;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Next, check what file contains the BCD */
|
|
|
|
Status = BlGetBootOptionString(BlpApplicationEntry.BcdData,
|
|
|
|
BcdBootMgrString_BcdFilePath,
|
|
|
|
&BcdPath);
|
|
|
|
if (NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
/* We don't handle custom BCDs yet */
|
2016-01-18 05:26:10 +00:00
|
|
|
EfiPrintf(L"Custom BCD Not handled: %s\r\n", BcdPath);
|
[BOOTLIB]:
- WIP work to begin reading, parsing, mounting and loading the BCD hive into a data store. Untested, has missing pieces.
- Implement BlFileSet/GetInformation, BlFileReadEx, BlFileReadAtOffsetEx and helper structures/functions. Document multiple previously unknown/magic flags.
- Implement BlMmAllocatePhysicalPages. Stub BlMmFreePhysicalPages.
- Implement MmUnmapVirtualAddress, BlMmUnmapVirtualAddressEx when operating in real mode.
- Implement ImgpGetFileSize, ImgpReadFileAtOffset, ImgpOpenFile, ImgpCloseFile, BlImgAllocateImageBuffer, BlImgLoadImageWithProgress2.
- Implement BdDebuggerInitialized, BlBdDebuggerEnabled, BlStatusPrint, BlStatuserror. Stub BlBdPullRemoteFile.
- Implement BlGetBootOptionDevice.
- Implement BiReferenceHive, BiDereferenceHive, BiCloseKey, BiOpenKey. Stub BiFlushKey, BiLoadHive.
- Implement BiAddStoreFromFile, BcdOpenStoreFromFile.
- Stub BlUtlUpdateProcess and BlResourceFindMessage.
- Other misc. cleanups.
[BOOTMGR]:
- Implement BmpFatalErrorMessageFilter, BmErrorPurge, BmpErrorLog, BmFatalErrorEx.
- Implement BmpFwGetFullPath.
- Implement BmOpenDataStore.
- Stub BmOpenBootIni
svn path=/trunk/; revision=69447
2015-10-04 21:07:12 +00:00
|
|
|
Status = STATUS_NOT_IMPLEMENTED;
|
|
|
|
goto Quickie;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Now check if the BCD is on a remote share */
|
|
|
|
if (BcdDevice->DeviceType == UdpDevice)
|
|
|
|
{
|
|
|
|
/* Nope. Nope. Nope */
|
2016-01-18 05:26:10 +00:00
|
|
|
EfiPrintf(L"UDP device Not handled\r\n");
|
[BOOTLIB]:
- WIP work to begin reading, parsing, mounting and loading the BCD hive into a data store. Untested, has missing pieces.
- Implement BlFileSet/GetInformation, BlFileReadEx, BlFileReadAtOffsetEx and helper structures/functions. Document multiple previously unknown/magic flags.
- Implement BlMmAllocatePhysicalPages. Stub BlMmFreePhysicalPages.
- Implement MmUnmapVirtualAddress, BlMmUnmapVirtualAddressEx when operating in real mode.
- Implement ImgpGetFileSize, ImgpReadFileAtOffset, ImgpOpenFile, ImgpCloseFile, BlImgAllocateImageBuffer, BlImgLoadImageWithProgress2.
- Implement BdDebuggerInitialized, BlBdDebuggerEnabled, BlStatusPrint, BlStatuserror. Stub BlBdPullRemoteFile.
- Implement BlGetBootOptionDevice.
- Implement BiReferenceHive, BiDereferenceHive, BiCloseKey, BiOpenKey. Stub BiFlushKey, BiLoadHive.
- Implement BiAddStoreFromFile, BcdOpenStoreFromFile.
- Stub BlUtlUpdateProcess and BlResourceFindMessage.
- Other misc. cleanups.
[BOOTMGR]:
- Implement BmpFatalErrorMessageFilter, BmErrorPurge, BmpErrorLog, BmFatalErrorEx.
- Implement BmpFwGetFullPath.
- Implement BmOpenDataStore.
- Stub BmOpenBootIni
svn path=/trunk/; revision=69447
2015-10-04 21:07:12 +00:00
|
|
|
Status = STATUS_NOT_IMPLEMENTED;
|
|
|
|
goto Quickie;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Otherwise, compute the hardcoded path of the BCD */
|
|
|
|
Status = BmpFwGetFullPath(L"\\BCD", &FullPath);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
/* User the raw path */
|
|
|
|
PathBuffer = BcdPath;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Use the path we got */
|
|
|
|
PathBuffer = FullPath;
|
|
|
|
HavePath = TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Check if we failed to get the BCD path */
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
goto Quickie;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Add a NUL to the path, make sure it'll fit */
|
|
|
|
PathLength = wcslen(PathBuffer);
|
2018-03-18 15:10:41 +00:00
|
|
|
Status = RtlSIZETAdd(PathLength, 1, &PathLength);
|
2016-01-05 06:09:22 +00:00
|
|
|
if (!NT_SUCCESS(Status))
|
[BOOTLIB]:
- WIP work to begin reading, parsing, mounting and loading the BCD hive into a data store. Untested, has missing pieces.
- Implement BlFileSet/GetInformation, BlFileReadEx, BlFileReadAtOffsetEx and helper structures/functions. Document multiple previously unknown/magic flags.
- Implement BlMmAllocatePhysicalPages. Stub BlMmFreePhysicalPages.
- Implement MmUnmapVirtualAddress, BlMmUnmapVirtualAddressEx when operating in real mode.
- Implement ImgpGetFileSize, ImgpReadFileAtOffset, ImgpOpenFile, ImgpCloseFile, BlImgAllocateImageBuffer, BlImgLoadImageWithProgress2.
- Implement BdDebuggerInitialized, BlBdDebuggerEnabled, BlStatusPrint, BlStatuserror. Stub BlBdPullRemoteFile.
- Implement BlGetBootOptionDevice.
- Implement BiReferenceHive, BiDereferenceHive, BiCloseKey, BiOpenKey. Stub BiFlushKey, BiLoadHive.
- Implement BiAddStoreFromFile, BcdOpenStoreFromFile.
- Stub BlUtlUpdateProcess and BlResourceFindMessage.
- Other misc. cleanups.
[BOOTMGR]:
- Implement BmpFatalErrorMessageFilter, BmErrorPurge, BmpErrorLog, BmFatalErrorEx.
- Implement BmpFwGetFullPath.
- Implement BmOpenDataStore.
- Stub BmOpenBootIni
svn path=/trunk/; revision=69447
2015-10-04 21:07:12 +00:00
|
|
|
{
|
2016-01-05 06:09:22 +00:00
|
|
|
goto Quickie;
|
[BOOTLIB]:
- WIP work to begin reading, parsing, mounting and loading the BCD hive into a data store. Untested, has missing pieces.
- Implement BlFileSet/GetInformation, BlFileReadEx, BlFileReadAtOffsetEx and helper structures/functions. Document multiple previously unknown/magic flags.
- Implement BlMmAllocatePhysicalPages. Stub BlMmFreePhysicalPages.
- Implement MmUnmapVirtualAddress, BlMmUnmapVirtualAddressEx when operating in real mode.
- Implement ImgpGetFileSize, ImgpReadFileAtOffset, ImgpOpenFile, ImgpCloseFile, BlImgAllocateImageBuffer, BlImgLoadImageWithProgress2.
- Implement BdDebuggerInitialized, BlBdDebuggerEnabled, BlStatusPrint, BlStatuserror. Stub BlBdPullRemoteFile.
- Implement BlGetBootOptionDevice.
- Implement BiReferenceHive, BiDereferenceHive, BiCloseKey, BiOpenKey. Stub BiFlushKey, BiLoadHive.
- Implement BiAddStoreFromFile, BcdOpenStoreFromFile.
- Stub BlUtlUpdateProcess and BlResourceFindMessage.
- Other misc. cleanups.
[BOOTMGR]:
- Implement BmpFatalErrorMessageFilter, BmErrorPurge, BmpErrorLog, BmFatalErrorEx.
- Implement BmpFwGetFullPath.
- Implement BmOpenDataStore.
- Stub BmOpenBootIni
svn path=/trunk/; revision=69447
2015-10-04 21:07:12 +00:00
|
|
|
}
|
|
|
|
|
2016-01-05 06:09:22 +00:00
|
|
|
/* Convert to bytes */
|
2018-03-18 15:10:41 +00:00
|
|
|
Status = RtlSIZETMult(PathLength, sizeof(WCHAR), &PathLength);
|
[BOOTLIB]:
- WIP work to begin reading, parsing, mounting and loading the BCD hive into a data store. Untested, has missing pieces.
- Implement BlFileSet/GetInformation, BlFileReadEx, BlFileReadAtOffsetEx and helper structures/functions. Document multiple previously unknown/magic flags.
- Implement BlMmAllocatePhysicalPages. Stub BlMmFreePhysicalPages.
- Implement MmUnmapVirtualAddress, BlMmUnmapVirtualAddressEx when operating in real mode.
- Implement ImgpGetFileSize, ImgpReadFileAtOffset, ImgpOpenFile, ImgpCloseFile, BlImgAllocateImageBuffer, BlImgLoadImageWithProgress2.
- Implement BdDebuggerInitialized, BlBdDebuggerEnabled, BlStatusPrint, BlStatuserror. Stub BlBdPullRemoteFile.
- Implement BlGetBootOptionDevice.
- Implement BiReferenceHive, BiDereferenceHive, BiCloseKey, BiOpenKey. Stub BiFlushKey, BiLoadHive.
- Implement BiAddStoreFromFile, BcdOpenStoreFromFile.
- Stub BlUtlUpdateProcess and BlResourceFindMessage.
- Other misc. cleanups.
[BOOTMGR]:
- Implement BmpFatalErrorMessageFilter, BmErrorPurge, BmpErrorLog, BmFatalErrorEx.
- Implement BmpFwGetFullPath.
- Implement BmOpenDataStore.
- Stub BmOpenBootIni
svn path=/trunk/; revision=69447
2015-10-04 21:07:12 +00:00
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
goto Quickie;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Now add the size of the path to the device path, check if it fits */
|
2018-03-18 15:10:41 +00:00
|
|
|
Status = RtlSIZETAdd(PathLength, BcdDevice->Size, &FullSize);
|
[BOOTLIB]:
- WIP work to begin reading, parsing, mounting and loading the BCD hive into a data store. Untested, has missing pieces.
- Implement BlFileSet/GetInformation, BlFileReadEx, BlFileReadAtOffsetEx and helper structures/functions. Document multiple previously unknown/magic flags.
- Implement BlMmAllocatePhysicalPages. Stub BlMmFreePhysicalPages.
- Implement MmUnmapVirtualAddress, BlMmUnmapVirtualAddressEx when operating in real mode.
- Implement ImgpGetFileSize, ImgpReadFileAtOffset, ImgpOpenFile, ImgpCloseFile, BlImgAllocateImageBuffer, BlImgLoadImageWithProgress2.
- Implement BdDebuggerInitialized, BlBdDebuggerEnabled, BlStatusPrint, BlStatuserror. Stub BlBdPullRemoteFile.
- Implement BlGetBootOptionDevice.
- Implement BiReferenceHive, BiDereferenceHive, BiCloseKey, BiOpenKey. Stub BiFlushKey, BiLoadHive.
- Implement BiAddStoreFromFile, BcdOpenStoreFromFile.
- Stub BlUtlUpdateProcess and BlResourceFindMessage.
- Other misc. cleanups.
[BOOTMGR]:
- Implement BmpFatalErrorMessageFilter, BmErrorPurge, BmpErrorLog, BmFatalErrorEx.
- Implement BmpFwGetFullPath.
- Implement BmOpenDataStore.
- Stub BmOpenBootIni
svn path=/trunk/; revision=69447
2015-10-04 21:07:12 +00:00
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
goto Quickie;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Allocate a final structure to hold both entities */
|
|
|
|
FinalBuffer = BlMmAllocateHeap(FullSize);
|
|
|
|
if (!FinalBuffer)
|
|
|
|
{
|
|
|
|
Status = STATUS_NO_MEMORY;
|
|
|
|
goto Quickie;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Copy the device path and file path into the final buffer */
|
|
|
|
RtlCopyMemory(FinalBuffer, BcdDevice, BcdDevice->Size);
|
|
|
|
RtlCopyMemory((PVOID)((ULONG_PTR)FinalBuffer + BcdDevice->Size),
|
|
|
|
PathBuffer,
|
2016-01-05 06:09:22 +00:00
|
|
|
PathLength);
|
[BOOTLIB]:
- WIP work to begin reading, parsing, mounting and loading the BCD hive into a data store. Untested, has missing pieces.
- Implement BlFileSet/GetInformation, BlFileReadEx, BlFileReadAtOffsetEx and helper structures/functions. Document multiple previously unknown/magic flags.
- Implement BlMmAllocatePhysicalPages. Stub BlMmFreePhysicalPages.
- Implement MmUnmapVirtualAddress, BlMmUnmapVirtualAddressEx when operating in real mode.
- Implement ImgpGetFileSize, ImgpReadFileAtOffset, ImgpOpenFile, ImgpCloseFile, BlImgAllocateImageBuffer, BlImgLoadImageWithProgress2.
- Implement BdDebuggerInitialized, BlBdDebuggerEnabled, BlStatusPrint, BlStatuserror. Stub BlBdPullRemoteFile.
- Implement BlGetBootOptionDevice.
- Implement BiReferenceHive, BiDereferenceHive, BiCloseKey, BiOpenKey. Stub BiFlushKey, BiLoadHive.
- Implement BiAddStoreFromFile, BcdOpenStoreFromFile.
- Stub BlUtlUpdateProcess and BlResourceFindMessage.
- Other misc. cleanups.
[BOOTMGR]:
- Implement BmpFatalErrorMessageFilter, BmErrorPurge, BmpErrorLog, BmFatalErrorEx.
- Implement BmpFwGetFullPath.
- Implement BmOpenDataStore.
- Stub BmOpenBootIni
svn path=/trunk/; revision=69447
2015-10-04 21:07:12 +00:00
|
|
|
|
|
|
|
/* Now tell the BCD engine to open the store */
|
|
|
|
BcdString.Length = FullSize;
|
|
|
|
BcdString.MaximumLength = FullSize;
|
|
|
|
BcdString.Buffer = FinalBuffer;
|
|
|
|
Status = BcdOpenStoreFromFile(&BcdString, Handle);
|
|
|
|
|
|
|
|
/* Free our final buffer */
|
|
|
|
BlMmFreeHeap(FinalBuffer);
|
|
|
|
|
|
|
|
Quickie:
|
|
|
|
/* Did we allocate a device? */
|
|
|
|
if (BcdDevice)
|
|
|
|
{
|
|
|
|
/* Free it */
|
|
|
|
BlMmFreeHeap(BcdDevice);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Is this the failure path? */
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
/* Raise a fatal error */
|
2016-01-05 06:09:22 +00:00
|
|
|
BmFatalErrorEx(BL_FATAL_ERROR_BCD_READ,
|
|
|
|
(ULONG_PTR)PathBuffer,
|
|
|
|
Status,
|
|
|
|
0,
|
|
|
|
0);
|
[BOOTLIB]:
- WIP work to begin reading, parsing, mounting and loading the BCD hive into a data store. Untested, has missing pieces.
- Implement BlFileSet/GetInformation, BlFileReadEx, BlFileReadAtOffsetEx and helper structures/functions. Document multiple previously unknown/magic flags.
- Implement BlMmAllocatePhysicalPages. Stub BlMmFreePhysicalPages.
- Implement MmUnmapVirtualAddress, BlMmUnmapVirtualAddressEx when operating in real mode.
- Implement ImgpGetFileSize, ImgpReadFileAtOffset, ImgpOpenFile, ImgpCloseFile, BlImgAllocateImageBuffer, BlImgLoadImageWithProgress2.
- Implement BdDebuggerInitialized, BlBdDebuggerEnabled, BlStatusPrint, BlStatuserror. Stub BlBdPullRemoteFile.
- Implement BlGetBootOptionDevice.
- Implement BiReferenceHive, BiDereferenceHive, BiCloseKey, BiOpenKey. Stub BiFlushKey, BiLoadHive.
- Implement BiAddStoreFromFile, BcdOpenStoreFromFile.
- Stub BlUtlUpdateProcess and BlResourceFindMessage.
- Other misc. cleanups.
[BOOTMGR]:
- Implement BmpFatalErrorMessageFilter, BmErrorPurge, BmpErrorLog, BmFatalErrorEx.
- Implement BmpFwGetFullPath.
- Implement BmOpenDataStore.
- Stub BmOpenBootIni
svn path=/trunk/; revision=69447
2015-10-04 21:07:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Did we get an allocated path? */
|
|
|
|
if ((PathBuffer) && (HavePath))
|
|
|
|
{
|
|
|
|
/* Free it */
|
|
|
|
BlMmFreeHeap(PathBuffer);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Return back to the caller */
|
|
|
|
return Status;
|
|
|
|
}
|
2015-09-07 23:48:21 +00:00
|
|
|
|
2016-01-06 04:43:23 +00:00
|
|
|
typedef struct _BL_BSD_LOG_OBJECT
|
|
|
|
{
|
|
|
|
ULONG DeviceId;
|
|
|
|
ULONG FileId;
|
|
|
|
ULONG Unknown;
|
|
|
|
ULONG Size;
|
|
|
|
ULONG Flags;
|
|
|
|
} BL_BSD_LOG_OBJECT, *PBL_BSD_LOG_OBJECT;
|
|
|
|
|
|
|
|
BL_BSD_LOG_OBJECT BsdpLogObject;
|
|
|
|
BOOLEAN BsdpLogObjectInitialized;
|
|
|
|
|
|
|
|
VOID
|
|
|
|
BlBsdInitializeLog (
|
|
|
|
_In_ PBL_DEVICE_DESCRIPTOR LogDevice,
|
|
|
|
_In_ PWCHAR LogPath,
|
|
|
|
_In_ ULONG Flags
|
|
|
|
)
|
|
|
|
{
|
|
|
|
NTSTATUS Status;
|
|
|
|
|
|
|
|
/* Don't initialize twice */
|
|
|
|
if (BsdpLogObjectInitialized)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Set invalid IDs for now */
|
|
|
|
BsdpLogObject.DeviceId = -1;
|
|
|
|
BsdpLogObject.FileId = -1;
|
|
|
|
|
|
|
|
/* Open the BSD device */
|
|
|
|
Status = BlpDeviceOpen(LogDevice,
|
|
|
|
BL_DEVICE_READ_ACCESS | BL_DEVICE_WRITE_ACCESS,
|
|
|
|
0,
|
|
|
|
&BsdpLogObject.DeviceId);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
/* Welp that didn't work */
|
|
|
|
goto FailurePath;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Now open the BSD itself */
|
|
|
|
Status = BlFileOpen(BsdpLogObject.DeviceId,
|
|
|
|
LogPath,
|
|
|
|
BL_FILE_READ_ACCESS | BL_FILE_WRITE_ACCESS,
|
|
|
|
&BsdpLogObject.FileId);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
/* D'oh */
|
|
|
|
goto FailurePath;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* The BSD is open. Start doing stuff to it */
|
|
|
|
EfiPrintf(L"Unimplemented BSD path\r\n");
|
2016-01-18 05:26:10 +00:00
|
|
|
Status = STATUS_NOT_IMPLEMENTED;
|
2016-01-06 04:43:23 +00:00
|
|
|
|
|
|
|
FailurePath:
|
|
|
|
/* Close the BSD if we had it open */
|
|
|
|
if (BsdpLogObject.FileId != -1)
|
|
|
|
{
|
|
|
|
BlFileClose(BsdpLogObject.FileId);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Close the device if we had it open */
|
|
|
|
if (BsdpLogObject.DeviceId != -1)
|
|
|
|
{
|
|
|
|
BlDeviceClose(BsdpLogObject.DeviceId);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Set BSD object to its uninitialized state */
|
|
|
|
BsdpLogObjectInitialized = FALSE;
|
|
|
|
BsdpLogObject.FileId = 0;
|
|
|
|
BsdpLogObject.DeviceId = 0;
|
|
|
|
BsdpLogObject.Flags = 0;
|
|
|
|
BsdpLogObject.Unknown = 0;
|
|
|
|
BsdpLogObject.Size = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
|
|
BmpInitializeBootStatusDataLog (
|
|
|
|
VOID
|
|
|
|
)
|
|
|
|
{
|
|
|
|
NTSTATUS Status;
|
|
|
|
PBL_DEVICE_DESCRIPTOR BsdDevice;
|
|
|
|
PWCHAR BsdPath;
|
|
|
|
ULONG Flags;
|
|
|
|
BOOLEAN PreserveBsd;
|
|
|
|
|
|
|
|
/* Initialize locals */
|
|
|
|
BsdPath = NULL;
|
|
|
|
BsdDevice = NULL;
|
|
|
|
Flags = 0;
|
|
|
|
|
|
|
|
/* Check if the BSD is stored in a custom device */
|
|
|
|
Status = BlGetBootOptionDevice(BlpApplicationEntry.BcdData,
|
|
|
|
BcdLibraryDevice_BsdLogDevice,
|
|
|
|
&BsdDevice,
|
|
|
|
NULL);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
/* Nope, use the boot device */
|
|
|
|
BsdDevice = BlpBootDevice;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Check if the path is custom as well */
|
|
|
|
Status = BlGetBootOptionString(BlpApplicationEntry.BcdData,
|
|
|
|
BcdLibraryString_BsdLogPath,
|
|
|
|
&BsdPath);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
/* Nope, use our default path */
|
|
|
|
Status = BmpFwGetFullPath(L"\\bootstat.dat", &BsdPath);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
BsdPath = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Set preserve flag */
|
|
|
|
Flags = 1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Set preserve flag */
|
|
|
|
Flags = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Finally, check if the BSD should be preserved */
|
|
|
|
Status = BlGetBootOptionBoolean(BlpApplicationEntry.BcdData,
|
|
|
|
BcdLibraryBoolean_PreserveBsdLog,
|
|
|
|
&PreserveBsd);
|
|
|
|
if (!(NT_SUCCESS(Status)) || !(PreserveBsd))
|
|
|
|
{
|
|
|
|
/* We failed to read, or we were asked not to preserve it */
|
|
|
|
Flags = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Initialize the log */
|
|
|
|
BlBsdInitializeLog(BsdDevice, BsdPath, Flags);
|
|
|
|
|
|
|
|
/* Free the BSD device descriptor if we had one */
|
|
|
|
if (BsdDevice)
|
|
|
|
{
|
|
|
|
BlMmFreeHeap(BsdDevice);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Free the BSD path if we had one */
|
|
|
|
if ((Flags) && (BsdPath))
|
|
|
|
{
|
|
|
|
BlMmFreeHeap(BsdPath);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
|
|
BmFwMemoryInitialize (
|
|
|
|
VOID
|
|
|
|
)
|
|
|
|
{
|
|
|
|
NTSTATUS Status;
|
|
|
|
PHYSICAL_ADDRESS PhysicalAddress;
|
|
|
|
BL_ADDRESS_RANGE AddressRange;
|
|
|
|
|
|
|
|
/* Select the range below 1MB */
|
|
|
|
AddressRange.Maximum = 0xFFFFF;
|
|
|
|
AddressRange.Minimum = 0;
|
|
|
|
|
2017-02-06 03:14:14 +00:00
|
|
|
/* Allocate one reserved page with the "below 1MB" attribute */
|
2016-01-06 04:43:23 +00:00
|
|
|
Status = MmPapAllocatePhysicalPagesInRange(&PhysicalAddress,
|
|
|
|
BlApplicationReserved,
|
|
|
|
1,
|
2017-02-06 03:14:14 +00:00
|
|
|
BlMemoryBelow1MB,
|
2016-01-06 04:43:23 +00:00
|
|
|
0,
|
|
|
|
&MmMdlUnmappedAllocated,
|
|
|
|
&AddressRange,
|
|
|
|
BL_MM_REQUEST_DEFAULT_TYPE);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
/* Print a message on error, but keep going */
|
|
|
|
BlStatusPrint(L"BmFwMemoryInitialize: Failed to allocate a page below 1MB. Status: 0x%08x\r\n",
|
|
|
|
Status);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-01-07 23:43:15 +00:00
|
|
|
NTSTATUS
|
|
|
|
BmpBgDisplayClearScreen (
|
|
|
|
_In_ ULONG Color
|
|
|
|
)
|
|
|
|
{
|
|
|
|
/* Not yet supported */
|
|
|
|
return STATUS_NOT_IMPLEMENTED;
|
|
|
|
}
|
|
|
|
|
2016-01-08 06:03:55 +00:00
|
|
|
NTSTATUS
|
|
|
|
BlXmiWrite (
|
|
|
|
_In_ PWCHAR XmlTag
|
|
|
|
)
|
|
|
|
{
|
|
|
|
/* Sigh */
|
|
|
|
EfiPrintf(L"XML: %s\r\n", XmlTag);
|
|
|
|
return STATUS_NOT_IMPLEMENTED;
|
|
|
|
}
|
|
|
|
|
2016-01-07 23:43:15 +00:00
|
|
|
NTSTATUS
|
|
|
|
BlXmiInitialize (
|
|
|
|
_In_ PWCHAR Stylesheet
|
|
|
|
)
|
|
|
|
{
|
|
|
|
/* Reset the cursor type */
|
|
|
|
BlDisplaySetCursorType(0);
|
|
|
|
|
|
|
|
/* Nope, not doing any XML stuff */
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
NTSTATUS
|
|
|
|
BmFwVerifySelfIntegrity (
|
|
|
|
VOID
|
|
|
|
)
|
|
|
|
{
|
2016-11-12 20:53:49 +00:00
|
|
|
/* Check if we're booted by UEFI off the DVD directly */
|
2016-01-07 23:43:15 +00:00
|
|
|
if ((BlpBootDevice->DeviceType == LocalDevice) &&
|
|
|
|
(BlpBootDevice->Local.Type == CdRomDevice) &&
|
2016-01-08 00:15:00 +00:00
|
|
|
(BlpApplicationFlags & BL_APPLICATION_FLAG_CONVERTED_FROM_EFI))
|
2016-01-07 23:43:15 +00:00
|
|
|
{
|
2016-01-08 06:03:55 +00:00
|
|
|
/* Windows actually bypasses integrity checks in this case. Works for us */
|
2016-01-07 23:43:15 +00:00
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2016-01-08 06:03:55 +00:00
|
|
|
/* Our binaries aren't signed, so always return failure */
|
2016-01-07 23:43:15 +00:00
|
|
|
return 0xC0000428;
|
|
|
|
}
|
2016-01-06 04:43:23 +00:00
|
|
|
|
2016-01-08 06:03:55 +00:00
|
|
|
NTSTATUS
|
|
|
|
BmFwRegisterRevocationList (
|
|
|
|
VOID
|
|
|
|
)
|
|
|
|
{
|
|
|
|
NTSTATUS Status;
|
|
|
|
BOOLEAN SecureBootEnabled;
|
|
|
|
|
|
|
|
/* Is SecureBoot enabled? */
|
|
|
|
Status = BlSecureBootIsEnabled(&SecureBootEnabled);
|
|
|
|
if ((NT_SUCCESS(Status)) && (SecureBootEnabled))
|
|
|
|
{
|
|
|
|
EfiPrintf(L"SB not implemented revok\r\n");
|
|
|
|
return STATUS_NOT_IMPLEMENTED;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Nothing to do without SecureBoot */
|
|
|
|
Status = STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Return revocation result back to caller */
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
NTSTATUS
|
|
|
|
BmResumeFromHibernate (
|
|
|
|
_Out_ PHANDLE BcdResumeHandle
|
|
|
|
)
|
|
|
|
{
|
|
|
|
NTSTATUS Status;
|
|
|
|
BOOLEAN AttemptResume;
|
|
|
|
|
|
|
|
/* Should we attempt to resume from hibernation? */
|
|
|
|
Status = BlGetBootOptionBoolean(BlpApplicationEntry.BcdData,
|
|
|
|
BcdBootMgrBoolean_AttemptResume,
|
|
|
|
&AttemptResume);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
/* Nope. Is automatic restart on crash enabled? */
|
|
|
|
AttemptResume = FALSE;
|
|
|
|
Status = BlGetBootOptionBoolean(BlpApplicationEntry.BcdData,
|
|
|
|
BcdOSLoaderBoolean_DisableCrashAutoReboot,
|
|
|
|
&AttemptResume);
|
|
|
|
AttemptResume = (NT_SUCCESS(Status) && (AttemptResume));
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Don't do anything if there's no need to resume anything */
|
|
|
|
if (!AttemptResume)
|
|
|
|
{
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Not yet implemented */
|
|
|
|
EfiPrintf(L"Resume not supported\r\n");
|
|
|
|
return STATUS_NOT_IMPLEMENTED;
|
|
|
|
}
|
|
|
|
|
2016-01-09 05:39:18 +00:00
|
|
|
NTSTATUS
|
|
|
|
BmpProcessBadMemory (
|
|
|
|
VOID
|
|
|
|
)
|
|
|
|
{
|
2016-01-17 21:48:00 +00:00
|
|
|
BL_PD_DATA_BLOB BadMemoryData;
|
|
|
|
NTSTATUS Status;
|
|
|
|
|
|
|
|
/* Try to get the memory data from the memtest application */
|
|
|
|
BadMemoryData.BlobSize = 0;
|
|
|
|
BadMemoryData.Data = NULL;
|
|
|
|
BadMemoryData.DataSize = 0;
|
|
|
|
Status = BlPdQueryData(&BadMemoryGuid, NULL, &BadMemoryData);
|
|
|
|
if (Status != STATUS_BUFFER_TOO_SMALL)
|
|
|
|
{
|
|
|
|
/* No results, or some other error */
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Not yet implemented */
|
|
|
|
EfiPrintf(L"Bad page list persistence not implemented\r\n");
|
2016-01-09 05:39:18 +00:00
|
|
|
return STATUS_NOT_IMPLEMENTED;
|
|
|
|
}
|
|
|
|
|
|
|
|
NTSTATUS
|
|
|
|
BmPurgeOption (
|
|
|
|
_In_ HANDLE BcdHandle,
|
|
|
|
_In_ PGUID ObjectId,
|
|
|
|
_In_ ULONG Type
|
|
|
|
)
|
|
|
|
{
|
2016-01-17 21:48:00 +00:00
|
|
|
HANDLE ObjectHandle;
|
|
|
|
NTSTATUS Status;
|
|
|
|
|
|
|
|
/* Open the object */
|
|
|
|
Status = BcdOpenObject(BcdHandle, ObjectId, &ObjectHandle);
|
|
|
|
if (NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
/* Delete the element */
|
|
|
|
BcdDeleteElement(ObjectHandle, Type);
|
|
|
|
|
|
|
|
/* Close the object and set success */
|
|
|
|
BiCloseKey(ObjectHandle);
|
|
|
|
Status = STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Return the result */
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
2016-01-18 16:54:44 +00:00
|
|
|
NTSTATUS
|
|
|
|
BmGetEntryDescription (
|
|
|
|
_In_ HANDLE BcdHandle,
|
|
|
|
_In_ PGUID ObjectId,
|
|
|
|
_Out_ PBCD_OBJECT_DESCRIPTION Description
|
|
|
|
)
|
|
|
|
{
|
|
|
|
NTSTATUS Status;
|
|
|
|
HANDLE ObjectHandle;
|
|
|
|
|
|
|
|
/* Open the BCD object */
|
|
|
|
Status = BcdOpenObject(BcdHandle, ObjectId, &ObjectHandle);
|
|
|
|
if (NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
/* Make sure the caller passed this argument in */
|
|
|
|
if (!Description)
|
|
|
|
{
|
|
|
|
/* Fail otherwise */
|
|
|
|
Status = STATUS_INVALID_PARAMETER;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Query the description from the BCD interface */
|
|
|
|
Status = BiGetObjectDescription(ObjectHandle, Description);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Close the object key */
|
|
|
|
BiCloseKey(ObjectHandle);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Return the result back */
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
2016-01-17 21:48:00 +00:00
|
|
|
NTSTATUS
|
|
|
|
BmpPopulateBootEntryList (
|
|
|
|
_In_ HANDLE BcdHandle,
|
|
|
|
_In_ PGUID SequenceList,
|
|
|
|
_In_ ULONG Flags,
|
|
|
|
_Out_ PBL_LOADED_APPLICATION_ENTRY* BootSequence,
|
|
|
|
_Out_ PULONG SequenceCount
|
|
|
|
)
|
|
|
|
{
|
2016-01-18 16:54:44 +00:00
|
|
|
NTSTATUS Status;
|
|
|
|
ULONG BootIndex, i, OptionSize;
|
|
|
|
PBL_LOADED_APPLICATION_ENTRY BootEntry;
|
|
|
|
PBL_BCD_OPTION Options;
|
|
|
|
BCD_OBJECT_DESCRIPTION Description;
|
|
|
|
BcdObjectType ObjectType;
|
|
|
|
BOOLEAN HavePath, IsWinPe, SoftReboot;
|
|
|
|
PWCHAR LoaderPath;
|
|
|
|
|
|
|
|
/* Initialize locals */
|
|
|
|
Options = NULL;
|
|
|
|
BootIndex = 0;
|
|
|
|
Status = STATUS_NOT_FOUND;
|
|
|
|
|
|
|
|
/* Loop through every element in the sequence */
|
|
|
|
for (i = 0; i < *SequenceCount; i++)
|
|
|
|
{
|
|
|
|
/* Assume failure */
|
|
|
|
BootEntry = NULL;
|
|
|
|
|
|
|
|
/* Get the options for the sequence element */
|
|
|
|
Status = BmGetOptionList(BcdHandle, SequenceList, &Options);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
EfiPrintf(L"option list failed: %lx\r\n", Status);
|
|
|
|
goto LoopQuickie;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Make sure there's at least a path and description */
|
|
|
|
if (!(MiscGetBootOption(Options, BcdLibraryDevice_ApplicationDevice)) ||
|
|
|
|
!(MiscGetBootOption(Options, BcdLibraryString_Description)))
|
|
|
|
{
|
|
|
|
Status = STATUS_UNSUCCESSFUL;
|
|
|
|
EfiPrintf(L"missing list failed: %lx\r\n", Status);
|
|
|
|
goto LoopQuickie;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Get the size of the BCD options and allocate a large enough entry */
|
|
|
|
OptionSize = BlGetBootOptionListSize(Options);
|
|
|
|
BootEntry = BlMmAllocateHeap(sizeof(*BootEntry) + OptionSize);
|
|
|
|
if (!BootEntry)
|
|
|
|
{
|
|
|
|
Status = STATUS_NO_MEMORY;
|
|
|
|
goto Quickie;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Save it as part of the sequence */
|
|
|
|
BootSequence[BootIndex] = BootEntry;
|
|
|
|
|
|
|
|
/* Initialize it, and copy the BCD data */
|
|
|
|
RtlZeroMemory(BootEntry, sizeof(*BootEntry));
|
|
|
|
BootEntry->Guid = *SequenceList;
|
|
|
|
BootEntry->BcdData = (PBL_BCD_OPTION)(BootEntry + 1);
|
|
|
|
BootEntry->Flags = Flags;
|
|
|
|
RtlCopyMemory(BootEntry->BcdData, Options, OptionSize);
|
|
|
|
|
|
|
|
/* Get the object descriptor to find out what kind of entry it is */
|
|
|
|
Status = BmGetEntryDescription(BcdHandle,
|
|
|
|
&BootEntry->Guid,
|
|
|
|
&Description);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
EfiPrintf(L"missing desc failed: %lx\r\n", Status);
|
|
|
|
goto LoopQuickie;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Check if a path was given or not */
|
|
|
|
HavePath = MiscGetBootOption(Options, BcdLibraryString_ApplicationPath) ?
|
|
|
|
TRUE : FALSE;
|
|
|
|
|
|
|
|
/* Now select based on what type of object this is -- must be an app */
|
|
|
|
ObjectType.PackedValue = Description.Type;
|
|
|
|
if (ObjectType.Application.ObjectCode == BCD_OBJECT_TYPE_APPLICATION)
|
|
|
|
{
|
|
|
|
/* Then select based on what kind of app it is */
|
|
|
|
switch (ObjectType.Application.ApplicationCode)
|
|
|
|
{
|
|
|
|
/* Another boot manager */
|
|
|
|
case BCD_APPLICATION_TYPE_BOOTMGR:
|
|
|
|
BootEntry->Flags |= BCD_APPLICATION_TYPE_BOOTMGR;
|
|
|
|
break;
|
|
|
|
|
|
|
|
/* An OS loader */
|
|
|
|
case BCD_APPLICATION_TYPE_OSLOADER:
|
|
|
|
BootEntry->Flags |= BL_APPLICATION_ENTRY_WINLOAD;
|
|
|
|
|
|
|
|
/* Do we have a path for it? */
|
|
|
|
if (!HavePath)
|
|
|
|
{
|
|
|
|
/* We'll try to make one up. Is this WinPE? */
|
|
|
|
IsWinPe = FALSE;
|
|
|
|
Status = BlGetBootOptionBoolean(Options,
|
|
|
|
BcdOSLoaderBoolean_WinPEMode,
|
|
|
|
&IsWinPe);
|
|
|
|
if (!(NT_SUCCESS(Status)) && (Status != STATUS_NOT_FOUND))
|
|
|
|
{
|
|
|
|
goto Quickie;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Use the appropriate path for WinPE or local install */
|
|
|
|
LoaderPath = IsWinPe ?
|
|
|
|
L"\\Windows\\System32\\boot\\winload.efi" :
|
|
|
|
L"\\Windows\\System32\\winload.efi";
|
|
|
|
|
|
|
|
/* Add the path to the boot entry */
|
2018-02-05 00:01:38 +00:00
|
|
|
Status = BlAppendBootOptionString(BootEntry,
|
|
|
|
BcdLibraryString_ApplicationPath,
|
|
|
|
LoaderPath);
|
2016-01-18 16:54:44 +00:00
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
goto Quickie;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* We have a path now */
|
|
|
|
HavePath = TRUE;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
/* A hibernate-resume application */
|
|
|
|
case BCD_APPLICATION_TYPE_RESUME:
|
|
|
|
BootEntry->Flags |= BL_APPLICATION_ENTRY_WINRESUME;
|
|
|
|
break;
|
|
|
|
|
|
|
|
/* An older OS NTLDR */
|
|
|
|
case BCD_APPLICATION_TYPE_NTLDR:
|
|
|
|
BootEntry->Flags |= BL_APPLICATION_ENTRY_NTLDR;
|
|
|
|
break;
|
|
|
|
|
|
|
|
/* An older OS SETUPLDR */
|
|
|
|
case BCD_APPLICATION_TYPE_SETUPLDR:
|
|
|
|
BootEntry->Flags |= BL_APPLICATION_ENTRY_SETUPLDR;
|
|
|
|
break;
|
|
|
|
|
|
|
|
/* A 3rd party/Win9x boot sector */
|
|
|
|
case BCD_APPLICATION_TYPE_BOOTSECTOR:
|
|
|
|
BootEntry->Flags |= BL_APPLICATION_ENTRY_BOOTSECTOR;
|
|
|
|
break;
|
|
|
|
|
|
|
|
/* Something else entirely */
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* We better have a path by now */
|
|
|
|
if (!HavePath)
|
|
|
|
{
|
|
|
|
Status = STATUS_UNSUCCESSFUL;
|
|
|
|
goto LoopQuickie;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Check if this is a real mode startup.com */
|
|
|
|
if ((ObjectType.Application.ObjectCode == BCD_OBJECT_TYPE_APPLICATION) &&
|
2016-07-13 15:43:08 +00:00
|
|
|
(ObjectType.Application.ImageCode == BCD_IMAGE_TYPE_REAL_MODE) &&
|
2016-01-18 16:54:44 +00:00
|
|
|
(ObjectType.Application.ApplicationCode == BCD_APPLICATION_TYPE_STARTUPCOM))
|
|
|
|
{
|
|
|
|
/* Check if PXE soft reboot will occur */
|
|
|
|
Status = BlGetBootOptionBoolean(Options,
|
|
|
|
BcdStartupBoolean_PxeSoftReboot,
|
|
|
|
&SoftReboot);
|
|
|
|
if ((NT_SUCCESS(Status)) && (SoftReboot))
|
|
|
|
{
|
|
|
|
/* Then it's a valid startup.com entry */
|
|
|
|
BootEntry->Flags |= BL_APPLICATION_ENTRY_STARTUP;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
LoopQuickie:
|
|
|
|
/* All done with this entry -- did we have BCD options? */
|
|
|
|
if (Options)
|
|
|
|
{
|
|
|
|
/* Free them, they're part of the entry now */
|
|
|
|
BlMmFreeHeap(Options);
|
|
|
|
Options = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Did we fail anywhere? */
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
/* Yep -- did we fail with an active boot entry? */
|
|
|
|
if (BootEntry)
|
|
|
|
{
|
|
|
|
/* Destroy it */
|
|
|
|
BlDestroyBootEntry(BootEntry);
|
|
|
|
BootSequence[BootIndex] = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* It worked, so populate the next index now */
|
|
|
|
BootIndex++;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* And move to the next GUID in the sequence list */
|
|
|
|
SequenceList++;
|
|
|
|
}
|
|
|
|
|
|
|
|
Quickie:
|
|
|
|
/* All done now -- did we have any BCD options? */
|
|
|
|
if (Options)
|
|
|
|
{
|
|
|
|
/* Free them */
|
|
|
|
BlMmFreeHeap(Options);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Return the status */
|
|
|
|
return Status;
|
2016-01-09 05:39:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
NTSTATUS
|
|
|
|
BmGetBootSequence (
|
|
|
|
_In_ HANDLE BcdHandle,
|
|
|
|
_In_ PGUID SequenceList,
|
|
|
|
_In_ ULONG SequenceListCount,
|
|
|
|
_In_ ULONG Flags,
|
|
|
|
_Out_ PBL_LOADED_APPLICATION_ENTRY** BootSequence,
|
|
|
|
_Out_ PULONG SequenceCount
|
|
|
|
)
|
|
|
|
{
|
2016-01-17 21:48:00 +00:00
|
|
|
PBL_LOADED_APPLICATION_ENTRY* Sequence;
|
2016-07-14 12:46:31 +00:00
|
|
|
ULONG Count = SequenceListCount;
|
2016-01-17 21:48:00 +00:00
|
|
|
NTSTATUS Status;
|
|
|
|
|
|
|
|
/* Allocate the sequence list */
|
|
|
|
Sequence = BlMmAllocateHeap(SequenceListCount * sizeof(*Sequence));
|
|
|
|
if (!Sequence)
|
|
|
|
{
|
|
|
|
return STATUS_NO_MEMORY;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Populate the sequence list */
|
|
|
|
Status = BmpPopulateBootEntryList(BcdHandle,
|
|
|
|
SequenceList,
|
|
|
|
Flags,
|
|
|
|
Sequence,
|
|
|
|
&Count);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
/* Free the list on failure */
|
|
|
|
BlMmFreeHeap(Sequence);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Otherwise, set success and return the list and count */
|
|
|
|
Status = STATUS_SUCCESS;
|
|
|
|
*BootSequence = Sequence;
|
|
|
|
*SequenceCount = Count;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* All done */
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
NTSTATUS
|
|
|
|
BmEnumerateBootEntries (
|
|
|
|
_In_ HANDLE BcdHandle,
|
2016-01-18 05:26:10 +00:00
|
|
|
_Out_ PBL_LOADED_APPLICATION_ENTRY **BootSequence,
|
2016-01-17 21:48:00 +00:00
|
|
|
_Out_ PULONG SequenceCount
|
|
|
|
)
|
|
|
|
{
|
2016-01-18 05:26:10 +00:00
|
|
|
NTSTATUS Status;
|
|
|
|
ULONG BootIndex, BootIniCount, BootEntryCount, BcdCount;
|
|
|
|
PBL_LOADED_APPLICATION_ENTRY* Sequence;
|
|
|
|
PGUID DisplayOrder;
|
|
|
|
GUID DefaultObject;
|
|
|
|
BOOLEAN UseDisplayList;
|
|
|
|
|
|
|
|
/* Initialize locals */
|
|
|
|
BootIndex = 0;
|
|
|
|
|
|
|
|
/* First try to get the display list, if any */
|
|
|
|
UseDisplayList = TRUE;
|
|
|
|
Status = BlGetBootOptionGuidList(BlpApplicationEntry.BcdData,
|
|
|
|
BcdBootMgrObjectList_DisplayOrder,
|
|
|
|
&DisplayOrder,
|
|
|
|
&BcdCount);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
/* No list, get the default entry instead */
|
|
|
|
Status = BlGetBootOptionGuid(BlpApplicationEntry.BcdData,
|
|
|
|
BcdBootMgrObject_DefaultObject,
|
|
|
|
&DefaultObject);
|
|
|
|
if (NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
/* Set the array to just our entry */
|
|
|
|
UseDisplayList = FALSE;
|
|
|
|
BcdCount = 1;
|
|
|
|
DisplayOrder = &DefaultObject;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* No default list either, return success but no entries */
|
|
|
|
*BootSequence = NULL;
|
|
|
|
*SequenceCount = 0;
|
|
|
|
Status = STATUS_SUCCESS;
|
|
|
|
DisplayOrder = NULL;
|
|
|
|
goto Quickie;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Check if boot.ini was used */
|
|
|
|
BootIniCount = 0;
|
|
|
|
if (BmBootIniUsed)
|
|
|
|
{
|
|
|
|
/* Get the entries from it */
|
|
|
|
EfiPrintf(L"Boot.ini not supported\r\n");
|
|
|
|
BootIniCount = 0;//BmBootIniGetEntryCount();
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Allocate an array large enough for the combined boot entries */
|
|
|
|
BootEntryCount = BootIniCount + BcdCount;
|
|
|
|
Sequence = BlMmAllocateHeap(BootEntryCount * sizeof(*Sequence));
|
|
|
|
if (!Sequence)
|
|
|
|
{
|
|
|
|
Status = STATUS_NO_MEMORY;
|
|
|
|
goto Quickie;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Zero it out */
|
|
|
|
RtlZeroMemory(Sequence, BootEntryCount * sizeof(*Sequence));
|
|
|
|
|
|
|
|
/* Check if we had BCD entries */
|
|
|
|
if (BcdCount)
|
|
|
|
{
|
|
|
|
/* Populate the list of bootable entries */
|
|
|
|
Status = BmpPopulateBootEntryList(BcdHandle,
|
|
|
|
DisplayOrder,
|
2016-01-18 16:54:44 +00:00
|
|
|
BL_APPLICATION_ENTRY_DISPLAY_ORDER,
|
2016-01-18 05:26:10 +00:00
|
|
|
Sequence,
|
|
|
|
&BcdCount);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
/* Bail out */
|
|
|
|
goto Quickie;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Check if we had boot.ini entries */
|
|
|
|
if (BootIniCount)
|
|
|
|
{
|
|
|
|
/* TODO */
|
|
|
|
EfiPrintf(L"Boot.ini not supported\r\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Return success and the sequence + count populated */
|
|
|
|
Status = STATUS_SUCCESS;
|
|
|
|
*BootSequence = Sequence;
|
|
|
|
*SequenceCount = BootIniCount + BcdCount;
|
|
|
|
|
|
|
|
Quickie:
|
|
|
|
/* Check if we had allocated a GUID list */
|
|
|
|
if ((UseDisplayList) && (DisplayOrder))
|
|
|
|
{
|
|
|
|
/* Free it */
|
|
|
|
BlMmFreeHeap(DisplayOrder);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Check if this is the failure path */
|
|
|
|
if (!(NT_SUCCESS(Status)) && (Sequence))
|
|
|
|
{
|
|
|
|
/* Loop the remaining boot entries */
|
|
|
|
while (BootIndex < BootEntryCount)
|
|
|
|
{
|
|
|
|
/* Check if it had been allocated */
|
|
|
|
if (Sequence[BootIndex])
|
|
|
|
{
|
|
|
|
/* Free it */
|
|
|
|
BlMmFreeHeap(Sequence[BootIndex]);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Next*/
|
|
|
|
BootIndex++;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Free the whole sequence now */
|
|
|
|
BlMmFreeHeap(Sequence);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* All done, return the result */
|
|
|
|
return Status;
|
2016-01-09 05:39:18 +00:00
|
|
|
}
|
|
|
|
|
2016-01-18 18:16:49 +00:00
|
|
|
VOID
|
|
|
|
BmpGetDefaultBootEntry (
|
|
|
|
_In_ PBL_LOADED_APPLICATION_ENTRY* Sequence,
|
|
|
|
_In_ ULONG Count,
|
|
|
|
_Out_ PBL_LOADED_APPLICATION_ENTRY* DefaultEntry,
|
|
|
|
_Out_ PULONG DefaultIndex
|
|
|
|
)
|
|
|
|
{
|
|
|
|
GUID DefaultObject;
|
|
|
|
NTSTATUS Status;
|
|
|
|
ULONG BootIndex;
|
|
|
|
|
|
|
|
/* Assume no default */
|
|
|
|
*DefaultEntry = *Sequence;
|
|
|
|
*DefaultIndex = 0;
|
|
|
|
|
|
|
|
/* Nothing to do if there's just one entry */
|
|
|
|
if (Count == 1)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Get the default object, bail out if there isn't one */
|
|
|
|
Status = BlGetBootOptionGuid(BlpApplicationEntry.BcdData,
|
|
|
|
BcdBootMgrObject_DefaultObject,
|
|
|
|
&DefaultObject);
|
|
|
|
if (!(NT_SUCCESS(Status)) || !(Count))
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Scan the boot sequence */
|
|
|
|
for (BootIndex = 0; BootIndex < Count; BootIndex++)
|
|
|
|
{
|
|
|
|
/* Find one that matches the default */
|
|
|
|
if (RtlEqualMemory(&Sequence[BootIndex]->Guid,
|
|
|
|
&DefaultObject,
|
|
|
|
sizeof(GUID)))
|
|
|
|
{
|
|
|
|
/* Return it */
|
|
|
|
*DefaultEntry = Sequence[BootIndex];
|
|
|
|
*DefaultIndex = BootIndex;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
BL_MENU_POLICY
|
|
|
|
BmGetBootMenuPolicy (
|
|
|
|
_In_ PBL_LOADED_APPLICATION_ENTRY BootEntry
|
|
|
|
)
|
|
|
|
{
|
|
|
|
NTSTATUS Status;
|
|
|
|
BOOLEAN EmsEnabled;
|
|
|
|
ULONGLONG BootMenuPolicy;
|
|
|
|
ULONG OptionId;
|
|
|
|
|
|
|
|
/* Check if EMS is enabled */
|
|
|
|
Status = BlGetBootOptionBoolean(BlpApplicationEntry.BcdData,
|
|
|
|
BcdOSLoaderBoolean_EmsEnabled,
|
|
|
|
&EmsEnabled);
|
|
|
|
if ((NT_SUCCESS(Status)) && (EmsEnabled))
|
|
|
|
{
|
|
|
|
/* No boot menu */
|
|
|
|
return MenuPolicyLegacy;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Check what entry we are looking at */
|
|
|
|
if (!BootEntry)
|
|
|
|
{
|
|
|
|
/* No entry, pick the selected one */
|
|
|
|
BootEntry = BmpSelectedBootEntry;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Do we still not have an entry? */
|
|
|
|
if (!BootEntry)
|
|
|
|
{
|
|
|
|
/* Show the menu */
|
|
|
|
return MenuPolicyStandard;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Check if this is an OS loader */
|
|
|
|
BootMenuPolicy = 0;
|
|
|
|
if (BootEntry->Flags & BL_APPLICATION_ENTRY_WINLOAD)
|
|
|
|
{
|
|
|
|
/* Use the correct option ID */
|
|
|
|
OptionId = BcdOSLoaderInteger_BootMenuPolicy;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Check if this is an OS resumer */
|
|
|
|
if (!(BootEntry->Flags & BL_APPLICATION_ENTRY_WINRESUME))
|
|
|
|
{
|
|
|
|
/* Nope, so no reason for a menu */
|
|
|
|
return MenuPolicyLegacy;
|
|
|
|
}
|
|
|
|
|
2016-11-12 20:53:49 +00:00
|
|
|
/* Use the correct option ID */
|
2016-01-18 18:16:49 +00:00
|
|
|
OptionId = BcdResumeInteger_BootMenuPolicy;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Check the option ID for the boot menu policy */
|
|
|
|
Status = BlGetBootOptionInteger(BootEntry->BcdData,
|
|
|
|
OptionId,
|
|
|
|
&BootMenuPolicy);
|
|
|
|
if (NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
/* We have one, return it */
|
|
|
|
return BootMenuPolicy;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* No policy, so assume no menu */
|
|
|
|
return MenuPolicyLegacy;
|
|
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
|
|
BmDisplayGetBootMenuStatus (
|
|
|
|
_Out_ PL_MENU_STATUS MenuStatus
|
|
|
|
)
|
|
|
|
{
|
|
|
|
/* For now, don't support key input at all */
|
|
|
|
MenuStatus->AsULong = 0;
|
|
|
|
MenuStatus->OemKey = UNICODE_NULL;
|
|
|
|
MenuStatus->BootIndex = -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
NTSTATUS
|
|
|
|
BmProcessCustomAction (
|
|
|
|
_In_ HANDLE BcdHandle,
|
|
|
|
_In_ PWCHAR ActionKey
|
|
|
|
)
|
|
|
|
{
|
|
|
|
EfiPrintf(L"Custom actions not yet handled\r\n");
|
|
|
|
return STATUS_NOT_IMPLEMENTED;
|
|
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
|
|
BmpProcessBootEntry (
|
|
|
|
_In_ HANDLE BcdHandle,
|
|
|
|
_In_ PBL_LOADED_APPLICATION_ENTRY BootEntry,
|
|
|
|
_Out_ PBOOLEAN ExitBootManager
|
|
|
|
)
|
|
|
|
{
|
|
|
|
BL_MENU_STATUS MenuStatus;
|
|
|
|
|
|
|
|
/* Don't exit */
|
|
|
|
*ExitBootManager = FALSE;
|
|
|
|
|
|
|
|
/* If the legacy menu must be shown, or if we have a boot entry */
|
|
|
|
if ((BmGetBootMenuPolicy(BootEntry) != MenuPolicyStandard) || (BootEntry))
|
|
|
|
{
|
2016-11-12 20:53:49 +00:00
|
|
|
/* Check if any key has been pressed */
|
2016-01-18 18:16:49 +00:00
|
|
|
BmDisplayGetBootMenuStatus(&MenuStatus);
|
|
|
|
if (MenuStatus.AnyKey)
|
|
|
|
{
|
|
|
|
/* Was the exit key pressed? */
|
|
|
|
if (MenuStatus.Exit)
|
|
|
|
{
|
|
|
|
/* Don't display a menu, and exit */
|
|
|
|
*ExitBootManager = TRUE;
|
|
|
|
BmpDisplayBootMenu = FALSE;
|
|
|
|
}
|
|
|
|
else if (MenuStatus.OemKey)
|
|
|
|
{
|
|
|
|
/* Process the OEM key action */
|
|
|
|
BmProcessCustomAction(BcdHandle, &MenuStatus.KeyValue);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Process other keys */
|
|
|
|
EfiPrintf(L"TODO\r\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-01-09 05:39:18 +00:00
|
|
|
NTSTATUS
|
|
|
|
BmpGetSelectedBootEntry (
|
|
|
|
_In_ HANDLE BcdHandle,
|
2016-01-18 18:16:49 +00:00
|
|
|
_Out_ PBL_LOADED_APPLICATION_ENTRY* SelectedBootEntry,
|
2016-01-09 05:39:18 +00:00
|
|
|
_Out_ PULONG EntryIndex,
|
|
|
|
_Out_ PBOOLEAN ExitBootManager
|
|
|
|
)
|
|
|
|
{
|
2016-01-17 21:48:00 +00:00
|
|
|
NTSTATUS Status;
|
|
|
|
PBL_LOADED_APPLICATION_ENTRY* Sequence;
|
|
|
|
PBL_LOADED_APPLICATION_ENTRY Entry, SelectedEntry;
|
2016-01-18 18:16:49 +00:00
|
|
|
ULONG Count, BootIndex, SelectedIndex;
|
|
|
|
// BOOLEAN FoundFailedEntry;
|
|
|
|
ULONGLONG Timeout;
|
2016-01-17 21:48:00 +00:00
|
|
|
|
|
|
|
/* Initialize locals */
|
|
|
|
BootIndex = 0;
|
|
|
|
Count = 0;
|
|
|
|
Sequence = NULL;
|
|
|
|
SelectedEntry = NULL;
|
|
|
|
|
|
|
|
/* Enumerate all the boot entries */
|
|
|
|
Status = BmEnumerateBootEntries(BcdHandle, &Sequence, &Count);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
/* Bail out if we failed */
|
|
|
|
goto Quickie;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Check if there are no entries */
|
|
|
|
if (!Count)
|
|
|
|
{
|
|
|
|
/* This is fatal -- kill the system */
|
|
|
|
Status = STATUS_FILE_INVALID;
|
|
|
|
BmFatalErrorEx(BL_FATAL_ERROR_BCD_ENTRIES, (ULONG_PTR)L"\\BCD", Status, 0, 0);
|
|
|
|
goto Quickie;
|
|
|
|
}
|
|
|
|
|
2016-01-18 18:16:49 +00:00
|
|
|
/* Check if we don't yet have an array of failed boot entries */
|
|
|
|
if (!BmpFailedBootEntries)
|
|
|
|
{
|
|
|
|
/* Allocate it */
|
|
|
|
BmpFailedBootEntries = BlMmAllocateHeap(Count);
|
|
|
|
if (BmpFailedBootEntries)
|
|
|
|
{
|
|
|
|
/* Zero it out */
|
|
|
|
RtlZeroMemory(BmpFailedBootEntries, Count);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Check if we have a hardcoded boot override */
|
|
|
|
if (BmBootEntryOverridePresent)
|
|
|
|
{
|
|
|
|
EfiPrintf(L"Hard-coded boot override mode not supported\r\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Log the OS count */
|
|
|
|
//BlLogEtwWrite(BOOT_BOOTMGR_MULTI_OS_COUNT);
|
|
|
|
|
|
|
|
/* Check if the display is already active and cached */
|
|
|
|
if (!BmDisplayStateCached)
|
|
|
|
{
|
|
|
|
/* Check if we should display a boot menu */
|
|
|
|
Status = BlGetBootOptionBoolean(BlpApplicationEntry.BcdData,
|
|
|
|
BcdBootMgrBoolean_DisplayBootMenu,
|
|
|
|
&BmpDisplayBootMenu);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
/* Assume not */
|
|
|
|
BmpDisplayBootMenu = FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Check if there's only one entry to boot anyway */
|
|
|
|
if (Count == 1)
|
|
|
|
{
|
|
|
|
/* Read it */
|
|
|
|
SelectedEntry = *Sequence;
|
|
|
|
|
|
|
|
/* Process it */
|
|
|
|
BmpProcessBootEntry(BcdHandle, SelectedEntry, ExitBootManager);
|
|
|
|
|
|
|
|
/* Check if we're not displaying a boot menu */
|
|
|
|
if (!BmpDisplayBootMenu)
|
|
|
|
{
|
|
|
|
/* Now we are */
|
|
|
|
BmpDisplayBootMenu = TRUE;
|
|
|
|
|
|
|
|
/* Return the entry and its index back */
|
|
|
|
*EntryIndex = 0;
|
|
|
|
*SelectedBootEntry = SelectedEntry;
|
|
|
|
Status = STATUS_SUCCESS;
|
|
|
|
goto Quickie;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Get the default boot entry */
|
|
|
|
BmpGetDefaultBootEntry(Sequence, Count, &SelectedEntry, &SelectedIndex);
|
|
|
|
|
|
|
|
/* Check if we have a failed boot entry array allocated */
|
|
|
|
//FoundFailedEntry = FALSE;
|
|
|
|
if (BmpFailedBootEntries)
|
|
|
|
{
|
|
|
|
/* Check if the default entry failed to boot */
|
|
|
|
if (BmpFailedBootEntries[SelectedIndex])
|
|
|
|
{
|
|
|
|
/* Loop through the current boot sequence */
|
|
|
|
for (SelectedIndex = 0; SelectedIndex < Count; SelectedIndex++)
|
|
|
|
{
|
|
|
|
/* Check if there's no sequence for this index, or it failed */
|
|
|
|
while (!(Sequence[SelectedIndex]) ||
|
|
|
|
(BmpFailedBootEntries[SelectedIndex]))
|
|
|
|
{
|
|
|
|
/* Remember that this is a failed entry */
|
|
|
|
SelectedEntry = Sequence[SelectedIndex];
|
|
|
|
//FoundFailedEntry = TRUE;
|
|
|
|
BmpDisplayBootMenu = FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Check if the entry is an OS loader */
|
|
|
|
if (SelectedEntry->Flags & BL_APPLICATION_ENTRY_WINLOAD)
|
|
|
|
{
|
|
|
|
// todo
|
|
|
|
EfiPrintf(L"todo path\r\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Check if there's no timeout */
|
|
|
|
Status = BlGetBootOptionInteger(BlpApplicationEntry.BcdData,
|
|
|
|
BcdBootMgrInteger_Timeout,
|
|
|
|
&Timeout);
|
|
|
|
if ((NT_SUCCESS(Status) && !(Timeout)))
|
|
|
|
{
|
|
|
|
/* There isn't, so just process the default entry right away */
|
|
|
|
BmpProcessBootEntry(BcdHandle, SelectedEntry, ExitBootManager);
|
|
|
|
|
|
|
|
/* Check if we're not displaying a boot menu */
|
|
|
|
if (!BmpDisplayBootMenu)
|
|
|
|
{
|
|
|
|
/* Now we are */
|
|
|
|
BmpDisplayBootMenu = TRUE;
|
|
|
|
|
|
|
|
/* Return the entry and its index back */
|
|
|
|
*EntryIndex = 0;
|
|
|
|
*SelectedBootEntry = SelectedEntry;
|
|
|
|
Status = STATUS_SUCCESS;
|
|
|
|
goto Quickie;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Remove the timeout for this boot instance */
|
|
|
|
BlRemoveBootOption(BlpApplicationEntry.BcdData,
|
|
|
|
BcdBootMgrInteger_Timeout);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Here is where we display the menu and list of tools */
|
|
|
|
EfiPrintf(L"Tool selection not yet implemented\r\n");
|
2016-01-18 16:54:44 +00:00
|
|
|
EfiStall(10000000);
|
2016-01-17 21:48:00 +00:00
|
|
|
*SelectedBootEntry = NULL;
|
|
|
|
|
|
|
|
Quickie:
|
|
|
|
/* We are done -- did we have a sequence? */
|
|
|
|
if (Sequence)
|
|
|
|
{
|
|
|
|
/* Do we have any boot entries we parsed? */
|
|
|
|
while (BootIndex < Count)
|
|
|
|
{
|
|
|
|
/* Get the current boot entry */
|
|
|
|
Entry = Sequence[BootIndex];
|
|
|
|
|
|
|
|
/* Did we fail, or is is not the selected one? */
|
|
|
|
if ((Entry) && ((Entry != SelectedEntry) || !(NT_SUCCESS(Status))))
|
|
|
|
{
|
|
|
|
/* Destroy it, as it won't be needed */
|
|
|
|
BlDestroyBootEntry(Entry);
|
|
|
|
}
|
|
|
|
else if (Entry == SelectedEntry)
|
|
|
|
{
|
|
|
|
/* It's the selected one, return its index */
|
|
|
|
*EntryIndex = BootIndex;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Move to the next entry */
|
|
|
|
BootIndex++;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Free the sequence of entries */
|
|
|
|
BlMmFreeHeap(Sequence);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Return the selection result */
|
|
|
|
return Status;
|
2016-01-09 05:39:18 +00:00
|
|
|
}
|
|
|
|
|
2016-01-19 18:21:54 +00:00
|
|
|
NTSTATUS
|
|
|
|
BmLaunchRecoverySequence (
|
|
|
|
_In_ PBL_LOADED_APPLICATION_ENTRY BootEntry,
|
|
|
|
_In_ ULONG LaunchCode
|
2016-01-09 05:39:18 +00:00
|
|
|
)
|
|
|
|
{
|
2016-01-19 18:21:54 +00:00
|
|
|
NTSTATUS Status;
|
|
|
|
PBL_LOADED_APPLICATION_ENTRY RecoveryEntry;
|
|
|
|
HANDLE BcdHandle;
|
|
|
|
PGUID RecoverySequence;
|
|
|
|
ULONG Count, i, RecoveryIndex, SequenceCount;
|
|
|
|
PBL_LOADED_APPLICATION_ENTRY* Sequence;
|
|
|
|
|
2016-01-20 02:58:39 +00:00
|
|
|
/* Initialize locals */
|
2016-01-19 18:21:54 +00:00
|
|
|
RecoveryIndex = 0;
|
|
|
|
Sequence = NULL;
|
|
|
|
RecoverySequence = NULL;
|
|
|
|
Count = 0;
|
|
|
|
BcdHandle = NULL;
|
|
|
|
|
2016-01-20 02:58:39 +00:00
|
|
|
/* Open the BCD*/
|
2016-01-19 18:21:54 +00:00
|
|
|
Status = BmOpenDataStore(&BcdHandle);
|
2016-01-20 02:58:39 +00:00
|
|
|
if (!NT_SUCCESS(Status))
|
2016-01-19 18:21:54 +00:00
|
|
|
{
|
2016-01-20 02:58:39 +00:00
|
|
|
goto Quickie;
|
|
|
|
}
|
2016-01-19 18:21:54 +00:00
|
|
|
|
2016-01-20 02:58:39 +00:00
|
|
|
/* Get the recovery sequence list */
|
|
|
|
Status = BlGetBootOptionGuidList(BootEntry->BcdData,
|
|
|
|
BcdLibraryObjectList_RecoverySequence,
|
|
|
|
&RecoverySequence,
|
|
|
|
&SequenceCount);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
goto Quickie;
|
|
|
|
}
|
2016-01-19 18:21:54 +00:00
|
|
|
|
2016-01-20 02:58:39 +00:00
|
|
|
/* Get the sequence of boot entries out of it */
|
|
|
|
Status = BmGetBootSequence(BcdHandle,
|
|
|
|
RecoverySequence,
|
|
|
|
SequenceCount,
|
|
|
|
BL_APPLICATION_ENTRY_RECOVERY,
|
|
|
|
&Sequence,
|
|
|
|
&Count);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
goto Quickie;
|
|
|
|
}
|
2016-01-19 18:21:54 +00:00
|
|
|
|
2016-01-20 02:58:39 +00:00
|
|
|
/* Was the BCD open? */
|
|
|
|
if (BcdHandle)
|
|
|
|
{
|
|
|
|
/* Close it */
|
|
|
|
BmCloseDataStore(BcdHandle);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Now go over every entry in the sequence */
|
|
|
|
for (i = 0; i < Count; ++i)
|
|
|
|
{
|
|
|
|
/* Check the code for this recovery launch */
|
|
|
|
if (LaunchCode == 2 || LaunchCode == 5)
|
|
|
|
{
|
|
|
|
/* Remove the override if there is one, and set it to 4 */
|
|
|
|
BlRemoveBootOption(Sequence[i]->BcdData, BcdLibraryInteger_DisplayMessageOverride);
|
|
|
|
BlAppendBootOptionInteger(Sequence[i],
|
|
|
|
BcdLibraryInteger_DisplayMessageOverride,
|
|
|
|
4);
|
2016-01-19 18:21:54 +00:00
|
|
|
}
|
2016-01-20 02:58:39 +00:00
|
|
|
else if (LaunchCode == 3)
|
|
|
|
{
|
|
|
|
/* Remove the override if there is one, and set it to 10 */
|
|
|
|
BlRemoveBootOption(Sequence[i]->BcdData, BcdLibraryInteger_DisplayMessageOverride);
|
|
|
|
BlAppendBootOptionInteger(Sequence[i],
|
|
|
|
BcdLibraryInteger_DisplayMessageOverride,
|
|
|
|
10);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Launch the boot entry for this part of the recovery sequence */
|
|
|
|
Status = BmpLaunchBootEntry(Sequence[i], NULL, LaunchCode, FALSE);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2016-01-19 18:21:54 +00:00
|
|
|
|
2016-01-20 02:58:39 +00:00
|
|
|
Quickie:
|
|
|
|
/* Did we have a sequence of entries? */
|
|
|
|
if (Sequence)
|
|
|
|
{
|
|
|
|
/* Loop through each one */
|
|
|
|
for (RecoveryIndex = 0; RecoveryIndex < Count; RecoveryIndex++)
|
2016-01-19 18:21:54 +00:00
|
|
|
{
|
2016-01-20 02:58:39 +00:00
|
|
|
/* Does this index have an allocated boot entry? */
|
|
|
|
RecoveryEntry = Sequence[RecoveryIndex];
|
|
|
|
if (RecoveryEntry)
|
|
|
|
{
|
|
|
|
/* Destroy it */
|
|
|
|
BlDestroyBootEntry(RecoveryEntry);
|
|
|
|
}
|
2016-01-19 18:21:54 +00:00
|
|
|
}
|
2016-01-20 02:58:39 +00:00
|
|
|
|
|
|
|
/* Free the sequence itself */
|
|
|
|
BlMmFreeHeap(Sequence);
|
2016-01-19 18:21:54 +00:00
|
|
|
}
|
|
|
|
|
2016-01-20 02:58:39 +00:00
|
|
|
/* Was there a sequence list? */
|
|
|
|
if (RecoverySequence)
|
|
|
|
{
|
|
|
|
/* Free it */
|
|
|
|
BlMmFreeHeap(RecoverySequence);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Return back to caller */
|
2016-01-19 18:21:54 +00:00
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
ULONG
|
|
|
|
BmDisplayDumpError (
|
|
|
|
_In_ PBL_LOADED_APPLICATION_ENTRY BootEntry,
|
|
|
|
_In_ ULONG LaunchCode
|
|
|
|
)
|
|
|
|
{
|
|
|
|
ULONG BootError;
|
|
|
|
NTSTATUS Status;
|
|
|
|
BOOLEAN Restart, NoError;
|
|
|
|
|
2016-01-20 02:58:39 +00:00
|
|
|
/* Assume we'll just reboot */
|
|
|
|
BootError = Reboot;
|
2016-01-19 18:21:54 +00:00
|
|
|
|
2016-01-20 02:58:39 +00:00
|
|
|
/* Should we reboot? */
|
2016-01-19 18:21:54 +00:00
|
|
|
Status = BlGetBootOptionBoolean(BlpApplicationEntry.BcdData,
|
|
|
|
BcdLibraryBoolean_RestartOnFailure,
|
|
|
|
&Restart);
|
|
|
|
if ((NT_SUCCESS(Status)) && (Restart))
|
|
|
|
{
|
|
|
|
return BootError;
|
|
|
|
}
|
|
|
|
|
2016-01-20 02:58:39 +00:00
|
|
|
/* Should we not show errors, and thus, reboot? */
|
2016-01-19 18:21:54 +00:00
|
|
|
Status = BlGetBootOptionBoolean(BlpApplicationEntry.BcdData,
|
|
|
|
BcdBootMgrBoolean_NoErrorDisplay,
|
|
|
|
&NoError);
|
|
|
|
if ((NT_SUCCESS(Status)) && (NoError))
|
|
|
|
{
|
|
|
|
return BootError;
|
|
|
|
}
|
|
|
|
|
2016-01-20 02:58:39 +00:00
|
|
|
/* Is there an internal boot error? */
|
2016-01-19 18:21:54 +00:00
|
|
|
if (BmpInternalBootError)
|
|
|
|
{
|
2016-01-20 02:58:39 +00:00
|
|
|
/* Return it -- but it's a pointer? */
|
2018-03-18 15:10:41 +00:00
|
|
|
return (ULONG_PTR)BmpInternalBootError; // ???
|
2016-01-19 18:21:54 +00:00
|
|
|
}
|
|
|
|
|
2016-01-20 02:58:39 +00:00
|
|
|
/* Otherwise, show the menu to see what to do */
|
2016-01-19 18:21:54 +00:00
|
|
|
EfiPrintf(L"Error menu not yet implemented\r\n");
|
|
|
|
return BootError;
|
|
|
|
}
|
|
|
|
|
|
|
|
NTSTATUS
|
|
|
|
BmpCreateDevices (
|
|
|
|
_In_ PBL_LOADED_APPLICATION_ENTRY BootEntry
|
|
|
|
)
|
|
|
|
{
|
|
|
|
ULONG NextOffset, DataOffset, ListOffset;
|
|
|
|
PBL_BCD_OPTION Option, ListOption;
|
|
|
|
BcdElementType ElementType;
|
|
|
|
PBCD_DEVICE_OPTION BcdDevice;
|
|
|
|
|
2016-01-20 02:58:39 +00:00
|
|
|
/* Starting at offset 0, loop every BCD option */
|
2016-01-19 18:21:54 +00:00
|
|
|
NextOffset = 0;
|
|
|
|
do
|
|
|
|
{
|
2016-01-20 02:58:39 +00:00
|
|
|
/* Get the current option, and its offset */
|
2016-01-19 18:21:54 +00:00
|
|
|
Option = (PBL_BCD_OPTION)((ULONG_PTR)BootEntry->BcdData + NextOffset);
|
|
|
|
NextOffset = Option->NextEntryOffset;
|
|
|
|
|
2016-01-20 02:58:39 +00:00
|
|
|
/* If it's empty, ignore it */
|
2016-01-19 18:21:54 +00:00
|
|
|
if (Option->Empty)
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2016-01-20 02:58:39 +00:00
|
|
|
/* If it's not a device option, ignore it */
|
2016-01-19 18:21:54 +00:00
|
|
|
ElementType.PackedValue = Option->Type;
|
|
|
|
if (ElementType.Format != BCD_TYPE_DEVICE)
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2016-01-20 02:58:39 +00:00
|
|
|
/* Get the data offset */
|
2016-01-19 18:21:54 +00:00
|
|
|
DataOffset = Option->DataOffset;
|
|
|
|
|
2016-01-20 02:58:39 +00:00
|
|
|
/* Extract the device out of it */
|
2016-01-19 18:21:54 +00:00
|
|
|
BcdDevice = (PBCD_DEVICE_OPTION)((ULONG_PTR)BootEntry->BcdData + DataOffset);
|
2016-01-20 02:58:39 +00:00
|
|
|
|
|
|
|
/* If the device is already fully specified, no need to build it */
|
2016-01-19 18:21:54 +00:00
|
|
|
if (!(BcdDevice->DeviceDescriptor.Flags & 1))
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2016-01-20 02:58:39 +00:00
|
|
|
/* Otherwise, check if there's any list options as well */
|
2016-01-19 18:21:54 +00:00
|
|
|
ListOption = NULL;
|
|
|
|
ListOffset = Option->ListOffset;
|
|
|
|
if (Option->ListOffset)
|
|
|
|
{
|
|
|
|
ListOption = (PBL_BCD_OPTION)((ULONG_PTR)BootEntry->BcdData + ListOffset);
|
|
|
|
}
|
|
|
|
|
2016-01-20 02:58:39 +00:00
|
|
|
/* And now call BlCreateDevice to build the full device descriptor */
|
2016-01-19 18:21:54 +00:00
|
|
|
EfiPrintf(L"Unspecified devices not yet supported: %p\r\n", ListOption);
|
|
|
|
return STATUS_NOT_SUPPORTED;
|
|
|
|
} while (NextOffset != 0);
|
|
|
|
|
2016-01-20 02:58:39 +00:00
|
|
|
/* Devices created successfully */
|
2016-01-19 18:21:54 +00:00
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
NTSTATUS
|
|
|
|
BmpTransferExecution (
|
|
|
|
_In_ PBL_LOADED_APPLICATION_ENTRY BootEntry,
|
|
|
|
_Out_ PULONG LaunchCode,
|
|
|
|
_Out_ PBOOLEAN Recover
|
|
|
|
)
|
|
|
|
{
|
|
|
|
PWCHAR AppPath;
|
|
|
|
NTSTATUS Status;
|
|
|
|
PBL_DEVICE_DESCRIPTOR AppDevice;
|
|
|
|
BL_RETURN_ARGUMENTS ReturnArgs;
|
|
|
|
BOOLEAN AdvancedOptions;
|
2016-01-20 01:28:50 +00:00
|
|
|
ULONG AppHandle;
|
2016-01-19 18:21:54 +00:00
|
|
|
|
2016-01-20 02:58:39 +00:00
|
|
|
/* Get the application path */
|
2016-01-19 18:21:54 +00:00
|
|
|
Status = BlGetBootOptionString(BootEntry->BcdData,
|
|
|
|
BcdLibraryString_ApplicationPath,
|
|
|
|
&AppPath);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
2016-01-20 02:58:39 +00:00
|
|
|
/* If we couldn't find one, set this to NULL */
|
2016-01-19 18:21:54 +00:00
|
|
|
AppPath = NULL;
|
|
|
|
}
|
|
|
|
|
2016-01-20 02:58:39 +00:00
|
|
|
/* Check if this is a PXE startup.com */
|
2016-01-19 18:21:54 +00:00
|
|
|
if (BootEntry->Flags & BL_APPLICATION_ENTRY_STARTUP)
|
|
|
|
{
|
|
|
|
#if BL_NET_SUPPORT
|
2016-01-20 02:58:39 +00:00
|
|
|
/* Do soft reboot to launch it */
|
2016-01-19 18:21:54 +00:00
|
|
|
Status = BlNetSoftReboot(BootEntry);
|
|
|
|
#else
|
|
|
|
EfiPrintf(L"Net boot not supported\r\n");
|
|
|
|
Status = STATUS_NOT_SUPPORTED;
|
|
|
|
#endif
|
2016-01-20 02:58:39 +00:00
|
|
|
/* Nothing else for us to do */
|
2016-01-19 18:21:54 +00:00
|
|
|
goto Quickie;
|
|
|
|
}
|
|
|
|
|
2016-01-20 02:58:39 +00:00
|
|
|
/* Loop as long as boot was not cancelled */
|
2016-01-19 18:21:54 +00:00
|
|
|
do
|
|
|
|
{
|
2016-01-20 02:58:39 +00:00
|
|
|
/* Load the boot application */
|
2016-01-19 18:21:54 +00:00
|
|
|
Status = BlImgLoadBootApplication(BootEntry, &AppHandle);
|
2016-01-20 02:58:39 +00:00
|
|
|
|
|
|
|
/* Did we not find it? */
|
2016-01-19 18:21:54 +00:00
|
|
|
if (Status == STATUS_NOT_FOUND)
|
|
|
|
{
|
2016-01-20 02:58:39 +00:00
|
|
|
/* Get the device for the boot application */
|
2016-01-19 18:21:54 +00:00
|
|
|
Status = BlGetBootOptionDevice(BootEntry->BcdData,
|
|
|
|
BcdLibraryDevice_ApplicationDevice,
|
|
|
|
&AppDevice,
|
|
|
|
NULL);
|
2017-02-04 19:45:38 +00:00
|
|
|
if (!NT_SUCCESS(Status))
|
2016-01-19 18:21:54 +00:00
|
|
|
{
|
2016-01-20 02:58:39 +00:00
|
|
|
/* Force re-enumeration */
|
2016-01-19 18:21:54 +00:00
|
|
|
Status = BlFwEnumerateDevice(AppDevice);
|
|
|
|
}
|
|
|
|
|
2016-01-20 02:58:39 +00:00
|
|
|
/* Did re-enumeration work? */
|
2016-01-19 18:21:54 +00:00
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
2016-01-20 02:58:39 +00:00
|
|
|
/* Nope, raise a fatal error */
|
|
|
|
BmFatalErrorEx(BL_FATAL_ERROR_APP_LOAD,
|
|
|
|
(ULONG_PTR)AppPath,
|
|
|
|
Status,
|
|
|
|
0,
|
|
|
|
0);
|
2016-01-19 18:21:54 +00:00
|
|
|
goto Quickie;
|
|
|
|
}
|
|
|
|
|
2016-01-20 02:58:39 +00:00
|
|
|
/* Yes, try booting it again */
|
2016-01-19 18:21:54 +00:00
|
|
|
Status = BlImgLoadBootApplication(BootEntry, &AppHandle);
|
|
|
|
}
|
|
|
|
|
2016-01-20 02:58:39 +00:00
|
|
|
/* Was boot cancelled?*/
|
2016-01-19 18:21:54 +00:00
|
|
|
if (Status == STATUS_CANCELLED)
|
|
|
|
{
|
2016-01-20 02:58:39 +00:00
|
|
|
/* Should we display the menu, or is there no launch sequence? */
|
2016-01-19 18:21:54 +00:00
|
|
|
if ((BmGetBootMenuPolicy(BootEntry) != MenuPolicyStandard) ||
|
|
|
|
!(MiscGetBootOption(BootEntry->BcdData,
|
|
|
|
BcdLibraryObjectList_RecoverySequence)))
|
|
|
|
{
|
2016-01-20 02:58:39 +00:00
|
|
|
/* Bail out, the menu will take care of it */
|
2016-01-19 18:21:54 +00:00
|
|
|
goto Quickie;
|
|
|
|
}
|
|
|
|
|
2016-01-20 02:58:39 +00:00
|
|
|
/* No menu and there's a sequence, launch it */
|
2016-01-19 18:21:54 +00:00
|
|
|
*LaunchCode = 4;
|
|
|
|
*Recover = TRUE;
|
|
|
|
goto Quickie;
|
|
|
|
}
|
|
|
|
|
2016-01-20 02:58:39 +00:00
|
|
|
/* STATUS_FVE_LOCKED_VOLUME -- bitlocker volume is locked */
|
2016-01-19 18:21:54 +00:00
|
|
|
if (Status == 0xC0210000)
|
|
|
|
{
|
2016-01-20 02:58:39 +00:00
|
|
|
/* Launch recovery mode */
|
2016-01-19 18:21:54 +00:00
|
|
|
*LaunchCode = 4;
|
|
|
|
*Recover = TRUE;
|
|
|
|
goto Quickie;
|
|
|
|
}
|
|
|
|
|
2016-01-20 02:58:39 +00:00
|
|
|
/* Was there some other error launching the boot application? */
|
2016-01-19 18:21:54 +00:00
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
2016-01-20 02:58:39 +00:00
|
|
|
/* Raise a fatal error */
|
|
|
|
BmFatalErrorEx(BL_FATAL_ERROR_APP_LOAD,
|
|
|
|
(ULONG_PTR)AppPath,
|
|
|
|
Status,
|
|
|
|
0,
|
|
|
|
0);
|
2016-01-19 18:21:54 +00:00
|
|
|
goto Quickie;
|
|
|
|
}
|
|
|
|
|
2016-01-20 02:58:39 +00:00
|
|
|
/* Zero out the return arguments */
|
2016-01-19 18:21:54 +00:00
|
|
|
RtlZeroMemory(&ReturnArgs, sizeof(ReturnArgs));
|
2016-01-20 02:58:39 +00:00
|
|
|
|
|
|
|
/* Log to ETW this launch */
|
2016-01-19 18:21:54 +00:00
|
|
|
//BmpLogApplicationLaunchEvent(&BootEntry->Guid, AppPath);
|
|
|
|
|
2016-01-20 02:58:39 +00:00
|
|
|
/* Launch the boot application*/
|
2016-01-19 18:21:54 +00:00
|
|
|
Status = BlImgStartBootApplication(AppHandle, &ReturnArgs);
|
|
|
|
|
|
|
|
#if BL_BITLOCKER_SUPPORT
|
2016-01-20 02:58:39 +00:00
|
|
|
/* Bitlocker stuff */
|
2016-01-19 18:21:54 +00:00
|
|
|
BlFveSecureBootCheckpointAppReturn(BootEntry, &ReturnArgs);
|
|
|
|
#endif
|
|
|
|
|
2016-01-20 02:58:39 +00:00
|
|
|
/* Log in the boot status log the launch */
|
2016-01-19 18:21:54 +00:00
|
|
|
//BlBsdLogEntry(1, 0x12, &BootEntry->Guid, 0x14);
|
|
|
|
|
2016-01-20 02:58:39 +00:00
|
|
|
/* Unloac the boot application if we've returned */
|
2016-01-19 18:21:54 +00:00
|
|
|
BlImgUnloadBootApplication(AppHandle);
|
|
|
|
|
2016-01-20 02:58:39 +00:00
|
|
|
/* Keep going unless STATUS_RESTART_BOOT_APPLICATION */
|
2016-01-19 18:21:54 +00:00
|
|
|
} while (Status != 0xC0000453);
|
|
|
|
|
2016-01-20 02:58:39 +00:00
|
|
|
/* We've come back. Assume we need to launch the recovery sequence */
|
2016-01-19 18:21:54 +00:00
|
|
|
*Recover = TRUE;
|
2016-01-20 02:58:39 +00:00
|
|
|
|
|
|
|
/* Why did we get back? */
|
2016-01-19 18:21:54 +00:00
|
|
|
if (ReturnArgs.Flags & 1)
|
|
|
|
{
|
2016-01-20 02:58:39 +00:00
|
|
|
/* Flag 1 -- should we display advanced options? */
|
2016-01-19 18:21:54 +00:00
|
|
|
Status = BlGetBootOptionBoolean(BootEntry->BcdData,
|
|
|
|
BcdLibraryBoolean_DisplayAdvancedOptions,
|
|
|
|
&AdvancedOptions);
|
|
|
|
if ((NT_SUCCESS(Status)) && (AdvancedOptions))
|
|
|
|
{
|
2016-01-20 02:58:39 +00:00
|
|
|
/* Yes, so return with code 2 */
|
2016-01-19 18:21:54 +00:00
|
|
|
*LaunchCode = 2;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2016-01-20 02:58:39 +00:00
|
|
|
/* No, return with code 1 */
|
2016-01-19 18:21:54 +00:00
|
|
|
*LaunchCode = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (ReturnArgs.Flags & 4)
|
|
|
|
{
|
2016-11-12 20:53:49 +00:00
|
|
|
/* Flag 4 -- unknown */
|
2016-01-19 18:21:54 +00:00
|
|
|
*LaunchCode = 1;
|
|
|
|
}
|
|
|
|
else if (ReturnArgs.Flags & 8)
|
|
|
|
{
|
2016-11-12 20:53:49 +00:00
|
|
|
/* Flag 5 -- unknown */
|
2016-01-19 18:21:54 +00:00
|
|
|
*LaunchCode = 5;
|
|
|
|
}
|
|
|
|
else if (ReturnArgs.Flags & 0x10)
|
|
|
|
{
|
2016-11-12 20:53:49 +00:00
|
|
|
/* Flag 6 -- unknown */
|
2016-01-19 18:21:54 +00:00
|
|
|
*LaunchCode = 6;
|
|
|
|
}
|
|
|
|
else if (ReturnArgs.Flags & 0x20)
|
|
|
|
{
|
2016-11-12 20:53:49 +00:00
|
|
|
/* Flag 7 -- unknown */
|
2016-01-19 18:21:54 +00:00
|
|
|
*LaunchCode = 7;
|
|
|
|
}
|
2016-01-20 02:58:39 +00:00
|
|
|
else if (ReturnArgs.Flags & BL_RETURN_ARGUMENTS_NO_PAE_FLAG)
|
2016-01-19 18:21:54 +00:00
|
|
|
{
|
2016-01-20 02:58:39 +00:00
|
|
|
/* PAE is not supported -- refuse to boot */
|
2016-01-19 18:21:54 +00:00
|
|
|
*Recover = FALSE;
|
2016-01-20 02:58:39 +00:00
|
|
|
BmFatalErrorEx(BL_FATAL_ERROR_NO_PAE, Status, 0, 0, 0);
|
2016-01-19 18:21:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Quickie:
|
2016-01-20 02:58:39 +00:00
|
|
|
/* All done, did we have an application path? */
|
2016-01-19 18:21:54 +00:00
|
|
|
if (AppPath)
|
|
|
|
{
|
2016-01-20 02:58:39 +00:00
|
|
|
/* Free it */
|
2016-01-19 18:21:54 +00:00
|
|
|
BlMmFreeHeap(AppPath);
|
|
|
|
}
|
|
|
|
|
2016-01-20 02:58:39 +00:00
|
|
|
/* Back to the caller now */
|
2016-01-19 18:21:54 +00:00
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
NTSTATUS
|
|
|
|
BmpLaunchBootEntry (
|
|
|
|
_In_ PBL_LOADED_APPLICATION_ENTRY BootEntry,
|
|
|
|
_Out_ PULONG EntryIndex,
|
|
|
|
_In_ ULONG LaunchCode,
|
|
|
|
_In_ BOOLEAN LaunchWinRe
|
|
|
|
)
|
|
|
|
{
|
|
|
|
HANDLE BcdHandle;
|
|
|
|
NTSTATUS Status;
|
|
|
|
GUID ObjectId;
|
2016-01-20 02:58:39 +00:00
|
|
|
BOOLEAN DoRecovery, AutoRecovery, DoSequence, RestartOnFailure;
|
2016-01-19 18:21:54 +00:00
|
|
|
ULONG ErrorCode;
|
2016-01-20 02:58:39 +00:00
|
|
|
BOOLEAN AdvancedOneTime, EditOneTime;
|
2016-01-19 18:21:54 +00:00
|
|
|
|
2016-01-20 02:58:39 +00:00
|
|
|
/* Check if this is the OS loader */
|
2016-01-19 18:21:54 +00:00
|
|
|
if (BootEntry->Flags & BL_APPLICATION_ENTRY_WINLOAD)
|
|
|
|
{
|
2016-01-20 02:58:39 +00:00
|
|
|
/* Check if one-time advanced options should be shown */
|
|
|
|
if (MiscGetBootOption(BootEntry->BcdData,
|
|
|
|
BcdOSLoaderBoolean_AdvancedOptionsOneTime))
|
2016-01-19 18:21:54 +00:00
|
|
|
{
|
2016-01-20 02:58:39 +00:00
|
|
|
/* Open the BCD */
|
2016-01-19 18:21:54 +00:00
|
|
|
BcdHandle = NULL;
|
|
|
|
Status = BmOpenDataStore(BcdHandle);
|
|
|
|
if (NT_SUCCESS(Status))
|
|
|
|
{
|
2016-01-20 02:58:39 +00:00
|
|
|
/* Delete the option from the BCD, so it doesn't happen again */
|
2016-01-19 18:21:54 +00:00
|
|
|
ObjectId = BootEntry->Guid;
|
2016-01-20 02:58:39 +00:00
|
|
|
BmPurgeOption(BcdHandle,
|
|
|
|
&ObjectId,
|
|
|
|
BcdOSLoaderBoolean_AdvancedOptionsOneTime);
|
2016-01-19 18:21:54 +00:00
|
|
|
BmCloseDataStore(BcdHandle);
|
|
|
|
}
|
|
|
|
}
|
2016-01-20 02:58:39 +00:00
|
|
|
|
|
|
|
/* Check if one-time options editor should be shown */
|
|
|
|
if (MiscGetBootOption(BootEntry->BcdData,
|
|
|
|
BcdOSLoaderBoolean_OptionsEditOneTime))
|
2016-01-19 18:21:54 +00:00
|
|
|
{
|
2016-01-20 02:58:39 +00:00
|
|
|
/* Open the BCD */
|
2016-01-19 18:21:54 +00:00
|
|
|
BcdHandle = NULL;
|
|
|
|
Status = BmOpenDataStore(BcdHandle);
|
|
|
|
if (NT_SUCCESS(Status))
|
|
|
|
{
|
2016-01-20 02:58:39 +00:00
|
|
|
/* Delete the option from the BCD, so it doesn't happen again */
|
2016-01-19 18:21:54 +00:00
|
|
|
ObjectId = BootEntry->Guid;
|
2016-01-20 02:58:39 +00:00
|
|
|
BmPurgeOption(BcdHandle,
|
|
|
|
&ObjectId,
|
|
|
|
BcdOSLoaderBoolean_OptionsEditOneTime);
|
2016-01-19 18:21:54 +00:00
|
|
|
BmCloseDataStore(BcdHandle);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
TryAgain:
|
2016-01-20 02:58:39 +00:00
|
|
|
/* Disable recovery mode */
|
2016-01-19 18:21:54 +00:00
|
|
|
DoRecovery = FALSE;
|
2016-01-20 02:58:39 +00:00
|
|
|
|
|
|
|
/* Store globally which entry we are trying to boot */
|
2016-01-19 18:21:54 +00:00
|
|
|
BmpSelectedBootEntry = BootEntry;
|
|
|
|
|
2016-01-20 02:58:39 +00:00
|
|
|
/* Create any devices that aren't yet fully defined for this boot entry */
|
2016-01-19 18:21:54 +00:00
|
|
|
Status = BmpCreateDevices(BootEntry);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
2016-01-20 02:58:39 +00:00
|
|
|
/* That failed -- can we launch the recovery environment? */
|
2016-01-19 18:21:54 +00:00
|
|
|
if (!LaunchWinRe)
|
|
|
|
{
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
2016-01-20 02:58:39 +00:00
|
|
|
/* Yes, so return with the WinRe launch code */
|
2016-01-19 18:21:54 +00:00
|
|
|
LaunchCode = 2;
|
|
|
|
goto Quickie;
|
|
|
|
}
|
|
|
|
|
2016-01-20 02:58:39 +00:00
|
|
|
/* Is this an OS loader/ */
|
2016-01-19 18:21:54 +00:00
|
|
|
if (BootEntry->Flags & BL_APPLICATION_ENTRY_WINLOAD)
|
|
|
|
{
|
2016-01-20 02:58:39 +00:00
|
|
|
/* Is the one-time advanced options menu option present? */
|
|
|
|
Status = BlGetBootOptionBoolean(BootEntry->BcdData,
|
|
|
|
BcdOSLoaderBoolean_AdvancedOptionsOneTime,
|
|
|
|
&AdvancedOneTime);
|
2016-01-19 18:21:54 +00:00
|
|
|
if (NT_SUCCESS(Status))
|
|
|
|
{
|
2016-01-20 02:58:39 +00:00
|
|
|
/* Is it turned on? */
|
2016-01-19 18:21:54 +00:00
|
|
|
if (AdvancedOneTime)
|
|
|
|
{
|
2016-01-20 02:58:39 +00:00
|
|
|
/* Set the option this once */
|
|
|
|
BlAppendBootOptionBoolean(BootEntry,
|
2018-02-05 00:01:38 +00:00
|
|
|
BcdLibraryBoolean_DisplayAdvancedOptions,
|
|
|
|
TRUE);
|
2016-01-19 18:21:54 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2016-01-20 02:58:39 +00:00
|
|
|
/* It's not, so disable the option if active */
|
|
|
|
BlRemoveBootOption(BootEntry->BcdData,
|
|
|
|
BcdLibraryBoolean_DisplayAdvancedOptions);
|
2016-01-19 18:21:54 +00:00
|
|
|
}
|
|
|
|
|
2016-01-20 02:58:39 +00:00
|
|
|
/* Remove the one-time option. We've already purged it earlier */
|
|
|
|
BlRemoveBootOption(BootEntry->BcdData,
|
|
|
|
BcdOSLoaderBoolean_AdvancedOptionsOneTime);
|
2016-01-19 18:21:54 +00:00
|
|
|
}
|
|
|
|
|
2016-01-20 02:58:39 +00:00
|
|
|
/* Is the one-time options editor menu option present? */
|
|
|
|
Status = BlGetBootOptionBoolean(BootEntry->BcdData,
|
|
|
|
BcdOSLoaderBoolean_OptionsEditOneTime,
|
|
|
|
&EditOneTime);
|
2016-01-19 18:21:54 +00:00
|
|
|
if (NT_SUCCESS(Status))
|
|
|
|
{
|
2016-01-20 02:58:39 +00:00
|
|
|
/* Is it turned on? */
|
|
|
|
if (EditOneTime)
|
2016-01-19 18:21:54 +00:00
|
|
|
{
|
2016-01-20 02:58:39 +00:00
|
|
|
/* Set the option this once */
|
|
|
|
BlAppendBootOptionBoolean(BootEntry,
|
2018-02-05 00:01:38 +00:00
|
|
|
BcdLibraryBoolean_DisplayOptionsEdit,
|
|
|
|
TRUE);
|
2016-01-19 18:21:54 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2016-01-20 02:58:39 +00:00
|
|
|
/* It's not, so disable the option if active */
|
|
|
|
BlRemoveBootOption(BootEntry->BcdData,
|
|
|
|
BcdLibraryBoolean_DisplayOptionsEdit);
|
2016-01-19 18:21:54 +00:00
|
|
|
}
|
|
|
|
|
2016-01-20 02:58:39 +00:00
|
|
|
/* Remove the one-time option. We've already purged it earlier */
|
|
|
|
BlRemoveBootOption(BootEntry->BcdData,
|
|
|
|
BcdOSLoaderBoolean_OptionsEditOneTime);
|
2016-01-19 18:21:54 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-01-20 02:58:39 +00:00
|
|
|
/* BCD handling done, transfer execution to this entry */
|
|
|
|
Status = BmpTransferExecution(BootEntry, &LaunchCode, &DoRecovery);
|
2016-01-19 18:21:54 +00:00
|
|
|
if (!LaunchWinRe)
|
|
|
|
{
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
2016-11-12 20:53:49 +00:00
|
|
|
/* Check if boot was successful, or cancelled and we're not doing WinRE */
|
2016-01-20 02:58:39 +00:00
|
|
|
if (((NT_SUCCESS(Status)) || (Status == STATUS_CANCELLED)) && !(DoRecovery))
|
2016-01-19 18:21:54 +00:00
|
|
|
{
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
2016-01-20 02:58:39 +00:00
|
|
|
/* Boot failed -- are we doing recovery? */
|
|
|
|
if (!DoRecovery)
|
2016-01-19 18:21:54 +00:00
|
|
|
{
|
2016-01-20 02:58:39 +00:00
|
|
|
/* Nope, bail out */
|
2016-01-19 18:21:54 +00:00
|
|
|
LaunchCode = 2;
|
|
|
|
goto Quickie;
|
|
|
|
}
|
|
|
|
|
|
|
|
Quickie:
|
2016-01-20 02:58:39 +00:00
|
|
|
/* Get the recovery sequence */
|
2016-01-19 18:21:54 +00:00
|
|
|
if (MiscGetBootOption(BootEntry->BcdData, BcdLibraryObjectList_RecoverySequence))
|
|
|
|
{
|
2016-01-20 02:58:39 +00:00
|
|
|
/* Check if the launch depends on auto-recovery being enabled or not */
|
2016-01-19 18:21:54 +00:00
|
|
|
if ((LaunchCode == 3) || (LaunchCode == 5) || (LaunchCode == 6))
|
|
|
|
{
|
2016-01-20 02:58:39 +00:00
|
|
|
Status = BlGetBootOptionBoolean(BootEntry->BcdData,
|
|
|
|
BcdLibraryBoolean_AutoRecoveryEnabled,
|
|
|
|
&AutoRecovery);
|
2016-01-19 18:21:54 +00:00
|
|
|
if (NT_SUCCESS(Status))
|
|
|
|
{
|
2016-01-20 02:58:39 +00:00
|
|
|
/* Override the setting */
|
2016-01-19 18:21:54 +00:00
|
|
|
DoRecovery = AutoRecovery;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2016-01-20 02:58:39 +00:00
|
|
|
/* There's no recovery setting */
|
2016-01-19 18:21:54 +00:00
|
|
|
DoRecovery = FALSE;
|
|
|
|
}
|
|
|
|
|
2016-01-20 02:58:39 +00:00
|
|
|
/* Check if we should restart on failure */
|
2016-01-19 18:21:54 +00:00
|
|
|
RestartOnFailure = FALSE;
|
2016-01-20 02:58:39 +00:00
|
|
|
BlGetBootOptionBoolean(BlpApplicationEntry.BcdData,
|
|
|
|
BcdLibraryBoolean_RestartOnFailure,
|
|
|
|
&RestartOnFailure);
|
|
|
|
|
|
|
|
/* Do the sequence if recovery is on, unless we should restart instead */
|
|
|
|
DoSequence = RestartOnFailure ? FALSE : DoRecovery;
|
2016-01-19 18:21:54 +00:00
|
|
|
while (1)
|
|
|
|
{
|
2016-01-20 02:58:39 +00:00
|
|
|
/* Are we doing the recovery sequence? */
|
|
|
|
if (DoSequence)
|
2016-01-19 18:21:54 +00:00
|
|
|
{
|
2016-01-20 02:58:39 +00:00
|
|
|
/* Because of automatic recovery? */
|
2016-01-19 18:21:54 +00:00
|
|
|
if (AutoRecovery)
|
|
|
|
{
|
2016-01-20 02:58:39 +00:00
|
|
|
#if BL_BITLOCKER_SUPPORT
|
|
|
|
/* Do bitlocker stuff */
|
|
|
|
BlFveRegisterBootEntryForTrustedWimBoot(BootEntry, TRUE);
|
|
|
|
#endif
|
2016-01-19 18:21:54 +00:00
|
|
|
}
|
|
|
|
|
2016-01-20 02:58:39 +00:00
|
|
|
/* Launch the recovery sequence*/
|
2016-01-19 18:21:54 +00:00
|
|
|
Status = BmLaunchRecoverySequence(BootEntry, LaunchCode);
|
|
|
|
|
2016-01-20 02:58:39 +00:00
|
|
|
/* Was it launched automatically? */
|
2016-01-19 18:21:54 +00:00
|
|
|
if (AutoRecovery)
|
|
|
|
{
|
2016-01-20 02:58:39 +00:00
|
|
|
#if BL_BITLOCKER_SUPPORT
|
|
|
|
/* Do bitlocker stuff */
|
|
|
|
BlFveRegisterBootEntryForTrustedWimBoot(BootEntry, FALSE);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* No need to do this again */
|
2016-01-19 18:21:54 +00:00
|
|
|
AutoRecovery = FALSE;
|
|
|
|
}
|
|
|
|
|
2016-01-20 02:58:39 +00:00
|
|
|
/* Did the recovery sequence work? */
|
2016-01-19 18:21:54 +00:00
|
|
|
if (NT_SUCCESS(Status))
|
|
|
|
{
|
2016-01-20 02:58:39 +00:00
|
|
|
/* All good */
|
2016-01-19 18:21:54 +00:00
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2016-01-20 02:58:39 +00:00
|
|
|
/* Remove the sequence, don't do it again */
|
2016-01-19 18:21:54 +00:00
|
|
|
BlRemoveBootOption(BootEntry->BcdData, BcdLibraryObjectList_RecoverySequence);
|
|
|
|
}
|
|
|
|
|
2016-01-20 02:58:39 +00:00
|
|
|
/* Recovery sequence also failed, show fatal error */
|
2016-01-19 18:21:54 +00:00
|
|
|
if (!BmpInternalBootError)
|
|
|
|
{
|
2016-01-20 02:58:39 +00:00
|
|
|
BmFatalErrorEx(BL_FATAL_ERROR_GENERIC, Status, 0, 0, 0);
|
2016-01-19 18:21:54 +00:00
|
|
|
}
|
|
|
|
|
2016-01-20 02:58:39 +00:00
|
|
|
/* Display the error menu */
|
2016-01-19 18:21:54 +00:00
|
|
|
ErrorCode = BmDisplayDumpError(BootEntry, LaunchCode);
|
|
|
|
BmErrorPurge();
|
|
|
|
|
2016-01-20 02:58:39 +00:00
|
|
|
/* See what the user wants to do */
|
2016-01-19 18:21:54 +00:00
|
|
|
switch (ErrorCode)
|
|
|
|
{
|
2016-01-20 02:58:39 +00:00
|
|
|
case TryAgain:
|
|
|
|
/* Try again */
|
2016-01-19 18:21:54 +00:00
|
|
|
goto TryAgain;
|
2016-01-20 02:58:39 +00:00
|
|
|
|
|
|
|
case NextOs:
|
|
|
|
/* Boot the next entry*/
|
2016-01-19 18:21:54 +00:00
|
|
|
break;
|
2016-01-20 02:58:39 +00:00
|
|
|
|
|
|
|
case OsSelection:
|
|
|
|
/* Cancel the boot*/
|
2016-01-19 18:21:54 +00:00
|
|
|
return STATUS_CANCELLED;
|
2016-01-20 02:58:39 +00:00
|
|
|
|
|
|
|
case RecoverOem:
|
|
|
|
/* Custom OEM recovery -- open the BCD */
|
2016-01-19 18:21:54 +00:00
|
|
|
Status = BmOpenDataStore(BcdHandle);
|
|
|
|
if (NT_SUCCESS(Status))
|
|
|
|
{
|
2016-01-20 02:58:39 +00:00
|
|
|
/* See what the custom sequence is */
|
2016-01-19 18:21:54 +00:00
|
|
|
Status = BmProcessCustomAction(BcdHandle, NULL);
|
|
|
|
}
|
2016-01-20 02:58:39 +00:00
|
|
|
|
|
|
|
/* All done, close the BCD */
|
2016-01-19 18:21:54 +00:00
|
|
|
if (BcdHandle)
|
|
|
|
{
|
|
|
|
BmCloseDataStore(BcdHandle);
|
|
|
|
}
|
|
|
|
return Status;
|
2016-01-20 02:58:39 +00:00
|
|
|
|
|
|
|
case AdvancedOptions:
|
|
|
|
/* Show the advanced options next iteration */
|
2018-02-05 00:01:38 +00:00
|
|
|
BlAppendBootOptionBoolean(BootEntry,
|
|
|
|
BcdOSLoaderBoolean_AdvancedOptionsOneTime,
|
|
|
|
TRUE);
|
2016-01-19 18:21:54 +00:00
|
|
|
goto TryAgain;
|
2016-01-20 02:58:39 +00:00
|
|
|
|
|
|
|
case BootOptions:
|
|
|
|
/* Show the options editor next iteration */
|
2018-02-05 00:01:38 +00:00
|
|
|
BlAppendBootOptionBoolean(BootEntry,
|
|
|
|
BcdOSLoaderBoolean_OptionsEditOneTime,
|
|
|
|
TRUE);
|
2016-01-19 18:21:54 +00:00
|
|
|
goto TryAgain;
|
2016-01-20 02:58:39 +00:00
|
|
|
|
|
|
|
case Recover:
|
|
|
|
/* Try the recovery sequence next time*/
|
|
|
|
DoSequence = TRUE;
|
2016-01-19 18:21:54 +00:00
|
|
|
LaunchCode = 1;
|
|
|
|
goto TryAgain;
|
2016-01-20 02:58:39 +00:00
|
|
|
|
2016-01-19 18:21:54 +00:00
|
|
|
default:
|
2016-01-20 02:58:39 +00:00
|
|
|
/* Something unknown */
|
2016-01-19 18:21:54 +00:00
|
|
|
return STATUS_CANCELLED;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-01-20 02:58:39 +00:00
|
|
|
/* We are booting the next OS, so return success as to not kill the boot */
|
2016-01-19 18:21:54 +00:00
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2015-09-04 14:16:56 +00:00
|
|
|
/*++
|
|
|
|
* @name BmMain
|
|
|
|
*
|
|
|
|
* The BmMain function implements the Windows Boot Application entrypoint for
|
|
|
|
* the Boot Manager.
|
|
|
|
*
|
|
|
|
* @param BootParameters
|
|
|
|
* Pointer to the Boot Application Parameter Block.
|
|
|
|
*
|
|
|
|
* @return NT_SUCCESS if the image was loaded correctly, relevant error code
|
|
|
|
* otherwise.
|
|
|
|
*
|
|
|
|
*--*/
|
|
|
|
NTSTATUS
|
2016-02-03 19:12:34 +00:00
|
|
|
NTAPI
|
2015-09-04 14:16:56 +00:00
|
|
|
BmMain (
|
|
|
|
_In_ PBOOT_APPLICATION_PARAMETER_BLOCK BootParameters
|
|
|
|
)
|
|
|
|
{
|
2016-01-05 06:09:22 +00:00
|
|
|
NTSTATUS Status, LibraryStatus;
|
2015-09-04 14:16:56 +00:00
|
|
|
BL_LIBRARY_PARAMETERS LibraryParameters;
|
2015-09-07 23:48:21 +00:00
|
|
|
PBL_RETURN_ARGUMENTS ReturnArguments;
|
|
|
|
PGUID AppIdentifier;
|
2016-01-08 06:03:55 +00:00
|
|
|
HANDLE BcdHandle, ResumeBcdHandle;
|
2016-01-05 06:09:22 +00:00
|
|
|
PBL_BCD_OPTION EarlyOptions;
|
2016-01-06 04:43:23 +00:00
|
|
|
PWCHAR Stylesheet;
|
2016-01-08 06:19:14 +00:00
|
|
|
BOOLEAN XmlLoaded, DisableIntegrity, TestSigning, PersistBootSequence;
|
2016-01-09 05:39:18 +00:00
|
|
|
BOOLEAN RebootOnError, CustomActions;
|
|
|
|
ULONG SequenceId;
|
|
|
|
PBL_LOADED_APPLICATION_ENTRY BootEntry;
|
|
|
|
PGUID SequenceList;
|
|
|
|
ULONG SequenceListCount;
|
|
|
|
PBL_LOADED_APPLICATION_ENTRY* BootSequence;
|
|
|
|
ULONG BootIndex;
|
|
|
|
BOOLEAN ExitBootManager;
|
|
|
|
BOOLEAN BootFailed;
|
|
|
|
BOOLEAN BootOk;
|
|
|
|
ULONG SequenceCount;
|
|
|
|
BOOLEAN GetEntry;
|
2016-01-08 15:01:11 +00:00
|
|
|
EfiPrintf(L"ReactOS UEFI Boot Manager Initializing...\r\n");
|
2015-09-07 23:48:21 +00:00
|
|
|
|
|
|
|
/* Reading the BCD can change this later on */
|
|
|
|
RebootOnError = FALSE;
|
2015-09-06 03:02:56 +00:00
|
|
|
|
|
|
|
/* Save the start/end-of-POST time */
|
2017-07-25 17:30:21 +00:00
|
|
|
#if defined(_M_IX86) || defined(_M_X64)
|
2015-09-06 03:02:56 +00:00
|
|
|
ApplicationStartTime = __rdtsc();
|
2017-07-25 17:30:21 +00:00
|
|
|
#else
|
|
|
|
EfiPrintf(L"No time source defined for this platform\r\n");
|
|
|
|
ApplicationStartTime = 0;
|
|
|
|
#endif
|
2015-09-06 03:02:56 +00:00
|
|
|
PostTime = ApplicationStartTime;
|
|
|
|
|
|
|
|
/* Setup the boot library parameters for this application */
|
|
|
|
BlSetupDefaultParameters(&LibraryParameters);
|
|
|
|
LibraryParameters.TranslationType = BlNone;
|
|
|
|
LibraryParameters.LibraryFlags = 0x400 | 0x8;
|
|
|
|
LibraryParameters.MinimumAllocationCount = 16;
|
|
|
|
LibraryParameters.MinimumHeapSize = 512 * 1024;
|
|
|
|
|
|
|
|
/* Initialize the boot library */
|
2015-09-04 14:16:56 +00:00
|
|
|
Status = BlInitializeLibrary(BootParameters, &LibraryParameters);
|
2015-09-07 23:48:21 +00:00
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
/* Check for failure due to invalid application entry */
|
|
|
|
if (Status != STATUS_INVALID_PARAMETER_9)
|
|
|
|
{
|
|
|
|
/* Specifically print out what happened */
|
|
|
|
EfiPrintf(L"BlInitializeLibrary failed 0x%x\r\n", Status);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Go to exit path */
|
|
|
|
goto Quickie;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Get the application identifier */
|
|
|
|
AppIdentifier = BlGetApplicationIdentifier();
|
|
|
|
if (!AppIdentifier)
|
|
|
|
{
|
|
|
|
/* None was given, so set our default one */
|
|
|
|
AppIdentifier = (PGUID)&GUID_WINDOWS_BOOTMGR;
|
|
|
|
}
|
[BOOTLIB]:
- WIP work to begin reading, parsing, mounting and loading the BCD hive into a data store. Untested, has missing pieces.
- Implement BlFileSet/GetInformation, BlFileReadEx, BlFileReadAtOffsetEx and helper structures/functions. Document multiple previously unknown/magic flags.
- Implement BlMmAllocatePhysicalPages. Stub BlMmFreePhysicalPages.
- Implement MmUnmapVirtualAddress, BlMmUnmapVirtualAddressEx when operating in real mode.
- Implement ImgpGetFileSize, ImgpReadFileAtOffset, ImgpOpenFile, ImgpCloseFile, BlImgAllocateImageBuffer, BlImgLoadImageWithProgress2.
- Implement BdDebuggerInitialized, BlBdDebuggerEnabled, BlStatusPrint, BlStatuserror. Stub BlBdPullRemoteFile.
- Implement BlGetBootOptionDevice.
- Implement BiReferenceHive, BiDereferenceHive, BiCloseKey, BiOpenKey. Stub BiFlushKey, BiLoadHive.
- Implement BiAddStoreFromFile, BcdOpenStoreFromFile.
- Stub BlUtlUpdateProcess and BlResourceFindMessage.
- Other misc. cleanups.
[BOOTMGR]:
- Implement BmpFatalErrorMessageFilter, BmErrorPurge, BmpErrorLog, BmFatalErrorEx.
- Implement BmpFwGetFullPath.
- Implement BmOpenDataStore.
- Stub BmOpenBootIni
svn path=/trunk/; revision=69447
2015-10-04 21:07:12 +00:00
|
|
|
|
2015-09-07 23:48:21 +00:00
|
|
|
/* Save our identifier */
|
|
|
|
BmApplicationIdentifier = *AppIdentifier;
|
|
|
|
|
|
|
|
/* Initialize the file system to open a handle to our root boot directory */
|
|
|
|
BmFwInitializeBootDirectoryPath();
|
|
|
|
|
[BOOTLIB]:
- WIP work to begin reading, parsing, mounting and loading the BCD hive into a data store. Untested, has missing pieces.
- Implement BlFileSet/GetInformation, BlFileReadEx, BlFileReadAtOffsetEx and helper structures/functions. Document multiple previously unknown/magic flags.
- Implement BlMmAllocatePhysicalPages. Stub BlMmFreePhysicalPages.
- Implement MmUnmapVirtualAddress, BlMmUnmapVirtualAddressEx when operating in real mode.
- Implement ImgpGetFileSize, ImgpReadFileAtOffset, ImgpOpenFile, ImgpCloseFile, BlImgAllocateImageBuffer, BlImgLoadImageWithProgress2.
- Implement BdDebuggerInitialized, BlBdDebuggerEnabled, BlStatusPrint, BlStatuserror. Stub BlBdPullRemoteFile.
- Implement BlGetBootOptionDevice.
- Implement BiReferenceHive, BiDereferenceHive, BiCloseKey, BiOpenKey. Stub BiFlushKey, BiLoadHive.
- Implement BiAddStoreFromFile, BcdOpenStoreFromFile.
- Stub BlUtlUpdateProcess and BlResourceFindMessage.
- Other misc. cleanups.
[BOOTMGR]:
- Implement BmpFatalErrorMessageFilter, BmErrorPurge, BmpErrorLog, BmFatalErrorEx.
- Implement BmpFwGetFullPath.
- Implement BmOpenDataStore.
- Stub BmOpenBootIni
svn path=/trunk/; revision=69447
2015-10-04 21:07:12 +00:00
|
|
|
/* Load and initialize the boot configuration database (BCD) */
|
2015-10-05 07:25:27 +00:00
|
|
|
Status = BmOpenDataStore(&BcdHandle);
|
2016-01-05 06:09:22 +00:00
|
|
|
if (NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
/* Copy the boot options */
|
|
|
|
Status = BlCopyBootOptions(BlpApplicationEntry.BcdData, &EarlyOptions);
|
|
|
|
if (NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
/* Update them */
|
|
|
|
Status = BmpUpdateApplicationOptions(BcdHandle);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
/* Log a fatal error */
|
|
|
|
BmFatalErrorEx(BL_FATAL_ERROR_BCD_PARSE,
|
|
|
|
(ULONG_PTR)L"\\BCD",
|
|
|
|
Status,
|
|
|
|
0,
|
|
|
|
0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef _SECURE_BOOT
|
|
|
|
/* Initialize the secure boot machine policy */
|
|
|
|
Status = BmSecureBootInitializeMachinePolicy();
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
BmFatalErrorEx(BL_FATAL_ERROR_SECURE_BOOT, Status, 0, 0, 0);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* Copy the library parameters and add the re-initialization flag */
|
|
|
|
RtlCopyMemory(&LibraryParameters,
|
|
|
|
&BlpLibraryParameters,
|
|
|
|
sizeof(LibraryParameters));
|
|
|
|
LibraryParameters.LibraryFlags |= (BL_LIBRARY_FLAG_REINITIALIZE_ALL |
|
|
|
|
BL_LIBRARY_FLAG_REINITIALIZE);
|
|
|
|
|
|
|
|
/* Now that we've parsed the BCD, re-initialize the library */
|
|
|
|
LibraryStatus = BlInitializeLibrary(BootParameters, &LibraryParameters);
|
|
|
|
if (!NT_SUCCESS(LibraryStatus) && (NT_SUCCESS(Status)))
|
|
|
|
{
|
|
|
|
Status = LibraryStatus;
|
|
|
|
}
|
2015-09-07 23:48:21 +00:00
|
|
|
|
2016-01-06 04:43:23 +00:00
|
|
|
/* Initialize firmware-specific memory regions */
|
2016-01-07 05:30:18 +00:00
|
|
|
BmFwMemoryInitialize();
|
2016-01-06 04:43:23 +00:00
|
|
|
|
|
|
|
/* Initialize the boot status data log (BSD) */
|
|
|
|
BmpInitializeBootStatusDataLog();
|
|
|
|
|
|
|
|
/* Find our XSL stylesheet */
|
|
|
|
Stylesheet = BlResourceFindHtml();
|
|
|
|
if (!Stylesheet)
|
|
|
|
{
|
|
|
|
/* Awe, no XML. This is actually fatal lol. Can't boot without XML. */
|
|
|
|
Status = STATUS_NOT_FOUND;
|
|
|
|
EfiPrintf(L"BlResourceFindMessage failed 0x%x\r\n", STATUS_NOT_FOUND);
|
|
|
|
goto Quickie;
|
|
|
|
}
|
|
|
|
|
2016-01-07 23:43:15 +00:00
|
|
|
/* Initialize the XML Engine (as a side-effect, resets cursor) */
|
|
|
|
Status = BlXmiInitialize(Stylesheet);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
EfiPrintf(L"\r\nBlXmiInitialize failed 0x%x\r\n", Status);
|
|
|
|
goto Failure;
|
|
|
|
}
|
|
|
|
XmlLoaded = TRUE;
|
2016-01-20 06:59:12 +00:00
|
|
|
|
2016-01-07 23:43:15 +00:00
|
|
|
/* Check if there's an active bitmap visible */
|
|
|
|
if (!BlDisplayValidOemBitmap())
|
|
|
|
{
|
|
|
|
/* Nope, make the screen black using BGFX */
|
|
|
|
if (!NT_SUCCESS(BmpBgDisplayClearScreen(0xFF000000)))
|
|
|
|
{
|
|
|
|
/* BGFX isn't active, use standard display */
|
|
|
|
BlDisplayClearScreen();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef _BIT_LOCKER_
|
|
|
|
/* Bitlocker will take over screen UI if enabled */
|
|
|
|
FveDisplayScreen = BmFveDisplayScreen;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* Check if any bypass options are enabled */
|
|
|
|
BlImgQueryCodeIntegrityBootOptions(&BlpApplicationEntry,
|
2016-01-08 06:19:14 +00:00
|
|
|
&DisableIntegrity,
|
|
|
|
&TestSigning);
|
2016-01-07 23:43:15 +00:00
|
|
|
if (!DisableIntegrity)
|
|
|
|
{
|
|
|
|
/* Integrity checks are enabled, so validate our signature */
|
|
|
|
Status = BmFwVerifySelfIntegrity();
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
/* Signature invalid, fail boot */
|
Three tiny squirmy subtle bugs combined themselves with the bug that was just fixed to make bootmgfw believe it was being booted from a raw removable disk (floppy). Because bootmgfw now correctly enumerates boot devices and detects the DVD/CDROM media, it could no longer 'find itself', believing it was on a floppy.
[BOOTLIB]: When failing to find a block device, keep going searching for more, instead of giving up (critical, because the CDROM FAT12 image is now device path #1, not #0).
[BOOTMGR]: Correctly use the right logical operator in EfiInitpGetDeviceNode to get the deepest-level media device node. We now get the CDROM node, not the raw node.
[CDMAKE]: Don't actually create an EFI/BOOT directory on the CDROM itself, but rather in the FAT12 image. Otherwise, this can confuse UEFI implementations to boot the boot manager off the raw CDROM, instead of the FAT12 image on the CDROM.
svn path=/trunk/; revision=70542
2016-01-08 01:18:08 +00:00
|
|
|
goto Failure;
|
2016-01-07 23:43:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-02-05 19:55:49 +00:00
|
|
|
|
|
|
|
/* TEST MODE */
|
|
|
|
EfiPrintf(L"Performing memory allocator tests...\r\n");
|
|
|
|
{
|
|
|
|
NTSTATUS Status;
|
2017-02-05 22:02:24 +00:00
|
|
|
PHYSICAL_ADDRESS PhysicalAddress, PhysicalAddress2;
|
2017-02-05 19:55:49 +00:00
|
|
|
|
|
|
|
/* Allocate 1 physical page */
|
|
|
|
PhysicalAddress.QuadPart = 0;
|
|
|
|
Status = BlMmAllocatePhysicalPages(&PhysicalAddress, BlLoaderData, 1, 0, 1);
|
2017-02-05 22:02:24 +00:00
|
|
|
if (Status != STATUS_SUCCESS)
|
|
|
|
{
|
|
|
|
EfiPrintf(L"FAIL: Allocation status: %lx at address: %llx\r\n", Status, PhysicalAddress.QuadPart);
|
|
|
|
EfiStall(100000000);
|
|
|
|
}
|
2017-02-05 19:55:49 +00:00
|
|
|
|
2017-02-05 22:02:24 +00:00
|
|
|
/* Write some data */
|
2017-02-05 22:17:07 +00:00
|
|
|
*(PULONG)((ULONG_PTR)PhysicalAddress.QuadPart) = 0x55555151;
|
2017-02-05 21:50:14 +00:00
|
|
|
|
2017-02-05 22:02:24 +00:00
|
|
|
/* Free it */
|
2017-02-05 21:50:14 +00:00
|
|
|
Status = BlMmFreePhysicalPages(PhysicalAddress);
|
2017-02-05 22:02:24 +00:00
|
|
|
if (Status != STATUS_SUCCESS)
|
|
|
|
{
|
|
|
|
EfiPrintf(L"FAIL: Memory free status: %lx\r\n", Status);
|
|
|
|
EfiStall(100000000);
|
|
|
|
}
|
2017-02-05 19:55:49 +00:00
|
|
|
|
2017-02-05 22:02:24 +00:00
|
|
|
/* Allocate a page again */
|
|
|
|
PhysicalAddress2.QuadPart = 0;
|
|
|
|
Status = BlMmAllocatePhysicalPages(&PhysicalAddress2, BlLoaderData, 1, 0, 1);
|
|
|
|
if (Status != STATUS_SUCCESS)
|
|
|
|
{
|
|
|
|
EfiPrintf(L"FAIL: Allocation status: %lx at address: %llx\r\n", Status, PhysicalAddress2.QuadPart);
|
|
|
|
EfiStall(100000000);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* It should've given us the same page, since we freed it */
|
|
|
|
if (PhysicalAddress.QuadPart != PhysicalAddress2.QuadPart)
|
|
|
|
{
|
|
|
|
EfiPrintf(L"FAIL: Non-matching addresses: %llx %llx\r\n", PhysicalAddress.QuadPart, PhysicalAddress2.QuadPart);
|
|
|
|
EfiStall(100000000);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* The data should still be there, since zero-ing is not on for bootmgr */
|
2017-02-05 22:17:07 +00:00
|
|
|
if (*(PULONG)((ULONG_PTR)PhysicalAddress2.QuadPart) != 0x55555151)
|
2017-02-05 22:02:24 +00:00
|
|
|
{
|
2017-02-05 22:17:07 +00:00
|
|
|
EfiPrintf(L"FAIL: Non-matching data: %lx %lx\r\n", 0x55555151, *(PULONG)((ULONG_PTR)PhysicalAddress2.QuadPart));
|
2017-02-05 22:02:24 +00:00
|
|
|
EfiStall(100000000);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* And free the second page again */
|
|
|
|
Status = BlMmFreePhysicalPages(PhysicalAddress);
|
|
|
|
if (Status != STATUS_SUCCESS)
|
|
|
|
{
|
|
|
|
EfiPrintf(L"FAIL: Memory free status: %lx\r\n", Status);
|
|
|
|
EfiStall(100000000);
|
|
|
|
}
|
|
|
|
}
|
2017-02-05 19:55:49 +00:00
|
|
|
|
2016-01-08 06:03:55 +00:00
|
|
|
/* Write out the first XML tag */
|
|
|
|
BlXmiWrite(L"<bootmgr/>");
|
2016-01-07 23:43:15 +00:00
|
|
|
|
2016-11-12 20:53:49 +00:00
|
|
|
/* Check for factory reset */
|
2016-01-08 06:03:55 +00:00
|
|
|
BlSecureBootCheckForFactoryReset();
|
|
|
|
|
|
|
|
/* Load the revocation list */
|
|
|
|
Status = BmFwRegisterRevocationList();
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
goto Failure;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Register our custom progress routine */
|
|
|
|
BlUtlRegisterProgressRoutine();
|
|
|
|
|
|
|
|
/* Display state is not currently cached */
|
|
|
|
BmDisplayStateCached = FALSE;
|
|
|
|
|
2016-01-08 15:01:11 +00:00
|
|
|
/* Check if we need to resume from hibernate */
|
2016-01-08 06:03:55 +00:00
|
|
|
Status = BmResumeFromHibernate(&ResumeBcdHandle);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
goto Failure;
|
|
|
|
}
|
2016-01-07 23:43:15 +00:00
|
|
|
|
2016-01-08 06:19:14 +00:00
|
|
|
#ifdef BL_NET_SUPPORT
|
|
|
|
/* Register multicast printing routine */
|
|
|
|
BlUtlRegisterMulticastRoutine();
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* Check if restart on failure is enabled */
|
|
|
|
BlGetBootOptionBoolean(BlpApplicationEntry.BcdData,
|
|
|
|
BcdLibraryBoolean_RestartOnFailure,
|
|
|
|
&RebootOnError);
|
|
|
|
|
|
|
|
/* Check if the boot sequence is persisted */
|
|
|
|
Status = BlGetBootOptionBoolean(BlpApplicationEntry.BcdData,
|
|
|
|
BcdBootMgrBoolean_PersistBootSequence,
|
|
|
|
&PersistBootSequence);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
/* It usually is */
|
|
|
|
PersistBootSequence = TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Check if there's custom actions to take */
|
|
|
|
Status = BlGetBootOptionBoolean(BlpApplicationEntry.BcdData,
|
|
|
|
BcdBootMgrBoolean_ProcessCustomActionsFirst,
|
|
|
|
&CustomActions);
|
|
|
|
if ((NT_SUCCESS(Status)) && (CustomActions))
|
|
|
|
{
|
2016-11-12 20:53:49 +00:00
|
|
|
/* We don't support this yet */
|
2016-01-08 06:19:14 +00:00
|
|
|
EfiPrintf(L"Not implemented\r\n");
|
|
|
|
Status = STATUS_NOT_IMPLEMENTED;
|
|
|
|
goto Failure;
|
|
|
|
}
|
|
|
|
|
2016-01-20 03:53:59 +00:00
|
|
|
//BlResourceFindMessage(BM_MSG_TEST);
|
|
|
|
|
2016-01-08 06:19:14 +00:00
|
|
|
/* At last, enter the boot selection stage */
|
|
|
|
SequenceId = 0;
|
2016-01-09 05:39:18 +00:00
|
|
|
GetEntry = FALSE;
|
|
|
|
BootFailed = FALSE;
|
|
|
|
SequenceList = NULL;
|
|
|
|
BootSequence = NULL;
|
|
|
|
SequenceCount = 0;
|
|
|
|
while (1)
|
|
|
|
{
|
|
|
|
/* We don't have a boot entry nor a sequence ID */
|
|
|
|
BootEntry = NULL;
|
|
|
|
BootOk = FALSE;
|
|
|
|
|
|
|
|
/* Do we have a hardcoded boot sequence set? */
|
|
|
|
if (!(BootSequence) && !(GetEntry))
|
|
|
|
{
|
|
|
|
/* Not yet, read the BCD to see if one is there */
|
|
|
|
Status = BlGetBootOptionGuidList(BlpApplicationEntry.BcdData,
|
|
|
|
BcdBootMgrObjectList_BootSequence,
|
|
|
|
&SequenceList,
|
|
|
|
&SequenceListCount);
|
|
|
|
if (NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
/* A GUID list for the boot sequence is set. Extract it */
|
|
|
|
Status = BmGetBootSequence(BcdHandle,
|
|
|
|
SequenceList,
|
|
|
|
SequenceListCount,
|
2016-01-18 16:54:44 +00:00
|
|
|
BL_APPLICATION_ENTRY_FIXED_SEQUENCE,
|
2016-01-09 05:39:18 +00:00
|
|
|
&BootSequence,
|
|
|
|
&SequenceCount);
|
|
|
|
if (NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
/* Don't get stuck in a loop repeating this sequence */
|
|
|
|
BlRemoveBootOption(BlpApplicationEntry.BcdData,
|
|
|
|
BcdBootMgrObjectList_BootSequence);
|
|
|
|
|
|
|
|
/* But do check if we should persist it */
|
|
|
|
if (PersistBootSequence)
|
|
|
|
{
|
|
|
|
/* Yes -- so go select an entry now */
|
|
|
|
GetEntry = TRUE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* We shouldn't, so wipe it from the BCD too */
|
|
|
|
Status = BmPurgeOption(BcdHandle,
|
|
|
|
&BmApplicationIdentifier,
|
|
|
|
BcdBootMgrObjectList_BootSequence);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
/* Well that failed */
|
|
|
|
goto LoopQuickie;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* No boot entry sequence for us */
|
|
|
|
BootSequence = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Do we have a sequence active, and are we still processing it? */
|
|
|
|
if ((BootSequence) && ((GetEntry) || (SequenceId < SequenceCount)))
|
|
|
|
{
|
|
|
|
/* Extract the next entry in the sequence */
|
|
|
|
BootEntry = BootSequence[SequenceId];
|
|
|
|
BootSequence[SequenceId] = NULL;
|
|
|
|
|
|
|
|
/* Move to the next entry for next time */
|
|
|
|
SequenceId++;
|
|
|
|
|
|
|
|
/* Unless there won't be a a next time? */
|
|
|
|
if (SequenceId == SequenceCount)
|
|
|
|
{
|
|
|
|
/* Clean up, it's the last entry */
|
|
|
|
BlMmFreeHeap(BootSequence);
|
|
|
|
BootSequence = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Get the selected boot entry from the user */
|
|
|
|
ExitBootManager = FALSE;
|
|
|
|
Status = BmpGetSelectedBootEntry(BcdHandle,
|
|
|
|
&BootEntry,
|
|
|
|
&BootIndex,
|
|
|
|
&ExitBootManager);
|
|
|
|
if (!(NT_SUCCESS(Status)) || (ExitBootManager))
|
|
|
|
{
|
|
|
|
/* Selection failed, or user wants to exit */
|
|
|
|
goto LoopQuickie;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Did we have a BCD open? */
|
|
|
|
if (BcdHandle)
|
|
|
|
{
|
|
|
|
/* Close it, we'll be opening a new one */
|
|
|
|
BmCloseDataStore(BcdHandle);
|
|
|
|
BcdHandle = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Launch the selected entry */
|
|
|
|
Status = BmpLaunchBootEntry(BootEntry, &BootIndex, 0, TRUE);
|
|
|
|
if (NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
/* Boot worked, uncache display and process the bad memory list */
|
|
|
|
BmDisplayStateCached = FALSE;
|
|
|
|
BmpProcessBadMemory();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Boot failed -- was it user driven? */
|
|
|
|
if (Status != STATUS_CANCELLED)
|
|
|
|
{
|
|
|
|
/* Nope, remember that booting failed */
|
|
|
|
BootFailed = TRUE;
|
|
|
|
goto LoopQuickie;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Yes -- the display is still valid */
|
|
|
|
BmDisplayStateCached = TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Reopen the BCD */
|
|
|
|
Status = BmOpenDataStore(&BcdHandle);
|
2016-01-08 06:19:14 +00:00
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
2016-01-09 05:39:18 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Put the BCD options back into our entry */
|
|
|
|
BlReplaceBootOptions(&BlpApplicationEntry, EarlyOptions);
|
|
|
|
|
|
|
|
/* Update our options one more time */
|
|
|
|
Status = BmpUpdateApplicationOptions(BcdHandle);
|
|
|
|
if (NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
/* Boot was 100% OK */
|
|
|
|
BootOk = TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
LoopQuickie:
|
|
|
|
/* Did we have a boot entry? */
|
|
|
|
if (BootEntry)
|
|
|
|
{
|
|
|
|
/* We can destroy it now */
|
|
|
|
BlDestroyBootEntry(BootEntry);
|
2016-01-08 06:19:14 +00:00
|
|
|
}
|
|
|
|
|
2016-01-09 05:39:18 +00:00
|
|
|
/* Is this the success path? */
|
2016-01-08 06:19:14 +00:00
|
|
|
if (NT_SUCCESS(Status))
|
|
|
|
{
|
2016-01-09 05:39:18 +00:00
|
|
|
/* Did we actually boot something? */
|
|
|
|
if (!BootOk)
|
|
|
|
{
|
|
|
|
/* Bope, fail out */
|
|
|
|
break;
|
|
|
|
}
|
2016-01-08 06:19:14 +00:00
|
|
|
}
|
|
|
|
|
2016-01-09 05:39:18 +00:00
|
|
|
/* This is the failure path... should we reboot? */
|
2016-01-08 06:19:14 +00:00
|
|
|
if (RebootOnError)
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
2016-01-09 05:39:18 +00:00
|
|
|
};
|
2015-09-07 23:48:21 +00:00
|
|
|
|
2016-01-07 23:43:15 +00:00
|
|
|
Failure:
|
2016-01-09 05:39:18 +00:00
|
|
|
if (!BootFailed)
|
2016-01-05 06:09:22 +00:00
|
|
|
{
|
2016-01-09 05:39:18 +00:00
|
|
|
/* Check if we got here due to an internal error */
|
|
|
|
if (BmpInternalBootError)
|
2016-01-05 06:09:22 +00:00
|
|
|
{
|
2016-01-09 05:39:18 +00:00
|
|
|
/* If XML is available, display the error */
|
|
|
|
if (XmlLoaded)
|
|
|
|
{
|
|
|
|
//BmDisplayDumpError(0, 0);
|
|
|
|
//BmErrorPurge();
|
|
|
|
}
|
2016-01-05 06:09:22 +00:00
|
|
|
|
2016-01-09 05:39:18 +00:00
|
|
|
/* Don't do a fatal error -- return back to firmware */
|
|
|
|
goto Quickie;
|
|
|
|
}
|
2016-01-05 06:09:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Log a general fatal error once we're here */
|
|
|
|
BmFatalErrorEx(BL_FATAL_ERROR_GENERIC, Status, 0, 0, 0);
|
|
|
|
|
2015-09-07 23:48:21 +00:00
|
|
|
Quickie:
|
|
|
|
/* Check if we should reboot */
|
|
|
|
if ((RebootOnError) ||
|
|
|
|
(BlpApplicationEntry.Flags & BL_APPLICATION_ENTRY_REBOOT_ON_ERROR))
|
|
|
|
{
|
|
|
|
/* Reboot the box */
|
|
|
|
BlFwReboot();
|
|
|
|
Status = STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Return back to the caller with the error argument encoded */
|
|
|
|
ReturnArguments = (PVOID)((ULONG_PTR)BootParameters + BootParameters->ReturnArgumentsOffset);
|
|
|
|
ReturnArguments->Version = BL_RETURN_ARGUMENTS_VERSION;
|
|
|
|
ReturnArguments->Status = Status;
|
|
|
|
|
2016-01-08 15:01:11 +00:00
|
|
|
/* Tear down the boot library */
|
2015-09-07 23:48:21 +00:00
|
|
|
BlDestroyLibrary();
|
|
|
|
}
|
2015-09-04 14:16:56 +00:00
|
|
|
|
2015-09-07 23:48:21 +00:00
|
|
|
/* Return back status */
|
2015-09-04 14:16:56 +00:00
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|