mirror of
https://github.com/reactos/reactos.git
synced 2025-05-07 02:41:22 +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";
|
L"\\Windows\\System32\\winload.efi";
|
||||||
|
|
||||||
/* Add the path to the boot entry */
|
/* Add the path to the boot entry */
|
||||||
Status = BlAppendBootOptionString(BootEntry, LoaderPath);
|
Status = BlAppendBootOptionString(BootEntry,
|
||||||
|
BcdLibraryString_ApplicationPath,
|
||||||
|
LoaderPath);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
goto Quickie;
|
goto Quickie;
|
||||||
|
@ -2511,7 +2513,8 @@ TryAgain:
|
||||||
{
|
{
|
||||||
/* Set the option this once */
|
/* Set the option this once */
|
||||||
BlAppendBootOptionBoolean(BootEntry,
|
BlAppendBootOptionBoolean(BootEntry,
|
||||||
BcdLibraryBoolean_DisplayAdvancedOptions);
|
BcdLibraryBoolean_DisplayAdvancedOptions,
|
||||||
|
TRUE);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -2536,7 +2539,8 @@ TryAgain:
|
||||||
{
|
{
|
||||||
/* Set the option this once */
|
/* Set the option this once */
|
||||||
BlAppendBootOptionBoolean(BootEntry,
|
BlAppendBootOptionBoolean(BootEntry,
|
||||||
BcdLibraryBoolean_DisplayOptionsEdit);
|
BcdLibraryBoolean_DisplayOptionsEdit,
|
||||||
|
TRUE);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -2686,12 +2690,16 @@ Quickie:
|
||||||
|
|
||||||
case AdvancedOptions:
|
case AdvancedOptions:
|
||||||
/* Show the advanced options next iteration */
|
/* Show the advanced options next iteration */
|
||||||
BlAppendBootOptionBoolean(BootEntry, BcdOSLoaderBoolean_AdvancedOptionsOneTime);
|
BlAppendBootOptionBoolean(BootEntry,
|
||||||
|
BcdOSLoaderBoolean_AdvancedOptionsOneTime,
|
||||||
|
TRUE);
|
||||||
goto TryAgain;
|
goto TryAgain;
|
||||||
|
|
||||||
case BootOptions:
|
case BootOptions:
|
||||||
/* Show the options editor next iteration */
|
/* Show the options editor next iteration */
|
||||||
BlAppendBootOptionBoolean(BootEntry, BcdOSLoaderBoolean_OptionsEditOneTime);
|
BlAppendBootOptionBoolean(BootEntry,
|
||||||
|
BcdOSLoaderBoolean_OptionsEditOneTime,
|
||||||
|
TRUE);
|
||||||
goto TryAgain;
|
goto TryAgain;
|
||||||
|
|
||||||
case Recover:
|
case Recover:
|
||||||
|
|
|
@ -50,6 +50,88 @@ BOOLEAN OslImcProcessingValid;
|
||||||
ULONG OslFreeMemoryDesctiptorsListSize;
|
ULONG OslFreeMemoryDesctiptorsListSize;
|
||||||
PVOID OslMemoryDescriptorBuffer;
|
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 *****************************************************************/
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
|
@ -139,8 +221,8 @@ OslpRemoveInternalApplicationOptions (
|
||||||
_wcsupr(LoadString);
|
_wcsupr(LoadString);
|
||||||
|
|
||||||
/* Remove the existing one */
|
/* Remove the existing one */
|
||||||
//BlRemoveBootOption(BlpApplicationEntry.BcdData,
|
BlRemoveBootOption(BlpApplicationEntry.BcdData,
|
||||||
// BcdLibraryString_LoadOptionsString);
|
BcdLibraryString_LoadOptionsString);
|
||||||
|
|
||||||
/* Sanitize strings we don't want */
|
/* Sanitize strings we don't want */
|
||||||
OslpSanitizeLoadOptionsString(LoadString, L"DISABLE_INTEGRITY_CHECKS");
|
OslpSanitizeLoadOptionsString(LoadString, L"DISABLE_INTEGRITY_CHECKS");
|
||||||
|
@ -148,9 +230,9 @@ OslpRemoveInternalApplicationOptions (
|
||||||
OslpSanitizeLoadOptionsString(LoadString, L"DISABLEELAMDRIVERS");
|
OslpSanitizeLoadOptionsString(LoadString, L"DISABLEELAMDRIVERS");
|
||||||
|
|
||||||
/* Add the sanitized one back */
|
/* Add the sanitized one back */
|
||||||
//Status = BlAppendBootOptionsString(&BlpApplicationEntry,
|
Status = BlAppendBootOptionString(&BlpApplicationEntry,
|
||||||
// BcdLibraryString_LoadOptionsString,
|
BcdLibraryString_LoadOptionsString,
|
||||||
// LoadString);
|
LoadString);
|
||||||
|
|
||||||
/* Free the original BCD one */
|
/* Free the original BCD one */
|
||||||
BlMmFreeHeap(LoadString);
|
BlMmFreeHeap(LoadString);
|
||||||
|
@ -163,6 +245,288 @@ OslpRemoveInternalApplicationOptions (
|
||||||
return Status;
|
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
|
NTSTATUS
|
||||||
OslPrepareTarget (
|
OslPrepareTarget (
|
||||||
_Out_ PULONG ReturnFlags,
|
_Out_ PULONG ReturnFlags,
|
||||||
|
@ -176,6 +540,16 @@ OslPrepareTarget (
|
||||||
SIZE_T RootLength, RootLengthWithSep;
|
SIZE_T RootLength, RootLengthWithSep;
|
||||||
ULONG i;
|
ULONG i;
|
||||||
ULONG64 StartPerf, EndPerf;
|
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 */
|
/* Assume no flags */
|
||||||
*ReturnFlags = 0;
|
*ReturnFlags = 0;
|
||||||
|
@ -214,9 +588,14 @@ OslPrepareTarget (
|
||||||
/* Capture the current TSC */
|
/* Capture the current TSC */
|
||||||
StartPerf = BlArchGetPerformanceCounter();
|
StartPerf = BlArchGetPerformanceCounter();
|
||||||
|
|
||||||
#ifdef BL_TPM_SUPPORT
|
/* Set our application type for SecureBoot/TPM purposes */
|
||||||
BlpSbdiCurrentApplicationType = 0x10200003;
|
BlpSbdiCurrentApplicationType.Application.ObjectCode =
|
||||||
#endif
|
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 */
|
/* Register an error handler */
|
||||||
BlpStatusErrorHandler = OslBlStatusErrorHandler;
|
BlpStatusErrorHandler = OslBlStatusErrorHandler;
|
||||||
|
@ -237,6 +616,7 @@ OslPrepareTarget (
|
||||||
Status = OslpRemoveInternalApplicationOptions();
|
Status = OslpRemoveInternalApplicationOptions();
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
|
EfiPrintf(L"Fail here: %d\r\n", __LINE__);
|
||||||
goto Quickie;
|
goto Quickie;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -247,6 +627,7 @@ OslPrepareTarget (
|
||||||
0);
|
0);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
|
EfiPrintf(L"Fail here: %d\r\n", __LINE__);
|
||||||
goto Quickie;
|
goto Quickie;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -265,6 +646,7 @@ OslPrepareTarget (
|
||||||
&SystemRoot);
|
&SystemRoot);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
|
EfiPrintf(L"Fail here: %d\r\n", __LINE__);
|
||||||
goto Quickie;
|
goto Quickie;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -286,6 +668,7 @@ OslPrepareTarget (
|
||||||
{
|
{
|
||||||
/* Bail out if we're out of memory */
|
/* Bail out if we're out of memory */
|
||||||
Status = STATUS_NO_MEMORY;
|
Status = STATUS_NO_MEMORY;
|
||||||
|
EfiPrintf(L"Fail here: %d\r\n", __LINE__);
|
||||||
goto Quickie;
|
goto Quickie;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -297,7 +680,162 @@ OslPrepareTarget (
|
||||||
BlMmFreeHeap(SystemRoot);
|
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;
|
Status = STATUS_NOT_IMPLEMENTED;
|
||||||
|
DBG_UNREFERENCED_LOCAL_VARIABLE(PowerBuffer);
|
||||||
|
|
||||||
/* Printf perf */
|
/* Printf perf */
|
||||||
EndPerf = BlArchGetPerformanceCounter();
|
EndPerf = BlArchGetPerformanceCounter();
|
||||||
|
|
|
@ -34,6 +34,12 @@
|
||||||
|
|
||||||
/* STRUCTURES ****************************************************************/
|
/* STRUCTURES ****************************************************************/
|
||||||
|
|
||||||
|
typedef struct _OSL_BSD_ITEM_TABLE_ENTRY
|
||||||
|
{
|
||||||
|
ULONG Offset;
|
||||||
|
ULONG Size;
|
||||||
|
} OSL_BSD_ITEM_TABLE_ENTRY;
|
||||||
|
|
||||||
/* FUNCTIONS *****************************************************************/
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
|
|
|
@ -150,8 +150,9 @@ typedef enum BcdOSLoaderElementTypes
|
||||||
BcdOSLoaderBoolean_UsePlatformClock = 0x260000A2,
|
BcdOSLoaderBoolean_UsePlatformClock = 0x260000A2,
|
||||||
BcdOSLoaderBoolean_ForceLegacyPlatform = 0x260000A3,
|
BcdOSLoaderBoolean_ForceLegacyPlatform = 0x260000A3,
|
||||||
BcdOSLoaderInteger_TscSyncPolicy = 0x250000A6,
|
BcdOSLoaderInteger_TscSyncPolicy = 0x250000A6,
|
||||||
BcdOSLoaderBoolean_EmsEnabled = 0x260000b0,
|
BcdOSLoaderBoolean_EmsEnabled = 0x260000B0,
|
||||||
BcdOSLoaderInteger_DriverLoadFailurePolicy = 0x250000c1,
|
BcdOSLoaderInteger_ForceFailure = 0x250000C0,
|
||||||
|
BcdOSLoaderInteger_DriverLoadFailurePolicy = 0x250000C1,
|
||||||
BcdOSLoaderInteger_BootMenuPolicy = 0x250000C2,
|
BcdOSLoaderInteger_BootMenuPolicy = 0x250000C2,
|
||||||
BcdOSLoaderBoolean_AdvancedOptionsOneTime = 0x260000C3,
|
BcdOSLoaderBoolean_AdvancedOptionsOneTime = 0x260000C3,
|
||||||
BcdOSLoaderBoolean_OptionsEditOneTime = 0x260000C4, /* Undocumented */
|
BcdOSLoaderBoolean_OptionsEditOneTime = 0x260000C4, /* Undocumented */
|
||||||
|
@ -195,7 +196,8 @@ typedef enum BcdBootMgrElementTypes
|
||||||
BcdBootMgrBoolean_PersistBootSequence = 0x26000031
|
BcdBootMgrBoolean_PersistBootSequence = 0x26000031
|
||||||
} BcdBootMgrElementTypes;
|
} BcdBootMgrElementTypes;
|
||||||
|
|
||||||
typedef enum _BcdResumeElementTypes {
|
typedef enum _BcdResumeElementTypes
|
||||||
|
{
|
||||||
Reserved1 = 0x21000001,
|
Reserved1 = 0x21000001,
|
||||||
Reserved2 = 0x22000002,
|
Reserved2 = 0x22000002,
|
||||||
BcdResumeBoolean_UseCustomSettings = 0x26000003,
|
BcdResumeBoolean_UseCustomSettings = 0x26000003,
|
||||||
|
@ -204,6 +206,18 @@ typedef enum _BcdResumeElementTypes {
|
||||||
BcdResumeInteger_BootMenuPolicy = 0x25000008
|
BcdResumeInteger_BootMenuPolicy = 0x25000008
|
||||||
} BcdResumeElementTypes;
|
} BcdResumeElementTypes;
|
||||||
|
|
||||||
|
typedef enum _BCDE_OSLOADER_TYPE_BOOT_STATUS_POLICY
|
||||||
|
{
|
||||||
|
DisplayAllFailures,
|
||||||
|
IgnoreAllFailures,
|
||||||
|
IgnoreShutdownFailures,
|
||||||
|
IgnoreBootFailures,
|
||||||
|
IgnoreCheckpointFailures,
|
||||||
|
DisplayShutdownFailures,
|
||||||
|
DisplayBootFailures,
|
||||||
|
DisplayCheckpointFailures
|
||||||
|
} BCDE_OSLOADER_TYPE_BOOT_STATUS_POLICY;
|
||||||
|
|
||||||
/* Undocumented */
|
/* Undocumented */
|
||||||
typedef enum BcdStartupElementTypes
|
typedef enum BcdStartupElementTypes
|
||||||
{
|
{
|
||||||
|
|
|
@ -923,7 +923,7 @@ typedef struct _BL_HARDDISK_DEVICE
|
||||||
|
|
||||||
typedef struct _BL_LOCAL_DEVICE
|
typedef struct _BL_LOCAL_DEVICE
|
||||||
{
|
{
|
||||||
ULONG Type;
|
BL_LOCAL_DEVICE_TYPE Type;
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
struct
|
struct
|
||||||
|
@ -933,6 +933,8 @@ typedef struct _BL_LOCAL_DEVICE
|
||||||
|
|
||||||
BL_HARDDISK_DEVICE HardDisk;
|
BL_HARDDISK_DEVICE HardDisk;
|
||||||
|
|
||||||
|
BL_HARDDISK_DEVICE VirtualHardDisk;
|
||||||
|
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
PHYSICAL_ADDRESS ImageBase;
|
PHYSICAL_ADDRESS ImageBase;
|
||||||
|
@ -2008,7 +2010,8 @@ BlCopyBootOptions (
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
BlAppendBootOptionBoolean (
|
BlAppendBootOptionBoolean (
|
||||||
_In_ PBL_LOADED_APPLICATION_ENTRY AppEntry,
|
_In_ PBL_LOADED_APPLICATION_ENTRY AppEntry,
|
||||||
_In_ ULONG OptionId
|
_In_ ULONG OptionId,
|
||||||
|
_In_ BOOLEAN Value
|
||||||
);
|
);
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
|
@ -2021,6 +2024,7 @@ BlAppendBootOptionInteger (
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
BlAppendBootOptionString (
|
BlAppendBootOptionString (
|
||||||
_In_ PBL_LOADED_APPLICATION_ENTRY AppEntry,
|
_In_ PBL_LOADED_APPLICATION_ENTRY AppEntry,
|
||||||
|
_In_ ULONG OptionId,
|
||||||
_In_ PWCHAR OptionString
|
_In_ PWCHAR OptionString
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -2430,6 +2434,12 @@ BlDeviceClose (
|
||||||
_In_ ULONG DeviceId
|
_In_ ULONG DeviceId
|
||||||
);
|
);
|
||||||
|
|
||||||
|
BOOLEAN
|
||||||
|
BlDeviceIsVirtualPartitionDevice (
|
||||||
|
_In_ PBL_DEVICE_DESCRIPTOR InputDevice,
|
||||||
|
_Outptr_ PBL_DEVICE_DESCRIPTOR* VirtualDevice
|
||||||
|
);
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
BlpDeviceOpen (
|
BlpDeviceOpen (
|
||||||
_In_ PBL_DEVICE_DESCRIPTOR Device,
|
_In_ PBL_DEVICE_DESCRIPTOR Device,
|
||||||
|
|
|
@ -608,6 +608,39 @@ BlockIoGetInformation (
|
||||||
return STATUS_SUCCESS;
|
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
|
NTSTATUS
|
||||||
BlDeviceSetInformation (
|
BlDeviceSetInformation (
|
||||||
_In_ ULONG DeviceId,
|
_In_ ULONG DeviceId,
|
||||||
|
|
|
@ -624,7 +624,8 @@ BlCopyBootOptions (
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
BlAppendBootOptionBoolean (
|
BlAppendBootOptionBoolean (
|
||||||
_In_ PBL_LOADED_APPLICATION_ENTRY AppEntry,
|
_In_ PBL_LOADED_APPLICATION_ENTRY AppEntry,
|
||||||
_In_ ULONG OptionId
|
_In_ ULONG OptionId,
|
||||||
|
_In_ BOOLEAN Value
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
@ -642,7 +643,7 @@ BlAppendBootOptionBoolean (
|
||||||
Option->DataSize = sizeof(USHORT);
|
Option->DataSize = sizeof(USHORT);
|
||||||
Option->Type = OptionId;
|
Option->Type = OptionId;
|
||||||
Option->DataOffset = sizeof(*Option);
|
Option->DataOffset = sizeof(*Option);
|
||||||
*(PBOOLEAN)(Option + 1) = TRUE;
|
*(PBOOLEAN)(Option + 1) = Value;
|
||||||
|
|
||||||
/* Append it */
|
/* Append it */
|
||||||
Status = BlAppendBootOptions(AppEntry, Option);
|
Status = BlAppendBootOptions(AppEntry, Option);
|
||||||
|
@ -687,6 +688,7 @@ BlAppendBootOptionInteger (
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
BlAppendBootOptionString (
|
BlAppendBootOptionString (
|
||||||
_In_ PBL_LOADED_APPLICATION_ENTRY AppEntry,
|
_In_ PBL_LOADED_APPLICATION_ENTRY AppEntry,
|
||||||
|
_In_ ULONG OptionId,
|
||||||
_In_ PWCHAR OptionString
|
_In_ PWCHAR OptionString
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
@ -719,7 +721,7 @@ BlAppendBootOptionString (
|
||||||
/* Initialize it and copy the string value */
|
/* Initialize it and copy the string value */
|
||||||
RtlZeroMemory(Option, sizeof(*Option) + StringSize);
|
RtlZeroMemory(Option, sizeof(*Option) + StringSize);
|
||||||
Option->DataSize = StringSize;
|
Option->DataSize = StringSize;
|
||||||
Option->Type = BcdLibraryString_ApplicationPath;
|
Option->Type = OptionId;
|
||||||
Option->DataOffset = sizeof(*Option);
|
Option->DataOffset = sizeof(*Option);
|
||||||
wcsncpy((PWCHAR)Option + 1, OptionString, StringSize / sizeof(WCHAR));
|
wcsncpy((PWCHAR)Option + 1, OptionString, StringSize / sizeof(WCHAR));
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue