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
23 // Include common header file for this module.
25 #include "CommonHeader.h"
27 #include "Generic/Bds.h"
28 #include "BootMaint.h"
29 #include "bdsplatform.h"
38 Delete Boot Option that represent a Deleted state in BootOptionMenu.
39 After deleting this boot option, call Var_ChangeBootOrder to
40 make sure BootOrder is in valid state.
43 LoadOption -- Pointer to the boot option that to be deleted
51 BM_MENU_ENTRY
*NewMenuEntry
;
52 BM_LOAD_CONTEXT
*NewLoadContext
;
54 UINT16 BootString
[10];
61 for (Index
= 0; Index
< BootOptionMenu
.MenuNumber
; Index
++) {
62 NewMenuEntry
= BOpt_GetMenuEntry (&BootOptionMenu
, (Index
- Index2
));
63 if (NULL
== NewMenuEntry
) {
67 NewLoadContext
= (BM_LOAD_CONTEXT
*) NewMenuEntry
->VariableContext
;
68 if (!NewLoadContext
->Deleted
) {
76 NewMenuEntry
->OptionNumber
79 EfiLibDeleteVariable (BootString
, &gEfiGlobalVariableGuid
);
82 // If current Load Option is the same as BootNext,
83 // must delete BootNext in order to make sure
84 // there will be no panic on next boot
86 if (NewLoadContext
->IsBootNext
) {
87 EfiLibDeleteVariable (L
"BootNext", &gEfiGlobalVariableGuid
);
90 RemoveEntryList (&NewMenuEntry
->Link
);
91 BOpt_DestroyMenuEntry (NewMenuEntry
);
95 BootOptionMenu
.MenuNumber
-= Index2
;
97 Status
= Var_ChangeBootOrder ();
102 Var_ChangeBootOrder (
108 After any operation on Boot####, there will be a discrepancy in BootOrder.
109 Since some are missing but in BootOrder, while some are present but are
110 not reflected by BootOrder. Then a function rebuild BootOrder from
111 scratch by content from BootOptionMenu is needed.
123 BM_MENU_ENTRY
*NewMenuEntry
;
124 UINT16
*BootOrderList
;
125 UINT16
*BootOrderListPtr
;
126 UINTN BootOrderListSize
;
129 BootOrderList
= NULL
;
130 BootOrderListSize
= 0;
133 // First check whether BootOrder is present in current configuration
135 BootOrderList
= BdsLibGetVariableAndSize (
137 &gEfiGlobalVariableGuid
,
142 // If exists, delete it to hold new BootOrder
145 EfiLibDeleteVariable (L
"BootOrder", &gEfiGlobalVariableGuid
);
146 SafeFreePool (BootOrderList
);
147 BootOrderList
= NULL
;
150 // Maybe here should be some check method to ensure that
151 // no new added boot options will be added
152 // but the setup engine now will give only one callback
153 // that is to say, user are granted only one chance to
154 // decide whether the boot option will be added or not
155 // there should be no indictor to show whether this
156 // is a "new" boot option
158 BootOrderListSize
= BootOptionMenu
.MenuNumber
;
160 if (BootOrderListSize
> 0) {
161 BootOrderList
= AllocateZeroPool (BootOrderListSize
* sizeof (UINT16
));
162 ASSERT (BootOrderList
!= NULL
);
163 BootOrderListPtr
= BootOrderList
;
166 // Get all current used Boot#### from BootOptionMenu.
167 // OptionNumber in each BM_LOAD_OPTION is really its
170 for (Index
= 0; Index
< BootOrderListSize
; Index
++) {
171 NewMenuEntry
= BOpt_GetMenuEntry (&BootOptionMenu
, Index
);
172 *BootOrderList
= (UINT16
) NewMenuEntry
->OptionNumber
;
176 BootOrderList
= BootOrderListPtr
;
179 // After building the BootOrderList, write it back
181 Status
= gRT
->SetVariable (
183 &gEfiGlobalVariableGuid
,
185 BootOrderListSize
* sizeof (UINT16
),
188 if (EFI_ERROR (Status
)) {
196 Var_DelDriverOption (
202 Delete Load Option that represent a Deleted state in BootOptionMenu.
203 After deleting this Driver option, call Var_ChangeDriverOrder to
204 make sure DriverOrder is in valid state.
207 LoadOption -- Pointer to the Driver option that to be deleted
215 BM_MENU_ENTRY
*NewMenuEntry
;
216 BM_LOAD_CONTEXT
*NewLoadContext
;
218 UINT16 DriverString
[12];
223 Status
= EFI_SUCCESS
;
225 for (Index
= 0; Index
< DriverOptionMenu
.MenuNumber
; Index
++) {
226 NewMenuEntry
= BOpt_GetMenuEntry (&DriverOptionMenu
, (Index
- Index2
));
227 if (NULL
== NewMenuEntry
) {
228 return EFI_NOT_FOUND
;
231 NewLoadContext
= (BM_LOAD_CONTEXT
*) NewMenuEntry
->VariableContext
;
232 if (!NewLoadContext
->Deleted
) {
238 sizeof (DriverString
),
240 NewMenuEntry
->OptionNumber
243 EfiLibDeleteVariable (DriverString
, &gEfiGlobalVariableGuid
);
246 RemoveEntryList (&NewMenuEntry
->Link
);
247 BOpt_DestroyMenuEntry (NewMenuEntry
);
251 DriverOptionMenu
.MenuNumber
-= Index2
;
253 Status
= Var_ChangeDriverOrder ();
258 Var_ChangeDriverOrder (
264 After any operation on Driver####, there will be a discrepancy in
265 DriverOrder. Since some are missing but in DriverOrder, while some
266 are present but are not reflected by DriverOrder. Then a function
267 rebuild DriverOrder from scratch by content from DriverOptionMenu is
279 BM_MENU_ENTRY
*NewMenuEntry
;
280 UINT16
*DriverOrderList
;
281 UINT16
*DriverOrderListPtr
;
282 UINTN DriverOrderListSize
;
285 DriverOrderList
= NULL
;
286 DriverOrderListSize
= 0;
289 // First check whether DriverOrder is present in current configuration
291 DriverOrderList
= BdsLibGetVariableAndSize (
293 &gEfiGlobalVariableGuid
,
298 // If exists, delete it to hold new DriverOrder
300 if (DriverOrderList
) {
301 EfiLibDeleteVariable (L
"DriverOrder", &gEfiGlobalVariableGuid
);
302 SafeFreePool (DriverOrderList
);
303 DriverOrderList
= NULL
;
306 DriverOrderListSize
= DriverOptionMenu
.MenuNumber
;
308 if (DriverOrderListSize
> 0) {
309 DriverOrderList
= AllocateZeroPool (DriverOrderListSize
* sizeof (UINT16
));
310 ASSERT (DriverOrderList
!= NULL
);
311 DriverOrderListPtr
= DriverOrderList
;
314 // Get all current used Driver#### from DriverOptionMenu.
315 // OptionNumber in each BM_LOAD_OPTION is really its
318 for (Index
= 0; Index
< DriverOrderListSize
; Index
++) {
319 NewMenuEntry
= BOpt_GetMenuEntry (&DriverOptionMenu
, Index
);
320 *DriverOrderList
= (UINT16
) NewMenuEntry
->OptionNumber
;
324 DriverOrderList
= DriverOrderListPtr
;
327 // After building the DriverOrderList, write it back
329 Status
= gRT
->SetVariable (
331 &gEfiGlobalVariableGuid
,
333 DriverOrderListSize
* sizeof (UINT16
),
336 if (EFI_ERROR (Status
)) {
344 Var_UpdateAllConsoleOption (
348 EFI_DEVICE_PATH_PROTOCOL
*OutDevicePath
;
349 EFI_DEVICE_PATH_PROTOCOL
*InpDevicePath
;
350 EFI_DEVICE_PATH_PROTOCOL
*ErrDevicePath
;
353 OutDevicePath
= EfiLibGetVariable (L
"ConOut", &gEfiGlobalVariableGuid
);
354 InpDevicePath
= EfiLibGetVariable (L
"ConIn", &gEfiGlobalVariableGuid
);
355 ErrDevicePath
= EfiLibGetVariable (L
"ErrOut", &gEfiGlobalVariableGuid
);
357 ChangeVariableDevicePath (OutDevicePath
);
358 Status
= gRT
->SetVariable (
360 &gEfiGlobalVariableGuid
,
362 GetDevicePathSize (OutDevicePath
),
365 ASSERT (!EFI_ERROR (Status
));
369 ChangeVariableDevicePath (InpDevicePath
);
370 Status
= gRT
->SetVariable (
372 &gEfiGlobalVariableGuid
,
374 GetDevicePathSize (InpDevicePath
),
377 ASSERT (!EFI_ERROR (Status
));
381 ChangeVariableDevicePath (ErrDevicePath
);
382 Status
= gRT
->SetVariable (
384 &gEfiGlobalVariableGuid
,
386 GetDevicePathSize (ErrDevicePath
),
389 ASSERT (!EFI_ERROR (Status
));
394 Var_UpdateConsoleOption (
395 IN UINT16
*ConsoleName
,
396 IN BM_MENU_OPTION
*ConsoleMenu
,
397 IN UINT16 UpdatePageId
400 EFI_DEVICE_PATH_PROTOCOL
*ConDevicePath
;
401 BM_MENU_ENTRY
*NewMenuEntry
;
402 BM_CONSOLE_CONTEXT
*NewConsoleContext
;
403 BM_TERMINAL_CONTEXT
*NewTerminalContext
;
405 VENDOR_DEVICE_PATH Vendor
;
406 EFI_DEVICE_PATH_PROTOCOL
*TerminalDevicePath
;
410 ConDevicePath
= EfiLibGetVariable (ConsoleName
, &gEfiGlobalVariableGuid
);
411 if (ConDevicePath
!= NULL
) {
412 EfiLibDeleteVariable (ConsoleName
, &gEfiGlobalVariableGuid
);
413 SafeFreePool (ConDevicePath
);
414 ConDevicePath
= NULL
;
418 // First add all console input device to it from console input menu
420 for (Index
= 0; Index
< ConsoleMenu
->MenuNumber
; Index
++) {
421 NewMenuEntry
= BOpt_GetMenuEntry (ConsoleMenu
, Index
);
422 if (NULL
== NewMenuEntry
) {
423 return EFI_NOT_FOUND
;
426 NewConsoleContext
= (BM_CONSOLE_CONTEXT
*) NewMenuEntry
->VariableContext
;
427 if (NewConsoleContext
->IsActive
) {
428 ConDevicePath
= AppendDevicePathInstance (
430 NewConsoleContext
->DevicePath
435 for (Index
= 0; Index
< TerminalMenu
.MenuNumber
; Index
++) {
436 NewMenuEntry
= BOpt_GetMenuEntry (&TerminalMenu
, Index
);
437 if (NULL
== NewMenuEntry
) {
438 return EFI_NOT_FOUND
;
441 NewTerminalContext
= (BM_TERMINAL_CONTEXT
*) NewMenuEntry
->VariableContext
;
442 if ((NewTerminalContext
->IsConIn
&& (UpdatePageId
== FORM_CON_IN_ID
)) ||
443 (NewTerminalContext
->IsConOut
&& (UpdatePageId
== FORM_CON_OUT_ID
)) ||
444 (NewTerminalContext
->IsStdErr
&& (UpdatePageId
== FORM_CON_ERR_ID
))
446 Vendor
.Header
.Type
= MESSAGING_DEVICE_PATH
;
447 Vendor
.Header
.SubType
= MSG_VENDOR_DP
;
450 &Guid
[NewTerminalContext
->TerminalType
],
453 SetDevicePathNodeLength (&Vendor
.Header
, sizeof (VENDOR_DEVICE_PATH
));
454 TerminalDevicePath
= AppendDevicePathNode (
455 NewTerminalContext
->DevicePath
,
456 (EFI_DEVICE_PATH_PROTOCOL
*) &Vendor
458 ASSERT (TerminalDevicePath
!= NULL
);
459 ChangeTerminalDevicePath (TerminalDevicePath
, TRUE
);
460 Temp
= DevicePathToStr (TerminalDevicePath
);
461 ConDevicePath
= AppendDevicePathInstance (
469 Status
= gRT
->SetVariable (
471 &gEfiGlobalVariableGuid
,
473 GetDevicePathSize (ConDevicePath
),
476 if (EFI_ERROR (Status
)) {
486 Var_UpdateConsoleInpOption (
490 return Var_UpdateConsoleOption (L
"ConIn", &ConsoleInpMenu
, FORM_CON_IN_ID
);
494 Var_UpdateConsoleOutOption (
498 return Var_UpdateConsoleOption (L
"ConOut", &ConsoleOutMenu
, FORM_CON_OUT_ID
);
502 Var_UpdateErrorOutOption (
506 return Var_UpdateConsoleOption (L
"ErrOut", &ConsoleErrMenu
, FORM_CON_ERR_ID
);
510 Var_UpdateDriverOption (
511 IN BMM_CALLBACK_DATA
*CallbackData
,
512 IN EFI_HII_HANDLE HiiHandle
,
513 IN UINT16
*DescriptionData
,
514 IN UINT16
*OptionalData
,
515 IN UINT8 ForceReconnect
519 UINT16
*DriverOrderList
;
520 UINT16
*NewDriverOrderList
;
521 UINT16 DriverString
[12];
522 UINTN DriverOrderListSize
;
526 BM_MENU_ENTRY
*NewMenuEntry
;
527 BM_LOAD_CONTEXT
*NewLoadContext
;
528 BOOLEAN OptionalDataExist
;
531 OptionalDataExist
= FALSE
;
533 Index
= BOpt_GetDriverOptionNumber ();
536 sizeof (DriverString
),
541 if (*DescriptionData
== 0x0000) {
542 StrCpy (DescriptionData
, DriverString
);
545 BufferSize
= sizeof (UINT32
) + sizeof (UINT16
) + StrSize (DescriptionData
) + GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
);
547 if (*OptionalData
!= 0x0000) {
548 OptionalDataExist
= TRUE
;
549 BufferSize
+= StrSize (OptionalData
);
552 Buffer
= AllocateZeroPool (BufferSize
);
553 if (NULL
== Buffer
) {
554 return EFI_OUT_OF_RESOURCES
;
557 NewMenuEntry
= BOpt_CreateMenuEntry (BM_LOAD_CONTEXT_SELECT
);
558 if (NULL
== NewMenuEntry
) {
559 return EFI_OUT_OF_RESOURCES
;
562 NewLoadContext
= (BM_LOAD_CONTEXT
*) NewMenuEntry
->VariableContext
;
563 NewLoadContext
->Deleted
= FALSE
;
564 NewLoadContext
->LoadOptionSize
= BufferSize
;
565 Ptr
= (UINT8
*) Buffer
;
566 NewLoadContext
->LoadOption
= Ptr
;
567 *((UINT32
*) Ptr
) = LOAD_OPTION_ACTIVE
| (ForceReconnect
<< 1);
568 NewLoadContext
->Attributes
= *((UINT32
*) Ptr
);
569 NewLoadContext
->IsActive
= TRUE
;
570 NewLoadContext
->ForceReconnect
= (BOOLEAN
) (NewLoadContext
->Attributes
& LOAD_OPTION_FORCE_RECONNECT
);
572 Ptr
+= sizeof (UINT32
);
573 *((UINT16
*) Ptr
) = (UINT16
) GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
);
574 NewLoadContext
->FilePathListLength
= *((UINT16
*) Ptr
);
576 Ptr
+= sizeof (UINT16
);
580 StrSize (DescriptionData
)
583 NewLoadContext
->Description
= AllocateZeroPool (StrSize (DescriptionData
));
584 ASSERT (NewLoadContext
->Description
!= NULL
);
585 NewMenuEntry
->DisplayString
= NewLoadContext
->Description
;
587 NewLoadContext
->Description
,
589 StrSize (DescriptionData
)
592 Ptr
+= StrSize (DescriptionData
);
595 CallbackData
->LoadContext
->FilePathList
,
596 GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
)
599 NewLoadContext
->FilePathList
= AllocateZeroPool (GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
));
600 ASSERT (NewLoadContext
->FilePathList
!= NULL
);
603 NewLoadContext
->FilePathList
,
605 GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
)
608 NewMenuEntry
->HelpString
= DevicePathToStr (NewLoadContext
->FilePathList
);
609 NewMenuEntry
->OptionNumber
= Index
;
610 NewMenuEntry
->DisplayStringToken
= GetStringTokenFromDepository (
612 DriverOptionStrDepository
614 CallbackData
->Hii
->NewString (
618 &NewMenuEntry
->DisplayStringToken
,
619 NewMenuEntry
->DisplayString
622 NewMenuEntry
->HelpStringToken
= GetStringTokenFromDepository (
624 DriverOptionHelpStrDepository
626 CallbackData
->Hii
->NewString (
630 &NewMenuEntry
->HelpStringToken
,
631 NewMenuEntry
->HelpString
634 if (OptionalDataExist
) {
635 Ptr
+= (UINT8
) GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
);
640 StrSize (OptionalData
)
644 Status
= gRT
->SetVariable (
646 &gEfiGlobalVariableGuid
,
651 DriverOrderList
= BdsLibGetVariableAndSize (
653 &gEfiGlobalVariableGuid
,
656 NewDriverOrderList
= AllocateZeroPool (DriverOrderListSize
+ sizeof (UINT16
));
657 ASSERT (NewDriverOrderList
!= NULL
);
658 CopyMem (NewDriverOrderList
, DriverOrderList
, DriverOrderListSize
);
659 NewDriverOrderList
[DriverOrderListSize
/ sizeof (UINT16
)] = Index
;
660 if (DriverOrderList
!= NULL
) {
661 EfiLibDeleteVariable (L
"DriverOrder", &gEfiGlobalVariableGuid
);
664 Status
= gRT
->SetVariable (
666 &gEfiGlobalVariableGuid
,
668 DriverOrderListSize
+ sizeof (UINT16
),
671 SafeFreePool (DriverOrderList
);
672 DriverOrderList
= NULL
;
673 SafeFreePool (NewDriverOrderList
);
674 NewDriverOrderList
= NULL
;
675 InsertTailList (&DriverOptionMenu
.Head
, &NewMenuEntry
->Link
);
676 DriverOptionMenu
.MenuNumber
++;
678 *DescriptionData
= 0x0000;
679 *OptionalData
= 0x0000;
684 Var_UpdateBootOption (
685 IN BMM_CALLBACK_DATA
*CallbackData
,
686 IN FILE_EXPLORER_NV_DATA
*NvRamMap
689 UINT16
*BootOrderList
;
690 UINT16
*NewBootOrderList
;
691 UINTN BootOrderListSize
;
692 UINT16 BootString
[10];
697 BM_MENU_ENTRY
*NewMenuEntry
;
698 BM_LOAD_CONTEXT
*NewLoadContext
;
699 BOOLEAN OptionalDataExist
;
702 OptionalDataExist
= FALSE
;
704 Index
= BOpt_GetBootOptionNumber ();
705 UnicodeSPrint (BootString
, sizeof (BootString
), L
"Boot%04x", Index
);
707 if (NvRamMap
->DescriptionData
[0] == 0x0000) {
708 StrCpy (NvRamMap
->DescriptionData
, BootString
);
711 BufferSize
= sizeof (UINT32
) + sizeof (UINT16
) + StrSize (NvRamMap
->DescriptionData
) + GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
);
713 if (NvRamMap
->OptionalData
[0] != 0x0000) {
714 OptionalDataExist
= TRUE
;
715 BufferSize
+= StrSize (NvRamMap
->OptionalData
);
718 Buffer
= AllocateZeroPool (BufferSize
);
719 if (NULL
== Buffer
) {
720 return EFI_OUT_OF_RESOURCES
;
723 NewMenuEntry
= BOpt_CreateMenuEntry (BM_LOAD_CONTEXT_SELECT
);
724 if (NULL
== NewMenuEntry
) {
725 return EFI_OUT_OF_RESOURCES
;
728 NewLoadContext
= (BM_LOAD_CONTEXT
*) NewMenuEntry
->VariableContext
;
729 NewLoadContext
->Deleted
= FALSE
;
730 NewLoadContext
->LoadOptionSize
= BufferSize
;
731 Ptr
= (UINT8
*) Buffer
;
732 NewLoadContext
->LoadOption
= Ptr
;
733 *((UINT32
*) Ptr
) = LOAD_OPTION_ACTIVE
;
734 NewLoadContext
->Attributes
= *((UINT32
*) Ptr
);
735 NewLoadContext
->IsActive
= TRUE
;
736 NewLoadContext
->ForceReconnect
= (BOOLEAN
) (NewLoadContext
->Attributes
& LOAD_OPTION_FORCE_RECONNECT
);
738 Ptr
+= sizeof (UINT32
);
739 *((UINT16
*) Ptr
) = (UINT16
) GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
);
740 NewLoadContext
->FilePathListLength
= *((UINT16
*) Ptr
);
741 Ptr
+= sizeof (UINT16
);
745 NvRamMap
->DescriptionData
,
746 StrSize (NvRamMap
->DescriptionData
)
749 NewLoadContext
->Description
= AllocateZeroPool (StrSize (NvRamMap
->DescriptionData
));
750 ASSERT (NewLoadContext
->Description
!= NULL
);
752 NewMenuEntry
->DisplayString
= NewLoadContext
->Description
;
754 NewLoadContext
->Description
,
756 StrSize (NvRamMap
->DescriptionData
)
759 Ptr
+= StrSize (NvRamMap
->DescriptionData
);
762 CallbackData
->LoadContext
->FilePathList
,
763 GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
)
766 NewLoadContext
->FilePathList
= AllocateZeroPool (GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
));
767 ASSERT (NewLoadContext
->FilePathList
!= NULL
);
770 NewLoadContext
->FilePathList
,
772 GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
)
775 NewMenuEntry
->HelpString
= DevicePathToStr (NewLoadContext
->FilePathList
);
776 NewMenuEntry
->OptionNumber
= Index
;
777 NewMenuEntry
->DisplayStringToken
= GetStringTokenFromDepository (
779 BootOptionStrDepository
781 CallbackData
->Hii
->NewString (
784 CallbackData
->FeHiiHandle
,
785 &NewMenuEntry
->DisplayStringToken
,
786 NewMenuEntry
->DisplayString
789 NewMenuEntry
->HelpStringToken
= GetStringTokenFromDepository (
791 BootOptionHelpStrDepository
794 CallbackData
->Hii
->NewString (
797 CallbackData
->FeHiiHandle
,
798 &NewMenuEntry
->HelpStringToken
,
799 NewMenuEntry
->HelpString
802 if (OptionalDataExist
) {
803 Ptr
+= (UINT8
) GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
);
805 CopyMem (Ptr
, NvRamMap
->OptionalData
, StrSize (NvRamMap
->OptionalData
));
808 Status
= gRT
->SetVariable (
810 &gEfiGlobalVariableGuid
,
816 BootOrderList
= BdsLibGetVariableAndSize (
818 &gEfiGlobalVariableGuid
,
822 NewBootOrderList
= AllocateZeroPool (BootOrderListSize
+ sizeof (UINT16
));
823 ASSERT (NewBootOrderList
!= NULL
);
824 CopyMem (NewBootOrderList
, BootOrderList
, BootOrderListSize
);
825 NewBootOrderList
[BootOrderListSize
/ sizeof (UINT16
)] = Index
;
827 if (BootOrderList
!= NULL
) {
828 EfiLibDeleteVariable (L
"BootOrder", &gEfiGlobalVariableGuid
);
831 Status
= gRT
->SetVariable (
833 &gEfiGlobalVariableGuid
,
835 BootOrderListSize
+ sizeof (UINT16
),
839 SafeFreePool (BootOrderList
);
840 BootOrderList
= NULL
;
841 SafeFreePool (NewBootOrderList
);
842 NewBootOrderList
= NULL
;
843 InsertTailList (&BootOptionMenu
.Head
, &NewMenuEntry
->Link
);
844 BootOptionMenu
.MenuNumber
++;
846 NvRamMap
->DescriptionData
[0] = 0x0000;
847 NvRamMap
->OptionalData
[0] = 0x0000;
853 IN BMM_CALLBACK_DATA
*CallbackData
856 BM_MENU_ENTRY
*NewMenuEntry
;
857 BM_LOAD_CONTEXT
*NewLoadContext
;
858 BMM_FAKE_NV_DATA
*CurrentFakeNVMap
;
862 Status
= EFI_SUCCESS
;
863 CurrentFakeNVMap
= CallbackData
->BmmFakeNvData
;
864 for (Index
= 0; Index
< BootOptionMenu
.MenuNumber
; Index
++) {
865 NewMenuEntry
= BOpt_GetMenuEntry (&BootOptionMenu
, Index
);
866 if (NULL
== NewMenuEntry
) {
867 return EFI_NOT_FOUND
;
870 NewLoadContext
= (BM_LOAD_CONTEXT
*) NewMenuEntry
->VariableContext
;
871 NewLoadContext
->IsBootNext
= FALSE
;
874 if (CurrentFakeNVMap
->BootNext
== BootOptionMenu
.MenuNumber
) {
875 EfiLibDeleteVariable (L
"BootNext", &gEfiGlobalVariableGuid
);
879 NewMenuEntry
= BOpt_GetMenuEntry (
881 CurrentFakeNVMap
->BootNext
883 if (NULL
== NewMenuEntry
) {
884 return EFI_NOT_FOUND
;
887 NewLoadContext
= (BM_LOAD_CONTEXT
*) NewMenuEntry
->VariableContext
;
888 Status
= gRT
->SetVariable (
890 &gEfiGlobalVariableGuid
,
893 &NewMenuEntry
->OptionNumber
895 NewLoadContext
->IsBootNext
= TRUE
;
896 CallbackData
->BmmOldFakeNVData
.BootNext
= CurrentFakeNVMap
->BootNext
;
901 Var_UpdateBootOrder (
902 IN BMM_CALLBACK_DATA
*CallbackData
907 UINT16
*BootOrderList
;
908 UINT16
*NewBootOrderList
;
909 UINTN BootOrderListSize
;
912 BootOrderList
= NULL
;
913 BootOrderListSize
= 0;
916 // First check whether BootOrder is present in current configuration
918 BootOrderList
= BdsLibGetVariableAndSize (
920 &gEfiGlobalVariableGuid
,
924 NewBootOrderList
= AllocateZeroPool (BootOrderListSize
);
925 if (!NewBootOrderList
) {
926 return EFI_OUT_OF_RESOURCES
;
929 Map
= AllocateZeroPool (BootOrderListSize
/ sizeof (UINT16
));
931 return EFI_OUT_OF_RESOURCES
;
934 // If exists, delete it to hold new BootOrder
937 EfiLibDeleteVariable (L
"BootOrder", &gEfiGlobalVariableGuid
);
940 for (Index
= 0; Index
< BootOptionMenu
.MenuNumber
; Index
++) {
941 NewBootOrderList
[Index
] = CallbackData
->BmmFakeNvData
->OptionOrder
[Index
] - 1;
944 Status
= gRT
->SetVariable (
946 &gEfiGlobalVariableGuid
,
951 SafeFreePool (BootOrderList
);
952 SafeFreePool (NewBootOrderList
);
954 if (EFI_ERROR (Status
)) {
958 BOpt_FreeMenu (&BootOptionMenu
);
959 BOpt_GetBootOptions (CallbackData
);
966 Var_UpdateDriverOrder (
967 IN BMM_CALLBACK_DATA
*CallbackData
972 UINT16
*DriverOrderList
;
973 UINT16
*NewDriverOrderList
;
974 UINTN DriverOrderListSize
;
976 DriverOrderList
= NULL
;
977 DriverOrderListSize
= 0;
980 // First check whether DriverOrder is present in current configuration
982 DriverOrderList
= BdsLibGetVariableAndSize (
984 &gEfiGlobalVariableGuid
,
988 NewDriverOrderList
= AllocateZeroPool (DriverOrderListSize
);
990 if (!NewDriverOrderList
) {
991 return EFI_OUT_OF_RESOURCES
;
994 // If exists, delete it to hold new DriverOrder
996 if (DriverOrderList
) {
997 EfiLibDeleteVariable (L
"DriverOrder", &gEfiGlobalVariableGuid
);
1000 for (Index
= 0; Index
< DriverOrderListSize
; Index
++) {
1001 NewDriverOrderList
[Index
] = CallbackData
->BmmFakeNvData
->OptionOrder
[Index
] - 1;
1004 Status
= gRT
->SetVariable (
1006 &gEfiGlobalVariableGuid
,
1008 DriverOrderListSize
,
1011 if (EFI_ERROR (Status
)) {
1015 SafeFreePool (DriverOrderList
);
1017 BOpt_FreeMenu (&DriverOptionMenu
);
1018 BOpt_GetDriverOptions (CallbackData
);
1023 Var_UpdateBBSOption (
1024 IN BMM_CALLBACK_DATA
*CallbackData
1029 VOID
*BootOptionVar
;
1030 CHAR16 VarName
[100];
1032 UINT16 FilePathSize
;
1035 CHAR16 DescString
[100];
1036 UINTN NewOptionSize
;
1037 UINT8
*NewOptionPtr
;
1041 BM_MENU_OPTION
*OptionMenu
;
1042 BM_LEGACY_DEVICE_CONTEXT
*LegacyDeviceContext
;
1046 BM_MENU_ENTRY
*NewMenuEntry
;
1047 BM_LEGACY_DEV_ORDER_CONTEXT
*DevOrder
;
1055 LegacyDeviceContext
= NULL
;
1059 if (FORM_SET_FD_ORDER_ID
== CallbackData
->BmmPreviousPageId
) {
1060 OptionMenu
= (BM_MENU_OPTION
*) &LegacyFDMenu
;
1061 LegacyDev
= CallbackData
->BmmFakeNvData
->LegacyFD
;
1062 CallbackData
->BbsType
= BBS_FLOPPY
;
1064 if (FORM_SET_HD_ORDER_ID
== CallbackData
->BmmPreviousPageId
) {
1065 OptionMenu
= (BM_MENU_OPTION
*) &LegacyHDMenu
;
1066 LegacyDev
= CallbackData
->BmmFakeNvData
->LegacyHD
;
1067 CallbackData
->BbsType
= BBS_HARDDISK
;
1069 if (FORM_SET_CD_ORDER_ID
== CallbackData
->BmmPreviousPageId
) {
1070 OptionMenu
= (BM_MENU_OPTION
*) &LegacyCDMenu
;
1071 LegacyDev
= CallbackData
->BmmFakeNvData
->LegacyCD
;
1072 CallbackData
->BbsType
= BBS_CDROM
;
1074 if (FORM_SET_NET_ORDER_ID
== CallbackData
->BmmPreviousPageId
) {
1075 OptionMenu
= (BM_MENU_OPTION
*) &LegacyNETMenu
;
1076 LegacyDev
= CallbackData
->BmmFakeNvData
->LegacyNET
;
1077 CallbackData
->BbsType
= BBS_EMBED_NETWORK
;
1079 OptionMenu
= (BM_MENU_OPTION
*) &LegacyBEVMenu
;
1080 LegacyDev
= CallbackData
->BmmFakeNvData
->LegacyBEV
;
1081 CallbackData
->BbsType
= BBS_BEV_DEVICE
;
1087 DisMap
= CallbackData
->BmmOldFakeNVData
.DisableMap
;
1088 Status
= EFI_SUCCESS
;
1091 // Find the first device's context
1092 // If all devices are disabled( 0xFF == LegacyDev[0]), LegacyDeviceContext can be set to any VariableContext
1093 // because we just use it to fill the desc string, and user can not see the string in UI
1095 for (Index
= 0; Index
< OptionMenu
->MenuNumber
; Index
++) {
1096 NewMenuEntry
= BOpt_GetMenuEntry (OptionMenu
, Index
);
1097 LegacyDeviceContext
= (BM_LEGACY_DEVICE_CONTEXT
*) NewMenuEntry
->VariableContext
;
1098 if (0xFF != LegacyDev
[0] && LegacyDev
[0] == LegacyDeviceContext
->Index
) {
1099 DEBUG ((EFI_D_ERROR
, "DescStr: %s\n", LegacyDeviceContext
->Description
));
1104 // Update the Variable "LegacyDevOrder"
1106 VarData
= (UINT8
*) BdsLibGetVariableAndSize (
1108 &EfiLegacyDevOrderGuid
,
1112 if (NULL
== VarData
) {
1113 return EFI_NOT_FOUND
;
1116 OriginalPtr
= VarData
;
1117 DevOrder
= (BM_LEGACY_DEV_ORDER_CONTEXT
*) VarData
;
1119 while (VarData
< VarData
+ VarSize
) {
1120 if (DevOrder
->BbsType
== CallbackData
->BbsType
) {
1124 VarData
+= sizeof (BBS_TYPE
);
1125 VarData
+= *(UINT16
*) VarData
;
1126 DevOrder
= (BM_LEGACY_DEV_ORDER_CONTEXT
*) VarData
;
1129 if (VarData
>= VarData
+ VarSize
) {
1130 SafeFreePool (OriginalPtr
);
1131 return EFI_NOT_FOUND
;
1134 NewOrder
= (UINT16
*) AllocateZeroPool (DevOrder
->Length
- sizeof (UINT16
));
1135 if (NULL
== NewOrder
) {
1136 SafeFreePool (VarData
);
1137 return EFI_OUT_OF_RESOURCES
;
1140 for (Index
= 0; Index
< OptionMenu
->MenuNumber
; Index
++) {
1141 if (0xFF == LegacyDev
[Index
]) {
1145 NewOrder
[Index
] = LegacyDev
[Index
];
1148 // Only the enable/disable state of each boot device with same device type can be changed,
1149 // so we can count on the index information in DevOrder.
1150 // DisMap bit array is the only reliable source to check a device's en/dis state,
1151 // so we use DisMap to set en/dis state of each item in NewOrder array
1153 for (Index2
= 0; Index2
< OptionMenu
->MenuNumber
; Index2
++) {
1154 Tmp
= *(UINT16
*) ((UINT8
*) DevOrder
+ sizeof (BBS_TYPE
) + sizeof (UINT16
) + Index2
* sizeof (UINT16
));
1157 Bit
= 7 - (Tmp
% 8);
1158 if (DisMap
[Pos
] & (1 << Bit
)) {
1159 NewOrder
[Index
] = (UINT16
) (0xFF00 | Tmp
);
1165 (UINT8
*) DevOrder
+ sizeof (BBS_TYPE
) + sizeof (UINT16
),
1167 DevOrder
->Length
- sizeof (UINT16
)
1169 SafeFreePool (NewOrder
);
1171 Status
= gRT
->SetVariable (
1173 &EfiLegacyDevOrderGuid
,
1179 SafeFreePool (OriginalPtr
);
1182 // Update Optional Data of Boot####
1184 BootOptionVar
= GetLegacyBootOptionVar (CallbackData
->BbsType
, &Index
, &OptionSize
);
1186 if (NULL
!= BootOptionVar
) {
1189 LegacyDeviceContext
->Description
,
1190 StrSize (LegacyDeviceContext
->Description
)
1193 NewOptionSize
= sizeof (UINT32
) + sizeof (UINT16
) + StrSize (DescString
) + sizeof (BBS_TABLE
) + sizeof (UINT16
);
1195 UnicodeSPrint (VarName
, 100, L
"Boot%04x", Index
);
1197 Ptr
= BootOptionVar
;
1199 Attribute
= (UINT32
*) Ptr
;
1200 *Attribute
|= LOAD_OPTION_ACTIVE
;
1201 if (0xFF == LegacyDev
[0]) {
1203 // Disable this legacy boot option
1205 *Attribute
&= ~LOAD_OPTION_ACTIVE
;
1208 Ptr
+= sizeof (UINT32
);
1210 FilePathSize
= *(UINT16
*) Ptr
;
1211 Ptr
+= sizeof (UINT16
);
1213 NewOptionSize
+= FilePathSize
;
1215 NewOptionPtr
= AllocateZeroPool (NewOptionSize
);
1216 if (NULL
== NewOptionPtr
) {
1217 return EFI_OUT_OF_RESOURCES
;
1220 TempPtr
= NewOptionPtr
;
1223 // Copy previous option data to new option except the description string
1228 sizeof (UINT32
) + sizeof (UINT16
)
1231 TempPtr
+= (sizeof (UINT32
) + sizeof (UINT16
));
1236 StrSize (DescString
)
1239 TempPtr
+= StrSize (DescString
);
1242 // Description = (CHAR16 *)Ptr;
1244 Ptr
+= StrSize ((CHAR16
*) Ptr
);
1252 TempPtr
+= FilePathSize
;
1255 // DevicePath = (EFI_DEVICE_PATH_PROTOCOL *)Ptr;
1257 Ptr
+= FilePathSize
;
1260 // Now Ptr point to optional data, i.e. Bbs Table
1264 LegacyDeviceContext
->BbsTable
,
1268 TempPtr
+= sizeof (BBS_TABLE
);
1269 *((UINT16
*) TempPtr
) = (UINT16
) LegacyDeviceContext
->Index
;
1271 Status
= gRT
->SetVariable (
1273 &gEfiGlobalVariableGuid
,
1279 SafeFreePool (NewOptionPtr
);
1280 SafeFreePool (BootOptionVar
);
1283 BOpt_GetBootOptions (CallbackData
);