3 Copyright (c) 2004 - 2008, 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 "BootMaint.h"
31 Delete Boot Option that represent a Deleted state in BootOptionMenu.
32 After deleting this boot option, call Var_ChangeBootOrder to
33 make sure BootOrder is in valid state.
36 LoadOption -- Pointer to the boot option that to be deleted
44 BM_MENU_ENTRY
*NewMenuEntry
;
45 BM_LOAD_CONTEXT
*NewLoadContext
;
46 UINT16 BootString
[10];
53 for (Index
= 0; Index
< BootOptionMenu
.MenuNumber
; Index
++) {
54 NewMenuEntry
= BOpt_GetMenuEntry (&BootOptionMenu
, (Index
- Index2
));
55 if (NULL
== NewMenuEntry
) {
59 NewLoadContext
= (BM_LOAD_CONTEXT
*) NewMenuEntry
->VariableContext
;
60 if (!NewLoadContext
->Deleted
) {
68 NewMenuEntry
->OptionNumber
71 EfiLibDeleteVariable (BootString
, &gEfiGlobalVariableGuid
);
74 // If current Load Option is the same as BootNext,
75 // must delete BootNext in order to make sure
76 // there will be no panic on next boot
78 if (NewLoadContext
->IsBootNext
) {
79 EfiLibDeleteVariable (L
"BootNext", &gEfiGlobalVariableGuid
);
82 RemoveEntryList (&NewMenuEntry
->Link
);
83 BOpt_DestroyMenuEntry (NewMenuEntry
);
87 BootOptionMenu
.MenuNumber
-= Index2
;
89 Status
= Var_ChangeBootOrder ();
100 After any operation on Boot####, there will be a discrepancy in BootOrder.
101 Since some are missing but in BootOrder, while some are present but are
102 not reflected by BootOrder. Then a function rebuild BootOrder from
103 scratch by content from BootOptionMenu is needed.
115 BM_MENU_ENTRY
*NewMenuEntry
;
116 UINT16
*BootOrderList
;
117 UINT16
*BootOrderListPtr
;
118 UINTN BootOrderListSize
;
121 BootOrderList
= NULL
;
122 BootOrderListSize
= 0;
125 // First check whether BootOrder is present in current configuration
127 BootOrderList
= BdsLibGetVariableAndSize (
129 &gEfiGlobalVariableGuid
,
134 // If exists, delete it to hold new BootOrder
137 EfiLibDeleteVariable (L
"BootOrder", &gEfiGlobalVariableGuid
);
138 SafeFreePool (BootOrderList
);
139 BootOrderList
= NULL
;
142 // Maybe here should be some check method to ensure that
143 // no new added boot options will be added
144 // but the setup engine now will give only one callback
145 // that is to say, user are granted only one chance to
146 // decide whether the boot option will be added or not
147 // there should be no indictor to show whether this
148 // is a "new" boot option
150 BootOrderListSize
= BootOptionMenu
.MenuNumber
;
152 if (BootOrderListSize
> 0) {
153 BootOrderList
= EfiAllocateZeroPool (BootOrderListSize
* sizeof (UINT16
));
154 ASSERT (BootOrderList
!= NULL
);
155 BootOrderListPtr
= BootOrderList
;
158 // Get all current used Boot#### from BootOptionMenu.
159 // OptionNumber in each BM_LOAD_OPTION is really its
162 for (Index
= 0; Index
< BootOrderListSize
; Index
++) {
163 NewMenuEntry
= BOpt_GetMenuEntry (&BootOptionMenu
, Index
);
164 *BootOrderList
= (UINT16
) NewMenuEntry
->OptionNumber
;
168 BootOrderList
= BootOrderListPtr
;
171 // After building the BootOrderList, write it back
173 Status
= gRT
->SetVariable (
175 &gEfiGlobalVariableGuid
,
177 BootOrderListSize
* sizeof (UINT16
),
180 if (EFI_ERROR (Status
)) {
188 Var_DelDriverOption (
194 Delete Load Option that represent a Deleted state in BootOptionMenu.
195 After deleting this Driver option, call Var_ChangeDriverOrder to
196 make sure DriverOrder is in valid state.
199 LoadOption -- Pointer to the Driver option that to be deleted
207 BM_MENU_ENTRY
*NewMenuEntry
;
208 BM_LOAD_CONTEXT
*NewLoadContext
;
209 UINT16 DriverString
[12];
214 Status
= EFI_SUCCESS
;
216 for (Index
= 0; Index
< DriverOptionMenu
.MenuNumber
; Index
++) {
217 NewMenuEntry
= BOpt_GetMenuEntry (&DriverOptionMenu
, (Index
- Index2
));
218 if (NULL
== NewMenuEntry
) {
219 return EFI_NOT_FOUND
;
222 NewLoadContext
= (BM_LOAD_CONTEXT
*) NewMenuEntry
->VariableContext
;
223 if (!NewLoadContext
->Deleted
) {
229 sizeof (DriverString
),
231 NewMenuEntry
->OptionNumber
234 EfiLibDeleteVariable (DriverString
, &gEfiGlobalVariableGuid
);
237 RemoveEntryList (&NewMenuEntry
->Link
);
238 BOpt_DestroyMenuEntry (NewMenuEntry
);
242 DriverOptionMenu
.MenuNumber
-= Index2
;
244 Status
= Var_ChangeDriverOrder ();
249 Var_ChangeDriverOrder (
255 After any operation on Driver####, there will be a discrepancy in
256 DriverOrder. Since some are missing but in DriverOrder, while some
257 are present but are not reflected by DriverOrder. Then a function
258 rebuild DriverOrder from scratch by content from DriverOptionMenu is
270 BM_MENU_ENTRY
*NewMenuEntry
;
271 UINT16
*DriverOrderList
;
272 UINT16
*DriverOrderListPtr
;
273 UINTN DriverOrderListSize
;
276 DriverOrderList
= NULL
;
277 DriverOrderListSize
= 0;
280 // First check whether DriverOrder is present in current configuration
282 DriverOrderList
= BdsLibGetVariableAndSize (
284 &gEfiGlobalVariableGuid
,
289 // If exists, delete it to hold new DriverOrder
291 if (DriverOrderList
) {
292 EfiLibDeleteVariable (L
"DriverOrder", &gEfiGlobalVariableGuid
);
293 SafeFreePool (DriverOrderList
);
294 DriverOrderList
= NULL
;
297 DriverOrderListSize
= DriverOptionMenu
.MenuNumber
;
299 if (DriverOrderListSize
> 0) {
300 DriverOrderList
= EfiAllocateZeroPool (DriverOrderListSize
* sizeof (UINT16
));
301 ASSERT (DriverOrderList
!= NULL
);
302 DriverOrderListPtr
= DriverOrderList
;
305 // Get all current used Driver#### from DriverOptionMenu.
306 // OptionNumber in each BM_LOAD_OPTION is really its
309 for (Index
= 0; Index
< DriverOrderListSize
; Index
++) {
310 NewMenuEntry
= BOpt_GetMenuEntry (&DriverOptionMenu
, Index
);
311 *DriverOrderList
= (UINT16
) NewMenuEntry
->OptionNumber
;
315 DriverOrderList
= DriverOrderListPtr
;
318 // After building the DriverOrderList, write it back
320 Status
= gRT
->SetVariable (
322 &gEfiGlobalVariableGuid
,
324 DriverOrderListSize
* sizeof (UINT16
),
327 if (EFI_ERROR (Status
)) {
335 Var_UpdateAllConsoleOption (
339 EFI_DEVICE_PATH_PROTOCOL
*OutDevicePath
;
340 EFI_DEVICE_PATH_PROTOCOL
*InpDevicePath
;
341 EFI_DEVICE_PATH_PROTOCOL
*ErrDevicePath
;
344 OutDevicePath
= EfiLibGetVariable (L
"ConOut", &gEfiGlobalVariableGuid
);
345 InpDevicePath
= EfiLibGetVariable (L
"ConIn", &gEfiGlobalVariableGuid
);
346 ErrDevicePath
= EfiLibGetVariable (L
"ErrOut", &gEfiGlobalVariableGuid
);
348 ChangeVariableDevicePath (OutDevicePath
);
349 Status
= gRT
->SetVariable (
351 &gEfiGlobalVariableGuid
,
353 GetDevicePathSize (OutDevicePath
),
356 ASSERT (!EFI_ERROR (Status
));
360 ChangeVariableDevicePath (InpDevicePath
);
361 Status
= gRT
->SetVariable (
363 &gEfiGlobalVariableGuid
,
365 GetDevicePathSize (InpDevicePath
),
368 ASSERT (!EFI_ERROR (Status
));
372 ChangeVariableDevicePath (ErrDevicePath
);
373 Status
= gRT
->SetVariable (
375 &gEfiGlobalVariableGuid
,
377 GetDevicePathSize (ErrDevicePath
),
380 ASSERT (!EFI_ERROR (Status
));
385 Var_UpdateConsoleOption (
386 IN UINT16
*ConsoleName
,
387 IN BM_MENU_OPTION
*ConsoleMenu
,
388 IN UINT16 UpdatePageId
391 EFI_DEVICE_PATH_PROTOCOL
*ConDevicePath
;
392 BM_MENU_ENTRY
*NewMenuEntry
;
393 BM_CONSOLE_CONTEXT
*NewConsoleContext
;
394 BM_TERMINAL_CONTEXT
*NewTerminalContext
;
396 VENDOR_DEVICE_PATH Vendor
;
397 EFI_DEVICE_PATH_PROTOCOL
*TerminalDevicePath
;
400 ConDevicePath
= EfiLibGetVariable (ConsoleName
, &gEfiGlobalVariableGuid
);
401 if (ConDevicePath
!= NULL
) {
402 EfiLibDeleteVariable (ConsoleName
, &gEfiGlobalVariableGuid
);
403 SafeFreePool (ConDevicePath
);
404 ConDevicePath
= NULL
;
408 // First add all console input device to it from console input menu
410 for (Index
= 0; Index
< ConsoleMenu
->MenuNumber
; Index
++) {
411 NewMenuEntry
= BOpt_GetMenuEntry (ConsoleMenu
, Index
);
412 if (NULL
== NewMenuEntry
) {
413 return EFI_NOT_FOUND
;
416 NewConsoleContext
= (BM_CONSOLE_CONTEXT
*) NewMenuEntry
->VariableContext
;
417 if (NewConsoleContext
->IsActive
) {
418 ConDevicePath
= AppendDevicePathInstance (
420 NewConsoleContext
->DevicePath
425 for (Index
= 0; Index
< TerminalMenu
.MenuNumber
; Index
++) {
426 NewMenuEntry
= BOpt_GetMenuEntry (&TerminalMenu
, Index
);
427 if (NULL
== NewMenuEntry
) {
428 return EFI_NOT_FOUND
;
431 NewTerminalContext
= (BM_TERMINAL_CONTEXT
*) NewMenuEntry
->VariableContext
;
432 if ((NewTerminalContext
->IsConIn
&& (UpdatePageId
== FORM_CON_IN_ID
)) ||
433 (NewTerminalContext
->IsConOut
&& (UpdatePageId
== FORM_CON_OUT_ID
)) ||
434 (NewTerminalContext
->IsStdErr
&& (UpdatePageId
== FORM_CON_ERR_ID
))
436 Vendor
.Header
.Type
= MESSAGING_DEVICE_PATH
;
437 Vendor
.Header
.SubType
= MSG_VENDOR_DP
;
440 &Guid
[NewTerminalContext
->TerminalType
],
443 SetDevicePathNodeLength (&Vendor
.Header
, sizeof (VENDOR_DEVICE_PATH
));
444 TerminalDevicePath
= AppendDevicePathNode (
445 NewTerminalContext
->DevicePath
,
446 (EFI_DEVICE_PATH_PROTOCOL
*) &Vendor
448 ASSERT (TerminalDevicePath
!= NULL
);
449 ChangeTerminalDevicePath (TerminalDevicePath
, TRUE
);
450 ConDevicePath
= AppendDevicePathInstance (
458 Status
= gRT
->SetVariable (
460 &gEfiGlobalVariableGuid
,
462 GetDevicePathSize (ConDevicePath
),
465 if (EFI_ERROR (Status
)) {
475 Var_UpdateConsoleInpOption (
479 return Var_UpdateConsoleOption (L
"ConIn", &ConsoleInpMenu
, FORM_CON_IN_ID
);
483 Var_UpdateConsoleOutOption (
487 return Var_UpdateConsoleOption (L
"ConOut", &ConsoleOutMenu
, FORM_CON_OUT_ID
);
491 Var_UpdateErrorOutOption (
495 return Var_UpdateConsoleOption (L
"ErrOut", &ConsoleErrMenu
, FORM_CON_ERR_ID
);
499 Var_UpdateDriverOption (
500 IN BMM_CALLBACK_DATA
*CallbackData
,
501 IN EFI_HII_HANDLE HiiHandle
,
502 IN UINT16
*DescriptionData
,
503 IN UINT16
*OptionalData
,
504 IN UINT8 ForceReconnect
508 UINT16
*DriverOrderList
;
509 UINT16
*NewDriverOrderList
;
510 UINT16 DriverString
[12];
511 UINTN DriverOrderListSize
;
515 BM_MENU_ENTRY
*NewMenuEntry
;
516 BM_LOAD_CONTEXT
*NewLoadContext
;
517 BOOLEAN OptionalDataExist
;
520 OptionalDataExist
= FALSE
;
522 Index
= BOpt_GetDriverOptionNumber ();
525 sizeof (DriverString
),
530 if (*DescriptionData
== 0x0000) {
531 StrCpy (DescriptionData
, DriverString
);
534 BufferSize
= sizeof (UINT32
) + sizeof (UINT16
) + StrSize (DescriptionData
);
535 BufferSize
+= GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
);
537 if (*OptionalData
!= 0x0000) {
538 OptionalDataExist
= TRUE
;
539 BufferSize
+= StrSize (OptionalData
);
542 Buffer
= EfiAllocateZeroPool (BufferSize
);
543 if (NULL
== Buffer
) {
544 return EFI_OUT_OF_RESOURCES
;
547 NewMenuEntry
= BOpt_CreateMenuEntry (BM_LOAD_CONTEXT_SELECT
);
548 if (NULL
== NewMenuEntry
) {
549 return EFI_OUT_OF_RESOURCES
;
552 NewLoadContext
= (BM_LOAD_CONTEXT
*) NewMenuEntry
->VariableContext
;
553 NewLoadContext
->Deleted
= FALSE
;
554 NewLoadContext
->LoadOptionSize
= BufferSize
;
555 Ptr
= (UINT8
*) Buffer
;
556 NewLoadContext
->LoadOption
= Ptr
;
557 *((UINT32
*) Ptr
) = LOAD_OPTION_ACTIVE
| (ForceReconnect
<< 1);
558 NewLoadContext
->Attributes
= *((UINT32
*) Ptr
);
559 NewLoadContext
->IsActive
= TRUE
;
560 NewLoadContext
->ForceReconnect
= (BOOLEAN
) (NewLoadContext
->Attributes
& LOAD_OPTION_FORCE_RECONNECT
);
562 Ptr
+= sizeof (UINT32
);
563 *((UINT16
*) Ptr
) = (UINT16
) GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
);
564 NewLoadContext
->FilePathListLength
= *((UINT16
*) Ptr
);
566 Ptr
+= sizeof (UINT16
);
570 StrSize (DescriptionData
)
573 NewLoadContext
->Description
= EfiAllocateZeroPool (StrSize (DescriptionData
));
574 ASSERT (NewLoadContext
->Description
!= NULL
);
575 NewMenuEntry
->DisplayString
= NewLoadContext
->Description
;
577 NewLoadContext
->Description
,
579 StrSize (DescriptionData
)
582 Ptr
+= StrSize (DescriptionData
);
585 CallbackData
->LoadContext
->FilePathList
,
586 GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
)
589 NewLoadContext
->FilePathList
= EfiAllocateZeroPool (GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
));
590 ASSERT (NewLoadContext
->FilePathList
!= NULL
);
593 NewLoadContext
->FilePathList
,
595 GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
)
598 NewMenuEntry
->HelpString
= DevicePathToStr (NewLoadContext
->FilePathList
);
599 NewMenuEntry
->OptionNumber
= Index
;
600 NewMenuEntry
->DisplayStringToken
= GetStringTokenFromDepository (
602 DriverOptionStrDepository
604 IfrLibNewString (HiiHandle
, &NewMenuEntry
->DisplayStringToken
, NewMenuEntry
->DisplayString
);
606 NewMenuEntry
->HelpStringToken
= GetStringTokenFromDepository (
608 DriverOptionHelpStrDepository
610 IfrLibNewString (HiiHandle
, &NewMenuEntry
->HelpStringToken
, NewMenuEntry
->HelpString
);
612 if (OptionalDataExist
) {
613 Ptr
+= (UINT8
) GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
);
618 StrSize (OptionalData
)
622 Status
= gRT
->SetVariable (
624 &gEfiGlobalVariableGuid
,
629 ASSERT_EFI_ERROR (Status
);
630 DriverOrderList
= BdsLibGetVariableAndSize (
632 &gEfiGlobalVariableGuid
,
635 NewDriverOrderList
= EfiAllocateZeroPool (DriverOrderListSize
+ sizeof (UINT16
));
636 ASSERT (NewDriverOrderList
!= NULL
);
637 CopyMem (NewDriverOrderList
, DriverOrderList
, DriverOrderListSize
);
638 NewDriverOrderList
[DriverOrderListSize
/ sizeof (UINT16
)] = Index
;
639 if (DriverOrderList
!= NULL
) {
640 EfiLibDeleteVariable (L
"DriverOrder", &gEfiGlobalVariableGuid
);
643 Status
= gRT
->SetVariable (
645 &gEfiGlobalVariableGuid
,
647 DriverOrderListSize
+ sizeof (UINT16
),
650 ASSERT_EFI_ERROR (Status
);
651 SafeFreePool (DriverOrderList
);
652 DriverOrderList
= NULL
;
653 SafeFreePool (NewDriverOrderList
);
654 NewDriverOrderList
= NULL
;
655 InsertTailList (&DriverOptionMenu
.Head
, &NewMenuEntry
->Link
);
656 DriverOptionMenu
.MenuNumber
++;
658 *DescriptionData
= 0x0000;
659 *OptionalData
= 0x0000;
664 Var_UpdateBootOption (
665 IN BMM_CALLBACK_DATA
*CallbackData
,
666 IN FILE_EXPLORER_NV_DATA
*NvRamMap
669 UINT16
*BootOrderList
;
670 UINT16
*NewBootOrderList
;
671 UINTN BootOrderListSize
;
672 UINT16 BootString
[10];
677 BM_MENU_ENTRY
*NewMenuEntry
;
678 BM_LOAD_CONTEXT
*NewLoadContext
;
679 BOOLEAN OptionalDataExist
;
682 OptionalDataExist
= FALSE
;
684 Index
= BOpt_GetBootOptionNumber () ;
685 UnicodeSPrint (BootString
, sizeof (BootString
), L
"Boot%04x", Index
);
687 if (NvRamMap
->DescriptionData
[0] == 0x0000) {
688 StrCpy (NvRamMap
->DescriptionData
, BootString
);
691 BufferSize
= sizeof (UINT32
) + sizeof (UINT16
) + StrSize (NvRamMap
->DescriptionData
);
692 BufferSize
+= GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
);
694 if (NvRamMap
->OptionalData
[0] != 0x0000) {
695 OptionalDataExist
= TRUE
;
696 BufferSize
+= StrSize (NvRamMap
->OptionalData
);
699 Buffer
= EfiAllocateZeroPool (BufferSize
);
700 if (NULL
== Buffer
) {
701 return EFI_OUT_OF_RESOURCES
;
704 NewMenuEntry
= BOpt_CreateMenuEntry (BM_LOAD_CONTEXT_SELECT
);
705 if (NULL
== NewMenuEntry
) {
706 return EFI_OUT_OF_RESOURCES
;
709 NewLoadContext
= (BM_LOAD_CONTEXT
*) NewMenuEntry
->VariableContext
;
710 NewLoadContext
->Deleted
= FALSE
;
711 NewLoadContext
->LoadOptionSize
= BufferSize
;
712 Ptr
= (UINT8
*) Buffer
;
713 NewLoadContext
->LoadOption
= Ptr
;
714 *((UINT32
*) Ptr
) = LOAD_OPTION_ACTIVE
;
715 NewLoadContext
->Attributes
= *((UINT32
*) Ptr
);
716 NewLoadContext
->IsActive
= TRUE
;
717 NewLoadContext
->ForceReconnect
= (BOOLEAN
) (NewLoadContext
->Attributes
& LOAD_OPTION_FORCE_RECONNECT
);
719 Ptr
+= sizeof (UINT32
);
720 *((UINT16
*) Ptr
) = (UINT16
) GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
);
721 NewLoadContext
->FilePathListLength
= *((UINT16
*) Ptr
);
722 Ptr
+= sizeof (UINT16
);
726 NvRamMap
->DescriptionData
,
727 StrSize (NvRamMap
->DescriptionData
)
730 NewLoadContext
->Description
= EfiAllocateZeroPool (StrSize (NvRamMap
->DescriptionData
));
731 ASSERT (NewLoadContext
->Description
!= NULL
);
733 NewMenuEntry
->DisplayString
= NewLoadContext
->Description
;
735 NewLoadContext
->Description
,
737 StrSize (NvRamMap
->DescriptionData
)
740 Ptr
+= StrSize (NvRamMap
->DescriptionData
);
743 CallbackData
->LoadContext
->FilePathList
,
744 GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
)
747 NewLoadContext
->FilePathList
= EfiAllocateZeroPool (GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
));
748 ASSERT (NewLoadContext
->FilePathList
!= NULL
);
751 NewLoadContext
->FilePathList
,
753 GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
)
756 NewMenuEntry
->HelpString
= DevicePathToStr (NewLoadContext
->FilePathList
);
757 NewMenuEntry
->OptionNumber
= Index
;
758 NewMenuEntry
->DisplayStringToken
= GetStringTokenFromDepository (
760 BootOptionStrDepository
762 IfrLibNewString (CallbackData
->FeHiiHandle
, &NewMenuEntry
->DisplayStringToken
, NewMenuEntry
->DisplayString
);
764 NewMenuEntry
->HelpStringToken
= GetStringTokenFromDepository (
766 BootOptionHelpStrDepository
768 IfrLibNewString (CallbackData
->FeHiiHandle
, &NewMenuEntry
->HelpStringToken
, NewMenuEntry
->HelpString
);
770 if (OptionalDataExist
) {
771 Ptr
+= (UINT8
) GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
);
773 CopyMem (Ptr
, NvRamMap
->OptionalData
, StrSize (NvRamMap
->OptionalData
));
776 Status
= gRT
->SetVariable (
778 &gEfiGlobalVariableGuid
,
783 ASSERT_EFI_ERROR (Status
);
785 BootOrderList
= BdsLibGetVariableAndSize (
787 &gEfiGlobalVariableGuid
,
791 NewBootOrderList
= EfiAllocateZeroPool (BootOrderListSize
+ sizeof (UINT16
));
792 ASSERT (NewBootOrderList
!= NULL
);
793 CopyMem (NewBootOrderList
, BootOrderList
, BootOrderListSize
);
794 NewBootOrderList
[BootOrderListSize
/ sizeof (UINT16
)] = Index
;
796 if (BootOrderList
!= NULL
) {
797 EfiLibDeleteVariable (L
"BootOrder", &gEfiGlobalVariableGuid
);
800 Status
= gRT
->SetVariable (
802 &gEfiGlobalVariableGuid
,
804 BootOrderListSize
+ sizeof (UINT16
),
807 ASSERT_EFI_ERROR (Status
);
809 SafeFreePool (BootOrderList
);
810 BootOrderList
= NULL
;
811 SafeFreePool (NewBootOrderList
);
812 NewBootOrderList
= NULL
;
813 InsertTailList (&BootOptionMenu
.Head
, &NewMenuEntry
->Link
);
814 BootOptionMenu
.MenuNumber
++;
816 NvRamMap
->DescriptionData
[0] = 0x0000;
817 NvRamMap
->OptionalData
[0] = 0x0000;
823 IN BMM_CALLBACK_DATA
*CallbackData
826 BM_MENU_ENTRY
*NewMenuEntry
;
827 BM_LOAD_CONTEXT
*NewLoadContext
;
828 BMM_FAKE_NV_DATA
*CurrentFakeNVMap
;
832 Status
= EFI_SUCCESS
;
833 CurrentFakeNVMap
= &CallbackData
->BmmFakeNvData
;
834 for (Index
= 0; Index
< BootOptionMenu
.MenuNumber
; Index
++) {
835 NewMenuEntry
= BOpt_GetMenuEntry (&BootOptionMenu
, Index
);
836 if (NULL
== NewMenuEntry
) {
837 return EFI_NOT_FOUND
;
840 NewLoadContext
= (BM_LOAD_CONTEXT
*) NewMenuEntry
->VariableContext
;
841 NewLoadContext
->IsBootNext
= FALSE
;
844 if (CurrentFakeNVMap
->BootNext
== BootOptionMenu
.MenuNumber
) {
845 EfiLibDeleteVariable (L
"BootNext", &gEfiGlobalVariableGuid
);
849 NewMenuEntry
= BOpt_GetMenuEntry (
851 CurrentFakeNVMap
->BootNext
853 if (NULL
== NewMenuEntry
) {
854 return EFI_NOT_FOUND
;
857 NewLoadContext
= (BM_LOAD_CONTEXT
*) NewMenuEntry
->VariableContext
;
858 Status
= gRT
->SetVariable (
860 &gEfiGlobalVariableGuid
,
863 &NewMenuEntry
->OptionNumber
865 NewLoadContext
->IsBootNext
= TRUE
;
866 CallbackData
->BmmOldFakeNVData
.BootNext
= CurrentFakeNVMap
->BootNext
;
871 Var_UpdateBootOrder (
872 IN BMM_CALLBACK_DATA
*CallbackData
877 UINT16
*BootOrderList
;
878 UINT16
*NewBootOrderList
;
879 UINTN BootOrderListSize
;
882 BootOrderList
= NULL
;
883 BootOrderListSize
= 0;
886 // First check whether BootOrder is present in current configuration
888 BootOrderList
= BdsLibGetVariableAndSize (
890 &gEfiGlobalVariableGuid
,
894 NewBootOrderList
= EfiAllocateZeroPool (BootOrderListSize
);
895 if (!NewBootOrderList
) {
896 return EFI_OUT_OF_RESOURCES
;
899 Map
= EfiAllocateZeroPool (BootOrderListSize
/ sizeof (UINT16
));
901 return EFI_OUT_OF_RESOURCES
;
904 // If exists, delete it to hold new BootOrder
907 EfiLibDeleteVariable (L
"BootOrder", &gEfiGlobalVariableGuid
);
910 for (Index
= 0; Index
< BootOptionMenu
.MenuNumber
; Index
++) {
911 NewBootOrderList
[Index
] = (UINT16
) (CallbackData
->BmmFakeNvData
.OptionOrder
[Index
] - 1);
914 Status
= gRT
->SetVariable (
916 &gEfiGlobalVariableGuid
,
921 SafeFreePool (BootOrderList
);
922 SafeFreePool (NewBootOrderList
);
924 if (EFI_ERROR (Status
)) {
928 BOpt_FreeMenu (&BootOptionMenu
);
929 BOpt_GetBootOptions (CallbackData
);
936 Var_UpdateDriverOrder (
937 IN BMM_CALLBACK_DATA
*CallbackData
942 UINT16
*DriverOrderList
;
943 UINT16
*NewDriverOrderList
;
944 UINTN DriverOrderListSize
;
946 DriverOrderList
= NULL
;
947 DriverOrderListSize
= 0;
950 // First check whether DriverOrder is present in current configuration
952 DriverOrderList
= BdsLibGetVariableAndSize (
954 &gEfiGlobalVariableGuid
,
958 NewDriverOrderList
= EfiAllocateZeroPool (DriverOrderListSize
);
960 if (!NewDriverOrderList
) {
961 return EFI_OUT_OF_RESOURCES
;
964 // If exists, delete it to hold new DriverOrder
966 if (DriverOrderList
) {
967 EfiLibDeleteVariable (L
"DriverOrder", &gEfiGlobalVariableGuid
);
970 for (Index
= 0; Index
< DriverOrderListSize
; Index
++) {
971 NewDriverOrderList
[Index
] = (UINT16
) (CallbackData
->BmmFakeNvData
.OptionOrder
[Index
] - 1);
974 Status
= gRT
->SetVariable (
976 &gEfiGlobalVariableGuid
,
981 if (EFI_ERROR (Status
)) {
985 SafeFreePool (DriverOrderList
);
987 BOpt_FreeMenu (&DriverOptionMenu
);
988 BOpt_GetDriverOptions (CallbackData
);
993 Var_UpdateBBSOption (
994 IN BMM_CALLBACK_DATA
*CallbackData
1000 CHAR16 VarName
[100];
1004 CHAR16 DescString
[100];
1005 CHAR8 DescAsciiString
[100];
1006 UINTN NewOptionSize
;
1007 UINT8
*NewOptionPtr
;
1010 BM_MENU_OPTION
*OptionMenu
;
1011 BM_LEGACY_DEVICE_CONTEXT
*LegacyDeviceContext
;
1015 BM_MENU_ENTRY
*NewMenuEntry
;
1016 BM_LEGACY_DEV_ORDER_CONTEXT
*DevOrder
;
1024 LegacyDeviceContext
= NULL
;
1028 if (FORM_SET_FD_ORDER_ID
== CallbackData
->BmmPreviousPageId
) {
1029 OptionMenu
= (BM_MENU_OPTION
*) &LegacyFDMenu
;
1030 LegacyDev
= CallbackData
->BmmFakeNvData
.LegacyFD
;
1031 CallbackData
->BbsType
= BBS_FLOPPY
;
1033 if (FORM_SET_HD_ORDER_ID
== CallbackData
->BmmPreviousPageId
) {
1034 OptionMenu
= (BM_MENU_OPTION
*) &LegacyHDMenu
;
1035 LegacyDev
= CallbackData
->BmmFakeNvData
.LegacyHD
;
1036 CallbackData
->BbsType
= BBS_HARDDISK
;
1038 if (FORM_SET_CD_ORDER_ID
== CallbackData
->BmmPreviousPageId
) {
1039 OptionMenu
= (BM_MENU_OPTION
*) &LegacyCDMenu
;
1040 LegacyDev
= CallbackData
->BmmFakeNvData
.LegacyCD
;
1041 CallbackData
->BbsType
= BBS_CDROM
;
1043 if (FORM_SET_NET_ORDER_ID
== CallbackData
->BmmPreviousPageId
) {
1044 OptionMenu
= (BM_MENU_OPTION
*) &LegacyNETMenu
;
1045 LegacyDev
= CallbackData
->BmmFakeNvData
.LegacyNET
;
1046 CallbackData
->BbsType
= BBS_EMBED_NETWORK
;
1048 OptionMenu
= (BM_MENU_OPTION
*) &LegacyBEVMenu
;
1049 LegacyDev
= CallbackData
->BmmFakeNvData
.LegacyBEV
;
1050 CallbackData
->BbsType
= BBS_BEV_DEVICE
;
1056 DisMap
= CallbackData
->BmmOldFakeNVData
.DisableMap
;
1057 Status
= EFI_SUCCESS
;
1060 // Find the first device's context
1061 // If all devices are disabled( 0xFF == LegacyDev[0]), LegacyDeviceContext can be set to any VariableContext
1062 // because we just use it to fill the desc string, and user can not see the string in UI
1064 for (Index
= 0; Index
< OptionMenu
->MenuNumber
; Index
++) {
1065 NewMenuEntry
= BOpt_GetMenuEntry (OptionMenu
, Index
);
1066 LegacyDeviceContext
= (BM_LEGACY_DEVICE_CONTEXT
*) NewMenuEntry
->VariableContext
;
1067 if (0xFF != LegacyDev
[0] && LegacyDev
[0] == LegacyDeviceContext
->Index
) {
1068 DEBUG ((DEBUG_ERROR
, "DescStr: %s\n", LegacyDeviceContext
->Description
));
1073 // Update the Variable "LegacyDevOrder"
1075 VarData
= (UINT8
*) BdsLibGetVariableAndSize (
1077 &EfiLegacyDevOrderGuid
,
1081 if (NULL
== VarData
) {
1082 return EFI_NOT_FOUND
;
1085 OriginalPtr
= VarData
;
1086 DevOrder
= (BM_LEGACY_DEV_ORDER_CONTEXT
*) VarData
;
1088 while (VarData
< VarData
+ VarSize
) {
1089 if (DevOrder
->BbsType
== CallbackData
->BbsType
) {
1093 VarData
+= sizeof (BBS_TYPE
);
1094 VarData
+= *(UINT16
*) VarData
;
1095 DevOrder
= (BM_LEGACY_DEV_ORDER_CONTEXT
*) VarData
;
1098 if (VarData
>= VarData
+ VarSize
) {
1099 SafeFreePool (OriginalPtr
);
1100 return EFI_NOT_FOUND
;
1103 NewOrder
= (UINT16
*) EfiAllocateZeroPool (DevOrder
->Length
- sizeof (UINT16
));
1104 if (NULL
== NewOrder
) {
1105 SafeFreePool (VarData
);
1106 return EFI_OUT_OF_RESOURCES
;
1109 for (Index
= 0; Index
< OptionMenu
->MenuNumber
; Index
++) {
1110 if (0xFF == LegacyDev
[Index
]) {
1114 NewOrder
[Index
] = LegacyDev
[Index
];
1117 // Only the enable/disable state of each boot device with same device type can be changed,
1118 // so we can count on the index information in DevOrder.
1119 // DisMap bit array is the only reliable source to check a device's en/dis state,
1120 // so we use DisMap to set en/dis state of each item in NewOrder array
1122 for (Index2
= 0; Index2
< OptionMenu
->MenuNumber
; Index2
++) {
1123 Tmp
= *(UINT16
*) ((UINT8
*) DevOrder
+ sizeof (BBS_TYPE
) + sizeof (UINT16
) + Index2
* sizeof (UINT16
));
1126 Bit
= 7 - (Tmp
% 8);
1127 if (DisMap
[Pos
] & (1 << Bit
)) {
1128 NewOrder
[Index
] = (UINT16
) (0xFF00 | Tmp
);
1134 (UINT8
*) DevOrder
+ sizeof (BBS_TYPE
) + sizeof (UINT16
),
1136 DevOrder
->Length
- sizeof (UINT16
)
1138 SafeFreePool (NewOrder
);
1140 Status
= gRT
->SetVariable (
1142 &EfiLegacyDevOrderGuid
,
1148 SafeFreePool (OriginalPtr
);
1151 // Update Optional Data of Boot####
1153 BootOptionVar
= GetLegacyBootOptionVar (CallbackData
->BbsType
, &Index
, &OptionSize
);
1155 if (NULL
!= BootOptionVar
) {
1158 LegacyDeviceContext
->Description
,
1159 StrSize (LegacyDeviceContext
->Description
)
1162 UnicodeToAscii (DescString
, StrSize (DescString
), DescAsciiString
);
1164 NewOptionSize
= sizeof (UINT32
) + sizeof (UINT16
) + StrSize (DescString
) +
1165 sizeof (BBS_BBS_DEVICE_PATH
);
1166 NewOptionSize
+= AsciiStrLen (DescAsciiString
) +
1167 EFI_END_DEVICE_PATH_LENGTH
+ sizeof (BBS_TABLE
) + sizeof (UINT16
);
1169 UnicodeSPrint (VarName
, 100, L
"Boot%04x", Index
);
1171 Ptr
= BootOptionVar
;
1173 Attribute
= (UINT32
*) Ptr
;
1174 *Attribute
|= LOAD_OPTION_ACTIVE
;
1175 if (0xFF == LegacyDev
[0]) {
1177 // Disable this legacy boot option
1179 *Attribute
&= ~LOAD_OPTION_ACTIVE
;
1182 Ptr
+= sizeof (UINT32
);
1184 Ptr
+= sizeof (UINT16
);
1185 Ptr
+= StrSize ((CHAR16
*) Ptr
);
1187 NewOptionPtr
= EfiAllocateZeroPool (NewOptionSize
);
1188 if (NULL
== NewOptionPtr
) {
1189 return EFI_OUT_OF_RESOURCES
;
1192 TempPtr
= NewOptionPtr
;
1203 TempPtr
+= sizeof (UINT32
);
1206 // BBS device path Length
1208 *((UINT16
*) TempPtr
) = (UINT16
) (sizeof (BBS_BBS_DEVICE_PATH
) +
1209 AsciiStrLen (DescAsciiString
) +
1210 EFI_END_DEVICE_PATH_LENGTH
);
1212 TempPtr
+= sizeof (UINT16
);
1215 // Description string
1220 StrSize (DescString
)
1223 TempPtr
+= StrSize (DescString
);
1231 sizeof (BBS_BBS_DEVICE_PATH
)
1235 ((BBS_BBS_DEVICE_PATH
*) TempPtr
)->String
,
1237 AsciiStrSize (DescAsciiString
)
1240 SetDevicePathNodeLength (
1241 (EFI_DEVICE_PATH_PROTOCOL
*) TempPtr
,
1242 sizeof (BBS_BBS_DEVICE_PATH
) + AsciiStrLen (DescAsciiString
)
1245 TempPtr
+= sizeof (BBS_BBS_DEVICE_PATH
) + AsciiStrLen (DescAsciiString
);
1253 EFI_END_DEVICE_PATH_LENGTH
1255 TempPtr
+= EFI_END_DEVICE_PATH_LENGTH
;
1258 // Now TempPtr point to optional data, i.e. Bbs Table
1262 LegacyDeviceContext
->BbsTable
,
1267 // Now TempPtr point to BBS index
1269 TempPtr
+= sizeof (BBS_TABLE
);
1270 *((UINT16
*) TempPtr
) = (UINT16
) LegacyDeviceContext
->Index
;
1272 Status
= gRT
->SetVariable (
1274 &gEfiGlobalVariableGuid
,
1280 SafeFreePool (NewOptionPtr
);
1281 SafeFreePool (BootOptionVar
);
1284 BOpt_GetBootOptions (CallbackData
);
1290 IN BMM_CALLBACK_DATA
*CallbackData
1295 CONSOLE_OUT_MODE ModeInfo
;
1297 Mode
= CallbackData
->BmmFakeNvData
.ConsoleOutMode
;
1299 Status
= gST
->ConOut
->QueryMode (gST
->ConOut
, Mode
, &(ModeInfo
.Column
), &(ModeInfo
.Row
));
1300 if (EFI_ERROR(Status
)) {
1301 ModeInfo
.Column
= 80;
1305 Status
= gRT
->SetVariable (
1307 &gEfiGenericPlatformVariableGuid
,
1308 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_NON_VOLATILE
,
1309 sizeof (CONSOLE_OUT_MODE
),