mirror of
https://github.com/reactos/reactos.git
synced 2025-05-06 18:31:26 +00:00
[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.
This commit is contained in:
parent
f0c7db730c
commit
9ec85c29e3
7 changed files with 632 additions and 21 deletions
|
@ -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:
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -34,6 +34,12 @@
|
|||
|
||||
/* STRUCTURES ****************************************************************/
|
||||
|
||||
typedef struct _OSL_BSD_ITEM_TABLE_ENTRY
|
||||
{
|
||||
ULONG Offset;
|
||||
ULONG Size;
|
||||
} OSL_BSD_ITEM_TABLE_ENTRY;
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
VOID
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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));
|
||||
|
||||
|
|
Loading…
Reference in a new issue