/** @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; | |
} | |