2 Provide boot option support for Application "BootMaint"
4 Include file system navigation, system handle selection
6 Boot option manipulation
8 Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
9 SPDX-License-Identifier: BSD-2-Clause-Patent
13 #include "BootMaint.h"
14 #include "BBSsupport.h"
17 Create a menu entry by given menu type.
19 @param MenuType The Menu type to be created.
21 @retval NULL If failed to create the menu.
22 @return the new menu entry.
26 BOpt_CreateMenuEntry (
30 BM_MENU_ENTRY
*MenuEntry
;
34 // Get context size according to menu type
37 case BM_LOAD_CONTEXT_SELECT
:
38 ContextSize
= sizeof (BM_LOAD_CONTEXT
);
41 case BM_FILE_CONTEXT_SELECT
:
42 ContextSize
= sizeof (BM_FILE_CONTEXT
);
45 case BM_CONSOLE_CONTEXT_SELECT
:
46 ContextSize
= sizeof (BM_CONSOLE_CONTEXT
);
49 case BM_TERMINAL_CONTEXT_SELECT
:
50 ContextSize
= sizeof (BM_TERMINAL_CONTEXT
);
53 case BM_HANDLE_CONTEXT_SELECT
:
54 ContextSize
= sizeof (BM_HANDLE_CONTEXT
);
57 case BM_LEGACY_DEV_CONTEXT_SELECT
:
58 ContextSize
= sizeof (BM_LEGACY_DEVICE_CONTEXT
);
66 if (ContextSize
== 0) {
71 // Create new menu entry
73 MenuEntry
= AllocateZeroPool (sizeof (BM_MENU_ENTRY
));
74 if (MenuEntry
== NULL
) {
78 MenuEntry
->VariableContext
= AllocateZeroPool (ContextSize
);
79 if (MenuEntry
->VariableContext
== NULL
) {
84 MenuEntry
->Signature
= BM_MENU_ENTRY_SIGNATURE
;
85 MenuEntry
->ContextSelection
= MenuType
;
90 Free up all resource allocated for a BM_MENU_ENTRY.
92 @param MenuEntry A pointer to BM_MENU_ENTRY.
96 BOpt_DestroyMenuEntry (
97 BM_MENU_ENTRY
*MenuEntry
100 BM_LOAD_CONTEXT
*LoadContext
;
101 BM_FILE_CONTEXT
*FileContext
;
102 BM_CONSOLE_CONTEXT
*ConsoleContext
;
103 BM_TERMINAL_CONTEXT
*TerminalContext
;
104 BM_HANDLE_CONTEXT
*HandleContext
;
105 BM_LEGACY_DEVICE_CONTEXT
*LegacyDevContext
;
108 // Select by the type in Menu entry for current context type
110 switch (MenuEntry
->ContextSelection
) {
111 case BM_LOAD_CONTEXT_SELECT
:
112 LoadContext
= (BM_LOAD_CONTEXT
*) MenuEntry
->VariableContext
;
113 FreePool (LoadContext
->FilePathList
);
114 FreePool (LoadContext
->LoadOption
);
115 if (LoadContext
->OptionalData
!= NULL
) {
116 FreePool (LoadContext
->OptionalData
);
118 FreePool (LoadContext
);
121 case BM_FILE_CONTEXT_SELECT
:
122 FileContext
= (BM_FILE_CONTEXT
*) MenuEntry
->VariableContext
;
124 if (!FileContext
->IsRoot
) {
125 FreePool (FileContext
->DevicePath
);
127 if (FileContext
->FHandle
!= NULL
) {
128 FileContext
->FHandle
->Close (FileContext
->FHandle
);
132 if (FileContext
->FileName
!= NULL
) {
133 FreePool (FileContext
->FileName
);
135 if (FileContext
->Info
!= NULL
) {
136 FreePool (FileContext
->Info
);
138 FreePool (FileContext
);
141 case BM_CONSOLE_CONTEXT_SELECT
:
142 ConsoleContext
= (BM_CONSOLE_CONTEXT
*) MenuEntry
->VariableContext
;
143 FreePool (ConsoleContext
->DevicePath
);
144 FreePool (ConsoleContext
);
147 case BM_TERMINAL_CONTEXT_SELECT
:
148 TerminalContext
= (BM_TERMINAL_CONTEXT
*) MenuEntry
->VariableContext
;
149 FreePool (TerminalContext
->DevicePath
);
150 FreePool (TerminalContext
);
153 case BM_HANDLE_CONTEXT_SELECT
:
154 HandleContext
= (BM_HANDLE_CONTEXT
*) MenuEntry
->VariableContext
;
155 FreePool (HandleContext
);
158 case BM_LEGACY_DEV_CONTEXT_SELECT
:
159 LegacyDevContext
= (BM_LEGACY_DEVICE_CONTEXT
*) MenuEntry
->VariableContext
;
160 FreePool (LegacyDevContext
);
166 FreePool (MenuEntry
->DisplayString
);
167 if (MenuEntry
->HelpString
!= NULL
) {
168 FreePool (MenuEntry
->HelpString
);
171 FreePool (MenuEntry
);
175 Get the Menu Entry from the list in Menu Entry List.
177 If MenuNumber is great or equal to the number of Menu
178 Entry in the list, then ASSERT.
180 @param MenuOption The Menu Entry List to read the menu entry.
181 @param MenuNumber The index of Menu Entry.
183 @return The Menu Entry.
188 BM_MENU_OPTION
*MenuOption
,
192 BM_MENU_ENTRY
*NewMenuEntry
;
196 ASSERT (MenuNumber
< MenuOption
->MenuNumber
);
198 List
= MenuOption
->Head
.ForwardLink
;
199 for (Index
= 0; Index
< MenuNumber
; Index
++) {
200 List
= List
->ForwardLink
;
203 NewMenuEntry
= CR (List
, BM_MENU_ENTRY
, Link
, BM_MENU_ENTRY_SIGNATURE
);
209 This function build the FsOptionMenu list which records all
210 available file system in the system. They includes all instances
211 of EFI_SIMPLE_FILE_SYSTEM_PROTOCOL, all instances of EFI_LOAD_FILE_SYSTEM
212 and all type of legacy boot device.
214 @param CallbackData BMM context data
216 @retval EFI_SUCCESS Success find the file system
217 @retval EFI_OUT_OF_RESOURCES Can not create menu entry
221 BOpt_FindFileSystem (
222 IN BMM_CALLBACK_DATA
*CallbackData
225 UINTN NoBlkIoHandles
;
226 UINTN NoSimpleFsHandles
;
227 UINTN NoLoadFileHandles
;
228 EFI_HANDLE
*BlkIoHandle
;
229 EFI_HANDLE
*SimpleFsHandle
;
230 EFI_HANDLE
*LoadFileHandle
;
232 EFI_BLOCK_IO_PROTOCOL
*BlkIo
;
235 BM_MENU_ENTRY
*MenuEntry
;
236 BM_FILE_CONTEXT
*FileContext
;
240 EFI_LEGACY_BIOS_PROTOCOL
*LegacyBios
;
242 BBS_BBS_DEVICE_PATH BbsDevicePathNode
;
243 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
244 BOOLEAN RemovableMedia
;
247 NoSimpleFsHandles
= 0;
248 NoLoadFileHandles
= 0;
250 InitializeListHead (&FsOptionMenu
.Head
);
253 // Locate Handles that support BlockIo protocol
255 Status
= gBS
->LocateHandleBuffer (
257 &gEfiBlockIoProtocolGuid
,
262 if (!EFI_ERROR (Status
)) {
264 for (Index
= 0; Index
< NoBlkIoHandles
; Index
++) {
265 Status
= gBS
->HandleProtocol (
267 &gEfiBlockIoProtocolGuid
,
271 if (EFI_ERROR (Status
)) {
276 // Issue a dummy read to trigger reinstall of BlockIo protocol for removable media
278 if (BlkIo
->Media
->RemovableMedia
) {
279 Buffer
= AllocateZeroPool (BlkIo
->Media
->BlockSize
);
280 if (NULL
== Buffer
) {
281 FreePool (BlkIoHandle
);
282 return EFI_OUT_OF_RESOURCES
;
287 BlkIo
->Media
->MediaId
,
289 BlkIo
->Media
->BlockSize
,
295 FreePool (BlkIoHandle
);
299 // Locate Handles that support Simple File System protocol
301 Status
= gBS
->LocateHandleBuffer (
303 &gEfiSimpleFileSystemProtocolGuid
,
308 if (!EFI_ERROR (Status
)) {
310 // Find all the instances of the File System prototocol
312 for (Index
= 0; Index
< NoSimpleFsHandles
; Index
++) {
313 Status
= gBS
->HandleProtocol (
314 SimpleFsHandle
[Index
],
315 &gEfiBlockIoProtocolGuid
,
318 if (EFI_ERROR (Status
)) {
320 // If no block IO exists assume it's NOT a removable media
322 RemovableMedia
= FALSE
;
325 // If block IO exists check to see if it's remobable media
327 RemovableMedia
= BlkIo
->Media
->RemovableMedia
;
331 // Allocate pool for this load option
333 MenuEntry
= BOpt_CreateMenuEntry (BM_FILE_CONTEXT_SELECT
);
334 if (NULL
== MenuEntry
) {
335 FreePool (SimpleFsHandle
);
336 return EFI_OUT_OF_RESOURCES
;
339 FileContext
= (BM_FILE_CONTEXT
*) MenuEntry
->VariableContext
;
341 FileContext
->Handle
= SimpleFsHandle
[Index
];
342 MenuEntry
->OptionNumber
= Index
;
343 FileContext
->FHandle
= EfiLibOpenRoot (FileContext
->Handle
);
344 if (FileContext
->FHandle
== NULL
) {
345 BOpt_DestroyMenuEntry (MenuEntry
);
349 MenuEntry
->HelpString
= DevicePathToStr (DevicePathFromHandle (FileContext
->Handle
));
350 FileContext
->Info
= EfiLibFileSystemVolumeLabelInfo (FileContext
->FHandle
);
351 FileContext
->FileName
= EfiStrDuplicate (L
"\\");
352 FileContext
->DevicePath
= FileDevicePath (
354 FileContext
->FileName
356 FileContext
->IsDir
= TRUE
;
357 FileContext
->IsRoot
= TRUE
;
358 FileContext
->IsRemovableMedia
= RemovableMedia
;
359 FileContext
->IsLoadFile
= FALSE
;
362 // Get current file system's Volume Label
364 if (FileContext
->Info
== NULL
) {
365 VolumeLabel
= L
"NO FILE SYSTEM INFO";
367 VolumeLabel
= FileContext
->Info
->VolumeLabel
;
368 if (*VolumeLabel
== 0x0000) {
369 VolumeLabel
= L
"NO VOLUME LABEL";
373 TempStr
= MenuEntry
->HelpString
;
374 MenuEntry
->DisplayString
= AllocateZeroPool (MAX_CHAR
);
375 ASSERT (MenuEntry
->DisplayString
!= NULL
);
377 MenuEntry
->DisplayString
,
384 InsertTailList (&FsOptionMenu
.Head
, &MenuEntry
->Link
);
388 if (NoSimpleFsHandles
!= 0) {
389 FreePool (SimpleFsHandle
);
392 // Searching for handles that support Load File protocol
394 Status
= gBS
->LocateHandleBuffer (
396 &gEfiLoadFileProtocolGuid
,
402 if (!EFI_ERROR (Status
)) {
403 for (Index
= 0; Index
< NoLoadFileHandles
; Index
++) {
404 MenuEntry
= BOpt_CreateMenuEntry (BM_FILE_CONTEXT_SELECT
);
405 if (NULL
== MenuEntry
) {
406 FreePool (LoadFileHandle
);
407 return EFI_OUT_OF_RESOURCES
;
410 FileContext
= (BM_FILE_CONTEXT
*) MenuEntry
->VariableContext
;
411 FileContext
->IsRemovableMedia
= FALSE
;
412 FileContext
->IsLoadFile
= TRUE
;
413 FileContext
->Handle
= LoadFileHandle
[Index
];
414 FileContext
->IsRoot
= TRUE
;
416 FileContext
->DevicePath
= DevicePathFromHandle (FileContext
->Handle
);
417 FileContext
->FileName
= DevicePathToStr (FileContext
->DevicePath
);
419 MenuEntry
->HelpString
= DevicePathToStr (FileContext
->DevicePath
);
421 TempStr
= MenuEntry
->HelpString
;
422 MenuEntry
->DisplayString
= AllocateZeroPool (MAX_CHAR
);
423 ASSERT (MenuEntry
->DisplayString
!= NULL
);
425 MenuEntry
->DisplayString
,
431 MenuEntry
->OptionNumber
= OptionNumber
;
433 InsertTailList (&FsOptionMenu
.Head
, &MenuEntry
->Link
);
437 if (NoLoadFileHandles
!= 0) {
438 FreePool (LoadFileHandle
);
442 // Add Legacy Boot Option Support Here
444 Status
= gBS
->LocateProtocol (
445 &gEfiLegacyBiosProtocolGuid
,
447 (VOID
**) &LegacyBios
449 if (!EFI_ERROR (Status
)) {
451 for (Index
= BBS_TYPE_FLOPPY
; Index
<= BBS_TYPE_EMBEDDED_NETWORK
; Index
++) {
452 MenuEntry
= BOpt_CreateMenuEntry (BM_FILE_CONTEXT_SELECT
);
453 if (NULL
== MenuEntry
) {
454 return EFI_OUT_OF_RESOURCES
;
457 FileContext
= (BM_FILE_CONTEXT
*) MenuEntry
->VariableContext
;
459 FileContext
->IsRemovableMedia
= FALSE
;
460 FileContext
->IsLoadFile
= TRUE
;
461 FileContext
->IsBootLegacy
= TRUE
;
462 DeviceType
= (UINT16
) Index
;
463 BbsDevicePathNode
.Header
.Type
= BBS_DEVICE_PATH
;
464 BbsDevicePathNode
.Header
.SubType
= BBS_BBS_DP
;
465 SetDevicePathNodeLength (
466 &BbsDevicePathNode
.Header
,
467 sizeof (BBS_BBS_DEVICE_PATH
)
469 BbsDevicePathNode
.DeviceType
= DeviceType
;
470 BbsDevicePathNode
.StatusFlag
= 0;
471 BbsDevicePathNode
.String
[0] = 0;
472 DevicePath
= AppendDevicePathNode (
474 (EFI_DEVICE_PATH_PROTOCOL
*) &BbsDevicePathNode
477 FileContext
->DevicePath
= DevicePath
;
478 MenuEntry
->HelpString
= DevicePathToStr (FileContext
->DevicePath
);
480 TempStr
= MenuEntry
->HelpString
;
481 MenuEntry
->DisplayString
= AllocateZeroPool (MAX_CHAR
);
482 ASSERT (MenuEntry
->DisplayString
!= NULL
);
484 MenuEntry
->DisplayString
,
489 MenuEntry
->OptionNumber
= OptionNumber
;
491 InsertTailList (&FsOptionMenu
.Head
, &MenuEntry
->Link
);
495 // Remember how many file system options are here
497 FsOptionMenu
.MenuNumber
= OptionNumber
;
502 Free resources allocated in Allocate Rountine.
504 @param FreeMenu Menu to be freed
508 BM_MENU_OPTION
*FreeMenu
511 BM_MENU_ENTRY
*MenuEntry
;
512 while (!IsListEmpty (&FreeMenu
->Head
)) {
514 FreeMenu
->Head
.ForwardLink
,
517 BM_MENU_ENTRY_SIGNATURE
519 RemoveEntryList (&MenuEntry
->Link
);
520 BOpt_DestroyMenuEntry (MenuEntry
);
522 FreeMenu
->MenuNumber
= 0;
526 Find files under current directory
527 All files and sub-directories in current directory
528 will be stored in DirectoryMenu for future use.
530 @param CallbackData The BMM context data.
531 @param MenuEntry The Menu Entry.
533 @retval EFI_SUCCESS Get files from current dir successfully.
534 @return Other value if can't get files from current dir.
539 IN BMM_CALLBACK_DATA
*CallbackData
,
540 IN BM_MENU_ENTRY
*MenuEntry
543 EFI_FILE_HANDLE NewDir
;
545 EFI_FILE_INFO
*DirInfo
;
548 BM_MENU_ENTRY
*NewMenuEntry
;
549 BM_FILE_CONTEXT
*FileContext
;
550 BM_FILE_CONTEXT
*NewFileContext
;
555 FileContext
= (BM_FILE_CONTEXT
*) MenuEntry
->VariableContext
;
556 Dir
= FileContext
->FHandle
;
559 // Open current directory to get files from it
564 FileContext
->FileName
,
568 if (!FileContext
->IsRoot
) {
572 if (EFI_ERROR (Status
)) {
576 DirInfo
= EfiLibFileInfo (NewDir
);
577 if (DirInfo
== NULL
) {
578 return EFI_NOT_FOUND
;
581 if ((DirInfo
->Attribute
& EFI_FILE_DIRECTORY
) == 0) {
582 return EFI_INVALID_PARAMETER
;
585 FileContext
->DevicePath
= FileDevicePath (
587 FileContext
->FileName
590 DirBufferSize
= sizeof (EFI_FILE_INFO
) + 1024;
591 DirInfo
= AllocateZeroPool (DirBufferSize
);
592 if (DirInfo
== NULL
) {
593 return EFI_OUT_OF_RESOURCES
;
596 // Get all files in current directory
597 // Pass 1 to get Directories
598 // Pass 2 to get files that are EFI images
600 for (Pass
= 1; Pass
<= 2; Pass
++) {
601 NewDir
->SetPosition (NewDir
, 0);
603 BufferSize
= DirBufferSize
;
604 Status
= NewDir
->Read (NewDir
, &BufferSize
, DirInfo
);
605 if (EFI_ERROR (Status
) || BufferSize
== 0) {
609 if (((DirInfo
->Attribute
& EFI_FILE_DIRECTORY
) != 0 && Pass
== 2) ||
610 ((DirInfo
->Attribute
& EFI_FILE_DIRECTORY
) == 0 && Pass
== 1)
613 // Pass 1 is for Directories
614 // Pass 2 is for file names
619 if (!(BOpt_IsEfiImageName (DirInfo
->FileName
) || (DirInfo
->Attribute
& EFI_FILE_DIRECTORY
) != 0)) {
621 // Slip file unless it is a directory entry or a .EFI file
626 NewMenuEntry
= BOpt_CreateMenuEntry (BM_FILE_CONTEXT_SELECT
);
627 if (NULL
== NewMenuEntry
) {
628 return EFI_OUT_OF_RESOURCES
;
631 NewFileContext
= (BM_FILE_CONTEXT
*) NewMenuEntry
->VariableContext
;
632 NewFileContext
->Handle
= FileContext
->Handle
;
633 NewFileContext
->FileName
= BOpt_AppendFileName (
634 FileContext
->FileName
,
637 NewFileContext
->FHandle
= NewDir
;
638 NewFileContext
->DevicePath
= FileDevicePath (
639 NewFileContext
->Handle
,
640 NewFileContext
->FileName
642 NewMenuEntry
->HelpString
= NULL
;
644 MenuEntry
->DisplayStringToken
= GetStringTokenFromDepository (
646 FileOptionStrDepository
649 NewFileContext
->IsDir
= (BOOLEAN
) ((DirInfo
->Attribute
& EFI_FILE_DIRECTORY
) == EFI_FILE_DIRECTORY
);
651 if (NewFileContext
->IsDir
) {
652 BufferSize
= StrLen (DirInfo
->FileName
) * 2 + 6;
653 NewMenuEntry
->DisplayString
= AllocateZeroPool (BufferSize
);
656 NewMenuEntry
->DisplayString
,
663 NewMenuEntry
->DisplayString
= EfiStrDuplicate (DirInfo
->FileName
);
666 NewFileContext
->IsRoot
= FALSE
;
667 NewFileContext
->IsLoadFile
= FALSE
;
668 NewFileContext
->IsRemovableMedia
= FALSE
;
670 NewMenuEntry
->OptionNumber
= OptionNumber
;
672 InsertTailList (&DirectoryMenu
.Head
, &NewMenuEntry
->Link
);
676 DirectoryMenu
.MenuNumber
= OptionNumber
;
682 Build the LegacyFDMenu LegacyHDMenu LegacyCDMenu according to LegacyBios.GetBbsInfo().
684 @retval EFI_SUCCESS The function complete successfully.
685 @retval EFI_OUT_OF_RESOURCES No enough memory to complete this function.
689 BOpt_GetLegacyOptions (
693 BM_MENU_ENTRY
*NewMenuEntry
;
694 BM_LEGACY_DEVICE_CONTEXT
*NewLegacyDevContext
;
696 EFI_LEGACY_BIOS_PROTOCOL
*LegacyBios
;
702 CHAR16 DescString
[100];
715 // Initialize Bbs Table Context from BBS info data
717 InitializeListHead (&LegacyFDMenu
.Head
);
718 InitializeListHead (&LegacyHDMenu
.Head
);
719 InitializeListHead (&LegacyCDMenu
.Head
);
720 InitializeListHead (&LegacyNETMenu
.Head
);
721 InitializeListHead (&LegacyBEVMenu
.Head
);
723 Status
= gBS
->LocateProtocol (
724 &gEfiLegacyBiosProtocolGuid
,
726 (VOID
**) &LegacyBios
728 if (!EFI_ERROR (Status
)) {
729 Status
= LegacyBios
->GetBbsInfo (
736 if (EFI_ERROR (Status
)) {
747 for (Index
= 0; Index
< BbsCount
; Index
++) {
748 if ((BBS_IGNORE_ENTRY
== BbsTable
[Index
].BootPriority
) ||
749 (BBS_DO_NOT_BOOT_FROM
== BbsTable
[Index
].BootPriority
)
754 NewMenuEntry
= BOpt_CreateMenuEntry (BM_LEGACY_DEV_CONTEXT_SELECT
);
755 if (NULL
== NewMenuEntry
) {
759 NewLegacyDevContext
= (BM_LEGACY_DEVICE_CONTEXT
*) NewMenuEntry
->VariableContext
;
760 NewLegacyDevContext
->BbsEntry
= &BbsTable
[Index
];
761 NewLegacyDevContext
->BbsIndex
= Index
;
762 NewLegacyDevContext
->BbsCount
= BbsCount
;
763 BdsBuildLegacyDevNameString (
769 NewLegacyDevContext
->Description
= AllocateCopyPool (StrSize (DescString
), DescString
);
770 if (NULL
== NewLegacyDevContext
->Description
) {
774 NewMenuEntry
->DisplayString
= NewLegacyDevContext
->Description
;
775 NewMenuEntry
->HelpString
= NULL
;
777 switch (BbsTable
[Index
].DeviceType
) {
779 InsertTailList (&LegacyFDMenu
.Head
, &NewMenuEntry
->Link
);
784 InsertTailList (&LegacyHDMenu
.Head
, &NewMenuEntry
->Link
);
789 InsertTailList (&LegacyCDMenu
.Head
, &NewMenuEntry
->Link
);
793 case BBS_EMBED_NETWORK
:
794 InsertTailList (&LegacyNETMenu
.Head
, &NewMenuEntry
->Link
);
799 InsertTailList (&LegacyBEVMenu
.Head
, &NewMenuEntry
->Link
);
805 if (Index
!= BbsCount
) {
806 BOpt_FreeLegacyOptions ();
807 return EFI_OUT_OF_RESOURCES
;
810 LegacyFDMenu
.MenuNumber
= FDNum
;
811 LegacyHDMenu
.MenuNumber
= HDNum
;
812 LegacyCDMenu
.MenuNumber
= CDNum
;
813 LegacyNETMenu
.MenuNumber
= NETNum
;
814 LegacyBEVMenu
.MenuNumber
= BEVNum
;
819 Free out resouce allocated from Legacy Boot Options.
823 BOpt_FreeLegacyOptions (
827 BOpt_FreeMenu (&LegacyFDMenu
);
828 BOpt_FreeMenu (&LegacyHDMenu
);
829 BOpt_FreeMenu (&LegacyCDMenu
);
830 BOpt_FreeMenu (&LegacyNETMenu
);
831 BOpt_FreeMenu (&LegacyBEVMenu
);
836 Build the BootOptionMenu according to BootOrder Variable.
837 This Routine will access the Boot#### to get EFI_LOAD_OPTION.
839 @param CallbackData The BMM context data.
841 @return EFI_NOT_FOUND Fail to find "BootOrder" variable.
842 @return EFI_SUCESS Success build boot option menu.
846 BOpt_GetBootOptions (
847 IN BMM_CALLBACK_DATA
*CallbackData
851 UINT16 BootString
[10];
852 UINT8
*LoadOptionFromVar
;
854 UINTN BootOptionSize
;
855 BOOLEAN BootNextFlag
;
856 UINT16
*BootOrderList
;
857 UINTN BootOrderListSize
;
860 BM_MENU_ENTRY
*NewMenuEntry
;
861 BM_LOAD_CONTEXT
*NewLoadContext
;
862 UINT8
*LoadOptionPtr
;
864 UINTN OptionalDataSize
;
865 UINT8
*LoadOptionEnd
;
866 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
871 BootOrderListSize
= 0;
873 BootOrderList
= NULL
;
875 LoadOptionFromVar
= NULL
;
876 BOpt_FreeMenu (&BootOptionMenu
);
877 InitializeListHead (&BootOptionMenu
.Head
);
880 // Get the BootOrder from the Var
882 BootOrderList
= BdsLibGetVariableAndSize (
884 &gEfiGlobalVariableGuid
,
887 if (BootOrderList
== NULL
) {
888 return EFI_NOT_FOUND
;
892 // Get the BootNext from the Var
894 BootNext
= BdsLibGetVariableAndSize (
896 &gEfiGlobalVariableGuid
,
900 if (BootNext
!= NULL
) {
901 if (BootNextSize
!= sizeof (UINT16
)) {
907 for (Index
= 0; Index
< BootOrderListSize
/ sizeof (UINT16
); Index
++) {
908 UnicodeSPrint (BootString
, sizeof (BootString
), L
"Boot%04x", BootOrderList
[Index
]);
910 // Get all loadoptions from the VAR
912 LoadOptionFromVar
= BdsLibGetVariableAndSize (
914 &gEfiGlobalVariableGuid
,
917 if (LoadOptionFromVar
== NULL
) {
921 LoadOption
= AllocateZeroPool (BootOptionSize
);
922 if (LoadOption
== NULL
) {
926 CopyMem (LoadOption
, LoadOptionFromVar
, BootOptionSize
);
927 FreePool (LoadOptionFromVar
);
929 if (BootNext
!= NULL
) {
930 BootNextFlag
= (BOOLEAN
) (*BootNext
== BootOrderList
[Index
]);
932 BootNextFlag
= FALSE
;
935 if (0 == (*((UINT32
*) LoadOption
) & LOAD_OPTION_ACTIVE
)) {
936 FreePool (LoadOption
);
940 // BUGBUG: could not return EFI_OUT_OF_RESOURCES here directly.
941 // the buffer allocated already should be freed before returning.
943 NewMenuEntry
= BOpt_CreateMenuEntry (BM_LOAD_CONTEXT_SELECT
);
944 if (NULL
== NewMenuEntry
) {
945 return EFI_OUT_OF_RESOURCES
;
948 NewLoadContext
= (BM_LOAD_CONTEXT
*) NewMenuEntry
->VariableContext
;
950 LoadOptionPtr
= LoadOption
;
951 LoadOptionEnd
= LoadOption
+ BootOptionSize
;
953 NewMenuEntry
->OptionNumber
= BootOrderList
[Index
];
954 NewLoadContext
->LoadOptionModified
= FALSE
;
955 NewLoadContext
->Deleted
= FALSE
;
956 NewLoadContext
->IsBootNext
= BootNextFlag
;
959 // Is a Legacy Device?
961 Ptr
= (UINT8
*) LoadOption
;
964 // Attribute = *(UINT32 *)Ptr;
966 Ptr
+= sizeof (UINT32
);
969 // FilePathSize = *(UINT16 *)Ptr;
971 Ptr
+= sizeof (UINT16
);
974 // Description = (CHAR16 *)Ptr;
976 Ptr
+= StrSize ((CHAR16
*) Ptr
);
979 // Now Ptr point to Device Path
981 DevicePath
= (EFI_DEVICE_PATH_PROTOCOL
*) Ptr
;
982 if ((BBS_DEVICE_PATH
== DevicePath
->Type
) && (BBS_BBS_DP
== DevicePath
->SubType
)) {
983 NewLoadContext
->IsLegacy
= TRUE
;
985 NewLoadContext
->IsLegacy
= FALSE
;
988 // LoadOption is a pointer type of UINT8
989 // for easy use with following LOAD_OPTION
990 // embedded in this struct
992 NewLoadContext
->LoadOption
= LoadOption
;
993 NewLoadContext
->LoadOptionSize
= BootOptionSize
;
995 NewLoadContext
->Attributes
= *(UINT32
*) LoadOptionPtr
;
996 NewLoadContext
->IsActive
= (BOOLEAN
) (NewLoadContext
->Attributes
& LOAD_OPTION_ACTIVE
);
998 NewLoadContext
->ForceReconnect
= (BOOLEAN
) (NewLoadContext
->Attributes
& LOAD_OPTION_FORCE_RECONNECT
);
1000 LoadOptionPtr
+= sizeof (UINT32
);
1002 NewLoadContext
->FilePathListLength
= *(UINT16
*) LoadOptionPtr
;
1003 LoadOptionPtr
+= sizeof (UINT16
);
1005 StringSize
= StrSize((UINT16
*)LoadOptionPtr
);
1007 NewLoadContext
->Description
= AllocateCopyPool (StrSize((UINT16
*)LoadOptionPtr
), LoadOptionPtr
);
1008 ASSERT (NewLoadContext
->Description
!= NULL
);
1010 NewMenuEntry
->DisplayString
= NewLoadContext
->Description
;
1012 LoadOptionPtr
+= StringSize
;
1014 NewLoadContext
->FilePathList
= AllocateZeroPool (NewLoadContext
->FilePathListLength
);
1015 ASSERT (NewLoadContext
->FilePathList
!= NULL
);
1017 NewLoadContext
->FilePathList
,
1018 (EFI_DEVICE_PATH_PROTOCOL
*) LoadOptionPtr
,
1019 NewLoadContext
->FilePathListLength
1022 NewMenuEntry
->HelpString
= DevicePathToStr (NewLoadContext
->FilePathList
);
1023 NewMenuEntry
->DisplayStringToken
= GetStringTokenFromDepository (
1025 BootOptionStrDepository
1027 NewMenuEntry
->HelpStringToken
= GetStringTokenFromDepository (
1029 BootOptionHelpStrDepository
1031 LoadOptionPtr
+= NewLoadContext
->FilePathListLength
;
1033 if (LoadOptionPtr
< LoadOptionEnd
) {
1034 OptionalDataSize
= BootOptionSize
-
1038 NewLoadContext
->FilePathListLength
;
1040 NewLoadContext
->OptionalData
= AllocateZeroPool (OptionalDataSize
);
1041 ASSERT (NewLoadContext
->OptionalData
!= NULL
);
1043 NewLoadContext
->OptionalData
,
1048 NewLoadContext
->OptionalDataSize
= OptionalDataSize
;
1051 InsertTailList (&BootOptionMenu
.Head
, &NewMenuEntry
->Link
);
1055 if (BootNext
!= NULL
) {
1056 FreePool (BootNext
);
1058 if (BootOrderList
!= NULL
) {
1059 FreePool (BootOrderList
);
1061 BootOptionMenu
.MenuNumber
= MenuCount
;
1067 Append file name to existing file name.
1069 @param Str1 The existing file name
1070 @param Str2 The file name to be appended
1072 @return Allocate a new string to hold the appended result.
1073 Caller is responsible to free the returned string.
1077 BOpt_AppendFileName (
1090 Size1
= StrSize (Str1
);
1091 Size2
= StrSize (Str2
);
1092 MaxLen
= (Size1
+ Size2
+ sizeof (CHAR16
)) / sizeof (CHAR16
);
1093 Str
= AllocateZeroPool (MaxLen
* sizeof (CHAR16
));
1094 ASSERT (Str
!= NULL
);
1096 TmpStr
= AllocateZeroPool (MaxLen
* sizeof (CHAR16
));
1097 ASSERT (TmpStr
!= NULL
);
1099 StrCatS (Str
, MaxLen
, Str1
);
1100 if (!((*Str
== '\\') && (*(Str
+ 1) == 0))) {
1101 StrCatS (Str
, MaxLen
, L
"\\");
1104 StrCatS (Str
, MaxLen
, Str2
);
1109 if (*Ptr
== '\\' && *(Ptr
+ 1) == '.' && *(Ptr
+ 2) == '.' && *(Ptr
+ 3) == L
'\\') {
1111 // Convert "\Name\..\" to "\"
1112 // DO NOT convert the .. if it is at the end of the string. This will
1113 // break the .. behavior in changing directories.
1117 // Use TmpStr as a backup, as StrCpyS in BaseLib does not handle copy of two strings
1120 StrCpyS (TmpStr
, MaxLen
, Ptr
+ 3);
1121 StrCpyS (LastSlash
, MaxLen
- ((UINTN
) LastSlash
- (UINTN
) Str
) / sizeof (CHAR16
), TmpStr
);
1123 } else if (*Ptr
== '\\' && *(Ptr
+ 1) == '.' && *(Ptr
+ 2) == '\\') {
1125 // Convert a "\.\" to a "\"
1129 // Use TmpStr as a backup, as StrCpyS in BaseLib does not handle copy of two strings
1132 StrCpyS (TmpStr
, MaxLen
, Ptr
+ 2);
1133 StrCpyS (Ptr
, MaxLen
- ((UINTN
) Ptr
- (UINTN
) Str
) / sizeof (CHAR16
), TmpStr
);
1135 } else if (*Ptr
== '\\') {
1149 Check whether current FileName point to a valid
1152 @param FileName File need to be checked.
1154 @retval TRUE Is Efi Image
1155 @retval FALSE Not a valid Efi Image
1159 BOpt_IsEfiImageName (
1164 // Search for ".efi" extension
1166 while (*FileName
!= L
'\0') {
1167 if (FileName
[0] == '.') {
1168 if (FileName
[1] == 'e' || FileName
[1] == 'E') {
1169 if (FileName
[2] == 'f' || FileName
[2] == 'F') {
1170 if (FileName
[3] == 'i' || FileName
[3] == 'I') {
1172 } else if (FileName
[3] == 0x0000) {
1175 } else if (FileName
[2] == 0x0000) {
1178 } else if (FileName
[1] == 0x0000) {
1193 Find drivers that will be added as Driver#### variables from handles
1194 in current system environment
1195 All valid handles in the system except those consume SimpleFs, LoadFile
1196 are stored in DriverMenu for future use.
1198 @retval EFI_SUCCESS The function complets successfully.
1199 @return Other value if failed to build the DriverMenu.
1207 UINTN NoDevicePathHandles
;
1208 EFI_HANDLE
*DevicePathHandle
;
1211 BM_MENU_ENTRY
*NewMenuEntry
;
1212 BM_HANDLE_CONTEXT
*NewHandleContext
;
1213 EFI_HANDLE CurHandle
;
1215 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
*SimpleFs
;
1216 EFI_LOAD_FILE_PROTOCOL
*LoadFile
;
1221 InitializeListHead (&DriverMenu
.Head
);
1224 // At first, get all handles that support Device Path
1225 // protocol which is the basic requirement for
1228 Status
= gBS
->LocateHandleBuffer (
1230 &gEfiDevicePathProtocolGuid
,
1232 &NoDevicePathHandles
,
1235 if (EFI_ERROR (Status
)) {
1240 for (Index
= 0; Index
< NoDevicePathHandles
; Index
++) {
1241 CurHandle
= DevicePathHandle
[Index
];
1243 Status
= gBS
->HandleProtocol (
1245 &gEfiSimpleFileSystemProtocolGuid
,
1248 if (Status
== EFI_SUCCESS
) {
1252 Status
= gBS
->HandleProtocol (
1254 &gEfiLoadFileProtocolGuid
,
1257 if (Status
== EFI_SUCCESS
) {
1261 NewMenuEntry
= BOpt_CreateMenuEntry (BM_HANDLE_CONTEXT_SELECT
);
1262 if (NULL
== NewMenuEntry
) {
1263 FreePool (DevicePathHandle
);
1264 return EFI_OUT_OF_RESOURCES
;
1267 NewHandleContext
= (BM_HANDLE_CONTEXT
*) NewMenuEntry
->VariableContext
;
1268 NewHandleContext
->Handle
= CurHandle
;
1269 NewHandleContext
->DevicePath
= DevicePathFromHandle (CurHandle
);
1270 NewMenuEntry
->DisplayString
= DevicePathToStr (NewHandleContext
->DevicePath
);
1271 NewMenuEntry
->HelpString
= NULL
;
1272 NewMenuEntry
->OptionNumber
= OptionNumber
;
1274 InsertTailList (&DriverMenu
.Head
, &NewMenuEntry
->Link
);
1278 if (DevicePathHandle
!= NULL
) {
1279 FreePool (DevicePathHandle
);
1282 DriverMenu
.MenuNumber
= OptionNumber
;
1288 Get the Option Number that has not been allocated for use.
1290 @param Type The type of Option.
1292 @return The available Option Number.
1296 BOpt_GetOptionNumber (
1301 UINTN OrderListSize
;
1304 UINT16
*OptionBuffer
;
1305 UINT16 OptionNumber
;
1313 UnicodeSPrint (StrTemp
, sizeof (StrTemp
), L
"%sOrder", Type
);
1315 OrderList
= BdsLibGetVariableAndSize (
1317 &gEfiGlobalVariableGuid
,
1321 for (OptionNumber
= 0; ; OptionNumber
++) {
1322 if (OrderList
!= NULL
) {
1323 for (Index
= 0; Index
< OrderListSize
/ sizeof (UINT16
); Index
++) {
1324 if (OptionNumber
== OrderList
[Index
]) {
1330 if (Index
< OrderListSize
/ sizeof (UINT16
)) {
1332 // The OptionNumber occurs in the OrderList, continue to use next one
1336 UnicodeSPrint (StrTemp
, sizeof (StrTemp
), L
"%s%04x", Type
, (UINTN
) OptionNumber
);
1337 DEBUG((EFI_D_ERROR
,"Option = %s\n", StrTemp
));
1338 OptionBuffer
= BdsLibGetVariableAndSize (
1340 &gEfiGlobalVariableGuid
,
1343 if (NULL
== OptionBuffer
) {
1345 // The Boot[OptionNumber] / Driver[OptionNumber] NOT occurs, we found it
1351 return OptionNumber
;
1356 Get the Option Number for Boot#### that does not used.
1358 @return The available Option Number.
1362 BOpt_GetBootOptionNumber (
1366 return BOpt_GetOptionNumber (L
"Boot");
1371 Get the Option Number for Driver#### that does not used.
1373 @return The unused Option Number.
1377 BOpt_GetDriverOptionNumber (
1381 return BOpt_GetOptionNumber (L
"Driver");
1386 Build up all DriverOptionMenu
1388 @param CallbackData The BMM context data.
1390 @retval EFI_SUCESS The functin completes successfully.
1391 @retval EFI_OUT_OF_RESOURCES Not enough memory to compete the operation.
1392 @retval EFI_NOT_FOUND Fail to get "DriverOrder" variable.
1396 BOpt_GetDriverOptions (
1397 IN BMM_CALLBACK_DATA
*CallbackData
1401 UINT16 DriverString
[12];
1402 UINT8
*LoadOptionFromVar
;
1404 UINTN DriverOptionSize
;
1406 UINT16
*DriverOrderList
;
1407 UINTN DriverOrderListSize
;
1408 BM_MENU_ENTRY
*NewMenuEntry
;
1409 BM_LOAD_CONTEXT
*NewLoadContext
;
1410 UINT8
*LoadOptionPtr
;
1412 UINTN OptionalDataSize
;
1413 UINT8
*LoadOptionEnd
;
1415 DriverOrderListSize
= 0;
1416 DriverOrderList
= NULL
;
1417 DriverOptionSize
= 0;
1418 LoadOptionFromVar
= NULL
;
1419 BOpt_FreeMenu (&DriverOptionMenu
);
1420 InitializeListHead (&DriverOptionMenu
.Head
);
1422 // Get the DriverOrder from the Var
1424 DriverOrderList
= BdsLibGetVariableAndSize (
1426 &gEfiGlobalVariableGuid
,
1427 &DriverOrderListSize
1429 if (DriverOrderList
== NULL
) {
1430 return EFI_NOT_FOUND
;
1433 for (Index
= 0; Index
< DriverOrderListSize
/ sizeof (UINT16
); Index
++) {
1436 sizeof (DriverString
),
1438 DriverOrderList
[Index
]
1441 // Get all loadoptions from the VAR
1443 LoadOptionFromVar
= BdsLibGetVariableAndSize (
1445 &gEfiGlobalVariableGuid
,
1448 if (LoadOptionFromVar
== NULL
) {
1452 LoadOption
= AllocateZeroPool (DriverOptionSize
);
1453 if (LoadOption
== NULL
) {
1457 CopyMem (LoadOption
, LoadOptionFromVar
, DriverOptionSize
);
1458 FreePool (LoadOptionFromVar
);
1460 NewMenuEntry
= BOpt_CreateMenuEntry (BM_LOAD_CONTEXT_SELECT
);
1461 if (NULL
== NewMenuEntry
) {
1462 return EFI_OUT_OF_RESOURCES
;
1465 NewLoadContext
= (BM_LOAD_CONTEXT
*) NewMenuEntry
->VariableContext
;
1466 LoadOptionPtr
= LoadOption
;
1467 LoadOptionEnd
= LoadOption
+ DriverOptionSize
;
1468 NewMenuEntry
->OptionNumber
= DriverOrderList
[Index
];
1469 NewLoadContext
->LoadOptionModified
= FALSE
;
1470 NewLoadContext
->Deleted
= FALSE
;
1471 NewLoadContext
->IsLegacy
= FALSE
;
1474 // LoadOption is a pointer type of UINT8
1475 // for easy use with following LOAD_OPTION
1476 // embedded in this struct
1478 NewLoadContext
->LoadOption
= LoadOption
;
1479 NewLoadContext
->LoadOptionSize
= DriverOptionSize
;
1481 NewLoadContext
->Attributes
= *(UINT32
*) LoadOptionPtr
;
1482 NewLoadContext
->IsActive
= (BOOLEAN
) (NewLoadContext
->Attributes
& LOAD_OPTION_ACTIVE
);
1484 NewLoadContext
->ForceReconnect
= (BOOLEAN
) (NewLoadContext
->Attributes
& LOAD_OPTION_FORCE_RECONNECT
);
1486 LoadOptionPtr
+= sizeof (UINT32
);
1488 NewLoadContext
->FilePathListLength
= *(UINT16
*) LoadOptionPtr
;
1489 LoadOptionPtr
+= sizeof (UINT16
);
1491 StringSize
= StrSize ((UINT16
*) LoadOptionPtr
);
1492 NewLoadContext
->Description
= AllocateZeroPool (StringSize
);
1493 ASSERT (NewLoadContext
->Description
!= NULL
);
1495 NewLoadContext
->Description
,
1496 (UINT16
*) LoadOptionPtr
,
1499 NewMenuEntry
->DisplayString
= NewLoadContext
->Description
;
1501 LoadOptionPtr
+= StringSize
;
1503 NewLoadContext
->FilePathList
= AllocateZeroPool (NewLoadContext
->FilePathListLength
);
1504 ASSERT (NewLoadContext
->FilePathList
!= NULL
);
1506 NewLoadContext
->FilePathList
,
1507 (EFI_DEVICE_PATH_PROTOCOL
*) LoadOptionPtr
,
1508 NewLoadContext
->FilePathListLength
1511 NewMenuEntry
->HelpString
= DevicePathToStr (NewLoadContext
->FilePathList
);
1512 NewMenuEntry
->DisplayStringToken
= GetStringTokenFromDepository (
1514 DriverOptionStrDepository
1516 NewMenuEntry
->HelpStringToken
= GetStringTokenFromDepository (
1518 DriverOptionHelpStrDepository
1520 LoadOptionPtr
+= NewLoadContext
->FilePathListLength
;
1522 if (LoadOptionPtr
< LoadOptionEnd
) {
1523 OptionalDataSize
= DriverOptionSize
-
1527 NewLoadContext
->FilePathListLength
;
1529 NewLoadContext
->OptionalData
= AllocateZeroPool (OptionalDataSize
);
1530 ASSERT (NewLoadContext
->OptionalData
!= NULL
);
1532 NewLoadContext
->OptionalData
,
1537 NewLoadContext
->OptionalDataSize
= OptionalDataSize
;
1540 InsertTailList (&DriverOptionMenu
.Head
, &NewMenuEntry
->Link
);
1544 if (DriverOrderList
!= NULL
) {
1545 FreePool (DriverOrderList
);
1547 DriverOptionMenu
.MenuNumber
= Index
;
1553 Get option number according to Boot#### and BootOrder variable.
1554 The value is saved as #### + 1.
1556 @param CallbackData The BMM context data.
1560 IN BMM_CALLBACK_DATA
*CallbackData
1563 BMM_FAKE_NV_DATA
*BmmConfig
;
1565 UINT16 OptionOrderIndex
;
1567 BM_MENU_ENTRY
*NewMenuEntry
;
1568 BM_LOAD_CONTEXT
*NewLoadContext
;
1570 ASSERT (CallbackData
!= NULL
);
1572 DeviceType
= (UINTN
) -1;
1573 BmmConfig
= &CallbackData
->BmmFakeNvData
;
1574 ZeroMem (BmmConfig
->BootOptionOrder
, sizeof (BmmConfig
->BootOptionOrder
));
1576 for (Index
= 0, OptionOrderIndex
= 0; ((Index
< BootOptionMenu
.MenuNumber
) &&
1577 (OptionOrderIndex
< (sizeof (BmmConfig
->BootOptionOrder
) / sizeof (BmmConfig
->BootOptionOrder
[0]))));
1579 NewMenuEntry
= BOpt_GetMenuEntry (&BootOptionMenu
, Index
);
1580 NewLoadContext
= (BM_LOAD_CONTEXT
*) NewMenuEntry
->VariableContext
;
1582 if (NewLoadContext
->IsLegacy
) {
1583 if (((BBS_BBS_DEVICE_PATH
*) NewLoadContext
->FilePathList
)->DeviceType
!= DeviceType
) {
1584 DeviceType
= ((BBS_BBS_DEVICE_PATH
*) NewLoadContext
->FilePathList
)->DeviceType
;
1587 // Only show one legacy boot option for the same device type
1588 // assuming the boot options are grouped by the device type
1593 BmmConfig
->BootOptionOrder
[OptionOrderIndex
++] = (UINT32
) (NewMenuEntry
->OptionNumber
+ 1);
1598 According to LegacyDevOrder variable to get legacy FD\HD\CD\NET\BEV
1601 @param CallbackData The BMM context data.
1604 GetLegacyDeviceOrder (
1605 IN BMM_CALLBACK_DATA
*CallbackData
1610 UINT16 PageIdList
[5];
1614 UINT8
*WorkingVarData
;
1615 LEGACY_DEV_ORDER_ENTRY
*DevOrder
;
1618 BM_MENU_OPTION
*OptionMenu
;
1625 ASSERT (CallbackData
!= NULL
);
1627 PageIdList
[0] = FORM_SET_FD_ORDER_ID
;
1628 PageIdList
[1] = FORM_SET_HD_ORDER_ID
;
1629 PageIdList
[2] = FORM_SET_CD_ORDER_ID
;
1630 PageIdList
[3] = FORM_SET_NET_ORDER_ID
;
1631 PageIdList
[4] = FORM_SET_BEV_ORDER_ID
;
1636 DisMap
= ZeroMem (CallbackData
->BmmFakeNvData
.DisableMap
, sizeof (CallbackData
->BmmFakeNvData
.DisableMap
));
1637 PageNum
= ARRAY_SIZE (PageIdList
);
1638 VarData
= BdsLibGetVariableAndSize (
1639 VAR_LEGACY_DEV_ORDER
,
1640 &gEfiLegacyDevOrderVariableGuid
,
1644 for (Index
= 0; Index
< PageNum
; Index
++) {
1645 switch (PageIdList
[Index
]) {
1647 case FORM_SET_FD_ORDER_ID
:
1648 OptionMenu
= (BM_MENU_OPTION
*) &LegacyFDMenu
;
1649 BbsType
= BBS_FLOPPY
;
1650 LegacyOrder
= CallbackData
->BmmFakeNvData
.LegacyFD
;
1651 OldData
= CallbackData
->BmmOldFakeNVData
.LegacyFD
;
1654 case FORM_SET_HD_ORDER_ID
:
1655 OptionMenu
= (BM_MENU_OPTION
*) &LegacyHDMenu
;
1656 BbsType
= BBS_HARDDISK
;
1657 LegacyOrder
= CallbackData
->BmmFakeNvData
.LegacyHD
;
1658 OldData
= CallbackData
->BmmOldFakeNVData
.LegacyHD
;
1661 case FORM_SET_CD_ORDER_ID
:
1662 OptionMenu
= (BM_MENU_OPTION
*) &LegacyCDMenu
;
1663 BbsType
= BBS_CDROM
;
1664 LegacyOrder
= CallbackData
->BmmFakeNvData
.LegacyCD
;
1665 OldData
= CallbackData
->BmmOldFakeNVData
.LegacyCD
;
1668 case FORM_SET_NET_ORDER_ID
:
1669 OptionMenu
= (BM_MENU_OPTION
*) &LegacyNETMenu
;
1670 BbsType
= BBS_EMBED_NETWORK
;
1671 LegacyOrder
= CallbackData
->BmmFakeNvData
.LegacyNET
;
1672 OldData
= CallbackData
->BmmOldFakeNVData
.LegacyNET
;
1676 ASSERT (PageIdList
[Index
] == FORM_SET_BEV_ORDER_ID
);
1677 OptionMenu
= (BM_MENU_OPTION
*) &LegacyBEVMenu
;
1678 BbsType
= BBS_BEV_DEVICE
;
1679 LegacyOrder
= CallbackData
->BmmFakeNvData
.LegacyBEV
;
1680 OldData
= CallbackData
->BmmOldFakeNVData
.LegacyBEV
;
1684 if (NULL
!= VarData
) {
1685 WorkingVarData
= VarData
;
1686 DevOrder
= (LEGACY_DEV_ORDER_ENTRY
*) WorkingVarData
;
1687 while (WorkingVarData
< VarData
+ VarSize
) {
1688 if (DevOrder
->BbsType
== BbsType
) {
1692 WorkingVarData
= (UINT8
*)((UINTN
)WorkingVarData
+ sizeof (BBS_TYPE
));
1693 WorkingVarData
+= *(UINT16
*) WorkingVarData
;
1694 DevOrder
= (LEGACY_DEV_ORDER_ENTRY
*) WorkingVarData
;
1696 for (OptionIndex
= 0; OptionIndex
< OptionMenu
->MenuNumber
; OptionIndex
++) {
1697 VarDevOrder
= *(UINT16
*) ((UINTN
) DevOrder
+ sizeof (BBS_TYPE
) + sizeof (UINT16
) + OptionIndex
* sizeof (UINT16
));
1698 if (0xFF00 == (VarDevOrder
& 0xFF00)) {
1699 LegacyOrder
[OptionIndex
] = 0xFF;
1700 Pos
= (VarDevOrder
& 0xFF) / 8;
1701 Bit
= 7 - ((VarDevOrder
& 0xFF) % 8);
1702 DisMap
[Pos
] = (UINT8
) (DisMap
[Pos
] | (UINT8
) (1 << Bit
));
1704 LegacyOrder
[OptionIndex
] = (UINT8
) (VarDevOrder
& 0xFF);
1707 CopyMem (OldData
, LegacyOrder
, 100);
1713 Get driver option order from globalc DriverOptionMenu.
1715 @param CallbackData The BMM context data.
1720 IN BMM_CALLBACK_DATA
*CallbackData
1723 BMM_FAKE_NV_DATA
*BmmConfig
;
1725 UINT16 OptionOrderIndex
;
1727 BM_MENU_ENTRY
*NewMenuEntry
;
1728 BM_LOAD_CONTEXT
*NewLoadContext
;
1730 ASSERT (CallbackData
!= NULL
);
1732 DeviceType
= (UINTN
) -1;
1733 BmmConfig
= &CallbackData
->BmmFakeNvData
;
1734 ZeroMem (BmmConfig
->DriverOptionOrder
, sizeof (BmmConfig
->DriverOptionOrder
));
1736 for (Index
= 0, OptionOrderIndex
= 0; ((Index
< DriverOptionMenu
.MenuNumber
) &&
1737 (OptionOrderIndex
< (sizeof (BmmConfig
->DriverOptionOrder
) / sizeof (BmmConfig
->DriverOptionOrder
[0]))));
1739 NewMenuEntry
= BOpt_GetMenuEntry (&DriverOptionMenu
, Index
);
1740 NewLoadContext
= (BM_LOAD_CONTEXT
*) NewMenuEntry
->VariableContext
;
1742 if (NewLoadContext
->IsLegacy
) {
1743 if (((BBS_BBS_DEVICE_PATH
*) NewLoadContext
->FilePathList
)->DeviceType
!= DeviceType
) {
1744 DeviceType
= ((BBS_BBS_DEVICE_PATH
*) NewLoadContext
->FilePathList
)->DeviceType
;
1747 // Only show one legacy boot option for the same device type
1748 // assuming the boot options are grouped by the device type
1753 BmmConfig
->DriverOptionOrder
[OptionOrderIndex
++] = (UINT32
) (NewMenuEntry
->OptionNumber
+ 1);