963 lines
34 KiB
C
963 lines
34 KiB
C
/** @file
|
|
Initial and callback functions for Boot page of SetupUtilityLib
|
|
|
|
;******************************************************************************
|
|
;* Copyright (c) 2012 - 2021, Insyde Software Corp. 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.
|
|
;*
|
|
;******************************************************************************
|
|
*/
|
|
|
|
#include "Boot.h"
|
|
|
|
STATIC EFI_CALLBACK_INFO *mBootCallBackInfo;
|
|
BOOT_CONFIGURATION mBootConfig;
|
|
NETWORK_CONFIGURATION mNetworkConfig;
|
|
|
|
/**
|
|
Initialize boot menu for setuputility use
|
|
|
|
@param HiiHandle Hii hanlde for the call back routine
|
|
|
|
@retval EFI_SUCCESS Function has completed successfully.
|
|
@return Other Error occurred during execution.
|
|
|
|
**/
|
|
STATIC
|
|
EFI_STATUS
|
|
InitBootMenu (
|
|
IN EFI_HII_HANDLE HiiHandle
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINT16 *BootOrder;
|
|
UINT16 BootDeviceNum;
|
|
UINTN BootOrderSize;
|
|
SETUP_UTILITY_BROWSER_DATA *SuBrowser;
|
|
UINT16 Timeout;
|
|
UINTN Size;
|
|
UINTN NetworkConfigBufferSize;
|
|
NETWORK_CONFIGURATION *NetworConfigBuffer;
|
|
|
|
Status = GetSetupUtilityBrowserData (&SuBrowser);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
//
|
|
// Sync Timeout variable to timeout value of Setup variable.
|
|
//
|
|
Timeout = 0;
|
|
Size = sizeof(UINT16);
|
|
Status = CommonGetVariable (
|
|
L"Timeout",
|
|
&gEfiGlobalVariableGuid,
|
|
&Size,
|
|
&Timeout
|
|
);
|
|
if (!EFI_ERROR(Status) && Timeout != ((KERNEL_CONFIGURATION *) SuBrowser->SCBuffer)->Timeout) {
|
|
((KERNEL_CONFIGURATION *) SuBrowser->SCBuffer)->Timeout = Timeout;
|
|
}
|
|
|
|
GetLegacyBootDevType (
|
|
&(SuBrowser->SUCInfo->LegacyBootDevTypeCount),
|
|
&(SuBrowser->SUCInfo->LegacyBootDevType)
|
|
);
|
|
|
|
BootOrder = NULL;
|
|
BootOrderSize = 0;
|
|
CommonGetVariableDataAndSize (
|
|
L"BootOrder",
|
|
&gEfiGlobalVariableGuid,
|
|
&BootOrderSize,
|
|
(VOID **) &BootOrder
|
|
);
|
|
if (BootOrderSize != 0) {
|
|
BootDeviceNum = (UINT16) (BootOrderSize / sizeof(UINT16));
|
|
} else {
|
|
BootDeviceNum = 0;
|
|
BootOrder = NULL;
|
|
}
|
|
|
|
SuBrowser->SUCInfo->BootOrder = BootOrder;
|
|
SuBrowser->SUCInfo->AdvBootDeviceNum = BootDeviceNum;
|
|
|
|
NetworConfigBuffer = NULL;
|
|
Status = CommonGetVariableDataAndSize (
|
|
SETUP_NETWORK_VARIABLE_NAME,
|
|
&gSystemConfigurationGuid,
|
|
&NetworkConfigBufferSize,
|
|
(VOID **) &NetworConfigBuffer
|
|
);
|
|
if (Status == EFI_NOT_FOUND){
|
|
mNetworkConfig.NetworkProtocolRetryTime = PcdGet8(PcdH2OPxeCheckMediaRetryCount);
|
|
} else if (!EFI_ERROR (Status)) {
|
|
CopyMem (&mNetworkConfig, NetworConfigBuffer, sizeof(NETWORK_CONFIGURATION));
|
|
FreePool (NetworConfigBuffer);
|
|
NetworConfigBuffer = NULL;
|
|
}
|
|
|
|
BootDevInfoInit ();
|
|
Status = UpdateBootOrderLabels (
|
|
HiiHandle,
|
|
(KERNEL_CONFIGURATION *) SuBrowser->SCBuffer
|
|
);
|
|
|
|
BootConfigInit (SuBrowser);
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
Load the default value of boot configuration varstore.
|
|
|
|
@retval EFI_SUCCESS Load the default value successfully.
|
|
@retval Other Fail to load the default value of boot configuration varstore.
|
|
**/
|
|
EFI_STATUS
|
|
BootLoadDefault (
|
|
VOID
|
|
)
|
|
{
|
|
return BootConfigLoadDefault ();
|
|
}
|
|
|
|
/**
|
|
Save the current settings of all varstores belong to NETWORK_CONFIGURATION.
|
|
|
|
@retval EFI_SUCCESS Save the current settings successfully
|
|
@retval Other Fail to save the current settings of security configuration or fail to get browser data.
|
|
**/
|
|
EFI_STATUS
|
|
NetworkSaveSetting (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
|
|
SetupVariableConfig (&gSystemConfigurationGuid, L"NetworkConfig", sizeof (NETWORK_CONFIGURATION), (UINT8 *) &mNetworkConfig , TRUE);
|
|
Status = gRT->SetVariable(
|
|
SETUP_NETWORK_VARIABLE_NAME,
|
|
&gSystemConfigurationGuid,
|
|
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
|
|
sizeof (NETWORK_CONFIGURATION),
|
|
&mNetworkConfig
|
|
);
|
|
|
|
return Status;
|
|
}
|
|
|
|
|
|
/**
|
|
Save the current settings of all varstores belong to Boot VFR.
|
|
|
|
@retval EFI_SUCCESS Save the current settings successfully
|
|
@retval Other Fail to save the current settings of boot configuration or fail to get browser data.
|
|
**/
|
|
EFI_STATUS
|
|
BootSaveSetting (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
SETUP_UTILITY_BROWSER_DATA *SuBrowser;
|
|
SETUP_UTILITY_CONFIGURATION *SUCInfo;
|
|
KERNEL_CONFIGURATION *KernelConfig;
|
|
|
|
Status = NetworkSaveSetting ();
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_ERROR, "NetworkSaveSetting failed!\n"));
|
|
}
|
|
|
|
Status = GetSetupUtilityBrowserData (&SuBrowser);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
SUCInfo = SuBrowser->SUCInfo;
|
|
KernelConfig = (KERNEL_CONFIGURATION *) SuBrowser->SCBuffer;
|
|
|
|
gRT->SetVariable (
|
|
L"BootOrder",
|
|
&gEfiGlobalVariableGuid,
|
|
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
|
|
SUCInfo->AdvBootDeviceNum * sizeof (UINT16),
|
|
(UINT16 *) SUCInfo->BootOrder
|
|
);
|
|
|
|
gRT->SetVariable (
|
|
L"Timeout",
|
|
&gEfiGlobalVariableGuid,
|
|
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
|
|
sizeof (UINT16),
|
|
(UINT16 *) &KernelConfig->Timeout
|
|
);
|
|
|
|
return BootConfigSaveSetting ();
|
|
}
|
|
|
|
/**
|
|
This function is called by the forms browser in response to a user action on a question which has the
|
|
EFI_IFR_FLAG_CALLBACK bit set in the EFI_IFR_QUESTION_HEADER. The user action is specified by Action.
|
|
Depending on the action, the browser may also pass the question value using Type and Value. Upon return,
|
|
the callback function may specify the desired browser action. Callback functions should return
|
|
EFI_UNSUPPORTEDfor all values of Action that they do not support.
|
|
|
|
@param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
|
|
@param Action Specifies the type of action taken by the browser.
|
|
@param QuestionId A unique value which is sent to the original exporting driver so that it can identify the
|
|
type of data to expect. The format of the data tends to vary based on the opcode that
|
|
generated the callback.
|
|
@param Type The type of value for the question.
|
|
@param Value A pointer to the data being sent to the original exporting driver. The type is specified
|
|
by Type. Type EFI_IFR_TYPE_VALUE is defined in EFI_IFR_ONE_OF_OPTION.
|
|
@param ActionRequest On return, points to the action requested by the callback function. Type
|
|
EFI_BROWSER_ACTION_REQUEST is specified in SendForm() in the Form Browser Protocol.
|
|
|
|
@retval EFI_SUCCESS The callback successfully handled the action.
|
|
@retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the variable and its data.
|
|
@retval EFI_DEVICE_ERROR The variable could not be saved.
|
|
@return EFI_UNSUPPORTED The specified Action is not supported by the callback.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
BootCallbackRoutine (
|
|
IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
|
|
IN EFI_BROWSER_ACTION Action,
|
|
IN EFI_QUESTION_ID QuestionId,
|
|
IN UINT8 Type,
|
|
IN EFI_IFR_TYPE_VALUE *Value,
|
|
OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
KERNEL_CONFIGURATION *MyIfrNVData;
|
|
SETUP_UTILITY_CONFIGURATION *SUCInfo;
|
|
EFI_CALLBACK_INFO *CallbackInfo;
|
|
SETUP_UTILITY_BROWSER_DATA *SuBrowser;
|
|
UINTN BufferSize;
|
|
EFI_GUID VarStoreGuid = SYSTEM_CONFIGURATION_GUID;
|
|
BOOT_DEV_INFO *BootDevInfo;
|
|
BOOLEAN RetrieveData;
|
|
|
|
if (Action != EFI_BROWSER_ACTION_CHANGED) {
|
|
return BootCallbackRoutineByAction (This, Action, QuestionId, Type, Value, ActionRequest);
|
|
}
|
|
|
|
*ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;
|
|
CallbackInfo = EFI_CALLBACK_INFO_FROM_THIS (This);
|
|
|
|
Status = GetSetupUtilityBrowserData (&SuBrowser);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
|
|
BufferSize = GetVarStoreSize (CallbackInfo->HiiHandle, &CallbackInfo->FormsetGuid, &VarStoreGuid, "SystemConfig");
|
|
|
|
SUCInfo = SuBrowser->SUCInfo;
|
|
RetrieveData = TRUE;
|
|
SetupVariableConfig (&VarStoreGuid, L"SystemConfig", BufferSize , (UINT8 *) SuBrowser->SCBuffer, RetrieveData);
|
|
SetupVariableConfig (&VarStoreGuid, L"BootConfig" , sizeof (BOOT_CONFIGURATION), (UINT8 *) &mBootConfig , RetrieveData);
|
|
MyIfrNVData = (KERNEL_CONFIGURATION *) SuBrowser->SCBuffer;
|
|
|
|
switch (QuestionId) {
|
|
|
|
case KEY_UP_SHIFT:
|
|
case KEY_DOWN_SHIFT:
|
|
if (Type != EFI_IFR_TYPE_NUM_SIZE_32) {
|
|
break;
|
|
}
|
|
|
|
Status = Shiftitem (
|
|
This,
|
|
(EFI_QUESTION_ID) Value->u16,
|
|
(BOOLEAN) (QuestionId == KEY_UP_SHIFT),
|
|
MyIfrNVData
|
|
);
|
|
break;
|
|
|
|
case KEY_BOOT_MENU_TYPE:
|
|
case KEY_NORMAL_BOOT_PRIORITY:
|
|
case KEY_LEGACY_NORMAL_BOOT_MENU:
|
|
if (QuestionId == KEY_NORMAL_BOOT_PRIORITY) {
|
|
AdjustBootOrder (
|
|
!((BOOLEAN) MyIfrNVData->BootNormalPriority),
|
|
SUCInfo->AdvBootDeviceNum,
|
|
SUCInfo->BootOrder
|
|
);
|
|
}
|
|
SetupUtilityLibUpdateDeviceString (CallbackInfo->HiiHandle, MyIfrNVData);
|
|
SyncBootOrderToBootConfig ();
|
|
break;
|
|
|
|
case KEY_NEW_POSITION_POLICY:
|
|
//
|
|
// If change New Added postion policy to auto, we need adjust boot oreder to suit the
|
|
// auto position policy
|
|
//
|
|
if (MyIfrNVData->NewPositionPolicy == IN_AUTO) {
|
|
ChangeToAutoBootOrder (
|
|
SUCInfo->AdvBootDeviceNum,
|
|
SUCInfo->BootOrder
|
|
);
|
|
SetupUtilityLibUpdateDeviceString (CallbackInfo->HiiHandle, MyIfrNVData);
|
|
SyncBootOrderToBootConfig ();
|
|
}
|
|
break;
|
|
|
|
case KEY_BOOT_MODE_TYPE:
|
|
switch (MyIfrNVData->BootType) {
|
|
|
|
case EFI_BOOT_TYPE:
|
|
if (MyIfrNVData->NetworkProtocol == UEFI_NETWORK_BOOT_OPTION_LEGACY) {
|
|
MyIfrNVData->NetworkProtocol = UEFI_NETWORK_BOOT_OPTION_DISABLE;
|
|
}
|
|
break;
|
|
|
|
case LEGACY_BOOT_TYPE:
|
|
if (MyIfrNVData->NetworkProtocol != UEFI_NETWORK_BOOT_OPTION_LEGACY && MyIfrNVData->NetworkProtocol != UEFI_NETWORK_BOOT_OPTION_DISABLE) {
|
|
MyIfrNVData->NetworkProtocol = UEFI_NETWORK_BOOT_OPTION_DISABLE;
|
|
}
|
|
break;
|
|
}
|
|
Status = SuBrowser->HotKeyCallback (
|
|
This,
|
|
Action,
|
|
QuestionId,
|
|
Type,
|
|
Value,
|
|
ActionRequest
|
|
);
|
|
break;
|
|
|
|
case KEY_PXE_BOOT_TO_LAN:
|
|
//
|
|
// Modify NetworkProtocol to DISABLE if PxeBootToLan switch to DISABLED.
|
|
//
|
|
MyIfrNVData->NetworkProtocol = UEFI_NETWORK_BOOT_OPTION_DISABLE;
|
|
break;
|
|
|
|
default:
|
|
BootDevInfo = GetBootDevInfo (QuestionId);
|
|
if (BootDevInfo != NULL) {
|
|
if (Type == EFI_IFR_TYPE_BOOLEAN && Value != NULL) {
|
|
BootDevInfoSetActiveValue (BootDevInfo->BootOptionNum, Value->b);
|
|
}
|
|
break;
|
|
}
|
|
|
|
Status = SuBrowser->HotKeyCallback (
|
|
This,
|
|
Action,
|
|
QuestionId,
|
|
Type,
|
|
Value,
|
|
ActionRequest
|
|
);
|
|
break;
|
|
}
|
|
|
|
RetrieveData = FALSE;
|
|
SetupVariableConfig (&VarStoreGuid, L"SystemConfig", BufferSize , (UINT8 *) SuBrowser->SCBuffer, RetrieveData);
|
|
SetupVariableConfig (&VarStoreGuid, L"BootConfig" , sizeof (BOOT_CONFIGURATION), (UINT8 *) &mBootConfig , RetrieveData);
|
|
|
|
return Status;
|
|
}
|
|
|
|
EFI_STATUS
|
|
BootCallbackRoutineByAction (
|
|
IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
|
|
IN EFI_BROWSER_ACTION Action,
|
|
IN EFI_QUESTION_ID QuestionId,
|
|
IN UINT8 Type,
|
|
IN EFI_IFR_TYPE_VALUE *Value,
|
|
OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
SETUP_UTILITY_BROWSER_DATA *SuBrowser;
|
|
EFI_CALLBACK_INFO *CallbackInfo;
|
|
UINTN BufferSize;
|
|
EFI_GUID VarStoreGuid = SYSTEM_CONFIGURATION_GUID;
|
|
EFI_IFR_TYPE_VALUE HotKeyValue;
|
|
EFI_QUESTION_ID HotKeyQuestionId;
|
|
BOOT_DEV_INFO *BootDevInfo;
|
|
BOOLEAN RetrieveData;
|
|
|
|
if ((This == NULL) ||
|
|
((Value == NULL) &&
|
|
(Action != EFI_BROWSER_ACTION_FORM_OPEN) &&
|
|
(Action != EFI_BROWSER_ACTION_FORM_CLOSE))||
|
|
(ActionRequest == NULL)) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
Status = GetSetupUtilityBrowserData (&SuBrowser);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
*ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;
|
|
CallbackInfo = EFI_CALLBACK_INFO_FROM_THIS (This);
|
|
Status = EFI_UNSUPPORTED;
|
|
|
|
switch (Action) {
|
|
|
|
case EFI_BROWSER_ACTION_FORM_OPEN:
|
|
case EFI_BROWSER_ACTION_FORM_CLOSE:
|
|
if (QuestionId == 0) {
|
|
RetrieveData = (BOOLEAN) (Action == EFI_BROWSER_ACTION_FORM_CLOSE);
|
|
BufferSize = GetVarStoreSize (CallbackInfo->HiiHandle, &CallbackInfo->FormsetGuid, &VarStoreGuid, "SystemConfig");
|
|
SetupVariableConfig (&VarStoreGuid, L"SystemConfig", BufferSize , (UINT8 *) SuBrowser->SCBuffer, RetrieveData);
|
|
SetupVariableConfig (&VarStoreGuid, L"BootConfig" , sizeof (BOOT_CONFIGURATION), (UINT8 *) &mBootConfig , RetrieveData);
|
|
SetupVariableConfig (&VarStoreGuid, L"NetworkConfig", sizeof (NETWORK_CONFIGURATION), (UINT8 *) &mNetworkConfig, RetrieveData);
|
|
}
|
|
break;
|
|
|
|
case EFI_BROWSER_ACTION_CHANGING:
|
|
Status = EFI_SUCCESS;
|
|
break;
|
|
|
|
case EFI_BROWSER_ACTION_DEFAULT_MANUFACTURING:
|
|
if (QuestionId == KEY_SCAN_F9) {
|
|
Status = SuBrowser->HotKeyCallback (
|
|
This,
|
|
Action,
|
|
QuestionId,
|
|
Type,
|
|
Value,
|
|
ActionRequest
|
|
);
|
|
RetrieveData = FALSE;
|
|
BufferSize = GetVarStoreSize (CallbackInfo->HiiHandle, &CallbackInfo->FormsetGuid, &VarStoreGuid, "SystemConfig");
|
|
SetupVariableConfig (&VarStoreGuid, L"SystemConfig", BufferSize , (UINT8 *) SuBrowser->SCBuffer, RetrieveData);
|
|
SetupVariableConfig (&VarStoreGuid, L"BootConfig" , sizeof (BOOT_CONFIGURATION), (UINT8 *) &mBootConfig , RetrieveData);
|
|
}
|
|
//
|
|
// avoid GetQuestionDefault execute ExtractConfig
|
|
//
|
|
return EFI_SUCCESS;
|
|
|
|
case H2O_BROWSER_ACTION_HOT_KEY_CALLBACK:
|
|
if (QuestionId == KEY_LEGACY_NORMAL_BOOT_MENU) {
|
|
//
|
|
// Because modify value hot key is changed to change boot order hot key in EFI\Legacy page,
|
|
// modify question value for this question to achieve the same behavior.
|
|
//
|
|
HotKeyValue.u8 = (((KERNEL_CONFIGURATION *) SuBrowser->SCBuffer)->LegacyNormalMenuType == 0) ? 1 : 0;
|
|
((KERNEL_CONFIGURATION *) SuBrowser->SCBuffer)->LegacyNormalMenuType = HotKeyValue.u8;
|
|
|
|
RetrieveData = FALSE;
|
|
BufferSize = GetVarStoreSize (CallbackInfo->HiiHandle, &CallbackInfo->FormsetGuid, &VarStoreGuid, "SystemConfig");
|
|
SetupVariableConfig (
|
|
&VarStoreGuid,
|
|
L"SystemConfig",
|
|
BufferSize,
|
|
(UINT8 *) SuBrowser->SCBuffer,
|
|
RetrieveData
|
|
);
|
|
|
|
BootCallbackRoutine (
|
|
This,
|
|
EFI_BROWSER_ACTION_CHANGED,
|
|
KEY_LEGACY_NORMAL_BOOT_MENU,
|
|
EFI_IFR_TYPE_NUM_SIZE_8,
|
|
&HotKeyValue,
|
|
ActionRequest
|
|
);
|
|
SendGotoHotKeyNotify (0, QuestionId);
|
|
break;
|
|
}
|
|
|
|
if (((KERNEL_CONFIGURATION *) SuBrowser->SCBuffer)->NewPositionPolicy == IN_AUTO) {
|
|
BootDevInfo = GetBootDevInfo (QuestionId);
|
|
if (BootDevInfo != NULL && BootDevInfo->IsEfiBootDev) {
|
|
//
|
|
// Not allow to change EFI boot device order when "Add Boot Options" is AUTO.
|
|
//
|
|
break;
|
|
}
|
|
}
|
|
|
|
HotKeyValue.u32 = QuestionId;
|
|
HotKeyQuestionId = Value->b ? KEY_UP_SHIFT : KEY_DOWN_SHIFT;
|
|
|
|
Status = BootCallbackRoutine (
|
|
This,
|
|
EFI_BROWSER_ACTION_CHANGED,
|
|
HotKeyQuestionId,
|
|
EFI_IFR_TYPE_NUM_SIZE_32,
|
|
&HotKeyValue,
|
|
ActionRequest
|
|
);
|
|
if (!EFI_ERROR (Status)) {
|
|
SendGotoHotKeyNotify (0, (HotKeyQuestionId == KEY_UP_SHIFT) ? QuestionId - 1 : QuestionId + 1);
|
|
}
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
/**
|
|
This function allows a caller to extract BootConfig configuration.
|
|
|
|
@param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
|
|
@param[in] Request A null-terminated Unicode string in <ConfigRequest> format.
|
|
@param[out] Progress On return, points to a character in the Request string.
|
|
Points to the string's null terminator if request was successful.
|
|
Points to the most recent '&' before the first failing name/value
|
|
pair (or the beginning of the string if the failure is in the
|
|
first name/value pair) if the request was not successful.
|
|
@param[out] Results A null-terminated Unicode string in <ConfigAltResp> format which
|
|
has all values filled in for the names in the Request string.
|
|
String to be allocated by the called function.
|
|
|
|
@retval EFI_SUCCESS The Results is filled with the requested values.
|
|
@retval EFI_OUT_OF_RESOURCES Not enough memory to store the results.
|
|
@retval EFI_INVALID_PARAMETER Request is NULL, illegal syntax, or unknown name.
|
|
@retval EFI_NOT_FOUND Routing data doesn't match any storage in this driver.
|
|
**/
|
|
EFI_STATUS
|
|
InternalBootExtractConfig (
|
|
IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
|
|
IN CONST EFI_STRING Request,
|
|
OUT EFI_STRING *Progress,
|
|
OUT EFI_STRING *Results
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINTN BufferSize;
|
|
EFI_STRING ConfigRequestHdr;
|
|
EFI_STRING ConfigRequest;
|
|
BOOLEAN AllocatedRequest;
|
|
UINTN Size;
|
|
CHAR16 *StrPointer;
|
|
EFI_CALLBACK_INFO *CallbackInfo;
|
|
EFI_HANDLE DriverHandle;
|
|
SETUP_UTILITY_BROWSER_DATA *SuBrowser;
|
|
|
|
if (This == NULL || Progress == NULL || Results == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
if (!HiiIsConfigHdrMatch (Request, &gSystemConfigurationGuid, L"BootConfig")) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
Status = GetSetupUtilityBrowserData (&SuBrowser);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
*Progress = Request;
|
|
CallbackInfo = EFI_CALLBACK_INFO_FROM_THIS (This);
|
|
BufferSize = sizeof (BOOT_CONFIGURATION);
|
|
ConfigRequestHdr = NULL;
|
|
ConfigRequest = NULL;
|
|
AllocatedRequest = FALSE;
|
|
Size = 0;
|
|
|
|
if (Request == NULL) {
|
|
//
|
|
// Request is set to NULL, construct full request string.
|
|
//
|
|
// Allocate and fill a buffer large enough to hold the <ConfigHdr> template
|
|
// followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator
|
|
//
|
|
Status = SuBrowser->HiiDatabase->GetPackageListHandle (SuBrowser->HiiDatabase, CallbackInfo->HiiHandle, &DriverHandle);
|
|
if (EFI_ERROR (Status)) {
|
|
return EFI_NOT_FOUND;
|
|
}
|
|
ConfigRequestHdr = HiiConstructConfigHdr (&gSystemConfigurationGuid, L"BootConfig", DriverHandle);
|
|
if (ConfigRequestHdr == NULL) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);
|
|
ConfigRequest = AllocateZeroPool (Size);
|
|
ASSERT (ConfigRequest != NULL);
|
|
if (ConfigRequest == NULL) {
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
AllocatedRequest = TRUE;
|
|
UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, (UINT64) BufferSize);
|
|
FreePool (ConfigRequestHdr);
|
|
ConfigRequestHdr = NULL;
|
|
} else {
|
|
//
|
|
// Set Request to the unified request string.
|
|
//
|
|
ConfigRequest = Request;
|
|
//
|
|
// Check whether Request includes Request Element.
|
|
//
|
|
if (StrStr (Request, L"OFFSET") == NULL) {
|
|
//
|
|
// Check Request Element does exist in Reques String
|
|
//
|
|
StrPointer = StrStr (Request, L"PATH");
|
|
if (StrPointer == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
if (StrStr (StrPointer, L"&") == NULL) {
|
|
Size = (StrLen (Request) + 32 + 1) * sizeof (CHAR16);
|
|
ConfigRequest = AllocateZeroPool (Size);
|
|
ASSERT (ConfigRequest != NULL);
|
|
if (ConfigRequest == NULL) {
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
AllocatedRequest = TRUE;
|
|
UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", Request, (UINT64) BufferSize);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (StrStr (ConfigRequest, L"OFFSET") == NULL) {
|
|
//
|
|
// If requesting Name/Value storage, return not found.
|
|
//
|
|
return EFI_NOT_FOUND;
|
|
}
|
|
|
|
//
|
|
// Convert buffer data to <ConfigResp> by helper function BlockToConfig()
|
|
//
|
|
Status = SuBrowser->HiiConfigRouting->BlockToConfig (
|
|
SuBrowser->HiiConfigRouting,
|
|
ConfigRequest,
|
|
(UINT8 *) &mBootConfig,
|
|
BufferSize,
|
|
Results,
|
|
Progress
|
|
);
|
|
if (AllocatedRequest) {
|
|
FreePool (ConfigRequest);
|
|
ConfigRequest = NULL;
|
|
}
|
|
//
|
|
// Set Progress string to the original request string.
|
|
//
|
|
if (Request == NULL) {
|
|
*Progress = NULL;
|
|
} else if (StrStr (Request, L"OFFSET") == NULL) {
|
|
*Progress = Request + StrLen (Request);
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
/**
|
|
This function allows a caller to extract NetworkConfig configuration.
|
|
|
|
@param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
|
|
@param[in] Request A null-terminated Unicode string in <ConfigRequest> format.
|
|
@param[out] Progress On return, points to a character in the Request string.
|
|
Points to the string's null terminator if request was successful.
|
|
Points to the most recent '&' before the first failing name/value
|
|
pair (or the beginning of the string if the failure is in the
|
|
first name/value pair) if the request was not successful.
|
|
@param[out] Results A null-terminated Unicode string in <ConfigAltResp> format which
|
|
has all values filled in for the names in the Request string.
|
|
String to be allocated by the called function.
|
|
|
|
@retval EFI_SUCCESS The Results is filled with the requested values.
|
|
@retval EFI_OUT_OF_RESOURCES Not enough memory to store the results.
|
|
@retval EFI_INVALID_PARAMETER Request is NULL, illegal syntax, or unknown name.
|
|
@retval EFI_NOT_FOUND Routing data doesn't match any storage in this driver.
|
|
**/
|
|
EFI_STATUS
|
|
InternalNetworkExtractConfig (
|
|
IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
|
|
IN CONST EFI_STRING Request,
|
|
OUT EFI_STRING *Progress,
|
|
OUT EFI_STRING *Results
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINTN BufferSize;
|
|
EFI_STRING ConfigRequestHdr;
|
|
EFI_STRING ConfigRequest;
|
|
BOOLEAN AllocatedRequest;
|
|
UINTN Size;
|
|
CHAR16 *StrPointer;
|
|
EFI_CALLBACK_INFO *CallbackInfo;
|
|
EFI_HANDLE DriverHandle;
|
|
SETUP_UTILITY_BROWSER_DATA *SuBrowser;
|
|
|
|
|
|
if (This == NULL || Progress == NULL || Results == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
if (!HiiIsConfigHdrMatch (Request, &gSystemConfigurationGuid, L"NetworkConfig")) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
Status = GetSetupUtilityBrowserData (&SuBrowser);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
*Progress = Request;
|
|
CallbackInfo = EFI_CALLBACK_INFO_FROM_THIS (This);
|
|
BufferSize = sizeof (NETWORK_CONFIGURATION);
|
|
ConfigRequestHdr = NULL;
|
|
ConfigRequest = NULL;
|
|
AllocatedRequest = FALSE;
|
|
Size = 0;
|
|
|
|
if (Request == NULL) {
|
|
//
|
|
// Request is set to NULL, construct full request string.
|
|
//
|
|
// Allocate and fill a buffer large enough to hold the <ConfigHdr> template
|
|
// followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator
|
|
//
|
|
Status = SuBrowser->HiiDatabase->GetPackageListHandle (SuBrowser->HiiDatabase, CallbackInfo->HiiHandle, &DriverHandle);
|
|
if (EFI_ERROR (Status)) {
|
|
return EFI_NOT_FOUND;
|
|
}
|
|
ConfigRequestHdr = HiiConstructConfigHdr (&gSystemConfigurationGuid, L"NetworkConfig", DriverHandle);
|
|
if (ConfigRequestHdr == NULL) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);
|
|
ConfigRequest = AllocateZeroPool (Size);
|
|
ASSERT (ConfigRequest != NULL);
|
|
if (ConfigRequest == NULL) {
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
AllocatedRequest = TRUE;
|
|
UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, (UINT64) BufferSize);
|
|
FreePool (ConfigRequestHdr);
|
|
ConfigRequestHdr = NULL;
|
|
} else {
|
|
//
|
|
// Set Request to the unified request string.
|
|
//
|
|
ConfigRequest = Request;
|
|
//
|
|
// Check whether Request includes Request Element.
|
|
//
|
|
if (StrStr (Request, L"OFFSET") == NULL) {
|
|
//
|
|
// Check Request Element does exist in Reques String
|
|
//
|
|
StrPointer = StrStr (Request, L"PATH");
|
|
if (StrPointer == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
if (StrStr (StrPointer, L"&") == NULL) {
|
|
Size = (StrLen (Request) + 32 + 1) * sizeof (CHAR16);
|
|
ConfigRequest = AllocateZeroPool (Size);
|
|
ASSERT (ConfigRequest != NULL);
|
|
if (ConfigRequest == NULL) {
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
AllocatedRequest = TRUE;
|
|
UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", Request, (UINT64) BufferSize);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (StrStr (ConfigRequest, L"OFFSET") == NULL) {
|
|
//
|
|
// If requesting Name/Value storage, return not found.
|
|
//
|
|
return EFI_NOT_FOUND;
|
|
}
|
|
|
|
//
|
|
// Convert buffer data to <ConfigResp> by helper function BlockToConfig()
|
|
//
|
|
Status = SuBrowser->HiiConfigRouting->BlockToConfig (
|
|
SuBrowser->HiiConfigRouting,
|
|
ConfigRequest,
|
|
(UINT8 *) &mNetworkConfig,
|
|
BufferSize,
|
|
Results,
|
|
Progress
|
|
);
|
|
if (AllocatedRequest) {
|
|
FreePool (ConfigRequest);
|
|
ConfigRequest = NULL;
|
|
}
|
|
//
|
|
// Set Progress string to the original request string.
|
|
//
|
|
if (Request == NULL) {
|
|
*Progress = NULL;
|
|
} else if (StrStr (Request, L"OFFSET") == NULL) {
|
|
*Progress = Request + StrLen (Request);
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
/**
|
|
This function allows a caller to extract the current configuration for one
|
|
or more named elements from the target driver.
|
|
|
|
@param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
|
|
@param[in] Request A null-terminated Unicode string in <ConfigRequest> format.
|
|
@param[out] Progress On return, points to a character in the Request string.
|
|
Points to the string's null terminator if request was successful.
|
|
Points to the most recent '&' before the first failing name/value
|
|
pair (or the beginning of the string if the failure is in the
|
|
first name/value pair) if the request was not successful.
|
|
@param[out] Results A null-terminated Unicode string in <ConfigAltResp> format which
|
|
has all values filled in for the names in the Request string.
|
|
String to be allocated by the called function.
|
|
|
|
@retval EFI_SUCCESS The Results is filled with the requested values.
|
|
@retval EFI_OUT_OF_RESOURCES Not enough memory to store the results.
|
|
@retval EFI_INVALID_PARAMETER Request is NULL, illegal syntax, or unknown name.
|
|
@retval EFI_NOT_FOUND Routing data doesn't match any storage in this driver.
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
BootExtractConfig (
|
|
IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
|
|
IN CONST EFI_STRING Request,
|
|
OUT EFI_STRING *Progress,
|
|
OUT EFI_STRING *Results
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
SETUP_UTILITY_BROWSER_DATA *SuBrowser;
|
|
|
|
Status = InternalBootExtractConfig (This, Request, Progress, Results);
|
|
if (!EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
Status = InternalNetworkExtractConfig (This, Request, Progress, Results);
|
|
if (!EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
Status = GetSetupUtilityBrowserData (&SuBrowser);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
return SuBrowser->ExtractConfig (This, Request, Progress, Results);
|
|
}
|
|
|
|
/**
|
|
Install Boot Callback routine.
|
|
|
|
@param DriverHandle Specific driver handle for the call back routine
|
|
@param HiiHandle Hii hanlde for the call back routine
|
|
|
|
@retval EFI_SUCCESS Function has completed successfully.
|
|
@return Other Error occurred during execution.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
InstallBootCallbackRoutine (
|
|
IN EFI_HANDLE DriverHandle,
|
|
IN EFI_HII_HANDLE HiiHandle
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
SETUP_UTILITY_BROWSER_DATA *SuBrowser;
|
|
EFI_GUID FormsetGuid = FORMSET_ID_GUID_BOOT;
|
|
|
|
Status = GetSetupUtilityBrowserData (&SuBrowser);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
mBootCallBackInfo = AllocatePool (sizeof(EFI_CALLBACK_INFO));
|
|
if (mBootCallBackInfo == NULL) {
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
|
|
mBootCallBackInfo->Signature = EFI_CALLBACK_INFO_SIGNATURE;
|
|
mBootCallBackInfo->DriverCallback.ExtractConfig = BootExtractConfig;
|
|
mBootCallBackInfo->DriverCallback.RouteConfig = SuBrowser->RouteConfig;
|
|
mBootCallBackInfo->DriverCallback.Callback = BootCallbackRoutine;
|
|
mBootCallBackInfo->HiiHandle = HiiHandle;
|
|
CopyGuid (&mBootCallBackInfo->FormsetGuid, &FormsetGuid);
|
|
|
|
//
|
|
// Install protocol interface
|
|
//
|
|
Status = gBS->InstallProtocolInterface (
|
|
&DriverHandle,
|
|
&gEfiHiiConfigAccessProtocolGuid,
|
|
EFI_NATIVE_INTERFACE,
|
|
&mBootCallBackInfo->DriverCallback
|
|
);
|
|
ASSERT_EFI_ERROR (Status);
|
|
|
|
Status = InitBootMenu (HiiHandle);
|
|
|
|
return Status;
|
|
}
|
|
|
|
/**
|
|
Uninstall Boot Callback routine.
|
|
|
|
@param DriverHandle Specific driver handle for the call back routine
|
|
|
|
@retval EFI_SUCCESS Function has completed successfully.
|
|
@return Other Error occurred during execution.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
UninstallBootCallbackRoutine (
|
|
IN EFI_HANDLE DriverHandle
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
SETUP_UTILITY_BROWSER_DATA *SuBrowser;
|
|
SETUP_UTILITY_CONFIGURATION *SUCInfo;
|
|
|
|
if (mBootCallBackInfo == NULL) {
|
|
return EFI_SUCCESS;
|
|
}
|
|
Status = gBS->UninstallProtocolInterface (
|
|
DriverHandle,
|
|
&gEfiHiiConfigAccessProtocolGuid,
|
|
&mBootCallBackInfo->DriverCallback
|
|
);
|
|
ASSERT_EFI_ERROR (Status);
|
|
FreePool (mBootCallBackInfo);
|
|
mBootCallBackInfo = NULL;
|
|
|
|
BootDevInfoShutdown ();
|
|
ShutdownBbsTypeTable ();
|
|
|
|
Status = GetSetupUtilityBrowserData (&SuBrowser);
|
|
if (!EFI_ERROR (Status)) {
|
|
SUCInfo = SuBrowser->SUCInfo;
|
|
|
|
if (SUCInfo->LegacyBootDevType != NULL) {
|
|
FreePool (SUCInfo->LegacyBootDevType);
|
|
SUCInfo->LegacyBootDevType = NULL;
|
|
}
|
|
if (SUCInfo->BootOrder != NULL) {
|
|
FreePool (SUCInfo->BootOrder);
|
|
SUCInfo->BootOrder = NULL;
|
|
}
|
|
if (SUCInfo->BootPriority != NULL) {
|
|
FreePool (SUCInfo->BootPriority);
|
|
SUCInfo->BootPriority = NULL;
|
|
}
|
|
}
|
|
|
|
return Status;
|
|
}
|