• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /** @file
2 
3   This library class defines a set of interfaces to customize Ui module
4 
5 Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
6 This program and the accompanying materials are licensed and made available under
7 the terms and conditions of the BSD License that accompanies this distribution.
8 The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php.
10 
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13 
14 **/
15 #include <Uefi.h>
16 
17 #include <Guid/MdeModuleHii.h>
18 #include <Guid/GlobalVariable.h>
19 
20 #include <Protocol/HiiConfigAccess.h>
21 #include <Protocol/HiiString.h>
22 
23 #include <Library/HiiLib.h>
24 #include <Library/DebugLib.h>
25 #include <Library/UefiLib.h>
26 #include <Library/BaseMemoryLib.h>
27 #include <Library/PcdLib.h>
28 #include <Library/MemoryAllocationLib.h>
29 #include <Library/UefiRuntimeServicesTableLib.h>
30 #include <Library/UefiHiiServicesLib.h>
31 #include <Library/DevicePathLib.h>
32 #include <Library/UefiBootServicesTableLib.h>
33 #include "FrontPageCustomizedUiSupport.h"
34 
35 //
36 // This is the VFR compiler generated header file which defines the
37 // string identifiers.
38 //
39 #define PRINTABLE_LANGUAGE_NAME_STRING_ID     0x0001
40 
41 #define UI_HII_DRIVER_LIST_SIZE               0x8
42 
43 #define FRONT_PAGE_KEY_CONTINUE               0x1000
44 #define FRONT_PAGE_KEY_RESET                  0x1001
45 #define FRONT_PAGE_KEY_LANGUAGE               0x1002
46 #define FRONT_PAGE_KEY_DRIVER                 0x2000
47 
48 typedef struct {
49   EFI_STRING_ID   PromptId;
50   EFI_STRING_ID   HelpId;
51   EFI_STRING_ID   DevicePathId;
52   EFI_GUID        FormSetGuid;
53   BOOLEAN         EmptyLineAfter;
54 } UI_HII_DRIVER_INSTANCE;
55 
56 CHAR8                        *gLanguageString;
57 EFI_STRING_ID                *gLanguageToken;
58 UI_HII_DRIVER_INSTANCE       *gHiiDriverList;
59 extern EFI_HII_HANDLE        gStringPackHandle;
60 UINT8                        gCurrentLanguageIndex;
61 
62 
63 /**
64   Get next language from language code list (with separator ';').
65 
66   If LangCode is NULL, then ASSERT.
67   If Lang is NULL, then ASSERT.
68 
69   @param  LangCode    On input: point to first language in the list. On
70                                  output: point to next language in the list, or
71                                  NULL if no more language in the list.
72   @param  Lang           The first language in the list.
73 
74 **/
75 VOID
GetNextLanguage(IN OUT CHAR8 ** LangCode,OUT CHAR8 * Lang)76 GetNextLanguage (
77   IN OUT CHAR8      **LangCode,
78   OUT CHAR8         *Lang
79   )
80 {
81   UINTN  Index;
82   CHAR8  *StringPtr;
83 
84   ASSERT (LangCode != NULL);
85   ASSERT (*LangCode != NULL);
86   ASSERT (Lang != NULL);
87 
88   Index = 0;
89   StringPtr = *LangCode;
90   while (StringPtr[Index] != 0 && StringPtr[Index] != ';') {
91     Index++;
92   }
93 
94   CopyMem (Lang, StringPtr, Index);
95   Lang[Index] = 0;
96 
97   if (StringPtr[Index] == ';') {
98     Index++;
99   }
100   *LangCode = StringPtr + Index;
101 }
102 
103 /**
104   This function processes the language changes in configuration.
105 
106   @param Value           A pointer to the data being sent to the original exporting driver.
107 
108 
109   @retval  TRUE          The callback successfully handled the action.
110   @retval  FALSE         The callback not supported in this handler.
111 
112 **/
113 EFI_STATUS
LanguageChangeHandler(IN EFI_IFR_TYPE_VALUE * Value)114 LanguageChangeHandler (
115   IN  EFI_IFR_TYPE_VALUE                     *Value
116   )
117 {
118   CHAR8                         *LangCode;
119   CHAR8                         *Lang;
120   UINTN                         Index;
121   EFI_STATUS                    Status;
122 
123   //
124   // Allocate working buffer for RFC 4646 language in supported LanguageString.
125   //
126   Lang = AllocatePool (AsciiStrSize (gLanguageString));
127   ASSERT (Lang != NULL);
128 
129   Index = 0;
130   LangCode = gLanguageString;
131   while (*LangCode != 0) {
132     GetNextLanguage (&LangCode, Lang);
133 
134     if (Index == Value->u8) {
135       gCurrentLanguageIndex = Value->u8;
136       break;
137     }
138 
139     Index++;
140   }
141 
142   if (Index == Value->u8) {
143     Status = gRT->SetVariable (
144                     L"PlatformLang",
145                     &gEfiGlobalVariableGuid,
146                     EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
147                     AsciiStrSize (Lang),
148                     Lang
149                     );
150     if (EFI_ERROR (Status)) {
151       FreePool (Lang);
152       return EFI_DEVICE_ERROR;
153     }
154   } else {
155     ASSERT (FALSE);
156   }
157   FreePool (Lang);
158 
159   return EFI_SUCCESS;
160 }
161 
162 /**
163   This function processes the results of changes in configuration.
164 
165 
166   @param HiiHandle       Points to the hii handle for this formset.
167   @param Action          Specifies the type of action taken by the browser.
168   @param QuestionId      A unique value which is sent to the original exporting driver
169                          so that it can identify the type of data to expect.
170   @param Type            The type of value for the question.
171   @param Value           A pointer to the data being sent to the original exporting driver.
172   @param ActionRequest   On return, points to the action requested by the callback function.
173   @param Status          Return the handle status.
174 
175   @retval  TRUE          The callback successfully handled the action.
176   @retval  FALSE         The callback not supported in this handler.
177 
178 **/
179 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)180 UiSupportLibCallbackHandler (
181   IN  EFI_HII_HANDLE                         HiiHandle,
182   IN  EFI_BROWSER_ACTION                     Action,
183   IN  EFI_QUESTION_ID                        QuestionId,
184   IN  UINT8                                  Type,
185   IN  EFI_IFR_TYPE_VALUE                     *Value,
186   OUT EFI_BROWSER_ACTION_REQUEST             *ActionRequest,
187   OUT EFI_STATUS                             *Status
188   )
189 {
190   if (QuestionId != FRONT_PAGE_KEY_CONTINUE &&
191       QuestionId != FRONT_PAGE_KEY_RESET &&
192       QuestionId != FRONT_PAGE_KEY_LANGUAGE) {
193     return FALSE;
194   }
195 
196   if (Action == EFI_BROWSER_ACTION_RETRIEVE) {
197     if (QuestionId == FRONT_PAGE_KEY_LANGUAGE) {
198       Value->u8 = gCurrentLanguageIndex;
199       *Status = EFI_SUCCESS;
200     } else {
201       *Status = EFI_UNSUPPORTED;
202     }
203     return TRUE;
204   }
205 
206   if (Action != EFI_BROWSER_ACTION_CHANGED) {
207     //
208     // Do nothing for other UEFI Action. Only do call back when data is changed.
209     //
210     *Status = EFI_UNSUPPORTED;
211     return TRUE;
212   }
213 
214   if (Action == EFI_BROWSER_ACTION_CHANGED) {
215     if ((Value == NULL) || (ActionRequest == NULL)) {
216       *Status = EFI_INVALID_PARAMETER;
217       return TRUE;
218     }
219 
220     *Status = EFI_SUCCESS;
221     switch (QuestionId) {
222     case FRONT_PAGE_KEY_CONTINUE:
223       //
224       // This is the continue - clear the screen and return an error to get out of FrontPage loop
225       //
226       *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;
227       break;
228 
229     case FRONT_PAGE_KEY_LANGUAGE:
230       *Status = LanguageChangeHandler(Value);
231       break;
232 
233     case FRONT_PAGE_KEY_RESET:
234       //
235       // Reset
236       //
237       gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL);
238       *Status = EFI_UNSUPPORTED;
239 
240     default:
241       break;
242     }
243   }
244 
245   return TRUE;
246 }
247 
248 /**
249   Create Select language menu in the front page with oneof opcode.
250 
251   @param[in]    HiiHandle           The hii handle for the Uiapp driver.
252   @param[in]    StartOpCodeHandle   The opcode handle to save the new opcode.
253 
254 **/
255 VOID
UiCreateLanguageMenu(IN EFI_HII_HANDLE HiiHandle,IN VOID * StartOpCodeHandle)256 UiCreateLanguageMenu (
257   IN EFI_HII_HANDLE              HiiHandle,
258   IN VOID                        *StartOpCodeHandle
259   )
260 {
261   CHAR8                       *LangCode;
262   CHAR8                       *Lang;
263   UINTN                       LangSize;
264   CHAR8                       *CurrentLang;
265   UINTN                       OptionCount;
266   CHAR16                      *StringBuffer;
267   VOID                        *OptionsOpCodeHandle;
268   UINTN                       StringSize;
269   EFI_STATUS                  Status;
270   EFI_HII_STRING_PROTOCOL     *HiiString;
271 
272   Lang         = NULL;
273   StringBuffer = NULL;
274 
275   //
276   // Init OpCode Handle and Allocate space for creation of UpdateData Buffer
277   //
278   OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();
279   ASSERT (OptionsOpCodeHandle != NULL);
280 
281   GetEfiGlobalVariable2 (L"PlatformLang", (VOID**)&CurrentLang, NULL);
282 
283   //
284   // Get Support language list from variable.
285   //
286   GetEfiGlobalVariable2 (L"PlatformLangCodes", (VOID**)&gLanguageString, NULL);
287   if (gLanguageString == NULL) {
288     gLanguageString = AllocateCopyPool (
289                                AsciiStrSize ((CHAR8 *) PcdGetPtr (PcdUefiVariableDefaultPlatformLangCodes)),
290                                (CHAR8 *) PcdGetPtr (PcdUefiVariableDefaultPlatformLangCodes)
291                                );
292     ASSERT (gLanguageString != NULL);
293   }
294 
295   if (gLanguageToken == NULL) {
296     //
297     // Count the language list number.
298     //
299     LangCode = gLanguageString;
300     Lang = AllocatePool (AsciiStrSize (gLanguageString));
301     ASSERT (Lang != NULL);
302 
303     OptionCount = 0;
304     while (*LangCode != 0) {
305       GetNextLanguage (&LangCode, Lang);
306       OptionCount ++;
307     }
308 
309     //
310     // Allocate extra 1 as the end tag.
311     //
312     gLanguageToken = AllocateZeroPool ((OptionCount + 1) * sizeof (EFI_STRING_ID));
313     ASSERT (gLanguageToken != NULL);
314 
315     Status = gBS->LocateProtocol (&gEfiHiiStringProtocolGuid, NULL, (VOID **) &HiiString);
316     ASSERT_EFI_ERROR (Status);
317 
318     LangCode     = gLanguageString;
319     OptionCount  = 0;
320     while (*LangCode != 0) {
321       GetNextLanguage (&LangCode, Lang);
322 
323       StringSize = 0;
324       Status = HiiString->GetString (HiiString, Lang, HiiHandle, PRINTABLE_LANGUAGE_NAME_STRING_ID, StringBuffer, &StringSize, NULL);
325       if (Status == EFI_BUFFER_TOO_SMALL) {
326         StringBuffer = AllocateZeroPool (StringSize);
327         ASSERT (StringBuffer != NULL);
328         Status = HiiString->GetString (HiiString, Lang, HiiHandle, PRINTABLE_LANGUAGE_NAME_STRING_ID, StringBuffer, &StringSize, NULL);
329         ASSERT_EFI_ERROR (Status);
330       }
331 
332       if (EFI_ERROR (Status)) {
333         LangSize = AsciiStrSize (Lang);
334         StringBuffer = AllocatePool (LangSize * sizeof (CHAR16));
335         ASSERT (StringBuffer != NULL);
336         AsciiStrToUnicodeStrS (Lang, StringBuffer, LangSize);
337       }
338 
339       ASSERT (StringBuffer != NULL);
340       gLanguageToken[OptionCount] = HiiSetString (HiiHandle, 0, StringBuffer, NULL);
341       FreePool (StringBuffer);
342 
343       OptionCount++;
344     }
345   }
346 
347   ASSERT (gLanguageToken != NULL);
348   LangCode = gLanguageString;
349   OptionCount = 0;
350   if (Lang == NULL) {
351     Lang = AllocatePool (AsciiStrSize (gLanguageString));
352     ASSERT (Lang != NULL);
353   }
354   while (*LangCode != 0) {
355     GetNextLanguage (&LangCode, Lang);
356 
357     if (CurrentLang != NULL && AsciiStrCmp (Lang, CurrentLang) == 0) {
358       HiiCreateOneOfOptionOpCode (
359         OptionsOpCodeHandle,
360         gLanguageToken[OptionCount],
361         EFI_IFR_OPTION_DEFAULT,
362         EFI_IFR_NUMERIC_SIZE_1,
363         (UINT8) OptionCount
364         );
365       gCurrentLanguageIndex = (UINT8) OptionCount;
366     } else {
367       HiiCreateOneOfOptionOpCode (
368         OptionsOpCodeHandle,
369         gLanguageToken[OptionCount],
370         0,
371         EFI_IFR_NUMERIC_SIZE_1,
372         (UINT8) OptionCount
373         );
374     }
375 
376     OptionCount++;
377   }
378 
379   if (CurrentLang != NULL) {
380     FreePool (CurrentLang);
381   }
382   FreePool (Lang);
383 
384   HiiCreateOneOfOpCode (
385     StartOpCodeHandle,
386     FRONT_PAGE_KEY_LANGUAGE,
387     0,
388     0,
389     STRING_TOKEN (STR_LANGUAGE_SELECT),
390     STRING_TOKEN (STR_LANGUAGE_SELECT_HELP),
391     EFI_IFR_FLAG_CALLBACK,
392     EFI_IFR_NUMERIC_SIZE_1,
393     OptionsOpCodeHandle,
394     NULL
395     );
396 }
397 
398 /**
399   Create continue menu in the front page.
400 
401   @param[in]    HiiHandle           The hii handle for the Uiapp driver.
402   @param[in]    StartOpCodeHandle   The opcode handle to save the new opcode.
403 
404 **/
405 VOID
UiCreateContinueMenu(IN EFI_HII_HANDLE HiiHandle,IN VOID * StartOpCodeHandle)406 UiCreateContinueMenu (
407   IN EFI_HII_HANDLE              HiiHandle,
408   IN VOID                        *StartOpCodeHandle
409   )
410 {
411   HiiCreateActionOpCode (
412     StartOpCodeHandle,
413     FRONT_PAGE_KEY_CONTINUE,
414     STRING_TOKEN (STR_CONTINUE_PROMPT),
415     STRING_TOKEN (STR_CONTINUE_PROMPT),
416     EFI_IFR_FLAG_CALLBACK,
417     0
418     );
419 }
420 
421 /**
422   Create empty line menu in the front page.
423 
424   @param    HiiHandle           The hii handle for the Uiapp driver.
425   @param    StartOpCodeHandle   The opcode handle to save the new opcode.
426 
427 **/
428 VOID
UiCreateEmptyLine(IN EFI_HII_HANDLE HiiHandle,IN VOID * StartOpCodeHandle)429 UiCreateEmptyLine (
430   IN EFI_HII_HANDLE              HiiHandle,
431   IN VOID                        *StartOpCodeHandle
432   )
433 {
434   HiiCreateSubTitleOpCode (StartOpCodeHandle, STRING_TOKEN (STR_NULL_STRING), 0, 0, 0);
435 }
436 
437 /**
438   Create Reset menu in the front page.
439 
440   @param[in]    HiiHandle           The hii handle for the Uiapp driver.
441   @param[in]    StartOpCodeHandle   The opcode handle to save the new opcode.
442 
443 **/
444 VOID
UiCreateResetMenu(IN EFI_HII_HANDLE HiiHandle,IN VOID * StartOpCodeHandle)445 UiCreateResetMenu (
446   IN EFI_HII_HANDLE              HiiHandle,
447   IN VOID                        *StartOpCodeHandle
448   )
449 {
450   HiiCreateActionOpCode (
451     StartOpCodeHandle,
452     FRONT_PAGE_KEY_RESET,
453     STRING_TOKEN (STR_RESET_STRING),
454     STRING_TOKEN (STR_RESET_STRING),
455     EFI_IFR_FLAG_CALLBACK,
456     0
457     );
458 }
459 
460 /**
461   Extract device path for given HII handle and class guid.
462 
463   @param Handle          The HII handle.
464 
465   @retval  NULL          Fail to get the device path string.
466   @return  PathString    Get the device path string.
467 
468 **/
469 CHAR16 *
ExtractDevicePathFromHiiHandle(IN EFI_HII_HANDLE Handle)470 ExtractDevicePathFromHiiHandle (
471   IN      EFI_HII_HANDLE      Handle
472   )
473 {
474   EFI_STATUS                       Status;
475   EFI_HANDLE                       DriverHandle;
476 
477   ASSERT (Handle != NULL);
478 
479   if (Handle == NULL) {
480     return NULL;
481   }
482 
483   Status = gHiiDatabase->GetPackageListHandle (gHiiDatabase, Handle, &DriverHandle);
484   if (EFI_ERROR (Status)) {
485     return NULL;
486   }
487 
488   return ConvertDevicePathToText(DevicePathFromHandle (DriverHandle), FALSE, FALSE);
489 }
490 
491 /**
492   Check whether this driver need to be shown in the front page.
493 
494   @param    HiiHandle           The hii handle for the driver.
495   @param    Guid                The special guid for the driver which is the target.
496   @param    PromptId            Return the prompt string id.
497   @param    HelpId              Return the help string id.
498   @param    FormsetGuid         Return the formset guid info.
499 
500   @retval   EFI_SUCCESS         Search the driver success
501 
502 **/
503 BOOLEAN
RequiredDriver(IN EFI_HII_HANDLE HiiHandle,IN EFI_GUID * Guid,OUT EFI_STRING_ID * PromptId,OUT EFI_STRING_ID * HelpId,OUT VOID * FormsetGuid)504 RequiredDriver (
505   IN  EFI_HII_HANDLE              HiiHandle,
506   IN  EFI_GUID                    *Guid,
507   OUT EFI_STRING_ID               *PromptId,
508   OUT EFI_STRING_ID               *HelpId,
509   OUT VOID                        *FormsetGuid
510   )
511 {
512   EFI_STATUS                  Status;
513   UINT8                       ClassGuidNum;
514   EFI_GUID                    *ClassGuid;
515   EFI_IFR_FORM_SET            *Buffer;
516   UINTN                       BufferSize;
517   UINT8                       *Ptr;
518   UINTN                       TempSize;
519   BOOLEAN                     RetVal;
520 
521   Status = HiiGetFormSetFromHiiHandle(HiiHandle, &Buffer,&BufferSize);
522   if (EFI_ERROR (Status)) {
523     return FALSE;
524   }
525 
526   RetVal = FALSE;
527   TempSize = 0;
528   Ptr = (UINT8 *) Buffer;
529   while(TempSize < BufferSize)  {
530     TempSize += ((EFI_IFR_OP_HEADER *) Ptr)->Length;
531 
532     if (((EFI_IFR_OP_HEADER *) Ptr)->Length <= OFFSET_OF (EFI_IFR_FORM_SET, Flags)){
533       Ptr += ((EFI_IFR_OP_HEADER *) Ptr)->Length;
534       continue;
535     }
536 
537     ClassGuidNum = (UINT8) (((EFI_IFR_FORM_SET *)Ptr)->Flags & 0x3);
538     ClassGuid = (EFI_GUID *) (VOID *)(Ptr + sizeof (EFI_IFR_FORM_SET));
539     while (ClassGuidNum-- > 0) {
540       if (!CompareGuid (Guid, ClassGuid)){
541         ClassGuid ++;
542         continue;
543       }
544 
545       *PromptId = ((EFI_IFR_FORM_SET *)Ptr)->FormSetTitle;
546       *HelpId = ((EFI_IFR_FORM_SET *)Ptr)->Help;
547       CopyMem (FormsetGuid, &((EFI_IFR_FORM_SET *) Ptr)->Guid, sizeof (EFI_GUID));
548       RetVal = TRUE;
549     }
550   }
551 
552   FreePool (Buffer);
553 
554   return RetVal;
555 }
556 
557 /**
558   Search the drivers in the system which need to show in the front page
559   and insert the menu to the front page.
560 
561   @param    HiiHandle           The hii handle for the Uiapp driver.
562   @param    ClassGuid           The class guid for the driver which is the target.
563   @param    SpecialHandlerFn    The pointer to the specail handler function, if any.
564   @param    StartOpCodeHandle   The opcode handle to save the new opcode.
565 
566   @retval   EFI_SUCCESS         Search the driver success
567 
568 **/
569 EFI_STATUS
UiListThirdPartyDrivers(IN EFI_HII_HANDLE HiiHandle,IN EFI_GUID * ClassGuid,IN DRIVER_SPECIAL_HANDLER SpecialHandlerFn,IN VOID * StartOpCodeHandle)570 UiListThirdPartyDrivers (
571   IN EFI_HII_HANDLE              HiiHandle,
572   IN EFI_GUID                    *ClassGuid,
573   IN DRIVER_SPECIAL_HANDLER      SpecialHandlerFn,
574   IN VOID                        *StartOpCodeHandle
575   )
576 {
577   UINTN                       Index;
578   EFI_STRING                  String;
579   EFI_STRING_ID               Token;
580   EFI_STRING_ID               TokenHelp;
581   EFI_HII_HANDLE              *HiiHandles;
582   CHAR16                      *DevicePathStr;
583   UINTN                       Count;
584   UINTN                       CurrentSize;
585   UI_HII_DRIVER_INSTANCE      *DriverListPtr;
586   EFI_STRING                  NewName;
587   BOOLEAN                     EmptyLineAfter;
588 
589   if (gHiiDriverList != NULL) {
590     FreePool (gHiiDriverList);
591   }
592 
593   HiiHandles = HiiGetHiiHandles (NULL);
594   ASSERT (HiiHandles != NULL);
595 
596   gHiiDriverList = AllocateZeroPool (UI_HII_DRIVER_LIST_SIZE * sizeof (UI_HII_DRIVER_INSTANCE));
597   ASSERT (gHiiDriverList != NULL);
598   DriverListPtr = gHiiDriverList;
599   CurrentSize = UI_HII_DRIVER_LIST_SIZE;
600 
601   for (Index = 0, Count = 0; HiiHandles[Index] != NULL; Index++) {
602     if (!RequiredDriver (HiiHandles[Index], ClassGuid, &Token, &TokenHelp, &gHiiDriverList[Count].FormSetGuid)) {
603       continue;
604     }
605 
606     String = HiiGetString (HiiHandles[Index], Token, NULL);
607     if (String == NULL) {
608       String = HiiGetString (gStringPackHandle, STRING_TOKEN (STR_MISSING_STRING), NULL);
609       ASSERT (String != NULL);
610     } else if (SpecialHandlerFn != NULL) {
611       //
612       // Check whether need to rename the driver name.
613       //
614       EmptyLineAfter = FALSE;
615       if (SpecialHandlerFn (String, &NewName, &EmptyLineAfter)) {
616         FreePool (String);
617         String = NewName;
618         DriverListPtr[Count].EmptyLineAfter = EmptyLineAfter;
619       }
620     }
621     DriverListPtr[Count].PromptId = HiiSetString (HiiHandle, 0, String, NULL);
622     FreePool (String);
623 
624     String = HiiGetString (HiiHandles[Index], TokenHelp, NULL);
625     if (String == NULL) {
626       String = HiiGetString (gStringPackHandle, STRING_TOKEN (STR_MISSING_STRING), NULL);
627       ASSERT (String != NULL);
628     }
629     DriverListPtr[Count].HelpId = HiiSetString (HiiHandle, 0, String, NULL);
630     FreePool (String);
631 
632     DevicePathStr = ExtractDevicePathFromHiiHandle(HiiHandles[Index]);
633     if (DevicePathStr != NULL){
634       DriverListPtr[Count].DevicePathId = HiiSetString (HiiHandle, 0, DevicePathStr, NULL);
635       FreePool (DevicePathStr);
636     } else {
637       DriverListPtr[Count].DevicePathId = 0;
638     }
639 
640     Count++;
641     if (Count >= CurrentSize) {
642       DriverListPtr = AllocateCopyPool ((Count + UI_HII_DRIVER_LIST_SIZE) * sizeof (UI_HII_DRIVER_INSTANCE), gHiiDriverList);
643       ASSERT (DriverListPtr != NULL);
644       FreePool (gHiiDriverList);
645       gHiiDriverList = DriverListPtr;
646       CurrentSize += UI_HII_DRIVER_LIST_SIZE;
647     }
648   }
649 
650   FreePool (HiiHandles);
651 
652   Index = 0;
653   while (gHiiDriverList[Index].PromptId != 0) {
654     HiiCreateGotoExOpCode (
655       StartOpCodeHandle,
656       0,
657       gHiiDriverList[Index].PromptId,
658       gHiiDriverList[Index].HelpId,
659       0,
660       (EFI_QUESTION_ID) (Index + FRONT_PAGE_KEY_DRIVER),
661       0,
662       &gHiiDriverList[Index].FormSetGuid,
663       gHiiDriverList[Index].DevicePathId
664     );
665 
666     if (gHiiDriverList[Index].EmptyLineAfter) {
667       UiCreateEmptyLine (HiiHandle, StartOpCodeHandle);
668     }
669 
670     Index ++;
671   }
672 
673   return EFI_SUCCESS;
674 }
675