+/** @file\r
+\r
+ This library class defines a set of interfaces to customize Ui module\r
+\r
+Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials are licensed and made available under\r
+the terms and conditions of the BSD License that accompanies this distribution.\r
+The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php.\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+#include <Uefi.h>\r
+\r
+#include <Guid/MdeModuleHii.h>\r
+#include <Guid/GlobalVariable.h>\r
+\r
+#include <Protocol/HiiConfigAccess.h>\r
+#include <Protocol/HiiString.h>\r
+\r
+#include <Library/HiiLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/UefiLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/PcdLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/UefiRuntimeServicesTableLib.h>\r
+#include <Library/UefiHiiServicesLib.h>\r
+#include <Library/DevicePathLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include "FrontPageCustomizedUiSupport.h"\r
+\r
+//\r
+// This is the VFR compiler generated header file which defines the\r
+// string identifiers.\r
+//\r
+#define PRINTABLE_LANGUAGE_NAME_STRING_ID 0x0001\r
+\r
+#define UI_HII_DRIVER_LIST_SIZE 0x8\r
+\r
+#define FRONT_PAGE_KEY_CONTINUE 0x1000\r
+#define FRONT_PAGE_KEY_RESET 0x1001\r
+#define FRONT_PAGE_KEY_LANGUAGE 0x1002\r
+\r
+typedef struct {\r
+ EFI_STRING_ID PromptId;\r
+ EFI_STRING_ID HelpId;\r
+ EFI_STRING_ID DevicePathId;\r
+ EFI_GUID FormSetGuid;\r
+ BOOLEAN EmptyLineAfter;\r
+} UI_HII_DRIVER_INSTANCE;\r
+\r
+CHAR8 *gLanguageString;\r
+EFI_STRING_ID *gLanguageToken;\r
+UI_HII_DRIVER_INSTANCE *gHiiDriverList;\r
+EFI_HII_HANDLE gHiiHandle;\r
+\r
+\r
+/**\r
+ Get next language from language code list (with separator ';').\r
+\r
+ If LangCode is NULL, then ASSERT.\r
+ If Lang is NULL, then ASSERT.\r
+\r
+ @param LangCode On input: point to first language in the list. On\r
+ output: point to next language in the list, or\r
+ NULL if no more language in the list.\r
+ @param Lang The first language in the list.\r
+\r
+**/\r
+VOID\r
+GetNextLanguage (\r
+ IN OUT CHAR8 **LangCode,\r
+ OUT CHAR8 *Lang\r
+ )\r
+{\r
+ UINTN Index;\r
+ CHAR8 *StringPtr;\r
+\r
+ ASSERT (LangCode != NULL);\r
+ ASSERT (*LangCode != NULL);\r
+ ASSERT (Lang != NULL);\r
+\r
+ Index = 0;\r
+ StringPtr = *LangCode;\r
+ while (StringPtr[Index] != 0 && StringPtr[Index] != ';') {\r
+ Index++;\r
+ }\r
+\r
+ CopyMem (Lang, StringPtr, Index);\r
+ Lang[Index] = 0;\r
+\r
+ if (StringPtr[Index] == ';') {\r
+ Index++;\r
+ }\r
+ *LangCode = StringPtr + Index;\r
+}\r
+\r
+/**\r
+ This function processes the language changes in configuration.\r
+\r
+ @param Value A pointer to the data being sent to the original exporting driver.\r
+\r
+\r
+ @retval TRUE The callback successfully handled the action.\r
+ @retval FALSE The callback not supported in this handler.\r
+\r
+**/\r
+EFI_STATUS\r
+LanguageChangeHandler (\r
+ IN EFI_IFR_TYPE_VALUE *Value\r
+ )\r
+{\r
+ CHAR8 *LangCode;\r
+ CHAR8 *Lang;\r
+ UINTN Index;\r
+ EFI_STATUS Status;\r
+\r
+ //\r
+ // Allocate working buffer for RFC 4646 language in supported LanguageString.\r
+ //\r
+ Lang = AllocatePool (AsciiStrSize (gLanguageString));\r
+ ASSERT (Lang != NULL);\r
+\r
+ Index = 0;\r
+ LangCode = gLanguageString;\r
+ while (*LangCode != 0) {\r
+ GetNextLanguage (&LangCode, Lang);\r
+\r
+ if (Index == Value->u8) {\r
+ break;\r
+ }\r
+\r
+ Index++;\r
+ }\r
+\r
+ if (Index == Value->u8) {\r
+ Status = gRT->SetVariable (\r
+ L"PlatformLang",\r
+ &gEfiGlobalVariableGuid,\r
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
+ AsciiStrSize (Lang),\r
+ Lang\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ FreePool (Lang);\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+ } else {\r
+ ASSERT (FALSE);\r
+ }\r
+ FreePool (Lang);\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ This function processes the results of changes in configuration.\r
+\r
+\r
+ @param HiiHandle Points to the hii handle for this formset.\r
+ @param Action Specifies the type of action taken by the browser.\r
+ @param QuestionId A unique value which is sent to the original exporting driver\r
+ so that it can identify the type of data to expect.\r
+ @param Type The type of value for the question.\r
+ @param Value A pointer to the data being sent to the original exporting driver.\r
+ @param ActionRequest On return, points to the action requested by the callback function.\r
+ @param Status Return the handle status.\r
+\r
+ @retval TRUE The callback successfully handled the action.\r
+ @retval FALSE The callback not supported in this handler.\r
+\r
+**/\r
+BOOLEAN\r
+UiSupportLibCallbackHandler (\r
+ IN EFI_HII_HANDLE HiiHandle,\r
+ IN EFI_BROWSER_ACTION Action,\r
+ IN EFI_QUESTION_ID QuestionId,\r
+ IN UINT8 Type,\r
+ IN EFI_IFR_TYPE_VALUE *Value,\r
+ OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest,\r
+ OUT EFI_STATUS *Status\r
+ )\r
+{\r
+ if (QuestionId != FRONT_PAGE_KEY_CONTINUE &&\r
+ QuestionId != FRONT_PAGE_KEY_RESET &&\r
+ QuestionId != FRONT_PAGE_KEY_LANGUAGE) {\r
+ return FALSE;\r
+ }\r
+\r
+ if (Action != EFI_BROWSER_ACTION_CHANGED) {\r
+ //\r
+ // Do nothing for other UEFI Action. Only do call back when data is changed.\r
+ //\r
+ *Status = EFI_UNSUPPORTED;\r
+ }\r
+\r
+ if (Action == EFI_BROWSER_ACTION_CHANGED) {\r
+ if ((Value == NULL) || (ActionRequest == NULL)) {\r
+ *Status = EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ *Status = EFI_SUCCESS;\r
+ switch (QuestionId) {\r
+ case FRONT_PAGE_KEY_CONTINUE:\r
+ //\r
+ // This is the continue - clear the screen and return an error to get out of FrontPage loop\r
+ //\r
+ *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;\r
+ break;\r
+\r
+ case FRONT_PAGE_KEY_LANGUAGE:\r
+ *Status = LanguageChangeHandler(Value);\r
+ break;\r
+\r
+ case FRONT_PAGE_KEY_RESET:\r
+ //\r
+ // Reset\r
+ //\r
+ gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL);\r
+ *Status = EFI_UNSUPPORTED;\r
+\r
+ default:\r
+ break;\r
+ }\r
+ }\r
+\r
+ return TRUE;\r
+}\r
+\r
+/**\r
+ Create Select language menu in the front page with oneof opcode.\r
+\r
+ @param[in] HiiHandle The hii handle for the Uiapp driver.\r
+ @param[in] QuestionId Question ID\r
+ @param[in] StartOpCodeHandle The opcode handle to save the new opcode.\r
+\r
+ @retval EFI_SUCCESS Search the driver success\r
+\r
+**/\r
+VOID\r
+UiCreateLanguageMenu (\r
+ IN EFI_HII_HANDLE HiiHandle,\r
+ IN VOID *StartOpCodeHandle\r
+ )\r
+{\r
+ CHAR8 *LangCode;\r
+ CHAR8 *Lang;\r
+ CHAR8 *CurrentLang;\r
+ UINTN OptionCount;\r
+ CHAR16 *StringBuffer;\r
+ VOID *OptionsOpCodeHandle;\r
+ UINTN StringSize;\r
+ EFI_STATUS Status;\r
+ EFI_HII_STRING_PROTOCOL *HiiString;\r
+\r
+ Lang = NULL;\r
+ StringBuffer = NULL;\r
+\r
+ //\r
+ // Init OpCode Handle and Allocate space for creation of UpdateData Buffer\r
+ //\r
+ OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();\r
+ ASSERT (OptionsOpCodeHandle != NULL);\r
+\r
+ GetEfiGlobalVariable2 (L"PlatformLang", (VOID**)&CurrentLang, NULL);\r
+\r
+ //\r
+ // Get Support language list from variable.\r
+ //\r
+ GetEfiGlobalVariable2 (L"PlatformLangCodes", (VOID**)&gLanguageString, NULL);\r
+ if (gLanguageString == NULL) {\r
+ gLanguageString = AllocateCopyPool (\r
+ AsciiStrSize ((CHAR8 *) PcdGetPtr (PcdUefiVariableDefaultPlatformLangCodes)),\r
+ (CHAR8 *) PcdGetPtr (PcdUefiVariableDefaultPlatformLangCodes)\r
+ );\r
+ ASSERT (gLanguageString != NULL);\r
+ }\r
+\r
+ if (gLanguageToken == NULL) {\r
+ //\r
+ // Count the language list number.\r
+ //\r
+ LangCode = gLanguageString;\r
+ Lang = AllocatePool (AsciiStrSize (gLanguageString));\r
+ ASSERT (Lang != NULL);\r
+\r
+ OptionCount = 0;\r
+ while (*LangCode != 0) {\r
+ GetNextLanguage (&LangCode, Lang);\r
+ OptionCount ++;\r
+ }\r
+\r
+ //\r
+ // Allocate extra 1 as the end tag.\r
+ //\r
+ gLanguageToken = AllocateZeroPool ((OptionCount + 1) * sizeof (EFI_STRING_ID));\r
+ ASSERT (gLanguageToken != NULL);\r
+\r
+ Status = gBS->LocateProtocol (&gEfiHiiStringProtocolGuid, NULL, (VOID **) &HiiString);\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ LangCode = gLanguageString;\r
+ OptionCount = 0;\r
+ while (*LangCode != 0) {\r
+ GetNextLanguage (&LangCode, Lang);\r
+\r
+ StringSize = 0;\r
+ Status = HiiString->GetString (HiiString, Lang, HiiHandle, PRINTABLE_LANGUAGE_NAME_STRING_ID, StringBuffer, &StringSize, NULL);\r
+ if (Status == EFI_BUFFER_TOO_SMALL) {\r
+ StringBuffer = AllocateZeroPool (StringSize);\r
+ ASSERT (StringBuffer != NULL);\r
+ Status = HiiString->GetString (HiiString, Lang, HiiHandle, PRINTABLE_LANGUAGE_NAME_STRING_ID, StringBuffer, &StringSize, NULL);\r
+ ASSERT_EFI_ERROR (Status);\r
+ }\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ StringBuffer = AllocatePool (AsciiStrSize (Lang) * sizeof (CHAR16));\r
+ ASSERT (StringBuffer != NULL);\r
+ AsciiStrToUnicodeStr (Lang, StringBuffer);\r
+ }\r
+\r
+ ASSERT (StringBuffer != NULL);\r
+ gLanguageToken[OptionCount] = HiiSetString (HiiHandle, 0, StringBuffer, NULL);\r
+ FreePool (StringBuffer);\r
+\r
+ OptionCount++;\r
+ }\r
+ }\r
+\r
+ ASSERT (gLanguageToken != NULL);\r
+ LangCode = gLanguageString;\r
+ OptionCount = 0;\r
+ if (Lang == NULL) {\r
+ Lang = AllocatePool (AsciiStrSize (gLanguageString));\r
+ ASSERT (Lang != NULL);\r
+ }\r
+ while (*LangCode != 0) {\r
+ GetNextLanguage (&LangCode, Lang);\r
+\r
+ if (CurrentLang != NULL && AsciiStrCmp (Lang, CurrentLang) == 0) {\r
+ HiiCreateOneOfOptionOpCode (\r
+ OptionsOpCodeHandle,\r
+ gLanguageToken[OptionCount],\r
+ EFI_IFR_OPTION_DEFAULT,\r
+ EFI_IFR_NUMERIC_SIZE_1,\r
+ (UINT8) OptionCount\r
+ );\r
+ } else {\r
+ HiiCreateOneOfOptionOpCode (\r
+ OptionsOpCodeHandle,\r
+ gLanguageToken[OptionCount],\r
+ 0,\r
+ EFI_IFR_NUMERIC_SIZE_1,\r
+ (UINT8) OptionCount\r
+ );\r
+ }\r
+\r
+ OptionCount++;\r
+ }\r
+\r
+ if (CurrentLang != NULL) {\r
+ FreePool (CurrentLang);\r
+ }\r
+ FreePool (Lang);\r
+\r
+ HiiCreateOneOfOpCode (\r
+ StartOpCodeHandle,\r
+ FRONT_PAGE_KEY_LANGUAGE,\r
+ 0,\r
+ 0,\r
+ STRING_TOKEN (STR_LANGUAGE_SELECT),\r
+ STRING_TOKEN (STR_LANGUAGE_SELECT_HELP),\r
+ EFI_IFR_FLAG_CALLBACK,\r
+ EFI_IFR_NUMERIC_SIZE_1,\r
+ OptionsOpCodeHandle,\r
+ NULL\r
+ );\r
+}\r
+\r
+/**\r
+ Create continue menu in the front page.\r
+\r
+ @param[in] HiiHandle The hii handle for the Uiapp driver.\r
+ @param[in] StartOpCodeHandle The opcode handle to save the new opcode.\r
+\r
+**/\r
+VOID\r
+UiCreateContinueMenu (\r
+ IN EFI_HII_HANDLE HiiHandle,\r
+ IN VOID *StartOpCodeHandle\r
+ )\r
+{\r
+ HiiCreateActionOpCode (\r
+ StartOpCodeHandle,\r
+ FRONT_PAGE_KEY_CONTINUE,\r
+ STRING_TOKEN (STR_CONTINUE_PROMPT),\r
+ STRING_TOKEN (STR_CONTINUE_PROMPT),\r
+ EFI_IFR_FLAG_CALLBACK,\r
+ 0\r
+ );\r
+}\r
+\r
+/**\r
+ Create empty line menu in the front page.\r
+\r
+ @param HiiHandle The hii handle for the Uiapp driver.\r
+ @param StartOpCodeHandle The opcode handle to save the new opcode.\r
+\r
+**/\r
+VOID\r
+UiCreateEmptyLine (\r
+ IN EFI_HII_HANDLE HiiHandle,\r
+ IN VOID *StartOpCodeHandle\r
+ )\r
+{\r
+ HiiCreateSubTitleOpCode (StartOpCodeHandle, STRING_TOKEN (STR_NULL_STRING), 0, 0, 0);\r
+}\r
+\r
+/**\r
+ Create Reset menu in the front page.\r
+\r
+ @param[in] HiiHandle The hii handle for the Uiapp driver.\r
+ @param[in] StartOpCodeHandle The opcode handle to save the new opcode.\r
+\r
+**/\r
+VOID\r
+UiCreateResetMenu (\r
+ IN EFI_HII_HANDLE HiiHandle,\r
+ IN VOID *StartOpCodeHandle\r
+ )\r
+{\r
+ HiiCreateActionOpCode (\r
+ StartOpCodeHandle,\r
+ FRONT_PAGE_KEY_RESET,\r
+ STRING_TOKEN (STR_RESET_STRING),\r
+ STRING_TOKEN (STR_RESET_STRING),\r
+ EFI_IFR_FLAG_CALLBACK,\r
+ 0\r
+ );\r
+}\r
+\r
+/**\r
+ Extract device path for given HII handle and class guid.\r
+\r
+ @param Handle The HII handle.\r
+\r
+ @retval NULL Fail to get the device path string.\r
+ @return PathString Get the device path string.\r
+\r
+**/\r
+CHAR16 *\r
+ExtractDevicePathFromHiiHandle (\r
+ IN EFI_HII_HANDLE Handle\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_HANDLE DriverHandle;\r
+\r
+ ASSERT (Handle != NULL);\r
+\r
+ if (Handle == NULL) {\r
+ return NULL;\r
+ }\r
+\r
+ Status = gHiiDatabase->GetPackageListHandle (gHiiDatabase, Handle, &DriverHandle);\r
+ if (EFI_ERROR (Status)) {\r
+ return NULL;\r
+ }\r
+\r
+ return ConvertDevicePathToText(DevicePathFromHandle (DriverHandle), FALSE, FALSE);\r
+}\r
+\r
+/**\r
+ Check whether this driver need to be shown in the front page.\r
+\r
+ @param HiiHandle The hii handle for the driver.\r
+ @param Guid The special guid for the driver which is the target.\r
+ @param PromptId Return the prompt string id.\r
+ @param HelpId Return the help string id.\r
+ @param FormsetGuid Return the formset guid info.\r
+\r
+ @retval EFI_SUCCESS Search the driver success\r
+\r
+**/\r
+BOOLEAN\r
+RequiredDriver (\r
+ IN EFI_HII_HANDLE HiiHandle,\r
+ IN EFI_GUID *Guid,\r
+ OUT EFI_STRING_ID *PromptId,\r
+ OUT EFI_STRING_ID *HelpId,\r
+ OUT VOID *FormsetGuid\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINT8 ClassGuidNum;\r
+ EFI_GUID *ClassGuid;\r
+ EFI_IFR_FORM_SET *Buffer;\r
+ UINTN BufferSize;\r
+ UINT8 *Ptr;\r
+ UINTN TempSize;\r
+ BOOLEAN RetVal;\r
+\r
+ Status = HiiGetFormSetFromHiiHandle(HiiHandle, &Buffer,&BufferSize);\r
+ if (EFI_ERROR (Status)) {\r
+ return FALSE;\r
+ }\r
+\r
+ RetVal = FALSE;\r
+ TempSize = 0;\r
+ Ptr = (UINT8 *) Buffer;\r
+ while(TempSize < BufferSize) {\r
+ TempSize += ((EFI_IFR_OP_HEADER *) Ptr)->Length;\r
+\r
+ if (((EFI_IFR_OP_HEADER *) Ptr)->Length <= OFFSET_OF (EFI_IFR_FORM_SET, Flags)){\r
+ Ptr += ((EFI_IFR_OP_HEADER *) Ptr)->Length;\r
+ continue;\r
+ }\r
+\r
+ ClassGuidNum = (UINT8) (((EFI_IFR_FORM_SET *)Ptr)->Flags & 0x3);\r
+ ClassGuid = (EFI_GUID *) (VOID *)(Ptr + sizeof (EFI_IFR_FORM_SET));\r
+ while (ClassGuidNum-- > 0) {\r
+ if (!CompareGuid (Guid, ClassGuid)){\r
+ ClassGuid ++;\r
+ continue;\r
+ }\r
+\r
+ *PromptId = ((EFI_IFR_FORM_SET *)Ptr)->FormSetTitle;\r
+ *HelpId = ((EFI_IFR_FORM_SET *)Ptr)->Help;\r
+ CopyMem (FormsetGuid, &((EFI_IFR_FORM_SET *) Ptr)->Guid, sizeof (EFI_GUID));\r
+ RetVal = TRUE;\r
+ }\r
+ }\r
+\r
+ FreePool (Buffer);\r
+\r
+ return RetVal;\r
+}\r
+\r
+/**\r
+ Search the drivers in the system which need to show in the front page\r
+ and insert the menu to the front page.\r
+\r
+ @param HiiHandle The hii handle for the Uiapp driver.\r
+ @param ClassGuid The class guid for the driver which is the target.\r
+ @param StartOpCodeHandle The opcode handle to save the new opcode.\r
+ @param SpecialHandler The pointer to the specail handler function, if any.\r
+\r
+ @retval EFI_SUCCESS Search the driver success\r
+\r
+**/\r
+EFI_STATUS\r
+UiListThirdPartyDrivers (\r
+ IN EFI_HII_HANDLE HiiHandle,\r
+ IN EFI_GUID *ClassGuid,\r
+ IN DRIVER_SPECIAL_HANDLER SpecialHandlerFn,\r
+ IN VOID *StartOpCodeHandle\r
+ )\r
+{\r
+ UINTN Index;\r
+ EFI_STRING String;\r
+ EFI_STRING_ID Token;\r
+ EFI_STRING_ID TokenHelp;\r
+ EFI_HII_HANDLE *HiiHandles;\r
+ CHAR16 *DevicePathStr;\r
+ UINTN Count;\r
+ UINTN CurrentSize;\r
+ UI_HII_DRIVER_INSTANCE *DriverListPtr;\r
+ EFI_STRING NewName;\r
+ BOOLEAN EmptyLineAfter;\r
+\r
+ if (gHiiDriverList != NULL) {\r
+ FreePool (gHiiDriverList);\r
+ }\r
+\r
+ HiiHandles = HiiGetHiiHandles (NULL);\r
+ ASSERT (HiiHandles != NULL);\r
+\r
+ gHiiDriverList = AllocateZeroPool (UI_HII_DRIVER_LIST_SIZE * sizeof (UI_HII_DRIVER_INSTANCE));\r
+ ASSERT (gHiiDriverList != NULL);\r
+ DriverListPtr = gHiiDriverList;\r
+ CurrentSize = UI_HII_DRIVER_LIST_SIZE;\r
+\r
+ for (Index = 0, Count = 0; HiiHandles[Index] != NULL; Index++) {\r
+ if (!RequiredDriver (HiiHandles[Index], ClassGuid, &Token, &TokenHelp, &gHiiDriverList[Count].FormSetGuid)) {\r
+ continue;\r
+ }\r
+\r
+ String = HiiGetString (HiiHandles[Index], Token, NULL);\r
+ if (String == NULL) {\r
+ String = HiiGetString (gHiiHandle, STRING_TOKEN (STR_MISSING_STRING), NULL);\r
+ ASSERT (String != NULL);\r
+ } else if (SpecialHandlerFn != NULL) {\r
+ //\r
+ // Check whether need to rename the driver name.\r
+ //\r
+ EmptyLineAfter = FALSE;\r
+ if (SpecialHandlerFn (String, &NewName, &EmptyLineAfter)) {\r
+ FreePool (String);\r
+ String = NewName;\r
+ DriverListPtr[Count].EmptyLineAfter = EmptyLineAfter;\r
+ }\r
+ }\r
+ DriverListPtr[Count].PromptId = HiiSetString (HiiHandle, 0, String, NULL);\r
+ FreePool (String);\r
+\r
+ String = HiiGetString (HiiHandles[Index], TokenHelp, NULL);\r
+ if (String == NULL) {\r
+ String = HiiGetString (gHiiHandle, STRING_TOKEN (STR_MISSING_STRING), NULL);\r
+ ASSERT (String != NULL);\r
+ }\r
+ DriverListPtr[Count].HelpId = HiiSetString (HiiHandle, 0, String, NULL);\r
+ FreePool (String);\r
+\r
+ DevicePathStr = ExtractDevicePathFromHiiHandle(HiiHandles[Index]);\r
+ if (DevicePathStr != NULL){\r
+ DriverListPtr[Count].DevicePathId = HiiSetString (HiiHandle, 0, DevicePathStr, NULL);\r
+ FreePool (DevicePathStr);\r
+ } else {\r
+ DriverListPtr[Count].DevicePathId = 0;\r
+ }\r
+\r
+ Count++;\r
+ if (Count >= CurrentSize) {\r
+ DriverListPtr = AllocateCopyPool ((Count + UI_HII_DRIVER_LIST_SIZE) * sizeof (UI_HII_DRIVER_INSTANCE), gHiiDriverList);\r
+ ASSERT (DriverListPtr != NULL);\r
+ FreePool (gHiiDriverList);\r
+ gHiiDriverList = DriverListPtr;\r
+ CurrentSize += UI_HII_DRIVER_LIST_SIZE;\r
+ }\r
+ }\r
+\r
+ FreePool (HiiHandles);\r
+\r
+ Index = 0;\r
+ while (gHiiDriverList[Index].PromptId != 0) {\r
+ HiiCreateGotoExOpCode (\r
+ StartOpCodeHandle,\r
+ 0,\r
+ gHiiDriverList[Index].PromptId,\r
+ gHiiDriverList[Index].HelpId,\r
+ 0,\r
+ 0,\r
+ 0,\r
+ &gHiiDriverList[Index].FormSetGuid,\r
+ gHiiDriverList[Index].DevicePathId\r
+ );\r
+\r
+ if (gHiiDriverList[Index].EmptyLineAfter) {\r
+ UiCreateEmptyLine (HiiHandle, StartOpCodeHandle);\r
+ }\r
+\r
+ Index ++;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r