mirror of
https://github.com/CloverHackyColor/CloverBootloader.git
synced 2024-12-26 16:47:40 +01:00
673 lines
19 KiB
C
673 lines
19 KiB
C
|
/** @file
|
||
|
|
||
|
This library class defines a set of interfaces to customize Ui module
|
||
|
|
||
|
Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
|
||
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||
|
|
||
|
**/
|
||
|
#include <Uefi.h>
|
||
|
|
||
|
#include <Guid/MdeModuleHii.h>
|
||
|
#include <Guid/GlobalVariable.h>
|
||
|
|
||
|
#include <Protocol/HiiConfigAccess.h>
|
||
|
#include <Protocol/HiiString.h>
|
||
|
|
||
|
#include <Library/HiiLib.h>
|
||
|
#include <Library/DebugLib.h>
|
||
|
#include <Library/UefiLib.h>
|
||
|
#include <Library/BaseMemoryLib.h>
|
||
|
#include <Library/PcdLib.h>
|
||
|
#include <Library/MemoryAllocationLib.h>
|
||
|
#include <Library/UefiRuntimeServicesTableLib.h>
|
||
|
#include <Library/UefiHiiServicesLib.h>
|
||
|
#include <Library/DevicePathLib.h>
|
||
|
#include <Library/UefiBootServicesTableLib.h>
|
||
|
#include "FrontPageCustomizedUiSupport.h"
|
||
|
|
||
|
//
|
||
|
// This is the VFR compiler generated header file which defines the
|
||
|
// string identifiers.
|
||
|
//
|
||
|
#define PRINTABLE_LANGUAGE_NAME_STRING_ID 0x0001
|
||
|
|
||
|
#define UI_HII_DRIVER_LIST_SIZE 0x8
|
||
|
|
||
|
#define FRONT_PAGE_KEY_CONTINUE 0x1000
|
||
|
#define FRONT_PAGE_KEY_RESET 0x1001
|
||
|
#define FRONT_PAGE_KEY_LANGUAGE 0x1002
|
||
|
#define FRONT_PAGE_KEY_DRIVER 0x2000
|
||
|
|
||
|
typedef struct {
|
||
|
EFI_STRING_ID PromptId;
|
||
|
EFI_STRING_ID HelpId;
|
||
|
EFI_STRING_ID DevicePathId;
|
||
|
EFI_GUID FormSetGuid;
|
||
|
BOOLEAN EmptyLineAfter;
|
||
|
} UI_HII_DRIVER_INSTANCE;
|
||
|
|
||
|
CHAR8 *gLanguageString;
|
||
|
EFI_STRING_ID *gLanguageToken;
|
||
|
UI_HII_DRIVER_INSTANCE *gHiiDriverList;
|
||
|
extern EFI_HII_HANDLE gStringPackHandle;
|
||
|
UINT8 gCurrentLanguageIndex;
|
||
|
|
||
|
|
||
|
/**
|
||
|
Get next language from language code list (with separator ';').
|
||
|
|
||
|
If LangCode is NULL, then ASSERT.
|
||
|
If Lang is NULL, then ASSERT.
|
||
|
|
||
|
@param LangCode On input: point to first language in the list. On
|
||
|
output: point to next language in the list, or
|
||
|
NULL if no more language in the list.
|
||
|
@param Lang The first language in the list.
|
||
|
|
||
|
**/
|
||
|
VOID
|
||
|
GetNextLanguage (
|
||
|
IN OUT CHAR8 **LangCode,
|
||
|
OUT CHAR8 *Lang
|
||
|
)
|
||
|
{
|
||
|
UINTN Index;
|
||
|
CHAR8 *StringPtr;
|
||
|
|
||
|
ASSERT (LangCode != NULL);
|
||
|
ASSERT (*LangCode != NULL);
|
||
|
ASSERT (Lang != NULL);
|
||
|
|
||
|
Index = 0;
|
||
|
StringPtr = *LangCode;
|
||
|
while (StringPtr[Index] != 0 && StringPtr[Index] != ';') {
|
||
|
Index++;
|
||
|
}
|
||
|
|
||
|
CopyMem (Lang, StringPtr, Index);
|
||
|
Lang[Index] = 0;
|
||
|
|
||
|
if (StringPtr[Index] == ';') {
|
||
|
Index++;
|
||
|
}
|
||
|
*LangCode = StringPtr + Index;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
This function processes the language changes in configuration.
|
||
|
|
||
|
@param Value A pointer to the data being sent to the original exporting driver.
|
||
|
|
||
|
|
||
|
@retval TRUE The callback successfully handled the action.
|
||
|
@retval FALSE The callback not supported in this handler.
|
||
|
|
||
|
**/
|
||
|
EFI_STATUS
|
||
|
LanguageChangeHandler (
|
||
|
IN EFI_IFR_TYPE_VALUE *Value
|
||
|
)
|
||
|
{
|
||
|
CHAR8 *LangCode;
|
||
|
CHAR8 *Lang;
|
||
|
UINTN Index;
|
||
|
EFI_STATUS Status;
|
||
|
|
||
|
//
|
||
|
// Allocate working buffer for RFC 4646 language in supported LanguageString.
|
||
|
//
|
||
|
Lang = AllocatePool (AsciiStrSize (gLanguageString));
|
||
|
ASSERT (Lang != NULL);
|
||
|
|
||
|
Index = 0;
|
||
|
LangCode = gLanguageString;
|
||
|
while (*LangCode != 0) {
|
||
|
GetNextLanguage (&LangCode, Lang);
|
||
|
|
||
|
if (Index == Value->u8) {
|
||
|
gCurrentLanguageIndex = Value->u8;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
Index++;
|
||
|
}
|
||
|
|
||
|
if (Index == Value->u8) {
|
||
|
Status = gRT->SetVariable (
|
||
|
L"PlatformLang",
|
||
|
&gEfiGlobalVariableGuid,
|
||
|
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
|
||
|
AsciiStrSize (Lang),
|
||
|
Lang
|
||
|
);
|
||
|
if (EFI_ERROR (Status)) {
|
||
|
FreePool (Lang);
|
||
|
return EFI_DEVICE_ERROR;
|
||
|
}
|
||
|
} else {
|
||
|
ASSERT (FALSE);
|
||
|
}
|
||
|
FreePool (Lang);
|
||
|
|
||
|
return EFI_SUCCESS;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
This function processes the results of changes in configuration.
|
||
|
|
||
|
|
||
|
@param HiiHandle Points to the hii handle for this formset.
|
||
|
@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.
|
||
|
@param Type The type of value for the question.
|
||
|
@param Value A pointer to the data being sent to the original exporting driver.
|
||
|
@param ActionRequest On return, points to the action requested by the callback function.
|
||
|
@param Status Return the handle status.
|
||
|
|
||
|
@retval TRUE The callback successfully handled the action.
|
||
|
@retval FALSE The callback not supported in this handler.
|
||
|
|
||
|
**/
|
||
|
BOOLEAN
|
||
|
UiSupportLibCallbackHandler (
|
||
|
IN EFI_HII_HANDLE HiiHandle,
|
||
|
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,
|
||
|
OUT EFI_STATUS *Status
|
||
|
)
|
||
|
{
|
||
|
if (QuestionId != FRONT_PAGE_KEY_CONTINUE &&
|
||
|
QuestionId != FRONT_PAGE_KEY_RESET &&
|
||
|
QuestionId != FRONT_PAGE_KEY_LANGUAGE) {
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
if (Action == EFI_BROWSER_ACTION_RETRIEVE) {
|
||
|
if (QuestionId == FRONT_PAGE_KEY_LANGUAGE) {
|
||
|
Value->u8 = gCurrentLanguageIndex;
|
||
|
*Status = EFI_SUCCESS;
|
||
|
} else {
|
||
|
*Status = EFI_UNSUPPORTED;
|
||
|
}
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
if (Action != EFI_BROWSER_ACTION_CHANGED) {
|
||
|
//
|
||
|
// Do nothing for other UEFI Action. Only do call back when data is changed.
|
||
|
//
|
||
|
*Status = EFI_UNSUPPORTED;
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
if (Action == EFI_BROWSER_ACTION_CHANGED) {
|
||
|
if ((Value == NULL) || (ActionRequest == NULL)) {
|
||
|
*Status = EFI_INVALID_PARAMETER;
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
*Status = EFI_SUCCESS;
|
||
|
switch (QuestionId) {
|
||
|
case FRONT_PAGE_KEY_CONTINUE:
|
||
|
//
|
||
|
// This is the continue - clear the screen and return an error to get out of FrontPage loop
|
||
|
//
|
||
|
*ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;
|
||
|
break;
|
||
|
|
||
|
case FRONT_PAGE_KEY_LANGUAGE:
|
||
|
*Status = LanguageChangeHandler(Value);
|
||
|
break;
|
||
|
|
||
|
case FRONT_PAGE_KEY_RESET:
|
||
|
//
|
||
|
// Reset
|
||
|
//
|
||
|
gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL);
|
||
|
*Status = EFI_UNSUPPORTED;
|
||
|
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
Create Select language menu in the front page with oneof opcode.
|
||
|
|
||
|
@param[in] HiiHandle The hii handle for the Uiapp driver.
|
||
|
@param[in] StartOpCodeHandle The opcode handle to save the new opcode.
|
||
|
|
||
|
**/
|
||
|
VOID
|
||
|
UiCreateLanguageMenu (
|
||
|
IN EFI_HII_HANDLE HiiHandle,
|
||
|
IN VOID *StartOpCodeHandle
|
||
|
)
|
||
|
{
|
||
|
CHAR8 *LangCode;
|
||
|
CHAR8 *Lang;
|
||
|
UINTN LangSize;
|
||
|
CHAR8 *CurrentLang;
|
||
|
UINTN OptionCount;
|
||
|
CHAR16 *StringBuffer;
|
||
|
VOID *OptionsOpCodeHandle;
|
||
|
UINTN StringSize;
|
||
|
EFI_STATUS Status;
|
||
|
EFI_HII_STRING_PROTOCOL *HiiString;
|
||
|
|
||
|
Lang = NULL;
|
||
|
StringBuffer = NULL;
|
||
|
|
||
|
//
|
||
|
// Init OpCode Handle and Allocate space for creation of UpdateData Buffer
|
||
|
//
|
||
|
OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();
|
||
|
ASSERT (OptionsOpCodeHandle != NULL);
|
||
|
|
||
|
GetEfiGlobalVariable2 (L"PlatformLang", (VOID**)&CurrentLang, NULL);
|
||
|
|
||
|
//
|
||
|
// Get Support language list from variable.
|
||
|
//
|
||
|
GetEfiGlobalVariable2 (L"PlatformLangCodes", (VOID**)&gLanguageString, NULL);
|
||
|
if (gLanguageString == NULL) {
|
||
|
gLanguageString = AllocateCopyPool (
|
||
|
AsciiStrSize ((CHAR8 *) PcdGetPtr (PcdUefiVariableDefaultPlatformLangCodes)),
|
||
|
(CHAR8 *) PcdGetPtr (PcdUefiVariableDefaultPlatformLangCodes)
|
||
|
);
|
||
|
ASSERT (gLanguageString != NULL);
|
||
|
}
|
||
|
|
||
|
if (gLanguageToken == NULL) {
|
||
|
//
|
||
|
// Count the language list number.
|
||
|
//
|
||
|
LangCode = gLanguageString;
|
||
|
Lang = AllocatePool (AsciiStrSize (gLanguageString));
|
||
|
ASSERT (Lang != NULL);
|
||
|
|
||
|
OptionCount = 0;
|
||
|
while (*LangCode != 0) {
|
||
|
GetNextLanguage (&LangCode, Lang);
|
||
|
OptionCount ++;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Allocate extra 1 as the end tag.
|
||
|
//
|
||
|
gLanguageToken = AllocateZeroPool ((OptionCount + 1) * sizeof (EFI_STRING_ID));
|
||
|
ASSERT (gLanguageToken != NULL);
|
||
|
|
||
|
Status = gBS->LocateProtocol (&gEfiHiiStringProtocolGuid, NULL, (VOID **) &HiiString);
|
||
|
ASSERT_EFI_ERROR (Status);
|
||
|
|
||
|
LangCode = gLanguageString;
|
||
|
OptionCount = 0;
|
||
|
while (*LangCode != 0) {
|
||
|
GetNextLanguage (&LangCode, Lang);
|
||
|
|
||
|
StringSize = 0;
|
||
|
Status = HiiString->GetString (HiiString, Lang, HiiHandle, PRINTABLE_LANGUAGE_NAME_STRING_ID, StringBuffer, &StringSize, NULL);
|
||
|
if (Status == EFI_BUFFER_TOO_SMALL) {
|
||
|
StringBuffer = AllocateZeroPool (StringSize);
|
||
|
ASSERT (StringBuffer != NULL);
|
||
|
Status = HiiString->GetString (HiiString, Lang, HiiHandle, PRINTABLE_LANGUAGE_NAME_STRING_ID, StringBuffer, &StringSize, NULL);
|
||
|
ASSERT_EFI_ERROR (Status);
|
||
|
}
|
||
|
|
||
|
if (EFI_ERROR (Status)) {
|
||
|
LangSize = AsciiStrSize (Lang);
|
||
|
StringBuffer = AllocatePool (LangSize * sizeof (CHAR16));
|
||
|
ASSERT (StringBuffer != NULL);
|
||
|
AsciiStrToUnicodeStrS (Lang, StringBuffer, LangSize);
|
||
|
}
|
||
|
|
||
|
ASSERT (StringBuffer != NULL);
|
||
|
gLanguageToken[OptionCount] = HiiSetString (HiiHandle, 0, StringBuffer, NULL);
|
||
|
FreePool (StringBuffer);
|
||
|
|
||
|
OptionCount++;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
ASSERT (gLanguageToken != NULL);
|
||
|
LangCode = gLanguageString;
|
||
|
OptionCount = 0;
|
||
|
if (Lang == NULL) {
|
||
|
Lang = AllocatePool (AsciiStrSize (gLanguageString));
|
||
|
ASSERT (Lang != NULL);
|
||
|
}
|
||
|
while (*LangCode != 0) {
|
||
|
GetNextLanguage (&LangCode, Lang);
|
||
|
|
||
|
if (CurrentLang != NULL && AsciiStrCmp (Lang, CurrentLang) == 0) {
|
||
|
HiiCreateOneOfOptionOpCode (
|
||
|
OptionsOpCodeHandle,
|
||
|
gLanguageToken[OptionCount],
|
||
|
EFI_IFR_OPTION_DEFAULT,
|
||
|
EFI_IFR_NUMERIC_SIZE_1,
|
||
|
(UINT8) OptionCount
|
||
|
);
|
||
|
gCurrentLanguageIndex = (UINT8) OptionCount;
|
||
|
} else {
|
||
|
HiiCreateOneOfOptionOpCode (
|
||
|
OptionsOpCodeHandle,
|
||
|
gLanguageToken[OptionCount],
|
||
|
0,
|
||
|
EFI_IFR_NUMERIC_SIZE_1,
|
||
|
(UINT8) OptionCount
|
||
|
);
|
||
|
}
|
||
|
|
||
|
OptionCount++;
|
||
|
}
|
||
|
|
||
|
if (CurrentLang != NULL) {
|
||
|
FreePool (CurrentLang);
|
||
|
}
|
||
|
FreePool (Lang);
|
||
|
|
||
|
HiiCreateOneOfOpCode (
|
||
|
StartOpCodeHandle,
|
||
|
FRONT_PAGE_KEY_LANGUAGE,
|
||
|
0,
|
||
|
0,
|
||
|
STRING_TOKEN (STR_LANGUAGE_SELECT),
|
||
|
STRING_TOKEN (STR_LANGUAGE_SELECT_HELP),
|
||
|
EFI_IFR_FLAG_CALLBACK,
|
||
|
EFI_IFR_NUMERIC_SIZE_1,
|
||
|
OptionsOpCodeHandle,
|
||
|
NULL
|
||
|
);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
Create continue menu in the front page.
|
||
|
|
||
|
@param[in] HiiHandle The hii handle for the Uiapp driver.
|
||
|
@param[in] StartOpCodeHandle The opcode handle to save the new opcode.
|
||
|
|
||
|
**/
|
||
|
VOID
|
||
|
UiCreateContinueMenu (
|
||
|
IN EFI_HII_HANDLE HiiHandle,
|
||
|
IN VOID *StartOpCodeHandle
|
||
|
)
|
||
|
{
|
||
|
HiiCreateActionOpCode (
|
||
|
StartOpCodeHandle,
|
||
|
FRONT_PAGE_KEY_CONTINUE,
|
||
|
STRING_TOKEN (STR_CONTINUE_PROMPT),
|
||
|
STRING_TOKEN (STR_CONTINUE_PROMPT),
|
||
|
EFI_IFR_FLAG_CALLBACK,
|
||
|
0
|
||
|
);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
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
|
||
|
UiCreateEmptyLine (
|
||
|
IN EFI_HII_HANDLE HiiHandle,
|
||
|
IN VOID *StartOpCodeHandle
|
||
|
)
|
||
|
{
|
||
|
HiiCreateSubTitleOpCode (StartOpCodeHandle, STRING_TOKEN (STR_NULL_STRING), 0, 0, 0);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
Create Reset menu in the front page.
|
||
|
|
||
|
@param[in] HiiHandle The hii handle for the Uiapp driver.
|
||
|
@param[in] StartOpCodeHandle The opcode handle to save the new opcode.
|
||
|
|
||
|
**/
|
||
|
VOID
|
||
|
UiCreateResetMenu (
|
||
|
IN EFI_HII_HANDLE HiiHandle,
|
||
|
IN VOID *StartOpCodeHandle
|
||
|
)
|
||
|
{
|
||
|
HiiCreateActionOpCode (
|
||
|
StartOpCodeHandle,
|
||
|
FRONT_PAGE_KEY_RESET,
|
||
|
STRING_TOKEN (STR_RESET_STRING),
|
||
|
STRING_TOKEN (STR_RESET_STRING),
|
||
|
EFI_IFR_FLAG_CALLBACK,
|
||
|
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 *
|
||
|
ExtractDevicePathFromHiiHandle (
|
||
|
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
|
||
|
RequiredDriver (
|
||
|
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
|
||
|
UiListThirdPartyDrivers (
|
||
|
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 (!RequiredDriver (HiiHandles[Index], ClassGuid, &Token, &TokenHelp, &gHiiDriverList[Count].FormSetGuid)) {
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
String = HiiGetString (HiiHandles[Index], Token, NULL);
|
||
|
if (String == NULL) {
|
||
|
String = HiiGetString (gStringPackHandle, 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 (gStringPackHandle, STRING_TOKEN (STR_MISSING_STRING), NULL);
|
||
|
ASSERT (String != NULL);
|
||
|
}
|
||
|
DriverListPtr[Count].HelpId = HiiSetString (HiiHandle, 0, String, NULL);
|
||
|
FreePool (String);
|
||
|
|
||
|
DevicePathStr = ExtractDevicePathFromHiiHandle(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,
|
||
|
(EFI_QUESTION_ID) (Index + FRONT_PAGE_KEY_DRIVER),
|
||
|
0,
|
||
|
&gHiiDriverList[Index].FormSetGuid,
|
||
|
gHiiDriverList[Index].DevicePathId
|
||
|
);
|
||
|
|
||
|
if (gHiiDriverList[Index].EmptyLineAfter) {
|
||
|
UiCreateEmptyLine (HiiHandle, StartOpCodeHandle);
|
||
|
}
|
||
|
|
||
|
Index ++;
|
||
|
}
|
||
|
|
||
|
return EFI_SUCCESS;
|
||
|
}
|