2246 lines
70 KiB
C
2246 lines
70 KiB
C
/** @file
|
|
|
|
;******************************************************************************
|
|
;* Copyright (c) 2021, Insyde Software Corporation. All Rights Reserved.
|
|
;*
|
|
;* You may not reproduce, distribute, publish, display, perform, modify, adapt,
|
|
;* transmit, broadcast, present, recite, release, license or otherwise exploit
|
|
;* any part of this publication in any form, by any means, without the prior
|
|
;* written permission of Insyde Software Corporation.
|
|
;*
|
|
;******************************************************************************
|
|
*/
|
|
|
|
/** @file
|
|
Intel One Click Recovery Setup Implementation.
|
|
|
|
@copyright
|
|
INTEL CONFIDENTIAL
|
|
Copyright 2020 - 2021 Intel Corporation.
|
|
|
|
The source code contained or described herein and all documents related to the
|
|
source code ("Material") are owned by Intel Corporation or its suppliers or
|
|
licensors. Title to the Material remains with Intel Corporation or its suppliers
|
|
and licensors. The Material may contain trade secrets and proprietary and
|
|
confidential information of Intel Corporation and its suppliers and licensors,
|
|
and is protected by worldwide copyright and trade secret laws and treaty
|
|
provisions. No part of the Material may be used, copied, reproduced, modified,
|
|
published, uploaded, posted, transmitted, distributed, or disclosed in any way
|
|
without Intel's prior express written permission.
|
|
|
|
No license under any patent, copyright, trade secret or other intellectual
|
|
property right is granted to or conferred upon you by disclosure or delivery
|
|
of the Materials, either expressly, by implication, inducement, estoppel or
|
|
otherwise. Any license under such intellectual property rights must be
|
|
express and approved by Intel in writing.
|
|
|
|
Unless otherwise agreed by Intel in writing, you may not remove or alter
|
|
this notice or any other notice embedded in Materials by Intel or
|
|
Intel's suppliers or licensors in any way.
|
|
|
|
This file contains a 'Sample Driver' and is licensed as such under the terms
|
|
of your license agreement with Intel or your vendor. This file may be modified
|
|
by the user, subject to the additional terms of the license agreement.
|
|
|
|
@par Specification Reference:
|
|
**/
|
|
|
|
#include <Library/IoLib.h>
|
|
#include <Library/DebugLib.h>
|
|
#include <OneClickRecoverySupport.h>
|
|
#include <Library/DevicePathLib.h>
|
|
#include <Library/PrintLib.h>
|
|
#include <Library/BaseMemoryLib.h>
|
|
#include <Library/MemoryAllocationLib.h>
|
|
#include <Library/PcdLib.h>
|
|
#include <SetupVariable.h>
|
|
#include <Library/DxeServicesTableLib.h>
|
|
#include <Library/DxeAsfHeciLib.h>
|
|
#include <Library/DxeAsfLib.h>
|
|
#include <Protocol/AsfProtocol.h>
|
|
#include <Library/DxeAmtHeciLib.h>
|
|
#include <MeBiosPayloadHob.h>
|
|
#include <Library/HobLib.h>
|
|
|
|
#include <Guid/GlobalVariable.h>
|
|
#include <Guid/AuthenticatedVariableFormat.h>
|
|
|
|
#include <Library/UefiBootServicesTableLib.h>
|
|
#include <Library/UefiRuntimeServicesTableLib.h>
|
|
#include <Library/UefiLib.h>
|
|
#include <Library/UefiBootManagerLib.h>
|
|
|
|
#include <Guid/StatusCodeDataTypeId.h>
|
|
#include <Protocol/ReportStatusCodeHandler.h>
|
|
#include <Protocol/Http.h>
|
|
#include <Protocol/HttpBootCallback.h>
|
|
#include <Protocol/HttpCallback.h>
|
|
#include <Library/HttpLib.h>
|
|
#include <IndustryStandard/Http11.h>
|
|
#include <Protocol/ReportStatusCodeHandler.h>
|
|
|
|
//
|
|
// One click Recovery Boot Settings GUID
|
|
//
|
|
GLOBAL_REMOVE_IF_UNREFERENCED EFI_GUID mOcrBootSettingsGuid = OCR_BOOT_SETTINGS_GUID;
|
|
|
|
//
|
|
// One Click Recovery Protocol
|
|
//
|
|
GLOBAL_REMOVE_IF_UNREFERENCED ONE_CLICK_RECOVERY_PROTOCOL mOneClickRecoveryProtocol = {
|
|
ONE_CLICK_RECOVERY_PROTOCOL_REVISION,
|
|
OneClickRecoveryMain,
|
|
OneClickRecoveryCapabilities,
|
|
OneClickRecoverySaveUefiBootOption
|
|
};
|
|
|
|
//
|
|
// One Click Recovery String
|
|
//
|
|
STATIC CHAR16 *mOcrString = L"One Click Recovery";
|
|
|
|
//
|
|
// One Click Recovery Boot Option
|
|
//
|
|
OCR_BOOT_OPTION *mOcrBootOption = NULL;
|
|
|
|
//
|
|
// AMT UEFI Boot Option Parameter
|
|
//
|
|
UEFI_BOOT_OPTION_PARAMETER mAmtUefiBootOption;
|
|
|
|
//
|
|
// OCR Capabilities
|
|
//
|
|
ONE_CLICK_RECOVERY_CAP mOcrCap;
|
|
|
|
//
|
|
// Data for the http boot progress, they are used by http boot callback.
|
|
//
|
|
STATIC UINT64 mHttpFileSize = 0;
|
|
STATIC UINT64 mHttpReceivedSize = 0;
|
|
STATIC UINT32 mHttpPercentage = 0;
|
|
|
|
//
|
|
// Flag to indicate if http boot download is complete.
|
|
//
|
|
STATIC BOOLEAN mHttpBootDownloadComplete = FALSE;
|
|
|
|
//
|
|
// Flag to indicate if HTTP Boot callback is invoked.
|
|
// If current OCR boot is HTTP boot but HTTP Boot callback is not invoked,
|
|
// it means there is no network connection available.
|
|
//
|
|
STATIC BOOLEAN mHttpBootCallbackInvoked = FALSE;
|
|
//
|
|
// Handle for EFI_HTTP_BOOT_CALLBACK_PROTOCOL
|
|
//
|
|
STATIC EFI_HANDLE mHttpBootCallbackHandle = NULL;
|
|
|
|
//
|
|
// Handle for EDKII_HTTP_CALLBACK_PROTOCOL
|
|
//
|
|
STATIC EFI_HANDLE mHttpCallbackHandle = NULL;
|
|
|
|
STATIC EFI_RSC_HANDLER_PROTOCOL *mRscHandlerProtocol = NULL;
|
|
|
|
/**
|
|
Callback function that is invoked when HTTP event occurs.
|
|
|
|
@param[in] This Pointer to the EDKII_HTTP_CALLBACK_PROTOCOL instance.
|
|
@param[in] Event The event that occurs in the current state.
|
|
@param[in] EventStatus The Status of Event, EFI_SUCCESS or other errors.
|
|
**/
|
|
VOID
|
|
EFIAPI
|
|
HttpCallback (
|
|
IN EDKII_HTTP_CALLBACK_PROTOCOL *This,
|
|
IN EDKII_HTTP_CALLBACK_EVENT Event,
|
|
IN EFI_STATUS EventStatus
|
|
);
|
|
|
|
/**
|
|
Callback function that is invoked when the HTTP Boot driver is about to transmit or has received a
|
|
packet.
|
|
|
|
This function is invoked when the HTTP Boot driver is about to transmit or has received a packet.
|
|
Parameters DataType and Received specify the type of event and the format of the buffer pointed
|
|
to by Data. Due to the polling nature of UEFI device drivers, this callback function should not
|
|
execute for more than 5 ms.
|
|
The returned status code determines the behavior of the HTTP Boot driver.
|
|
|
|
@param[in] This Pointer to the EFI_HTTP_BOOT_CALLBACK_PROTOCOL instance.
|
|
@param[in] DataType The event that occurs in the current state.
|
|
@param[in] Received TRUE if the callback is being invoked due to a receive event.
|
|
FALSE if the callback is being invoked due to a transmit event.
|
|
@param[in] DataLength The length in bytes of the buffer pointed to by Data.
|
|
@param[in] Data A pointer to the buffer of data, the data type is specified by
|
|
DataType.
|
|
|
|
@retval EFI_SUCCESS Tells the HTTP Boot driver to continue the HTTP Boot process.
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
HttpBootCallback (
|
|
IN EFI_HTTP_BOOT_CALLBACK_PROTOCOL *This,
|
|
IN EFI_HTTP_BOOT_CALLBACK_DATA_TYPE DataType,
|
|
IN BOOLEAN Received,
|
|
IN UINT32 DataLength,
|
|
IN VOID *Data OPTIONAL
|
|
);
|
|
|
|
///
|
|
/// HTTP Boot Callback Protocol instance
|
|
///
|
|
STATIC
|
|
EDKII_HTTP_CALLBACK_PROTOCOL mHttpCallback = {
|
|
HttpCallback
|
|
};
|
|
|
|
///
|
|
/// HTTP Callback Protocol instance
|
|
///
|
|
STATIC
|
|
EFI_HTTP_BOOT_CALLBACK_PROTOCOL mHttpBootCallback = {
|
|
HttpBootCallback
|
|
};
|
|
|
|
//[-start-211111-IB09480171-add]//
|
|
UINT8
|
|
GetSecureBootState (
|
|
VOID
|
|
)
|
|
{
|
|
UINT8 Data1;
|
|
UINT8 Data2;
|
|
UINT8 SecureBootState;
|
|
UINT32 VarAttributes;
|
|
UINTN VarSize;
|
|
EFI_STATUS Status;
|
|
|
|
|
|
Data1 = 0;
|
|
Data2 = 0;
|
|
SecureBootState = 0;
|
|
|
|
VarSize = sizeof (UINT8);
|
|
Status = gRT->GetVariable (
|
|
EFI_SECURE_BOOT_ENFORCE_NAME,
|
|
&gEfiGenericVariableGuid,
|
|
&VarAttributes,
|
|
&VarSize,
|
|
&Data1
|
|
);
|
|
|
|
Status = gRT->GetVariable (
|
|
EFI_SECURE_BOOT_MODE_NAME,
|
|
&gEfiGlobalVariableGuid,
|
|
NULL,
|
|
&VarSize,
|
|
&Data2
|
|
);
|
|
|
|
SecureBootState = Data1 & Data2;
|
|
|
|
return SecureBootState;
|
|
}
|
|
//[-end-211111-IB09480171-add]//
|
|
|
|
/**
|
|
Indicate if the HTTP status code indicates a redirection.
|
|
|
|
@param[in] StatusCode HTTP status code from server.
|
|
|
|
@return TRUE if it's redirection.
|
|
|
|
**/
|
|
BOOLEAN
|
|
IsHttpRedirectStatusCode (
|
|
IN EFI_HTTP_STATUS_CODE StatusCode
|
|
)
|
|
{
|
|
switch (StatusCode) {
|
|
case HTTP_STATUS_301_MOVED_PERMANENTLY:
|
|
case HTTP_STATUS_302_FOUND:
|
|
case HTTP_STATUS_307_TEMPORARY_REDIRECT:
|
|
case HTTP_STATUS_308_PERMANENT_REDIRECT:
|
|
return TRUE;
|
|
default:
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
/**
|
|
Callback function that is invoked when the HTTP Boot driver is about to transmit or has received a
|
|
packet.
|
|
|
|
This function is invoked when the HTTP Boot driver is about to transmit or has received a packet.
|
|
Parameters DataType and Received specify the type of event and the format of the buffer pointed
|
|
to by Data. Due to the polling nature of UEFI device drivers, this callback function should not
|
|
execute for more than 5 ms.
|
|
The returned status code determines the behavior of the HTTP Boot driver.
|
|
|
|
@param[in] This Pointer to the EFI_HTTP_BOOT_CALLBACK_PROTOCOL instance.
|
|
@param[in] DataType The event that occurs in the current state.
|
|
@param[in] Received TRUE if the callback is being invoked due to a receive event.
|
|
FALSE if the callback is being invoked due to a transmit event.
|
|
@param[in] DataLength The length in bytes of the buffer pointed to by Data.
|
|
@param[in] Data A pointer to the buffer of data, the data type is specified by
|
|
DataType.
|
|
|
|
@retval EFI_SUCCESS Tells the HTTP Boot driver to continue the HTTP Boot process.
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
HttpBootCallback (
|
|
IN EFI_HTTP_BOOT_CALLBACK_PROTOCOL *This,
|
|
IN EFI_HTTP_BOOT_CALLBACK_DATA_TYPE DataType,
|
|
IN BOOLEAN Received,
|
|
IN UINT32 DataLength,
|
|
IN VOID *Data OPTIONAL
|
|
)
|
|
{
|
|
EFI_HTTP_MESSAGE *HttpMessage;
|
|
EFI_HTTP_HEADER *HttpHeader;
|
|
UINT32 Percentage;
|
|
|
|
mHttpBootCallbackInvoked = TRUE;
|
|
|
|
switch (DataType) {
|
|
case HttpBootDhcp4:
|
|
case HttpBootDhcp6:
|
|
Print (L".");
|
|
break;
|
|
|
|
case HttpBootHttpRequest:
|
|
if (Data != NULL) {
|
|
HttpMessage = (EFI_HTTP_MESSAGE *) Data;
|
|
if (HttpMessage->Data.Request->Method == HttpMethodGet &&
|
|
HttpMessage->Data.Request->Url != NULL) {
|
|
Print (L"\n URI: %s\n", HttpMessage->Data.Request->Url);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case HttpBootHttpResponse:
|
|
if (Data != NULL) {
|
|
HttpMessage = (EFI_HTTP_MESSAGE *) Data;
|
|
|
|
if (HttpMessage->Data.Response != NULL) {
|
|
if (IsHttpRedirectStatusCode (HttpMessage->Data.Response->StatusCode)) {
|
|
//
|
|
// Server indicates the resource has been redirected to a different URL
|
|
// according to the section 6.4 of RFC 7231 and the RFC 7538.
|
|
// Display the redirect information on the screen.
|
|
//
|
|
HttpHeader = HttpFindHeader (
|
|
HttpMessage->HeaderCount,
|
|
HttpMessage->Headers,
|
|
HTTP_HEADER_LOCATION
|
|
);
|
|
if (HttpHeader != NULL) {
|
|
Print (L"\n HTTP ERROR: Resource Redirected.\n New Location: %a\n", HttpHeader->FieldValue);
|
|
}
|
|
break;
|
|
}
|
|
|
|
if (HttpMessage->Data.Response->StatusCode == HTTP_STATUS_404_NOT_FOUND) {
|
|
DEBUG ((DEBUG_INFO, "OCR: HTTPS Boot File not found\n"));
|
|
SendOcrPetEvent (
|
|
ASF_EVENT_OFFSET_ONE_CLICK_RECOVERY_ERROR,
|
|
ASF_OCR_EVENT_DATA3_HTTPS_BOOT_FILE_NOT_FOUND,
|
|
0
|
|
);
|
|
} else if (HttpMessage->Data.Response->StatusCode == HTTP_STATUS_401_UNAUTHORIZED) {
|
|
DEBUG ((DEBUG_INFO, "OCR: HTTPS Digest Auth failed\n"));
|
|
SendOcrPetEvent (
|
|
ASF_EVENT_OFFSET_ONE_CLICK_RECOVERY_ERROR,
|
|
ASF_OCR_EVENT_DATA3_HTTPS_DIGEST_AUTH_FAILED,
|
|
0
|
|
);
|
|
}
|
|
|
|
}
|
|
|
|
HttpHeader = HttpFindHeader (
|
|
HttpMessage->HeaderCount,
|
|
HttpMessage->Headers,
|
|
HTTP_HEADER_CONTENT_LENGTH
|
|
);
|
|
if (HttpHeader != NULL) {
|
|
mHttpFileSize = AsciiStrDecimalToUintn (HttpHeader->FieldValue);
|
|
mHttpReceivedSize = 0;
|
|
mHttpPercentage = 0;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case HttpBootHttpEntityBody:
|
|
if (DataLength != 0) {
|
|
if (mHttpFileSize != 0) {
|
|
//
|
|
// We already know the file size, print in percentage format.
|
|
//
|
|
if (mHttpReceivedSize == 0) {
|
|
Print (L" File Size: %lu Bytes\n", mHttpFileSize);
|
|
}
|
|
mHttpReceivedSize += DataLength;
|
|
Percentage = (UINT32) DivU64x64Remainder (MultU64x32 (mHttpReceivedSize, 100), mHttpFileSize, NULL);
|
|
if (mHttpPercentage != Percentage) {
|
|
mHttpPercentage = Percentage;
|
|
Print (L"\r Downloading...%d%%", Percentage);
|
|
if (mHttpPercentage >= 100) {
|
|
DEBUG ((DEBUG_INFO, "\nOCR: HTTPSBoot download is completed: %d/%d\n", mHttpReceivedSize, mHttpFileSize));
|
|
mHttpBootDownloadComplete = TRUE;;
|
|
SendOcrPetEvent (
|
|
ASF_EVENT_OFFSET_ONE_CLICK_RECOVERY_PROGRESS,
|
|
ASF_OCR_EVENT_DATA3_HTTPS_BOOT_DOWNLOAD,
|
|
0
|
|
);
|
|
}
|
|
}
|
|
|
|
} else {
|
|
//
|
|
// In some case we couldn't get the file size from the HTTP header, so we
|
|
// just print the downloaded file size.
|
|
//
|
|
mHttpReceivedSize += DataLength;
|
|
Print (L"\r Downloading...%lu Bytes", mHttpReceivedSize);
|
|
}
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
Callback function that is invoked when HTTP event occurs.
|
|
|
|
@param[in] This Pointer to the EDKII_HTTP_CALLBACK_PROTOCOL instance.
|
|
@param[in] Event The event that occurs in the current state.
|
|
@param[in] EventStatus The Status of Event, EFI_SUCCESS or other errors.
|
|
**/
|
|
VOID
|
|
EFIAPI
|
|
HttpCallback (
|
|
IN EDKII_HTTP_CALLBACK_PROTOCOL *This,
|
|
IN EDKII_HTTP_CALLBACK_EVENT Event,
|
|
IN EFI_STATUS EventStatus
|
|
)
|
|
{
|
|
DEBUG ((DEBUG_INFO, "OCR: HttpCallback: %d - %r\n", Event, EventStatus));
|
|
|
|
switch (Event) {
|
|
case HttpEventDns:
|
|
if (EFI_ERROR (EventStatus)) {
|
|
DEBUG ((DEBUG_INFO, "OCR: Name Resolution of URI failed\n"));
|
|
SendOcrPetEvent (ASF_EVENT_OFFSET_ONE_CLICK_RECOVERY_ERROR, ASF_OCR_EVENT_DATA3_NAME_RESOLUTION_URI_FAILED, 0);
|
|
} else {
|
|
DEBUG ((DEBUG_INFO, "OCR: HTTPS URI Name Resolved\n"));
|
|
SendOcrPetEvent (ASF_EVENT_OFFSET_ONE_CLICK_RECOVERY_PROGRESS, ASF_OCR_EVENT_DATA3_HTTPS_URI_NAME_RESOLVED, 0);
|
|
}
|
|
break;
|
|
|
|
case HttpEventConnectTcp:
|
|
break;
|
|
|
|
case HttpEventTlsConnectSession:
|
|
if (EFI_ERROR (EventStatus)) {
|
|
DEBUG ((DEBUG_INFO, "OCR: HTTPS TLS Auth failed\n"));
|
|
SendOcrPetEvent (ASF_EVENT_OFFSET_ONE_CLICK_RECOVERY_ERROR, ASF_OCR_EVENT_DATA3_HTTPS_TLS_AUTH_FAILED, 0);
|
|
}
|
|
break;
|
|
|
|
case HttpEventInitSession:
|
|
if (!EFI_ERROR (EventStatus)) {
|
|
DEBUG ((DEBUG_INFO, "OCR: HTTPS Connected Successfully\n"));
|
|
SendOcrPetEvent (ASF_EVENT_OFFSET_ONE_CLICK_RECOVERY_PROGRESS, ASF_OCR_EVENT_DATA3_HTTPS_CONNECTED_SUCCESS, 0);
|
|
} else {
|
|
DEBUG ((DEBUG_INFO, "OCR: Connect to URI failed\n"));
|
|
SendOcrPetEvent (ASF_EVENT_OFFSET_ONE_CLICK_RECOVERY_ERROR, ASF_OCR_EVENT_DATA3_CONNECT_TO_URI_FAILED, 0);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
/**
|
|
Check whether Left and Right are the same without matching the specific
|
|
device path data in IP device path and URI device path node.
|
|
|
|
@retval TRUE Left and Right are the same.
|
|
@retval FALSE Left and Right are the different.
|
|
**/
|
|
BOOLEAN
|
|
MatchHttpBootDevicePath (
|
|
IN EFI_DEVICE_PATH_PROTOCOL *Left,
|
|
IN EFI_DEVICE_PATH_PROTOCOL *Right
|
|
)
|
|
{
|
|
if ((Left == NULL) || (Right == NULL)) {
|
|
return FALSE;
|
|
}
|
|
|
|
for (; !IsDevicePathEnd (Left) && !IsDevicePathEnd (Right)
|
|
; Left = NextDevicePathNode (Left), Right = NextDevicePathNode (Right)
|
|
) {
|
|
if (CompareMem (Left, Right, DevicePathNodeLength (Left)) != 0) {
|
|
if ((DevicePathType (Left) != MESSAGING_DEVICE_PATH) || (DevicePathType (Right) != MESSAGING_DEVICE_PATH)) {
|
|
return FALSE;
|
|
}
|
|
|
|
if (DevicePathSubType (Left) == MSG_DNS_DP) {
|
|
Left = NextDevicePathNode (Left);
|
|
}
|
|
|
|
if (DevicePathSubType (Right) == MSG_DNS_DP) {
|
|
Right = NextDevicePathNode (Right);
|
|
}
|
|
|
|
if (((DevicePathSubType (Left) != MSG_IPv4_DP) || (DevicePathSubType (Right) != MSG_IPv4_DP)) &&
|
|
((DevicePathSubType (Left) != MSG_IPv6_DP) || (DevicePathSubType (Right) != MSG_IPv6_DP)) &&
|
|
((DevicePathSubType (Left) != MSG_URI_DP) || (DevicePathSubType (Right) != MSG_URI_DP))
|
|
) {
|
|
return FALSE;
|
|
}
|
|
}
|
|
}
|
|
return (BOOLEAN) (IsDevicePathEnd (Left) && IsDevicePathEnd (Right));
|
|
}
|
|
|
|
/**
|
|
Install the network callback, include gEfiHttpBootCallbackProtocolGuid
|
|
and gEdkiiHttpCallbackProtocolGuid
|
|
|
|
@param[in] DevicePath Device Path.
|
|
**/
|
|
VOID
|
|
InstallNetworkCallback (
|
|
IN CHAR16 *DevicePath
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
EFI_HANDLE *Handles;
|
|
UINTN Index;
|
|
UINTN HandleCount;
|
|
EFI_DEVICE_PATH_PROTOCOL *FilePath;
|
|
EFI_DEVICE_PATH_PROTOCOL *PathFromHandle;
|
|
|
|
DEBUG ((DEBUG_INFO, "InstallNetworkCallback\n"));
|
|
|
|
FilePath = ConvertTextToDevicePath (DevicePath);
|
|
//
|
|
// Use wide match algorithm to find the handle.
|
|
//
|
|
Status = gBS->LocateHandleBuffer (
|
|
ByProtocol,
|
|
&gEfiLoadFileProtocolGuid,
|
|
NULL,
|
|
&HandleCount,
|
|
&Handles
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
return;
|
|
}
|
|
|
|
for (Index = 0; Index < HandleCount; Index++) {
|
|
PathFromHandle = DevicePathFromHandle (Handles[Index]);
|
|
if (PathFromHandle != NULL) {
|
|
if (MatchHttpBootDevicePath (PathFromHandle, FilePath)) {
|
|
mHttpBootCallbackHandle = Handles[Index];
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (Handles != NULL) {
|
|
FreePool (Handles);
|
|
}
|
|
|
|
//
|
|
// Install a Http Boot callback
|
|
//
|
|
if (mHttpBootCallbackHandle != NULL) {
|
|
DEBUG ((DEBUG_INFO, "Install gEfiHttpBootCallbackProtocolGuid\n"));
|
|
Status = gBS->InstallProtocolInterface (
|
|
&mHttpBootCallbackHandle,
|
|
&gEfiHttpBootCallbackProtocolGuid,
|
|
EFI_NATIVE_INTERFACE,
|
|
&mHttpBootCallback
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
mHttpBootCallbackHandle = NULL;
|
|
}
|
|
|
|
//
|
|
// Install a Http callback for http boot only.
|
|
//
|
|
if (mHttpCallbackHandle == NULL) {
|
|
DEBUG ((DEBUG_INFO, "Install gEdkiiHttpCallbackProtocolGuid\n"));
|
|
mHttpBootCallbackInvoked = FALSE;
|
|
mHttpBootDownloadComplete = FALSE;;
|
|
Status = gBS->InstallProtocolInterface (
|
|
&mHttpCallbackHandle,
|
|
&gEdkiiHttpCallbackProtocolGuid,
|
|
EFI_NATIVE_INTERFACE,
|
|
&mHttpCallback
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
mHttpCallbackHandle = NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
Uninstall the network callback, include gEfiHttpBootCallbackProtocolGuid
|
|
and gEdkiiHttpCallbackProtocolGuid
|
|
**/
|
|
VOID
|
|
UninstallNetworkCallback (
|
|
VOID
|
|
)
|
|
{
|
|
DEBUG ((DEBUG_INFO, "UninstallNetworkCallback\n"));
|
|
if (mHttpBootCallbackHandle != NULL) {
|
|
DEBUG ((DEBUG_INFO, "Uninstall gEfiHttpBootCallbackProtocolGuid\n"));
|
|
gBS->UninstallProtocolInterface (
|
|
mHttpBootCallbackHandle,
|
|
&gEfiHttpBootCallbackProtocolGuid,
|
|
&mHttpBootCallback
|
|
);
|
|
mHttpBootCallbackHandle = NULL;
|
|
}
|
|
|
|
if (mHttpCallbackHandle != NULL) {
|
|
DEBUG ((DEBUG_INFO, "Uninstall gEdkiiHttpCallbackProtocolGuid\n"));
|
|
gBS->UninstallProtocolInterface (
|
|
mHttpCallbackHandle,
|
|
&gEdkiiHttpCallbackProtocolGuid,
|
|
&mHttpCallback
|
|
);
|
|
mHttpCallbackHandle = NULL;
|
|
}
|
|
}
|
|
|
|
/**
|
|
Report status code listener of FPDT. This is used to collect performance data
|
|
for OsLoaderLoadImageStart and OsLoaderStartImageStart in FPDT.
|
|
|
|
@param[in] CodeType Indicates the type of status code being reported.
|
|
@param[in] Value Describes the current status of a hardware or software entity.
|
|
This included information about the class and subclass that is used to
|
|
classify the entity as well as an operation.
|
|
@param[in] Instance The enumeration of a hardware or software entity within
|
|
the system. Valid instance numbers start with 1.
|
|
@param[in] CallerId This optional parameter may be used to identify the caller.
|
|
This parameter allows the status code driver to apply different rules to
|
|
different callers.
|
|
@param[in] Data This optional parameter may be used to pass additional data.
|
|
|
|
@retval EFI_SUCCESS Status code is what we expected.
|
|
@retval EFI_UNSUPPORTED Status code not supported.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
OcrStatusCodeListener (
|
|
IN EFI_STATUS_CODE_TYPE CodeType,
|
|
IN EFI_STATUS_CODE_VALUE Value,
|
|
IN UINT32 Instance,
|
|
IN EFI_GUID *CallerId,
|
|
IN EFI_STATUS_CODE_DATA *Data
|
|
)
|
|
{
|
|
EFI_RETURN_STATUS_EXTENDED_DATA *ExtendedData;
|
|
UINT32 ErrorCode;
|
|
|
|
//
|
|
// Check whether status code is what we are interested in.
|
|
//
|
|
if (((CodeType & EFI_STATUS_CODE_TYPE_MASK) != EFI_ERROR_CODE) ||
|
|
(Value & (EFI_STATUS_CODE_CLASS_MASK | EFI_STATUS_CODE_SUBCLASS_MASK)) != EFI_SOFTWARE_DXE_BS_DRIVER) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
ErrorCode = Value & EFI_STATUS_CODE_OPERATION_MASK;
|
|
if ((ErrorCode == EFI_SW_DXE_BS_EC_BOOT_OPTION_LOAD_ERROR) || (ErrorCode == EFI_SW_DXE_BS_EC_BOOT_OPTION_FAILED)) {
|
|
ExtendedData = (EFI_RETURN_STATUS_EXTENDED_DATA *)Data;
|
|
DEBUG ((DEBUG_INFO, "OCR: CodeType %x, Value %x, Status %d - %r\n",
|
|
CodeType, Value, ExtendedData->ReturnStatus, ExtendedData->ReturnStatus));
|
|
|
|
switch (ErrorCode) {
|
|
case EFI_SW_DXE_BS_EC_BOOT_OPTION_LOAD_ERROR:
|
|
switch (ExtendedData->ReturnStatus) {
|
|
case EFI_NOT_FOUND:
|
|
if ((AsfGetSpecialCommand () == ASF_INTEL_OEM_FORCE_PBA_BOOT_CMD)) {
|
|
DEBUG ((DEBUG_INFO, "OCR: OEM App not found at local URI\n"));
|
|
SendOcrPetEvent (
|
|
ASF_EVENT_OFFSET_ONE_CLICK_RECOVERY_ERROR,
|
|
ASF_OCR_EVENT_DATA3_FILEPATH_NOT_FOUND,
|
|
0
|
|
);
|
|
} else if ((AsfGetSpecialCommand () == ASF_INTEL_OEM_FORCE_HTTPS_BOOT_CMD)) {
|
|
if (mHttpBootCallbackInvoked == FALSE) {
|
|
//
|
|
// HTTP Boot callback is not invoked, it means there is no network connection available.
|
|
//
|
|
DEBUG ((DEBUG_INFO, "OCR: No network connection available\n"));
|
|
SendOcrPetEvent (
|
|
ASF_EVENT_OFFSET_ONE_CLICK_RECOVERY_ERROR,
|
|
ASF_OCR_EVENT_DATA3_NO_NETWORK_CONNECTION,
|
|
0
|
|
);
|
|
} else if (mHttpBootDownloadComplete == TRUE) {
|
|
//
|
|
// it is bad image because Http boot image is downloaded but can't find boot app.
|
|
//
|
|
DEBUG ((DEBUG_INFO, "OCR: Verified boot failed (bad image)\n"));
|
|
SendOcrPetEvent (
|
|
ASF_EVENT_OFFSET_ONE_CLICK_RECOVERY_ERROR,
|
|
ASF_OCR_EVENT_DATA3_VERIFIED_BOOT_FAILED,
|
|
0
|
|
);
|
|
}
|
|
}
|
|
break;
|
|
case EFI_ACCESS_DENIED:
|
|
case EFI_SECURITY_VIOLATION:
|
|
DEBUG ((DEBUG_INFO, "OCR: Verified boot failed\n"));
|
|
SendOcrPetEvent (
|
|
ASF_EVENT_OFFSET_ONE_CLICK_RECOVERY_ERROR,
|
|
ASF_OCR_EVENT_DATA3_VERIFIED_BOOT_FAILED,
|
|
0
|
|
);
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case EFI_SW_DXE_BS_EC_BOOT_OPTION_FAILED:
|
|
if (ExtendedData->ReturnStatus == EFI_SECURITY_VIOLATION) {
|
|
DEBUG ((DEBUG_INFO, "OCR: Verified boot failed(boot failure)\n"));
|
|
SendOcrPetEvent (
|
|
ASF_EVENT_OFFSET_ONE_CLICK_RECOVERY_ERROR,
|
|
ASF_OCR_EVENT_DATA3_VERIFIED_BOOT_FAILED,
|
|
0
|
|
);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
Is Intel One Click Recovery supported
|
|
|
|
@retval TRUE Intel One Click Recovery is supported
|
|
@retval FALSE Intel One Click Recovery is not supported
|
|
**/
|
|
BOOLEAN
|
|
IsOcrSupported (
|
|
VOID
|
|
)
|
|
{
|
|
ME_BIOS_PAYLOAD_HOB *MbpHob;
|
|
|
|
MbpHob = GetFirstGuidHob (&gMeBiosPayloadHobGuid);
|
|
if (MbpHob == NULL) {
|
|
return FALSE;
|
|
}
|
|
|
|
// Check that ME is corporate and supports AMT
|
|
if (MbpHob->MeBiosPayload.FwPlatType.RuleData.Fields.IntelMeFwImageType != IntelMeCorporateFw ||
|
|
MbpHob->MeBiosPayload.FwFeaturesState.FwFeatures.Fields.Amt != 1 ||
|
|
MbpHob->MeBiosPayload.FwCapsSku.FwCapabilities.Fields.Amt != 1 ) {
|
|
return FALSE;
|
|
}
|
|
|
|
// Check that BIOS supports one of boot options: HTTPS, PBA, Win Re
|
|
if (mOcrCap.Bits.OcrBootHttps == ONE_CLICK_RECOVERY_HTTPS_BOOT_CAPABLE ||
|
|
mOcrCap.Bits.OcrBootPba == ONE_CLICK_RECOVERY_PBA_BOOT_CAPABLE ||
|
|
mOcrCap.Bits.OcrBootWinRe == ONE_CLICK_RECOVERY_WIN_RE_BOOT_CAPABLE) {
|
|
return TRUE;
|
|
} else {
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
/**
|
|
Get OCR Boot Setting EFI Variable
|
|
|
|
@retval OCR_BOOT_SETTINGS OCR boot Setting
|
|
**/
|
|
OCR_BOOT_SETTINGS
|
|
GetOcrBootSettings (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINTN VarSize;
|
|
OCR_BOOT_SETTINGS OcrBootSettings;
|
|
|
|
VarSize = sizeof (OCR_BOOT_SETTINGS);
|
|
|
|
Status = gRT->GetVariable(
|
|
OCR_BOOT_SETTINGS_NAME,
|
|
&mOcrBootSettingsGuid,
|
|
NULL,
|
|
&VarSize,
|
|
&OcrBootSettings
|
|
);
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
OcrBootSettings.BootOptionExists = BOOT_OPTION_EXISTS_NONE;
|
|
OcrBootSettings.RestoreSecureBootSetting = RESTORE_SECURE_BOOT_NONE;
|
|
}
|
|
|
|
return OcrBootSettings;
|
|
}
|
|
|
|
/**
|
|
Creates OCR Description Title
|
|
|
|
@param[in] Description Title to Append to boot option
|
|
@param[out] OcrDescription OCR Description
|
|
@param[in] MaxOcrDescriptionSize Max OCR Description Size
|
|
|
|
@retval EFI_SUCCESS Created OCR Description
|
|
@retval EFI_INVALID_PARAMETER Pointers are null
|
|
@retval EFI_BUFFER_TOO_SMALL Description will be larger than max size
|
|
**/
|
|
EFI_STATUS
|
|
CreateOcrBootOptionDescription (
|
|
IN CHAR16* Description,
|
|
OUT CHAR16* OcrDescription,
|
|
IN UINT32 MaxOcrDescriptionSize
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINTN BootOptionSize;
|
|
|
|
if (Description == NULL || OcrDescription == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
BootOptionSize = StrSize (Description) + StrSize (mOcrString) - 1;
|
|
|
|
if (BootOptionSize > MaxOcrDescriptionSize) {
|
|
return EFI_BUFFER_TOO_SMALL;
|
|
}
|
|
|
|
Status = StrCpyS (OcrDescription, BootOptionSize, mOcrString);
|
|
if (!EFI_ERROR (Status)) {
|
|
Status = StrCatS (OcrDescription, BootOptionSize, Description);
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
/**
|
|
Frees OCR Boot Option
|
|
**/
|
|
VOID
|
|
FreeOcrBootOption (
|
|
VOID
|
|
)
|
|
{
|
|
if (mOcrBootOption != NULL) {
|
|
if (mOcrBootOption->OptionalData != NULL) {
|
|
FreePool (mOcrBootOption->OptionalData);
|
|
}
|
|
|
|
FreePool (mOcrBootOption);
|
|
mOcrBootOption = NULL;
|
|
}
|
|
}
|
|
|
|
/**
|
|
Cancels OCR Boot Option by freeing memory, report bios status failure and perform warm reset if secure boot is disabled
|
|
**/
|
|
VOID
|
|
CancelOcrBootOption (
|
|
VOID
|
|
)
|
|
{
|
|
OCR_BOOT_SETTINGS OcrBootSettings;
|
|
EFI_STATUS Status;
|
|
|
|
FreeOcrBootOption ();
|
|
Status = ReportBiosStatus (AsfRbsGeneralFailure);
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_INFO, "OCR failed to report BIOS Status\n"));
|
|
}
|
|
|
|
OcrBootSettings = GetOcrBootSettings ();
|
|
// Reset System if secure boot was disabled for OCR HTTPS Boot but current boot is not OCR.
|
|
if (OcrBootSettings.RestoreSecureBootSetting == RESTORE_SECURE_BOOT_ENABLED) {
|
|
DEBUG ((DEBUG_INFO, "Secure Boot disabled for OCR HTTPS Boot but not booting to OCR HTTPS - Warm Reset!\n"));
|
|
gRT->ResetSystem (EfiResetWarm, EFI_SUCCESS, 0, NULL);
|
|
}
|
|
}
|
|
|
|
/**
|
|
Set UEFI Boot Options State
|
|
|
|
@param[in] MeSetup ME Setup Configuration
|
|
|
|
@retval EFI_SUCCESS Set AMT UEFI boot options states
|
|
**/
|
|
EFI_STATUS
|
|
SetUefiBootOptionsState (
|
|
IN ME_SETUP MeSetup
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
AMT_BOOT_CONTROL UserAmtBootControl;
|
|
AMT_BOOT_CONTROL CurrentAmtBootControl;
|
|
|
|
Status = AsfGetUefiBootOptionsState (&CurrentAmtBootControl);
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
UserAmtBootControl.Uint32 = CurrentAmtBootControl.Uint32;
|
|
|
|
UserAmtBootControl.Bits.AmtTrigBootToHttps = (mOcrCap.Bits.OcrBootHttps == ONE_CLICK_RECOVERY_HTTPS_BOOT_CAPABLE) ? MeSetup.OcrBootHttps : 0;
|
|
UserAmtBootControl.Bits.AmtTrigBootToPba = (mOcrCap.Bits.OcrBootPba == ONE_CLICK_RECOVERY_PBA_BOOT_CAPABLE) ? MeSetup.OcrBootPba : 0;
|
|
UserAmtBootControl.Bits.AmtTrigBootToWinRe = (mOcrCap.Bits.OcrBootWinRe == ONE_CLICK_RECOVERY_WIN_RE_BOOT_CAPABLE) ? MeSetup.OcrBootWinRe : 0;
|
|
UserAmtBootControl.Bits.AmtAllowedToDisSecureBoot = (mOcrCap.Bits.OcrAmtDisSecBoot == ONE_CLICK_RECOVERY_DIS_SEC_BOOT_CAPABLE) ? MeSetup.OcrAmtDisSecBoot : 0;
|
|
|
|
if (CurrentAmtBootControl.Uint32 != UserAmtBootControl.Uint32) {
|
|
Status = AsfSetUefiBootOptionsState (UserAmtBootControl);
|
|
}
|
|
|
|
DEBUG ((DEBUG_INFO, "OcrBootHttps: %d\n", UserAmtBootControl.Bits.AmtTrigBootToHttps));
|
|
DEBUG ((DEBUG_INFO, "OcrBootPba: %d\n", UserAmtBootControl.Bits.AmtTrigBootToPba));
|
|
DEBUG ((DEBUG_INFO, "OcrBootWinRe: %d\n", UserAmtBootControl.Bits.AmtTrigBootToWinRe));
|
|
DEBUG ((DEBUG_INFO, "OcrAmtDisSecBoot: %d\n", UserAmtBootControl.Bits.AmtAllowedToDisSecureBoot));
|
|
|
|
return Status;
|
|
}
|
|
|
|
// List of GUIDs for registering Certificates
|
|
STATIC EFI_GUID mOcrTlsAuthConfigGuid[MAX_NUM_ROOT_CA_CERTIFICATE] = {
|
|
{ 0xf575f8b1, 0xc4a8, 0x4571, { 0xba, 0xb0, 0x13, 0x5d, 0xbb, 0x09, 0xdb, 0xff }},
|
|
{ 0x352791b0, 0x2931, 0x4e4e, { 0x91, 0xf8, 0x0b, 0xb4, 0xda, 0x6e, 0xc7, 0x6a }},
|
|
{ 0xf021cb20, 0xfe1b, 0x4fec, { 0x8a, 0x2e, 0x73, 0x77, 0x4d, 0x18, 0x0c, 0x38 }},
|
|
{ 0xb801e82a, 0xb794, 0x4f56, { 0xbc, 0x15, 0xb0, 0x78, 0x12, 0xbc, 0x57, 0x32 }}
|
|
};
|
|
|
|
/**
|
|
Get All Root CA Certificates
|
|
|
|
@retval EFI_SUCCESS successful sync CA Certicates
|
|
**/
|
|
EFI_STATUS
|
|
GetRootCaCertificates (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINT32 Index;
|
|
ROOT_CA_CERTIFICATE Cert;
|
|
|
|
// Get all Certificates and enroll them
|
|
for (Index = 0; Index < MAX_NUM_ROOT_CA_CERTIFICATE; Index++) {
|
|
Status = AsfGetRootCaCertificate (Index, &Cert);
|
|
|
|
if (!EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_ERROR, "Root CA Certificate\n Index: %d\n CertSize: %d\n", Index, Cert.CertSize));
|
|
Status = EnrollOcrX509Certificate (Cert.Cert, Cert.CertSize, &mOcrTlsAuthConfigGuid[Index]);
|
|
}
|
|
|
|
if (EFI_ERROR (Status) || Cert.LastCert) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
/**
|
|
Adds OCR Boot Option to EFI Boot Manager
|
|
|
|
@param[in] BootOption Boot Option
|
|
|
|
@retval EFI_SUCCESS Added OCR Boot Option
|
|
@retval EFI_INVALID OCR Boot Option is NULL
|
|
@retval EFI_NOT_FOUND OCR Boot Device Path not found
|
|
@retval EFI_UNSUPPORTED OCR Boot Option is not supported
|
|
**/
|
|
EFI_STATUS
|
|
AddOcrBootOption (
|
|
IN OCR_BOOT_OPTION *BootOption
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
EFI_BOOT_MANAGER_LOAD_OPTION SetupOption;
|
|
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
|
|
|
|
if (BootOption == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
DevicePath = ConvertTextToDevicePath (BootOption->DevicePath);
|
|
|
|
if (DevicePath == NULL) {
|
|
return EFI_NOT_FOUND;
|
|
}
|
|
|
|
Status = EfiBootManagerInitializeLoadOption (
|
|
&SetupOption,
|
|
LoadOptionNumberUnassigned,
|
|
LoadOptionTypeBoot,
|
|
LOAD_OPTION_ACTIVE,
|
|
BootOption->Description,
|
|
DevicePath,
|
|
BootOption->OptionalData,
|
|
BootOption->OptionalDataSize
|
|
);
|
|
|
|
if (!EFI_ERROR (Status)) {
|
|
// Place as default boot option to load
|
|
Status = EfiBootManagerAddLoadOptionVariable (&SetupOption, 0);
|
|
DEBUG ((DEBUG_INFO, "OCR EfiBootManagerAddLoadOptionVariable: %x\n", Status));
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
//[-start-211215-IB09480180-add]//
|
|
/**
|
|
Internal function to uninstall all of specific protocols in all of handles.
|
|
|
|
@param[in] Protocol Provides the protocol to remove.
|
|
|
|
@retval EFI_SUCCESS Uninstall all of protcols successfully.
|
|
@return Other Any other error occurred while uninstalling protocols.
|
|
**/
|
|
STATIC
|
|
EFI_STATUS
|
|
UninstallSpecificProtocols (
|
|
IN EFI_GUID *Protocol
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINTN NoHandles;
|
|
EFI_HANDLE *Buffer;
|
|
UINTN Index;
|
|
|
|
Status = gBS->LocateHandleBuffer (
|
|
ByProtocol,
|
|
Protocol,
|
|
NULL,
|
|
&NoHandles,
|
|
&Buffer
|
|
);
|
|
if (!EFI_ERROR (Status)) {
|
|
for (Index = 0; Index < NoHandles; Index++) {
|
|
Status = gBS->UninstallProtocolInterface (
|
|
Buffer[Index],
|
|
Protocol,
|
|
NULL
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
FreePool (Buffer);
|
|
return Status;
|
|
}
|
|
}
|
|
FreePool (Buffer);
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
Disable BootOrder variable hook mechanism.
|
|
|
|
@retval EFI_SUCCESS Disable BootOrder variable hook mechanism successfully.
|
|
@return Other Disable BootOrder variable hook mechanism failed.
|
|
**/
|
|
EFI_STATUS
|
|
BdsLibDisableBootOrderHook (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
EFI_HANDLE Handle;
|
|
VOID *Interface;
|
|
|
|
if (!FeaturePcdGet (PcdAutoCreateDummyBootOption)) {
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
Status = UninstallSpecificProtocols (&gBootOrderHookEnableGuid);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
Status = gBS->LocateProtocol (
|
|
&gBootOrderHookDisableGuid,
|
|
NULL,
|
|
(VOID **)&Interface
|
|
);
|
|
if (!EFI_ERROR (Status)) {
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
Handle = NULL;
|
|
return gBS->InstallProtocolInterface (
|
|
&Handle,
|
|
&gBootOrderHookDisableGuid,
|
|
EFI_NATIVE_INTERFACE,
|
|
NULL
|
|
);
|
|
}
|
|
|
|
/**
|
|
Enable BootOrder variable hook mechanism.
|
|
|
|
@retval EFI_SUCCESS Enable BootOrder variable hook mechanism successfully.
|
|
@return Other Enable BootOrder variable hook mechanism failed.
|
|
**/
|
|
EFI_STATUS
|
|
BdsLibEnableBootOrderHook (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
EFI_HANDLE Handle;
|
|
VOID *Interface;
|
|
|
|
if (!FeaturePcdGet (PcdAutoCreateDummyBootOption)) {
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
Status = UninstallSpecificProtocols (&gBootOrderHookDisableGuid);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
Status = gBS->LocateProtocol (
|
|
&gBootOrderHookEnableGuid,
|
|
NULL,
|
|
(VOID **)&Interface
|
|
);
|
|
if (!EFI_ERROR (Status)) {
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
Handle = NULL;
|
|
return gBS->InstallProtocolInterface (
|
|
&Handle,
|
|
&gBootOrderHookEnableGuid,
|
|
EFI_NATIVE_INTERFACE,
|
|
NULL
|
|
);
|
|
}
|
|
|
|
/**
|
|
Function uses to check BootOrder variable hook mechanism is whether enabled.
|
|
|
|
@retval TRUE BootOrder variable hook mechanism is enabled.
|
|
@retval FALSE BootOrder variable hook mechanism is disabled
|
|
**/
|
|
BOOLEAN
|
|
BdsLibIsBootOrderHookEnabled (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
VOID *BootOrderHook;
|
|
|
|
Status = gBS->LocateProtocol (
|
|
&gBootOrderHookEnableGuid,
|
|
NULL,
|
|
(VOID **)&BootOrderHook
|
|
);
|
|
if (!EFI_ERROR (Status)) {
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
//[-end-211215-IB09480180-add]//
|
|
|
|
/**
|
|
Delete One Click Recovery Boot Options if they exist
|
|
**/
|
|
VOID
|
|
DeleteOcrBootOption (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_BOOT_MANAGER_LOAD_OPTION *BootOptions;
|
|
UINTN BootOptionCount;
|
|
UINTN Index;
|
|
EFI_STATUS Status;
|
|
OCR_BOOT_SETTINGS OcrBootSettings;
|
|
//[-start-211215-IB09480180-add]//
|
|
BOOLEAN IsBootOrderHookEnabled;
|
|
//[-end-211215-IB09480180-add]//
|
|
|
|
OcrBootSettings = GetOcrBootSettings ();
|
|
|
|
if (OcrBootSettings.BootOptionExists != BOOT_OPTION_EXISTS_NONE) {
|
|
|
|
//[-start-211215-IB09480180-add]//
|
|
IsBootOrderHookEnabled = BdsLibIsBootOrderHookEnabled ();
|
|
if (!IsBootOrderHookEnabled) {
|
|
BdsLibEnableBootOrderHook ();
|
|
}
|
|
//[-end-211215-IB09480180-add]//
|
|
|
|
BootOptions = EfiBootManagerGetLoadOptions (&BootOptionCount, LoadOptionTypeBoot);
|
|
|
|
if (BootOptions != NULL) {
|
|
// Remove OCR boot options from load options
|
|
for (Index = 0; Index < BootOptionCount; Index++) {
|
|
if ((StrnCmp(BootOptions[Index].Description, mOcrString, StrLen(mOcrString))) == 0) {
|
|
EfiBootManagerDeleteLoadOptionVariable (BootOptions[Index].OptionNumber, LoadOptionTypeBoot);
|
|
}
|
|
}
|
|
|
|
DEBUG((DEBUG_INFO, "Remove OCR Boot options\n"));
|
|
EfiBootManagerFreeLoadOptions (BootOptions, BootOptionCount);
|
|
}
|
|
|
|
// remove all previous certificates
|
|
for (Index = 0; Index < MAX_NUM_ROOT_CA_CERTIFICATE; Index++) {
|
|
DeleteOcrX509Certificate (&mOcrTlsAuthConfigGuid[Index]);
|
|
}
|
|
|
|
//
|
|
// Update OcrBootSettings variable with Boot Option Exists to None
|
|
//
|
|
OcrBootSettings.BootOptionExists = BOOT_OPTION_EXISTS_NONE;
|
|
|
|
Status = gRT->SetVariable (
|
|
OCR_BOOT_SETTINGS_NAME,
|
|
&mOcrBootSettingsGuid,
|
|
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
|
|
sizeof (OCR_BOOT_SETTINGS),
|
|
&OcrBootSettings
|
|
);
|
|
ASSERT_EFI_ERROR (Status);
|
|
|
|
//[-start-211215-IB09480180-add]//
|
|
if (!IsBootOrderHookEnabled) {
|
|
BdsLibDisableBootOrderHook ();
|
|
}
|
|
//[-end-211215-IB09480180-add]//
|
|
|
|
}
|
|
}
|
|
|
|
/**
|
|
Is the current Boot Option the One Click Recovery Boot Option
|
|
|
|
@retval TRUE Current Boot Option is One Click Recovery Boot Option
|
|
@retval False Current Boot Option is not One Click Recovery Boot Option
|
|
**/
|
|
BOOLEAN
|
|
IsCurrentBootOcrBootOption (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
BOOLEAN IsOcrBootOption;
|
|
UINTN VarSize;
|
|
UINT16 BootCurrent;
|
|
CHAR16 BootXXXX[16];
|
|
EFI_BOOT_MANAGER_LOAD_OPTION CurrentBootOption;
|
|
CHAR16 *CurrentDevicePath;
|
|
|
|
IsOcrBootOption = FALSE;
|
|
|
|
VarSize = sizeof (UINT16);
|
|
Status = gRT->GetVariable (
|
|
L"BootCurrent",
|
|
&gEfiGlobalVariableGuid,
|
|
NULL,
|
|
&VarSize,
|
|
&BootCurrent
|
|
);
|
|
|
|
if (!EFI_ERROR (Status)) {
|
|
UnicodeSPrint (BootXXXX, sizeof(BootXXXX), L"Boot%04X", BootCurrent);
|
|
|
|
Status = EfiBootManagerVariableToLoadOption (BootXXXX, &CurrentBootOption);
|
|
if (!EFI_ERROR (Status)) {
|
|
|
|
CurrentDevicePath = ConvertDevicePathToText (CurrentBootOption.FilePath, TRUE, TRUE);
|
|
if (CurrentDevicePath != NULL) {
|
|
DEBUG ((DEBUG_INFO, "Current Boot description: %s\nCurrent Boot DevicePath: %s\n",CurrentBootOption.Description, CurrentBootOption.FilePath));
|
|
|
|
// Compare Current Boot option and OCR Boot option
|
|
if ((StrnCmp (mOcrBootOption->Description, CurrentBootOption.Description, MAX_UEFI_BOOT_OPTION_DESC_LENGTH) == 0) &&
|
|
(StrnCmp (mOcrBootOption->DevicePath, CurrentDevicePath, MAX_UEFI_BOOT_OPTION_DEV_PATH_LENGTH) == 0) &&
|
|
(CompareMem(mOcrBootOption->OptionalData, CurrentBootOption.OptionalData, mOcrBootOption->OptionalDataSize) == 0) &&
|
|
(mOcrBootOption->OptionalDataSize == CurrentBootOption.OptionalDataSize)) {
|
|
IsOcrBootOption = TRUE;
|
|
}
|
|
}
|
|
EfiBootManagerFreeLoadOption (&CurrentBootOption);
|
|
}
|
|
}
|
|
|
|
return IsOcrBootOption;
|
|
}
|
|
|
|
/**
|
|
During Ready To Boot Event, Removes One Click Recovery from load options
|
|
and sends status to AMT
|
|
|
|
@param[in] Event Event whose notification function is being invoked
|
|
@param[in] Context Pointer to the notification function's context
|
|
**/
|
|
VOID
|
|
EFIAPI
|
|
OneClickRecoveryReadyToBootService (
|
|
IN EFI_EVENT Event,
|
|
IN VOID *Context
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
BOOLEAN IsOcrBootOption;
|
|
OCR_BOOT_SETTINGS OcrBootSettings;
|
|
UINT32 AsfBiosStatus;
|
|
|
|
IsOcrBootOption = IsCurrentBootOcrBootOption ();
|
|
|
|
if (IsOcrBootOption) {
|
|
DEBUG ((DEBUG_INFO, "Booting OCR Boot Option\n"));
|
|
AsfBiosStatus = AsfRbsSuccess;
|
|
|
|
if (AsfIsFwProgressEnabled ()) {
|
|
if (mOcrBootOption != NULL) {
|
|
InstallNetworkCallback (mOcrBootOption->DevicePath);
|
|
}
|
|
|
|
//
|
|
// Get Report Status Code Handler Protocol.
|
|
//
|
|
Status = gBS->LocateProtocol (&gEfiRscHandlerProtocolGuid, NULL, (VOID **) &mRscHandlerProtocol);
|
|
ASSERT_EFI_ERROR (Status);
|
|
|
|
//
|
|
// Register report status code listener for OS Loader load and start.
|
|
//
|
|
DEBUG ((DEBUG_INFO, "Register report status code listener\n"));
|
|
Status = mRscHandlerProtocol->Register (OcrStatusCodeListener, TPL_HIGH_LEVEL);
|
|
ASSERT_EFI_ERROR (Status);
|
|
}
|
|
} else {
|
|
AsfBiosStatus = AsfRbsGeneralFailure;
|
|
if (AsfIsFwProgressEnabled ()) {
|
|
UninstallNetworkCallback ();
|
|
}
|
|
|
|
//
|
|
// Unregister report status code listener.
|
|
//
|
|
if (mRscHandlerProtocol != NULL) {
|
|
DEBUG ((DEBUG_INFO, "Unregister report status code listener\n"));
|
|
mRscHandlerProtocol->Unregister (OcrStatusCodeListener);
|
|
mRscHandlerProtocol = NULL;
|
|
}
|
|
}
|
|
// report Bios Status to AMT based on if we're going to boot OCR boot option requested
|
|
Status = ReportBiosStatus (AsfBiosStatus);
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_INFO, "OCR failed to report BIOS Status\n"));
|
|
}
|
|
// report PET if were booting OCR Boot Optiona and PET are enabled
|
|
if (AsfIsFwProgressEnabled () && IsOcrBootOption) {
|
|
Status = SendOcrPetEvent (ASF_EVENT_OFFSET_ONE_CLICK_RECOVERY_PROGRESS, ASF_OCR_EVENT_DATA3_ATTEMPT_TO_BOOT, 0);
|
|
}
|
|
|
|
if (!IsOcrBootOption) {
|
|
OcrBootSettings = GetOcrBootSettings ();
|
|
// Reset System if secure boot was disable for OCR HTTPS Boot but current boot is not OCR.
|
|
if (OcrBootSettings.RestoreSecureBootSetting == RESTORE_SECURE_BOOT_ENABLED) {
|
|
DEBUG ((DEBUG_INFO, "Secure Boot disabled for OCR HTTPS Boot but not booting to OCR HTTPS - Warm Reset!\n"));
|
|
gRT->ResetSystem (EfiResetWarm, EFI_SUCCESS, 0, NULL);
|
|
}
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
/**
|
|
During Exit Boot Event, sends AMT PET on whether OCR Boot Option Booted
|
|
|
|
@param Event Event whose notification function is being invoked
|
|
@param Context Pointer to the notification function's context
|
|
**/
|
|
VOID
|
|
EFIAPI
|
|
OneClickRecoveryExitBootService (
|
|
IN EFI_EVENT Event,
|
|
IN VOID *Context
|
|
)
|
|
{
|
|
// report PET if were booting OCR Boot Optiona and PET are enabled
|
|
if (AsfIsFwProgressEnabled () && IsCurrentBootOcrBootOption ()) {
|
|
DEBUG ((DEBUG_INFO, "OCR Boot Option Booted\n"));
|
|
UninstallNetworkCallback ();
|
|
|
|
//
|
|
// Unregister report status code listener.
|
|
//
|
|
if (mRscHandlerProtocol != NULL) {
|
|
DEBUG ((DEBUG_INFO, "Unregister report status code listener\n"));
|
|
mRscHandlerProtocol->Unregister (OcrStatusCodeListener);
|
|
mRscHandlerProtocol = NULL;
|
|
}
|
|
SendOcrPetEvent (ASF_EVENT_OFFSET_ONE_CLICK_RECOVERY_PROGRESS, ASF_OCR_EVENT_DATA3_EXIT_BOOT_SERVICES, 0);
|
|
}
|
|
|
|
DeleteOcrBootOption ();
|
|
|
|
gBS->CloseEvent (Event);
|
|
|
|
return;
|
|
}
|
|
|
|
/**
|
|
Registers a callback on Exit Boot Service event that will remove One Click Recovery from load options
|
|
|
|
@retval EFI_SUCCESS Callback was successfully registered
|
|
@retval Others Callback was not registered
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
RegisterOneClickRecoveryCallback (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
EFI_EVENT ReadyToBootServiceEvent;
|
|
EFI_EVENT ExitBootServiceEvent;
|
|
|
|
//
|
|
// Register Ready to Boot Event for One Click Recovery
|
|
//
|
|
Status = EfiCreateEventReadyToBootEx (
|
|
TPL_CALLBACK,
|
|
OneClickRecoveryReadyToBootService,
|
|
NULL,
|
|
&ReadyToBootServiceEvent
|
|
);
|
|
ASSERT_EFI_ERROR (Status);
|
|
|
|
//
|
|
// Register Exit Boot Services Event for One Click Recovery
|
|
//
|
|
Status = gBS->CreateEventEx (
|
|
EVT_NOTIFY_SIGNAL,
|
|
TPL_NOTIFY,
|
|
OneClickRecoveryExitBootService,
|
|
NULL,
|
|
&gEfiEventExitBootServicesGuid,
|
|
&ExitBootServiceEvent
|
|
);
|
|
ASSERT_EFI_ERROR (Status);
|
|
return Status;
|
|
}
|
|
|
|
// List of WinRe Boot option supported Parameter types
|
|
STATIC UINT32 mWinReBootOptionParamSupport[] = {
|
|
EfiBootOptionalDataParamType
|
|
};
|
|
|
|
// List of PBA Boot option supported Parameter types
|
|
STATIC UINT32 mPbaBootOptionParamSupport[] = {
|
|
EfiFileDeviceParamType,
|
|
BootImageHashSha256ParamType,
|
|
BootImageHashSha384ParamType,
|
|
BootImageHashSha512ParamType,
|
|
EfiBootOptionalDataParamType
|
|
};
|
|
|
|
// List of Https Boot option supported Parameter types
|
|
STATIC UINT32 mHttpsBootOptionParamSupport[] = {
|
|
EfiNetworkDevicePathParamType,
|
|
HttpsCertSyncRootCaParamType,
|
|
HttpsCertServerNameParamType,
|
|
HttpsServerNameVerifyMethodParamType,
|
|
HttpsServerCertHashSha256ParamType,
|
|
HttpsServerCertHashSha384ParamType,
|
|
HttpsServerCertHashSha512ParamType,
|
|
HttpsRequestTimeOutParamType,
|
|
HttpsDigestUserNameParamType,
|
|
HttpsDigestPasswordParamType
|
|
};
|
|
|
|
/**
|
|
Check if Parameter is supported by OCR Boot Option Type
|
|
|
|
@param[in] BootType OCR Boot Option Type
|
|
@param[in] ParamType OCR Parameter Type
|
|
|
|
@retval TRUE Parameter is supported
|
|
@retval FALSE Parameter isn't supported
|
|
**/
|
|
BOOLEAN
|
|
IsParamSupported (
|
|
IN UINT32 BootType,
|
|
IN UINT32 ParamType
|
|
)
|
|
{
|
|
UINT32 *SupportedBootParam;
|
|
UINT32 SupportedBootParamCount;
|
|
UINT32 Index;
|
|
|
|
switch (BootType) {
|
|
case WinRe:
|
|
SupportedBootParam = mWinReBootOptionParamSupport;
|
|
SupportedBootParamCount = sizeof (mWinReBootOptionParamSupport) / sizeof (UINT32);
|
|
break;
|
|
case Pba:
|
|
SupportedBootParam = mPbaBootOptionParamSupport;
|
|
SupportedBootParamCount = sizeof (mPbaBootOptionParamSupport) / sizeof (UINT32);
|
|
case Https:
|
|
SupportedBootParam = mHttpsBootOptionParamSupport;
|
|
SupportedBootParamCount = sizeof (mHttpsBootOptionParamSupport) / sizeof (UINT32);
|
|
break;
|
|
default:
|
|
return FALSE;
|
|
}
|
|
|
|
for (Index = 0; Index < SupportedBootParamCount; Index++) {
|
|
if (SupportedBootParam[Index] == ParamType) {
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
/**
|
|
Setups up Http Device Path
|
|
|
|
@param[in] OcrParamTlv OCR Parameter TLV
|
|
@param[in,out] BootOption OCR Boot Option
|
|
|
|
@retval EFI_SUCCESS Successful consume OCR Param
|
|
@retval EFI_INVALID_PARAMETER Pointer is NULL or Length is too long
|
|
@retval EFI_UNSUPPORTED Url is not https
|
|
**/
|
|
EFI_STATUS
|
|
NetworkDevicePathParam (
|
|
IN OCR_PARAMETER_TLV *OcrParamTlv,
|
|
IN OUT OCR_BOOT_OPTION *BootOption
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
CHAR16 *DevicePath;
|
|
EFI_DEVICE_PATH_PROTOCOL *HttpDevice;
|
|
UINTN Length;
|
|
CHAR16 UriPath[MAX_UEFI_BOOT_OPTION_DEV_PATH_LENGTH];
|
|
UINTN UriLength;
|
|
|
|
if ((OcrParamTlv == NULL) || (BootOption == NULL) || (OcrParamTlv->Header.Length > MAX_UEFI_BOOT_OPTION_DEV_PATH_LENGTH)) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
HttpDevice = AllocateZeroPool (sizeof (EFI_DEVICE_PATH_PROTOCOL));
|
|
if (HttpDevice == NULL) {
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
|
|
Status = SearchHttpDevicePath (&HttpDevice);
|
|
if (!EFI_ERROR (Status)) {
|
|
DevicePath = ConvertDevicePathToText (HttpDevice, TRUE, TRUE);
|
|
if (DevicePath == NULL) {
|
|
return EFI_NOT_FOUND;
|
|
}
|
|
|
|
if (!IsHttpsUrl ((CHAR8*)OcrParamTlv->Value, OcrParamTlv->Header.Length)) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
Length = StrnLenS (DevicePath, MAX_UEFI_BOOT_OPTION_DEV_PATH_LENGTH)
|
|
+ StrnLenS (L"/Uri()", MAX_UEFI_BOOT_OPTION_DEV_PATH_LENGTH)
|
|
+ OcrParamTlv->Header.Length;
|
|
|
|
if (Length > MAX_UEFI_BOOT_OPTION_DEV_PATH_LENGTH) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
AsciiStrnToUnicodeStrS (
|
|
(CHAR8*)OcrParamTlv->Value,
|
|
OcrParamTlv->Header.Length,
|
|
UriPath,
|
|
MAX_UEFI_BOOT_OPTION_DEV_PATH_LENGTH,
|
|
&UriLength
|
|
);
|
|
|
|
UnicodeSPrint (
|
|
BootOption->DevicePath,
|
|
MAX_UEFI_BOOT_OPTION_DEV_PATH_LENGTH*sizeof(CHAR16),
|
|
L"%s/Uri(%s)",
|
|
DevicePath,
|
|
UriPath
|
|
);
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
/**
|
|
Setups up File Device Path
|
|
|
|
@param[in] OcrParamTlv OCR Parameter TLV
|
|
@param[in,out] BootOption OCR Boot Option
|
|
|
|
@retval EFI_SUCCESS Successful consume OCR Param
|
|
@retval EFI_INVALID_PARAMETER Pointer are NULL or Length is too long
|
|
**/
|
|
EFI_STATUS
|
|
FileDeviceParam (
|
|
IN OCR_PARAMETER_TLV *OcrParamTlv,
|
|
IN OUT OCR_BOOT_OPTION *BootOption
|
|
)
|
|
{
|
|
UINTN Length;
|
|
|
|
if ((OcrParamTlv == NULL) || (BootOption == NULL) || (OcrParamTlv->Header.Length > MAX_UEFI_BOOT_OPTION_DEV_PATH_LENGTH)) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
AsciiStrnToUnicodeStrS (
|
|
(CHAR8*)OcrParamTlv->Value,
|
|
OcrParamTlv->Header.Length,
|
|
BootOption->DevicePath,
|
|
MAX_UEFI_BOOT_OPTION_DEV_PATH_LENGTH,
|
|
&Length
|
|
);
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
Setups up Optional Data Parameter for Boot Option
|
|
|
|
@param[in] OcrParamTlv OCR Parameter TLV
|
|
@param[in,out] BootOption OCR Boot Option
|
|
|
|
@retval EFI_SUCCESS Successful consume OCR Param
|
|
@retval EFI_INVALID_PARAMETER Pointer are NULL or Length is too long
|
|
@retval EFI_OUT_OF_RESOURCES Out of resources
|
|
**/
|
|
EFI_STATUS
|
|
OptionalDataParam (
|
|
IN OCR_PARAMETER_TLV *OcrParamTlv,
|
|
IN OUT OCR_BOOT_OPTION *BootOption
|
|
)
|
|
{
|
|
UINT32 BufferSize;
|
|
UINT8 *Buffer;
|
|
|
|
if ((OcrParamTlv == NULL) || (BootOption == NULL) || (OcrParamTlv->Header.Length > MAX_UEFI_OPTIONAL_DATA) ||
|
|
(BootOption->OptionalData != NULL && BootOption->OptionalDataSize == 0) ||
|
|
(BootOption->OptionalData == NULL && BootOption->OptionalDataSize != 0)) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
if (BootOption->OptionalData == NULL) {
|
|
BufferSize = OcrParamTlv->Header.Length;
|
|
Buffer = AllocatePool (BufferSize);
|
|
} else {
|
|
BufferSize = BootOption->OptionalDataSize + OcrParamTlv->Header.Length;
|
|
Buffer = ReallocatePool (BootOption->OptionalDataSize, BufferSize, BootOption->OptionalData);
|
|
}
|
|
|
|
if (Buffer == NULL) {
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
|
|
BootOption->OptionalData = Buffer;
|
|
CopyMem ((BootOption->OptionalData + BootOption->OptionalDataSize), OcrParamTlv->Value, OcrParamTlv->Header.Length);
|
|
BootOption->OptionalDataSize = BufferSize;
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
Check if Boot Option was requested and add it.
|
|
|
|
@param[in,out] BootOption OCR Boot Option
|
|
|
|
@retval EFI_SUCCESS Successfully consumed OCR Parameters
|
|
@retval EFI_INVALID_PARAMETER parameter pointer is null
|
|
**/
|
|
EFI_STATUS
|
|
SetupOcrBootOptionParams (
|
|
IN OUT OCR_BOOT_OPTION *BootOption
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
OCR_PARAMETER_TLV *OcrParamTlv;
|
|
UINT32 Index;
|
|
|
|
Status = EFI_SUCCESS;
|
|
if (BootOption == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
OcrParamTlv = (OCR_PARAMETER_TLV*)mAmtUefiBootOption.ParametersArray;
|
|
|
|
for (Index = 0; Index < mAmtUefiBootOption.NumberOfParams; Index++) {
|
|
DEBUG ((DEBUG_INFO, "Index:%d ParamTypeId: %d\n length:%d\n", Index, OcrParamTlv->Header.ParamType.ParamTypeId, OcrParamTlv->Header.Length));
|
|
|
|
if (IsParamSupported (mAmtUefiBootOption.UefiBootOptionType, OcrParamTlv->Header.ParamType.ParamTypeId)) {
|
|
switch (OcrParamTlv->Header.ParamType.ParamTypeId) {
|
|
case EfiNetworkDevicePathParamType:
|
|
Status = NetworkDevicePathParam (OcrParamTlv, BootOption);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
break;
|
|
case EfiFileDeviceParamType:
|
|
Status = FileDeviceParam (OcrParamTlv, BootOption);
|
|
break;
|
|
case EfiBootOptionalDataParamType:
|
|
Status = OptionalDataParam (OcrParamTlv, BootOption);
|
|
break;
|
|
case HttpsCertSyncRootCaParamType:
|
|
if (*OcrParamTlv->Value) {
|
|
Status = GetRootCaCertificates ();
|
|
}
|
|
break;
|
|
case HttpsRequestTimeOutParamType:
|
|
Status = SetHttpTimeout (OcrParamTlv);
|
|
break;
|
|
case EfiDevicePathLenParamType:
|
|
case BootImageHashSha256ParamType:
|
|
case BootImageHashSha384ParamType:
|
|
case BootImageHashSha512ParamType:
|
|
case HttpsCertServerNameParamType:
|
|
case HttpsServerNameVerifyMethodParamType:
|
|
case HttpsServerCertHashSha256ParamType:
|
|
case HttpsServerCertHashSha384ParamType:
|
|
case HttpsServerCertHashSha512ParamType:
|
|
case HttpsDigestUserNameParamType:
|
|
case HttpsDigestPasswordParamType:
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Increment to next OcrParamTlv
|
|
OcrParamTlv = (OCR_PARAMETER_TLV*)(((UINT8 *)OcrParamTlv) + sizeof (OCR_PARAMETER_TLV_HEADER) + OcrParamTlv->Header.Length);
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
/**
|
|
Setup OCR Boot Option if requested from AMT
|
|
|
|
@param[in] ME_SETUP ME Setup Configuration
|
|
|
|
@retval EFI_SUCCESS OCR Boot Option is setup.
|
|
@retval EFI_NOT_FOUND OCR was not requested.
|
|
@retval EFI_OUT_OF_RESOURCES Ran out of resources
|
|
@retval EFI_ABORTED Boot Option requested is not valid
|
|
@retval EFI_SECURITY_VIOLATION Secure Boot needs to be enable for OCR WinRe and PBA
|
|
**/
|
|
EFI_STATUS
|
|
OcrBootOptionRequest (
|
|
IN ME_SETUP MeSetup
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
CHAR16* Description;
|
|
CHAR16* WinReOptionalData;
|
|
UINT8 SecureBootState;
|
|
UINTN VarSize;
|
|
//[-start-211111-IB09480171-remove]//
|
|
// UINT32 VarAttributes;
|
|
//[-end-211111-IB09480171-remove]//
|
|
OCR_BOOT_SETTINGS OcrBootSettings;
|
|
AMT_BOOT_CONTROL LoadOptionType;
|
|
UINT16 SpecialCommand;
|
|
|
|
WinReOptionalData = L"/RecoveryBCD";
|
|
LoadOptionType.Uint32 = 0;
|
|
|
|
SpecialCommand = AsfGetSpecialCommand ();
|
|
|
|
if (SpecialCommand != ASF_INTEL_OEM_FORCE_HTTPS_BOOT_CMD &&
|
|
SpecialCommand != ASF_INTEL_OEM_FORCE_PBA_BOOT_CMD) {
|
|
DEBUG ((DEBUG_INFO, "OCR was not requested.\n"));
|
|
return EFI_NOT_FOUND;
|
|
}
|
|
|
|
// report in progress Bios Status to AMT
|
|
Status = ReportBiosStatus (AsfRbsInProgress);
|
|
|
|
mOcrBootOption = AllocateZeroPool (sizeof (OCR_BOOT_OPTION));
|
|
if (mOcrBootOption == NULL) {
|
|
CancelOcrBootOption ();
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
|
|
// Check that system supports requested OCR boot option
|
|
if (SpecialCommand == ASF_INTEL_OEM_FORCE_HTTPS_BOOT_CMD &&
|
|
mAmtUefiBootOption.UefiBootOptionType == Https &&
|
|
MeSetup.OcrBootHttps == 1 &&
|
|
mOcrCap.Bits.OcrBootHttps == ONE_CLICK_RECOVERY_HTTPS_BOOT_CAPABLE) {
|
|
// OCR HTTPS Boot was requested
|
|
Description = L" HTTPS";
|
|
LoadOptionType.Bits.AmtTrigBootToHttps = 1;
|
|
} else if (SpecialCommand == ASF_INTEL_OEM_FORCE_PBA_BOOT_CMD &&
|
|
mAmtUefiBootOption.UefiBootOptionType == Pba &&
|
|
MeSetup.OcrBootPba == 1 &&
|
|
mOcrCap.Bits.OcrBootPba == ONE_CLICK_RECOVERY_PBA_BOOT_CAPABLE) {
|
|
// OCR PBA Boot was requested
|
|
Description = L" PBA";
|
|
LoadOptionType.Bits.AmtTrigBootToPba = 1;
|
|
} else if (SpecialCommand == ASF_INTEL_OEM_FORCE_PBA_BOOT_CMD &&
|
|
mAmtUefiBootOption.UefiBootOptionType == WinRe &&
|
|
MeSetup.OcrBootWinRe == 1 &&
|
|
mOcrCap.Bits.OcrBootWinRe == ONE_CLICK_RECOVERY_WIN_RE_BOOT_CAPABLE) {
|
|
// OCR Win Re Boot was requested
|
|
Description = L" WinRe";
|
|
LoadOptionType.Bits.AmtTrigBootToWinRe = 1;
|
|
|
|
// add Optional Data to launch WinRe
|
|
mOcrBootOption->OptionalDataSize = (UINT32) StrSize (WinReOptionalData);
|
|
mOcrBootOption->OptionalData = AllocatePool (mOcrBootOption->OptionalDataSize);
|
|
if (mOcrBootOption->OptionalData == NULL) {
|
|
CancelOcrBootOption ();
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
CopyMem (mOcrBootOption->OptionalData, WinReOptionalData, mOcrBootOption->OptionalDataSize);
|
|
} else {
|
|
DEBUG ((DEBUG_INFO, "Boot Option Request is not supported.\n"));
|
|
CancelOcrBootOption ();
|
|
return EFI_ABORTED;
|
|
}
|
|
|
|
// Check to make sure Secure Boot is enabled for PBA or WinRe
|
|
if (mAmtUefiBootOption.UefiBootOptionType == WinRe || mAmtUefiBootOption.UefiBootOptionType == Pba) {
|
|
VarSize = sizeof (UINT8);
|
|
//[-start-211111-IB09480171-modify]//
|
|
// Status = gRT->GetVariable (
|
|
// EFI_SECURE_BOOT_ENABLE_NAME,
|
|
// &gEfiSecureBootEnableDisableGuid,
|
|
// &VarAttributes,
|
|
// &VarSize,
|
|
// &SecureBootState
|
|
// );
|
|
// if (EFI_ERROR (Status)) {
|
|
// CancelOcrBootOption ();
|
|
// return Status;
|
|
// }
|
|
|
|
SecureBootState = GetSecureBootState();
|
|
//[-end-211111-IB09480171-modify]//
|
|
|
|
if (SecureBootState == SECURE_BOOT_DISABLE) {
|
|
DEBUG ((DEBUG_INFO, "OCR PBA or WinRe cannot be setup without Secure Boot Enabled\n"));
|
|
CancelOcrBootOption ();
|
|
return EFI_SECURITY_VIOLATION;
|
|
}
|
|
}
|
|
|
|
// Set Boot Option Description
|
|
Status = CreateOcrBootOptionDescription (Description, mOcrBootOption->Description, MAX_UEFI_BOOT_OPTION_DESC_LENGTH);
|
|
if (EFI_ERROR (Status)) {
|
|
CancelOcrBootOption ();
|
|
return Status;
|
|
}
|
|
|
|
if (mAmtUefiBootOption.EfiDevicePathLen != 0) {
|
|
// Convert Device Path back to Unicode
|
|
Status = AsciiStrToUnicodeStrS (
|
|
(CHAR8 *) &mAmtUefiBootOption.EfiDevicePath,
|
|
mOcrBootOption->DevicePath,
|
|
MAX_UEFI_BOOT_OPTION_DEV_PATH_LENGTH
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
CancelOcrBootOption ();
|
|
return Status;
|
|
}
|
|
}
|
|
|
|
Status = SetupOcrBootOptionParams (mOcrBootOption);
|
|
if (EFI_ERROR (Status)) {
|
|
CancelOcrBootOption ();
|
|
return Status;
|
|
}
|
|
|
|
//[-start-211215-IB09480180-add]//
|
|
if (mAmtUefiBootOption.UefiBootOptionType == Pba) {
|
|
Status = UpdatePbaDevPath (mOcrBootOption);
|
|
}
|
|
//[-end-211215-IB09480180-add]//
|
|
|
|
DEBUG ((DEBUG_INFO, "OCR Boot request\n devicepath: %s\n devicepath len:0x%x\n UEFItype: 0x%x", mOcrBootOption->DevicePath, mAmtUefiBootOption.EfiDevicePathLen, mAmtUefiBootOption.UefiBootOptionType));
|
|
DEBUG ((DEBUG_INFO, " numofparam: 0x%x\n length:0x%x\n", mAmtUefiBootOption.NumberOfParams, mAmtUefiBootOption.LengthOfParamsArray));
|
|
|
|
Status = AddOcrBootOption (mOcrBootOption);
|
|
if (EFI_ERROR (Status)) {
|
|
CancelOcrBootOption ();
|
|
return Status;
|
|
}
|
|
|
|
if (AsfIsFwProgressEnabled ()) {
|
|
Status = SendOcrPetEvent (
|
|
ASF_EVENT_OFFSET_ONE_CLICK_RECOVERY_PROGRESS,
|
|
ASF_OCR_EVENT_DATA3_CSME_BOOT_OPTION_ADDED,
|
|
(UINT8) LoadOptionType.Uint32
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_INFO, "OCR failed to report PET event for adding OCR Boot option\n"));
|
|
}
|
|
}
|
|
|
|
//
|
|
// Set variable to delete OCR boot option if system is power off before
|
|
//
|
|
OcrBootSettings = GetOcrBootSettings ();
|
|
OcrBootSettings.BootOptionExists = 1;
|
|
Status = gRT->SetVariable (
|
|
OCR_BOOT_SETTINGS_NAME,
|
|
&mOcrBootSettingsGuid,
|
|
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
|
|
sizeof (OCR_BOOT_SETTINGS),
|
|
&OcrBootSettings
|
|
);
|
|
ASSERT_EFI_ERROR (Status);
|
|
|
|
Status = RegisterOneClickRecoveryCallback ();
|
|
if (EFI_ERROR (Status)) {
|
|
CancelOcrBootOption ();
|
|
return Status;
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
/**
|
|
This routine disables Secure Boot if requested for One Click Recovery.
|
|
|
|
@param[in] MeSetup ME Setup Configuration
|
|
|
|
@retval EFI_SUCCESS Successful
|
|
@retval EFI_ABORTED Unable to get Secure Boot EFI Variable
|
|
**/
|
|
EFI_STATUS
|
|
OcrDisableSecureBootState (
|
|
IN ASF_BOOT_OPTIONS AsfBootOptions
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINTN VarSize;
|
|
//[-start-211111-IB09480171-remove]//
|
|
// UINT32 VarAttributes;
|
|
//[-end-211111-IB09480171-remove]//
|
|
ME_SETUP MeSetup;
|
|
UINT8 SecureBootState;
|
|
OCR_BOOT_SETTINGS OcrBootSettings;
|
|
BOOLEAN EnforceSecureBoot;
|
|
BOOLEAN OcrHttpsBoot;
|
|
|
|
OcrBootSettings = GetOcrBootSettings ();
|
|
EnforceSecureBoot = (AsfBootOptions.SpecialCommandParamLowByte & ENFORCE_SECURE_BOOT) == ENFORCE_SECURE_BOOT;;
|
|
OcrHttpsBoot = AsfBootOptions.SpecialCommand == ASF_INTEL_OEM_FORCE_HTTPS_BOOT_CMD;
|
|
|
|
VarSize = sizeof (ME_SETUP);
|
|
Status = gRT->GetVariable (
|
|
L"MeSetup",
|
|
&gMeSetupVariableGuid,
|
|
NULL,
|
|
&VarSize,
|
|
&MeSetup
|
|
);
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
VarSize = sizeof (UINT8);
|
|
//[-start-211111-IB09480171-modify]//
|
|
// Status = gRT->GetVariable (
|
|
// EFI_SECURE_BOOT_ENABLE_NAME,
|
|
// &gEfiSecureBootEnableDisableGuid,
|
|
// &VarAttributes,
|
|
// &VarSize,
|
|
// &SecureBootState
|
|
// );
|
|
// if (EFI_ERROR (Status)) {
|
|
// return EFI_ABORTED;
|
|
// }
|
|
|
|
SecureBootState = GetSecureBootState();
|
|
//[-end-211111-IB09480171-modify]//
|
|
|
|
if (mOcrCap.Bits.OcrAmtDisSecBoot == ONE_CLICK_RECOVERY_DIS_SEC_BOOT_CAPABLE &&
|
|
MeSetup.OcrAmtDisSecBoot == 1 &&
|
|
SecureBootState == SECURE_BOOT_ENABLE &&
|
|
OcrHttpsBoot &&
|
|
!EnforceSecureBoot) {
|
|
// Secure Boot needs to be disabled if were doing One Click Recovery HTTPS Boot and Enforce Secure Boot is not set
|
|
SecureBootState = SECURE_BOOT_DISABLE;
|
|
|
|
//[-start-211111-IB09480171-modify]//
|
|
// Status = gRT->SetVariable (
|
|
// L"SecureBootEnable",
|
|
// &gEfiSecureBootEnableDisableGuid,
|
|
// VarAttributes,
|
|
// sizeof (UINT8),
|
|
// &SecureBootState
|
|
// );
|
|
// ASSERT_EFI_ERROR (Status);
|
|
|
|
AsfSecureBootChangedSmiCall(SecureBootState, PcdGet16(PcdSoftwareSmiPort));
|
|
//[-end-211111-IB09480171-modify]//
|
|
|
|
// Set variable to restore previous secure boot state
|
|
OcrBootSettings.RestoreSecureBootSetting = RESTORE_SECURE_BOOT_ENABLED;
|
|
Status = gRT->SetVariable (
|
|
OCR_BOOT_SETTINGS_NAME,
|
|
&mOcrBootSettingsGuid,
|
|
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
|
|
sizeof (OCR_BOOT_SETTINGS),
|
|
&OcrBootSettings
|
|
);
|
|
ASSERT_EFI_ERROR (Status);
|
|
DEBUG ((DEBUG_INFO, "Secure Boot disabled for OCR HTTPS Boot - Cold Reset!\n"));
|
|
gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL);
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
This routine restores Secure Boot for One Click Recovery.
|
|
|
|
@retval EFI_SUCCESS Successful
|
|
@retval EFI_ABORTED Unable to get Secure Boot EFI Variable
|
|
**/
|
|
EFI_STATUS
|
|
OcrRestoreSecureBootState (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINTN VarSize;
|
|
//[-start-211111-IB09480171-remove]//
|
|
// UINT32 VarAttributes;
|
|
//[-end-211111-IB09480171-remove]//
|
|
UINT8 SecureBootState;
|
|
OCR_BOOT_SETTINGS OcrBootSettings;
|
|
BOOLEAN EnforceSecureBoot;
|
|
BOOLEAN OcrHttpsBoot;
|
|
|
|
VarSize = sizeof (UINT8);
|
|
OcrBootSettings = GetOcrBootSettings ();
|
|
EnforceSecureBoot = (AsfGetSpecialCmdParamLowByte () & ENFORCE_SECURE_BOOT) == ENFORCE_SECURE_BOOT;
|
|
OcrHttpsBoot = (AsfGetSpecialCommand () == ASF_INTEL_OEM_FORCE_HTTPS_BOOT_CMD);
|
|
|
|
//[-start-211111-IB09480171-modify]//
|
|
// Status = gRT->GetVariable (
|
|
// EFI_SECURE_BOOT_ENABLE_NAME,
|
|
// &gEfiSecureBootEnableDisableGuid,
|
|
// &VarAttributes,
|
|
// &VarSize,
|
|
// &SecureBootState
|
|
// );
|
|
// if (EFI_ERROR (Status)) {
|
|
// return EFI_ABORTED;
|
|
// }
|
|
|
|
SecureBootState = GetSecureBootState();
|
|
//[-end-211111-IB09480171-modify]//
|
|
|
|
if (OcrBootSettings.RestoreSecureBootSetting == RESTORE_SECURE_BOOT_ENABLED &&
|
|
SecureBootState == SECURE_BOOT_DISABLE &&
|
|
!(OcrHttpsBoot && !EnforceSecureBoot)) {
|
|
// Secure boot need to be re-enable from previous One Click Recovery HTTPS Boot
|
|
SecureBootState = SECURE_BOOT_ENABLE;
|
|
OcrBootSettings.RestoreSecureBootSetting = RESTORE_SECURE_BOOT_NONE;
|
|
//[-start-211111-IB09480171-modify]//
|
|
// Status = gRT->SetVariable (
|
|
// L"SecureBootEnable",
|
|
// &gEfiSecureBootEnableDisableGuid,
|
|
// VarAttributes,
|
|
// VarSize,
|
|
// &SecureBootState
|
|
// );
|
|
// ASSERT_EFI_ERROR (Status);
|
|
|
|
AsfSecureBootChangedSmiCall(SecureBootState, PcdGet16(PcdSoftwareSmiPort));
|
|
//[-end-211111-IB09480171-modify]//
|
|
|
|
Status = gRT->SetVariable (
|
|
OCR_BOOT_SETTINGS_NAME,
|
|
&mOcrBootSettingsGuid,
|
|
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
|
|
sizeof (OCR_BOOT_SETTINGS),
|
|
&OcrBootSettings
|
|
);
|
|
ASSERT_EFI_ERROR (Status);
|
|
DEBUG ((DEBUG_INFO, "Secure Boot settings restored after OCR HTTPS Boot - Cold Reset!\n"));
|
|
gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL);
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
The Intel One Click Recovery Setup main function.
|
|
|
|
The function does the necessary work to Setup the One Click Recovery feature.
|
|
|
|
@retval EFI_SUCCESS One Click Recovery tasks have been ran
|
|
@retval EFI_UNSUPPORTED One Click Recovery is not supported
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
OneClickRecoveryMain (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UEFI_BOOT_OPTION *UefiBootOptions;
|
|
UINT16 NumOfUefiBootOptions;
|
|
ME_SETUP MeSetup;
|
|
UINTN VariableSize;
|
|
|
|
DEBUG ((DEBUG_INFO, "OneClickRecovery setup\n"));
|
|
|
|
VariableSize = sizeof (ME_SETUP);
|
|
Status = gRT->GetVariable (
|
|
L"MeSetup",
|
|
&gMeSetupVariableGuid,
|
|
NULL,
|
|
&VariableSize,
|
|
&MeSetup
|
|
);
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
// Restore Secure Boot State from pre-existing OCR HTTPS
|
|
OcrRestoreSecureBootState ();
|
|
|
|
// Delete pre-existing OCR Boot Options
|
|
DeleteOcrBootOption ();
|
|
|
|
// Check for a pending OCR request and set it up
|
|
Status = OcrBootOptionRequest (MeSetup);
|
|
|
|
// If OCR boot is setup, skip syncing available boot options and boot states
|
|
if (EFI_ERROR (Status)) {
|
|
SetUefiBootOptionsState (MeSetup);
|
|
|
|
// Allocate Boot Options list
|
|
NumOfUefiBootOptions = 0;
|
|
UefiBootOptions = AllocateZeroPool (MAX_UEFI_BOOT_OPTIONS * sizeof (UEFI_BOOT_OPTION));
|
|
|
|
if (UefiBootOptions == NULL) {
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
|
|
// Add PBA Boot Options
|
|
if (MeSetup.OcrBootPba == 1 && mOcrCap.Bits.OcrBootPba == ONE_CLICK_RECOVERY_PBA_BOOT_CAPABLE) {
|
|
AddOemPbaBootOptions (UefiBootOptions, &NumOfUefiBootOptions);
|
|
}
|
|
|
|
// Add WinRe Boot Options
|
|
if (MeSetup.OcrBootWinRe == 1 && mOcrCap.Bits.OcrBootWinRe == ONE_CLICK_RECOVERY_WIN_RE_BOOT_CAPABLE) {
|
|
AddWinReBootOptions (UefiBootOptions, &NumOfUefiBootOptions);
|
|
}
|
|
|
|
Status = AsfUpdateUefiBootOptions (UefiBootOptions, NumOfUefiBootOptions);
|
|
|
|
if (UefiBootOptions != NULL) {
|
|
FreePool(UefiBootOptions);
|
|
}
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
Saves OCR Uefi Boot Option from AMT.
|
|
|
|
Needs to Be called before Clear Boot Options.
|
|
|
|
@retval EFI_SUCCESS Saved Boot Option
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
OneClickRecoverySaveUefiBootOption (
|
|
IN ASF_BOOT_OPTIONS AsfBootOptions
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
|
|
// Disable Secure Boot if requested
|
|
OcrDisableSecureBootState (AsfBootOptions);
|
|
|
|
// Get Asf UEFI Boot Option
|
|
Status = AsfGetUefiBootParameters (&mAmtUefiBootOption);
|
|
|
|
if (AsfBootOptions.BootOptionsMaskByte2 & FORCE_PROGRESS_EVENTS) {
|
|
SendOcrPetEvent (ASF_EVENT_OFFSET_ONE_CLICK_RECOVERY_PROGRESS, ASF_OCR_EVENT_DATA3_BOOT_PARAMETER_RECEIVED, 0);
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
/**
|
|
Entry point of the Intel One Click Recovery Setup DXE Driver
|
|
|
|
Installs the One Click Recovery Setup Protocol for other functions to locate and use
|
|
|
|
@param[in] ImageHandle Handle for this drivers loaded image protocol.
|
|
@param[in] SystemTable EFI system table.
|
|
|
|
@retval EFI_SUCCESS The protocol has installed successfully
|
|
@retval EFI_UNSUPPORTED The protocol is not supported
|
|
@retval Others The protocol did not install successfully
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
OneClickRecoveryEntryPoint (
|
|
IN EFI_HANDLE ImageHandle,
|
|
IN EFI_SYSTEM_TABLE *SystemTable
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
|
|
mOcrCap = OneClickRecoveryCapabilities ();
|
|
|
|
if (!IsOcrSupported ()) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
ZeroMem ((VOID *) &mAmtUefiBootOption, sizeof (UEFI_BOOT_OPTION_PARAMETER));
|
|
|
|
Status = gBS->InstallMultipleProtocolInterfaces (
|
|
&ImageHandle,
|
|
&gOneClickRecoveryProtocolGuid,
|
|
&mOneClickRecoveryProtocol,
|
|
NULL
|
|
);
|
|
|
|
ASSERT_EFI_ERROR (Status);
|
|
DEBUG ((DEBUG_INFO, "OneClickRecovery Protocol Install Status: %r\n", Status));
|
|
|
|
return Status;
|
|
}
|