2 Load option library functions which relate with creating and processing load options.
4 Copyright (c) 2011 - 2015, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15 #include "InternalBm.h"
18 Get the Option Number that wasn't used.
20 @param OrderVariableName Could be L"BootOrder" or L"DriverOrder".
21 @param FreeOptionNumber To receive the minimal free option number.
23 @retval EFI_SUCCESS The option number is found
24 @retval EFI_OUT_OF_RESOURCES There is no free option number that can be used.
25 @retval EFI_INVALID_PARAMETER FreeOptionNumber is NULL
29 BmGetFreeOptionNumber (
30 IN CHAR16
*OrderVariableName
,
31 OUT UINT16
*FreeOptionNumber
38 UINTN OptionOrderSize
;
41 if (FreeOptionNumber
== NULL
) {
42 return EFI_INVALID_PARAMETER
;
45 GetEfiGlobalVariable2 (OrderVariableName
, (VOID
**) &OptionOrder
, &OptionOrderSize
);
47 if (*OrderVariableName
== L
'B') {
48 GetEfiGlobalVariable2 (L
"BootNext", (VOID
**) &BootNext
, NULL
);
51 for (OptionNumber
= 0;
52 OptionNumber
< OptionOrderSize
/ sizeof (UINT16
)
53 + ((BootNext
!= NULL
) ? 1 : 0);
57 // Search in OptionOrder whether the OptionNumber exists
59 for (Index
= 0; Index
< OptionOrderSize
/ sizeof (UINT16
); Index
++) {
60 if (OptionNumber
== OptionOrder
[Index
]) {
66 // We didn't find it in the ****Order array and it doesn't equal to BootNext
67 // Otherwise, OptionNumber equals to OptionOrderSize / sizeof (UINT16) + 1
69 if ((Index
== OptionOrderSize
/ sizeof (UINT16
)) &&
70 ((BootNext
== NULL
) || (OptionNumber
!= *BootNext
))
75 if (OptionOrder
!= NULL
) {
76 FreePool (OptionOrder
);
79 if (BootNext
!= NULL
) {
84 // When BootOrder & BootNext conver all numbers in the range [0 ... 0xffff],
85 // OptionNumber equals to 0x10000 which is not valid.
87 ASSERT (OptionNumber
<= 0x10000);
88 if (OptionNumber
== 0x10000) {
89 return EFI_OUT_OF_RESOURCES
;
91 *FreeOptionNumber
= (UINT16
) OptionNumber
;
97 Update order variable .
99 @param OptionOrderName Order variable name which need to be updated.
100 @param OptionNumber Option number for the new option.
101 @param Position Position of the new load option to put in the ****Order variable.
103 @retval EFI_SUCCESS The boot#### or driver#### have been successfully registered.
104 @retval EFI_ALREADY_STARTED The option number of Option is being used already.
105 @retval EFI_STATUS Return the status of gRT->SetVariable ().
109 BmAddOptionNumberToOrderVariable (
110 IN CHAR16
*OptionOrderName
,
111 IN UINT16 OptionNumber
,
118 UINT16
*NewOptionOrder
;
119 UINTN OptionOrderSize
;
121 // Update the option order variable
123 GetEfiGlobalVariable2 (OptionOrderName
, (VOID
**) &OptionOrder
, &OptionOrderSize
);
125 Status
= EFI_SUCCESS
;
126 for (Index
= 0; Index
< OptionOrderSize
/ sizeof (UINT16
); Index
++) {
127 if (OptionOrder
[Index
] == OptionNumber
) {
128 Status
= EFI_ALREADY_STARTED
;
133 if (!EFI_ERROR (Status
)) {
134 Position
= MIN (Position
, OptionOrderSize
/ sizeof (UINT16
));
136 NewOptionOrder
= AllocatePool (OptionOrderSize
+ sizeof (UINT16
));
137 ASSERT (NewOptionOrder
!= NULL
);
138 if (OptionOrderSize
!= 0) {
139 CopyMem (NewOptionOrder
, OptionOrder
, Position
* sizeof (UINT16
));
140 CopyMem (&NewOptionOrder
[Position
+ 1], &OptionOrder
[Position
], OptionOrderSize
- Position
* sizeof (UINT16
));
142 NewOptionOrder
[Position
] = OptionNumber
;
144 Status
= gRT
->SetVariable (
146 &gEfiGlobalVariableGuid
,
147 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
| EFI_VARIABLE_NON_VOLATILE
,
148 OptionOrderSize
+ sizeof (UINT16
),
151 FreePool (NewOptionOrder
);
154 if (OptionOrder
!= NULL
) {
155 FreePool (OptionOrder
);
162 Create the Boot#### or Driver#### variable from the load option.
164 @param LoadOption Pointer to the load option.
166 @retval EFI_SUCCESS The variable was created.
167 @retval Others Error status returned by RT->SetVariable.
171 EfiBootManagerLoadOptionToVariable (
172 IN CONST EFI_BOOT_MANAGER_LOAD_OPTION
*Option
178 CHAR16 OptionName
[sizeof ("Driver####")];
182 if ((Option
->OptionNumber
== LoadOptionNumberUnassigned
) ||
183 (Option
->FilePath
== NULL
) ||
184 (Option
->OptionType
>= LoadOptionTypeMax
)
186 return EFI_INVALID_PARAMETER
;
190 // Convert NULL description to empty description
193 Description
= Option
->Description
;
194 if (Description
== NULL
) {
195 Description
= &NullChar
;
200 UINT16 FilePathListLength;
201 CHAR16 Description[];
202 EFI_DEVICE_PATH_PROTOCOL FilePathList[];
203 UINT8 OptionalData[];
204 TODO: FilePathList[] IS:
205 A packed array of UEFI device paths. The first element of the
206 array is a device path that describes the device and location of the
207 Image for this load option. The FilePathList[0] is specific
208 to the device type. Other device paths may optionally exist in the
209 FilePathList, but their usage is OSV specific. Each element
210 in the array is variable length, and ends at the device path end
213 VariableSize
= sizeof (Option
->Attributes
)
215 + StrSize (Description
)
216 + GetDevicePathSize (Option
->FilePath
)
217 + Option
->OptionalDataSize
;
219 Variable
= AllocatePool (VariableSize
);
220 ASSERT (Variable
!= NULL
);
223 *(UINT32
*) Ptr
= Option
->Attributes
;
224 Ptr
+= sizeof (Option
->Attributes
);
225 *(UINT16
*) Ptr
= (UINT16
) GetDevicePathSize (Option
->FilePath
);
226 Ptr
+= sizeof (UINT16
);
227 CopyMem (Ptr
, Description
, StrSize (Description
));
228 Ptr
+= StrSize (Description
);
229 CopyMem (Ptr
, Option
->FilePath
, GetDevicePathSize (Option
->FilePath
));
230 Ptr
+= GetDevicePathSize (Option
->FilePath
);
231 CopyMem (Ptr
, Option
->OptionalData
, Option
->OptionalDataSize
);
236 (Option
->OptionType
== LoadOptionTypeBoot
) ? L
"Boot%04x" : L
"Driver%04x",
240 return gRT
->SetVariable (
242 &gEfiGlobalVariableGuid
,
243 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
| EFI_VARIABLE_NON_VOLATILE
,
250 This function will register the new boot#### or driver#### option.
251 After the boot#### or driver#### updated, the BootOrder or DriverOrder will also be updated.
253 @param Option Pointer to load option to add.
254 @param Position Position of the new load option to put in the ****Order variable.
256 @retval EFI_SUCCESS The boot#### or driver#### have been successfully registered.
257 @retval EFI_INVALID_PARAMETER The option number exceeds 0xFFFF.
258 @retval EFI_ALREADY_STARTED The option number of Option is being used already.
259 Note: this API only adds new load option, no replacement support.
260 @retval EFI_OUT_OF_RESOURCES There is no free option number that can be used when the
261 option number specified in the Option is LoadOptionNumberUnassigned.
262 @retval EFI_STATUS Return the status of gRT->SetVariable ().
267 EfiBootManagerAddLoadOptionVariable (
268 IN EFI_BOOT_MANAGER_LOAD_OPTION
*Option
,
275 if (Option
== NULL
) {
276 return EFI_INVALID_PARAMETER
;
280 // Get the free option number if the option number is unassigned
282 if (Option
->OptionNumber
== LoadOptionNumberUnassigned
) {
283 Status
= BmGetFreeOptionNumber (
284 Option
->OptionType
== LoadOptionTypeBoot
? L
"BootOrder" : L
"DriverOrder",
287 if (EFI_ERROR (Status
)) {
290 Option
->OptionNumber
= OptionNumber
;
293 if (Option
->OptionNumber
>= LoadOptionNumberMax
) {
294 return EFI_INVALID_PARAMETER
;
297 Status
= BmAddOptionNumberToOrderVariable (
298 Option
->OptionType
== LoadOptionTypeBoot
? L
"BootOrder" : L
"DriverOrder",
299 (UINT16
) Option
->OptionNumber
,
302 if (!EFI_ERROR (Status
)) {
304 // Save the Boot#### or Driver#### variable
306 Status
= EfiBootManagerLoadOptionToVariable (Option
);
307 if (EFI_ERROR (Status
)) {
309 // Remove the #### from *Order variable when the Boot####/Driver#### cannot be saved.
311 EfiBootManagerDeleteLoadOptionVariable (Option
->OptionNumber
, Option
->OptionType
);
319 Sort the load option. The DriverOrder or BootOrder will be re-created to
320 reflect the new order.
322 @param OptionType Load option type
323 @param CompareFunction The comparator
327 EfiBootManagerSortLoadOptionVariable (
328 EFI_BOOT_MANAGER_LOAD_OPTION_TYPE OptionType
,
329 SORT_COMPARE CompareFunction
333 EFI_BOOT_MANAGER_LOAD_OPTION
*LoadOption
;
334 UINTN LoadOptionCount
;
338 LoadOption
= EfiBootManagerGetLoadOptions (&LoadOptionCount
, OptionType
);
341 // Insertion sort algorithm
346 sizeof (EFI_BOOT_MANAGER_LOAD_OPTION
),
351 // Create new ****Order variable
353 OptionOrder
= AllocatePool (LoadOptionCount
* sizeof (UINT16
));
354 ASSERT (OptionOrder
!= NULL
);
355 for (Index
= 0; Index
< LoadOptionCount
; Index
++) {
356 OptionOrder
[Index
] = (UINT16
) LoadOption
[Index
].OptionNumber
;
359 Status
= gRT
->SetVariable (
360 OptionType
== LoadOptionTypeBoot
? L
"BootOrder" : L
"DriverOrder",
361 &gEfiGlobalVariableGuid
,
362 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
| EFI_VARIABLE_NON_VOLATILE
,
363 LoadOptionCount
* sizeof (UINT16
),
367 // Changing the *Order content without increasing its size with current variable implementation shouldn't fail.
369 ASSERT_EFI_ERROR (Status
);
371 FreePool (OptionOrder
);
372 EfiBootManagerFreeLoadOptions (LoadOption
, LoadOptionCount
);
376 Initialize a load option.
378 @param Option Pointer to the load option to be initialized.
379 @param OptionNumber Option number of the load option.
380 @param OptionType Type of the load option.
381 @param Attributes Attributes of the load option.
382 @param Description Description of the load option.
383 @param FilePath Device path of the load option.
384 @param OptionalData Optional data of the load option.
385 @param OptionalDataSize Size of the optional data of the load option.
387 @retval EFI_SUCCESS The load option was initialized successfully.
388 @retval EFI_INVALID_PARAMETER Option, Description or FilePath is NULL.
392 EfiBootManagerInitializeLoadOption (
393 IN OUT EFI_BOOT_MANAGER_LOAD_OPTION
*Option
,
394 IN UINTN OptionNumber
,
395 IN EFI_BOOT_MANAGER_LOAD_OPTION_TYPE OptionType
,
396 IN UINT32 Attributes
,
397 IN CHAR16
*Description
,
398 IN EFI_DEVICE_PATH_PROTOCOL
*FilePath
,
399 IN UINT8
*OptionalData
, OPTIONAL
400 IN UINT32 OptionalDataSize
403 if ((Option
== NULL
) || (Description
== NULL
) || (FilePath
== NULL
)) {
404 return EFI_INVALID_PARAMETER
;
407 if (((OptionalData
!= NULL
) && (OptionalDataSize
== 0)) ||
408 ((OptionalData
== NULL
) && (OptionalDataSize
!= 0))) {
409 return EFI_INVALID_PARAMETER
;
412 ZeroMem (Option
, sizeof (EFI_BOOT_MANAGER_LOAD_OPTION
));
413 Option
->OptionNumber
= OptionNumber
;
414 Option
->OptionType
= OptionType
;
415 Option
->Attributes
= Attributes
;
416 Option
->Description
= AllocateCopyPool (StrSize (Description
), Description
);
417 Option
->FilePath
= DuplicateDevicePath (FilePath
);
418 if (OptionalData
!= NULL
) {
419 Option
->OptionalData
= AllocateCopyPool (OptionalDataSize
, OptionalData
);
420 Option
->OptionalDataSize
= OptionalDataSize
;
428 Return the index of the load option in the load option array.
430 The function consider two load options are equal when the
431 OptionType, Attributes, Description, FilePath and OptionalData are equal.
433 @param Key Pointer to the load option to be found.
434 @param Array Pointer to the array of load options to be found.
435 @param Count Number of entries in the Array.
437 @retval -1 Key wasn't found in the Array.
438 @retval 0 ~ Count-1 The index of the Key in the Array.
442 IN CONST EFI_BOOT_MANAGER_LOAD_OPTION
*Key
,
443 IN CONST EFI_BOOT_MANAGER_LOAD_OPTION
*Array
,
449 for (Index
= 0; Index
< Count
; Index
++) {
450 if ((Key
->OptionType
== Array
[Index
].OptionType
) &&
451 (Key
->Attributes
== Array
[Index
].Attributes
) &&
452 (StrCmp (Key
->Description
, Array
[Index
].Description
) == 0) &&
453 (CompareMem (Key
->FilePath
, Array
[Index
].FilePath
, GetDevicePathSize (Key
->FilePath
)) == 0) &&
454 (Key
->OptionalDataSize
== Array
[Index
].OptionalDataSize
) &&
455 (CompareMem (Key
->OptionalData
, Array
[Index
].OptionalData
, Key
->OptionalDataSize
) == 0)) {
464 Update the BootOrder or DriverOrder to delete OptionNumber .
466 @param OptionOrderVariable Order variable name which need to be updated.
467 @param OptionNumber Indicate the option number of load option
469 @retval EFI_NOT_FOUND The load option cannot be found
470 @retval EFI_SUCCESS The load option was deleted
471 @retval others Status of RT->SetVariable()
474 BmDeleteOptionVariable (
475 IN CHAR16
*OptionOrderVariable
,
476 IN UINT16 OptionNumber
480 UINTN OptionOrderSize
;
484 Status
= EFI_NOT_FOUND
;
485 GetEfiGlobalVariable2 (OptionOrderVariable
, (VOID
**) &OptionOrder
, &OptionOrderSize
);
486 for (Index
= 0; Index
< OptionOrderSize
/ sizeof (UINT16
); Index
++) {
487 if (OptionOrder
[Index
] == OptionNumber
) {
488 OptionOrderSize
-= sizeof (UINT16
);
489 CopyMem (&OptionOrder
[Index
], &OptionOrder
[Index
+ 1], OptionOrderSize
- Index
* sizeof (UINT16
));
490 Status
= gRT
->SetVariable (
492 &gEfiGlobalVariableGuid
,
493 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
| EFI_VARIABLE_NON_VOLATILE
,
500 if (OptionOrder
!= NULL
) {
501 FreePool (OptionOrder
);
508 Update the BootOrder or DriverOrder according to the OptionType to delete OptionNumber .
510 @param OptionNumber Indicate the option number of load option
511 @param OptionType Indicate the type of load option
513 @retval EFI_INVALID_PARAMETER OptionType or OptionNumber is invalid.
514 @retval EFI_NOT_FOUND The load option cannot be found
515 @retval EFI_SUCCESS The load option was deleted
519 EfiBootManagerDeleteLoadOptionVariable (
520 IN UINTN OptionNumber
,
521 IN EFI_BOOT_MANAGER_LOAD_OPTION_TYPE OptionType
524 if ((OptionType
>= LoadOptionTypeMax
) || (OptionNumber
>= LoadOptionNumberMax
)) {
525 return EFI_INVALID_PARAMETER
;
528 return BmDeleteOptionVariable (
529 OptionType
== LoadOptionTypeBoot
? L
"BootOrder" : L
"DriverOrder",
530 (UINT16
) OptionNumber
535 Convert a single character to number.
536 It assumes the input Char is in the scope of L'0' ~ L'9' and L'A' ~ L'F'
538 @param Char The input char which need to convert to int.
545 if ((Char
>= L
'0') && (Char
<= L
'9')) {
546 return (UINTN
) (Char
- L
'0');
549 if ((Char
>= L
'A') && (Char
<= L
'F')) {
550 return (UINTN
) (Char
- L
'A' + 0xA);
558 Returns the size of a device path in bytes.
560 This function returns the size, in bytes, of the device path data structure
561 specified by DevicePath including the end of device path node. If DevicePath
562 is NULL, then 0 is returned. If the length of the device path is bigger than
563 MaxSize, also return 0 to indicate this is an invalidate device path.
565 @param DevicePath A pointer to a device path data structure.
566 @param MaxSize Max valid device path size. If big than this size,
569 @retval 0 An invalid device path.
570 @retval Others The size of a device path in bytes.
574 BmGetDevicePathSizeEx (
575 IN CONST EFI_DEVICE_PATH_PROTOCOL
*DevicePath
,
582 if (DevicePath
== NULL
) {
587 // Search for the end of the device path structure
590 while (!IsDevicePathEnd (DevicePath
)) {
591 NodeSize
= DevicePathNodeLength (DevicePath
);
596 if (Size
> MaxSize
) {
599 DevicePath
= NextDevicePathNode (DevicePath
);
601 Size
+= DevicePathNodeLength (DevicePath
);
602 if (Size
> MaxSize
) {
610 Returns the length of a Null-terminated Unicode string. If the length is
611 bigger than MaxStringLen, return length 0 to indicate that this is an
614 This function returns the number of Unicode characters in the Null-terminated
615 Unicode string specified by String.
617 If String is NULL, then ASSERT().
618 If String is not aligned on a 16-bit boundary, then ASSERT().
620 @param String A pointer to a Null-terminated Unicode string.
621 @param MaxStringLen Max string len in this string.
623 @retval 0 An invalid string.
624 @retval Others The length of String.
629 IN CONST CHAR16
*String
,
630 IN UINTN MaxStringLen
635 ASSERT (String
!= NULL
&& MaxStringLen
!= 0);
636 ASSERT (((UINTN
) String
& BIT0
) == 0);
638 for (Length
= 0; *String
!= L
'\0' && MaxStringLen
!= Length
; String
++, Length
+=2);
640 if (*String
!= L
'\0' && MaxStringLen
== Length
) {
648 Validate the EFI Boot#### variable (VendorGuid/Name)
650 @param Variable Boot#### variable data.
651 @param VariableSize Returns the size of the EFI variable that was read
653 @retval TRUE The variable data is correct.
654 @retval FALSE The variable data is corrupted.
665 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
668 if (VariableSize
<= sizeof (UINT16
) + sizeof (UINT32
)) {
673 // Skip the option attribute
676 TempPtr
+= sizeof (UINT32
);
679 // Get the option's device path size
681 FilePathSize
= *(UINT16
*) TempPtr
;
682 TempPtr
+= sizeof (UINT16
);
685 // Get the option's description string size
687 TempSize
= BmStrSizeEx ((CHAR16
*) TempPtr
, VariableSize
- sizeof (UINT16
) - sizeof (UINT32
));
691 // Get the option's device path
693 DevicePath
= (EFI_DEVICE_PATH_PROTOCOL
*) TempPtr
;
694 TempPtr
+= FilePathSize
;
697 // Validation boot option variable.
699 if ((FilePathSize
== 0) || (TempSize
== 0)) {
703 if (TempSize
+ FilePathSize
+ sizeof (UINT16
) + sizeof (UINT32
) > VariableSize
) {
707 return (BOOLEAN
) (BmGetDevicePathSizeEx (DevicePath
, FilePathSize
) != 0);
711 Build the Boot#### or Driver#### option from the VariableName.
713 @param VariableName EFI Variable name indicate if it is Boot#### or
715 @param Option Return the Boot#### or Driver#### option.
717 @retval EFI_SUCCESS Get the option just been created
718 @retval EFI_NOT_FOUND Failed to get the new option
723 EfiBootManagerVariableToLoadOption (
724 IN CHAR16
*VariableName
,
725 IN OUT EFI_BOOT_MANAGER_LOAD_OPTION
*Option
734 EFI_DEVICE_PATH_PROTOCOL
*FilePath
;
736 UINT32 OptionalDataSize
;
739 EFI_BOOT_MANAGER_LOAD_OPTION_TYPE OptionType
;
742 if ((VariableName
== NULL
) || (Option
== NULL
)) {
743 return EFI_INVALID_PARAMETER
;
749 GetEfiGlobalVariable2 (VariableName
, (VOID
**) &Variable
, &VariableSize
);
750 if (Variable
== NULL
) {
751 return EFI_NOT_FOUND
;
755 // Validate Boot#### variable data.
757 if (!BmValidateOption(Variable
, VariableSize
)) {
759 return EFI_INVALID_PARAMETER
;
763 // Notes: careful defined the variable of Boot#### or
764 // Driver####, consider use some macro to abstract the code
767 // Get the option attribute
770 Attribute
= *(UINT32
*) Variable
;
771 TempPtr
+= sizeof (UINT32
);
774 // Get the option's device path size
776 FilePathSize
= *(UINT16
*) TempPtr
;
777 TempPtr
+= sizeof (UINT16
);
780 // Get the option's description string
782 Description
= (CHAR16
*) TempPtr
;
785 // Get the option's description string size
787 TempPtr
+= StrSize ((CHAR16
*) TempPtr
);
790 // Get the option's device path
792 FilePath
= (EFI_DEVICE_PATH_PROTOCOL
*) TempPtr
;
793 TempPtr
+= FilePathSize
;
795 OptionalDataSize
= (UINT32
) (VariableSize
- (UINTN
) (TempPtr
- Variable
));
796 if (OptionalDataSize
== 0) {
799 OptionalData
= TempPtr
;
802 if (*VariableName
== L
'B') {
803 OptionType
= LoadOptionTypeBoot
;
804 NumOff
= (UINT8
) (sizeof (L
"Boot") / sizeof (CHAR16
) - 1);
806 OptionType
= LoadOptionTypeDriver
;
807 NumOff
= (UINT8
) (sizeof (L
"Driver") / sizeof (CHAR16
) - 1);
811 // Get the value from VariableName Unicode string
812 // since the ISO standard assumes ASCII equivalent abbreviations, we can be safe in converting this
813 // Unicode stream to ASCII without any loss in meaning.
815 OptionNumber
= (UINT16
) (BmCharToUint (VariableName
[NumOff
+0]) * 0x1000)
816 + (UINT16
) (BmCharToUint (VariableName
[NumOff
+1]) * 0x100)
817 + (UINT16
) (BmCharToUint (VariableName
[NumOff
+2]) * 0x10)
818 + (UINT16
) (BmCharToUint (VariableName
[NumOff
+3]) * 0x1);
820 Status
= EfiBootManagerInitializeLoadOption (
830 ASSERT_EFI_ERROR (Status
);
837 Returns an array of load options based on the EFI variable
838 L"BootOrder"/L"DriverOrder" and the L"Boot####"/L"Driver####" variables impled by it.
839 #### is the hex value of the UINT16 in each BootOrder/DriverOrder entry.
841 @param LoadOptionCount Returns number of entries in the array.
842 @param LoadOptionType The type of the load option.
844 @retval NULL No load options exist.
845 @retval !NULL Array of load option entries.
848 EFI_BOOT_MANAGER_LOAD_OPTION
*
850 EfiBootManagerGetLoadOptions (
851 OUT UINTN
*OptionCount
,
852 IN EFI_BOOT_MANAGER_LOAD_OPTION_TYPE LoadOptionType
857 UINTN OptionOrderSize
;
860 EFI_BOOT_MANAGER_LOAD_OPTION
*Option
;
861 CHAR16 OptionName
[sizeof ("Driver####")];
867 // Read the BootOrder, or DriverOrder variable.
869 GetEfiGlobalVariable2 (
870 (LoadOptionType
== LoadOptionTypeBoot
) ? L
"BootOrder" : L
"DriverOrder",
871 (VOID
**) &OptionOrder
,
874 if (OptionOrder
== NULL
) {
878 *OptionCount
= OptionOrderSize
/ sizeof (UINT16
);
880 Option
= AllocatePool (*OptionCount
* sizeof (EFI_BOOT_MANAGER_LOAD_OPTION
));
881 ASSERT (Option
!= NULL
);
884 for (Index
= 0; Index
< *OptionCount
; Index
++) {
885 OptionNumber
= OptionOrder
[Index
];
886 if (LoadOptionType
== LoadOptionTypeBoot
) {
887 UnicodeSPrint (OptionName
, sizeof (OptionName
), L
"Boot%04x", OptionNumber
);
889 UnicodeSPrint (OptionName
, sizeof (OptionName
), L
"Driver%04x", OptionNumber
);
892 Status
= EfiBootManagerVariableToLoadOption (OptionName
, &Option
[OptionIndex
]);
893 if (EFI_ERROR (Status
)) {
894 DEBUG ((EFI_D_INFO
, "[Bds] %s doesn't exist - Update ****Order variable to remove the reference!!", OptionName
));
895 EfiBootManagerDeleteLoadOptionVariable (OptionNumber
, LoadOptionTypeBoot
);
897 ASSERT (Option
[OptionIndex
].OptionNumber
== OptionNumber
);
902 if (OptionOrder
!= NULL
) {
903 FreePool (OptionOrder
);
906 if (OptionIndex
< *OptionCount
) {
907 Option
= ReallocatePool (
908 *OptionCount
* sizeof (EFI_BOOT_MANAGER_LOAD_OPTION
),
909 OptionIndex
* sizeof (EFI_BOOT_MANAGER_LOAD_OPTION
),
912 ASSERT (Option
!= NULL
);
913 *OptionCount
= OptionIndex
;
920 Free an EFI_BOOT_MANGER_LOAD_OPTION entry that was allocate by the library.
922 @param LoadOption Pointer to boot option to Free.
924 @return EFI_SUCCESS BootOption was freed
925 @return EFI_NOT_FOUND BootOption == NULL
930 EfiBootManagerFreeLoadOption (
931 IN EFI_BOOT_MANAGER_LOAD_OPTION
*LoadOption
934 if (LoadOption
== NULL
) {
935 return EFI_NOT_FOUND
;
938 if (LoadOption
->Description
!= NULL
) {
939 FreePool (LoadOption
->Description
);
941 if (LoadOption
->FilePath
!= NULL
) {
942 FreePool (LoadOption
->FilePath
);
944 if (LoadOption
->OptionalData
!= NULL
) {
945 FreePool (LoadOption
->OptionalData
);
952 Free an EFI_BOOT_MANGER_LOAD_OPTION array that was allocated by
953 EfiBootManagerGetLoadOptions().
955 @param Option Pointer to boot option array to free.
956 @param OptionCount Number of array entries in BootOption
958 @return EFI_SUCCESS BootOption was freed
959 @return EFI_NOT_FOUND BootOption == NULL
964 EfiBootManagerFreeLoadOptions (
965 IN EFI_BOOT_MANAGER_LOAD_OPTION
*Option
,
971 if (Option
== NULL
) {
972 return EFI_NOT_FOUND
;
975 for (Index
= 0;Index
< OptionCount
; Index
++) {
976 EfiBootManagerFreeLoadOption (&Option
[Index
]);