diff options
Diffstat (limited to 'MdeModulePkg/Application/UiApp/FrontPageCustomizedUiSupport.c')
| -rw-r--r-- | MdeModulePkg/Application/UiApp/FrontPageCustomizedUiSupport.c | 1358 |
1 files changed, 679 insertions, 679 deletions
diff --git a/MdeModulePkg/Application/UiApp/FrontPageCustomizedUiSupport.c b/MdeModulePkg/Application/UiApp/FrontPageCustomizedUiSupport.c index 8bc7883bb7..9004d40f51 100644 --- a/MdeModulePkg/Application/UiApp/FrontPageCustomizedUiSupport.c +++ b/MdeModulePkg/Application/UiApp/FrontPageCustomizedUiSupport.c @@ -1,679 +1,679 @@ -/** @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 special 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;
-}
+/** @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 special 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; +} |
