3 Copyright (c) 2006 - 2007, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 Misc BDS library function
22 #define MAX_STRING_LEN 200
23 static BOOLEAN mFeaturerSwitch
= TRUE
;
24 static BOOLEAN mResetRequired
= FALSE
;
25 extern UINT16 gPlatformBootTimeOutDefault
;
35 Return the default value for system Timeout variable.
52 // Return Timeout variable or 0xffff if no valid
53 // Timeout variable exists.
55 Size
= sizeof (UINT16
);
56 Status
= gRT
->GetVariable (L
"Timeout", &gEfiGlobalVariableGuid
, NULL
, &Size
, &Timeout
);
57 if (!EFI_ERROR (Status
)) {
61 // To make the current EFI Automatic-Test activity possible, just add
62 // following code to make AutoBoot enabled when this variable is not
64 // This code should be removed later.
66 Timeout
= gPlatformBootTimeOutDefault
;
69 // Notes: Platform should set default variable if non exists on all error cases!!!
71 Status
= gRT
->SetVariable (
73 &gEfiGlobalVariableGuid
,
74 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
| EFI_VARIABLE_NON_VOLATILE
,
83 IN LIST_ENTRY
*BdsDriverLists
89 The function will go through the driver optoin link list, load and start
90 every driver the driver optoin device path point to.
94 BdsDriverLists - The header of the current driver option link list
104 BDS_COMMON_OPTION
*Option
;
105 EFI_HANDLE ImageHandle
;
106 EFI_LOADED_IMAGE_PROTOCOL
*ImageInfo
;
109 BOOLEAN ReconnectAll
;
111 ReconnectAll
= FALSE
;
114 // Process the driver option
116 for (Link
= BdsDriverLists
->ForwardLink
; Link
!= BdsDriverLists
; Link
= Link
->ForwardLink
) {
117 Option
= CR (Link
, BDS_COMMON_OPTION
, Link
, BDS_LOAD_OPTION_SIGNATURE
);
119 // If a load option is not marked as LOAD_OPTION_ACTIVE,
120 // the boot manager will not automatically load the option.
122 if (!IS_LOAD_OPTION_TYPE (Option
->Attribute
, LOAD_OPTION_ACTIVE
)) {
126 // If a driver load option is marked as LOAD_OPTION_FORCE_RECONNECT,
127 // then all of the EFI drivers in the system will be disconnected and
128 // reconnected after the last driver load option is processed.
130 if (IS_LOAD_OPTION_TYPE (Option
->Attribute
, LOAD_OPTION_FORCE_RECONNECT
)) {
134 // Make sure the driver path is connected.
136 BdsLibConnectDevicePath (Option
->DevicePath
);
139 // Load and start the image that Driver#### describes
141 Status
= gBS
->LoadImage (
150 if (!EFI_ERROR (Status
)) {
151 gBS
->HandleProtocol (ImageHandle
, &gEfiLoadedImageProtocolGuid
, &ImageInfo
);
154 // Verify whether this image is a driver, if not,
155 // exit it and continue to parse next load option
157 if (ImageInfo
->ImageCodeType
!= EfiBootServicesCode
&& ImageInfo
->ImageCodeType
!= EfiRuntimeServicesCode
) {
158 gBS
->Exit (ImageHandle
, EFI_INVALID_PARAMETER
, 0, NULL
);
162 if (Option
->LoadOptionsSize
!= 0) {
163 ImageInfo
->LoadOptionsSize
= Option
->LoadOptionsSize
;
164 ImageInfo
->LoadOptions
= Option
->LoadOptions
;
167 // Before calling the image, enable the Watchdog Timer for
168 // the 5 Minute period
170 gBS
->SetWatchdogTimer (5 * 60, 0x0000, 0x00, NULL
);
172 Status
= gBS
->StartImage (ImageHandle
, &ExitDataSize
, &ExitData
);
173 DEBUG ((EFI_D_INFO
| EFI_D_LOAD
, "Driver Return Status = %r\n", Status
));
176 // Clear the Watchdog Timer after the image returns
178 gBS
->SetWatchdogTimer (0x0000, 0x0000, 0x0000, NULL
);
182 // Process the LOAD_OPTION_FORCE_RECONNECT driver option
185 BdsLibDisconnectAllEfi ();
192 BdsLibRegisterNewOption (
193 IN LIST_ENTRY
*BdsOptionList
,
194 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath
,
196 IN CHAR16
*VariableName
202 This function will register the new boot#### or driver#### option base on
203 the VariableName. The new registered boot#### or driver#### will be linked
204 to BdsOptionList and also update to the VariableName. After the boot#### or
205 driver#### updated, the BootOrder or DriverOrder will also be updated.
209 BdsOptionList - The header of the boot#### or driver#### link list
211 DevicePath - The device path which the boot####
212 or driver#### option present
214 String - The description of the boot#### or driver####
216 VariableName - Indicate if the boot#### or driver#### option
220 EFI_SUCCESS - The boot#### or driver#### have been success registered
222 EFI_STATUS - Return the status of gRT->SetVariable ().
228 UINT16 MaxOptionNumber
;
229 UINT16 RegisterOptionNumber
;
230 UINT16
*TempOptionPtr
;
231 UINTN TempOptionSize
;
232 UINT16
*OptionOrderPtr
;
236 EFI_DEVICE_PATH_PROTOCOL
*OptionDevicePath
;
238 CHAR16 OptionName
[10];
239 BOOLEAN UpdateBootDevicePath
;
244 OptionDevicePath
= NULL
;
247 OptionOrderPtr
= NULL
;
248 UpdateBootDevicePath
= FALSE
;
249 ZeroMem (OptionName
, sizeof (OptionName
));
253 TempOptionPtr
= BdsLibGetVariableAndSize (
255 &gEfiGlobalVariableGuid
,
260 // Compare with current option variable
262 for (Index
= 0; Index
< TempOptionSize
/ sizeof (UINT16
); Index
++) {
264 // Got the max option#### number
266 if (MaxOptionNumber
< TempOptionPtr
[Index
]) {
267 MaxOptionNumber
= TempOptionPtr
[Index
];
270 if (*VariableName
== 'B') {
271 UnicodeSPrint (OptionName
, sizeof (OptionName
), L
"Boot%04x", TempOptionPtr
[Index
]);
273 UnicodeSPrint (OptionName
, sizeof (OptionName
), L
"Driver%04x", TempOptionPtr
[Index
]);
276 OptionPtr
= BdsLibGetVariableAndSize (
278 &gEfiGlobalVariableGuid
,
282 TempPtr
+= sizeof (UINT32
) + sizeof (UINT16
);
283 Description
= (CHAR16
*) TempPtr
;
284 TempPtr
+= StrSize ((CHAR16
*) TempPtr
);
285 OptionDevicePath
= (EFI_DEVICE_PATH_PROTOCOL
*) TempPtr
;
288 // Notes: the description may will change base on the GetStringToken
290 if (CompareMem (Description
, String
, StrSize (Description
)) == 0) {
291 if (CompareMem (OptionDevicePath
, DevicePath
, GetDevicePathSize (OptionDevicePath
)) == 0) {
293 // Got the option, so just return
295 FreePool (OptionPtr
);
296 FreePool (TempOptionPtr
);
300 // Boot device path changed, need update.
302 UpdateBootDevicePath
= TRUE
;
307 FreePool (OptionPtr
);
310 OptionSize
= sizeof (UINT32
) + sizeof (UINT16
) + StrSize (String
) + GetDevicePathSize (DevicePath
);
311 OptionPtr
= AllocateZeroPool (OptionSize
);
313 *(UINT32
*) TempPtr
= LOAD_OPTION_ACTIVE
;
314 TempPtr
+= sizeof (UINT32
);
315 *(UINT16
*) TempPtr
= (UINT16
) GetDevicePathSize (DevicePath
);
316 TempPtr
+= sizeof (UINT16
);
317 CopyMem (TempPtr
, String
, StrSize (String
));
318 TempPtr
+= StrSize (String
);
319 CopyMem (TempPtr
, DevicePath
, GetDevicePathSize (DevicePath
));
321 if (UpdateBootDevicePath
) {
323 // The number in option#### to be updated
325 RegisterOptionNumber
= TempOptionPtr
[Index
];
328 // The new option#### number
330 RegisterOptionNumber
= MaxOptionNumber
+ 1;
333 if (*VariableName
== 'B') {
334 UnicodeSPrint (OptionName
, sizeof (OptionName
), L
"Boot%04x", RegisterOptionNumber
);
336 UnicodeSPrint (OptionName
, sizeof (OptionName
), L
"Driver%04x", RegisterOptionNumber
);
339 Status
= gRT
->SetVariable (
341 &gEfiGlobalVariableGuid
,
342 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
| EFI_VARIABLE_NON_VOLATILE
,
346 if (EFI_ERROR (Status
) || UpdateBootDevicePath
) {
347 FreePool (OptionPtr
);
348 FreePool (TempOptionPtr
);
352 FreePool (OptionPtr
);
355 // Update the option order variable
357 OptionOrderPtr
= AllocateZeroPool ((Index
+ 1) * sizeof (UINT16
));
358 CopyMem (OptionOrderPtr
, TempOptionPtr
, Index
* sizeof (UINT16
));
359 OptionOrderPtr
[Index
] = RegisterOptionNumber
;
360 Status
= gRT
->SetVariable (
362 &gEfiGlobalVariableGuid
,
363 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
| EFI_VARIABLE_NON_VOLATILE
,
364 (Index
+ 1) * sizeof (UINT16
),
367 if (EFI_ERROR (Status
)) {
368 FreePool (TempOptionPtr
);
369 FreePool (OptionOrderPtr
);
373 if (TempOptionPtr
!= NULL
) {
374 FreePool (TempOptionPtr
);
376 FreePool (OptionOrderPtr
);
382 BdsLibVariableToOption (
383 IN OUT LIST_ENTRY
*BdsCommonOptionList
,
384 IN CHAR16
*VariableName
390 Build the boot#### or driver#### option from the VariableName, the
391 build boot#### or driver#### will also be linked to BdsCommonOptionList
395 BdsCommonOptionList - The header of the boot#### or driver#### option link list
397 VariableName - EFI Variable name indicate if it is boot#### or driver####
401 BDS_COMMON_OPTION - Get the option just been created
403 NULL - Failed to get the new option
412 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
413 BDS_COMMON_OPTION
*Option
;
415 UINT32 LoadOptionsSize
;
419 // Read the variable. We will never free this data.
421 Variable
= BdsLibGetVariableAndSize (
423 &gEfiGlobalVariableGuid
,
426 if (Variable
== NULL
) {
430 // Notes: careful defined the variable of Boot#### or
431 // Driver####, consider use some macro to abstract the code
434 // Get the option attribute
437 Attribute
= *(UINT32
*) Variable
;
438 TempPtr
+= sizeof (UINT32
);
441 // Get the option's device path size
443 FilePathSize
= *(UINT16
*) TempPtr
;
444 TempPtr
+= sizeof (UINT16
);
447 // Get the option's description string
449 Description
= (CHAR16
*) TempPtr
;
452 // Get the option's description string size
454 TempPtr
+= StrSize ((CHAR16
*) TempPtr
);
457 // Get the option's device path
459 DevicePath
= (EFI_DEVICE_PATH_PROTOCOL
*) TempPtr
;
460 TempPtr
+= FilePathSize
;
462 LoadOptions
= TempPtr
;
463 LoadOptionsSize
= (UINT32
) (VariableSize
- (UINTN
) (TempPtr
- Variable
));
466 // The Console variables may have multiple device paths, so make
467 // an Entry for each one.
469 Option
= AllocateZeroPool (sizeof (BDS_COMMON_OPTION
));
470 if (Option
== NULL
) {
474 Option
->Signature
= BDS_LOAD_OPTION_SIGNATURE
;
475 Option
->DevicePath
= AllocateZeroPool (GetDevicePathSize (DevicePath
));
476 CopyMem (Option
->DevicePath
, DevicePath
, GetDevicePathSize (DevicePath
));
477 Option
->Attribute
= Attribute
;
478 Option
->Description
= AllocateZeroPool (StrSize (Description
));
479 CopyMem (Option
->Description
, Description
, StrSize (Description
));
480 Option
->LoadOptions
= AllocateZeroPool (LoadOptionsSize
);
481 CopyMem (Option
->LoadOptions
, LoadOptions
, LoadOptionsSize
);
482 Option
->LoadOptionsSize
= LoadOptionsSize
;
485 // Insert active entry to BdsDeviceList
487 if ((Option
->Attribute
& LOAD_OPTION_ACTIVE
) == LOAD_OPTION_ACTIVE
) {
488 InsertTailList (BdsCommonOptionList
, &Option
->Link
);
500 BdsLibBuildOptionFromVar (
501 IN LIST_ENTRY
*BdsCommonOptionList
,
502 IN CHAR16
*VariableName
508 Process BootOrder, or DriverOrder variables, by calling
509 BdsLibVariableToOption () for each UINT16 in the variables.
513 BdsCommonOptionList - The header of the option list base on variable
516 VariableName - EFI Variable name indicate the BootOrder or DriverOrder
520 EFI_SUCCESS - Success create the boot option or driver option list
522 EFI_OUT_OF_RESOURCES - Failed to get the boot option or driver option list
527 UINTN OptionOrderSize
;
529 BDS_COMMON_OPTION
*Option
;
530 CHAR16 OptionName
[20];
533 // Zero Buffer in order to get all BOOT#### variables
535 ZeroMem (OptionName
, sizeof (OptionName
));
538 // Read the BootOrder, or DriverOrder variable.
540 OptionOrder
= BdsLibGetVariableAndSize (
542 &gEfiGlobalVariableGuid
,
545 if (OptionOrder
== NULL
) {
546 return EFI_OUT_OF_RESOURCES
;
549 for (Index
= 0; Index
< OptionOrderSize
/ sizeof (UINT16
); Index
++) {
550 if (*VariableName
== 'B') {
551 UnicodeSPrint (OptionName
, sizeof (OptionName
), L
"Boot%04x", OptionOrder
[Index
]);
553 UnicodeSPrint (OptionName
, sizeof (OptionName
), L
"Driver%04x", OptionOrder
[Index
]);
555 Option
= BdsLibVariableToOption (BdsCommonOptionList
, OptionName
);
556 Option
->BootCurrent
= OptionOrder
[Index
];
560 FreePool (OptionOrder
);
566 BdsLibGetVariableAndSize (
568 IN EFI_GUID
*VendorGuid
,
569 OUT UINTN
*VariableSize
575 Read the EFI variable (VendorGuid/Name) and return a dynamically allocated
576 buffer, and the size of the buffer. If failure return NULL.
580 Name - String part of EFI variable name
582 VendorGuid - GUID part of EFI variable name
584 VariableSize - Returns the size of the EFI variable that was read
588 Dynamically allocated memory that contains a copy of the EFI variable.
589 Caller is responsible freeing the buffer.
591 NULL - Variable was not read
602 // Pass in a zero size buffer to find the required buffer size.
605 Status
= gRT
->GetVariable (Name
, VendorGuid
, NULL
, &BufferSize
, Buffer
);
606 if (Status
== EFI_BUFFER_TOO_SMALL
) {
608 // Allocate the buffer to return
610 Buffer
= AllocateZeroPool (BufferSize
);
611 if (Buffer
== NULL
) {
615 // Read variable into the allocated buffer.
617 Status
= gRT
->GetVariable (Name
, VendorGuid
, NULL
, &BufferSize
, Buffer
);
618 if (EFI_ERROR (Status
)) {
623 *VariableSize
= BufferSize
;
639 Buffer - The allocated pool entry to free
643 Pointer of the buffer allocated.
647 if (Buffer
!= NULL
) {
653 EFI_DEVICE_PATH_PROTOCOL
*
654 BdsLibDelPartMatchInstance (
655 IN EFI_DEVICE_PATH_PROTOCOL
*Multi
,
656 IN EFI_DEVICE_PATH_PROTOCOL
*Single
662 Delete the instance in Multi which matches partly with Single instance
666 Multi - A pointer to a multi-instance device path data structure.
668 Single - A pointer to a single-instance device path data structure.
672 This function will remove the device path instances in Multi which partly
673 match with the Single, and return the result device path. If there is no
674 remaining device path as a result, this function will return NULL.
678 EFI_DEVICE_PATH_PROTOCOL
*Instance
;
679 EFI_DEVICE_PATH_PROTOCOL
*NewDevicePath
;
680 EFI_DEVICE_PATH_PROTOCOL
*TempNewDevicePath
;
685 NewDevicePath
= NULL
;
686 TempNewDevicePath
= NULL
;
688 if (Multi
== NULL
|| Single
== NULL
) {
692 Instance
= GetNextDevicePathInstance (&Multi
, &InstanceSize
);
693 SingleDpSize
= GetDevicePathSize (Single
) - END_DEVICE_PATH_LENGTH
;
694 InstanceSize
-= END_DEVICE_PATH_LENGTH
;
696 while (Instance
!= NULL
) {
698 Size
= (SingleDpSize
< InstanceSize
) ? SingleDpSize
: InstanceSize
;
700 if ((CompareMem (Instance
, Single
, Size
) != 0)) {
702 // Append the device path instance which does not match with Single
704 TempNewDevicePath
= NewDevicePath
;
705 NewDevicePath
= AppendDevicePathInstance (NewDevicePath
, Instance
);
706 BdsLibSafeFreePool(TempNewDevicePath
);
708 BdsLibSafeFreePool(Instance
);
709 Instance
= GetNextDevicePathInstance (&Multi
, &InstanceSize
);
710 InstanceSize
-= END_DEVICE_PATH_LENGTH
;
713 return NewDevicePath
;
717 BdsLibMatchDevicePaths (
718 IN EFI_DEVICE_PATH_PROTOCOL
*Multi
,
719 IN EFI_DEVICE_PATH_PROTOCOL
*Single
725 Function compares a device path data structure to that of all the nodes of a
726 second device path instance.
730 Multi - A pointer to a multi-instance device path data structure.
732 Single - A pointer to a single-instance device path data structure.
736 TRUE - If the Single is contained within Multi
738 FALSE - The Single is not match within Multi
743 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
744 EFI_DEVICE_PATH_PROTOCOL
*DevicePathInst
;
747 if (!Multi
|| !Single
) {
752 DevicePathInst
= GetNextDevicePathInstance (&DevicePath
, &Size
);
755 // Search for the match of 'Single' in 'Multi'
757 while (DevicePathInst
!= NULL
) {
759 // If the single device path is found in multiple device paths,
762 if (CompareMem (Single
, DevicePathInst
, Size
) == 0) {
763 FreePool (DevicePathInst
);
767 FreePool (DevicePathInst
);
768 DevicePathInst
= GetNextDevicePathInstance (&DevicePath
, &Size
);
775 BdsLibOutputStrings (
776 IN EFI_SIMPLE_TEXT_OUT_PROTOCOL
*ConOut
,
783 This function prints a series of strings.
787 ConOut - Pointer to EFI_SIMPLE_TEXT_OUT_PROTOCOL
789 ... - A variable argument list containing series of strings,
790 the last string must be NULL.
794 EFI_SUCCESS - Success print out the string using ConOut.
796 EFI_STATUS - Return the status of the ConOut->OutputString ().
804 Status
= EFI_SUCCESS
;
805 VA_START (args
, ConOut
);
807 while (!EFI_ERROR (Status
)) {
809 // If String is NULL, then it's the end of the list
811 String
= VA_ARG (args
, CHAR16
*);
816 Status
= ConOut
->OutputString (ConOut
, String
);
818 if (EFI_ERROR (Status
)) {
827 // Following are BDS Lib functions which contain all the code about setup browser reset reminder feature.
828 // Setup Browser reset reminder feature is that an reset reminder will be given before user leaves the setup browser if
829 // user change any option setting which needs a reset to be effective, and the reset will be applied according to the user selection.
833 EnableResetReminderFeature (
840 Enable the setup browser reset reminder feature.
841 This routine is used in platform tip. If the platform policy need the feature, use the routine to enable it.
853 mFeaturerSwitch
= TRUE
;
857 DisableResetReminderFeature (
864 Disable the setup browser reset reminder feature.
865 This routine is used in platform tip. If the platform policy do not want the feature, use the routine to disable it.
877 mFeaturerSwitch
= FALSE
;
881 EnableResetRequired (
888 Record the info that a reset is required.
889 A module boolean variable is used to record whether a reset is required.
901 mResetRequired
= TRUE
;
905 DisableResetRequired (
912 Record the info that no reset is required.
913 A module boolean variable is used to record whether a reset is required.
925 mResetRequired
= FALSE
;
929 IsResetReminderFeatureEnable (
936 Check whether platform policy enable the reset reminder feature. The default is enabled.
948 return mFeaturerSwitch
;
959 Check if user changed any option setting which needs a system reset to be effective.
971 return mResetRequired
;
982 Check whether a reset is needed, and finish the reset reminder feature.
983 If a reset is needed, Popup a menu to notice user, and finish the feature
984 according to the user selection.
997 EFI_FORM_BROWSER_PROTOCOL
*Browser
;
999 CHAR16
*StringBuffer1
;
1000 CHAR16
*StringBuffer2
;
1004 //check any reset required change is applied? if yes, reset system
1006 if (IsResetReminderFeatureEnable ()) {
1007 if (IsResetRequired ()) {
1009 Status
= gBS
->LocateProtocol (
1010 &gEfiFormBrowserProtocolGuid
,
1015 StringBuffer1
= AllocateZeroPool (MAX_STRING_LEN
* sizeof (CHAR16
));
1016 ASSERT (StringBuffer1
!= NULL
);
1017 StringBuffer2
= AllocateZeroPool (MAX_STRING_LEN
* sizeof (CHAR16
));
1018 ASSERT (StringBuffer2
!= NULL
);
1019 StrCpy (StringBuffer1
, L
"Configuration changed. Reset to apply it Now ? ");
1020 StrCpy (StringBuffer2
, L
"Enter (YES) / Esc (NO)");
1022 // Popup a menu to notice user
1025 Browser
->CreatePopUp (2, TRUE
, 0, NULL
, &Key
, StringBuffer1
, StringBuffer2
);
1026 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1028 FreePool (StringBuffer1
);
1029 FreePool (StringBuffer2
);
1031 // If the user hits the YES Response key, reset
1033 if ((Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
)) {
1034 gRT
->ResetSystem (EfiResetCold
, EFI_SUCCESS
, 0, NULL
);
1036 gST
->ConOut
->ClearScreen (gST
->ConOut
);
1042 BdsLibGetHiiHandles (
1043 IN EFI_HII_PROTOCOL
*Hii
,
1044 IN OUT UINT16
*HandleBufferLength
,
1045 OUT EFI_HII_HANDLE
**HiiHandleBuffer
1049 Routine Description:
1051 Determines the handles that are currently active in the database.
1052 It's the caller's responsibility to free handle buffer.
1056 This - A pointer to the EFI_HII_PROTOCOL instance.
1057 HandleBufferLength - On input, a pointer to the length of the handle buffer. On output,
1058 the length of the handle buffer that is required for the handles found.
1059 HiiHandleBuffer - Pointer to an array of EFI_HII_PROTOCOL instances returned.
1063 EFI_SUCCESS - Get an array of EFI_HII_PROTOCOL instances successfully.
1064 EFI_INVALID_PARAMETER - Hii is NULL.
1065 EFI_NOT_FOUND - Database not found.
1069 UINT16 TempBufferLength
;
1072 TempBufferLength
= 0;
1075 // Try to find the actual buffer size for HiiHandle Buffer.
1077 Status
= Hii
->FindHandles (Hii
, &TempBufferLength
, *HiiHandleBuffer
);
1079 if (Status
== EFI_BUFFER_TOO_SMALL
) {
1080 *HiiHandleBuffer
= AllocateZeroPool (TempBufferLength
);
1081 Status
= Hii
->FindHandles (Hii
, &TempBufferLength
, *HiiHandleBuffer
);
1083 // we should not fail here.
1085 ASSERT_EFI_ERROR (Status
);
1088 *HandleBufferLength
= TempBufferLength
;