alder_lake_bios/Insyde/InsydeModulePkg/Library/SetupUtilityLib/Exit/Exit.c

609 lines
19 KiB
C

/** @file
Initial and callback functions for Exit page of SetupUtilityLib
;******************************************************************************
;* Copyright (c) 2012 - 2020, 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 "Exit.h"
STATIC EFI_CALLBACK_INFO *mExitCallBackInfo;
/**
For all form set including "link" page, save or load custom default variable.
@param Save TRUE is save custom default, FALSE is load custom default.
@param DefaultId It is load custom default
@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.
**/
EFI_STATUS
SaveLoadCustomDefault (
IN BOOLEAN Save,
IN UINT16 DefaultId
)
{
EFI_STATUS Status;
SETUP_UTILITY_BROWSER_DATA *SuBrowser;
H2O_FORM_BROWSER_PROTOCOL *FBProtocol;
UINTN PageIdx;
UINTN CheckPageIdx;
UINT32 PageIdCount;
H2O_PAGE_ID *PageIdList;
H2O_PAGE_ID PageId;
BOOLEAN FoundSamePage;
EFI_VARSTORE_ID VarStoreId;
UINTN VarStoreIdIdx;
UINTN VarStoreIdCount;
EFI_VARSTORE_ID *VarStoreIdList;
H2O_FORM_BROWSER_VS *VarStoreData;
CHAR16 *CustomDefaultVarName;
UINT8 *VarBuffer;
UINTN VarBufferSize;
Status = GetSetupUtilityBrowserData (&SuBrowser);
if (EFI_ERROR (Status)) {
return Status;
}
Status = gBS->LocateProtocol (
&gH2OFormBrowserProtocolGuid,
NULL,
(VOID **)&FBProtocol
);
ASSERT_EFI_ERROR (Status);
if (EFI_ERROR (Status)) {
return Status;
}
Status = FBProtocol->GetPAll (FBProtocol, &PageIdCount, &PageIdList);
if (EFI_ERROR (Status)) {
return Status;
}
for (PageIdx = 0; PageIdx < PageIdCount; PageIdx++) {
PageId = PageIdList[PageIdx];
//
// skip the same formset
//
FoundSamePage = FALSE;
for (CheckPageIdx = 1; CheckPageIdx < PageIdx; CheckPageIdx++) {
if ((PageIdList[CheckPageIdx] >> 16) == (PageId >> 16)) {
FoundSamePage = TRUE;
break;
}
}
if (FoundSamePage) {
continue;
}
Status = FBProtocol->GetVSAll (FBProtocol, PageId, &VarStoreIdCount, &VarStoreIdList);
ASSERT_EFI_ERROR (Status);
if (EFI_ERROR (Status)) {
continue;
}
for (VarStoreIdIdx = 0; VarStoreIdIdx < VarStoreIdCount; VarStoreIdIdx++) {
VarStoreData = NULL;
VarStoreId = VarStoreIdList[VarStoreIdIdx];
Status = FBProtocol->GetVSInfo (FBProtocol, PageId, VarStoreId, &VarStoreData);
ASSERT_EFI_ERROR (Status);
if (EFI_ERROR (Status)) {
continue;
}
//
// skip name value
//
if (VarStoreData->Name == NULL) {
FreePool (VarStoreData);
continue;
}
CustomDefaultVarName = CatSPrint (NULL, L"%s%04x", VarStoreData->Name, DefaultId);
if (CustomDefaultVarName == NULL) {
FreePool (VarStoreData);
FreePool (VarStoreIdList);
FreePool (PageIdList);
return EFI_OUT_OF_RESOURCES;
}
if (Save) {
VarBufferSize = VarStoreData->StorageSize;
VarBuffer = VarStoreData->EditBuffer;
//
// Avoid Setup variable isn't same in multiple page, use SCBuffer directly.
//
if (StrCmp (VarStoreData->Name, L"SystemConfig") == 0) {
VarBufferSize = GetSetupVariableSize ();
VarBuffer = SuBrowser->SCBuffer;
}
Status = gRT->SetVariable (
CustomDefaultVarName,
&VarStoreData->Guid,
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
VarBufferSize,
VarBuffer
);
ASSERT_EFI_ERROR (Status);
} else {
VarBuffer = NULL;
VarBufferSize = 0;
Status = CommonGetVariableDataAndSize (
CustomDefaultVarName,
&VarStoreData->Guid,
&VarBufferSize,
(VOID **)&VarBuffer
);
if (!EFI_ERROR (Status)) {
if (VarStoreData->StorageSize < VarBufferSize) {
VarBufferSize = VarStoreData->StorageSize;
}
CopyMem (VarStoreData->EditBuffer, VarBuffer, VarBufferSize);
FreePool (VarBuffer);
}
}
DEBUG ((EFI_D_INFO, "%g %s\n", &VarStoreData->Guid, VarStoreData->Name));
FreePool (CustomDefaultVarName);
FreePool (VarStoreData);
}
FreePool (VarStoreIdList);
}
FreePool (PageIdList);
return EFI_SUCCESS;
}
/**
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
ExitCallbackRoutine (
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;
CHAR16 *StringPtr;
KERNEL_CONFIGURATION *MyIfrNVData;
EFI_HII_HANDLE HiiHandle;
EFI_INPUT_KEY Key;
EFI_CALLBACK_INFO *CallbackInfo;
SETUP_UTILITY_CONFIGURATION *SUCInfo;
EFI_SETUP_UTILITY_BROWSER_PROTOCOL *Interface;
SETUP_UTILITY_BROWSER_DATA *SuBrowser;
UINTN BufferSize;
EFI_GUID VarStoreGuid = SYSTEM_CONFIGURATION_GUID;
if (Action != EFI_BROWSER_ACTION_CHANGED) {
return ExitCallbackRoutineByAction (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;
Status = EFI_SUCCESS;
StringPtr = NULL;
HiiHandle = CallbackInfo->HiiHandle;
Status = SetupVariableConfig (
&VarStoreGuid,
L"SystemConfig",
BufferSize,
(UINT8 *) SuBrowser->SCBuffer,
TRUE
);
Interface = &SuBrowser->Interface;
Interface->MyIfrNVData = (UINT8 *) SuBrowser->SCBuffer;
MyIfrNVData = (KERNEL_CONFIGURATION *) SuBrowser->SCBuffer;
switch (QuestionId) {
case KEY_SAVE_EXIT:
Status = SuBrowser->HotKeyCallback (
This,
Action,
KEY_SCAN_F10,
Type,
Value,
ActionRequest
);
break;
case KEY_EXIT_DISCARD:
//
// Discard setup and exit
//
Status = SuBrowser->HotKeyCallback (
This,
Action,
KEY_SCAN_ESC,
Type,
Value,
ActionRequest
);
break;
case KEY_LOAD_OPTIMAL:
//
//Select "Load Optimal Defaults" and Press "Load Optimal hotkey", the functionality is the same,
//so remove the original code Use "Load Optimal hotkey" to call HotKeyCallBack () directly
//
Status = SuBrowser->HotKeyCallback (
This,
Action,
KEY_SCAN_F9,
Type,
Value,
ActionRequest
);
break;
case KEY_LOAD_CUSTOM:
//
// Load custom setup.
//
if ((MyIfrNVData->SetUserPass == TRUE) &&
((MyIfrNVData->UserAccessLevel == 2) ||
(MyIfrNVData->UserAccessLevel == 3))) {
return EFI_UNSUPPORTED;
}
StringPtr = HiiGetString (
HiiHandle,
STRING_TOKEN (STR_LOAD_CUSTOM_DEFAULTS_STRING),
NULL
);
SuBrowser->H2ODialog->ConfirmDialog (
0,
FALSE,
0,
NULL,
&Key,
StringPtr
);
if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {
Status = LoadCustomOption (This);
if (FeaturePcdGet (PcdH2OCustomDefaultSupported)) {
Status = SaveLoadCustomDefault (FALSE, 0xC001);
}
if (!EFI_ERROR (Status)) {
SUCInfo->DoRefresh = TRUE;
BrowserRefreshFormSet ();
Status = SuBrowser->HotKeyCallback (
This,
Action,
KEY_LOAD_CUSTOM,
Type,
Value,
ActionRequest
);
}
} else {
Status = EFI_UNSUPPORTED;
}
FreePool (StringPtr);
break;
case KEY_SAVE_CUSTOM:
//
// Save custom setup.
//
StringPtr = HiiGetString (
HiiHandle,
STRING_TOKEN (STR_SAVE_CUSTOM_DEFAULTS_STRING),
NULL
);
SuBrowser->H2ODialog->ConfirmDialog (
0,
FALSE,
0,
NULL,
&Key,
StringPtr
);
if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {
if (FeaturePcdGet (PcdH2OCustomDefaultSupported)) {
Status = SaveLoadCustomDefault (TRUE, 0xC001);
}
Status = SaveCustomOption (This);
if (!EFI_ERROR (Status)) {
Status = SuBrowser->HotKeyCallback (
This,
Action,
KEY_SAVE_CUSTOM,
Type,
Value,
ActionRequest
);
}
} else {
Status = EFI_UNSUPPORTED;
}
FreePool (StringPtr);
break;
default:
Status = SuBrowser->HotKeyCallback (
This,
Action,
QuestionId,
Type,
Value,
ActionRequest
);
break;
}
SetupVariableConfig (
&VarStoreGuid,
L"SystemConfig",
BufferSize,
(UINT8 *) SuBrowser->SCBuffer,
FALSE
);
return Status;
}
EFI_STATUS
ExitCallbackRoutineByAction (
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;
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);
BufferSize = GetVarStoreSize (CallbackInfo->HiiHandle, &CallbackInfo->FormsetGuid, &VarStoreGuid, "SystemConfig");
Status = EFI_UNSUPPORTED;
switch (Action) {
case EFI_BROWSER_ACTION_FORM_OPEN:
if (QuestionId == 0) {
Status = SetupVariableConfig (
&VarStoreGuid,
L"SystemConfig",
BufferSize,
(UINT8 *) SuBrowser->SCBuffer,
FALSE
);
}
break;
case EFI_BROWSER_ACTION_FORM_CLOSE:
if (QuestionId == 0) {
Status = SetupVariableConfig (
&VarStoreGuid,
L"SystemConfig",
BufferSize,
(UINT8 *) SuBrowser->SCBuffer,
TRUE
);
}
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
);
Status = SetupVariableConfig (
&VarStoreGuid,
L"SystemConfig",
BufferSize,
(UINT8 *) SuBrowser->SCBuffer,
TRUE
);
}
//
// avoid GetQuestionDefault execute ExtractConfig
//
return EFI_SUCCESS;
case H2O_BROWSER_ACTION_HOT_KEY_CALLBACK:
Status = SuBrowser->HotKeyCallback (
This,
EFI_BROWSER_ACTION_CHANGED,
QuestionId,
Type,
Value,
ActionRequest
);
break;
default:
break;
}
return Status;
}
/**
Install Exit 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
InstallExitCallbackRoutine (
IN EFI_HANDLE DriverHandle,
IN EFI_HII_HANDLE HiiHandle
)
{
EFI_STATUS Status;
SETUP_UTILITY_BROWSER_DATA *SuBrowser;
EFI_GUID FormsetGuid = FORMSET_ID_GUID_EXIT;
Status = GetSetupUtilityBrowserData (&SuBrowser);
if (EFI_ERROR (Status)) {
return Status;
}
mExitCallBackInfo = AllocatePool (sizeof (EFI_CALLBACK_INFO));
if (mExitCallBackInfo == NULL) {
return EFI_OUT_OF_RESOURCES;
}
mExitCallBackInfo->Signature = EFI_CALLBACK_INFO_SIGNATURE;
mExitCallBackInfo->DriverCallback.ExtractConfig = SuBrowser->ExtractConfig;
mExitCallBackInfo->DriverCallback.RouteConfig = SuBrowser->RouteConfig;
mExitCallBackInfo->DriverCallback.Callback = ExitCallbackRoutine;
mExitCallBackInfo->HiiHandle = HiiHandle;
CopyGuid (&mExitCallBackInfo->FormsetGuid, &FormsetGuid);
//
// Install protocol interface
//
Status = gBS->InstallProtocolInterface (
&DriverHandle,
&gEfiHiiConfigAccessProtocolGuid,
EFI_NATIVE_INTERFACE,
&mExitCallBackInfo->DriverCallback
);
ASSERT_EFI_ERROR (Status);
return Status;
}
/**
Uninstall Exit 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
UninstallExitCallbackRoutine (
IN EFI_HANDLE DriverHandle
)
{
EFI_STATUS Status;
if (mExitCallBackInfo == NULL) {
return EFI_SUCCESS;
}
Status = gBS->UninstallProtocolInterface (
DriverHandle,
&gEfiHiiConfigAccessProtocolGuid,
&mExitCallBackInfo->DriverCallback
);
ASSERT_EFI_ERROR (Status);
FreePool (mExitCallBackInfo);
mExitCallBackInfo = NULL;
return Status;
}
/**
Initialize exit 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.
**/
EFI_STATUS
InitExitMenu (
IN EFI_HII_HANDLE HiiHandle
)
{
return EFI_SUCCESS;
}