blob: e16936041a4dc13b11b09b93339e889f4be9ddf7 [file] [log] [blame]
/** @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;
}