https://git.reactos.org/?p=reactos.git;a=commitdiff;h=9ec85c29e31206918868e…
commit 9ec85c29e31206918868e05beff71fa4ecb47559
Author: Alex Ionescu <aionescu(a)gmail.com>
AuthorDate: Sun Feb 4 16:01:38 2018 -0800
Commit: Alex Ionescu <aionescu(a)gmail.com>
CommitDate: Sun Feb 4 16:01:38 2018 -0800
[ROSLOAD]: Continue work on target preparation OslPrepareTarget 2/104.
[ROSLOAD]: Stubplement OslpCheckForcedFailure, OslpGetSetBootStatusData,
OslSetBootStatusData, OslGetBootStatusData.
[ROSLOAD]: Stub OslpInitializeBootStatusDataLog, OslpReadWriteBootStatusData.
[BOOTLIB]: Fix BlAppendBootOptionString to accept an actual BCD ID instead of
hardcoding LibraryPath.
[BOOTLIB]: Fix BlAppendBootOptionBoolean to accept an actual BOOLEAN value instead of
hardcoding TRUE.
[BOOTLIB]: Implement BlDeviceIsVirtualPartitionDevice.
[BOOTLIB]: Add missing BcdOSLoaderInteger_ForceFailure BCD value. Add
BCDE_OSLOADER_TYPE_BOOT_STATUS_POLICY based on BcdEdit.exe and Geoff Chappel site.
---
boot/environ/app/bootmgr/bootmgr.c | 18 +-
boot/environ/app/rosload/rosload.c | 554 ++++++++++++++++++++++++++++++++++++-
boot/environ/app/rosload/rosload.h | 6 +
boot/environ/include/bcd.h | 20 +-
boot/environ/include/bl.h | 14 +-
boot/environ/lib/io/device.c | 33 +++
boot/environ/lib/misc/bcdopt.c | 8 +-
7 files changed, 632 insertions(+), 21 deletions(-)
diff --git a/boot/environ/app/bootmgr/bootmgr.c b/boot/environ/app/bootmgr/bootmgr.c
index b63e63b201..85d501b310 100644
--- a/boot/environ/app/bootmgr/bootmgr.c
+++ b/boot/environ/app/bootmgr/bootmgr.c
@@ -1357,7 +1357,9 @@ BmpPopulateBootEntryList (
L"\\Windows\\System32\\winload.efi";
/* Add the path to the boot entry */
- Status = BlAppendBootOptionString(BootEntry, LoaderPath);
+ Status = BlAppendBootOptionString(BootEntry,
+
BcdLibraryString_ApplicationPath,
+ LoaderPath);
if (!NT_SUCCESS(Status))
{
goto Quickie;
@@ -2511,7 +2513,8 @@ TryAgain:
{
/* Set the option this once */
BlAppendBootOptionBoolean(BootEntry,
- BcdLibraryBoolean_DisplayAdvancedOptions);
+ BcdLibraryBoolean_DisplayAdvancedOptions,
+ TRUE);
}
else
{
@@ -2536,7 +2539,8 @@ TryAgain:
{
/* Set the option this once */
BlAppendBootOptionBoolean(BootEntry,
- BcdLibraryBoolean_DisplayOptionsEdit);
+ BcdLibraryBoolean_DisplayOptionsEdit,
+ TRUE);
}
else
{
@@ -2686,12 +2690,16 @@ Quickie:
case AdvancedOptions:
/* Show the advanced options next iteration */
- BlAppendBootOptionBoolean(BootEntry,
BcdOSLoaderBoolean_AdvancedOptionsOneTime);
+ BlAppendBootOptionBoolean(BootEntry,
+ BcdOSLoaderBoolean_AdvancedOptionsOneTime,
+ TRUE);
goto TryAgain;
case BootOptions:
/* Show the options editor next iteration */
- BlAppendBootOptionBoolean(BootEntry,
BcdOSLoaderBoolean_OptionsEditOneTime);
+ BlAppendBootOptionBoolean(BootEntry,
+ BcdOSLoaderBoolean_OptionsEditOneTime,
+ TRUE);
goto TryAgain;
case Recover:
diff --git a/boot/environ/app/rosload/rosload.c b/boot/environ/app/rosload/rosload.c
index 9eda2d31fe..65fa445c77 100644
--- a/boot/environ/app/rosload/rosload.c
+++ b/boot/environ/app/rosload/rosload.c
@@ -50,6 +50,88 @@ BOOLEAN OslImcProcessingValid;
ULONG OslFreeMemoryDesctiptorsListSize;
PVOID OslMemoryDescriptorBuffer;
+BcdObjectType BlpSbdiCurrentApplicationType;
+
+PRTL_BSD_DATA BsdBootStatusData;
+
+OSL_BSD_ITEM_TABLE_ENTRY OslpBootStatusFields[RtlBsdItemMax] =
+{
+ {
+ FIELD_OFFSET(RTL_BSD_DATA, Version),
+ sizeof(&BsdBootStatusData->Version)
+ }, // RtlBsdItemVersionNumber
+ {
+ FIELD_OFFSET(RTL_BSD_DATA, ProductType),
+ sizeof(&BsdBootStatusData->ProductType)
+ }, // RtlBsdItemProductType
+ {
+ FIELD_OFFSET(RTL_BSD_DATA, AabEnabled),
+ sizeof(&BsdBootStatusData->AabEnabled)
+ }, // RtlBsdItemAabEnabled
+ {
+ FIELD_OFFSET(RTL_BSD_DATA, AabTimeout),
+ sizeof(&BsdBootStatusData->AabTimeout)
+ }, // RtlBsdItemAabTimeout
+ {
+ FIELD_OFFSET(RTL_BSD_DATA, LastBootSucceeded),
+ sizeof(&BsdBootStatusData->LastBootSucceeded)
+ }, // RtlBsdItemBootGood
+ {
+ FIELD_OFFSET(RTL_BSD_DATA, LastBootShutdown),
+ sizeof(&BsdBootStatusData->LastBootShutdown)
+ }, // RtlBsdItemBootShutdown
+ {
+ FIELD_OFFSET(RTL_BSD_DATA, SleepInProgress),
+ sizeof(&BsdBootStatusData->SleepInProgress)
+ }, // RtlBsdSleepInProgress
+ {
+ FIELD_OFFSET(RTL_BSD_DATA, PowerTransition),
+ sizeof(&BsdBootStatusData->PowerTransition)
+ }, // RtlBsdPowerTransition
+ {
+ FIELD_OFFSET(RTL_BSD_DATA, BootAttemptCount),
+ sizeof(&BsdBootStatusData->BootAttemptCount)
+ }, // RtlBsdItemBootAttemptCount
+ {
+ FIELD_OFFSET(RTL_BSD_DATA, LastBootCheckpoint),
+ sizeof(&BsdBootStatusData->LastBootCheckpoint)
+ }, // RtlBsdItemBootCheckpoint
+ {
+ FIELD_OFFSET(RTL_BSD_DATA, LastBootId),
+ sizeof(&BsdBootStatusData->LastBootId)
+ }, // RtlBsdItemBootId
+ {
+ FIELD_OFFSET(RTL_BSD_DATA, LastSuccessfulShutdownBootId),
+ sizeof(&BsdBootStatusData->LastSuccessfulShutdownBootId)
+ }, // RtlBsdItemShutdownBootId
+ {
+ FIELD_OFFSET(RTL_BSD_DATA, LastReportedAbnormalShutdownBootId),
+ sizeof(&BsdBootStatusData->LastReportedAbnormalShutdownBootId)
+ }, // RtlBsdItemReportedAbnormalShutdownBootId
+ {
+ FIELD_OFFSET(RTL_BSD_DATA, ErrorInfo),
+ sizeof(&BsdBootStatusData->ErrorInfo)
+ }, // RtlBsdItemErrorInfo
+ {
+ FIELD_OFFSET(RTL_BSD_DATA, PowerButtonPressInfo),
+ sizeof(&BsdBootStatusData->PowerButtonPressInfo)
+ }, // RtlBsdItemPowerButtonPressInfo
+ {
+ FIELD_OFFSET(RTL_BSD_DATA, Checksum),
+ sizeof(&BsdBootStatusData->Checksum)
+ }, // RtlBsdItemChecksum
+};
+
+ULONG OslBootAttemptCount;
+ULONG OslBootCountUpdateRequestForAbort;
+ULONG OslBootAttemptMaximum;
+
+ULONG OslBootCountUpdateIncrement;
+
+BOOLEAN OslCurrentBootCheckpoint;
+BOOLEAN OslCurrentBootSucceeded;
+BOOLEAN OslCurrentBootShutdown;
+
/* FUNCTIONS *****************************************************************/
VOID
@@ -139,8 +221,8 @@ OslpRemoveInternalApplicationOptions (
_wcsupr(LoadString);
/* Remove the existing one */
- //BlRemoveBootOption(BlpApplicationEntry.BcdData,
- // BcdLibraryString_LoadOptionsString);
+ BlRemoveBootOption(BlpApplicationEntry.BcdData,
+ BcdLibraryString_LoadOptionsString);
/* Sanitize strings we don't want */
OslpSanitizeLoadOptionsString(LoadString,
L"DISABLE_INTEGRITY_CHECKS");
@@ -148,9 +230,9 @@ OslpRemoveInternalApplicationOptions (
OslpSanitizeLoadOptionsString(LoadString, L"DISABLEELAMDRIVERS");
/* Add the sanitized one back */
- //Status = BlAppendBootOptionsString(&BlpApplicationEntry,
- // BcdLibraryString_LoadOptionsString,
- // LoadString);
+ Status = BlAppendBootOptionString(&BlpApplicationEntry,
+ BcdLibraryString_LoadOptionsString,
+ LoadString);
/* Free the original BCD one */
BlMmFreeHeap(LoadString);
@@ -163,6 +245,288 @@ OslpRemoveInternalApplicationOptions (
return Status;
}
+NTSTATUS
+OslpCheckForcedFailure (
+ VOID
+ )
+{
+ ULONG64 ForceReason;
+ NTSTATUS Status;
+
+ /* Read the option */
+ Status = BlGetBootOptionInteger(BlpApplicationEntry.BcdData,
+ BcdOSLoaderInteger_ForceFailure,
+ &ForceReason);
+ if (NT_SUCCESS(Status) && (ForceReason < 4))
+ {
+ /* For reasons above 3, don't actually do anything */
+ if (ForceReason > 3)
+ {
+ return STATUS_SUCCESS;
+ }
+ }
+
+ /* If the option isn't there or invalid, always return success */
+ return STATUS_SUCCESS;
+}
+
+VOID
+OslpInitializeBootStatusDataLog (
+ VOID
+ )
+{
+ /* TODO */
+ return;
+}
+
+NTSTATUS
+OslpReadWriteBootStatusData (
+ _In_ BOOLEAN WriteAccess
+ )
+{
+ /* Are you trying to write? */
+ if (WriteAccess)
+ {
+ /* Have we already read? */
+ if (!BsdBootStatusData)
+ {
+ /* No -- fail */
+ return STATUS_UNSUCCESSFUL;
+ }
+ }
+ else if (BsdBootStatusData)
+ {
+ /* No -- you're trying to read and we already have the data: no-op */
+ return STATUS_SUCCESS;
+ }
+
+ /* TODO */
+ return STATUS_NOT_IMPLEMENTED;
+}
+
+NTSTATUS
+OslpGetSetBootStatusData (
+ _In_ BOOLEAN Read,
+ _In_ RTL_BSD_ITEM_TYPE DataClass,
+ _Out_ PVOID Buffer,
+ _Inout_ PULONG Size
+ )
+{
+ NTSTATUS Status;
+ ULONG Length, Offset;
+
+ /* No data has been read yet, fail */
+ if (!BsdBootStatusData)
+ {
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ /* Invalid data item, fail */
+ if (DataClass >= RtlBsdItemMax)
+ {
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ /* Capture the length and offset */
+ Length = OslpBootStatusFields[DataClass].Size;
+ Offset = OslpBootStatusFields[DataClass].Offset;
+
+ /* Make sure it doesn't overflow past the structure we've read */
+ if ((Length + Offset) > BsdBootStatusData->Version)
+ {
+ return STATUS_REVISION_MISMATCH;
+ }
+
+ /* Make sure we have enough space */
+ if (*Size >= Length)
+ {
+ /* We do -- is this a read? */
+ if (Read)
+ {
+ /* Yes, copy into the caller's buffer */
+ RtlCopyMemory(Buffer,
+ (PVOID)((ULONG_PTR)BsdBootStatusData + Offset),
+ Length);
+ }
+ else
+ {
+ /* It's a write, copy from caller's buffer */
+ RtlCopyMemory((PVOID)((ULONG_PTR)BsdBootStatusData + Offset),
+ Buffer,
+ Length);
+ }
+
+ /* Set success */
+ Status = STATUS_SUCCESS;
+ }
+ else
+ {
+ /* Return size needed and failure code */
+ *Size = Length;
+ Status = STATUS_BUFFER_TOO_SMALL;
+ }
+
+ /* All good */
+ return Status;
+}
+
+NTSTATUS
+OslSetBootStatusData (
+ _In_ BOOLEAN LastBootGood,
+ _In_ BOOLEAN LastBootShutdown,
+ _In_ BOOLEAN LastBootCheckpoint,
+ _In_ ULONG UpdateIncrement,
+ _In_ ULONG BootAttemptCount
+ )
+{
+ NTSTATUS Status;
+ ULONG Size;
+
+ /* Capture the BSD data in our globals, if needed */
+ Status = OslpReadWriteBootStatusData(FALSE);
+ if (!NT_SUCCESS(Status))
+ {
+ goto Quickie;
+ }
+
+ /* Write last boot shutdown */
+ Size = sizeof(LastBootShutdown);
+ Status = OslpGetSetBootStatusData(FALSE,
+ RtlBsdItemBootShutdown,
+ &LastBootShutdown,
+ &Size);
+ if (!NT_SUCCESS(Status))
+ {
+ goto Quickie;
+ }
+
+ /* Write last boot good */
+ Size = sizeof(LastBootGood);
+ Status = OslpGetSetBootStatusData(FALSE,
+ RtlBsdItemBootGood,
+ &LastBootGood,
+ &Size);
+ if (!NT_SUCCESS(Status))
+ {
+ goto Quickie;
+ }
+
+ /* Write last boot checkpoint */
+ Size = sizeof(LastBootCheckpoint);
+ Status = OslpGetSetBootStatusData(FALSE,
+ RtlBsdItemBootCheckpoint,
+ &LastBootCheckpoint,
+ &Size);
+ if (!NT_SUCCESS(Status))
+ {
+ goto Quickie;
+ }
+
+ /* Write boot attempt count */
+ Size = sizeof(BootAttemptCount);
+ Status = OslpGetSetBootStatusData(FALSE,
+ RtlBsdItemBootAttemptCount,
+ &BootAttemptCount,
+ &Size);
+ if (!NT_SUCCESS(Status))
+ {
+ goto Quickie;
+ }
+
+ /* TODO: Update Boot ID*/
+
+ /* Now write the data */
+ Status = OslpReadWriteBootStatusData(TRUE);
+
+Quickie:
+ return Status;
+}
+
+NTSTATUS
+OslGetBootStatusData (
+ _Out_ PBOOLEAN LastBootGood,
+ _Out_ PBOOLEAN LastBootShutdown,
+ _Out_ PBOOLEAN LastBootCheckpoint,
+ _Out_ PULONG LastBootId,
+ _Out_ PBOOLEAN BootGood,
+ _Out_ PBOOLEAN BootShutdown
+ )
+{
+ NTSTATUS Status;
+ ULONG Size;
+ ULONG64 BootStatusPolicy;
+ BOOLEAN localBootShutdown, localBootGood;
+
+ /* Capture the BSD data in our globals, if needed */
+ Status = OslpReadWriteBootStatusData(FALSE);
+ if (!NT_SUCCESS(Status))
+ {
+ goto Quickie;
+ }
+
+ /* Read the last boot ID */
+ Size = sizeof(*LastBootId);
+ Status = OslpGetSetBootStatusData(TRUE, RtlBsdItemBootId, LastBootId, &Size);
+ if (!NT_SUCCESS(Status))
+ {
+ /* Set to zero if we couldn't find it */
+ *LastBootId = 0;
+ }
+
+ /* Get the boot status policy */
+ Status = BlGetBootOptionInteger(BlpApplicationEntry.BcdData,
+ BcdOSLoaderInteger_BootStatusPolicy,
+ &BootStatusPolicy);
+ if (!NT_SUCCESS(Status))
+ {
+ /* Apply a default if none exists */
+ BootStatusPolicy = IgnoreShutdownFailures;
+ }
+
+ /* Check if this was a good shutdown */
+ Size = sizeof(localBootShutdown);
+ Status = OslpGetSetBootStatusData(TRUE,
+ RtlBsdItemBootShutdown,
+ &localBootShutdown,
+ &Size);
+ if (!NT_SUCCESS(Status))
+ {
+ goto Quickie;
+ }
+
+ /* Tell the caller */
+ *BootShutdown = localBootShutdown;
+
+ /* Check if this was a good boot */
+ Size = sizeof(localBootGood);
+ Status = OslpGetSetBootStatusData(TRUE,
+ RtlBsdItemBootGood,
+ &localBootGood,
+ &Size);
+ if (!NT_SUCCESS(Status))
+ {
+ goto Quickie;
+ }
+
+ /* Tell the caller*/
+ *BootGood = localBootGood;
+
+ /* TODO: Additional logic for checkpoints and such */
+ Status = STATUS_NOT_IMPLEMENTED;
+
+Quickie:
+ return Status;
+}
+
+BOOLEAN
+OslpAdvancedOptionsRequested (
+ VOID
+ )
+{
+ /* TODO */
+ return FALSE;
+}
+
NTSTATUS
OslPrepareTarget (
_Out_ PULONG ReturnFlags,
@@ -176,6 +540,16 @@ OslPrepareTarget (
SIZE_T RootLength, RootLengthWithSep;
ULONG i;
ULONG64 StartPerf, EndPerf;
+ RTL_BSD_DATA_POWER_TRANSITION PowerTransitionData;
+ PRTL_BSD_DATA_POWER_TRANSITION PowerBuffer;
+ ULONG OsDeviceHandle;
+ BOOLEAN LastBootGood, LastBootShutdown, LastBootCheckpoint;
+ ULONG BootId;
+ BOOLEAN BootGood, BootShutdown;
+ ULONG BsdSize;
+
+ /* Initialize locals */
+ PowerBuffer = NULL;
/* Assume no flags */
*ReturnFlags = 0;
@@ -214,9 +588,14 @@ OslPrepareTarget (
/* Capture the current TSC */
StartPerf = BlArchGetPerformanceCounter();
-#ifdef BL_TPM_SUPPORT
- BlpSbdiCurrentApplicationType = 0x10200003;
-#endif
+ /* Set our application type for SecureBoot/TPM purposes */
+ BlpSbdiCurrentApplicationType.Application.ObjectCode =
+ BCD_OBJECT_TYPE_APPLICATION;
+ BlpSbdiCurrentApplicationType.Application.ImageCode =
+ BCD_IMAGE_TYPE_BOOT_APP;
+ BlpSbdiCurrentApplicationType.Application.ApplicationCode =
+ BCD_APPLICATION_TYPE_OSLOADER;
+ BlpSbdiCurrentApplicationType.Application.Reserved = 0;
/* Register an error handler */
BlpStatusErrorHandler = OslBlStatusErrorHandler;
@@ -237,6 +616,7 @@ OslPrepareTarget (
Status = OslpRemoveInternalApplicationOptions();
if (!NT_SUCCESS(Status))
{
+ EfiPrintf(L"Fail here: %d\r\n", __LINE__);
goto Quickie;
}
@@ -247,6 +627,7 @@ OslPrepareTarget (
0);
if (!NT_SUCCESS(Status))
{
+ EfiPrintf(L"Fail here: %d\r\n", __LINE__);
goto Quickie;
}
@@ -265,6 +646,7 @@ OslPrepareTarget (
&SystemRoot);
if (!NT_SUCCESS(Status))
{
+ EfiPrintf(L"Fail here: %d\r\n", __LINE__);
goto Quickie;
}
@@ -286,6 +668,7 @@ OslPrepareTarget (
{
/* Bail out if we're out of memory */
Status = STATUS_NO_MEMORY;
+ EfiPrintf(L"Fail here: %d\r\n", __LINE__);
goto Quickie;
}
@@ -297,7 +680,162 @@ OslPrepareTarget (
BlMmFreeHeap(SystemRoot);
}
+ /* Initialize access to the BSD */
+ OslpInitializeBootStatusDataLog();
+
+ /* Check if we're supposed to fail on purpose */
+ Status = OslpCheckForcedFailure();
+ if (!NT_SUCCESS(Status))
+ {
+ EfiPrintf(L"Fail here: %d\r\n", __LINE__);
+ goto Quickie;
+ }
+
+ /* Always disable VGA mode */
+ Status = BlAppendBootOptionBoolean(&BlpApplicationEntry,
+ BcdOSLoaderBoolean_DisableVgaMode,
+ TRUE);
+ if (!NT_SUCCESS(Status))
+ {
+ EfiPrintf(L"Fail here: %d\r\n", __LINE__);
+ goto Quickie;
+ }
+
+ /* Get telemetry data from the last boot */
+ Status = OslGetBootStatusData(&LastBootGood,
+ &LastBootShutdown,
+ &LastBootCheckpoint,
+ &BootId,
+ &BootGood,
+ &BootShutdown);
+ if (!NT_SUCCESS(Status))
+ {
+ /* Assume this is the very first boot and everything went well */
+ BootId = 0;
+ LastBootGood = TRUE;
+ LastBootShutdown = TRUE;
+ LastBootCheckpoint = TRUE;
+ BootGood = TRUE;
+ BootShutdown = TRUE;
+
+ /* Set 0 boot attempts */
+ OslBootAttemptCount = 0;
+ }
+
+ /* Set more attempt variables to their initial state */
+ OslResetBootStatus = TRUE;
+ OslBootCountUpdateRequestForAbort = 0;
+
+ /* Read the current BSD data into the global buffer */
+ Status = OslpReadWriteBootStatusData(FALSE);
+ if (NT_SUCCESS(Status))
+ {
+ /* Get the power transition buffer from the BSD */
+ BsdSize = sizeof(PowerTransitionData);
+ Status = OslpGetSetBootStatusData(TRUE,
+ RtlBsdPowerTransition,
+ &PowerTransitionData,
+ &BsdSize);
+ if (NT_SUCCESS(Status))
+ {
+ /* Save the buffer */
+ PowerBuffer = &PowerTransitionData;
+ }
+ }
+
+ /* Check if this is VHD boot, which gets 3 boot attempts instead of 2 */
+ OslBootAttemptMaximum = 2;
+ OslBootAttemptMaximum += BlDeviceIsVirtualPartitionDevice(OslLoadDevice, NULL);
+
+ /* Check if the user wants to see the advanced menu */
+ if (!OslpAdvancedOptionsRequested())
+ {
+ /* The last boot failed more than the maximum */
+ if (!(LastBootGood) &&
+ (OslBootAttemptCount >= OslBootAttemptMaximum))
+ {
+ /* Return failure due to boot -- launch recovery */
+ *ReturnFlags |= 8;
+
+ /* Update the attempt count and status variables */
+ OslBootAttemptCount = OslBootAttemptMaximum - 1;
+ OslCurrentBootCheckpoint = LastBootCheckpoint;
+ OslCurrentBootSucceeded = FALSE;
+ OslCurrentBootShutdown = LastBootShutdown;
+
+ /* Crash with code 15 and abort boot */
+ OslFatalErrorEx(15, 0, 0, 0);
+ Status = STATUS_UNSUCCESSFUL;
+ EfiPrintf(L"Fail here: %d\r\n", __LINE__);
+ goto Quickie;
+ }
+
+ /* We never made it far enough, more than the maximum */
+ if (!(LastBootCheckpoint) &&
+ (OslBootAttemptCount >= OslBootAttemptMaximum))
+ {
+ /* Return crash/dirty shutdown during boot attempt */
+ *ReturnFlags |= 0x10;
+
+ /* Update the attempt count and status variables */
+ OslBootAttemptCount = OslBootAttemptMaximum - 1;
+ OslCurrentBootSucceeded = LastBootGood;
+ OslCurrentBootShutdown = LastBootShutdown;
+ OslCurrentBootCheckpoint = FALSE;
+
+ /* Crash with code 16 and abort boot */
+ OslFatalErrorEx(16, 0, 0, 0);
+ Status = STATUS_UNSUCCESSFUL;
+ EfiPrintf(L"Fail here: %d\r\n", __LINE__);
+ goto Quickie;
+ }
+
+ /* We failed to shutdown cleanly, and haven't booted yet */
+ if (!(LastBootShutdown) && !(OslBootAttemptCount))
+ {
+ /* Return crash/dirty shutdown */
+ *ReturnFlags |= 0x10;
+
+ /* There's no boot attempt, so only update shutdown variables */
+ OslCurrentBootSucceeded = LastBootGood;
+ OslCurrentBootShutdown = TRUE;
+ OslCurrentBootCheckpoint = LastBootCheckpoint;
+
+ /* Crash with code 16 and abort boot */
+ OslFatalErrorEx(16, 0, 0, 0);
+ Status = STATUS_UNSUCCESSFUL;
+ EfiPrintf(L"Fail here: %d\r\n", __LINE__);
+ goto Quickie;
+ }
+ }
+
+ /* Officially increment the number of boot attempts */
+ OslBootAttemptCount++;
+
+ /* No success yet, write to boot status file */
+ OslCurrentBootCheckpoint = FALSE;
+ OslCurrentBootSucceeded = FALSE;
+ OslCurrentBootShutdown = FALSE;
+ OslSetBootStatusData(FALSE,
+ FALSE,
+ FALSE,
+ OslBootCountUpdateIncrement,
+ OslBootAttemptCount);
+
+ /* Open the OS Loader Device for Read/Write access */
+ Status = BlpDeviceOpen(OslLoadDevice,
+ BL_DEVICE_READ_ACCESS | BL_DEVICE_WRITE_ACCESS,
+ 0,
+ &OsDeviceHandle);
+ if (!NT_SUCCESS(Status))
+ {
+ EfiPrintf(L"Fail here: %d\r\n", __LINE__);
+ goto Quickie;
+ }
+
+ /* That's all for now, folks */
Status = STATUS_NOT_IMPLEMENTED;
+ DBG_UNREFERENCED_LOCAL_VARIABLE(PowerBuffer);
/* Printf perf */
EndPerf = BlArchGetPerformanceCounter();
diff --git a/boot/environ/app/rosload/rosload.h b/boot/environ/app/rosload/rosload.h
index 5b19b4f161..c5cad3a493 100644
--- a/boot/environ/app/rosload/rosload.h
+++ b/boot/environ/app/rosload/rosload.h
@@ -34,6 +34,12 @@
/* STRUCTURES ****************************************************************/
+typedef struct _OSL_BSD_ITEM_TABLE_ENTRY
+{
+ ULONG Offset;
+ ULONG Size;
+} OSL_BSD_ITEM_TABLE_ENTRY;
+
/* FUNCTIONS *****************************************************************/
VOID
diff --git a/boot/environ/include/bcd.h b/boot/environ/include/bcd.h
index cee8a0c79e..d0b8641cd3 100644
--- a/boot/environ/include/bcd.h
+++ b/boot/environ/include/bcd.h
@@ -150,8 +150,9 @@ typedef enum BcdOSLoaderElementTypes
BcdOSLoaderBoolean_UsePlatformClock = 0x260000A2,
BcdOSLoaderBoolean_ForceLegacyPlatform = 0x260000A3,
BcdOSLoaderInteger_TscSyncPolicy = 0x250000A6,
- BcdOSLoaderBoolean_EmsEnabled = 0x260000b0,
- BcdOSLoaderInteger_DriverLoadFailurePolicy = 0x250000c1,
+ BcdOSLoaderBoolean_EmsEnabled = 0x260000B0,
+ BcdOSLoaderInteger_ForceFailure = 0x250000C0,
+ BcdOSLoaderInteger_DriverLoadFailurePolicy = 0x250000C1,
BcdOSLoaderInteger_BootMenuPolicy = 0x250000C2,
BcdOSLoaderBoolean_AdvancedOptionsOneTime = 0x260000C3,
BcdOSLoaderBoolean_OptionsEditOneTime = 0x260000C4, /* Undocumented */
@@ -195,7 +196,8 @@ typedef enum BcdBootMgrElementTypes
BcdBootMgrBoolean_PersistBootSequence = 0x26000031
} BcdBootMgrElementTypes;
-typedef enum _BcdResumeElementTypes {
+typedef enum _BcdResumeElementTypes
+{
Reserved1 = 0x21000001,
Reserved2 = 0x22000002,
BcdResumeBoolean_UseCustomSettings = 0x26000003,
@@ -204,6 +206,18 @@ typedef enum _BcdResumeElementTypes {
BcdResumeInteger_BootMenuPolicy = 0x25000008
} BcdResumeElementTypes;
+typedef enum _BCDE_OSLOADER_TYPE_BOOT_STATUS_POLICY
+{
+ DisplayAllFailures,
+ IgnoreAllFailures,
+ IgnoreShutdownFailures,
+ IgnoreBootFailures,
+ IgnoreCheckpointFailures,
+ DisplayShutdownFailures,
+ DisplayBootFailures,
+ DisplayCheckpointFailures
+} BCDE_OSLOADER_TYPE_BOOT_STATUS_POLICY;
+
/* Undocumented */
typedef enum BcdStartupElementTypes
{
diff --git a/boot/environ/include/bl.h b/boot/environ/include/bl.h
index 0e31deb8e9..82edfbcb00 100644
--- a/boot/environ/include/bl.h
+++ b/boot/environ/include/bl.h
@@ -923,7 +923,7 @@ typedef struct _BL_HARDDISK_DEVICE
typedef struct _BL_LOCAL_DEVICE
{
- ULONG Type;
+ BL_LOCAL_DEVICE_TYPE Type;
union
{
struct
@@ -933,6 +933,8 @@ typedef struct _BL_LOCAL_DEVICE
BL_HARDDISK_DEVICE HardDisk;
+ BL_HARDDISK_DEVICE VirtualHardDisk;
+
struct
{
PHYSICAL_ADDRESS ImageBase;
@@ -2008,7 +2010,8 @@ BlCopyBootOptions (
NTSTATUS
BlAppendBootOptionBoolean (
_In_ PBL_LOADED_APPLICATION_ENTRY AppEntry,
- _In_ ULONG OptionId
+ _In_ ULONG OptionId,
+ _In_ BOOLEAN Value
);
NTSTATUS
@@ -2021,6 +2024,7 @@ BlAppendBootOptionInteger (
NTSTATUS
BlAppendBootOptionString (
_In_ PBL_LOADED_APPLICATION_ENTRY AppEntry,
+ _In_ ULONG OptionId,
_In_ PWCHAR OptionString
);
@@ -2430,6 +2434,12 @@ BlDeviceClose (
_In_ ULONG DeviceId
);
+BOOLEAN
+BlDeviceIsVirtualPartitionDevice (
+ _In_ PBL_DEVICE_DESCRIPTOR InputDevice,
+ _Outptr_ PBL_DEVICE_DESCRIPTOR* VirtualDevice
+ );
+
NTSTATUS
BlpDeviceOpen (
_In_ PBL_DEVICE_DESCRIPTOR Device,
diff --git a/boot/environ/lib/io/device.c b/boot/environ/lib/io/device.c
index 76dbed0674..b4fd38e178 100644
--- a/boot/environ/lib/io/device.c
+++ b/boot/environ/lib/io/device.c
@@ -608,6 +608,39 @@ BlockIoGetInformation (
return STATUS_SUCCESS;
}
+BOOLEAN
+BlDeviceIsVirtualPartitionDevice (
+ _In_ PBL_DEVICE_DESCRIPTOR InputDevice,
+ _Outptr_ PBL_DEVICE_DESCRIPTOR* VirtualDevice
+ )
+{
+ BOOLEAN IsVirtual;
+ PBL_LOCAL_DEVICE ParentDisk;
+
+ /* Assume it isn't */
+ IsVirtual = FALSE;
+
+ /* Check if this is a partition device */
+ if ((InputDevice->DeviceType == LegacyPartitionDevice) ||
+ (InputDevice->DeviceType == PartitionDevice))
+ {
+ /* Check if the parent disk is a VHD */
+ ParentDisk = &InputDevice->Partition.Disk;
+ if (ParentDisk->Type == VirtualDiskDevice)
+ {
+ /* This is a virtual partition device -- does the caller want it? */
+ IsVirtual = TRUE;
+ if (VirtualDevice)
+ {
+ *VirtualDevice =
(PBL_DEVICE_DESCRIPTOR)(&ParentDisk->VirtualHardDisk + 1);
+ }
+ }
+ }
+
+ /* Return */
+ return IsVirtual;
+}
+
NTSTATUS
BlDeviceSetInformation (
_In_ ULONG DeviceId,
diff --git a/boot/environ/lib/misc/bcdopt.c b/boot/environ/lib/misc/bcdopt.c
index 0b4f82e467..1b1600182c 100644
--- a/boot/environ/lib/misc/bcdopt.c
+++ b/boot/environ/lib/misc/bcdopt.c
@@ -624,7 +624,8 @@ BlCopyBootOptions (
NTSTATUS
BlAppendBootOptionBoolean (
_In_ PBL_LOADED_APPLICATION_ENTRY AppEntry,
- _In_ ULONG OptionId
+ _In_ ULONG OptionId,
+ _In_ BOOLEAN Value
)
{
NTSTATUS Status;
@@ -642,7 +643,7 @@ BlAppendBootOptionBoolean (
Option->DataSize = sizeof(USHORT);
Option->Type = OptionId;
Option->DataOffset = sizeof(*Option);
- *(PBOOLEAN)(Option + 1) = TRUE;
+ *(PBOOLEAN)(Option + 1) = Value;
/* Append it */
Status = BlAppendBootOptions(AppEntry, Option);
@@ -687,6 +688,7 @@ BlAppendBootOptionInteger (
NTSTATUS
BlAppendBootOptionString (
_In_ PBL_LOADED_APPLICATION_ENTRY AppEntry,
+ _In_ ULONG OptionId,
_In_ PWCHAR OptionString
)
{
@@ -719,7 +721,7 @@ BlAppendBootOptionString (
/* Initialize it and copy the string value */
RtlZeroMemory(Option, sizeof(*Option) + StringSize);
Option->DataSize = StringSize;
- Option->Type = BcdLibraryString_ApplicationPath;
+ Option->Type = OptionId;
Option->DataOffset = sizeof(*Option);
wcsncpy((PWCHAR)Option + 1, OptionString, StringSize / sizeof(WCHAR));