3 Copyright (c) 2006, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 Variable operation that will be used by bootmaint
22 #include "Generic/Bds.h"
23 #include "bootmaint.h"
24 #include "bdsplatform.h"
33 Delete Boot Option that represent a Deleted state in BootOptionMenu.
34 After deleting this boot option, call Var_ChangeBootOrder to
35 make sure BootOrder is in valid state.
38 LoadOption -- Pointer to the boot option that to be deleted
46 BM_MENU_ENTRY
*NewMenuEntry
;
47 BM_LOAD_CONTEXT
*NewLoadContext
;
49 UINT16 BootString
[10];
56 for (Index
= 0; Index
< BootOptionMenu
.MenuNumber
; Index
++) {
57 NewMenuEntry
= BOpt_GetMenuEntry (&BootOptionMenu
, (Index
- Index2
));
58 if (NULL
== NewMenuEntry
) {
62 NewLoadContext
= (BM_LOAD_CONTEXT
*) NewMenuEntry
->VariableContext
;
63 if (!NewLoadContext
->Deleted
) {
71 NewMenuEntry
->OptionNumber
74 EfiLibDeleteVariable (BootString
, &gEfiGlobalVariableGuid
);
77 // If current Load Option is the same as BootNext,
78 // must delete BootNext in order to make sure
79 // there will be no panic on next boot
81 if (NewLoadContext
->IsBootNext
) {
82 EfiLibDeleteVariable (L
"BootNext", &gEfiGlobalVariableGuid
);
85 RemoveEntryList (&NewMenuEntry
->Link
);
86 BOpt_DestroyMenuEntry (NewMenuEntry
);
90 BootOptionMenu
.MenuNumber
-= Index2
;
92 Status
= Var_ChangeBootOrder ();
103 After any operation on Boot####, there will be a discrepancy in BootOrder.
104 Since some are missing but in BootOrder, while some are present but are
105 not reflected by BootOrder. Then a function rebuild BootOrder from
106 scratch by content from BootOptionMenu is needed.
118 BM_MENU_ENTRY
*NewMenuEntry
;
119 UINT16
*BootOrderList
;
120 UINT16
*BootOrderListPtr
;
121 UINTN BootOrderListSize
;
124 BootOrderList
= NULL
;
125 BootOrderListSize
= 0;
128 // First check whether BootOrder is present in current configuration
130 BootOrderList
= BdsLibGetVariableAndSize (
132 &gEfiGlobalVariableGuid
,
137 // If exists, delete it to hold new BootOrder
140 EfiLibDeleteVariable (L
"BootOrder", &gEfiGlobalVariableGuid
);
141 SafeFreePool (BootOrderList
);
142 BootOrderList
= NULL
;
145 // Maybe here should be some check method to ensure that
146 // no new added boot options will be added
147 // but the setup engine now will give only one callback
148 // that is to say, user are granted only one chance to
149 // decide whether the boot option will be added or not
150 // there should be no indictor to show whether this
151 // is a "new" boot option
153 BootOrderListSize
= BootOptionMenu
.MenuNumber
;
155 if (BootOrderListSize
> 0) {
156 BootOrderList
= AllocateZeroPool (BootOrderListSize
* sizeof (UINT16
));
157 ASSERT (BootOrderList
!= NULL
);
158 BootOrderListPtr
= BootOrderList
;
161 // Get all current used Boot#### from BootOptionMenu.
162 // OptionNumber in each BM_LOAD_OPTION is really its
165 for (Index
= 0; Index
< BootOrderListSize
; Index
++) {
166 NewMenuEntry
= BOpt_GetMenuEntry (&BootOptionMenu
, Index
);
167 *BootOrderList
= (UINT16
) NewMenuEntry
->OptionNumber
;
171 BootOrderList
= BootOrderListPtr
;
174 // After building the BootOrderList, write it back
176 Status
= gRT
->SetVariable (
178 &gEfiGlobalVariableGuid
,
180 BootOrderListSize
* sizeof (UINT16
),
183 if (EFI_ERROR (Status
)) {
191 Var_DelDriverOption (
197 Delete Load Option that represent a Deleted state in BootOptionMenu.
198 After deleting this Driver option, call Var_ChangeDriverOrder to
199 make sure DriverOrder is in valid state.
202 LoadOption -- Pointer to the Driver option that to be deleted
210 BM_MENU_ENTRY
*NewMenuEntry
;
211 BM_LOAD_CONTEXT
*NewLoadContext
;
213 UINT16 DriverString
[12];
218 Status
= EFI_SUCCESS
;
220 for (Index
= 0; Index
< DriverOptionMenu
.MenuNumber
; Index
++) {
221 NewMenuEntry
= BOpt_GetMenuEntry (&DriverOptionMenu
, (Index
- Index2
));
222 if (NULL
== NewMenuEntry
) {
223 return EFI_NOT_FOUND
;
226 NewLoadContext
= (BM_LOAD_CONTEXT
*) NewMenuEntry
->VariableContext
;
227 if (!NewLoadContext
->Deleted
) {
233 sizeof (DriverString
),
235 NewMenuEntry
->OptionNumber
238 EfiLibDeleteVariable (DriverString
, &gEfiGlobalVariableGuid
);
241 RemoveEntryList (&NewMenuEntry
->Link
);
242 BOpt_DestroyMenuEntry (NewMenuEntry
);
246 DriverOptionMenu
.MenuNumber
-= Index2
;
248 Status
= Var_ChangeDriverOrder ();
253 Var_ChangeDriverOrder (
259 After any operation on Driver####, there will be a discrepancy in
260 DriverOrder. Since some are missing but in DriverOrder, while some
261 are present but are not reflected by DriverOrder. Then a function
262 rebuild DriverOrder from scratch by content from DriverOptionMenu is
274 BM_MENU_ENTRY
*NewMenuEntry
;
275 UINT16
*DriverOrderList
;
276 UINT16
*DriverOrderListPtr
;
277 UINTN DriverOrderListSize
;
280 DriverOrderList
= NULL
;
281 DriverOrderListSize
= 0;
284 // First check whether DriverOrder is present in current configuration
286 DriverOrderList
= BdsLibGetVariableAndSize (
288 &gEfiGlobalVariableGuid
,
293 // If exists, delete it to hold new DriverOrder
295 if (DriverOrderList
) {
296 EfiLibDeleteVariable (L
"DriverOrder", &gEfiGlobalVariableGuid
);
297 SafeFreePool (DriverOrderList
);
298 DriverOrderList
= NULL
;
301 DriverOrderListSize
= DriverOptionMenu
.MenuNumber
;
303 if (DriverOrderListSize
> 0) {
304 DriverOrderList
= AllocateZeroPool (DriverOrderListSize
* sizeof (UINT16
));
305 ASSERT (DriverOrderList
!= NULL
);
306 DriverOrderListPtr
= DriverOrderList
;
309 // Get all current used Driver#### from DriverOptionMenu.
310 // OptionNumber in each BM_LOAD_OPTION is really its
313 for (Index
= 0; Index
< DriverOrderListSize
; Index
++) {
314 NewMenuEntry
= BOpt_GetMenuEntry (&DriverOptionMenu
, Index
);
315 *DriverOrderList
= (UINT16
) NewMenuEntry
->OptionNumber
;
319 DriverOrderList
= DriverOrderListPtr
;
322 // After building the DriverOrderList, write it back
324 Status
= gRT
->SetVariable (
326 &gEfiGlobalVariableGuid
,
328 DriverOrderListSize
* sizeof (UINT16
),
331 if (EFI_ERROR (Status
)) {
339 Var_UpdateAllConsoleOption (
343 EFI_DEVICE_PATH_PROTOCOL
*OutDevicePath
;
344 EFI_DEVICE_PATH_PROTOCOL
*InpDevicePath
;
345 EFI_DEVICE_PATH_PROTOCOL
*ErrDevicePath
;
348 OutDevicePath
= EfiLibGetVariable (L
"ConOut", &gEfiGlobalVariableGuid
);
349 InpDevicePath
= EfiLibGetVariable (L
"ConIn", &gEfiGlobalVariableGuid
);
350 ErrDevicePath
= EfiLibGetVariable (L
"ErrOut", &gEfiGlobalVariableGuid
);
352 ChangeVariableDevicePath (OutDevicePath
);
353 Status
= gRT
->SetVariable (
355 &gEfiGlobalVariableGuid
,
357 GetDevicePathSize (OutDevicePath
),
360 ASSERT (!EFI_ERROR (Status
));
364 ChangeVariableDevicePath (InpDevicePath
);
365 Status
= gRT
->SetVariable (
367 &gEfiGlobalVariableGuid
,
369 GetDevicePathSize (InpDevicePath
),
372 ASSERT (!EFI_ERROR (Status
));
376 ChangeVariableDevicePath (ErrDevicePath
);
377 Status
= gRT
->SetVariable (
379 &gEfiGlobalVariableGuid
,
381 GetDevicePathSize (ErrDevicePath
),
384 ASSERT (!EFI_ERROR (Status
));
389 Var_UpdateConsoleOption (
390 IN UINT16
*ConsoleName
,
391 IN BM_MENU_OPTION
*ConsoleMenu
,
392 IN UINT16 UpdatePageId
395 EFI_DEVICE_PATH_PROTOCOL
*ConDevicePath
;
396 BM_MENU_ENTRY
*NewMenuEntry
;
397 BM_CONSOLE_CONTEXT
*NewConsoleContext
;
398 BM_TERMINAL_CONTEXT
*NewTerminalContext
;
400 VENDOR_DEVICE_PATH Vendor
;
401 EFI_DEVICE_PATH_PROTOCOL
*TerminalDevicePath
;
405 ConDevicePath
= EfiLibGetVariable (ConsoleName
, &gEfiGlobalVariableGuid
);
406 if (ConDevicePath
!= NULL
) {
407 EfiLibDeleteVariable (ConsoleName
, &gEfiGlobalVariableGuid
);
408 SafeFreePool (ConDevicePath
);
409 ConDevicePath
= NULL
;
413 // First add all console input device to it from console input menu
415 for (Index
= 0; Index
< ConsoleMenu
->MenuNumber
; Index
++) {
416 NewMenuEntry
= BOpt_GetMenuEntry (ConsoleMenu
, Index
);
417 if (NULL
== NewMenuEntry
) {
418 return EFI_NOT_FOUND
;
421 NewConsoleContext
= (BM_CONSOLE_CONTEXT
*) NewMenuEntry
->VariableContext
;
422 if (NewConsoleContext
->IsActive
) {
423 ConDevicePath
= AppendDevicePathInstance (
425 NewConsoleContext
->DevicePath
430 for (Index
= 0; Index
< TerminalMenu
.MenuNumber
; Index
++) {
431 NewMenuEntry
= BOpt_GetMenuEntry (&TerminalMenu
, Index
);
432 if (NULL
== NewMenuEntry
) {
433 return EFI_NOT_FOUND
;
436 NewTerminalContext
= (BM_TERMINAL_CONTEXT
*) NewMenuEntry
->VariableContext
;
437 if ((NewTerminalContext
->IsConIn
&& (UpdatePageId
== FORM_CON_IN_ID
)) ||
438 (NewTerminalContext
->IsConOut
&& (UpdatePageId
== FORM_CON_OUT_ID
)) ||
439 (NewTerminalContext
->IsStdErr
&& (UpdatePageId
== FORM_CON_ERR_ID
))
441 Vendor
.Header
.Type
= MESSAGING_DEVICE_PATH
;
442 Vendor
.Header
.SubType
= MSG_VENDOR_DP
;
445 &Guid
[NewTerminalContext
->TerminalType
],
448 SetDevicePathNodeLength (&Vendor
.Header
, sizeof (VENDOR_DEVICE_PATH
));
449 TerminalDevicePath
= AppendDevicePathNode (
450 NewTerminalContext
->DevicePath
,
451 (EFI_DEVICE_PATH_PROTOCOL
*) &Vendor
453 ChangeTerminalDevicePath (TerminalDevicePath
, TRUE
);
454 Temp
= DevicePathToStr (TerminalDevicePath
);
455 ConDevicePath
= AppendDevicePathInstance (
463 Status
= gRT
->SetVariable (
465 &gEfiGlobalVariableGuid
,
467 GetDevicePathSize (ConDevicePath
),
470 if (EFI_ERROR (Status
)) {
480 Var_UpdateConsoleInpOption (
484 return Var_UpdateConsoleOption (L
"ConIn", &ConsoleInpMenu
, FORM_CON_IN_ID
);
488 Var_UpdateConsoleOutOption (
492 return Var_UpdateConsoleOption (L
"ConOut", &ConsoleOutMenu
, FORM_CON_OUT_ID
);
496 Var_UpdateErrorOutOption (
500 return Var_UpdateConsoleOption (L
"ErrOut", &ConsoleErrMenu
, FORM_CON_ERR_ID
);
504 Var_UpdateDriverOption (
505 IN BMM_CALLBACK_DATA
*CallbackData
,
506 IN EFI_HII_HANDLE HiiHandle
,
507 IN UINT16
*DescriptionData
,
508 IN UINT16
*OptionalData
,
509 IN UINT8 ForceReconnect
513 UINT16
*DriverOrderList
;
514 UINT16
*NewDriverOrderList
;
515 UINT16 DriverString
[12];
516 UINTN DriverOrderListSize
;
520 BM_MENU_ENTRY
*NewMenuEntry
;
521 BM_LOAD_CONTEXT
*NewLoadContext
;
522 BOOLEAN OptionalDataExist
;
525 OptionalDataExist
= FALSE
;
527 Index
= BOpt_GetDriverOptionNumber ();
530 sizeof (DriverString
),
535 if (*DescriptionData
== 0x0000) {
536 StrCpy (DescriptionData
, DriverString
);
539 BufferSize
= sizeof (UINT32
) + sizeof (UINT16
) + StrSize (DescriptionData
) + GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
);
541 if (*OptionalData
!= 0x0000) {
542 OptionalDataExist
= TRUE
;
543 BufferSize
+= StrSize (OptionalData
);
546 Buffer
= AllocateZeroPool (BufferSize
);
547 if (NULL
== Buffer
) {
548 return EFI_OUT_OF_RESOURCES
;
551 NewMenuEntry
= BOpt_CreateMenuEntry (BM_LOAD_CONTEXT_SELECT
);
552 if (NULL
== NewMenuEntry
) {
553 return EFI_OUT_OF_RESOURCES
;
556 NewLoadContext
= (BM_LOAD_CONTEXT
*) NewMenuEntry
->VariableContext
;
557 NewLoadContext
->Deleted
= FALSE
;
558 NewLoadContext
->LoadOptionSize
= BufferSize
;
559 Ptr
= (UINT8
*) Buffer
;
560 NewLoadContext
->LoadOption
= Ptr
;
561 *((UINT32
*) Ptr
) = LOAD_OPTION_ACTIVE
| (ForceReconnect
<< 1);
562 NewLoadContext
->Attributes
= *((UINT32
*) Ptr
);
563 NewLoadContext
->IsActive
= TRUE
;
564 NewLoadContext
->ForceReconnect
= (BOOLEAN
) (NewLoadContext
->Attributes
& LOAD_OPTION_FORCE_RECONNECT
);
566 Ptr
+= sizeof (UINT32
);
567 *((UINT16
*) Ptr
) = (UINT16
) GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
);
568 NewLoadContext
->FilePathListLength
= *((UINT16
*) Ptr
);
570 Ptr
+= sizeof (UINT16
);
574 StrSize (DescriptionData
)
577 NewLoadContext
->Description
= AllocateZeroPool (StrSize (DescriptionData
));
578 ASSERT (NewLoadContext
->Description
!= NULL
);
579 NewMenuEntry
->DisplayString
= NewLoadContext
->Description
;
581 NewLoadContext
->Description
,
583 StrSize (DescriptionData
)
586 Ptr
+= StrSize (DescriptionData
);
589 CallbackData
->LoadContext
->FilePathList
,
590 GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
)
593 NewLoadContext
->FilePathList
= AllocateZeroPool (GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
));
594 ASSERT (NewLoadContext
->FilePathList
!= NULL
);
597 NewLoadContext
->FilePathList
,
599 GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
)
602 NewMenuEntry
->HelpString
= DevicePathToStr (NewLoadContext
->FilePathList
);
603 NewMenuEntry
->OptionNumber
= Index
;
604 NewMenuEntry
->DisplayStringToken
= GetStringTokenFromDepository (
606 DriverOptionStrDepository
608 CallbackData
->Hii
->NewString (
612 &NewMenuEntry
->DisplayStringToken
,
613 NewMenuEntry
->DisplayString
616 NewMenuEntry
->HelpStringToken
= GetStringTokenFromDepository (
618 DriverOptionHelpStrDepository
620 CallbackData
->Hii
->NewString (
624 &NewMenuEntry
->HelpStringToken
,
625 NewMenuEntry
->HelpString
628 if (OptionalDataExist
) {
629 Ptr
+= (UINT8
) GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
);
634 StrSize (OptionalData
)
638 Status
= gRT
->SetVariable (
640 &gEfiGlobalVariableGuid
,
645 DriverOrderList
= BdsLibGetVariableAndSize (
647 &gEfiGlobalVariableGuid
,
650 NewDriverOrderList
= AllocateZeroPool (DriverOrderListSize
+ sizeof (UINT16
));
651 ASSERT (NewDriverOrderList
!= NULL
);
652 CopyMem (NewDriverOrderList
, DriverOrderList
, DriverOrderListSize
);
653 NewDriverOrderList
[DriverOrderListSize
/ sizeof (UINT16
)] = Index
;
654 if (DriverOrderList
!= NULL
) {
655 EfiLibDeleteVariable (L
"DriverOrder", &gEfiGlobalVariableGuid
);
658 Status
= gRT
->SetVariable (
660 &gEfiGlobalVariableGuid
,
662 DriverOrderListSize
+ sizeof (UINT16
),
665 SafeFreePool (DriverOrderList
);
666 DriverOrderList
= NULL
;
667 SafeFreePool (NewDriverOrderList
);
668 NewDriverOrderList
= NULL
;
669 InsertTailList (&DriverOptionMenu
.Head
, &NewMenuEntry
->Link
);
670 DriverOptionMenu
.MenuNumber
++;
672 *DescriptionData
= 0x0000;
673 *OptionalData
= 0x0000;
678 Var_UpdateBootOption (
679 IN BMM_CALLBACK_DATA
*CallbackData
,
680 IN FILE_EXPLORER_NV_DATA
*NvRamMap
683 UINT16
*BootOrderList
;
684 UINT16
*NewBootOrderList
;
685 UINTN BootOrderListSize
;
686 UINT16 BootString
[10];
691 BM_MENU_ENTRY
*NewMenuEntry
;
692 BM_LOAD_CONTEXT
*NewLoadContext
;
693 BOOLEAN OptionalDataExist
;
696 OptionalDataExist
= FALSE
;
698 Index
= BOpt_GetBootOptionNumber ();
699 UnicodeSPrint (BootString
, sizeof (BootString
), L
"Boot%04x", Index
);
701 if (NvRamMap
->DescriptionData
[0] == 0x0000) {
702 StrCpy (NvRamMap
->DescriptionData
, BootString
);
705 BufferSize
= sizeof (UINT32
) + sizeof (UINT16
) + StrSize (NvRamMap
->DescriptionData
) + GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
);
707 if (NvRamMap
->OptionalData
[0] != 0x0000) {
708 OptionalDataExist
= TRUE
;
709 BufferSize
+= StrSize (NvRamMap
->OptionalData
);
712 Buffer
= AllocateZeroPool (BufferSize
);
713 if (NULL
== Buffer
) {
714 return EFI_OUT_OF_RESOURCES
;
717 NewMenuEntry
= BOpt_CreateMenuEntry (BM_LOAD_CONTEXT_SELECT
);
718 if (NULL
== NewMenuEntry
) {
719 return EFI_OUT_OF_RESOURCES
;
722 NewLoadContext
= (BM_LOAD_CONTEXT
*) NewMenuEntry
->VariableContext
;
723 NewLoadContext
->Deleted
= FALSE
;
724 NewLoadContext
->LoadOptionSize
= BufferSize
;
725 Ptr
= (UINT8
*) Buffer
;
726 NewLoadContext
->LoadOption
= Ptr
;
727 *((UINT32
*) Ptr
) = LOAD_OPTION_ACTIVE
;
728 NewLoadContext
->Attributes
= *((UINT32
*) Ptr
);
729 NewLoadContext
->IsActive
= TRUE
;
730 NewLoadContext
->ForceReconnect
= (BOOLEAN
) (NewLoadContext
->Attributes
& LOAD_OPTION_FORCE_RECONNECT
);
732 Ptr
+= sizeof (UINT32
);
733 *((UINT16
*) Ptr
) = (UINT16
) GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
);
734 NewLoadContext
->FilePathListLength
= *((UINT16
*) Ptr
);
735 Ptr
+= sizeof (UINT16
);
739 NvRamMap
->DescriptionData
,
740 StrSize (NvRamMap
->DescriptionData
)
743 NewLoadContext
->Description
= AllocateZeroPool (StrSize (NvRamMap
->DescriptionData
));
744 ASSERT (NewLoadContext
->Description
!= NULL
);
746 NewMenuEntry
->DisplayString
= NewLoadContext
->Description
;
748 NewLoadContext
->Description
,
750 StrSize (NvRamMap
->DescriptionData
)
753 Ptr
+= StrSize (NvRamMap
->DescriptionData
);
756 CallbackData
->LoadContext
->FilePathList
,
757 GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
)
760 NewLoadContext
->FilePathList
= AllocateZeroPool (GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
));
761 ASSERT (NewLoadContext
->FilePathList
!= NULL
);
764 NewLoadContext
->FilePathList
,
766 GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
)
769 NewMenuEntry
->HelpString
= DevicePathToStr (NewLoadContext
->FilePathList
);
770 NewMenuEntry
->OptionNumber
= Index
;
771 NewMenuEntry
->DisplayStringToken
= GetStringTokenFromDepository (
773 BootOptionStrDepository
775 CallbackData
->Hii
->NewString (
778 CallbackData
->FeHiiHandle
,
779 &NewMenuEntry
->DisplayStringToken
,
780 NewMenuEntry
->DisplayString
783 NewMenuEntry
->HelpStringToken
= GetStringTokenFromDepository (
785 BootOptionHelpStrDepository
788 CallbackData
->Hii
->NewString (
791 CallbackData
->FeHiiHandle
,
792 &NewMenuEntry
->HelpStringToken
,
793 NewMenuEntry
->HelpString
796 if (OptionalDataExist
) {
797 Ptr
+= (UINT8
) GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
);
799 CopyMem (Ptr
, NvRamMap
->OptionalData
, StrSize (NvRamMap
->OptionalData
));
802 Status
= gRT
->SetVariable (
804 &gEfiGlobalVariableGuid
,
810 BootOrderList
= BdsLibGetVariableAndSize (
812 &gEfiGlobalVariableGuid
,
816 NewBootOrderList
= AllocateZeroPool (BootOrderListSize
+ sizeof (UINT16
));
817 ASSERT (NewBootOrderList
!= NULL
);
818 CopyMem (NewBootOrderList
, BootOrderList
, BootOrderListSize
);
819 NewBootOrderList
[BootOrderListSize
/ sizeof (UINT16
)] = Index
;
821 if (BootOrderList
!= NULL
) {
822 EfiLibDeleteVariable (L
"BootOrder", &gEfiGlobalVariableGuid
);
825 Status
= gRT
->SetVariable (
827 &gEfiGlobalVariableGuid
,
829 BootOrderListSize
+ sizeof (UINT16
),
833 SafeFreePool (BootOrderList
);
834 BootOrderList
= NULL
;
835 SafeFreePool (NewBootOrderList
);
836 NewBootOrderList
= NULL
;
837 InsertTailList (&BootOptionMenu
.Head
, &NewMenuEntry
->Link
);
838 BootOptionMenu
.MenuNumber
++;
840 NvRamMap
->DescriptionData
[0] = 0x0000;
841 NvRamMap
->OptionalData
[0] = 0x0000;
847 IN BMM_CALLBACK_DATA
*CallbackData
850 BM_MENU_ENTRY
*NewMenuEntry
;
851 BM_LOAD_CONTEXT
*NewLoadContext
;
852 BMM_FAKE_NV_DATA
*CurrentFakeNVMap
;
856 Status
= EFI_SUCCESS
;
857 CurrentFakeNVMap
= CallbackData
->BmmFakeNvData
;
858 for (Index
= 0; Index
< BootOptionMenu
.MenuNumber
; Index
++) {
859 NewMenuEntry
= BOpt_GetMenuEntry (&BootOptionMenu
, Index
);
860 if (NULL
== NewMenuEntry
) {
861 return EFI_NOT_FOUND
;
864 NewLoadContext
= (BM_LOAD_CONTEXT
*) NewMenuEntry
->VariableContext
;
865 NewLoadContext
->IsBootNext
= FALSE
;
868 if (CurrentFakeNVMap
->BootNext
== BootOptionMenu
.MenuNumber
) {
869 EfiLibDeleteVariable (L
"BootNext", &gEfiGlobalVariableGuid
);
873 NewMenuEntry
= BOpt_GetMenuEntry (
875 CurrentFakeNVMap
->BootNext
877 if (NULL
== NewMenuEntry
) {
878 return EFI_NOT_FOUND
;
881 NewLoadContext
= (BM_LOAD_CONTEXT
*) NewMenuEntry
->VariableContext
;
882 Status
= gRT
->SetVariable (
884 &gEfiGlobalVariableGuid
,
887 &NewMenuEntry
->OptionNumber
889 NewLoadContext
->IsBootNext
= TRUE
;
890 CallbackData
->BmmOldFakeNVData
.BootNext
= CurrentFakeNVMap
->BootNext
;
895 Var_UpdateBootOrder (
896 IN BMM_CALLBACK_DATA
*CallbackData
901 UINT16
*BootOrderList
;
902 UINT16
*NewBootOrderList
;
903 UINTN BootOrderListSize
;
906 BootOrderList
= NULL
;
907 BootOrderListSize
= 0;
910 // First check whether BootOrder is present in current configuration
912 BootOrderList
= BdsLibGetVariableAndSize (
914 &gEfiGlobalVariableGuid
,
918 NewBootOrderList
= AllocateZeroPool (BootOrderListSize
);
919 if (!NewBootOrderList
) {
920 return EFI_OUT_OF_RESOURCES
;
923 Map
= AllocateZeroPool (BootOrderListSize
/ sizeof (UINT16
));
925 return EFI_OUT_OF_RESOURCES
;
928 // If exists, delete it to hold new BootOrder
931 EfiLibDeleteVariable (L
"BootOrder", &gEfiGlobalVariableGuid
);
934 for (Index
= 0; Index
< BootOptionMenu
.MenuNumber
; Index
++) {
935 NewBootOrderList
[Index
] = CallbackData
->BmmFakeNvData
->OptionOrder
[Index
] - 1;
938 Status
= gRT
->SetVariable (
940 &gEfiGlobalVariableGuid
,
945 SafeFreePool (BootOrderList
);
946 SafeFreePool (NewBootOrderList
);
948 if (EFI_ERROR (Status
)) {
952 BOpt_FreeMenu (&BootOptionMenu
);
953 BOpt_GetBootOptions (CallbackData
);
960 Var_UpdateDriverOrder (
961 IN BMM_CALLBACK_DATA
*CallbackData
966 UINT16
*DriverOrderList
;
967 UINT16
*NewDriverOrderList
;
968 UINTN DriverOrderListSize
;
970 DriverOrderList
= NULL
;
971 DriverOrderListSize
= 0;
974 // First check whether DriverOrder is present in current configuration
976 DriverOrderList
= BdsLibGetVariableAndSize (
978 &gEfiGlobalVariableGuid
,
982 NewDriverOrderList
= AllocateZeroPool (DriverOrderListSize
);
984 if (!NewDriverOrderList
) {
985 return EFI_OUT_OF_RESOURCES
;
988 // If exists, delete it to hold new DriverOrder
990 if (DriverOrderList
) {
991 EfiLibDeleteVariable (L
"DriverOrder", &gEfiGlobalVariableGuid
);
994 for (Index
= 0; Index
< DriverOrderListSize
; Index
++) {
995 NewDriverOrderList
[Index
] = CallbackData
->BmmFakeNvData
->OptionOrder
[Index
] - 1;
998 Status
= gRT
->SetVariable (
1000 &gEfiGlobalVariableGuid
,
1002 DriverOrderListSize
,
1005 if (EFI_ERROR (Status
)) {
1009 SafeFreePool (DriverOrderList
);
1011 BOpt_FreeMenu (&DriverOptionMenu
);
1012 BOpt_GetDriverOptions (CallbackData
);
1017 Var_UpdateBBSOption (
1018 IN BMM_CALLBACK_DATA
*CallbackData
1023 VOID
*BootOptionVar
;
1024 CHAR16 VarName
[100];
1026 UINT16 FilePathSize
;
1029 CHAR16 DescString
[100];
1030 UINTN NewOptionSize
;
1031 UINT8
*NewOptionPtr
;
1035 BM_MENU_OPTION
*OptionMenu
;
1036 BM_LEGACY_DEVICE_CONTEXT
*LegacyDeviceContext
;
1040 BM_MENU_ENTRY
*NewMenuEntry
;
1041 BM_LEGACY_DEV_ORDER_CONTEXT
*DevOrder
;
1049 LegacyDeviceContext
= NULL
;
1053 if (FORM_SET_FD_ORDER_ID
== CallbackData
->BmmPreviousPageId
) {
1054 OptionMenu
= (BM_MENU_OPTION
*) &LegacyFDMenu
;
1055 LegacyDev
= CallbackData
->BmmFakeNvData
->LegacyFD
;
1056 CallbackData
->BbsType
= BBS_FLOPPY
;
1058 if (FORM_SET_HD_ORDER_ID
== CallbackData
->BmmPreviousPageId
) {
1059 OptionMenu
= (BM_MENU_OPTION
*) &LegacyHDMenu
;
1060 LegacyDev
= CallbackData
->BmmFakeNvData
->LegacyHD
;
1061 CallbackData
->BbsType
= BBS_HARDDISK
;
1063 if (FORM_SET_CD_ORDER_ID
== CallbackData
->BmmPreviousPageId
) {
1064 OptionMenu
= (BM_MENU_OPTION
*) &LegacyCDMenu
;
1065 LegacyDev
= CallbackData
->BmmFakeNvData
->LegacyCD
;
1066 CallbackData
->BbsType
= BBS_CDROM
;
1068 if (FORM_SET_NET_ORDER_ID
== CallbackData
->BmmPreviousPageId
) {
1069 OptionMenu
= (BM_MENU_OPTION
*) &LegacyNETMenu
;
1070 LegacyDev
= CallbackData
->BmmFakeNvData
->LegacyNET
;
1071 CallbackData
->BbsType
= BBS_EMBED_NETWORK
;
1073 OptionMenu
= (BM_MENU_OPTION
*) &LegacyBEVMenu
;
1074 LegacyDev
= CallbackData
->BmmFakeNvData
->LegacyBEV
;
1075 CallbackData
->BbsType
= BBS_BEV_DEVICE
;
1081 DisMap
= CallbackData
->BmmOldFakeNVData
.DisableMap
;
1082 Status
= EFI_SUCCESS
;
1085 // Find the first device's context
1086 // If all devices are disabled( 0xFF == LegacyDev[0]), LegacyDeviceContext can be set to any VariableContext
1087 // because we just use it to fill the desc string, and user can not see the string in UI
1089 for (Index
= 0; Index
< OptionMenu
->MenuNumber
; Index
++) {
1090 NewMenuEntry
= BOpt_GetMenuEntry (OptionMenu
, Index
);
1091 LegacyDeviceContext
= (BM_LEGACY_DEVICE_CONTEXT
*) NewMenuEntry
->VariableContext
;
1092 if (0xFF != LegacyDev
[0] && LegacyDev
[0] == LegacyDeviceContext
->Index
) {
1093 DEBUG ((EFI_D_ERROR
, "DescStr: %s\n", LegacyDeviceContext
->Description
));
1098 // Update the Variable "LegacyDevOrder"
1100 VarData
= (UINT8
*) BdsLibGetVariableAndSize (
1102 &EfiLegacyDevOrderGuid
,
1106 if (NULL
== VarData
) {
1107 return EFI_NOT_FOUND
;
1110 OriginalPtr
= VarData
;
1111 DevOrder
= (BM_LEGACY_DEV_ORDER_CONTEXT
*) VarData
;
1113 while (VarData
< VarData
+ VarSize
) {
1114 if (DevOrder
->BbsType
== CallbackData
->BbsType
) {
1118 VarData
+= sizeof (BBS_TYPE
);
1119 VarData
+= *(UINT16
*) VarData
;
1120 DevOrder
= (BM_LEGACY_DEV_ORDER_CONTEXT
*) VarData
;
1123 if (VarData
>= VarData
+ VarSize
) {
1124 SafeFreePool (OriginalPtr
);
1125 return EFI_NOT_FOUND
;
1128 NewOrder
= (UINT16
*) AllocateZeroPool (DevOrder
->Length
- sizeof (UINT16
));
1129 if (NULL
== NewOrder
) {
1130 SafeFreePool (VarData
);
1131 return EFI_OUT_OF_RESOURCES
;
1134 for (Index
= 0; Index
< OptionMenu
->MenuNumber
; Index
++) {
1135 if (0xFF == LegacyDev
[Index
]) {
1139 NewOrder
[Index
] = LegacyDev
[Index
];
1142 // Only the enable/disable state of each boot device with same device type can be changed,
1143 // so we can count on the index information in DevOrder.
1144 // DisMap bit array is the only reliable source to check a device's en/dis state,
1145 // so we use DisMap to set en/dis state of each item in NewOrder array
1147 for (Index2
= 0; Index2
< OptionMenu
->MenuNumber
; Index2
++) {
1148 Tmp
= *(UINT16
*) ((UINT8
*) DevOrder
+ sizeof (BBS_TYPE
) + sizeof (UINT16
) + Index2
* sizeof (UINT16
));
1151 Bit
= 7 - (Tmp
% 8);
1152 if (DisMap
[Pos
] & (1 << Bit
)) {
1153 NewOrder
[Index
] = (UINT16
) (0xFF00 | Tmp
);
1159 (UINT8
*) DevOrder
+ sizeof (BBS_TYPE
) + sizeof (UINT16
),
1161 DevOrder
->Length
- sizeof (UINT16
)
1163 SafeFreePool (NewOrder
);
1165 Status
= gRT
->SetVariable (
1167 &EfiLegacyDevOrderGuid
,
1173 SafeFreePool (OriginalPtr
);
1176 // Update Optional Data of Boot####
1178 BootOptionVar
= GetLegacyBootOptionVar (CallbackData
->BbsType
, &Index
, &OptionSize
);
1180 if (NULL
!= BootOptionVar
) {
1183 LegacyDeviceContext
->Description
,
1184 StrSize (LegacyDeviceContext
->Description
)
1187 NewOptionSize
= sizeof (UINT32
) + sizeof (UINT16
) + StrSize (DescString
) + sizeof (BBS_TABLE
) + sizeof (UINT16
);
1189 UnicodeSPrint (VarName
, 100, L
"Boot%04x", Index
);
1191 Ptr
= BootOptionVar
;
1193 Attribute
= (UINT32
*) Ptr
;
1194 *Attribute
|= LOAD_OPTION_ACTIVE
;
1195 if (0xFF == LegacyDev
[0]) {
1197 // Disable this legacy boot option
1199 *Attribute
&= ~LOAD_OPTION_ACTIVE
;
1202 Ptr
+= sizeof (UINT32
);
1204 FilePathSize
= *(UINT16
*) Ptr
;
1205 Ptr
+= sizeof (UINT16
);
1207 NewOptionSize
+= FilePathSize
;
1209 NewOptionPtr
= AllocateZeroPool (NewOptionSize
);
1210 if (NULL
== NewOptionPtr
) {
1211 return EFI_OUT_OF_RESOURCES
;
1214 TempPtr
= NewOptionPtr
;
1217 // Copy previous option data to new option except the description string
1222 sizeof (UINT32
) + sizeof (UINT16
)
1225 TempPtr
+= (sizeof (UINT32
) + sizeof (UINT16
));
1230 StrSize (DescString
)
1233 TempPtr
+= StrSize (DescString
);
1236 // Description = (CHAR16 *)Ptr;
1238 Ptr
+= StrSize ((CHAR16
*) Ptr
);
1246 TempPtr
+= FilePathSize
;
1249 // DevicePath = (EFI_DEVICE_PATH_PROTOCOL *)Ptr;
1251 Ptr
+= FilePathSize
;
1254 // Now Ptr point to optional data, i.e. Bbs Table
1258 LegacyDeviceContext
->BbsTable
,
1262 TempPtr
+= sizeof (BBS_TABLE
);
1263 *((UINT16
*) TempPtr
) = (UINT16
) LegacyDeviceContext
->Index
;
1265 Status
= gRT
->SetVariable (
1267 &gEfiGlobalVariableGuid
,
1273 SafeFreePool (NewOptionPtr
);
1274 SafeFreePool (BootOptionVar
);
1277 BOpt_GetBootOptions (CallbackData
);