mirror of
https://github.com/CloverHackyColor/CloverBootloader.git
synced 2024-12-26 16:47:40 +01:00
6b33696c93
Signed-off-by: SergeySlice <sergey.slice@gmail.com>
470 lines
13 KiB
C
470 lines
13 KiB
C
/** @file
|
|
The functions for Boot Maintainence Main menu.
|
|
|
|
Copyright (c) 2004 - 2016, Intel Corporation. All rights reserved.<BR>
|
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
|
|
|
**/
|
|
|
|
|
|
#include "BootMaintenanceManager.h"
|
|
#include "BootMaintenanceManagerCustomizedUiSupport.h"
|
|
|
|
#define UI_HII_DRIVER_LIST_SIZE 0x8
|
|
|
|
typedef struct {
|
|
EFI_STRING_ID PromptId;
|
|
EFI_STRING_ID HelpId;
|
|
EFI_STRING_ID DevicePathId;
|
|
EFI_GUID FormSetGuid;
|
|
BOOLEAN EmptyLineAfter;
|
|
} UI_HII_DRIVER_INSTANCE;
|
|
|
|
STATIC UI_HII_DRIVER_INSTANCE *gHiiDriverList;
|
|
|
|
|
|
/**
|
|
Create the dynamic item to allow user to set the "BootNext" vaule.
|
|
|
|
@param[in] HiiHandle The hii handle for the Uiapp driver.
|
|
@param[in] StartOpCodeHandle The opcode handle to save the new opcode.
|
|
|
|
**/
|
|
VOID
|
|
BmmCreateBootNextMenu(
|
|
IN EFI_HII_HANDLE HiiHandle,
|
|
IN VOID *StartOpCodeHandle
|
|
)
|
|
{
|
|
BM_MENU_ENTRY *NewMenuEntry;
|
|
BM_LOAD_CONTEXT *NewLoadContext;
|
|
UINT16 Index;
|
|
VOID *OptionsOpCodeHandle;
|
|
UINT32 BootNextIndex;
|
|
|
|
if (BootOptionMenu.MenuNumber == 0) {
|
|
return;
|
|
}
|
|
|
|
BootNextIndex = NONE_BOOTNEXT_VALUE;
|
|
|
|
OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();
|
|
ASSERT (OptionsOpCodeHandle != NULL);
|
|
|
|
for (Index = 0; Index < BootOptionMenu.MenuNumber; Index++) {
|
|
NewMenuEntry = BOpt_GetMenuEntry (&BootOptionMenu, Index);
|
|
NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;
|
|
|
|
if (NewLoadContext->IsBootNext) {
|
|
HiiCreateOneOfOptionOpCode (
|
|
OptionsOpCodeHandle,
|
|
NewMenuEntry->DisplayStringToken,
|
|
EFI_IFR_OPTION_DEFAULT,
|
|
EFI_IFR_TYPE_NUM_SIZE_32,
|
|
Index
|
|
);
|
|
BootNextIndex = Index;
|
|
} else {
|
|
HiiCreateOneOfOptionOpCode (
|
|
OptionsOpCodeHandle,
|
|
NewMenuEntry->DisplayStringToken,
|
|
0,
|
|
EFI_IFR_TYPE_NUM_SIZE_32,
|
|
Index
|
|
);
|
|
}
|
|
}
|
|
|
|
if (BootNextIndex == NONE_BOOTNEXT_VALUE) {
|
|
HiiCreateOneOfOptionOpCode (
|
|
OptionsOpCodeHandle,
|
|
STRING_TOKEN (STR_NONE),
|
|
EFI_IFR_OPTION_DEFAULT,
|
|
EFI_IFR_TYPE_NUM_SIZE_32,
|
|
NONE_BOOTNEXT_VALUE
|
|
);
|
|
} else {
|
|
HiiCreateOneOfOptionOpCode (
|
|
OptionsOpCodeHandle,
|
|
STRING_TOKEN (STR_NONE),
|
|
0,
|
|
EFI_IFR_TYPE_NUM_SIZE_32,
|
|
NONE_BOOTNEXT_VALUE
|
|
);
|
|
}
|
|
|
|
HiiCreateOneOfOpCode (
|
|
StartOpCodeHandle,
|
|
(EFI_QUESTION_ID) BOOT_NEXT_QUESTION_ID,
|
|
VARSTORE_ID_BOOT_MAINT,
|
|
BOOT_NEXT_VAR_OFFSET,
|
|
STRING_TOKEN (STR_BOOT_NEXT),
|
|
STRING_TOKEN (STR_BOOT_NEXT_HELP),
|
|
0,
|
|
EFI_IFR_NUMERIC_SIZE_4,
|
|
OptionsOpCodeHandle,
|
|
NULL
|
|
);
|
|
|
|
HiiFreeOpCodeHandle (OptionsOpCodeHandle);
|
|
|
|
}
|
|
|
|
/**
|
|
Create Time Out Menu in the page.
|
|
|
|
@param[in] HiiHandle The hii handle for the Uiapp driver.
|
|
@param[in] StartOpCodeHandle The opcode handle to save the new opcode.
|
|
|
|
**/
|
|
VOID
|
|
BmmCreateTimeOutMenu (
|
|
IN EFI_HII_HANDLE HiiHandle,
|
|
IN VOID *StartOpCodeHandle
|
|
)
|
|
{
|
|
HiiCreateNumericOpCode (
|
|
StartOpCodeHandle,
|
|
(EFI_QUESTION_ID) FORM_TIME_OUT_ID,
|
|
VARSTORE_ID_BOOT_MAINT,
|
|
BOOT_TIME_OUT_VAR_OFFSET,
|
|
STRING_TOKEN(STR_NUM_AUTO_BOOT),
|
|
STRING_TOKEN(STR_HLP_AUTO_BOOT),
|
|
EFI_IFR_FLAG_CALLBACK,
|
|
EFI_IFR_NUMERIC_SIZE_2 | EFI_IFR_DISPLAY_UINT_DEC,
|
|
0,
|
|
65535,
|
|
0,
|
|
NULL
|
|
);
|
|
}
|
|
|
|
/**
|
|
Create Boot Option menu in the page.
|
|
|
|
@param[in] HiiHandle The hii handle for the Uiapp driver.
|
|
@param[in] StartOpCodeHandle The opcode handle to save the new opcode.
|
|
|
|
**/
|
|
VOID
|
|
BmmCreateBootOptionMenu (
|
|
IN EFI_HII_HANDLE HiiHandle,
|
|
IN VOID *StartOpCodeHandle
|
|
)
|
|
{
|
|
HiiCreateGotoOpCode (
|
|
StartOpCodeHandle,
|
|
FORM_BOOT_SETUP_ID,
|
|
STRING_TOKEN (STR_FORM_BOOT_SETUP_TITLE),
|
|
STRING_TOKEN (STR_FORM_BOOT_SETUP_HELP),
|
|
EFI_IFR_FLAG_CALLBACK,
|
|
FORM_BOOT_SETUP_ID
|
|
);
|
|
}
|
|
|
|
/**
|
|
Create Driver Option menu in the page.
|
|
|
|
@param[in] HiiHandle The hii handle for the Uiapp driver.
|
|
@param[in] StartOpCodeHandle The opcode handle to save the new opcode.
|
|
|
|
**/
|
|
VOID
|
|
BmmCreateDriverOptionMenu (
|
|
IN EFI_HII_HANDLE HiiHandle,
|
|
IN VOID *StartOpCodeHandle
|
|
)
|
|
{
|
|
HiiCreateGotoOpCode (
|
|
StartOpCodeHandle,
|
|
FORM_DRIVER_SETUP_ID,
|
|
STRING_TOKEN (STR_FORM_DRIVER_SETUP_TITLE),
|
|
STRING_TOKEN (STR_FORM_DRIVER_SETUP_HELP),
|
|
EFI_IFR_FLAG_CALLBACK,
|
|
FORM_DRIVER_SETUP_ID
|
|
);
|
|
}
|
|
|
|
/**
|
|
Create Com Option menu in the page.
|
|
|
|
@param[in] HiiHandle The hii handle for the Uiapp driver.
|
|
@param[in] StartOpCodeHandle The opcode handle to save the new opcode.
|
|
|
|
**/
|
|
VOID
|
|
BmmCreateComOptionMenu (
|
|
IN EFI_HII_HANDLE HiiHandle,
|
|
IN VOID *StartOpCodeHandle
|
|
)
|
|
{
|
|
HiiCreateGotoOpCode (
|
|
StartOpCodeHandle,
|
|
FORM_CON_MAIN_ID,
|
|
STRING_TOKEN (STR_FORM_CON_MAIN_TITLE),
|
|
STRING_TOKEN (STR_FORM_CON_MAIN_HELP),
|
|
EFI_IFR_FLAG_CALLBACK,
|
|
FORM_CON_MAIN_ID
|
|
);
|
|
}
|
|
|
|
/**
|
|
Create Com Option menu in the page.
|
|
|
|
@param[in] HiiHandle The hii handle for the Uiapp driver.
|
|
@param[in] StartOpCodeHandle The opcode handle to save the new opcode.
|
|
|
|
**/
|
|
VOID
|
|
BmmCreateBootFromFileMenu (
|
|
IN EFI_HII_HANDLE HiiHandle,
|
|
IN VOID *StartOpCodeHandle
|
|
)
|
|
{
|
|
HiiCreateGotoOpCode (
|
|
StartOpCodeHandle,
|
|
FORM_MAIN_ID,
|
|
STRING_TOKEN (STR_BOOT_FROM_FILE),
|
|
STRING_TOKEN (STR_BOOT_FROM_FILE_HELP),
|
|
EFI_IFR_FLAG_CALLBACK,
|
|
KEY_VALUE_BOOT_FROM_FILE
|
|
);
|
|
}
|
|
|
|
/**
|
|
Create empty line menu in the front page.
|
|
|
|
@param HiiHandle The hii handle for the Uiapp driver.
|
|
@param StartOpCodeHandle The opcode handle to save the new opcode.
|
|
|
|
**/
|
|
VOID
|
|
BmmCreateEmptyLine (
|
|
IN EFI_HII_HANDLE HiiHandle,
|
|
IN VOID *StartOpCodeHandle
|
|
)
|
|
{
|
|
HiiCreateSubTitleOpCode (StartOpCodeHandle, STRING_TOKEN (STR_NULL_STRING), 0, 0, 0);
|
|
}
|
|
|
|
/**
|
|
Extract device path for given HII handle and class guid.
|
|
|
|
@param Handle The HII handle.
|
|
|
|
@retval NULL Fail to get the device path string.
|
|
@return PathString Get the device path string.
|
|
|
|
**/
|
|
CHAR16 *
|
|
ExtractDevicePathFromHandle (
|
|
IN EFI_HII_HANDLE Handle
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
EFI_HANDLE DriverHandle;
|
|
|
|
ASSERT (Handle != NULL);
|
|
|
|
if (Handle == NULL) {
|
|
return NULL;
|
|
}
|
|
|
|
Status = gHiiDatabase->GetPackageListHandle (gHiiDatabase, Handle, &DriverHandle);
|
|
if (EFI_ERROR(Status)) {
|
|
return NULL;
|
|
}
|
|
|
|
return ConvertDevicePathToText(DevicePathFromHandle (DriverHandle), FALSE, FALSE);
|
|
}
|
|
|
|
/**
|
|
Check whether this driver need to be shown in the front page.
|
|
|
|
@param HiiHandle The hii handle for the driver.
|
|
@param Guid The special guid for the driver which is the target.
|
|
@param PromptId Return the prompt string id.
|
|
@param HelpId Return the help string id.
|
|
@param FormsetGuid Return the formset guid info.
|
|
|
|
@retval EFI_SUCCESS Search the driver success
|
|
|
|
**/
|
|
BOOLEAN
|
|
IsRequiredDriver (
|
|
IN EFI_HII_HANDLE HiiHandle,
|
|
IN EFI_GUID *Guid,
|
|
OUT EFI_STRING_ID *PromptId,
|
|
OUT EFI_STRING_ID *HelpId,
|
|
OUT VOID *FormsetGuid
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINT8 ClassGuidNum;
|
|
EFI_GUID *ClassGuid;
|
|
EFI_IFR_FORM_SET *Buffer;
|
|
UINTN BufferSize;
|
|
UINT8 *Ptr;
|
|
UINTN TempSize;
|
|
BOOLEAN RetVal;
|
|
|
|
Status = HiiGetFormSetFromHiiHandle(HiiHandle, &Buffer,&BufferSize);
|
|
if (EFI_ERROR(Status)) {
|
|
return FALSE;
|
|
}
|
|
|
|
RetVal = FALSE;
|
|
TempSize = 0;
|
|
Ptr = (UINT8 *) Buffer;
|
|
while(TempSize < BufferSize) {
|
|
TempSize += ((EFI_IFR_OP_HEADER *) Ptr)->Length;
|
|
|
|
if (((EFI_IFR_OP_HEADER *) Ptr)->Length <= OFFSET_OF (EFI_IFR_FORM_SET, Flags)){
|
|
Ptr += ((EFI_IFR_OP_HEADER *) Ptr)->Length;
|
|
continue;
|
|
}
|
|
|
|
ClassGuidNum = (UINT8) (((EFI_IFR_FORM_SET *)Ptr)->Flags & 0x3);
|
|
ClassGuid = (EFI_GUID *) (VOID *)(Ptr + sizeof (EFI_IFR_FORM_SET));
|
|
while (ClassGuidNum-- > 0) {
|
|
if (!CompareGuid (Guid, ClassGuid)){
|
|
ClassGuid ++;
|
|
continue;
|
|
}
|
|
|
|
*PromptId = ((EFI_IFR_FORM_SET *)Ptr)->FormSetTitle;
|
|
*HelpId = ((EFI_IFR_FORM_SET *)Ptr)->Help;
|
|
CopyMem(FormsetGuid, &((EFI_IFR_FORM_SET *) Ptr)->Guid, sizeof (EFI_GUID));
|
|
RetVal = TRUE;
|
|
}
|
|
}
|
|
|
|
FreePool(Buffer);
|
|
|
|
return RetVal;
|
|
}
|
|
|
|
/**
|
|
Search the drivers in the system which need to show in the front page
|
|
and insert the menu to the front page.
|
|
|
|
@param HiiHandle The hii handle for the Uiapp driver.
|
|
@param ClassGuid The class guid for the driver which is the target.
|
|
@param SpecialHandlerFn The pointer to the specail handler function, if any.
|
|
@param StartOpCodeHandle The opcode handle to save the new opcode.
|
|
|
|
@retval EFI_SUCCESS Search the driver success
|
|
|
|
**/
|
|
EFI_STATUS
|
|
BmmListThirdPartyDrivers (
|
|
IN EFI_HII_HANDLE HiiHandle,
|
|
IN EFI_GUID *ClassGuid,
|
|
IN DRIVER_SPECIAL_HANDLER SpecialHandlerFn,
|
|
IN VOID *StartOpCodeHandle
|
|
)
|
|
{
|
|
UINTN Index;
|
|
EFI_STRING String;
|
|
EFI_STRING_ID Token;
|
|
EFI_STRING_ID TokenHelp;
|
|
EFI_HII_HANDLE *HiiHandles;
|
|
CHAR16 *DevicePathStr;
|
|
UINTN Count;
|
|
UINTN CurrentSize;
|
|
UI_HII_DRIVER_INSTANCE *DriverListPtr;
|
|
EFI_STRING NewName;
|
|
BOOLEAN EmptyLineAfter;
|
|
|
|
if (gHiiDriverList != NULL) {
|
|
FreePool(gHiiDriverList);
|
|
}
|
|
|
|
HiiHandles = HiiGetHiiHandles (NULL);
|
|
ASSERT (HiiHandles != NULL);
|
|
|
|
gHiiDriverList = AllocateZeroPool(UI_HII_DRIVER_LIST_SIZE * sizeof (UI_HII_DRIVER_INSTANCE));
|
|
ASSERT (gHiiDriverList != NULL);
|
|
DriverListPtr = gHiiDriverList;
|
|
CurrentSize = UI_HII_DRIVER_LIST_SIZE;
|
|
|
|
for (Index = 0, Count = 0; HiiHandles[Index] != NULL; Index++) {
|
|
if (!IsRequiredDriver (HiiHandles[Index], ClassGuid, &Token, &TokenHelp, &gHiiDriverList[Count].FormSetGuid)) {
|
|
continue;
|
|
}
|
|
|
|
String = HiiGetString (HiiHandles[Index], Token, NULL);
|
|
if (String == NULL) {
|
|
String = HiiGetString (HiiHandle, STRING_TOKEN (STR_MISSING_STRING), NULL);
|
|
ASSERT (String != NULL);
|
|
} else if (SpecialHandlerFn != NULL) {
|
|
//
|
|
// Check whether need to rename the driver name.
|
|
//
|
|
EmptyLineAfter = FALSE;
|
|
if (SpecialHandlerFn (String, &NewName, &EmptyLineAfter)) {
|
|
FreePool(String);
|
|
String = NewName;
|
|
DriverListPtr[Count].EmptyLineAfter = EmptyLineAfter;
|
|
}
|
|
}
|
|
DriverListPtr[Count].PromptId = HiiSetString (HiiHandle, 0, String, NULL);
|
|
FreePool(String);
|
|
|
|
String = HiiGetString (HiiHandles[Index], TokenHelp, NULL);
|
|
if (String == NULL) {
|
|
String = HiiGetString (HiiHandle, STRING_TOKEN (STR_MISSING_STRING), NULL);
|
|
ASSERT (String != NULL);
|
|
}
|
|
DriverListPtr[Count].HelpId = HiiSetString (HiiHandle, 0, String, NULL);
|
|
FreePool(String);
|
|
|
|
DevicePathStr = ExtractDevicePathFromHandle(HiiHandles[Index]);
|
|
if (DevicePathStr != NULL){
|
|
DriverListPtr[Count].DevicePathId = HiiSetString (HiiHandle, 0, DevicePathStr, NULL);
|
|
FreePool(DevicePathStr);
|
|
} else {
|
|
DriverListPtr[Count].DevicePathId = 0;
|
|
}
|
|
|
|
Count++;
|
|
if (Count >= CurrentSize) {
|
|
DriverListPtr = ReallocatePool (
|
|
CurrentSize * sizeof (UI_HII_DRIVER_INSTANCE),
|
|
(Count + UI_HII_DRIVER_LIST_SIZE)
|
|
* sizeof (UI_HII_DRIVER_INSTANCE),
|
|
gHiiDriverList
|
|
);
|
|
ASSERT (DriverListPtr != NULL);
|
|
gHiiDriverList = DriverListPtr;
|
|
CurrentSize += UI_HII_DRIVER_LIST_SIZE;
|
|
}
|
|
}
|
|
|
|
FreePool(HiiHandles);
|
|
|
|
Index = 0;
|
|
while (gHiiDriverList[Index].PromptId != 0) {
|
|
HiiCreateGotoExOpCode (
|
|
StartOpCodeHandle,
|
|
0,
|
|
gHiiDriverList[Index].PromptId,
|
|
gHiiDriverList[Index].HelpId,
|
|
0,
|
|
0,
|
|
0,
|
|
&gHiiDriverList[Index].FormSetGuid,
|
|
gHiiDriverList[Index].DevicePathId
|
|
);
|
|
|
|
if (gHiiDriverList[Index].EmptyLineAfter) {
|
|
BmmCreateEmptyLine (HiiHandle, StartOpCodeHandle);
|
|
}
|
|
|
|
Index ++;
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|