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