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 #include <EdkGenericBdsLibInternal.h>
25 #define MAX_STRING_LEN 200
26 static BOOLEAN mFeaturerSwitch
= TRUE
;
27 static BOOLEAN mResetRequired
= FALSE
;
38 Return the default value for system Timeout variable.
55 // Return Timeout variable or 0xffff if no valid
56 // Timeout variable exists.
58 Size
= sizeof (UINT16
);
59 Status
= gRT
->GetVariable (L
"Timeout", &gEfiGlobalVariableGuid
, NULL
, &Size
, &Timeout
);
60 if (!EFI_ERROR (Status
)) {
64 // To make the current EFI Automatic-Test activity possible, just add
65 // following code to make AutoBoot enabled when this variable is not
67 // This code should be removed later.
69 Timeout
= PcdGet16 (PcdUefiVariableDefaultTimeout
);
72 // Notes: Platform should set default variable if non exists on all error cases!!!
74 Status
= gRT
->SetVariable (
76 &gEfiGlobalVariableGuid
,
77 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
| EFI_VARIABLE_NON_VOLATILE
,
86 IN LIST_ENTRY
*BdsDriverLists
92 The function will go through the driver optoin link list, load and start
93 every driver the driver optoin device path point to.
97 BdsDriverLists - The header of the current driver option link list
107 BDS_COMMON_OPTION
*Option
;
108 EFI_HANDLE ImageHandle
;
109 EFI_LOADED_IMAGE_PROTOCOL
*ImageInfo
;
112 BOOLEAN ReconnectAll
;
114 ReconnectAll
= FALSE
;
117 // Process the driver option
119 for (Link
= BdsDriverLists
->ForwardLink
; Link
!= BdsDriverLists
; Link
= Link
->ForwardLink
) {
120 Option
= CR (Link
, BDS_COMMON_OPTION
, Link
, BDS_LOAD_OPTION_SIGNATURE
);
122 // If a load option is not marked as LOAD_OPTION_ACTIVE,
123 // the boot manager will not automatically load the option.
125 if (!IS_LOAD_OPTION_TYPE (Option
->Attribute
, LOAD_OPTION_ACTIVE
)) {
129 // If a driver load option is marked as LOAD_OPTION_FORCE_RECONNECT,
130 // then all of the EFI drivers in the system will be disconnected and
131 // reconnected after the last driver load option is processed.
133 if (IS_LOAD_OPTION_TYPE (Option
->Attribute
, LOAD_OPTION_FORCE_RECONNECT
)) {
137 // Make sure the driver path is connected.
139 BdsLibConnectDevicePath (Option
->DevicePath
);
142 // Load and start the image that Driver#### describes
144 Status
= gBS
->LoadImage (
153 if (!EFI_ERROR (Status
)) {
154 gBS
->HandleProtocol (ImageHandle
, &gEfiLoadedImageProtocolGuid
, &ImageInfo
);
157 // Verify whether this image is a driver, if not,
158 // exit it and continue to parse next load option
160 if (ImageInfo
->ImageCodeType
!= EfiBootServicesCode
&& ImageInfo
->ImageCodeType
!= EfiRuntimeServicesCode
) {
161 gBS
->Exit (ImageHandle
, EFI_INVALID_PARAMETER
, 0, NULL
);
165 if (Option
->LoadOptionsSize
!= 0) {
166 ImageInfo
->LoadOptionsSize
= Option
->LoadOptionsSize
;
167 ImageInfo
->LoadOptions
= Option
->LoadOptions
;
170 // Before calling the image, enable the Watchdog Timer for
171 // the 5 Minute period
173 gBS
->SetWatchdogTimer (5 * 60, 0x0000, 0x00, NULL
);
175 Status
= gBS
->StartImage (ImageHandle
, &ExitDataSize
, &ExitData
);
176 DEBUG ((EFI_D_INFO
| EFI_D_LOAD
, "Driver Return Status = %r\n", Status
));
179 // Clear the Watchdog Timer after the image returns
181 gBS
->SetWatchdogTimer (0x0000, 0x0000, 0x0000, NULL
);
185 // Process the LOAD_OPTION_FORCE_RECONNECT driver option
188 BdsLibDisconnectAllEfi ();
195 BdsLibRegisterNewOption (
196 IN LIST_ENTRY
*BdsOptionList
,
197 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath
,
199 IN CHAR16
*VariableName
205 This function will register the new boot#### or driver#### option base on
206 the VariableName. The new registered boot#### or driver#### will be linked
207 to BdsOptionList and also update to the VariableName. After the boot#### or
208 driver#### updated, the BootOrder or DriverOrder will also be updated.
212 BdsOptionList - The header of the boot#### or driver#### link list
214 DevicePath - The device path which the boot####
215 or driver#### option present
217 String - The description of the boot#### or driver####
219 VariableName - Indicate if the boot#### or driver#### option
223 EFI_SUCCESS - The boot#### or driver#### have been success registered
225 EFI_STATUS - Return the status of gRT->SetVariable ().
231 UINT16 MaxOptionNumber
;
232 UINT16 RegisterOptionNumber
;
233 UINT16
*TempOptionPtr
;
234 UINTN TempOptionSize
;
235 UINT16
*OptionOrderPtr
;
239 EFI_DEVICE_PATH_PROTOCOL
*OptionDevicePath
;
241 CHAR16 OptionName
[10];
242 BOOLEAN UpdateBootDevicePath
;
247 OptionDevicePath
= NULL
;
250 OptionOrderPtr
= NULL
;
251 UpdateBootDevicePath
= FALSE
;
252 ZeroMem (OptionName
, sizeof (OptionName
));
256 TempOptionPtr
= BdsLibGetVariableAndSize (
258 &gEfiGlobalVariableGuid
,
263 // Compare with current option variable
265 for (Index
= 0; Index
< TempOptionSize
/ sizeof (UINT16
); Index
++) {
267 // Got the max option#### number
269 if (MaxOptionNumber
< TempOptionPtr
[Index
]) {
270 MaxOptionNumber
= TempOptionPtr
[Index
];
273 if (*VariableName
== 'B') {
274 UnicodeSPrint (OptionName
, sizeof (OptionName
), L
"Boot%04x", TempOptionPtr
[Index
]);
276 UnicodeSPrint (OptionName
, sizeof (OptionName
), L
"Driver%04x", TempOptionPtr
[Index
]);
279 OptionPtr
= BdsLibGetVariableAndSize (
281 &gEfiGlobalVariableGuid
,
285 TempPtr
+= sizeof (UINT32
) + sizeof (UINT16
);
286 Description
= (CHAR16
*) TempPtr
;
287 TempPtr
+= StrSize ((CHAR16
*) TempPtr
);
288 OptionDevicePath
= (EFI_DEVICE_PATH_PROTOCOL
*) TempPtr
;
291 // Notes: the description may will change base on the GetStringToken
293 if (CompareMem (Description
, String
, StrSize (Description
)) == 0) {
294 if (CompareMem (OptionDevicePath
, DevicePath
, GetDevicePathSize (OptionDevicePath
)) == 0) {
296 // Got the option, so just return
298 FreePool (OptionPtr
);
299 FreePool (TempOptionPtr
);
303 // Boot device path changed, need update.
305 UpdateBootDevicePath
= TRUE
;
310 FreePool (OptionPtr
);
313 OptionSize
= sizeof (UINT32
) + sizeof (UINT16
) + StrSize (String
) + GetDevicePathSize (DevicePath
);
314 OptionPtr
= AllocateZeroPool (OptionSize
);
316 *(UINT32
*) TempPtr
= LOAD_OPTION_ACTIVE
;
317 TempPtr
+= sizeof (UINT32
);
318 *(UINT16
*) TempPtr
= (UINT16
) GetDevicePathSize (DevicePath
);
319 TempPtr
+= sizeof (UINT16
);
320 CopyMem (TempPtr
, String
, StrSize (String
));
321 TempPtr
+= StrSize (String
);
322 CopyMem (TempPtr
, DevicePath
, GetDevicePathSize (DevicePath
));
324 if (UpdateBootDevicePath
) {
326 // The number in option#### to be updated
328 RegisterOptionNumber
= TempOptionPtr
[Index
];
331 // The new option#### number
333 RegisterOptionNumber
= MaxOptionNumber
+ 1;
336 if (*VariableName
== 'B') {
337 UnicodeSPrint (OptionName
, sizeof (OptionName
), L
"Boot%04x", RegisterOptionNumber
);
339 UnicodeSPrint (OptionName
, sizeof (OptionName
), L
"Driver%04x", RegisterOptionNumber
);
342 Status
= gRT
->SetVariable (
344 &gEfiGlobalVariableGuid
,
345 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
| EFI_VARIABLE_NON_VOLATILE
,
349 if (EFI_ERROR (Status
) || UpdateBootDevicePath
) {
350 FreePool (OptionPtr
);
351 FreePool (TempOptionPtr
);
355 FreePool (OptionPtr
);
358 // Update the option order variable
360 OptionOrderPtr
= AllocateZeroPool ((Index
+ 1) * sizeof (UINT16
));
361 CopyMem (OptionOrderPtr
, TempOptionPtr
, Index
* sizeof (UINT16
));
362 OptionOrderPtr
[Index
] = RegisterOptionNumber
;
363 Status
= gRT
->SetVariable (
365 &gEfiGlobalVariableGuid
,
366 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
| EFI_VARIABLE_NON_VOLATILE
,
367 (Index
+ 1) * sizeof (UINT16
),
370 if (EFI_ERROR (Status
)) {
371 FreePool (TempOptionPtr
);
372 FreePool (OptionOrderPtr
);
376 if (TempOptionPtr
!= NULL
) {
377 FreePool (TempOptionPtr
);
379 FreePool (OptionOrderPtr
);
385 BdsLibVariableToOption (
386 IN OUT LIST_ENTRY
*BdsCommonOptionList
,
387 IN CHAR16
*VariableName
393 Build the boot#### or driver#### option from the VariableName, the
394 build boot#### or driver#### will also be linked to BdsCommonOptionList
398 BdsCommonOptionList - The header of the boot#### or driver#### option link list
400 VariableName - EFI Variable name indicate if it is boot#### or driver####
404 BDS_COMMON_OPTION - Get the option just been created
406 NULL - Failed to get the new option
415 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
416 BDS_COMMON_OPTION
*Option
;
418 UINT32 LoadOptionsSize
;
422 // Read the variable. We will never free this data.
424 Variable
= BdsLibGetVariableAndSize (
426 &gEfiGlobalVariableGuid
,
429 if (Variable
== NULL
) {
433 // Notes: careful defined the variable of Boot#### or
434 // Driver####, consider use some macro to abstract the code
437 // Get the option attribute
440 Attribute
= *(UINT32
*) Variable
;
441 TempPtr
+= sizeof (UINT32
);
444 // Get the option's device path size
446 FilePathSize
= *(UINT16
*) TempPtr
;
447 TempPtr
+= sizeof (UINT16
);
450 // Get the option's description string
452 Description
= (CHAR16
*) TempPtr
;
455 // Get the option's description string size
457 TempPtr
+= StrSize ((CHAR16
*) TempPtr
);
460 // Get the option's device path
462 DevicePath
= (EFI_DEVICE_PATH_PROTOCOL
*) TempPtr
;
463 TempPtr
+= FilePathSize
;
465 LoadOptions
= TempPtr
;
466 LoadOptionsSize
= (UINT32
) (VariableSize
- (UINTN
) (TempPtr
- Variable
));
469 // The Console variables may have multiple device paths, so make
470 // an Entry for each one.
472 Option
= AllocateZeroPool (sizeof (BDS_COMMON_OPTION
));
473 if (Option
== NULL
) {
477 Option
->Signature
= BDS_LOAD_OPTION_SIGNATURE
;
478 Option
->DevicePath
= AllocateZeroPool (GetDevicePathSize (DevicePath
));
479 CopyMem (Option
->DevicePath
, DevicePath
, GetDevicePathSize (DevicePath
));
480 Option
->Attribute
= Attribute
;
481 Option
->Description
= AllocateZeroPool (StrSize (Description
));
482 CopyMem (Option
->Description
, Description
, StrSize (Description
));
483 Option
->LoadOptions
= AllocateZeroPool (LoadOptionsSize
);
484 CopyMem (Option
->LoadOptions
, LoadOptions
, LoadOptionsSize
);
485 Option
->LoadOptionsSize
= LoadOptionsSize
;
488 // Insert active entry to BdsDeviceList
490 if ((Option
->Attribute
& LOAD_OPTION_ACTIVE
) == LOAD_OPTION_ACTIVE
) {
491 InsertTailList (BdsCommonOptionList
, &Option
->Link
);
503 BdsLibBuildOptionFromVar (
504 IN LIST_ENTRY
*BdsCommonOptionList
,
505 IN CHAR16
*VariableName
511 Process BootOrder, or DriverOrder variables, by calling
512 BdsLibVariableToOption () for each UINT16 in the variables.
516 BdsCommonOptionList - The header of the option list base on variable
519 VariableName - EFI Variable name indicate the BootOrder or DriverOrder
523 EFI_SUCCESS - Success create the boot option or driver option list
525 EFI_OUT_OF_RESOURCES - Failed to get the boot option or driver option list
530 UINTN OptionOrderSize
;
532 BDS_COMMON_OPTION
*Option
;
533 CHAR16 OptionName
[20];
536 // Zero Buffer in order to get all BOOT#### variables
538 ZeroMem (OptionName
, sizeof (OptionName
));
541 // Read the BootOrder, or DriverOrder variable.
543 OptionOrder
= BdsLibGetVariableAndSize (
545 &gEfiGlobalVariableGuid
,
548 if (OptionOrder
== NULL
) {
549 return EFI_OUT_OF_RESOURCES
;
552 for (Index
= 0; Index
< OptionOrderSize
/ sizeof (UINT16
); Index
++) {
553 if (*VariableName
== 'B') {
554 UnicodeSPrint (OptionName
, sizeof (OptionName
), L
"Boot%04x", OptionOrder
[Index
]);
556 UnicodeSPrint (OptionName
, sizeof (OptionName
), L
"Driver%04x", OptionOrder
[Index
]);
558 Option
= BdsLibVariableToOption (BdsCommonOptionList
, OptionName
);
559 Option
->BootCurrent
= OptionOrder
[Index
];
563 FreePool (OptionOrder
);
569 BdsLibGetVariableAndSize (
571 IN EFI_GUID
*VendorGuid
,
572 OUT UINTN
*VariableSize
578 Read the EFI variable (VendorGuid/Name) and return a dynamically allocated
579 buffer, and the size of the buffer. If failure return NULL.
583 Name - String part of EFI variable name
585 VendorGuid - GUID part of EFI variable name
587 VariableSize - Returns the size of the EFI variable that was read
591 Dynamically allocated memory that contains a copy of the EFI variable.
592 Caller is responsible freeing the buffer.
594 NULL - Variable was not read
605 // Pass in a zero size buffer to find the required buffer size.
608 Status
= gRT
->GetVariable (Name
, VendorGuid
, NULL
, &BufferSize
, Buffer
);
609 if (Status
== EFI_BUFFER_TOO_SMALL
) {
611 // Allocate the buffer to return
613 Buffer
= AllocateZeroPool (BufferSize
);
614 if (Buffer
== NULL
) {
618 // Read variable into the allocated buffer.
620 Status
= gRT
->GetVariable (Name
, VendorGuid
, NULL
, &BufferSize
, Buffer
);
621 if (EFI_ERROR (Status
)) {
626 *VariableSize
= BufferSize
;
642 Buffer - The allocated pool entry to free
646 Pointer of the buffer allocated.
650 if (Buffer
!= NULL
) {
656 EFI_DEVICE_PATH_PROTOCOL
*
657 BdsLibDelPartMatchInstance (
658 IN EFI_DEVICE_PATH_PROTOCOL
*Multi
,
659 IN EFI_DEVICE_PATH_PROTOCOL
*Single
665 Delete the instance in Multi which matches partly with Single instance
669 Multi - A pointer to a multi-instance device path data structure.
671 Single - A pointer to a single-instance device path data structure.
675 This function will remove the device path instances in Multi which partly
676 match with the Single, and return the result device path. If there is no
677 remaining device path as a result, this function will return NULL.
681 EFI_DEVICE_PATH_PROTOCOL
*Instance
;
682 EFI_DEVICE_PATH_PROTOCOL
*NewDevicePath
;
683 EFI_DEVICE_PATH_PROTOCOL
*TempNewDevicePath
;
688 NewDevicePath
= NULL
;
689 TempNewDevicePath
= NULL
;
691 if (Multi
== NULL
|| Single
== NULL
) {
695 Instance
= GetNextDevicePathInstance (&Multi
, &InstanceSize
);
696 SingleDpSize
= GetDevicePathSize (Single
) - END_DEVICE_PATH_LENGTH
;
697 InstanceSize
-= END_DEVICE_PATH_LENGTH
;
699 while (Instance
!= NULL
) {
701 Size
= (SingleDpSize
< InstanceSize
) ? SingleDpSize
: InstanceSize
;
703 if ((CompareMem (Instance
, Single
, Size
) != 0)) {
705 // Append the device path instance which does not match with Single
707 TempNewDevicePath
= NewDevicePath
;
708 NewDevicePath
= AppendDevicePathInstance (NewDevicePath
, Instance
);
709 BdsLibSafeFreePool(TempNewDevicePath
);
711 BdsLibSafeFreePool(Instance
);
712 Instance
= GetNextDevicePathInstance (&Multi
, &InstanceSize
);
713 InstanceSize
-= END_DEVICE_PATH_LENGTH
;
716 return NewDevicePath
;
720 BdsLibMatchDevicePaths (
721 IN EFI_DEVICE_PATH_PROTOCOL
*Multi
,
722 IN EFI_DEVICE_PATH_PROTOCOL
*Single
728 Function compares a device path data structure to that of all the nodes of a
729 second device path instance.
733 Multi - A pointer to a multi-instance device path data structure.
735 Single - A pointer to a single-instance device path data structure.
739 TRUE - If the Single is contained within Multi
741 FALSE - The Single is not match within Multi
746 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
747 EFI_DEVICE_PATH_PROTOCOL
*DevicePathInst
;
750 if (!Multi
|| !Single
) {
755 DevicePathInst
= GetNextDevicePathInstance (&DevicePath
, &Size
);
758 // Search for the match of 'Single' in 'Multi'
760 while (DevicePathInst
!= NULL
) {
762 // If the single device path is found in multiple device paths,
765 if (CompareMem (Single
, DevicePathInst
, Size
) == 0) {
766 FreePool (DevicePathInst
);
770 FreePool (DevicePathInst
);
771 DevicePathInst
= GetNextDevicePathInstance (&DevicePath
, &Size
);
778 BdsLibOutputStrings (
779 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*ConOut
,
786 This function prints a series of strings.
790 ConOut - Pointer to EFI_SIMPLE_TEXT_OUT_PROTOCOL
792 ... - A variable argument list containing series of strings,
793 the last string must be NULL.
797 EFI_SUCCESS - Success print out the string using ConOut.
799 EFI_STATUS - Return the status of the ConOut->OutputString ().
807 Status
= EFI_SUCCESS
;
808 VA_START (args
, ConOut
);
810 while (!EFI_ERROR (Status
)) {
812 // If String is NULL, then it's the end of the list
814 String
= VA_ARG (args
, CHAR16
*);
819 Status
= ConOut
->OutputString (ConOut
, String
);
821 if (EFI_ERROR (Status
)) {
830 // Following are BDS Lib functions which contain all the code about setup browser reset reminder feature.
831 // Setup Browser reset reminder feature is that an reset reminder will be given before user leaves the setup browser if
832 // user change any option setting which needs a reset to be effective, and the reset will be applied according to the user selection.
836 EnableResetReminderFeature (
843 Enable the setup browser reset reminder feature.
844 This routine is used in platform tip. If the platform policy need the feature, use the routine to enable it.
856 mFeaturerSwitch
= TRUE
;
860 DisableResetReminderFeature (
867 Disable the setup browser reset reminder feature.
868 This routine is used in platform tip. If the platform policy do not want the feature, use the routine to disable it.
880 mFeaturerSwitch
= FALSE
;
884 EnableResetRequired (
891 Record the info that a reset is required.
892 A module boolean variable is used to record whether a reset is required.
904 mResetRequired
= TRUE
;
908 DisableResetRequired (
915 Record the info that no reset is required.
916 A module boolean variable is used to record whether a reset is required.
928 mResetRequired
= FALSE
;
932 IsResetReminderFeatureEnable (
939 Check whether platform policy enable the reset reminder feature. The default is enabled.
951 return mFeaturerSwitch
;
962 Check if user changed any option setting which needs a system reset to be effective.
974 return mResetRequired
;
985 Check whether a reset is needed, and finish the reset reminder feature.
986 If a reset is needed, Popup a menu to notice user, and finish the feature
987 according to the user selection.
1000 EFI_FORM_BROWSER_PROTOCOL
*Browser
;
1002 CHAR16
*StringBuffer1
;
1003 CHAR16
*StringBuffer2
;
1007 //check any reset required change is applied? if yes, reset system
1009 if (IsResetReminderFeatureEnable ()) {
1010 if (IsResetRequired ()) {
1012 Status
= gBS
->LocateProtocol (
1013 &gEfiFormBrowserProtocolGuid
,
1018 ASSERT_EFI_ERROR (Status
);
1020 StringBuffer1
= AllocateZeroPool (MAX_STRING_LEN
* sizeof (CHAR16
));
1021 ASSERT (StringBuffer1
!= NULL
);
1022 StringBuffer2
= AllocateZeroPool (MAX_STRING_LEN
* sizeof (CHAR16
));
1023 ASSERT (StringBuffer2
!= NULL
);
1024 StrCpy (StringBuffer1
, L
"Configuration changed. Reset to apply it Now ? ");
1025 StrCpy (StringBuffer2
, L
"Enter (YES) / Esc (NO)");
1027 // Popup a menu to notice user
1030 Browser
->CreatePopUp (2, TRUE
, 0, NULL
, &Key
, StringBuffer1
, StringBuffer2
);
1031 } while ((Key
.ScanCode
!= SCAN_ESC
) && (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
));
1033 FreePool (StringBuffer1
);
1034 FreePool (StringBuffer2
);
1036 // If the user hits the YES Response key, reset
1038 if ((Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
)) {
1039 gRT
->ResetSystem (EfiResetCold
, EFI_SUCCESS
, 0, NULL
);
1041 gST
->ConOut
->ClearScreen (gST
->ConOut
);
1047 BdsLibGetHiiHandles (
1048 IN EFI_HII_PROTOCOL
*Hii
,
1049 IN OUT UINT16
*HandleBufferLength
,
1050 OUT EFI_HII_HANDLE
**HiiHandleBuffer
1054 Routine Description:
1056 Determines the handles that are currently active in the database.
1057 It's the caller's responsibility to free handle buffer.
1061 This - A pointer to the EFI_HII_PROTOCOL instance.
1062 HandleBufferLength - On input, a pointer to the length of the handle buffer. On output,
1063 the length of the handle buffer that is required for the handles found.
1064 HiiHandleBuffer - Pointer to an array of EFI_HII_PROTOCOL instances returned.
1068 EFI_SUCCESS - Get an array of EFI_HII_PROTOCOL instances successfully.
1069 EFI_INVALID_PARAMETER - Hii is NULL.
1070 EFI_NOT_FOUND - Database not found.
1074 UINT16 TempBufferLength
;
1077 TempBufferLength
= 0;
1080 // Try to find the actual buffer size for HiiHandle Buffer.
1082 Status
= Hii
->FindHandles (Hii
, &TempBufferLength
, *HiiHandleBuffer
);
1084 if (Status
== EFI_BUFFER_TOO_SMALL
) {
1085 *HiiHandleBuffer
= AllocateZeroPool (TempBufferLength
);
1086 Status
= Hii
->FindHandles (Hii
, &TempBufferLength
, *HiiHandleBuffer
);
1088 // we should not fail here.
1090 ASSERT_EFI_ERROR (Status
);
1093 *HandleBufferLength
= TempBufferLength
;