2 Provide boot option support for Application "BootMaint"
4 Include file system navigation, system handle selection
6 Boot option manipulation
8 Copyright (c) 2004 - 2010, Intel Corporation. <BR>
9 All rights reserved. This program and the accompanying materials
10 are licensed and made available under the terms and conditions of the BSD License
11 which accompanies this distribution. The full text of the license may be found at
12 http://opensource.org/licenses/bsd-license.php
14 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
15 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
19 #include "BootMaint.h"
20 #include "BBSsupport.h"
23 Create a menu entry by given menu type.
25 @param MenuType The Menu type to be created.
27 @retval NULL If failed to create the menu.
28 @return the new menu entry.
32 BOpt_CreateMenuEntry (
36 BM_MENU_ENTRY
*MenuEntry
;
40 // Get context size according to menu type
43 case BM_LOAD_CONTEXT_SELECT
:
44 ContextSize
= sizeof (BM_LOAD_CONTEXT
);
47 case BM_FILE_CONTEXT_SELECT
:
48 ContextSize
= sizeof (BM_FILE_CONTEXT
);
51 case BM_CONSOLE_CONTEXT_SELECT
:
52 ContextSize
= sizeof (BM_CONSOLE_CONTEXT
);
55 case BM_TERMINAL_CONTEXT_SELECT
:
56 ContextSize
= sizeof (BM_TERMINAL_CONTEXT
);
59 case BM_HANDLE_CONTEXT_SELECT
:
60 ContextSize
= sizeof (BM_HANDLE_CONTEXT
);
63 case BM_LEGACY_DEV_CONTEXT_SELECT
:
64 ContextSize
= sizeof (BM_LEGACY_DEVICE_CONTEXT
);
72 if (ContextSize
== 0) {
77 // Create new menu entry
79 MenuEntry
= AllocateZeroPool (sizeof (BM_MENU_ENTRY
));
80 if (MenuEntry
== NULL
) {
84 MenuEntry
->VariableContext
= AllocateZeroPool (ContextSize
);
85 if (MenuEntry
->VariableContext
== NULL
) {
90 MenuEntry
->Signature
= BM_MENU_ENTRY_SIGNATURE
;
91 MenuEntry
->ContextSelection
= MenuType
;
96 Free up all resource allocated for a BM_MENU_ENTRY.
98 @param MenuEntry A pointer to BM_MENU_ENTRY.
102 BOpt_DestroyMenuEntry (
103 BM_MENU_ENTRY
*MenuEntry
106 BM_LOAD_CONTEXT
*LoadContext
;
107 BM_FILE_CONTEXT
*FileContext
;
108 BM_CONSOLE_CONTEXT
*ConsoleContext
;
109 BM_TERMINAL_CONTEXT
*TerminalContext
;
110 BM_HANDLE_CONTEXT
*HandleContext
;
111 BM_LEGACY_DEVICE_CONTEXT
*LegacyDevContext
;
114 // Select by the type in Menu entry for current context type
116 switch (MenuEntry
->ContextSelection
) {
117 case BM_LOAD_CONTEXT_SELECT
:
118 LoadContext
= (BM_LOAD_CONTEXT
*) MenuEntry
->VariableContext
;
119 FreePool (LoadContext
->FilePathList
);
120 FreePool (LoadContext
->LoadOption
);
121 if (LoadContext
->OptionalData
!= NULL
) {
122 FreePool (LoadContext
->OptionalData
);
124 FreePool (LoadContext
);
127 case BM_FILE_CONTEXT_SELECT
:
128 FileContext
= (BM_FILE_CONTEXT
*) MenuEntry
->VariableContext
;
130 if (!FileContext
->IsRoot
) {
131 FreePool (FileContext
->DevicePath
);
133 if (FileContext
->FHandle
!= NULL
) {
134 FileContext
->FHandle
->Close (FileContext
->FHandle
);
138 if (FileContext
->FileName
!= NULL
) {
139 FreePool (FileContext
->FileName
);
141 if (FileContext
->Info
!= NULL
) {
142 FreePool (FileContext
->Info
);
144 FreePool (FileContext
);
147 case BM_CONSOLE_CONTEXT_SELECT
:
148 ConsoleContext
= (BM_CONSOLE_CONTEXT
*) MenuEntry
->VariableContext
;
149 FreePool (ConsoleContext
->DevicePath
);
150 FreePool (ConsoleContext
);
153 case BM_TERMINAL_CONTEXT_SELECT
:
154 TerminalContext
= (BM_TERMINAL_CONTEXT
*) MenuEntry
->VariableContext
;
155 FreePool (TerminalContext
->DevicePath
);
156 FreePool (TerminalContext
);
159 case BM_HANDLE_CONTEXT_SELECT
:
160 HandleContext
= (BM_HANDLE_CONTEXT
*) MenuEntry
->VariableContext
;
161 FreePool (HandleContext
);
164 case BM_LEGACY_DEV_CONTEXT_SELECT
:
165 LegacyDevContext
= (BM_LEGACY_DEVICE_CONTEXT
*) MenuEntry
->VariableContext
;
166 FreePool (LegacyDevContext
);
172 FreePool (MenuEntry
->DisplayString
);
173 if (MenuEntry
->HelpString
!= NULL
) {
174 FreePool (MenuEntry
->HelpString
);
177 FreePool (MenuEntry
);
181 Get the Menu Entry from the list in Menu Entry List.
183 If MenuNumber is great or equal to the number of Menu
184 Entry in the list, then ASSERT.
186 @param MenuOption The Menu Entry List to read the menu entry.
187 @param MenuNumber The index of Menu Entry.
189 @return The Menu Entry.
194 BM_MENU_OPTION
*MenuOption
,
198 BM_MENU_ENTRY
*NewMenuEntry
;
202 ASSERT (MenuNumber
< MenuOption
->MenuNumber
);
204 List
= MenuOption
->Head
.ForwardLink
;
205 for (Index
= 0; Index
< MenuNumber
; Index
++) {
206 List
= List
->ForwardLink
;
209 NewMenuEntry
= CR (List
, BM_MENU_ENTRY
, Link
, BM_MENU_ENTRY_SIGNATURE
);
215 This function build the FsOptionMenu list which records all
216 available file system in the system. They includes all instances
217 of EFI_SIMPLE_FILE_SYSTEM_PROTOCOL, all instances of EFI_LOAD_FILE_SYSTEM
218 and all type of legacy boot device.
220 @param CallbackData BMM context data
222 @retval EFI_SUCCESS Success find the file system
223 @retval EFI_OUT_OF_RESOURCES Can not create menu entry
227 BOpt_FindFileSystem (
228 IN BMM_CALLBACK_DATA
*CallbackData
231 UINTN NoBlkIoHandles
;
232 UINTN NoSimpleFsHandles
;
233 UINTN NoLoadFileHandles
;
234 EFI_HANDLE
*BlkIoHandle
;
235 EFI_HANDLE
*SimpleFsHandle
;
236 EFI_HANDLE
*LoadFileHandle
;
238 EFI_BLOCK_IO_PROTOCOL
*BlkIo
;
241 BM_MENU_ENTRY
*MenuEntry
;
242 BM_FILE_CONTEXT
*FileContext
;
246 EFI_LEGACY_BIOS_PROTOCOL
*LegacyBios
;
248 BBS_BBS_DEVICE_PATH BbsDevicePathNode
;
249 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
250 BOOLEAN RemovableMedia
;
253 NoSimpleFsHandles
= 0;
254 NoLoadFileHandles
= 0;
256 InitializeListHead (&FsOptionMenu
.Head
);
259 // Locate Handles that support BlockIo protocol
261 Status
= gBS
->LocateHandleBuffer (
263 &gEfiBlockIoProtocolGuid
,
268 if (!EFI_ERROR (Status
)) {
270 for (Index
= 0; Index
< NoBlkIoHandles
; Index
++) {
271 Status
= gBS
->HandleProtocol (
273 &gEfiBlockIoProtocolGuid
,
277 if (EFI_ERROR (Status
)) {
282 // Issue a dummy read to trigger reinstall of BlockIo protocol for removable media
284 if (BlkIo
->Media
->RemovableMedia
) {
285 Buffer
= AllocateZeroPool (BlkIo
->Media
->BlockSize
);
286 if (NULL
== Buffer
) {
287 FreePool (BlkIoHandle
);
288 return EFI_OUT_OF_RESOURCES
;
293 BlkIo
->Media
->MediaId
,
295 BlkIo
->Media
->BlockSize
,
301 FreePool (BlkIoHandle
);
305 // Locate Handles that support Simple File System protocol
307 Status
= gBS
->LocateHandleBuffer (
309 &gEfiSimpleFileSystemProtocolGuid
,
314 if (!EFI_ERROR (Status
)) {
316 // Find all the instances of the File System prototocol
318 for (Index
= 0; Index
< NoSimpleFsHandles
; Index
++) {
319 Status
= gBS
->HandleProtocol (
320 SimpleFsHandle
[Index
],
321 &gEfiBlockIoProtocolGuid
,
324 if (EFI_ERROR (Status
)) {
326 // If no block IO exists assume it's NOT a removable media
328 RemovableMedia
= FALSE
;
331 // If block IO exists check to see if it's remobable media
333 RemovableMedia
= BlkIo
->Media
->RemovableMedia
;
337 // Allocate pool for this load option
339 MenuEntry
= BOpt_CreateMenuEntry (BM_FILE_CONTEXT_SELECT
);
340 if (NULL
== MenuEntry
) {
341 FreePool (SimpleFsHandle
);
342 return EFI_OUT_OF_RESOURCES
;
345 FileContext
= (BM_FILE_CONTEXT
*) MenuEntry
->VariableContext
;
347 FileContext
->Handle
= SimpleFsHandle
[Index
];
348 MenuEntry
->OptionNumber
= Index
;
349 FileContext
->FHandle
= EfiLibOpenRoot (FileContext
->Handle
);
350 if (FileContext
->FHandle
== NULL
) {
351 BOpt_DestroyMenuEntry (MenuEntry
);
355 MenuEntry
->HelpString
= DevicePathToStr (DevicePathFromHandle (FileContext
->Handle
));
356 FileContext
->Info
= EfiLibFileSystemVolumeLabelInfo (FileContext
->FHandle
);
357 FileContext
->FileName
= EfiStrDuplicate (L
"\\");
358 FileContext
->DevicePath
= FileDevicePath (
360 FileContext
->FileName
362 FileContext
->IsDir
= TRUE
;
363 FileContext
->IsRoot
= TRUE
;
364 FileContext
->IsRemovableMedia
= RemovableMedia
;
365 FileContext
->IsLoadFile
= FALSE
;
368 // Get current file system's Volume Label
370 if (FileContext
->Info
== NULL
) {
371 VolumeLabel
= L
"NO FILE SYSTEM INFO";
373 if (FileContext
->Info
->VolumeLabel
== NULL
) {
374 VolumeLabel
= L
"NULL VOLUME LABEL";
376 VolumeLabel
= FileContext
->Info
->VolumeLabel
;
377 if (*VolumeLabel
== 0x0000) {
378 VolumeLabel
= L
"NO VOLUME LABEL";
383 TempStr
= MenuEntry
->HelpString
;
384 MenuEntry
->DisplayString
= AllocateZeroPool (MAX_CHAR
);
385 ASSERT (MenuEntry
->DisplayString
!= NULL
);
387 MenuEntry
->DisplayString
,
394 InsertTailList (&FsOptionMenu
.Head
, &MenuEntry
->Link
);
398 if (NoSimpleFsHandles
!= 0) {
399 FreePool (SimpleFsHandle
);
402 // Searching for handles that support Load File protocol
404 Status
= gBS
->LocateHandleBuffer (
406 &gEfiLoadFileProtocolGuid
,
412 if (!EFI_ERROR (Status
)) {
413 for (Index
= 0; Index
< NoLoadFileHandles
; Index
++) {
414 MenuEntry
= BOpt_CreateMenuEntry (BM_FILE_CONTEXT_SELECT
);
415 if (NULL
== MenuEntry
) {
416 FreePool (LoadFileHandle
);
417 return EFI_OUT_OF_RESOURCES
;
420 FileContext
= (BM_FILE_CONTEXT
*) MenuEntry
->VariableContext
;
421 FileContext
->IsRemovableMedia
= FALSE
;
422 FileContext
->IsLoadFile
= TRUE
;
423 FileContext
->Handle
= LoadFileHandle
[Index
];
424 FileContext
->IsRoot
= TRUE
;
426 FileContext
->DevicePath
= DevicePathFromHandle (FileContext
->Handle
);
427 FileContext
->FileName
= DevicePathToStr (FileContext
->DevicePath
);
429 MenuEntry
->HelpString
= DevicePathToStr (FileContext
->DevicePath
);
431 TempStr
= MenuEntry
->HelpString
;
432 MenuEntry
->DisplayString
= AllocateZeroPool (MAX_CHAR
);
433 ASSERT (MenuEntry
->DisplayString
!= NULL
);
435 MenuEntry
->DisplayString
,
441 MenuEntry
->OptionNumber
= OptionNumber
;
443 InsertTailList (&FsOptionMenu
.Head
, &MenuEntry
->Link
);
447 if (NoLoadFileHandles
!= 0) {
448 FreePool (LoadFileHandle
);
452 // Add Legacy Boot Option Support Here
454 Status
= gBS
->LocateProtocol (
455 &gEfiLegacyBiosProtocolGuid
,
457 (VOID
**) &LegacyBios
459 if (!EFI_ERROR (Status
)) {
461 for (Index
= BBS_TYPE_FLOPPY
; Index
<= BBS_TYPE_EMBEDDED_NETWORK
; Index
++) {
462 MenuEntry
= BOpt_CreateMenuEntry (BM_FILE_CONTEXT_SELECT
);
463 if (NULL
== MenuEntry
) {
464 return EFI_OUT_OF_RESOURCES
;
467 FileContext
= (BM_FILE_CONTEXT
*) MenuEntry
->VariableContext
;
469 FileContext
->IsRemovableMedia
= FALSE
;
470 FileContext
->IsLoadFile
= TRUE
;
471 FileContext
->IsBootLegacy
= TRUE
;
472 DeviceType
= (UINT16
) Index
;
473 BbsDevicePathNode
.Header
.Type
= BBS_DEVICE_PATH
;
474 BbsDevicePathNode
.Header
.SubType
= BBS_BBS_DP
;
475 SetDevicePathNodeLength (
476 &BbsDevicePathNode
.Header
,
477 sizeof (BBS_BBS_DEVICE_PATH
)
479 BbsDevicePathNode
.DeviceType
= DeviceType
;
480 BbsDevicePathNode
.StatusFlag
= 0;
481 BbsDevicePathNode
.String
[0] = 0;
482 DevicePath
= AppendDevicePathNode (
484 (EFI_DEVICE_PATH_PROTOCOL
*) &BbsDevicePathNode
487 FileContext
->DevicePath
= DevicePath
;
488 MenuEntry
->HelpString
= DevicePathToStr (FileContext
->DevicePath
);
490 TempStr
= MenuEntry
->HelpString
;
491 MenuEntry
->DisplayString
= AllocateZeroPool (MAX_CHAR
);
492 ASSERT (MenuEntry
->DisplayString
!= NULL
);
494 MenuEntry
->DisplayString
,
499 MenuEntry
->OptionNumber
= OptionNumber
;
501 InsertTailList (&FsOptionMenu
.Head
, &MenuEntry
->Link
);
505 // Remember how many file system options are here
507 FsOptionMenu
.MenuNumber
= OptionNumber
;
512 Free resources allocated in Allocate Rountine.
514 @param FreeMenu Menu to be freed
518 BM_MENU_OPTION
*FreeMenu
521 BM_MENU_ENTRY
*MenuEntry
;
522 while (!IsListEmpty (&FreeMenu
->Head
)) {
524 FreeMenu
->Head
.ForwardLink
,
527 BM_MENU_ENTRY_SIGNATURE
529 RemoveEntryList (&MenuEntry
->Link
);
530 BOpt_DestroyMenuEntry (MenuEntry
);
535 Find files under current directory
536 All files and sub-directories in current directory
537 will be stored in DirectoryMenu for future use.
539 @param CallbackData The BMM context data.
540 @param MenuEntry The Menu Entry.
542 @retval EFI_SUCCESS Get files from current dir successfully.
543 @return Other value if can't get files from current dir.
548 IN BMM_CALLBACK_DATA
*CallbackData
,
549 IN BM_MENU_ENTRY
*MenuEntry
552 EFI_FILE_HANDLE NewDir
;
554 EFI_FILE_INFO
*DirInfo
;
557 BM_MENU_ENTRY
*NewMenuEntry
;
558 BM_FILE_CONTEXT
*FileContext
;
559 BM_FILE_CONTEXT
*NewFileContext
;
564 FileContext
= (BM_FILE_CONTEXT
*) MenuEntry
->VariableContext
;
565 Dir
= FileContext
->FHandle
;
568 // Open current directory to get files from it
573 FileContext
->FileName
,
577 if (!FileContext
->IsRoot
) {
581 if (EFI_ERROR (Status
)) {
585 DirInfo
= EfiLibFileInfo (NewDir
);
586 if (DirInfo
== NULL
) {
587 return EFI_NOT_FOUND
;
590 if ((DirInfo
->Attribute
& EFI_FILE_DIRECTORY
) == 0) {
591 return EFI_INVALID_PARAMETER
;
594 FileContext
->DevicePath
= FileDevicePath (
596 FileContext
->FileName
599 DirBufferSize
= sizeof (EFI_FILE_INFO
) + 1024;
600 DirInfo
= AllocateZeroPool (DirBufferSize
);
601 if (DirInfo
== NULL
) {
602 return EFI_OUT_OF_RESOURCES
;
605 // Get all files in current directory
606 // Pass 1 to get Directories
607 // Pass 2 to get files that are EFI images
609 for (Pass
= 1; Pass
<= 2; Pass
++) {
610 NewDir
->SetPosition (NewDir
, 0);
612 BufferSize
= DirBufferSize
;
613 Status
= NewDir
->Read (NewDir
, &BufferSize
, DirInfo
);
614 if (EFI_ERROR (Status
) || BufferSize
== 0) {
618 if (((DirInfo
->Attribute
& EFI_FILE_DIRECTORY
) != 0 && Pass
== 2) ||
619 ((DirInfo
->Attribute
& EFI_FILE_DIRECTORY
) == 0 && Pass
== 1)
622 // Pass 1 is for Directories
623 // Pass 2 is for file names
628 if (!(BOpt_IsEfiImageName (DirInfo
->FileName
) || (DirInfo
->Attribute
& EFI_FILE_DIRECTORY
) != 0)) {
630 // Slip file unless it is a directory entry or a .EFI file
635 NewMenuEntry
= BOpt_CreateMenuEntry (BM_FILE_CONTEXT_SELECT
);
636 if (NULL
== NewMenuEntry
) {
637 return EFI_OUT_OF_RESOURCES
;
640 NewFileContext
= (BM_FILE_CONTEXT
*) NewMenuEntry
->VariableContext
;
641 NewFileContext
->Handle
= FileContext
->Handle
;
642 NewFileContext
->FileName
= BOpt_AppendFileName (
643 FileContext
->FileName
,
646 NewFileContext
->FHandle
= NewDir
;
647 NewFileContext
->DevicePath
= FileDevicePath (
648 NewFileContext
->Handle
,
649 NewFileContext
->FileName
651 NewMenuEntry
->HelpString
= NULL
;
653 MenuEntry
->DisplayStringToken
= GetStringTokenFromDepository (
655 FileOptionStrDepository
658 NewFileContext
->IsDir
= (BOOLEAN
) ((DirInfo
->Attribute
& EFI_FILE_DIRECTORY
) == EFI_FILE_DIRECTORY
);
660 if (NewFileContext
->IsDir
) {
661 BufferSize
= StrLen (DirInfo
->FileName
) * 2 + 6;
662 NewMenuEntry
->DisplayString
= AllocateZeroPool (BufferSize
);
665 NewMenuEntry
->DisplayString
,
672 NewMenuEntry
->DisplayString
= EfiStrDuplicate (DirInfo
->FileName
);
675 NewFileContext
->IsRoot
= FALSE
;
676 NewFileContext
->IsLoadFile
= FALSE
;
677 NewFileContext
->IsRemovableMedia
= FALSE
;
679 NewMenuEntry
->OptionNumber
= OptionNumber
;
681 InsertTailList (&DirectoryMenu
.Head
, &NewMenuEntry
->Link
);
685 DirectoryMenu
.MenuNumber
= OptionNumber
;
691 Build the LegacyFDMenu LegacyHDMenu LegacyCDMenu according to LegacyBios.GetBbsInfo().
693 @retval EFI_SUCCESS The function complete successfully.
694 @retval EFI_OUT_OF_RESOURCES No enough memory to complete this function.
698 BOpt_GetLegacyOptions (
702 BM_MENU_ENTRY
*NewMenuEntry
;
703 BM_LEGACY_DEVICE_CONTEXT
*NewLegacyDevContext
;
705 EFI_LEGACY_BIOS_PROTOCOL
*LegacyBios
;
711 CHAR16 DescString
[100];
724 // Initialize Bbs Table Context from BBS info data
726 InitializeListHead (&LegacyFDMenu
.Head
);
727 InitializeListHead (&LegacyHDMenu
.Head
);
728 InitializeListHead (&LegacyCDMenu
.Head
);
729 InitializeListHead (&LegacyNETMenu
.Head
);
730 InitializeListHead (&LegacyBEVMenu
.Head
);
732 Status
= gBS
->LocateProtocol (
733 &gEfiLegacyBiosProtocolGuid
,
735 (VOID
**) &LegacyBios
737 if (!EFI_ERROR (Status
)) {
738 Status
= LegacyBios
->GetBbsInfo (
745 if (EFI_ERROR (Status
)) {
756 for (Index
= 0; Index
< BbsCount
; Index
++) {
757 if ((BBS_IGNORE_ENTRY
== BbsTable
[Index
].BootPriority
) ||
758 (BBS_DO_NOT_BOOT_FROM
== BbsTable
[Index
].BootPriority
)
763 NewMenuEntry
= BOpt_CreateMenuEntry (BM_LEGACY_DEV_CONTEXT_SELECT
);
764 if (NULL
== NewMenuEntry
) {
768 NewLegacyDevContext
= (BM_LEGACY_DEVICE_CONTEXT
*) NewMenuEntry
->VariableContext
;
769 NewLegacyDevContext
->BbsTable
= &BbsTable
[Index
];
770 NewLegacyDevContext
->Index
= Index
;
771 NewLegacyDevContext
->BbsCount
= BbsCount
;
772 BdsBuildLegacyDevNameString (
778 NewLegacyDevContext
->Description
= AllocateZeroPool (StrSize (DescString
));
779 if (NULL
== NewLegacyDevContext
->Description
) {
783 CopyMem (NewLegacyDevContext
->Description
, DescString
, StrSize (DescString
));
784 NewMenuEntry
->DisplayString
= NewLegacyDevContext
->Description
;
785 NewMenuEntry
->HelpString
= NULL
;
787 switch (BbsTable
[Index
].DeviceType
) {
789 InsertTailList (&LegacyFDMenu
.Head
, &NewMenuEntry
->Link
);
794 InsertTailList (&LegacyHDMenu
.Head
, &NewMenuEntry
->Link
);
799 InsertTailList (&LegacyCDMenu
.Head
, &NewMenuEntry
->Link
);
803 case BBS_EMBED_NETWORK
:
804 InsertTailList (&LegacyNETMenu
.Head
, &NewMenuEntry
->Link
);
809 InsertTailList (&LegacyBEVMenu
.Head
, &NewMenuEntry
->Link
);
815 if (Index
!= BbsCount
) {
816 BOpt_FreeLegacyOptions ();
817 return EFI_OUT_OF_RESOURCES
;
820 LegacyFDMenu
.MenuNumber
= FDNum
;
821 LegacyHDMenu
.MenuNumber
= HDNum
;
822 LegacyCDMenu
.MenuNumber
= CDNum
;
823 LegacyNETMenu
.MenuNumber
= NETNum
;
824 LegacyBEVMenu
.MenuNumber
= BEVNum
;
829 Free out resouce allocated from Legacy Boot Options.
833 BOpt_FreeLegacyOptions (
837 BOpt_FreeMenu (&LegacyFDMenu
);
838 BOpt_FreeMenu (&LegacyHDMenu
);
839 BOpt_FreeMenu (&LegacyCDMenu
);
840 BOpt_FreeMenu (&LegacyNETMenu
);
841 BOpt_FreeMenu (&LegacyBEVMenu
);
846 Build the BootOptionMenu according to BootOrder Variable.
847 This Routine will access the Boot#### to get EFI_LOAD_OPTION.
849 @param CallbackData The BMM context data.
851 @return EFI_NOT_FOUND Fail to find "BootOrder" variable.
852 @return EFI_SUCESS Success build boot option menu.
856 BOpt_GetBootOptions (
857 IN BMM_CALLBACK_DATA
*CallbackData
861 UINT16 BootString
[10];
862 UINT8
*LoadOptionFromVar
;
864 UINTN BootOptionSize
;
865 BOOLEAN BootNextFlag
;
866 UINT16
*BootOrderList
;
867 UINTN BootOrderListSize
;
870 BM_MENU_ENTRY
*NewMenuEntry
;
871 BM_LOAD_CONTEXT
*NewLoadContext
;
872 UINT8
*LoadOptionPtr
;
874 UINTN OptionalDataSize
;
875 UINT8
*LoadOptionEnd
;
876 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
879 UINTN DevicePathType
;
883 BootOrderListSize
= 0;
885 BootOrderList
= NULL
;
887 LoadOptionFromVar
= NULL
;
888 BOpt_FreeMenu (&BootOptionMenu
);
889 InitializeListHead (&BootOptionMenu
.Head
);
892 // Get the BootOrder from the Var
894 BootOrderList
= BdsLibGetVariableAndSize (
896 &gEfiGlobalVariableGuid
,
899 if (BootOrderList
== NULL
) {
900 return EFI_NOT_FOUND
;
904 // Get the BootNext from the Var
906 BootNext
= BdsLibGetVariableAndSize (
908 &gEfiGlobalVariableGuid
,
912 if (BootNext
!= NULL
) {
913 if (BootNextSize
!= sizeof (UINT16
)) {
919 for (Index
= 0; Index
< BootOrderListSize
/ sizeof (UINT16
); Index
++) {
920 UnicodeSPrint (BootString
, sizeof (BootString
), L
"Boot%04x", BootOrderList
[Index
]);
922 // Get all loadoptions from the VAR
924 LoadOptionFromVar
= BdsLibGetVariableAndSize (
926 &gEfiGlobalVariableGuid
,
929 if (LoadOptionFromVar
== NULL
) {
933 LoadOption
= AllocateZeroPool (BootOptionSize
);
934 if (LoadOption
== NULL
) {
938 CopyMem (LoadOption
, LoadOptionFromVar
, BootOptionSize
);
939 FreePool (LoadOptionFromVar
);
941 if (BootNext
!= NULL
) {
942 BootNextFlag
= (BOOLEAN
) (*BootNext
== BootOrderList
[Index
]);
944 BootNextFlag
= FALSE
;
947 if (0 == (*((UINT32
*) LoadOption
) & LOAD_OPTION_ACTIVE
)) {
948 FreePool (LoadOption
);
952 // BUGBUG: could not return EFI_OUT_OF_RESOURCES here directly.
953 // the buffer allocated already should be freed before returning.
955 NewMenuEntry
= BOpt_CreateMenuEntry (BM_LOAD_CONTEXT_SELECT
);
956 if (NULL
== NewMenuEntry
) {
957 return EFI_OUT_OF_RESOURCES
;
960 NewLoadContext
= (BM_LOAD_CONTEXT
*) NewMenuEntry
->VariableContext
;
962 LoadOptionPtr
= LoadOption
;
963 LoadOptionEnd
= LoadOption
+ BootOptionSize
;
965 NewMenuEntry
->OptionNumber
= BootOrderList
[Index
];
966 NewLoadContext
->LoadOptionModified
= FALSE
;
967 NewLoadContext
->Deleted
= FALSE
;
968 NewLoadContext
->IsBootNext
= BootNextFlag
;
971 // Is a Legacy Device?
973 Ptr
= (UINT8
*) LoadOption
;
976 // Attribute = *(UINT32 *)Ptr;
978 Ptr
+= sizeof (UINT32
);
981 // FilePathSize = *(UINT16 *)Ptr;
983 Ptr
+= sizeof (UINT16
);
986 // Description = (CHAR16 *)Ptr;
988 Ptr
+= StrSize ((CHAR16
*) Ptr
);
991 // Now Ptr point to Device Path
993 DevicePath
= (EFI_DEVICE_PATH_PROTOCOL
*) Ptr
;
994 if ((BBS_DEVICE_PATH
== DevicePath
->Type
) && (BBS_BBS_DP
== DevicePath
->SubType
)) {
995 NewLoadContext
->IsLegacy
= TRUE
;
997 NewLoadContext
->IsLegacy
= FALSE
;
1000 // LoadOption is a pointer type of UINT8
1001 // for easy use with following LOAD_OPTION
1002 // embedded in this struct
1004 NewLoadContext
->LoadOption
= LoadOption
;
1005 NewLoadContext
->LoadOptionSize
= BootOptionSize
;
1007 NewLoadContext
->Attributes
= *(UINT32
*) LoadOptionPtr
;
1008 NewLoadContext
->IsActive
= (BOOLEAN
) (NewLoadContext
->Attributes
& LOAD_OPTION_ACTIVE
);
1010 NewLoadContext
->ForceReconnect
= (BOOLEAN
) (NewLoadContext
->Attributes
& LOAD_OPTION_FORCE_RECONNECT
);
1012 LoadOptionPtr
+= sizeof (UINT32
);
1014 NewLoadContext
->FilePathListLength
= *(UINT16
*) LoadOptionPtr
;
1015 LoadOptionPtr
+= sizeof (UINT16
);
1017 StringSize
= StrSize((UINT16
*)LoadOptionPtr
);
1019 // Get Hii description string according to device path type
1022 DevicePathType
= BdsGetBootTypeFromDevicePath (DevicePath
);
1023 switch (DevicePathType
) {
1024 case BDS_EFI_ACPI_FLOPPY_BOOT
:
1025 HiiString
= GetStringById (STRING_TOKEN (STR_DESCRIPTION_FLOPPY
));
1027 case BDS_EFI_MESSAGE_SATA_BOOT
:
1028 case BDS_EFI_MESSAGE_ATAPI_BOOT
:
1029 case BDS_EFI_MEDIA_CDROM_BOOT
:
1030 HiiString
= GetStringById (STRING_TOKEN (STR_DESCRIPTION_DVD
));
1032 case BDS_EFI_MESSAGE_USB_DEVICE_BOOT
:
1033 HiiString
= GetStringById (STRING_TOKEN (STR_DESCRIPTION_USB
));
1035 case BDS_EFI_MESSAGE_SCSI_BOOT
:
1036 HiiString
= GetStringById (STRING_TOKEN (STR_DESCRIPTION_SCSI
));
1038 case BDS_EFI_MESSAGE_MISC_BOOT
:
1039 HiiString
= GetStringById (STRING_TOKEN (STR_DESCRIPTION_MISC
));
1041 case BDS_EFI_MESSAGE_MAC_BOOT
:
1042 HiiString
= GetStringById (STRING_TOKEN (STR_DESCRIPTION_NETWORK
));
1044 case BBS_DEVICE_PATH
:
1046 // Do nothing for legacy boot option.
1050 DEBUG((EFI_D_INFO
, "Can not find HiiString for given device path type 0x%x\n", DevicePathType
));
1053 if (HiiString
!= NULL
) {
1054 NewLoadContext
->Description
= AllocateZeroPool(StringSize
+ StrSize(HiiString
));
1055 ASSERT (NewLoadContext
->Description
!= NULL
);
1056 StrCpy (NewLoadContext
->Description
, HiiString
);
1057 if (StrnCmp ((UINT16
*)LoadOptionPtr
, L
"0", 1) != 0) {
1058 StrCat (NewLoadContext
->Description
, L
" ");
1059 StrCat (NewLoadContext
->Description
, (UINT16
*)LoadOptionPtr
);
1062 FreePool (HiiString
);
1064 NewLoadContext
->Description
= AllocateZeroPool (StrSize((UINT16
*)LoadOptionPtr
));
1065 StrCpy(NewLoadContext
->Description
, (UINT16
*)LoadOptionPtr
);
1068 ASSERT (NewLoadContext
->Description
!= NULL
);
1069 NewMenuEntry
->DisplayString
= NewLoadContext
->Description
;
1071 LoadOptionPtr
+= StringSize
;
1073 NewLoadContext
->FilePathList
= AllocateZeroPool (NewLoadContext
->FilePathListLength
);
1074 ASSERT (NewLoadContext
->FilePathList
!= NULL
);
1076 NewLoadContext
->FilePathList
,
1077 (EFI_DEVICE_PATH_PROTOCOL
*) LoadOptionPtr
,
1078 NewLoadContext
->FilePathListLength
1081 NewMenuEntry
->HelpString
= DevicePathToStr (NewLoadContext
->FilePathList
);
1082 NewMenuEntry
->DisplayStringToken
= GetStringTokenFromDepository (
1084 BootOptionStrDepository
1086 NewMenuEntry
->HelpStringToken
= GetStringTokenFromDepository (
1088 BootOptionHelpStrDepository
1090 LoadOptionPtr
+= NewLoadContext
->FilePathListLength
;
1092 if (LoadOptionPtr
< LoadOptionEnd
) {
1093 OptionalDataSize
= BootOptionSize
-
1097 NewLoadContext
->FilePathListLength
;
1099 NewLoadContext
->OptionalData
= AllocateZeroPool (OptionalDataSize
);
1100 ASSERT (NewLoadContext
->OptionalData
!= NULL
);
1102 NewLoadContext
->OptionalData
,
1107 NewLoadContext
->OptionalDataSize
= OptionalDataSize
;
1110 InsertTailList (&BootOptionMenu
.Head
, &NewMenuEntry
->Link
);
1114 if (BootNext
!= NULL
) {
1115 FreePool (BootNext
);
1117 if (BootOrderList
!= NULL
) {
1118 FreePool (BootOrderList
);
1120 BootOptionMenu
.MenuNumber
= MenuCount
;
1126 Append file name to existing file name.
1128 @param Str1 The existing file name
1129 @param Str2 The file name to be appended
1131 @return Allocate a new string to hold the appended result.
1132 Caller is responsible to free the returned string.
1136 BOpt_AppendFileName (
1148 Size1
= StrSize (Str1
);
1149 Size2
= StrSize (Str2
);
1150 Str
= AllocateZeroPool (Size1
+ Size2
+ sizeof (CHAR16
));
1151 ASSERT (Str
!= NULL
);
1153 TmpStr
= AllocateZeroPool (Size1
+ Size2
+ sizeof (CHAR16
));
1154 ASSERT (TmpStr
!= NULL
);
1157 if (!((*Str
== '\\') && (*(Str
+ 1) == 0))) {
1158 StrCat (Str
, L
"\\");
1166 if (*Ptr
== '\\' && *(Ptr
+ 1) == '.' && *(Ptr
+ 2) == '.' && *(Ptr
+ 3) == L
'\\') {
1168 // Convert "\Name\..\" to "\"
1169 // DO NOT convert the .. if it is at the end of the string. This will
1170 // break the .. behavior in changing directories.
1174 // Use TmpStr as a backup, as StrCpy in BaseLib does not handle copy of two strings
1177 StrCpy (TmpStr
, Ptr
+ 3);
1178 StrCpy (LastSlash
, TmpStr
);
1180 } else if (*Ptr
== '\\' && *(Ptr
+ 1) == '.' && *(Ptr
+ 2) == '\\') {
1182 // Convert a "\.\" to a "\"
1186 // Use TmpStr as a backup, as StrCpy in BaseLib does not handle copy of two strings
1189 StrCpy (TmpStr
, Ptr
+ 2);
1190 StrCpy (Ptr
, TmpStr
);
1192 } else if (*Ptr
== '\\') {
1206 Check whether current FileName point to a valid
1209 @param FileName File need to be checked.
1211 @retval TRUE Is Efi Image
1212 @retval FALSE Not a valid Efi Image
1216 BOpt_IsEfiImageName (
1221 // Search for ".efi" extension
1223 while (*FileName
!= L
'\0') {
1224 if (FileName
[0] == '.') {
1225 if (FileName
[1] == 'e' || FileName
[1] == 'E') {
1226 if (FileName
[2] == 'f' || FileName
[2] == 'F') {
1227 if (FileName
[3] == 'i' || FileName
[3] == 'I') {
1229 } else if (FileName
[3] == 0x0000) {
1232 } else if (FileName
[2] == 0x0000) {
1235 } else if (FileName
[1] == 0x0000) {
1248 Check whether current FileName point to a valid Efi Application
1250 @param Dir Pointer to current Directory
1251 @param FileName Pointer to current File name.
1253 @retval TRUE Is a valid Efi Application
1254 @retval FALSE not a valid Efi Application
1259 IN EFI_FILE_HANDLE Dir
,
1264 EFI_IMAGE_DOS_HEADER DosHdr
;
1266 EFI_FILE_HANDLE File
;
1268 EFI_IMAGE_OPTIONAL_HEADER_UNION PeHdr
;
1270 Status
= Dir
->Open (Dir
, &File
, FileName
, EFI_FILE_MODE_READ
, 0);
1272 if (EFI_ERROR (Status
)) {
1276 BufferSize
= sizeof (EFI_IMAGE_DOS_HEADER
);
1277 File
->Read (File
, &BufferSize
, &DosHdr
);
1278 if (DosHdr
.e_magic
!= EFI_IMAGE_DOS_SIGNATURE
) {
1283 File
->SetPosition (File
, DosHdr
.e_lfanew
);
1284 BufferSize
= sizeof (EFI_IMAGE_OPTIONAL_HEADER_UNION
);
1285 File
->Read (File
, &BufferSize
, &PeHdr
);
1286 if (PeHdr
.Pe32
.Signature
!= EFI_IMAGE_NT_SIGNATURE
) {
1291 // Determine PE type and read subsytem
1293 if (PeHdr
.Pe32
.OptionalHeader
.Magic
== EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC
) {
1294 Subsystem
= PeHdr
.Pe32
.OptionalHeader
.Subsystem
;
1295 } else if (PeHdr
.Pe32
.OptionalHeader
.Magic
== EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC
) {
1296 Subsystem
= PeHdr
.Pe32Plus
.OptionalHeader
.Subsystem
;
1301 if (Subsystem
== EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION
) {
1312 Find drivers that will be added as Driver#### variables from handles
1313 in current system environment
1314 All valid handles in the system except those consume SimpleFs, LoadFile
1315 are stored in DriverMenu for future use.
1317 @retval EFI_SUCCESS The function complets successfully.
1318 @return Other value if failed to build the DriverMenu.
1326 UINTN NoDevicePathHandles
;
1327 EFI_HANDLE
*DevicePathHandle
;
1330 BM_MENU_ENTRY
*NewMenuEntry
;
1331 BM_HANDLE_CONTEXT
*NewHandleContext
;
1332 EFI_HANDLE CurHandle
;
1334 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
*SimpleFs
;
1335 EFI_LOAD_FILE_PROTOCOL
*LoadFile
;
1340 InitializeListHead (&DriverMenu
.Head
);
1343 // At first, get all handles that support Device Path
1344 // protocol which is the basic requirement for
1347 Status
= gBS
->LocateHandleBuffer (
1349 &gEfiDevicePathProtocolGuid
,
1351 &NoDevicePathHandles
,
1354 if (EFI_ERROR (Status
)) {
1359 for (Index
= 0; Index
< NoDevicePathHandles
; Index
++) {
1360 CurHandle
= DevicePathHandle
[Index
];
1362 Status
= gBS
->HandleProtocol (
1364 &gEfiSimpleFileSystemProtocolGuid
,
1367 if (Status
== EFI_SUCCESS
) {
1371 Status
= gBS
->HandleProtocol (
1373 &gEfiLoadFileProtocolGuid
,
1376 if (Status
== EFI_SUCCESS
) {
1380 NewMenuEntry
= BOpt_CreateMenuEntry (BM_HANDLE_CONTEXT_SELECT
);
1381 if (NULL
== NewMenuEntry
) {
1382 FreePool (DevicePathHandle
);
1383 return EFI_OUT_OF_RESOURCES
;
1386 NewHandleContext
= (BM_HANDLE_CONTEXT
*) NewMenuEntry
->VariableContext
;
1387 NewHandleContext
->Handle
= CurHandle
;
1388 NewHandleContext
->DevicePath
= DevicePathFromHandle (CurHandle
);
1389 NewMenuEntry
->DisplayString
= DevicePathToStr (NewHandleContext
->DevicePath
);
1390 NewMenuEntry
->HelpString
= NULL
;
1391 NewMenuEntry
->OptionNumber
= OptionNumber
;
1393 InsertTailList (&DriverMenu
.Head
, &NewMenuEntry
->Link
);
1397 if (DevicePathHandle
!= NULL
) {
1398 FreePool (DevicePathHandle
);
1401 DriverMenu
.MenuNumber
= OptionNumber
;
1407 Get the Option Number that has not been allocated for use.
1409 @return The available Option Number.
1413 BOpt_GetBootOptionNumber (
1417 BM_MENU_ENTRY
*NewMenuEntry
;
1418 UINT16
*BootOrderList
;
1419 UINTN BootOrderListSize
;
1424 CHAR16 StrTemp
[100];
1425 UINT16
*OptionBuffer
;
1428 BootOrderListSize
= 0;
1429 BootOrderList
= NULL
;
1431 BootOrderList
= BdsLibGetVariableAndSize (
1433 &gEfiGlobalVariableGuid
,
1436 if (BootOrderList
!= NULL
) {
1438 // already have Boot####
1440 // AlreadyBootNumbers = BootOrderListSize / sizeof(UINT16);
1442 for (Index
= 0; Index
< BootOrderListSize
/ sizeof (UINT16
); Index
++) {
1444 for (Index2
= 0; Index2
< BootOptionMenu
.MenuNumber
; Index2
++) {
1445 NewMenuEntry
= BOpt_GetMenuEntry (&BootOptionMenu
, Index2
);
1446 if (Index
== NewMenuEntry
->OptionNumber
) {
1453 UnicodeSPrint (StrTemp
, 100, L
"Boot%04x", Index
);
1454 DEBUG((DEBUG_ERROR
,"INdex= %s\n", StrTemp
));
1455 OptionBuffer
= BdsLibGetVariableAndSize (
1457 &gEfiGlobalVariableGuid
,
1460 if (NULL
== OptionBuffer
) {
1468 Number
= (UINT16
) Index
;
1481 Get the Option Number that is not in use.
1483 @return The unused Option Number.
1487 BOpt_GetDriverOptionNumber (
1491 BM_MENU_ENTRY
*NewMenuEntry
;
1492 UINT16
*DriverOrderList
;
1493 UINTN DriverOrderListSize
;
1499 DriverOrderListSize
= 0;
1500 DriverOrderList
= NULL
;
1502 DriverOrderList
= BdsLibGetVariableAndSize (
1504 &gEfiGlobalVariableGuid
,
1505 &DriverOrderListSize
1507 if (DriverOrderList
!= NULL
) {
1509 // already have Driver####
1511 // AlreadyDriverNumbers = DriverOrderListSize / sizeof(UINT16);
1513 for (Index
= 0; Index
< DriverOrderListSize
/ sizeof (UINT16
); Index
++) {
1515 for (Index2
= 0; Index2
< DriverOptionMenu
.MenuNumber
; Index2
++) {
1516 NewMenuEntry
= BOpt_GetMenuEntry (&DriverOptionMenu
, Index2
);
1517 if (Index
== NewMenuEntry
->OptionNumber
) {
1530 Number
= (UINT16
) Index
;
1543 Build up all DriverOptionMenu
1545 @param CallbackData The BMM context data.
1547 @retval EFI_SUCESS The functin completes successfully.
1548 @retval EFI_OUT_OF_RESOURCES Not enough memory to compete the operation.
1549 @retval EFI_NOT_FOUND Fail to get "DriverOrder" variable.
1553 BOpt_GetDriverOptions (
1554 IN BMM_CALLBACK_DATA
*CallbackData
1558 UINT16 DriverString
[12];
1559 UINT8
*LoadOptionFromVar
;
1561 UINTN DriverOptionSize
;
1563 UINT16
*DriverOrderList
;
1564 UINTN DriverOrderListSize
;
1565 BM_MENU_ENTRY
*NewMenuEntry
;
1566 BM_LOAD_CONTEXT
*NewLoadContext
;
1567 UINT8
*LoadOptionPtr
;
1569 UINTN OptionalDataSize
;
1570 UINT8
*LoadOptionEnd
;
1572 DriverOrderListSize
= 0;
1573 DriverOrderList
= NULL
;
1574 DriverOptionSize
= 0;
1575 LoadOptionFromVar
= NULL
;
1576 BOpt_FreeMenu (&DriverOptionMenu
);
1577 InitializeListHead (&DriverOptionMenu
.Head
);
1579 // Get the DriverOrder from the Var
1581 DriverOrderList
= BdsLibGetVariableAndSize (
1583 &gEfiGlobalVariableGuid
,
1584 &DriverOrderListSize
1586 if (DriverOrderList
== NULL
) {
1587 return EFI_NOT_FOUND
;
1590 for (Index
= 0; Index
< DriverOrderListSize
/ sizeof (UINT16
); Index
++) {
1593 sizeof (DriverString
),
1595 DriverOrderList
[Index
]
1598 // Get all loadoptions from the VAR
1600 LoadOptionFromVar
= BdsLibGetVariableAndSize (
1602 &gEfiGlobalVariableGuid
,
1605 if (LoadOptionFromVar
== NULL
) {
1609 LoadOption
= AllocateZeroPool (DriverOptionSize
);
1610 if (LoadOption
== NULL
) {
1614 CopyMem (LoadOption
, LoadOptionFromVar
, DriverOptionSize
);
1615 FreePool (LoadOptionFromVar
);
1617 NewMenuEntry
= BOpt_CreateMenuEntry (BM_LOAD_CONTEXT_SELECT
);
1618 if (NULL
== NewMenuEntry
) {
1619 return EFI_OUT_OF_RESOURCES
;
1622 NewLoadContext
= (BM_LOAD_CONTEXT
*) NewMenuEntry
->VariableContext
;
1623 LoadOptionPtr
= LoadOption
;
1624 LoadOptionEnd
= LoadOption
+ DriverOptionSize
;
1625 NewMenuEntry
->OptionNumber
= DriverOrderList
[Index
];
1626 NewLoadContext
->LoadOptionModified
= FALSE
;
1627 NewLoadContext
->Deleted
= FALSE
;
1628 NewLoadContext
->IsLegacy
= FALSE
;
1631 // LoadOption is a pointer type of UINT8
1632 // for easy use with following LOAD_OPTION
1633 // embedded in this struct
1635 NewLoadContext
->LoadOption
= LoadOption
;
1636 NewLoadContext
->LoadOptionSize
= DriverOptionSize
;
1638 NewLoadContext
->Attributes
= *(UINT32
*) LoadOptionPtr
;
1639 NewLoadContext
->IsActive
= (BOOLEAN
) (NewLoadContext
->Attributes
& LOAD_OPTION_ACTIVE
);
1641 NewLoadContext
->ForceReconnect
= (BOOLEAN
) (NewLoadContext
->Attributes
& LOAD_OPTION_FORCE_RECONNECT
);
1643 LoadOptionPtr
+= sizeof (UINT32
);
1645 NewLoadContext
->FilePathListLength
= *(UINT16
*) LoadOptionPtr
;
1646 LoadOptionPtr
+= sizeof (UINT16
);
1648 StringSize
= StrSize ((UINT16
*) LoadOptionPtr
);
1649 NewLoadContext
->Description
= AllocateZeroPool (StringSize
);
1650 ASSERT (NewLoadContext
->Description
!= NULL
);
1652 NewLoadContext
->Description
,
1653 (UINT16
*) LoadOptionPtr
,
1656 NewMenuEntry
->DisplayString
= NewLoadContext
->Description
;
1658 LoadOptionPtr
+= StringSize
;
1660 NewLoadContext
->FilePathList
= AllocateZeroPool (NewLoadContext
->FilePathListLength
);
1661 ASSERT (NewLoadContext
->FilePathList
!= NULL
);
1663 NewLoadContext
->FilePathList
,
1664 (EFI_DEVICE_PATH_PROTOCOL
*) LoadOptionPtr
,
1665 NewLoadContext
->FilePathListLength
1668 NewMenuEntry
->HelpString
= DevicePathToStr (NewLoadContext
->FilePathList
);
1669 NewMenuEntry
->DisplayStringToken
= GetStringTokenFromDepository (
1671 DriverOptionStrDepository
1673 NewMenuEntry
->HelpStringToken
= GetStringTokenFromDepository (
1675 DriverOptionHelpStrDepository
1677 LoadOptionPtr
+= NewLoadContext
->FilePathListLength
;
1679 if (LoadOptionPtr
< LoadOptionEnd
) {
1680 OptionalDataSize
= DriverOptionSize
-
1684 NewLoadContext
->FilePathListLength
;
1686 NewLoadContext
->OptionalData
= AllocateZeroPool (OptionalDataSize
);
1687 ASSERT (NewLoadContext
->OptionalData
!= NULL
);
1689 NewLoadContext
->OptionalData
,
1694 NewLoadContext
->OptionalDataSize
= OptionalDataSize
;
1697 InsertTailList (&DriverOptionMenu
.Head
, &NewMenuEntry
->Link
);
1701 if (DriverOrderList
!= NULL
) {
1702 FreePool (DriverOrderList
);
1704 DriverOptionMenu
.MenuNumber
= Index
;