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 ASSERT (TerminalDevicePath
!= NULL
);
454 ChangeTerminalDevicePath (TerminalDevicePath
, TRUE
);
455 Temp
= DevicePathToStr (TerminalDevicePath
);
456 ConDevicePath
= AppendDevicePathInstance (
464 Status
= gRT
->SetVariable (
466 &gEfiGlobalVariableGuid
,
468 GetDevicePathSize (ConDevicePath
),
471 if (EFI_ERROR (Status
)) {
481 Var_UpdateConsoleInpOption (
485 return Var_UpdateConsoleOption (L
"ConIn", &ConsoleInpMenu
, FORM_CON_IN_ID
);
489 Var_UpdateConsoleOutOption (
493 return Var_UpdateConsoleOption (L
"ConOut", &ConsoleOutMenu
, FORM_CON_OUT_ID
);
497 Var_UpdateErrorOutOption (
501 return Var_UpdateConsoleOption (L
"ErrOut", &ConsoleErrMenu
, FORM_CON_ERR_ID
);
505 Var_UpdateDriverOption (
506 IN BMM_CALLBACK_DATA
*CallbackData
,
507 IN EFI_HII_HANDLE HiiHandle
,
508 IN UINT16
*DescriptionData
,
509 IN UINT16
*OptionalData
,
510 IN UINT8 ForceReconnect
514 UINT16
*DriverOrderList
;
515 UINT16
*NewDriverOrderList
;
516 UINT16 DriverString
[12];
517 UINTN DriverOrderListSize
;
521 BM_MENU_ENTRY
*NewMenuEntry
;
522 BM_LOAD_CONTEXT
*NewLoadContext
;
523 BOOLEAN OptionalDataExist
;
526 OptionalDataExist
= FALSE
;
528 Index
= BOpt_GetDriverOptionNumber ();
531 sizeof (DriverString
),
536 if (*DescriptionData
== 0x0000) {
537 StrCpy (DescriptionData
, DriverString
);
540 BufferSize
= sizeof (UINT32
) + sizeof (UINT16
) + StrSize (DescriptionData
) + GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
);
542 if (*OptionalData
!= 0x0000) {
543 OptionalDataExist
= TRUE
;
544 BufferSize
+= StrSize (OptionalData
);
547 Buffer
= AllocateZeroPool (BufferSize
);
548 if (NULL
== Buffer
) {
549 return EFI_OUT_OF_RESOURCES
;
552 NewMenuEntry
= BOpt_CreateMenuEntry (BM_LOAD_CONTEXT_SELECT
);
553 if (NULL
== NewMenuEntry
) {
554 return EFI_OUT_OF_RESOURCES
;
557 NewLoadContext
= (BM_LOAD_CONTEXT
*) NewMenuEntry
->VariableContext
;
558 NewLoadContext
->Deleted
= FALSE
;
559 NewLoadContext
->LoadOptionSize
= BufferSize
;
560 Ptr
= (UINT8
*) Buffer
;
561 NewLoadContext
->LoadOption
= Ptr
;
562 *((UINT32
*) Ptr
) = LOAD_OPTION_ACTIVE
| (ForceReconnect
<< 1);
563 NewLoadContext
->Attributes
= *((UINT32
*) Ptr
);
564 NewLoadContext
->IsActive
= TRUE
;
565 NewLoadContext
->ForceReconnect
= (BOOLEAN
) (NewLoadContext
->Attributes
& LOAD_OPTION_FORCE_RECONNECT
);
567 Ptr
+= sizeof (UINT32
);
568 *((UINT16
*) Ptr
) = (UINT16
) GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
);
569 NewLoadContext
->FilePathListLength
= *((UINT16
*) Ptr
);
571 Ptr
+= sizeof (UINT16
);
575 StrSize (DescriptionData
)
578 NewLoadContext
->Description
= AllocateZeroPool (StrSize (DescriptionData
));
579 ASSERT (NewLoadContext
->Description
!= NULL
);
580 NewMenuEntry
->DisplayString
= NewLoadContext
->Description
;
582 NewLoadContext
->Description
,
584 StrSize (DescriptionData
)
587 Ptr
+= StrSize (DescriptionData
);
590 CallbackData
->LoadContext
->FilePathList
,
591 GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
)
594 NewLoadContext
->FilePathList
= AllocateZeroPool (GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
));
595 ASSERT (NewLoadContext
->FilePathList
!= NULL
);
598 NewLoadContext
->FilePathList
,
600 GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
)
603 NewMenuEntry
->HelpString
= DevicePathToStr (NewLoadContext
->FilePathList
);
604 NewMenuEntry
->OptionNumber
= Index
;
605 NewMenuEntry
->DisplayStringToken
= GetStringTokenFromDepository (
607 DriverOptionStrDepository
609 CallbackData
->Hii
->NewString (
613 &NewMenuEntry
->DisplayStringToken
,
614 NewMenuEntry
->DisplayString
617 NewMenuEntry
->HelpStringToken
= GetStringTokenFromDepository (
619 DriverOptionHelpStrDepository
621 CallbackData
->Hii
->NewString (
625 &NewMenuEntry
->HelpStringToken
,
626 NewMenuEntry
->HelpString
629 if (OptionalDataExist
) {
630 Ptr
+= (UINT8
) GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
);
635 StrSize (OptionalData
)
639 Status
= gRT
->SetVariable (
641 &gEfiGlobalVariableGuid
,
646 DriverOrderList
= BdsLibGetVariableAndSize (
648 &gEfiGlobalVariableGuid
,
651 NewDriverOrderList
= AllocateZeroPool (DriverOrderListSize
+ sizeof (UINT16
));
652 ASSERT (NewDriverOrderList
!= NULL
);
653 CopyMem (NewDriverOrderList
, DriverOrderList
, DriverOrderListSize
);
654 NewDriverOrderList
[DriverOrderListSize
/ sizeof (UINT16
)] = Index
;
655 if (DriverOrderList
!= NULL
) {
656 EfiLibDeleteVariable (L
"DriverOrder", &gEfiGlobalVariableGuid
);
659 Status
= gRT
->SetVariable (
661 &gEfiGlobalVariableGuid
,
663 DriverOrderListSize
+ sizeof (UINT16
),
666 SafeFreePool (DriverOrderList
);
667 DriverOrderList
= NULL
;
668 SafeFreePool (NewDriverOrderList
);
669 NewDriverOrderList
= NULL
;
670 InsertTailList (&DriverOptionMenu
.Head
, &NewMenuEntry
->Link
);
671 DriverOptionMenu
.MenuNumber
++;
673 *DescriptionData
= 0x0000;
674 *OptionalData
= 0x0000;
679 Var_UpdateBootOption (
680 IN BMM_CALLBACK_DATA
*CallbackData
,
681 IN FILE_EXPLORER_NV_DATA
*NvRamMap
684 UINT16
*BootOrderList
;
685 UINT16
*NewBootOrderList
;
686 UINTN BootOrderListSize
;
687 UINT16 BootString
[10];
692 BM_MENU_ENTRY
*NewMenuEntry
;
693 BM_LOAD_CONTEXT
*NewLoadContext
;
694 BOOLEAN OptionalDataExist
;
697 OptionalDataExist
= FALSE
;
699 Index
= BOpt_GetBootOptionNumber ();
700 UnicodeSPrint (BootString
, sizeof (BootString
), L
"Boot%04x", Index
);
702 if (NvRamMap
->DescriptionData
[0] == 0x0000) {
703 StrCpy (NvRamMap
->DescriptionData
, BootString
);
706 BufferSize
= sizeof (UINT32
) + sizeof (UINT16
) + StrSize (NvRamMap
->DescriptionData
) + GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
);
708 if (NvRamMap
->OptionalData
[0] != 0x0000) {
709 OptionalDataExist
= TRUE
;
710 BufferSize
+= StrSize (NvRamMap
->OptionalData
);
713 Buffer
= AllocateZeroPool (BufferSize
);
714 if (NULL
== Buffer
) {
715 return EFI_OUT_OF_RESOURCES
;
718 NewMenuEntry
= BOpt_CreateMenuEntry (BM_LOAD_CONTEXT_SELECT
);
719 if (NULL
== NewMenuEntry
) {
720 return EFI_OUT_OF_RESOURCES
;
723 NewLoadContext
= (BM_LOAD_CONTEXT
*) NewMenuEntry
->VariableContext
;
724 NewLoadContext
->Deleted
= FALSE
;
725 NewLoadContext
->LoadOptionSize
= BufferSize
;
726 Ptr
= (UINT8
*) Buffer
;
727 NewLoadContext
->LoadOption
= Ptr
;
728 *((UINT32
*) Ptr
) = LOAD_OPTION_ACTIVE
;
729 NewLoadContext
->Attributes
= *((UINT32
*) Ptr
);
730 NewLoadContext
->IsActive
= TRUE
;
731 NewLoadContext
->ForceReconnect
= (BOOLEAN
) (NewLoadContext
->Attributes
& LOAD_OPTION_FORCE_RECONNECT
);
733 Ptr
+= sizeof (UINT32
);
734 *((UINT16
*) Ptr
) = (UINT16
) GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
);
735 NewLoadContext
->FilePathListLength
= *((UINT16
*) Ptr
);
736 Ptr
+= sizeof (UINT16
);
740 NvRamMap
->DescriptionData
,
741 StrSize (NvRamMap
->DescriptionData
)
744 NewLoadContext
->Description
= AllocateZeroPool (StrSize (NvRamMap
->DescriptionData
));
745 ASSERT (NewLoadContext
->Description
!= NULL
);
747 NewMenuEntry
->DisplayString
= NewLoadContext
->Description
;
749 NewLoadContext
->Description
,
751 StrSize (NvRamMap
->DescriptionData
)
754 Ptr
+= StrSize (NvRamMap
->DescriptionData
);
757 CallbackData
->LoadContext
->FilePathList
,
758 GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
)
761 NewLoadContext
->FilePathList
= AllocateZeroPool (GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
));
762 ASSERT (NewLoadContext
->FilePathList
!= NULL
);
765 NewLoadContext
->FilePathList
,
767 GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
)
770 NewMenuEntry
->HelpString
= DevicePathToStr (NewLoadContext
->FilePathList
);
771 NewMenuEntry
->OptionNumber
= Index
;
772 NewMenuEntry
->DisplayStringToken
= GetStringTokenFromDepository (
774 BootOptionStrDepository
776 CallbackData
->Hii
->NewString (
779 CallbackData
->FeHiiHandle
,
780 &NewMenuEntry
->DisplayStringToken
,
781 NewMenuEntry
->DisplayString
784 NewMenuEntry
->HelpStringToken
= GetStringTokenFromDepository (
786 BootOptionHelpStrDepository
789 CallbackData
->Hii
->NewString (
792 CallbackData
->FeHiiHandle
,
793 &NewMenuEntry
->HelpStringToken
,
794 NewMenuEntry
->HelpString
797 if (OptionalDataExist
) {
798 Ptr
+= (UINT8
) GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
);
800 CopyMem (Ptr
, NvRamMap
->OptionalData
, StrSize (NvRamMap
->OptionalData
));
803 Status
= gRT
->SetVariable (
805 &gEfiGlobalVariableGuid
,
811 BootOrderList
= BdsLibGetVariableAndSize (
813 &gEfiGlobalVariableGuid
,
817 NewBootOrderList
= AllocateZeroPool (BootOrderListSize
+ sizeof (UINT16
));
818 ASSERT (NewBootOrderList
!= NULL
);
819 CopyMem (NewBootOrderList
, BootOrderList
, BootOrderListSize
);
820 NewBootOrderList
[BootOrderListSize
/ sizeof (UINT16
)] = Index
;
822 if (BootOrderList
!= NULL
) {
823 EfiLibDeleteVariable (L
"BootOrder", &gEfiGlobalVariableGuid
);
826 Status
= gRT
->SetVariable (
828 &gEfiGlobalVariableGuid
,
830 BootOrderListSize
+ sizeof (UINT16
),
834 SafeFreePool (BootOrderList
);
835 BootOrderList
= NULL
;
836 SafeFreePool (NewBootOrderList
);
837 NewBootOrderList
= NULL
;
838 InsertTailList (&BootOptionMenu
.Head
, &NewMenuEntry
->Link
);
839 BootOptionMenu
.MenuNumber
++;
841 NvRamMap
->DescriptionData
[0] = 0x0000;
842 NvRamMap
->OptionalData
[0] = 0x0000;
848 IN BMM_CALLBACK_DATA
*CallbackData
851 BM_MENU_ENTRY
*NewMenuEntry
;
852 BM_LOAD_CONTEXT
*NewLoadContext
;
853 BMM_FAKE_NV_DATA
*CurrentFakeNVMap
;
857 Status
= EFI_SUCCESS
;
858 CurrentFakeNVMap
= CallbackData
->BmmFakeNvData
;
859 for (Index
= 0; Index
< BootOptionMenu
.MenuNumber
; Index
++) {
860 NewMenuEntry
= BOpt_GetMenuEntry (&BootOptionMenu
, Index
);
861 if (NULL
== NewMenuEntry
) {
862 return EFI_NOT_FOUND
;
865 NewLoadContext
= (BM_LOAD_CONTEXT
*) NewMenuEntry
->VariableContext
;
866 NewLoadContext
->IsBootNext
= FALSE
;
869 if (CurrentFakeNVMap
->BootNext
== BootOptionMenu
.MenuNumber
) {
870 EfiLibDeleteVariable (L
"BootNext", &gEfiGlobalVariableGuid
);
874 NewMenuEntry
= BOpt_GetMenuEntry (
876 CurrentFakeNVMap
->BootNext
878 if (NULL
== NewMenuEntry
) {
879 return EFI_NOT_FOUND
;
882 NewLoadContext
= (BM_LOAD_CONTEXT
*) NewMenuEntry
->VariableContext
;
883 Status
= gRT
->SetVariable (
885 &gEfiGlobalVariableGuid
,
888 &NewMenuEntry
->OptionNumber
890 NewLoadContext
->IsBootNext
= TRUE
;
891 CallbackData
->BmmOldFakeNVData
.BootNext
= CurrentFakeNVMap
->BootNext
;
896 Var_UpdateBootOrder (
897 IN BMM_CALLBACK_DATA
*CallbackData
902 UINT16
*BootOrderList
;
903 UINT16
*NewBootOrderList
;
904 UINTN BootOrderListSize
;
907 BootOrderList
= NULL
;
908 BootOrderListSize
= 0;
911 // First check whether BootOrder is present in current configuration
913 BootOrderList
= BdsLibGetVariableAndSize (
915 &gEfiGlobalVariableGuid
,
919 NewBootOrderList
= AllocateZeroPool (BootOrderListSize
);
920 if (!NewBootOrderList
) {
921 return EFI_OUT_OF_RESOURCES
;
924 Map
= AllocateZeroPool (BootOrderListSize
/ sizeof (UINT16
));
926 return EFI_OUT_OF_RESOURCES
;
929 // If exists, delete it to hold new BootOrder
932 EfiLibDeleteVariable (L
"BootOrder", &gEfiGlobalVariableGuid
);
935 for (Index
= 0; Index
< BootOptionMenu
.MenuNumber
; Index
++) {
936 NewBootOrderList
[Index
] = CallbackData
->BmmFakeNvData
->OptionOrder
[Index
] - 1;
939 Status
= gRT
->SetVariable (
941 &gEfiGlobalVariableGuid
,
946 SafeFreePool (BootOrderList
);
947 SafeFreePool (NewBootOrderList
);
949 if (EFI_ERROR (Status
)) {
953 BOpt_FreeMenu (&BootOptionMenu
);
954 BOpt_GetBootOptions (CallbackData
);
961 Var_UpdateDriverOrder (
962 IN BMM_CALLBACK_DATA
*CallbackData
967 UINT16
*DriverOrderList
;
968 UINT16
*NewDriverOrderList
;
969 UINTN DriverOrderListSize
;
971 DriverOrderList
= NULL
;
972 DriverOrderListSize
= 0;
975 // First check whether DriverOrder is present in current configuration
977 DriverOrderList
= BdsLibGetVariableAndSize (
979 &gEfiGlobalVariableGuid
,
983 NewDriverOrderList
= AllocateZeroPool (DriverOrderListSize
);
985 if (!NewDriverOrderList
) {
986 return EFI_OUT_OF_RESOURCES
;
989 // If exists, delete it to hold new DriverOrder
991 if (DriverOrderList
) {
992 EfiLibDeleteVariable (L
"DriverOrder", &gEfiGlobalVariableGuid
);
995 for (Index
= 0; Index
< DriverOrderListSize
; Index
++) {
996 NewDriverOrderList
[Index
] = CallbackData
->BmmFakeNvData
->OptionOrder
[Index
] - 1;
999 Status
= gRT
->SetVariable (
1001 &gEfiGlobalVariableGuid
,
1003 DriverOrderListSize
,
1006 if (EFI_ERROR (Status
)) {
1010 SafeFreePool (DriverOrderList
);
1012 BOpt_FreeMenu (&DriverOptionMenu
);
1013 BOpt_GetDriverOptions (CallbackData
);
1018 Var_UpdateBBSOption (
1019 IN BMM_CALLBACK_DATA
*CallbackData
1024 VOID
*BootOptionVar
;
1025 CHAR16 VarName
[100];
1027 UINT16 FilePathSize
;
1030 CHAR16 DescString
[100];
1031 UINTN NewOptionSize
;
1032 UINT8
*NewOptionPtr
;
1036 BM_MENU_OPTION
*OptionMenu
;
1037 BM_LEGACY_DEVICE_CONTEXT
*LegacyDeviceContext
;
1041 BM_MENU_ENTRY
*NewMenuEntry
;
1042 BM_LEGACY_DEV_ORDER_CONTEXT
*DevOrder
;
1050 LegacyDeviceContext
= NULL
;
1054 if (FORM_SET_FD_ORDER_ID
== CallbackData
->BmmPreviousPageId
) {
1055 OptionMenu
= (BM_MENU_OPTION
*) &LegacyFDMenu
;
1056 LegacyDev
= CallbackData
->BmmFakeNvData
->LegacyFD
;
1057 CallbackData
->BbsType
= BBS_FLOPPY
;
1059 if (FORM_SET_HD_ORDER_ID
== CallbackData
->BmmPreviousPageId
) {
1060 OptionMenu
= (BM_MENU_OPTION
*) &LegacyHDMenu
;
1061 LegacyDev
= CallbackData
->BmmFakeNvData
->LegacyHD
;
1062 CallbackData
->BbsType
= BBS_HARDDISK
;
1064 if (FORM_SET_CD_ORDER_ID
== CallbackData
->BmmPreviousPageId
) {
1065 OptionMenu
= (BM_MENU_OPTION
*) &LegacyCDMenu
;
1066 LegacyDev
= CallbackData
->BmmFakeNvData
->LegacyCD
;
1067 CallbackData
->BbsType
= BBS_CDROM
;
1069 if (FORM_SET_NET_ORDER_ID
== CallbackData
->BmmPreviousPageId
) {
1070 OptionMenu
= (BM_MENU_OPTION
*) &LegacyNETMenu
;
1071 LegacyDev
= CallbackData
->BmmFakeNvData
->LegacyNET
;
1072 CallbackData
->BbsType
= BBS_EMBED_NETWORK
;
1074 OptionMenu
= (BM_MENU_OPTION
*) &LegacyBEVMenu
;
1075 LegacyDev
= CallbackData
->BmmFakeNvData
->LegacyBEV
;
1076 CallbackData
->BbsType
= BBS_BEV_DEVICE
;
1082 DisMap
= CallbackData
->BmmOldFakeNVData
.DisableMap
;
1083 Status
= EFI_SUCCESS
;
1086 // Find the first device's context
1087 // If all devices are disabled( 0xFF == LegacyDev[0]), LegacyDeviceContext can be set to any VariableContext
1088 // because we just use it to fill the desc string, and user can not see the string in UI
1090 for (Index
= 0; Index
< OptionMenu
->MenuNumber
; Index
++) {
1091 NewMenuEntry
= BOpt_GetMenuEntry (OptionMenu
, Index
);
1092 LegacyDeviceContext
= (BM_LEGACY_DEVICE_CONTEXT
*) NewMenuEntry
->VariableContext
;
1093 if (0xFF != LegacyDev
[0] && LegacyDev
[0] == LegacyDeviceContext
->Index
) {
1094 DEBUG ((EFI_D_ERROR
, "DescStr: %s\n", LegacyDeviceContext
->Description
));
1099 // Update the Variable "LegacyDevOrder"
1101 VarData
= (UINT8
*) BdsLibGetVariableAndSize (
1103 &EfiLegacyDevOrderGuid
,
1107 if (NULL
== VarData
) {
1108 return EFI_NOT_FOUND
;
1111 OriginalPtr
= VarData
;
1112 DevOrder
= (BM_LEGACY_DEV_ORDER_CONTEXT
*) VarData
;
1114 while (VarData
< VarData
+ VarSize
) {
1115 if (DevOrder
->BbsType
== CallbackData
->BbsType
) {
1119 VarData
+= sizeof (BBS_TYPE
);
1120 VarData
+= *(UINT16
*) VarData
;
1121 DevOrder
= (BM_LEGACY_DEV_ORDER_CONTEXT
*) VarData
;
1124 if (VarData
>= VarData
+ VarSize
) {
1125 SafeFreePool (OriginalPtr
);
1126 return EFI_NOT_FOUND
;
1129 NewOrder
= (UINT16
*) AllocateZeroPool (DevOrder
->Length
- sizeof (UINT16
));
1130 if (NULL
== NewOrder
) {
1131 SafeFreePool (VarData
);
1132 return EFI_OUT_OF_RESOURCES
;
1135 for (Index
= 0; Index
< OptionMenu
->MenuNumber
; Index
++) {
1136 if (0xFF == LegacyDev
[Index
]) {
1140 NewOrder
[Index
] = LegacyDev
[Index
];
1143 // Only the enable/disable state of each boot device with same device type can be changed,
1144 // so we can count on the index information in DevOrder.
1145 // DisMap bit array is the only reliable source to check a device's en/dis state,
1146 // so we use DisMap to set en/dis state of each item in NewOrder array
1148 for (Index2
= 0; Index2
< OptionMenu
->MenuNumber
; Index2
++) {
1149 Tmp
= *(UINT16
*) ((UINT8
*) DevOrder
+ sizeof (BBS_TYPE
) + sizeof (UINT16
) + Index2
* sizeof (UINT16
));
1152 Bit
= 7 - (Tmp
% 8);
1153 if (DisMap
[Pos
] & (1 << Bit
)) {
1154 NewOrder
[Index
] = (UINT16
) (0xFF00 | Tmp
);
1160 (UINT8
*) DevOrder
+ sizeof (BBS_TYPE
) + sizeof (UINT16
),
1162 DevOrder
->Length
- sizeof (UINT16
)
1164 SafeFreePool (NewOrder
);
1166 Status
= gRT
->SetVariable (
1168 &EfiLegacyDevOrderGuid
,
1174 SafeFreePool (OriginalPtr
);
1177 // Update Optional Data of Boot####
1179 BootOptionVar
= GetLegacyBootOptionVar (CallbackData
->BbsType
, &Index
, &OptionSize
);
1181 if (NULL
!= BootOptionVar
) {
1184 LegacyDeviceContext
->Description
,
1185 StrSize (LegacyDeviceContext
->Description
)
1188 NewOptionSize
= sizeof (UINT32
) + sizeof (UINT16
) + StrSize (DescString
) + sizeof (BBS_TABLE
) + sizeof (UINT16
);
1190 UnicodeSPrint (VarName
, 100, L
"Boot%04x", Index
);
1192 Ptr
= BootOptionVar
;
1194 Attribute
= (UINT32
*) Ptr
;
1195 *Attribute
|= LOAD_OPTION_ACTIVE
;
1196 if (0xFF == LegacyDev
[0]) {
1198 // Disable this legacy boot option
1200 *Attribute
&= ~LOAD_OPTION_ACTIVE
;
1203 Ptr
+= sizeof (UINT32
);
1205 FilePathSize
= *(UINT16
*) Ptr
;
1206 Ptr
+= sizeof (UINT16
);
1208 NewOptionSize
+= FilePathSize
;
1210 NewOptionPtr
= AllocateZeroPool (NewOptionSize
);
1211 if (NULL
== NewOptionPtr
) {
1212 return EFI_OUT_OF_RESOURCES
;
1215 TempPtr
= NewOptionPtr
;
1218 // Copy previous option data to new option except the description string
1223 sizeof (UINT32
) + sizeof (UINT16
)
1226 TempPtr
+= (sizeof (UINT32
) + sizeof (UINT16
));
1231 StrSize (DescString
)
1234 TempPtr
+= StrSize (DescString
);
1237 // Description = (CHAR16 *)Ptr;
1239 Ptr
+= StrSize ((CHAR16
*) Ptr
);
1247 TempPtr
+= FilePathSize
;
1250 // DevicePath = (EFI_DEVICE_PATH_PROTOCOL *)Ptr;
1252 Ptr
+= FilePathSize
;
1255 // Now Ptr point to optional data, i.e. Bbs Table
1259 LegacyDeviceContext
->BbsTable
,
1263 TempPtr
+= sizeof (BBS_TABLE
);
1264 *((UINT16
*) TempPtr
) = (UINT16
) LegacyDeviceContext
->Index
;
1266 Status
= gRT
->SetVariable (
1268 &gEfiGlobalVariableGuid
,
1274 SafeFreePool (NewOptionPtr
);
1275 SafeFreePool (BootOptionVar
);
1278 BOpt_GetBootOptions (CallbackData
);