2 Legacy Boot Maintainence UI implementation.
4 Copyright (c) 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.
16 #include "LegacyBootMaintUi.h"
18 LEGACY_BOOT_OPTION_CALLBACK_DATA
*mLegacyBootOptionPrivate
;
19 EFI_GUID mLegacyBootOptionGuid
= LEGACY_BOOT_OPTION_FORMSET_GUID
;
20 CHAR16 mLegacyBootStorageName
[] = L
"LegacyBootData";
21 BBS_TYPE mBbsType
[] = {BBS_FLOPPY
, BBS_HARDDISK
, BBS_CDROM
, BBS_EMBED_NETWORK
, BBS_BEV_DEVICE
, BBS_UNKNOWN
};
25 /// Legacy FD Info from LegacyBios.GetBbsInfo()
27 LEGACY_MENU_OPTION LegacyFDMenu
= {
28 LEGACY_MENU_OPTION_SIGNATURE
,
34 /// Legacy HD Info from LegacyBios.GetBbsInfo()
36 LEGACY_MENU_OPTION LegacyHDMenu
= {
37 LEGACY_MENU_OPTION_SIGNATURE
,
43 /// Legacy CD Info from LegacyBios.GetBbsInfo()
45 LEGACY_MENU_OPTION LegacyCDMenu
= {
46 LEGACY_MENU_OPTION_SIGNATURE
,
52 /// Legacy NET Info from LegacyBios.GetBbsInfo()
54 LEGACY_MENU_OPTION LegacyNETMenu
= {
55 LEGACY_MENU_OPTION_SIGNATURE
,
61 /// Legacy NET Info from LegacyBios.GetBbsInfo()
63 LEGACY_MENU_OPTION LegacyBEVMenu
= {
64 LEGACY_MENU_OPTION_SIGNATURE
,
70 VOID
*mLegacyStartOpCodeHandle
= NULL
;
71 VOID
*mLegacyEndOpCodeHandle
= NULL
;
72 EFI_IFR_GUID_LABEL
*mLegacyStartLabel
= NULL
;
73 EFI_IFR_GUID_LABEL
*mLegacyEndLabel
= NULL
;
76 HII_VENDOR_DEVICE_PATH mLegacyBootOptionHiiVendorDevicePath
= {
82 (UINT8
) (sizeof (VENDOR_DEVICE_PATH
)),
83 (UINT8
) ((sizeof (VENDOR_DEVICE_PATH
)) >> 8)
86 { 0x6bc75598, 0x89b4, 0x483d, { 0x91, 0x60, 0x7f, 0x46, 0x9a, 0x96, 0x35, 0x31 } }
90 END_ENTIRE_DEVICE_PATH_SUBTYPE
,
92 (UINT8
) (END_DEVICE_PATH_LENGTH
),
93 (UINT8
) ((END_DEVICE_PATH_LENGTH
) >> 8)
100 Re-order the Boot Option according to the DevOrder.
102 The routine re-orders the Boot Option in BootOption array according to
103 the order specified by DevOrder.
105 @param DevOrder Pointer to buffer containing the BBS Index,
106 high 8-bit value 0xFF indicating a disabled boot option
107 @param DevOrderCount Count of the BBS Index
108 @param EnBootOption Callee allocated buffer containing the enabled Boot Option Numbers
109 @param EnBootOptionCount Count of the enabled Boot Option Numbers
110 @param DisBootOption Callee allocated buffer containing the disabled Boot Option Numbers
111 @param DisBootOptionCount Count of the disabled Boot Option Numbers
114 OrderLegacyBootOption4SameType (
117 UINT16
**EnBootOption
,
118 UINTN
*EnBootOptionCount
,
119 UINT16
**DisBootOption
,
120 UINTN
*DisBootOptionCount
124 UINT16
*NewBootOption
;
130 EFI_BOOT_MANAGER_LOAD_OPTION BootOption
;
132 CHAR16 OptionName
[sizeof ("Boot####")];
133 UINT16
*BbsIndexArray
;
134 UINT16
*DeviceTypeArray
;
136 GetEfiGlobalVariable2 (L
"BootOrder", (VOID
**) &BootOrder
, &BootOrderSize
);
137 ASSERT (BootOrder
!= NULL
);
139 BbsIndexArray
= AllocatePool (BootOrderSize
);
140 DeviceTypeArray
= AllocatePool (BootOrderSize
);
141 *EnBootOption
= AllocatePool (BootOrderSize
);
142 *DisBootOption
= AllocatePool (BootOrderSize
);
143 *DisBootOptionCount
= 0;
144 *EnBootOptionCount
= 0;
147 ASSERT (*EnBootOption
!= NULL
);
148 ASSERT (*DisBootOption
!= NULL
);
150 for (Index
= 0; Index
< BootOrderSize
/ sizeof (UINT16
); Index
++) {
152 UnicodeSPrint (OptionName
, sizeof (OptionName
), L
"Boot%04x", BootOrder
[Index
]);
153 Status
= EfiBootManagerVariableToLoadOption (OptionName
, &BootOption
);
154 ASSERT_EFI_ERROR (Status
);
156 if ((DevicePathType (BootOption
.FilePath
) == BBS_DEVICE_PATH
) &&
157 (DevicePathSubType (BootOption
.FilePath
) == BBS_BBS_DP
)) {
159 // Legacy Boot Option
161 ASSERT (BootOption
.OptionalDataSize
== sizeof (LEGACY_BOOT_OPTION_BBS_DATA
));
163 DeviceTypeArray
[Index
] = ((BBS_BBS_DEVICE_PATH
*) BootOption
.FilePath
)->DeviceType
;
164 BbsIndexArray
[Index
] = ((LEGACY_BOOT_OPTION_BBS_DATA
*) BootOption
.OptionalData
)->BbsIndex
;
166 DeviceTypeArray
[Index
] = BBS_TYPE_UNKNOWN
;
167 BbsIndexArray
[Index
] = 0xFFFF;
169 EfiBootManagerFreeLoadOption (&BootOption
);
173 // Record the corresponding Boot Option Numbers according to the DevOrder
174 // Record the EnBootOption and DisBootOption according to the DevOrder
176 StartPosition
= BootOrderSize
/ sizeof (UINT16
);
177 NewBootOption
= AllocatePool (DevOrderCount
* sizeof (UINT16
));
178 while (DevOrderCount
-- != 0) {
179 for (Index
= 0; Index
< BootOrderSize
/ sizeof (UINT16
); Index
++) {
180 if (BbsIndexArray
[Index
] == (DevOrder
[DevOrderCount
] & 0xFF)) {
181 StartPosition
= MIN (StartPosition
, Index
);
182 NewBootOption
[DevOrderCount
] = BootOrder
[Index
];
184 if ((DevOrder
[DevOrderCount
] & 0xFF00) == 0xFF00) {
185 (*DisBootOption
)[*DisBootOptionCount
] = BootOrder
[Index
];
186 (*DisBootOptionCount
)++;
188 (*EnBootOption
)[*EnBootOptionCount
] = BootOrder
[Index
];
189 (*EnBootOptionCount
)++;
197 // Overwrite the old BootOption
199 CopyMem (&BootOrder
[StartPosition
], NewBootOption
, (*DisBootOptionCount
+ *EnBootOptionCount
) * sizeof (UINT16
));
200 Status
= gRT
->SetVariable (
202 &gEfiGlobalVariableGuid
,
207 ASSERT_EFI_ERROR (Status
);
209 FreePool (NewBootOption
);
210 FreePool (DeviceTypeArray
);
211 FreePool (BbsIndexArray
);
215 Update the legacy BBS boot option. L"LegacyDevOrder" and gEfiLegacyDevOrderVariableGuid EFI Variable
216 is udpated with the new Legacy Boot order. The EFI Variable of "Boot####" and gEfiGlobalVariableGuid
219 @param CallbackData The context data for BMM.
221 @return EFI_SUCCESS The function completed successfully.
222 @retval EFI_NOT_FOUND If L"LegacyDevOrder" and gEfiLegacyDevOrderVariableGuid EFI Variable can be found.
223 @retval EFI_OUT_OF_RESOURCES Fail to allocate memory resource
227 IN LEGACY_BOOT_NV_DATA
*NVMapData
238 LEGACY_MENU_OPTION
*OptionMenu
;
240 UINT16
*InitialLegacyDev
;
243 LEGACY_DEV_ORDER_ENTRY
*DevOrder
;
250 UINT16
*EnBootOption
;
251 UINTN EnBootOptionCount
;
252 UINT16
*DisBootOption
;
253 UINTN DisBootOptionCount
;
262 DisMap
= mLegacyBootOptionPrivate
->MaintainMapData
->DisableMap
;
263 Status
= EFI_SUCCESS
;
266 // Update the Variable "LegacyDevOrder"
268 GetVariable2 (VAR_LEGACY_DEV_ORDER
, &gEfiLegacyDevOrderVariableGuid
, (VOID
**) &VarData
, &VarSize
);
269 if (VarData
== NULL
) {
270 return EFI_NOT_FOUND
;
272 OriginalPtr
= VarData
;
274 while (mBbsType
[CurrentType
] != BBS_UNKNOWN
) {
275 switch (mBbsType
[CurrentType
]) {
277 OptionMenu
= (LEGACY_MENU_OPTION
*) &LegacyFDMenu
;
278 LegacyDev
= NVMapData
->LegacyFD
;
279 InitialLegacyDev
= mLegacyBootOptionPrivate
->MaintainMapData
->InitialNvData
.LegacyFD
;
280 BufferSize
= sizeof (NVMapData
->LegacyFD
);
284 OptionMenu
= (LEGACY_MENU_OPTION
*) &LegacyHDMenu
;
285 LegacyDev
= NVMapData
->LegacyHD
;
286 InitialLegacyDev
= mLegacyBootOptionPrivate
->MaintainMapData
->InitialNvData
.LegacyHD
;
288 BufferSize
= sizeof (NVMapData
->LegacyHD
);
292 OptionMenu
= (LEGACY_MENU_OPTION
*) &LegacyCDMenu
;
293 LegacyDev
= NVMapData
->LegacyCD
;
294 InitialLegacyDev
= mLegacyBootOptionPrivate
->MaintainMapData
->InitialNvData
.LegacyCD
;
295 BufferSize
= sizeof (NVMapData
->LegacyCD
);
298 case BBS_EMBED_NETWORK
:
299 OptionMenu
= (LEGACY_MENU_OPTION
*) &LegacyNETMenu
;
300 LegacyDev
= NVMapData
->LegacyNET
;
301 InitialLegacyDev
= mLegacyBootOptionPrivate
->MaintainMapData
->InitialNvData
.LegacyNET
;
302 BufferSize
= sizeof (NVMapData
->LegacyNET
);
306 ASSERT (mBbsType
[CurrentType
] == BBS_BEV_DEVICE
);
307 OptionMenu
= (LEGACY_MENU_OPTION
*) &LegacyBEVMenu
;
308 LegacyDev
= NVMapData
->LegacyBEV
;
309 InitialLegacyDev
= mLegacyBootOptionPrivate
->MaintainMapData
->InitialNvData
.LegacyBEV
;
310 BufferSize
= sizeof (NVMapData
->LegacyBEV
);
315 // Check whether has value changed.
317 if (CompareMem (LegacyDev
, InitialLegacyDev
, BufferSize
) == 0) {
322 DevOrder
= (LEGACY_DEV_ORDER_ENTRY
*) OriginalPtr
;
323 while (VarData
< OriginalPtr
+ VarSize
) {
324 if (DevOrder
->BbsType
== mBbsType
[CurrentType
]) {
328 VarData
+= sizeof (BBS_TYPE
) + DevOrder
->Length
;
329 DevOrder
= (LEGACY_DEV_ORDER_ENTRY
*) VarData
;
332 if (VarData
>= OriginalPtr
+ VarSize
) {
333 FreePool (OriginalPtr
);
334 return EFI_NOT_FOUND
;
337 NewOrder
= AllocateZeroPool (DevOrder
->Length
- sizeof (DevOrder
->Length
));
338 if (NewOrder
== NULL
) {
339 FreePool (OriginalPtr
);
340 return EFI_OUT_OF_RESOURCES
;
343 for (Index
= 0; Index
< OptionMenu
->MenuNumber
; Index
++) {
344 if (0xFF == LegacyDev
[Index
]) {
348 NewOrder
[Index
] = LegacyDev
[Index
];
352 // Only the enable/disable state of each boot device with same device type can be changed,
353 // so we can count on the index information in DevOrder.
354 // DisMap bit array is the only reliable source to check a device's en/dis state,
355 // so we use DisMap to set en/dis state of each item in NewOrder array
357 for (Index2
= 0; Index2
< OptionMenu
->MenuNumber
; Index2
++) {
358 Tmp
= (UINT16
) (DevOrder
->Data
[Index2
] & 0xFF);
361 if ((DisMap
[Pos
] & (1 << Bit
)) != 0) {
362 NewOrder
[Index
] = (UINT16
) (0xFF00 | Tmp
);
370 DevOrder
->Length
- sizeof (DevOrder
->Length
)
375 // Update BootOrder and Boot####.Attribute
377 // 1. Re-order the Option Number in BootOrder according to Legacy Dev Order
379 ASSERT (OptionMenu
->MenuNumber
== DevOrder
->Length
/ sizeof (UINT16
) - 1);
381 OrderLegacyBootOption4SameType (
383 DevOrder
->Length
/ sizeof (UINT16
) - 1,
391 // 2. Deactivate the DisBootOption and activate the EnBootOption
393 for (Index
= 0; Index
< DisBootOptionCount
; Index
++) {
394 UnicodeSPrint (VarName
, sizeof (VarName
), L
"Boot%04x", DisBootOption
[Index
]);
395 GetEfiGlobalVariable2 (VarName
, (VOID
**) &BootOptionVar
, &OptionSize
);
396 if (BootOptionVar
!= NULL
) {
397 Attribute
= (UINT32
*) BootOptionVar
;
398 *Attribute
&= ~LOAD_OPTION_ACTIVE
;
400 Status
= gRT
->SetVariable (
402 &gEfiGlobalVariableGuid
,
408 FreePool (BootOptionVar
);
412 for (Index
= 0; Index
< EnBootOptionCount
; Index
++) {
413 UnicodeSPrint (VarName
, sizeof (VarName
), L
"Boot%04x", EnBootOption
[Index
]);
414 GetEfiGlobalVariable2 (VarName
, (VOID
**) &BootOptionVar
, &OptionSize
);
415 if (BootOptionVar
!= NULL
) {
416 Attribute
= (UINT32
*) BootOptionVar
;
417 *Attribute
|= LOAD_OPTION_ACTIVE
;
419 Status
= gRT
->SetVariable (
421 &gEfiGlobalVariableGuid
,
427 FreePool (BootOptionVar
);
432 FreePool (EnBootOption
);
433 FreePool (DisBootOption
);
438 Status
= gRT
->SetVariable (
439 VAR_LEGACY_DEV_ORDER
,
440 &gEfiLegacyDevOrderVariableGuid
,
441 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_NON_VOLATILE
,
446 FreePool (OriginalPtr
);
451 This function allows a caller to extract the current configuration for one
452 or more named elements from the target driver.
455 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
456 @param Request A null-terminated Unicode string in <ConfigRequest> format.
457 @param Progress On return, points to a character in the Request string.
458 Points to the string's null terminator if request was successful.
459 Points to the most recent '&' before the first failing name/value
460 pair (or the beginning of the string if the failure is in the
461 first name/value pair) if the request was not successful.
462 @param Results A null-terminated Unicode string in <ConfigAltResp> format which
463 has all values filled in for the names in the Request string.
464 String to be allocated by the called function.
466 @retval EFI_SUCCESS The Results is filled with the requested values.
467 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the results.
468 @retval EFI_INVALID_PARAMETER Request is illegal syntax, or unknown name.
469 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this driver.
474 LegacyBootOptionExtractConfig (
475 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
476 IN CONST EFI_STRING Request
,
477 OUT EFI_STRING
*Progress
,
478 OUT EFI_STRING
*Results
481 if (Progress
== NULL
|| Results
== NULL
) {
482 return EFI_INVALID_PARAMETER
;
485 return EFI_NOT_FOUND
;
489 This function processes the results of changes in configuration.
492 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
493 @param Configuration A null-terminated Unicode string in <ConfigResp> format.
494 @param Progress A pointer to a string filled in with the offset of the most
495 recent '&' before the first failing name/value pair (or the
496 beginning of the string if the failure is in the first
497 name/value pair) or the terminating NULL if all was successful.
499 @retval EFI_SUCCESS The Results is processed successfully.
500 @retval EFI_INVALID_PARAMETER Configuration is NULL.
501 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this driver.
506 LegacyBootOptionRouteConfig (
507 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
508 IN CONST EFI_STRING Configuration
,
509 OUT EFI_STRING
*Progress
513 EFI_HII_CONFIG_ROUTING_PROTOCOL
*ConfigRouting
;
514 LEGACY_BOOT_NV_DATA
*CurrentNVMapData
;
518 if (Configuration
== NULL
|| Progress
== NULL
) {
519 return EFI_INVALID_PARAMETER
;
523 // Check routing data in <ConfigHdr>.
524 // Note: there is no name for Name/Value storage, only GUID will be checked
526 if (!HiiIsConfigHdrMatch (Configuration
, &mLegacyBootOptionGuid
, mLegacyBootStorageName
)) {
527 return EFI_NOT_FOUND
;
530 Status
= gBS
->LocateProtocol (
531 &gEfiHiiConfigRoutingProtocolGuid
,
533 (VOID
**) &ConfigRouting
535 if (EFI_ERROR (Status
)) {
540 // Convert <ConfigResp> to buffer data by helper function ConfigToBlock()
542 CurrentNVMapData
= &mLegacyBootOptionPrivate
->MaintainMapData
->CurrentNvData
;
543 Status
= ConfigRouting
->ConfigToBlock (
546 (UINT8
*) CurrentNVMapData
,
550 ASSERT_EFI_ERROR (Status
);
552 Status
= UpdateBBSOption (CurrentNVMapData
);
558 Refresh the global UpdateData structure.
562 RefreshLegacyUpdateData (
567 // Free current updated date
569 if (mLegacyStartOpCodeHandle
!= NULL
) {
570 HiiFreeOpCodeHandle (mLegacyStartOpCodeHandle
);
572 if (mLegacyEndOpCodeHandle
!= NULL
) {
573 HiiFreeOpCodeHandle (mLegacyEndOpCodeHandle
);
577 // Create new OpCode Handle
579 mLegacyStartOpCodeHandle
= HiiAllocateOpCodeHandle ();
580 mLegacyEndOpCodeHandle
= HiiAllocateOpCodeHandle ();
583 // Create Hii Extend Label OpCode as the start opcode
585 mLegacyStartLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (
586 mLegacyStartOpCodeHandle
,
589 sizeof (EFI_IFR_GUID_LABEL
)
591 mLegacyStartLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
593 mLegacyStartLabel
->Number
= FORM_BOOT_LEGACY_DEVICE_ID
;
596 // Create Hii Extend Label OpCode as the start opcode
598 mLegacyEndLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (
599 mLegacyEndOpCodeHandle
,
602 sizeof (EFI_IFR_GUID_LABEL
)
604 mLegacyEndLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
606 mLegacyEndLabel
->Number
= FORM_BOOT_LEGACY_LABEL_END
;
611 Get the Menu Entry from the list in Menu Entry List.
613 If MenuNumber is great or equal to the number of Menu
614 Entry in the list, then ASSERT.
616 @param MenuOption The Menu Entry List to read the menu entry.
617 @param MenuNumber The index of Menu Entry.
619 @return The Menu Entry.
624 LEGACY_MENU_OPTION
*MenuOption
,
628 LEGACY_MENU_ENTRY
*NewMenuEntry
;
632 ASSERT (MenuNumber
< MenuOption
->MenuNumber
);
634 List
= MenuOption
->Head
.ForwardLink
;
635 for (Index
= 0; Index
< MenuNumber
; Index
++) {
636 List
= List
->ForwardLink
;
639 NewMenuEntry
= CR (List
, LEGACY_MENU_ENTRY
, Link
, LEGACY_MENU_ENTRY_SIGNATURE
);
645 Create string tokens for a menu from its help strings and display strings
647 @param HiiHandle Hii Handle of the package to be updated.
648 @param MenuOption The Menu whose string tokens need to be created
650 @retval EFI_SUCCESS String tokens created successfully
651 @retval others contain some errors
654 CreateLegacyMenuStringToken (
655 IN EFI_HII_HANDLE HiiHandle
,
656 IN LEGACY_MENU_OPTION
*MenuOption
659 LEGACY_MENU_ENTRY
*NewMenuEntry
;
662 for (Index
= 0; Index
< MenuOption
->MenuNumber
; Index
++) {
663 NewMenuEntry
= GetMenuEntry (MenuOption
, Index
);
665 NewMenuEntry
->DisplayStringToken
= HiiSetString (
668 NewMenuEntry
->DisplayString
,
672 if (NULL
== NewMenuEntry
->HelpString
) {
673 NewMenuEntry
->HelpStringToken
= NewMenuEntry
->DisplayStringToken
;
675 NewMenuEntry
->HelpStringToken
= HiiSetString (
678 NewMenuEntry
->HelpString
,
686 Create a dynamic page so that Legacy Device boot order
687 can be set for specified device type.
689 @param UpdatePageId The form ID. It also spefies the legacy device type.
694 UpdateLegacyDeviceOrderPage (
695 IN UINT16 UpdatePageId
698 LEGACY_MENU_OPTION
*OptionMenu
;
699 LEGACY_MENU_ENTRY
*NewMenuEntry
;
700 EFI_STRING_ID StrRef
;
701 EFI_STRING_ID StrRefHelp
;
710 VOID
*OptionsOpCodeHandle
;
711 VOID
*DefaultOpCodeHandle
;
720 BbsType
= BBS_FLOPPY
;
722 RefreshLegacyUpdateData();
725 // Create oneof option list
727 switch (UpdatePageId
) {
728 case FORM_FLOPPY_BOOT_ID
:
729 OptionMenu
= (LEGACY_MENU_OPTION
*) &LegacyFDMenu
;
730 Key
= (UINT16
) LEGACY_FD_QUESTION_ID
;
731 TypeStr
= STR_FLOPPY
;
732 TypeStrHelp
= STR_FLOPPY_HELP
;
733 FormTitle
= STR_FLOPPY_TITLE
;
734 BbsType
= BBS_FLOPPY
;
735 Default
= mLegacyBootOptionPrivate
->MaintainMapData
->CurrentNvData
.LegacyFD
;
738 case FORM_HARDDISK_BOOT_ID
:
739 OptionMenu
= (LEGACY_MENU_OPTION
*) &LegacyHDMenu
;
740 Key
= (UINT16
) LEGACY_HD_QUESTION_ID
;
741 TypeStr
= STR_HARDDISK
;
742 TypeStrHelp
= STR_HARDDISK_HELP
;
743 FormTitle
= STR_HARDDISK_TITLE
;
744 BbsType
= BBS_HARDDISK
;
745 Default
= mLegacyBootOptionPrivate
->MaintainMapData
->CurrentNvData
.LegacyHD
;
748 case FORM_CDROM_BOOT_ID
:
749 OptionMenu
= (LEGACY_MENU_OPTION
*) &LegacyCDMenu
;
750 Key
= (UINT16
) LEGACY_CD_QUESTION_ID
;
752 TypeStrHelp
= STR_CDROM_HELP
;
753 FormTitle
= STR_CDROM_TITLE
;
755 Default
= mLegacyBootOptionPrivate
->MaintainMapData
->CurrentNvData
.LegacyCD
;
758 case FORM_NET_BOOT_ID
:
759 OptionMenu
= (LEGACY_MENU_OPTION
*) &LegacyNETMenu
;
760 Key
= (UINT16
) LEGACY_NET_QUESTION_ID
;
762 TypeStrHelp
= STR_NET_HELP
;
763 FormTitle
= STR_NET_TITLE
;
764 BbsType
= BBS_EMBED_NETWORK
;
765 Default
= mLegacyBootOptionPrivate
->MaintainMapData
->CurrentNvData
.LegacyNET
;
768 case FORM_BEV_BOOT_ID
:
769 OptionMenu
= (LEGACY_MENU_OPTION
*) &LegacyBEVMenu
;
770 Key
= (UINT16
) LEGACY_BEV_QUESTION_ID
;
772 TypeStrHelp
= STR_BEV_HELP
;
773 FormTitle
= STR_BEV_TITLE
;
774 BbsType
= BBS_BEV_DEVICE
;
775 Default
= mLegacyBootOptionPrivate
->MaintainMapData
->CurrentNvData
.LegacyBEV
;
779 DEBUG ((EFI_D_ERROR
, "Invalid command ID for updating page!\n"));
783 HiiSetString (mLegacyBootOptionPrivate
->HiiHandle
, STRING_TOKEN(STR_ORDER_CHANGE_PROMPT
), FormTitle
, NULL
);
785 CreateLegacyMenuStringToken (mLegacyBootOptionPrivate
->HiiHandle
, OptionMenu
);
787 OptionsOpCodeHandle
= HiiAllocateOpCodeHandle ();
788 ASSERT (OptionsOpCodeHandle
!= NULL
);
791 for (Index
= 0; Index
< OptionMenu
->MenuNumber
; Index
++) {
792 NewMenuEntry
= GetMenuEntry (OptionMenu
, Index
);
794 // Create OneOf for each legacy device
796 HiiCreateOneOfOptionOpCode (
798 NewMenuEntry
->DisplayStringToken
,
800 EFI_IFR_TYPE_NUM_SIZE_16
,
801 ((LEGACY_DEVICE_CONTEXT
*) NewMenuEntry
->VariableContext
)->BbsIndex
806 // Create OneOf for item "Disabled"
808 HiiCreateOneOfOptionOpCode (
810 STRING_TOKEN (STR_DISABLE_LEGACY_DEVICE
),
812 EFI_IFR_TYPE_NUM_SIZE_16
,
817 // Create oneof tag here for FD/HD/CD #1 #2
819 for (Index
= 0; Index
< OptionMenu
->MenuNumber
; Index
++) {
820 DefaultOpCodeHandle
= HiiAllocateOpCodeHandle ();
821 ASSERT (DefaultOpCodeHandle
!= NULL
);
823 HiiCreateDefaultOpCode (
825 EFI_HII_DEFAULT_CLASS_STANDARD
,
826 EFI_IFR_TYPE_NUM_SIZE_16
,
831 // Create the string for oneof tag
833 UnicodeSPrint (String
, sizeof (String
), TypeStr
, Index
);
834 StrRef
= HiiSetString (mLegacyBootOptionPrivate
->HiiHandle
, 0, String
, NULL
);
836 UnicodeSPrint (String
, sizeof (String
), TypeStrHelp
, Index
);
837 StrRefHelp
= HiiSetString (mLegacyBootOptionPrivate
->HiiHandle
, 0, String
, NULL
);
839 HiiCreateOneOfOpCode (
840 mLegacyStartOpCodeHandle
,
841 (EFI_QUESTION_ID
) (Key
+ Index
),
842 VARSTORE_ID_LEGACY_BOOT
,
843 (UINT16
) (Key
+ Index
* 2 - CONFIG_OPTION_OFFSET
),
846 EFI_IFR_FLAG_CALLBACK
,
847 EFI_IFR_NUMERIC_SIZE_2
,
849 DefaultOpCodeHandle
//NULL //
852 HiiFreeOpCodeHandle (DefaultOpCodeHandle
);
856 mLegacyBootOptionPrivate
->HiiHandle
,
857 &mLegacyBootOptionGuid
,
858 LEGACY_ORDER_CHANGE_FORM_ID
,
859 mLegacyStartOpCodeHandle
,
860 mLegacyEndOpCodeHandle
863 HiiFreeOpCodeHandle (OptionsOpCodeHandle
);
868 Adjust question value when one question value has been changed.
870 @param QuestionId The question id for the value changed question.
871 @param Value The value for the changed question.
876 IN UINT16 QuestionId
,
877 IN EFI_IFR_TYPE_VALUE
*Value
882 LEGACY_DEV_ORDER_ENTRY
*DevOrder
;
884 LEGACY_BOOT_NV_DATA
*CurrentNVMap
;
897 BbsType
= BBS_UNKNOWN
;
905 // Update Select FD/HD/CD/NET/BEV Order Form
907 ASSERT ((QuestionId
>= LEGACY_FD_QUESTION_ID
) && (QuestionId
< LEGACY_BEV_QUESTION_ID
+ MAX_MENU_NUMBER
));
909 CurrentNVMap
= &mLegacyBootOptionPrivate
->MaintainMapData
->CurrentNvData
;
910 HiiGetBrowserData (&mLegacyBootOptionGuid
, mLegacyBootStorageName
, sizeof (LEGACY_BOOT_NV_DATA
), (UINT8
*) CurrentNVMap
);
911 DisMap
= mLegacyBootOptionPrivate
->MaintainMapData
->DisableMap
;
913 if (QuestionId
>= LEGACY_FD_QUESTION_ID
&& QuestionId
< LEGACY_FD_QUESTION_ID
+ MAX_MENU_NUMBER
) {
914 Number
= (UINT16
) LegacyFDMenu
.MenuNumber
;
915 BbsType
= BBS_FLOPPY
;
916 CurrentVal
= CurrentNVMap
->LegacyFD
;
917 Default
= mLegacyBootOptionPrivate
->MaintainMapData
->LastTimeNvData
.LegacyFD
;
918 } else if (QuestionId
>= LEGACY_HD_QUESTION_ID
&& QuestionId
< LEGACY_HD_QUESTION_ID
+ MAX_MENU_NUMBER
) {
919 Number
= (UINT16
) LegacyHDMenu
.MenuNumber
;
920 BbsType
= BBS_HARDDISK
;
921 CurrentVal
= CurrentNVMap
->LegacyHD
;
922 Default
= mLegacyBootOptionPrivate
->MaintainMapData
->LastTimeNvData
.LegacyHD
;
923 } else if (QuestionId
>= LEGACY_CD_QUESTION_ID
&& QuestionId
< LEGACY_CD_QUESTION_ID
+ MAX_MENU_NUMBER
) {
924 Number
= (UINT16
) LegacyCDMenu
.MenuNumber
;
926 CurrentVal
= CurrentNVMap
->LegacyCD
;
927 Default
= mLegacyBootOptionPrivate
->MaintainMapData
->LastTimeNvData
.LegacyCD
;
928 } else if (QuestionId
>= LEGACY_NET_QUESTION_ID
&& QuestionId
< LEGACY_NET_QUESTION_ID
+ MAX_MENU_NUMBER
) {
929 Number
= (UINT16
) LegacyNETMenu
.MenuNumber
;
930 BbsType
= BBS_EMBED_NETWORK
;
931 CurrentVal
= CurrentNVMap
->LegacyNET
;
932 Default
= mLegacyBootOptionPrivate
->MaintainMapData
->LastTimeNvData
.LegacyNET
;
933 } else if (QuestionId
>= LEGACY_BEV_QUESTION_ID
&& QuestionId
< LEGACY_BEV_QUESTION_ID
+ MAX_MENU_NUMBER
) {
934 Number
= (UINT16
) LegacyBEVMenu
.MenuNumber
;
935 BbsType
= BBS_BEV_DEVICE
;
936 CurrentVal
= CurrentNVMap
->LegacyBEV
;
937 Default
= mLegacyBootOptionPrivate
->MaintainMapData
->LastTimeNvData
.LegacyBEV
;
941 // First, find the different position
942 // if there is change, it should be only one
944 for (Index
= 0; Index
< Number
; Index
++) {
945 if (CurrentVal
[Index
] != Default
[Index
]) {
946 OldValue
= Default
[Index
];
947 NewValue
= CurrentVal
[Index
];
952 if (Index
!= Number
) {
954 // there is change, now process
956 if (0xFF == NewValue
) {
958 // This item will be disable
959 // Just move the items behind this forward to overlap it
962 Bit
= 7 - (OldValue
% 8);
963 DisMap
[Pos
] = (UINT8
) (DisMap
[Pos
] | (UINT8
) (1 << Bit
));
964 for (Index2
= Index
; Index2
< Number
- 1; Index2
++) {
965 CurrentVal
[Index2
] = CurrentVal
[Index2
+ 1];
968 CurrentVal
[Index2
] = 0xFF;
970 for (Index2
= 0; Index2
< Number
; Index2
++) {
971 if (Index2
== Index
) {
975 if (Default
[Index2
] == NewValue
) {
977 // If NewValue is in OldLegacyDev array
978 // remember its old position
980 NewValuePos
= Index2
;
985 if (Index2
!= Number
) {
987 // We will change current item to an existing item
988 // (It's hard to describe here, please read code, it's like a cycle-moving)
990 for (Index2
= NewValuePos
; Index2
!= Index
;) {
991 if (NewValuePos
< Index
) {
992 CurrentVal
[Index2
] = Default
[Index2
+ 1];
995 CurrentVal
[Index2
] = Default
[Index2
- 1];
1001 // If NewValue is not in OldlegacyDev array, we are changing to a disabled item
1002 // so we should modify DisMap to reflect the change
1005 Bit
= 7 - (NewValue
% 8);
1006 DisMap
[Pos
] = (UINT8
) (DisMap
[Pos
] & (~ (UINT8
) (1 << Bit
)));
1007 if (0xFF != OldValue
) {
1009 // Because NewValue is a item that was disabled before
1010 // so after changing the OldValue should be disabled
1011 // actually we are doing a swap of enable-disable states of two items
1014 Bit
= 7 - (OldValue
% 8);
1015 DisMap
[Pos
] = (UINT8
) (DisMap
[Pos
] | (UINT8
) (1 << Bit
));
1020 // To prevent DISABLE appears in the middle of the list
1021 // we should perform a re-ordering
1025 while (Index
< Number
) {
1026 if (0xFF != CurrentVal
[Index
]) {
1033 while (Index2
< Number
) {
1034 if (0xFF != CurrentVal
[Index2
]) {
1041 if (Index2
< Number
) {
1042 CurrentVal
[Index
] = CurrentVal
[Index2
];
1043 CurrentVal
[Index2
] = 0xFF;
1050 // Return correct question value.
1052 Value
->u16
= CurrentVal
[Index3
];
1053 CopyMem (Default
, CurrentVal
, sizeof (UINT16
) * Number
);
1057 // Pass changed uncommitted data back to Form Browser
1059 HiiSetBrowserData (&mLegacyBootOptionGuid
, mLegacyBootStorageName
, sizeof (LEGACY_BOOT_NV_DATA
), (UINT8
*) CurrentNVMap
, NULL
);
1063 This call back function is registered with Boot Manager formset.
1064 When user selects a boot option, this call back function will
1065 be triggered. The boot option is saved for later processing.
1068 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
1069 @param Action Specifies the type of action taken by the browser.
1070 @param QuestionId A unique value which is sent to the original exporting driver
1071 so that it can identify the type of data to expect.
1072 @param Type The type of value for the question.
1073 @param Value A pointer to the data being sent to the original exporting driver.
1074 @param ActionRequest On return, points to the action requested by the callback function.
1076 @retval EFI_SUCCESS The callback successfully handled the action.
1077 @retval EFI_INVALID_PARAMETER The setup browser call this function with invalid parameters.
1082 LegacyBootOptionCallback (
1083 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
1084 IN EFI_BROWSER_ACTION Action
,
1085 IN EFI_QUESTION_ID QuestionId
,
1087 IN EFI_IFR_TYPE_VALUE
*Value
,
1088 OUT EFI_BROWSER_ACTION_REQUEST
*ActionRequest
1091 if (Action
!= EFI_BROWSER_ACTION_CHANGED
&& Action
!= EFI_BROWSER_ACTION_CHANGING
) {
1093 // Do nothing for other UEFI Action. Only do call back when data is changed.
1095 return EFI_UNSUPPORTED
;
1098 if ((Value
== NULL
) || (ActionRequest
== NULL
)) {
1099 return EFI_INVALID_PARAMETER
;
1102 if (Action
== EFI_BROWSER_ACTION_CHANGING
) {
1103 switch (QuestionId
) {
1104 case FORM_FLOPPY_BOOT_ID
:
1105 case FORM_HARDDISK_BOOT_ID
:
1106 case FORM_CDROM_BOOT_ID
:
1107 case FORM_NET_BOOT_ID
:
1108 case FORM_BEV_BOOT_ID
:
1109 UpdateLegacyDeviceOrderPage (QuestionId
);
1115 } else if (Action
== EFI_BROWSER_ACTION_CHANGED
) {
1116 if ((Value
== NULL
) || (ActionRequest
== NULL
)) {
1117 return EFI_INVALID_PARAMETER
;
1120 if ((QuestionId
>= LEGACY_FD_QUESTION_ID
) && (QuestionId
< LEGACY_BEV_QUESTION_ID
+ MAX_MENU_NUMBER
)) {
1121 AdjustOptionValue(QuestionId
, Value
);
1129 Create a menu entry by given menu type.
1131 @param MenuType The Menu type to be created.
1133 @retval NULL If failed to create the menu.
1134 @return the new menu entry.
1142 LEGACY_MENU_ENTRY
*MenuEntry
;
1145 // Create new menu entry
1147 MenuEntry
= AllocateZeroPool (sizeof (LEGACY_MENU_ENTRY
));
1148 if (MenuEntry
== NULL
) {
1152 MenuEntry
->VariableContext
= AllocateZeroPool (sizeof (LEGACY_DEVICE_CONTEXT
));
1153 if (MenuEntry
->VariableContext
== NULL
) {
1154 FreePool (MenuEntry
);
1158 MenuEntry
->Signature
= LEGACY_MENU_ENTRY_SIGNATURE
;
1164 Base on the L"LegacyDevOrder" variable to build the current order data.
1168 GetLegacyOptionsOrder (
1175 LEGACY_DEV_ORDER_ENTRY
*DevOrder
;
1178 LEGACY_MENU_OPTION
*OptionMenu
;
1187 DisMap
= ZeroMem (mLegacyBootOptionPrivate
->MaintainMapData
->DisableMap
, sizeof (mLegacyBootOptionPrivate
->MaintainMapData
->DisableMap
));
1190 // Get Device Order from variable
1192 GetVariable2 (VAR_LEGACY_DEV_ORDER
, &gEfiLegacyDevOrderVariableGuid
, (VOID
**) &VarData
, &VarSize
);
1194 if (NULL
!= VarData
) {
1195 DevOrder
= (LEGACY_DEV_ORDER_ENTRY
*) VarData
;
1196 while (VarData
< VarTmp
+ VarSize
) {
1197 switch (DevOrder
->BbsType
) {
1199 LegacyDev
= mLegacyBootOptionPrivate
->MaintainMapData
->InitialNvData
.LegacyFD
;
1200 OptionMenu
= &LegacyFDMenu
;
1204 LegacyDev
= mLegacyBootOptionPrivate
->MaintainMapData
->InitialNvData
.LegacyHD
;
1205 OptionMenu
= &LegacyHDMenu
;
1209 LegacyDev
= mLegacyBootOptionPrivate
->MaintainMapData
->InitialNvData
.LegacyCD
;
1210 OptionMenu
= &LegacyCDMenu
;
1213 case BBS_EMBED_NETWORK
:
1214 LegacyDev
= mLegacyBootOptionPrivate
->MaintainMapData
->InitialNvData
.LegacyNET
;
1215 OptionMenu
= &LegacyNETMenu
;
1218 case BBS_BEV_DEVICE
:
1219 LegacyDev
= mLegacyBootOptionPrivate
->MaintainMapData
->InitialNvData
.LegacyBEV
;
1220 OptionMenu
= &LegacyBEVMenu
;
1226 DEBUG ((DEBUG_ERROR
, "Unsupported device type found!\n"));
1231 // Create oneof tag here for FD/HD/CD #1 #2
1233 for (Index
= 0; Index
< OptionMenu
->MenuNumber
; Index
++) {
1234 VarDevOrder
= *(UINT16
*) ((UINT8
*) DevOrder
+ sizeof (BBS_TYPE
) + sizeof (UINT16
) + Index
* sizeof (UINT16
));
1236 if (0xFF00 == (VarDevOrder
& 0xFF00)) {
1237 LegacyDev
[Index
] = 0xFF;
1238 Pos
= (VarDevOrder
& 0xFF) / 8;
1239 Bit
= 7 - ((VarDevOrder
& 0xFF) % 8);
1240 DisMap
[Pos
] = (UINT8
) (DisMap
[Pos
] | (UINT8
) (1 << Bit
));
1242 LegacyDev
[Index
] = VarDevOrder
& 0xFF;
1246 VarData
+= sizeof (BBS_TYPE
);
1247 VarData
+= *(UINT16
*) VarData
;
1248 DevOrder
= (LEGACY_DEV_ORDER_ENTRY
*) VarData
;
1252 CopyMem (&mLegacyBootOptionPrivate
->MaintainMapData
->LastTimeNvData
, &mLegacyBootOptionPrivate
->MaintainMapData
->InitialNvData
, sizeof (LEGACY_BOOT_NV_DATA
));
1253 CopyMem (&mLegacyBootOptionPrivate
->MaintainMapData
->CurrentNvData
, &mLegacyBootOptionPrivate
->MaintainMapData
->InitialNvData
, sizeof (LEGACY_BOOT_NV_DATA
));
1258 Build the LegacyFDMenu LegacyHDMenu LegacyCDMenu according to LegacyBios.GetBbsInfo().
1266 LEGACY_MENU_ENTRY
*NewMenuEntry
;
1267 LEGACY_DEVICE_CONTEXT
*NewLegacyDevContext
;
1268 EFI_BOOT_MANAGER_LOAD_OPTION
*BootOption
;
1269 UINTN BootOptionCount
;
1278 // Initialize Bbs Table Context from BBS info data
1280 InitializeListHead (&LegacyFDMenu
.Head
);
1281 InitializeListHead (&LegacyHDMenu
.Head
);
1282 InitializeListHead (&LegacyCDMenu
.Head
);
1283 InitializeListHead (&LegacyNETMenu
.Head
);
1284 InitializeListHead (&LegacyBEVMenu
.Head
);
1292 EfiBootManagerConnectAll ();
1295 // for better user experience
1296 // 1. User changes HD configuration (e.g.: unplug HDD), here we have a chance to remove the HDD boot option
1297 // 2. User enables/disables UEFI PXE, here we have a chance to add/remove EFI Network boot option
1299 EfiBootManagerRefreshAllBootOption ();
1301 BootOption
= EfiBootManagerGetLoadOptions (&BootOptionCount
, LoadOptionTypeBoot
);
1302 for (Index
= 0; Index
< BootOptionCount
; Index
++) {
1303 if ((DevicePathType (BootOption
[Index
].FilePath
) != BBS_DEVICE_PATH
) ||
1304 (DevicePathSubType (BootOption
[Index
].FilePath
) != BBS_BBS_DP
)
1308 ASSERT (BootOption
[Index
].OptionalDataSize
== sizeof (LEGACY_BOOT_OPTION_BBS_DATA
));
1309 NewMenuEntry
= CreateMenuEntry ();
1310 ASSERT (NewMenuEntry
!= NULL
);
1312 NewLegacyDevContext
= (LEGACY_DEVICE_CONTEXT
*) NewMenuEntry
->VariableContext
;
1313 NewLegacyDevContext
->BbsIndex
= ((LEGACY_BOOT_OPTION_BBS_DATA
*) BootOption
[Index
].OptionalData
)->BbsIndex
;
1314 NewLegacyDevContext
->Description
= AllocateCopyPool (StrSize (BootOption
[Index
].Description
), BootOption
[Index
].Description
);
1315 ASSERT (NewLegacyDevContext
->Description
!= NULL
);
1317 NewMenuEntry
->DisplayString
= NewLegacyDevContext
->Description
;
1318 NewMenuEntry
->HelpString
= NULL
;
1320 switch (((BBS_BBS_DEVICE_PATH
*) BootOption
[Index
].FilePath
)->DeviceType
) {
1321 case BBS_TYPE_FLOPPY
:
1322 InsertTailList (&LegacyFDMenu
.Head
, &NewMenuEntry
->Link
);
1326 case BBS_TYPE_HARDDRIVE
:
1327 InsertTailList (&LegacyHDMenu
.Head
, &NewMenuEntry
->Link
);
1331 case BBS_TYPE_CDROM
:
1332 InsertTailList (&LegacyCDMenu
.Head
, &NewMenuEntry
->Link
);
1336 case BBS_TYPE_EMBEDDED_NETWORK
:
1337 InsertTailList (&LegacyNETMenu
.Head
, &NewMenuEntry
->Link
);
1342 InsertTailList (&LegacyBEVMenu
.Head
, &NewMenuEntry
->Link
);
1348 EfiBootManagerFreeLoadOptions (BootOption
, BootOptionCount
);
1350 LegacyFDMenu
.MenuNumber
= FDNum
;
1351 LegacyHDMenu
.MenuNumber
= HDNum
;
1352 LegacyCDMenu
.MenuNumber
= CDNum
;
1353 LegacyNETMenu
.MenuNumber
= NETNum
;
1354 LegacyBEVMenu
.MenuNumber
= BEVNum
;
1360 Install Boot Manager Menu driver.
1362 @param ImageHandle The image handle.
1363 @param SystemTable The system table.
1365 @retval EFI_SUCEESS Install Boot manager menu success.
1366 @retval Other Return error status.
1371 LegacyBootMaintUiLibConstructor (
1372 IN EFI_HANDLE ImageHandle
,
1373 IN EFI_SYSTEM_TABLE
*SystemTable
1377 EFI_LEGACY_BIOS_PROTOCOL
*LegacyBios
;
1378 LEGACY_BOOT_OPTION_CALLBACK_DATA
*LegacyBootOptionData
;
1380 Status
= gBS
->LocateProtocol (&gEfiLegacyBiosProtocolGuid
, NULL
, (VOID
**) &LegacyBios
);
1381 if (!EFI_ERROR (Status
)) {
1383 // Create LegacyBootOptionData structures for Driver Callback
1385 LegacyBootOptionData
= AllocateZeroPool (sizeof (LEGACY_BOOT_OPTION_CALLBACK_DATA
));
1386 ASSERT (LegacyBootOptionData
!= NULL
);
1388 LegacyBootOptionData
->MaintainMapData
= AllocateZeroPool (sizeof (LEGACY_BOOT_MAINTAIN_DATA
));
1389 ASSERT (LegacyBootOptionData
->MaintainMapData
!= NULL
);
1391 LegacyBootOptionData
->ConfigAccess
.ExtractConfig
= LegacyBootOptionExtractConfig
;
1392 LegacyBootOptionData
->ConfigAccess
.RouteConfig
= LegacyBootOptionRouteConfig
;
1393 LegacyBootOptionData
->ConfigAccess
.Callback
= LegacyBootOptionCallback
;
1396 // Install Device Path Protocol and Config Access protocol to driver handle
1398 Status
= gBS
->InstallMultipleProtocolInterfaces (
1399 &LegacyBootOptionData
->DriverHandle
,
1400 &gEfiDevicePathProtocolGuid
,
1401 &mLegacyBootOptionHiiVendorDevicePath
,
1402 &gEfiHiiConfigAccessProtocolGuid
,
1403 &LegacyBootOptionData
->ConfigAccess
,
1406 ASSERT_EFI_ERROR (Status
);
1409 // Publish our HII data
1411 LegacyBootOptionData
->HiiHandle
= HiiAddPackages (
1412 &mLegacyBootOptionGuid
,
1413 LegacyBootOptionData
->DriverHandle
,
1414 LegacyBootMaintUiVfrBin
,
1415 LegacyBootMaintUiLibStrings
,
1418 ASSERT (LegacyBootOptionData
->HiiHandle
!= NULL
);
1420 mLegacyBootOptionPrivate
= LegacyBootOptionData
;
1422 GetLegacyOptions ();
1424 GetLegacyOptionsOrder();
1431 Destructor of Customized Display Library Instance.
1433 @param ImageHandle The firmware allocated handle for the EFI image.
1434 @param SystemTable A pointer to the EFI System Table.
1436 @retval EFI_SUCCESS The destructor completed successfully.
1437 @retval Other value The destructor did not complete successfully.
1442 LegacyBootMaintUiLibDestructor (
1443 IN EFI_HANDLE ImageHandle
,
1444 IN EFI_SYSTEM_TABLE
*SystemTable
1449 if (mLegacyBootOptionPrivate
->DriverHandle
!= NULL
) {
1450 Status
= gBS
->UninstallMultipleProtocolInterfaces (
1451 mLegacyBootOptionPrivate
->DriverHandle
,
1452 &gEfiDevicePathProtocolGuid
,
1453 &mLegacyBootOptionHiiVendorDevicePath
,
1454 &gEfiHiiConfigAccessProtocolGuid
,
1455 &mLegacyBootOptionPrivate
->ConfigAccess
,
1458 ASSERT_EFI_ERROR (Status
);
1460 HiiRemovePackages (mLegacyBootOptionPrivate
->HiiHandle
);
1462 FreePool (mLegacyBootOptionPrivate
->MaintainMapData
);
1463 FreePool (mLegacyBootOptionPrivate
);