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 "BootMaint.h"
32 Delete Boot Option that represent a Deleted state in BootOptionMenu.
33 After deleting this boot option, call Var_ChangeBootOrder to
34 make sure BootOrder is in valid state.
37 LoadOption -- Pointer to the boot option that to be deleted
45 BM_MENU_ENTRY
*NewMenuEntry
;
46 BM_LOAD_CONTEXT
*NewLoadContext
;
48 UINT16 BootString
[10];
55 for (Index
= 0; Index
< BootOptionMenu
.MenuNumber
; Index
++) {
56 NewMenuEntry
= BOpt_GetMenuEntry (&BootOptionMenu
, (Index
- Index2
));
57 if (NULL
== NewMenuEntry
) {
61 NewLoadContext
= (BM_LOAD_CONTEXT
*) NewMenuEntry
->VariableContext
;
62 if (!NewLoadContext
->Deleted
) {
70 NewMenuEntry
->OptionNumber
73 EfiLibDeleteVariable (BootString
, &gEfiGlobalVariableGuid
);
76 // If current Load Option is the same as BootNext,
77 // must delete BootNext in order to make sure
78 // there will be no panic on next boot
80 if (NewLoadContext
->IsBootNext
) {
81 EfiLibDeleteVariable (L
"BootNext", &gEfiGlobalVariableGuid
);
84 RemoveEntryList (&NewMenuEntry
->Link
);
85 BOpt_DestroyMenuEntry (NewMenuEntry
);
89 BootOptionMenu
.MenuNumber
-= Index2
;
91 Status
= Var_ChangeBootOrder ();
102 After any operation on Boot####, there will be a discrepancy in BootOrder.
103 Since some are missing but in BootOrder, while some are present but are
104 not reflected by BootOrder. Then a function rebuild BootOrder from
105 scratch by content from BootOptionMenu is needed.
117 BM_MENU_ENTRY
*NewMenuEntry
;
118 UINT16
*BootOrderList
;
119 UINT16
*BootOrderListPtr
;
120 UINTN BootOrderListSize
;
123 BootOrderList
= NULL
;
124 BootOrderListSize
= 0;
127 // First check whether BootOrder is present in current configuration
129 BootOrderList
= BdsLibGetVariableAndSize (
131 &gEfiGlobalVariableGuid
,
136 // If exists, delete it to hold new BootOrder
139 EfiLibDeleteVariable (L
"BootOrder", &gEfiGlobalVariableGuid
);
140 SafeFreePool (BootOrderList
);
141 BootOrderList
= NULL
;
144 // Maybe here should be some check method to ensure that
145 // no new added boot options will be added
146 // but the setup engine now will give only one callback
147 // that is to say, user are granted only one chance to
148 // decide whether the boot option will be added or not
149 // there should be no indictor to show whether this
150 // is a "new" boot option
152 BootOrderListSize
= BootOptionMenu
.MenuNumber
;
154 if (BootOrderListSize
> 0) {
155 BootOrderList
= AllocateZeroPool (BootOrderListSize
* sizeof (UINT16
));
156 ASSERT (BootOrderList
!= NULL
);
157 BootOrderListPtr
= BootOrderList
;
160 // Get all current used Boot#### from BootOptionMenu.
161 // OptionNumber in each BM_LOAD_OPTION is really its
164 for (Index
= 0; Index
< BootOrderListSize
; Index
++) {
165 NewMenuEntry
= BOpt_GetMenuEntry (&BootOptionMenu
, Index
);
166 *BootOrderList
= (UINT16
) NewMenuEntry
->OptionNumber
;
170 BootOrderList
= BootOrderListPtr
;
173 // After building the BootOrderList, write it back
175 Status
= gRT
->SetVariable (
177 &gEfiGlobalVariableGuid
,
179 BootOrderListSize
* sizeof (UINT16
),
182 if (EFI_ERROR (Status
)) {
190 Var_DelDriverOption (
196 Delete Load Option that represent a Deleted state in BootOptionMenu.
197 After deleting this Driver option, call Var_ChangeDriverOrder to
198 make sure DriverOrder is in valid state.
201 LoadOption -- Pointer to the Driver option that to be deleted
209 BM_MENU_ENTRY
*NewMenuEntry
;
210 BM_LOAD_CONTEXT
*NewLoadContext
;
212 UINT16 DriverString
[12];
217 Status
= EFI_SUCCESS
;
219 for (Index
= 0; Index
< DriverOptionMenu
.MenuNumber
; Index
++) {
220 NewMenuEntry
= BOpt_GetMenuEntry (&DriverOptionMenu
, (Index
- Index2
));
221 if (NULL
== NewMenuEntry
) {
222 return EFI_NOT_FOUND
;
225 NewLoadContext
= (BM_LOAD_CONTEXT
*) NewMenuEntry
->VariableContext
;
226 if (!NewLoadContext
->Deleted
) {
232 sizeof (DriverString
),
234 NewMenuEntry
->OptionNumber
237 EfiLibDeleteVariable (DriverString
, &gEfiGlobalVariableGuid
);
240 RemoveEntryList (&NewMenuEntry
->Link
);
241 BOpt_DestroyMenuEntry (NewMenuEntry
);
245 DriverOptionMenu
.MenuNumber
-= Index2
;
247 Status
= Var_ChangeDriverOrder ();
252 Var_ChangeDriverOrder (
258 After any operation on Driver####, there will be a discrepancy in
259 DriverOrder. Since some are missing but in DriverOrder, while some
260 are present but are not reflected by DriverOrder. Then a function
261 rebuild DriverOrder from scratch by content from DriverOptionMenu is
273 BM_MENU_ENTRY
*NewMenuEntry
;
274 UINT16
*DriverOrderList
;
275 UINT16
*DriverOrderListPtr
;
276 UINTN DriverOrderListSize
;
279 DriverOrderList
= NULL
;
280 DriverOrderListSize
= 0;
283 // First check whether DriverOrder is present in current configuration
285 DriverOrderList
= BdsLibGetVariableAndSize (
287 &gEfiGlobalVariableGuid
,
292 // If exists, delete it to hold new DriverOrder
294 if (DriverOrderList
) {
295 EfiLibDeleteVariable (L
"DriverOrder", &gEfiGlobalVariableGuid
);
296 SafeFreePool (DriverOrderList
);
297 DriverOrderList
= NULL
;
300 DriverOrderListSize
= DriverOptionMenu
.MenuNumber
;
302 if (DriverOrderListSize
> 0) {
303 DriverOrderList
= AllocateZeroPool (DriverOrderListSize
* sizeof (UINT16
));
304 ASSERT (DriverOrderList
!= NULL
);
305 DriverOrderListPtr
= DriverOrderList
;
308 // Get all current used Driver#### from DriverOptionMenu.
309 // OptionNumber in each BM_LOAD_OPTION is really its
312 for (Index
= 0; Index
< DriverOrderListSize
; Index
++) {
313 NewMenuEntry
= BOpt_GetMenuEntry (&DriverOptionMenu
, Index
);
314 *DriverOrderList
= (UINT16
) NewMenuEntry
->OptionNumber
;
318 DriverOrderList
= DriverOrderListPtr
;
321 // After building the DriverOrderList, write it back
323 Status
= gRT
->SetVariable (
325 &gEfiGlobalVariableGuid
,
327 DriverOrderListSize
* sizeof (UINT16
),
330 if (EFI_ERROR (Status
)) {
338 Var_UpdateAllConsoleOption (
342 EFI_DEVICE_PATH_PROTOCOL
*OutDevicePath
;
343 EFI_DEVICE_PATH_PROTOCOL
*InpDevicePath
;
344 EFI_DEVICE_PATH_PROTOCOL
*ErrDevicePath
;
347 OutDevicePath
= EfiLibGetVariable (L
"ConOut", &gEfiGlobalVariableGuid
);
348 InpDevicePath
= EfiLibGetVariable (L
"ConIn", &gEfiGlobalVariableGuid
);
349 ErrDevicePath
= EfiLibGetVariable (L
"ErrOut", &gEfiGlobalVariableGuid
);
351 ChangeVariableDevicePath (OutDevicePath
);
352 Status
= gRT
->SetVariable (
354 &gEfiGlobalVariableGuid
,
356 GetDevicePathSize (OutDevicePath
),
359 ASSERT (!EFI_ERROR (Status
));
363 ChangeVariableDevicePath (InpDevicePath
);
364 Status
= gRT
->SetVariable (
366 &gEfiGlobalVariableGuid
,
368 GetDevicePathSize (InpDevicePath
),
371 ASSERT (!EFI_ERROR (Status
));
375 ChangeVariableDevicePath (ErrDevicePath
);
376 Status
= gRT
->SetVariable (
378 &gEfiGlobalVariableGuid
,
380 GetDevicePathSize (ErrDevicePath
),
383 ASSERT (!EFI_ERROR (Status
));
388 Var_UpdateConsoleOption (
389 IN UINT16
*ConsoleName
,
390 IN BM_MENU_OPTION
*ConsoleMenu
,
391 IN UINT16 UpdatePageId
394 EFI_DEVICE_PATH_PROTOCOL
*ConDevicePath
;
395 BM_MENU_ENTRY
*NewMenuEntry
;
396 BM_CONSOLE_CONTEXT
*NewConsoleContext
;
397 BM_TERMINAL_CONTEXT
*NewTerminalContext
;
399 VENDOR_DEVICE_PATH Vendor
;
400 EFI_DEVICE_PATH_PROTOCOL
*TerminalDevicePath
;
404 ConDevicePath
= EfiLibGetVariable (ConsoleName
, &gEfiGlobalVariableGuid
);
405 if (ConDevicePath
!= NULL
) {
406 EfiLibDeleteVariable (ConsoleName
, &gEfiGlobalVariableGuid
);
407 SafeFreePool (ConDevicePath
);
408 ConDevicePath
= NULL
;
412 // First add all console input device to it from console input menu
414 for (Index
= 0; Index
< ConsoleMenu
->MenuNumber
; Index
++) {
415 NewMenuEntry
= BOpt_GetMenuEntry (ConsoleMenu
, Index
);
416 if (NULL
== NewMenuEntry
) {
417 return EFI_NOT_FOUND
;
420 NewConsoleContext
= (BM_CONSOLE_CONTEXT
*) NewMenuEntry
->VariableContext
;
421 if (NewConsoleContext
->IsActive
) {
422 ConDevicePath
= AppendDevicePathInstance (
424 NewConsoleContext
->DevicePath
429 for (Index
= 0; Index
< TerminalMenu
.MenuNumber
; Index
++) {
430 NewMenuEntry
= BOpt_GetMenuEntry (&TerminalMenu
, Index
);
431 if (NULL
== NewMenuEntry
) {
432 return EFI_NOT_FOUND
;
435 NewTerminalContext
= (BM_TERMINAL_CONTEXT
*) NewMenuEntry
->VariableContext
;
436 if ((NewTerminalContext
->IsConIn
&& (UpdatePageId
== FORM_CON_IN_ID
)) ||
437 (NewTerminalContext
->IsConOut
&& (UpdatePageId
== FORM_CON_OUT_ID
)) ||
438 (NewTerminalContext
->IsStdErr
&& (UpdatePageId
== FORM_CON_ERR_ID
))
440 Vendor
.Header
.Type
= MESSAGING_DEVICE_PATH
;
441 Vendor
.Header
.SubType
= MSG_VENDOR_DP
;
444 &Guid
[NewTerminalContext
->TerminalType
],
447 SetDevicePathNodeLength (&Vendor
.Header
, sizeof (VENDOR_DEVICE_PATH
));
448 TerminalDevicePath
= AppendDevicePathNode (
449 NewTerminalContext
->DevicePath
,
450 (EFI_DEVICE_PATH_PROTOCOL
*) &Vendor
452 ChangeTerminalDevicePath (TerminalDevicePath
, TRUE
);
453 Temp
= DevicePathToStr (TerminalDevicePath
);
454 ConDevicePath
= AppendDevicePathInstance (
462 Status
= gRT
->SetVariable (
464 &gEfiGlobalVariableGuid
,
466 GetDevicePathSize (ConDevicePath
),
469 if (EFI_ERROR (Status
)) {
479 Var_UpdateConsoleInpOption (
483 return Var_UpdateConsoleOption (L
"ConIn", &ConsoleInpMenu
, FORM_CON_IN_ID
);
487 Var_UpdateConsoleOutOption (
491 return Var_UpdateConsoleOption (L
"ConOut", &ConsoleOutMenu
, FORM_CON_OUT_ID
);
495 Var_UpdateErrorOutOption (
499 return Var_UpdateConsoleOption (L
"ErrOut", &ConsoleErrMenu
, FORM_CON_ERR_ID
);
503 Var_UpdateDriverOption (
504 IN BMM_CALLBACK_DATA
*CallbackData
,
505 IN EFI_HII_HANDLE HiiHandle
,
506 IN UINT16
*DescriptionData
,
507 IN UINT16
*OptionalData
,
508 IN UINT8 ForceReconnect
512 UINT16
*DriverOrderList
;
513 UINT16
*NewDriverOrderList
;
514 UINT16 DriverString
[12];
515 UINTN DriverOrderListSize
;
519 BM_MENU_ENTRY
*NewMenuEntry
;
520 BM_LOAD_CONTEXT
*NewLoadContext
;
521 BOOLEAN OptionalDataExist
;
524 OptionalDataExist
= FALSE
;
526 Index
= BOpt_GetDriverOptionNumber ();
529 sizeof (DriverString
),
534 if (*DescriptionData
== 0x0000) {
535 StrCpy (DescriptionData
, DriverString
);
538 BufferSize
= sizeof (UINT32
) + sizeof (UINT16
) + StrSize (DescriptionData
) + GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
);
540 if (*OptionalData
!= 0x0000) {
541 OptionalDataExist
= TRUE
;
542 BufferSize
+= StrSize (OptionalData
);
545 Buffer
= AllocateZeroPool (BufferSize
);
546 if (NULL
== Buffer
) {
547 return EFI_OUT_OF_RESOURCES
;
550 NewMenuEntry
= BOpt_CreateMenuEntry (BM_LOAD_CONTEXT_SELECT
);
551 if (NULL
== NewMenuEntry
) {
552 return EFI_OUT_OF_RESOURCES
;
555 NewLoadContext
= (BM_LOAD_CONTEXT
*) NewMenuEntry
->VariableContext
;
556 NewLoadContext
->Deleted
= FALSE
;
557 NewLoadContext
->LoadOptionSize
= BufferSize
;
558 Ptr
= (UINT8
*) Buffer
;
559 NewLoadContext
->LoadOption
= Ptr
;
560 *((UINT32
*) Ptr
) = LOAD_OPTION_ACTIVE
| (ForceReconnect
<< 1);
561 NewLoadContext
->Attributes
= *((UINT32
*) Ptr
);
562 NewLoadContext
->IsActive
= TRUE
;
563 NewLoadContext
->ForceReconnect
= (BOOLEAN
) (NewLoadContext
->Attributes
& LOAD_OPTION_FORCE_RECONNECT
);
565 Ptr
+= sizeof (UINT32
);
566 *((UINT16
*) Ptr
) = (UINT16
) GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
);
567 NewLoadContext
->FilePathListLength
= *((UINT16
*) Ptr
);
569 Ptr
+= sizeof (UINT16
);
573 StrSize (DescriptionData
)
576 NewLoadContext
->Description
= AllocateZeroPool (StrSize (DescriptionData
));
577 ASSERT (NewLoadContext
->Description
!= NULL
);
578 NewMenuEntry
->DisplayString
= NewLoadContext
->Description
;
580 NewLoadContext
->Description
,
582 StrSize (DescriptionData
)
585 Ptr
+= StrSize (DescriptionData
);
588 CallbackData
->LoadContext
->FilePathList
,
589 GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
)
592 NewLoadContext
->FilePathList
= AllocateZeroPool (GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
));
593 ASSERT (NewLoadContext
->FilePathList
!= NULL
);
596 NewLoadContext
->FilePathList
,
598 GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
)
601 NewMenuEntry
->HelpString
= DevicePathToStr (NewLoadContext
->FilePathList
);
602 NewMenuEntry
->OptionNumber
= Index
;
603 NewMenuEntry
->DisplayStringToken
= GetStringTokenFromDepository (
605 DriverOptionStrDepository
607 CallbackData
->Hii
->NewString (
611 &NewMenuEntry
->DisplayStringToken
,
612 NewMenuEntry
->DisplayString
615 NewMenuEntry
->HelpStringToken
= GetStringTokenFromDepository (
617 DriverOptionHelpStrDepository
619 CallbackData
->Hii
->NewString (
623 &NewMenuEntry
->HelpStringToken
,
624 NewMenuEntry
->HelpString
627 if (OptionalDataExist
) {
628 Ptr
+= (UINT8
) GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
);
633 StrSize (OptionalData
)
637 Status
= gRT
->SetVariable (
639 &gEfiGlobalVariableGuid
,
644 DriverOrderList
= BdsLibGetVariableAndSize (
646 &gEfiGlobalVariableGuid
,
649 NewDriverOrderList
= AllocateZeroPool (DriverOrderListSize
+ sizeof (UINT16
));
650 ASSERT (NewDriverOrderList
!= NULL
);
651 CopyMem (NewDriverOrderList
, DriverOrderList
, DriverOrderListSize
);
652 NewDriverOrderList
[DriverOrderListSize
/ sizeof (UINT16
)] = Index
;
653 if (DriverOrderList
!= NULL
) {
654 EfiLibDeleteVariable (L
"DriverOrder", &gEfiGlobalVariableGuid
);
657 Status
= gRT
->SetVariable (
659 &gEfiGlobalVariableGuid
,
661 DriverOrderListSize
+ sizeof (UINT16
),
664 SafeFreePool (DriverOrderList
);
665 DriverOrderList
= NULL
;
666 SafeFreePool (NewDriverOrderList
);
667 NewDriverOrderList
= NULL
;
668 InsertTailList (&DriverOptionMenu
.Head
, &NewMenuEntry
->Link
);
669 DriverOptionMenu
.MenuNumber
++;
671 *DescriptionData
= 0x0000;
672 *OptionalData
= 0x0000;
677 Var_UpdateBootOption (
678 IN BMM_CALLBACK_DATA
*CallbackData
,
679 IN FILE_EXPLORER_NV_DATA
*NvRamMap
682 UINT16
*BootOrderList
;
683 UINT16
*NewBootOrderList
;
684 UINTN BootOrderListSize
;
685 UINT16 BootString
[10];
690 BM_MENU_ENTRY
*NewMenuEntry
;
691 BM_LOAD_CONTEXT
*NewLoadContext
;
692 BOOLEAN OptionalDataExist
;
695 OptionalDataExist
= FALSE
;
697 Index
= BOpt_GetBootOptionNumber ();
698 UnicodeSPrint (BootString
, sizeof (BootString
), L
"Boot%04x", Index
);
700 if (NvRamMap
->DescriptionData
[0] == 0x0000) {
701 StrCpy (NvRamMap
->DescriptionData
, BootString
);
704 BufferSize
= sizeof (UINT32
) + sizeof (UINT16
) + StrSize (NvRamMap
->DescriptionData
) + GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
);
706 if (NvRamMap
->OptionalData
[0] != 0x0000) {
707 OptionalDataExist
= TRUE
;
708 BufferSize
+= StrSize (NvRamMap
->OptionalData
);
711 Buffer
= AllocateZeroPool (BufferSize
);
712 if (NULL
== Buffer
) {
713 return EFI_OUT_OF_RESOURCES
;
716 NewMenuEntry
= BOpt_CreateMenuEntry (BM_LOAD_CONTEXT_SELECT
);
717 if (NULL
== NewMenuEntry
) {
718 return EFI_OUT_OF_RESOURCES
;
721 NewLoadContext
= (BM_LOAD_CONTEXT
*) NewMenuEntry
->VariableContext
;
722 NewLoadContext
->Deleted
= FALSE
;
723 NewLoadContext
->LoadOptionSize
= BufferSize
;
724 Ptr
= (UINT8
*) Buffer
;
725 NewLoadContext
->LoadOption
= Ptr
;
726 *((UINT32
*) Ptr
) = LOAD_OPTION_ACTIVE
;
727 NewLoadContext
->Attributes
= *((UINT32
*) Ptr
);
728 NewLoadContext
->IsActive
= TRUE
;
729 NewLoadContext
->ForceReconnect
= (BOOLEAN
) (NewLoadContext
->Attributes
& LOAD_OPTION_FORCE_RECONNECT
);
731 Ptr
+= sizeof (UINT32
);
732 *((UINT16
*) Ptr
) = (UINT16
) GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
);
733 NewLoadContext
->FilePathListLength
= *((UINT16
*) Ptr
);
734 Ptr
+= sizeof (UINT16
);
738 NvRamMap
->DescriptionData
,
739 StrSize (NvRamMap
->DescriptionData
)
742 NewLoadContext
->Description
= AllocateZeroPool (StrSize (NvRamMap
->DescriptionData
));
743 ASSERT (NewLoadContext
->Description
!= NULL
);
745 NewMenuEntry
->DisplayString
= NewLoadContext
->Description
;
747 NewLoadContext
->Description
,
749 StrSize (NvRamMap
->DescriptionData
)
752 Ptr
+= StrSize (NvRamMap
->DescriptionData
);
755 CallbackData
->LoadContext
->FilePathList
,
756 GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
)
759 NewLoadContext
->FilePathList
= AllocateZeroPool (GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
));
760 ASSERT (NewLoadContext
->FilePathList
!= NULL
);
763 NewLoadContext
->FilePathList
,
765 GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
)
768 NewMenuEntry
->HelpString
= DevicePathToStr (NewLoadContext
->FilePathList
);
769 NewMenuEntry
->OptionNumber
= Index
;
770 NewMenuEntry
->DisplayStringToken
= GetStringTokenFromDepository (
772 BootOptionStrDepository
774 CallbackData
->Hii
->NewString (
777 CallbackData
->FeHiiHandle
,
778 &NewMenuEntry
->DisplayStringToken
,
779 NewMenuEntry
->DisplayString
782 NewMenuEntry
->HelpStringToken
= GetStringTokenFromDepository (
784 BootOptionHelpStrDepository
787 CallbackData
->Hii
->NewString (
790 CallbackData
->FeHiiHandle
,
791 &NewMenuEntry
->HelpStringToken
,
792 NewMenuEntry
->HelpString
795 if (OptionalDataExist
) {
796 Ptr
+= (UINT8
) GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
);
798 CopyMem (Ptr
, NvRamMap
->OptionalData
, StrSize (NvRamMap
->OptionalData
));
801 Status
= gRT
->SetVariable (
803 &gEfiGlobalVariableGuid
,
809 BootOrderList
= BdsLibGetVariableAndSize (
811 &gEfiGlobalVariableGuid
,
815 NewBootOrderList
= AllocateZeroPool (BootOrderListSize
+ sizeof (UINT16
));
816 ASSERT (NewBootOrderList
!= NULL
);
817 CopyMem (NewBootOrderList
, BootOrderList
, BootOrderListSize
);
818 NewBootOrderList
[BootOrderListSize
/ sizeof (UINT16
)] = Index
;
820 if (BootOrderList
!= NULL
) {
821 EfiLibDeleteVariable (L
"BootOrder", &gEfiGlobalVariableGuid
);
824 Status
= gRT
->SetVariable (
826 &gEfiGlobalVariableGuid
,
828 BootOrderListSize
+ sizeof (UINT16
),
832 SafeFreePool (BootOrderList
);
833 BootOrderList
= NULL
;
834 SafeFreePool (NewBootOrderList
);
835 NewBootOrderList
= NULL
;
836 InsertTailList (&BootOptionMenu
.Head
, &NewMenuEntry
->Link
);
837 BootOptionMenu
.MenuNumber
++;
839 NvRamMap
->DescriptionData
[0] = 0x0000;
840 NvRamMap
->OptionalData
[0] = 0x0000;
846 IN BMM_CALLBACK_DATA
*CallbackData
849 BM_MENU_ENTRY
*NewMenuEntry
;
850 BM_LOAD_CONTEXT
*NewLoadContext
;
851 BMM_FAKE_NV_DATA
*CurrentFakeNVMap
;
855 Status
= EFI_SUCCESS
;
856 CurrentFakeNVMap
= CallbackData
->BmmFakeNvData
;
857 for (Index
= 0; Index
< BootOptionMenu
.MenuNumber
; Index
++) {
858 NewMenuEntry
= BOpt_GetMenuEntry (&BootOptionMenu
, Index
);
859 if (NULL
== NewMenuEntry
) {
860 return EFI_NOT_FOUND
;
863 NewLoadContext
= (BM_LOAD_CONTEXT
*) NewMenuEntry
->VariableContext
;
864 NewLoadContext
->IsBootNext
= FALSE
;
867 if (CurrentFakeNVMap
->BootNext
== BootOptionMenu
.MenuNumber
) {
868 EfiLibDeleteVariable (L
"BootNext", &gEfiGlobalVariableGuid
);
872 NewMenuEntry
= BOpt_GetMenuEntry (
874 CurrentFakeNVMap
->BootNext
876 if (NULL
== NewMenuEntry
) {
877 return EFI_NOT_FOUND
;
880 NewLoadContext
= (BM_LOAD_CONTEXT
*) NewMenuEntry
->VariableContext
;
881 Status
= gRT
->SetVariable (
883 &gEfiGlobalVariableGuid
,
886 &NewMenuEntry
->OptionNumber
888 NewLoadContext
->IsBootNext
= TRUE
;
889 CallbackData
->BmmOldFakeNVData
.BootNext
= CurrentFakeNVMap
->BootNext
;
894 Var_UpdateBootOrder (
895 IN BMM_CALLBACK_DATA
*CallbackData
900 UINT16
*BootOrderList
;
901 UINT16
*NewBootOrderList
;
902 UINTN BootOrderListSize
;
905 BootOrderList
= NULL
;
906 BootOrderListSize
= 0;
909 // First check whether BootOrder is present in current configuration
911 BootOrderList
= BdsLibGetVariableAndSize (
913 &gEfiGlobalVariableGuid
,
917 NewBootOrderList
= AllocateZeroPool (BootOrderListSize
);
918 if (!NewBootOrderList
) {
919 return EFI_OUT_OF_RESOURCES
;
922 Map
= AllocateZeroPool (BootOrderListSize
/ sizeof (UINT16
));
924 return EFI_OUT_OF_RESOURCES
;
927 // If exists, delete it to hold new BootOrder
930 EfiLibDeleteVariable (L
"BootOrder", &gEfiGlobalVariableGuid
);
933 for (Index
= 0; Index
< BootOptionMenu
.MenuNumber
; Index
++) {
934 NewBootOrderList
[Index
] = CallbackData
->BmmFakeNvData
->OptionOrder
[Index
] - 1;
937 Status
= gRT
->SetVariable (
939 &gEfiGlobalVariableGuid
,
944 SafeFreePool (BootOrderList
);
945 SafeFreePool (NewBootOrderList
);
947 if (EFI_ERROR (Status
)) {
951 BOpt_FreeMenu (&BootOptionMenu
);
952 BOpt_GetBootOptions (CallbackData
);
959 Var_UpdateDriverOrder (
960 IN BMM_CALLBACK_DATA
*CallbackData
965 UINT16
*DriverOrderList
;
966 UINT16
*NewDriverOrderList
;
967 UINTN DriverOrderListSize
;
969 DriverOrderList
= NULL
;
970 DriverOrderListSize
= 0;
973 // First check whether DriverOrder is present in current configuration
975 DriverOrderList
= BdsLibGetVariableAndSize (
977 &gEfiGlobalVariableGuid
,
981 NewDriverOrderList
= AllocateZeroPool (DriverOrderListSize
);
983 if (!NewDriverOrderList
) {
984 return EFI_OUT_OF_RESOURCES
;
987 // If exists, delete it to hold new DriverOrder
989 if (DriverOrderList
) {
990 EfiLibDeleteVariable (L
"DriverOrder", &gEfiGlobalVariableGuid
);
993 for (Index
= 0; Index
< DriverOrderListSize
; Index
++) {
994 NewDriverOrderList
[Index
] = CallbackData
->BmmFakeNvData
->OptionOrder
[Index
] - 1;
997 Status
= gRT
->SetVariable (
999 &gEfiGlobalVariableGuid
,
1001 DriverOrderListSize
,
1004 if (EFI_ERROR (Status
)) {
1008 SafeFreePool (DriverOrderList
);
1010 BOpt_FreeMenu (&DriverOptionMenu
);
1011 BOpt_GetDriverOptions (CallbackData
);
1016 Var_UpdateBBSOption (
1017 IN BMM_CALLBACK_DATA
*CallbackData
1022 VOID
*BootOptionVar
;
1023 CHAR16 VarName
[100];
1025 UINT16 FilePathSize
;
1028 CHAR16 DescString
[100];
1029 UINTN NewOptionSize
;
1030 UINT8
*NewOptionPtr
;
1034 BM_MENU_OPTION
*OptionMenu
;
1035 BM_LEGACY_DEVICE_CONTEXT
*LegacyDeviceContext
;
1039 BM_MENU_ENTRY
*NewMenuEntry
;
1040 BM_LEGACY_DEV_ORDER_CONTEXT
*DevOrder
;
1048 LegacyDeviceContext
= NULL
;
1052 if (FORM_SET_FD_ORDER_ID
== CallbackData
->BmmPreviousPageId
) {
1053 OptionMenu
= (BM_MENU_OPTION
*) &LegacyFDMenu
;
1054 LegacyDev
= CallbackData
->BmmFakeNvData
->LegacyFD
;
1055 CallbackData
->BbsType
= BBS_FLOPPY
;
1057 if (FORM_SET_HD_ORDER_ID
== CallbackData
->BmmPreviousPageId
) {
1058 OptionMenu
= (BM_MENU_OPTION
*) &LegacyHDMenu
;
1059 LegacyDev
= CallbackData
->BmmFakeNvData
->LegacyHD
;
1060 CallbackData
->BbsType
= BBS_HARDDISK
;
1062 if (FORM_SET_CD_ORDER_ID
== CallbackData
->BmmPreviousPageId
) {
1063 OptionMenu
= (BM_MENU_OPTION
*) &LegacyCDMenu
;
1064 LegacyDev
= CallbackData
->BmmFakeNvData
->LegacyCD
;
1065 CallbackData
->BbsType
= BBS_CDROM
;
1067 if (FORM_SET_NET_ORDER_ID
== CallbackData
->BmmPreviousPageId
) {
1068 OptionMenu
= (BM_MENU_OPTION
*) &LegacyNETMenu
;
1069 LegacyDev
= CallbackData
->BmmFakeNvData
->LegacyNET
;
1070 CallbackData
->BbsType
= BBS_EMBED_NETWORK
;
1072 OptionMenu
= (BM_MENU_OPTION
*) &LegacyBEVMenu
;
1073 LegacyDev
= CallbackData
->BmmFakeNvData
->LegacyBEV
;
1074 CallbackData
->BbsType
= BBS_BEV_DEVICE
;
1080 DisMap
= CallbackData
->BmmOldFakeNVData
.DisableMap
;
1081 Status
= EFI_SUCCESS
;
1084 // Find the first device's context
1085 // If all devices are disabled( 0xFF == LegacyDev[0]), LegacyDeviceContext can be set to any VariableContext
1086 // because we just use it to fill the desc string, and user can not see the string in UI
1088 for (Index
= 0; Index
< OptionMenu
->MenuNumber
; Index
++) {
1089 NewMenuEntry
= BOpt_GetMenuEntry (OptionMenu
, Index
);
1090 LegacyDeviceContext
= (BM_LEGACY_DEVICE_CONTEXT
*) NewMenuEntry
->VariableContext
;
1091 if (0xFF != LegacyDev
[0] && LegacyDev
[0] == LegacyDeviceContext
->Index
) {
1092 DEBUG ((EFI_D_ERROR
, "DescStr: %s\n", LegacyDeviceContext
->Description
));
1097 // Update the Variable "LegacyDevOrder"
1099 VarData
= (UINT8
*) BdsLibGetVariableAndSize (
1101 &EfiLegacyDevOrderGuid
,
1105 if (NULL
== VarData
) {
1106 return EFI_NOT_FOUND
;
1109 OriginalPtr
= VarData
;
1110 DevOrder
= (BM_LEGACY_DEV_ORDER_CONTEXT
*) VarData
;
1112 while (VarData
< VarData
+ VarSize
) {
1113 if (DevOrder
->BbsType
== CallbackData
->BbsType
) {
1117 VarData
+= sizeof (BBS_TYPE
);
1118 VarData
+= *(UINT16
*) VarData
;
1119 DevOrder
= (BM_LEGACY_DEV_ORDER_CONTEXT
*) VarData
;
1122 if (VarData
>= VarData
+ VarSize
) {
1123 SafeFreePool (OriginalPtr
);
1124 return EFI_NOT_FOUND
;
1127 NewOrder
= (UINT16
*) AllocateZeroPool (DevOrder
->Length
- sizeof (UINT16
));
1128 if (NULL
== NewOrder
) {
1129 SafeFreePool (VarData
);
1130 return EFI_OUT_OF_RESOURCES
;
1133 for (Index
= 0; Index
< OptionMenu
->MenuNumber
; Index
++) {
1134 if (0xFF == LegacyDev
[Index
]) {
1138 NewOrder
[Index
] = LegacyDev
[Index
];
1141 // Only the enable/disable state of each boot device with same device type can be changed,
1142 // so we can count on the index information in DevOrder.
1143 // DisMap bit array is the only reliable source to check a device's en/dis state,
1144 // so we use DisMap to set en/dis state of each item in NewOrder array
1146 for (Index2
= 0; Index2
< OptionMenu
->MenuNumber
; Index2
++) {
1147 Tmp
= *(UINT16
*) ((UINT8
*) DevOrder
+ sizeof (BBS_TYPE
) + sizeof (UINT16
) + Index2
* sizeof (UINT16
));
1150 Bit
= 7 - (Tmp
% 8);
1151 if (DisMap
[Pos
] & (1 << Bit
)) {
1152 NewOrder
[Index
] = (UINT16
) (0xFF00 | Tmp
);
1158 (UINT8
*) DevOrder
+ sizeof (BBS_TYPE
) + sizeof (UINT16
),
1160 DevOrder
->Length
- sizeof (UINT16
)
1162 SafeFreePool (NewOrder
);
1164 Status
= gRT
->SetVariable (
1166 &EfiLegacyDevOrderGuid
,
1172 SafeFreePool (OriginalPtr
);
1175 // Update Optional Data of Boot####
1177 BootOptionVar
= GetLegacyBootOptionVar (CallbackData
->BbsType
, &Index
, &OptionSize
);
1179 if (NULL
!= BootOptionVar
) {
1182 LegacyDeviceContext
->Description
,
1183 StrSize (LegacyDeviceContext
->Description
)
1186 NewOptionSize
= sizeof (UINT32
) + sizeof (UINT16
) + StrSize (DescString
) + sizeof (BBS_TABLE
) + sizeof (UINT16
);
1188 UnicodeSPrint (VarName
, 100, L
"Boot%04x", Index
);
1190 Ptr
= BootOptionVar
;
1192 Attribute
= (UINT32
*) Ptr
;
1193 *Attribute
|= LOAD_OPTION_ACTIVE
;
1194 if (0xFF == LegacyDev
[0]) {
1196 // Disable this legacy boot option
1198 *Attribute
&= ~LOAD_OPTION_ACTIVE
;
1201 Ptr
+= sizeof (UINT32
);
1203 FilePathSize
= *(UINT16
*) Ptr
;
1204 Ptr
+= sizeof (UINT16
);
1206 NewOptionSize
+= FilePathSize
;
1208 NewOptionPtr
= AllocateZeroPool (NewOptionSize
);
1209 if (NULL
== NewOptionPtr
) {
1210 return EFI_OUT_OF_RESOURCES
;
1213 TempPtr
= NewOptionPtr
;
1216 // Copy previous option data to new option except the description string
1221 sizeof (UINT32
) + sizeof (UINT16
)
1224 TempPtr
+= (sizeof (UINT32
) + sizeof (UINT16
));
1229 StrSize (DescString
)
1232 TempPtr
+= StrSize (DescString
);
1235 // Description = (CHAR16 *)Ptr;
1237 Ptr
+= StrSize ((CHAR16
*) Ptr
);
1245 TempPtr
+= FilePathSize
;
1248 // DevicePath = (EFI_DEVICE_PATH_PROTOCOL *)Ptr;
1250 Ptr
+= FilePathSize
;
1253 // Now Ptr point to optional data, i.e. Bbs Table
1257 LegacyDeviceContext
->BbsTable
,
1261 TempPtr
+= sizeof (BBS_TABLE
);
1262 *((UINT16
*) TempPtr
) = (UINT16
) LegacyDeviceContext
->Index
;
1264 Status
= gRT
->SetVariable (
1266 &gEfiGlobalVariableGuid
,
1272 SafeFreePool (NewOptionPtr
);
1273 SafeFreePool (BootOptionVar
);
1276 BOpt_GetBootOptions (CallbackData
);