2 Variable operation that will be used by bootmaint
4 Copyright (c) 2004 - 2008, Intel Corporation. <BR>
5 All rights reserved. This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15 #include "BootMaint.h"
18 Delete Boot Option that represent a Deleted state in BootOptionMenu.
19 After deleting this boot option, call Var_ChangeBootOrder to
20 make sure BootOrder is in valid state.
23 @param VOID EDES_TODO: Add parameter description
25 EDES_TODO: Incomplete Descriptions EFI_SUCCESS
26 EDES_TODO: Incomplete Descriptions Others
34 BM_MENU_ENTRY
*NewMenuEntry
;
35 BM_LOAD_CONTEXT
*NewLoadContext
;
36 UINT16 BootString
[10];
43 for (Index
= 0; Index
< BootOptionMenu
.MenuNumber
; Index
++) {
44 NewMenuEntry
= BOpt_GetMenuEntry (&BootOptionMenu
, (Index
- Index2
));
45 if (NULL
== NewMenuEntry
) {
49 NewLoadContext
= (BM_LOAD_CONTEXT
*) NewMenuEntry
->VariableContext
;
50 if (!NewLoadContext
->Deleted
) {
58 NewMenuEntry
->OptionNumber
61 EfiLibDeleteVariable (BootString
, &gEfiGlobalVariableGuid
);
64 // If current Load Option is the same as BootNext,
65 // must delete BootNext in order to make sure
66 // there will be no panic on next boot
68 if (NewLoadContext
->IsBootNext
) {
69 EfiLibDeleteVariable (L
"BootNext", &gEfiGlobalVariableGuid
);
72 RemoveEntryList (&NewMenuEntry
->Link
);
73 BOpt_DestroyMenuEntry (NewMenuEntry
);
77 BootOptionMenu
.MenuNumber
-= Index2
;
79 Status
= Var_ChangeBootOrder ();
84 After any operation on Boot####, there will be a discrepancy in BootOrder.
85 Since some are missing but in BootOrder, while some are present but are
86 not reflected by BootOrder. Then a function rebuild BootOrder from
87 scratch by content from BootOptionMenu is needed.
90 @param VOID EDES_TODO: Add parameter description
92 EDES_TODO: Incomplete Descriptions EFI_SUCCESS
93 EDES_TODO: Incomplete Descriptions Others
103 BM_MENU_ENTRY
*NewMenuEntry
;
104 UINT16
*BootOrderList
;
105 UINT16
*BootOrderListPtr
;
106 UINTN BootOrderListSize
;
109 BootOrderList
= NULL
;
110 BootOrderListSize
= 0;
113 // First check whether BootOrder is present in current configuration
115 BootOrderList
= BdsLibGetVariableAndSize (
117 &gEfiGlobalVariableGuid
,
122 // If exists, delete it to hold new BootOrder
125 EfiLibDeleteVariable (L
"BootOrder", &gEfiGlobalVariableGuid
);
126 SafeFreePool (BootOrderList
);
127 BootOrderList
= NULL
;
130 // Maybe here should be some check method to ensure that
131 // no new added boot options will be added
132 // but the setup engine now will give only one callback
133 // that is to say, user are granted only one chance to
134 // decide whether the boot option will be added or not
135 // there should be no indictor to show whether this
136 // is a "new" boot option
138 BootOrderListSize
= BootOptionMenu
.MenuNumber
;
140 if (BootOrderListSize
> 0) {
141 BootOrderList
= EfiAllocateZeroPool (BootOrderListSize
* sizeof (UINT16
));
142 ASSERT (BootOrderList
!= NULL
);
143 BootOrderListPtr
= BootOrderList
;
146 // Get all current used Boot#### from BootOptionMenu.
147 // OptionNumber in each BM_LOAD_OPTION is really its
150 for (Index
= 0; Index
< BootOrderListSize
; Index
++) {
151 NewMenuEntry
= BOpt_GetMenuEntry (&BootOptionMenu
, Index
);
152 *BootOrderList
= (UINT16
) NewMenuEntry
->OptionNumber
;
156 BootOrderList
= BootOrderListPtr
;
159 // After building the BootOrderList, write it back
161 Status
= gRT
->SetVariable (
163 &gEfiGlobalVariableGuid
,
165 BootOrderListSize
* sizeof (UINT16
),
168 if (EFI_ERROR (Status
)) {
176 Delete Load Option that represent a Deleted state in BootOptionMenu.
177 After deleting this Driver option, call Var_ChangeDriverOrder to
178 make sure DriverOrder is in valid state.
181 @param VOID EDES_TODO: Add parameter description
183 EDES_TODO: Incomplete Descriptions EFI_SUCCESS
184 EDES_TODO: Incomplete Descriptions Others
188 Var_DelDriverOption (
192 BM_MENU_ENTRY
*NewMenuEntry
;
193 BM_LOAD_CONTEXT
*NewLoadContext
;
194 UINT16 DriverString
[12];
199 Status
= EFI_SUCCESS
;
201 for (Index
= 0; Index
< DriverOptionMenu
.MenuNumber
; Index
++) {
202 NewMenuEntry
= BOpt_GetMenuEntry (&DriverOptionMenu
, (Index
- Index2
));
203 if (NULL
== NewMenuEntry
) {
204 return EFI_NOT_FOUND
;
207 NewLoadContext
= (BM_LOAD_CONTEXT
*) NewMenuEntry
->VariableContext
;
208 if (!NewLoadContext
->Deleted
) {
214 sizeof (DriverString
),
216 NewMenuEntry
->OptionNumber
219 EfiLibDeleteVariable (DriverString
, &gEfiGlobalVariableGuid
);
222 RemoveEntryList (&NewMenuEntry
->Link
);
223 BOpt_DestroyMenuEntry (NewMenuEntry
);
227 DriverOptionMenu
.MenuNumber
-= Index2
;
229 Status
= Var_ChangeDriverOrder ();
234 After any operation on Driver####, there will be a discrepancy in
235 DriverOrder. Since some are missing but in DriverOrder, while some
236 are present but are not reflected by DriverOrder. Then a function
237 rebuild DriverOrder from scratch by content from DriverOptionMenu is
241 @param VOID EDES_TODO: Add parameter description
243 EDES_TODO: Incomplete Descriptions EFI_SUCCESS
244 EDES_TODO: Incomplete Descriptions Others
248 Var_ChangeDriverOrder (
253 BM_MENU_ENTRY
*NewMenuEntry
;
254 UINT16
*DriverOrderList
;
255 UINT16
*DriverOrderListPtr
;
256 UINTN DriverOrderListSize
;
259 DriverOrderList
= NULL
;
260 DriverOrderListSize
= 0;
263 // First check whether DriverOrder is present in current configuration
265 DriverOrderList
= BdsLibGetVariableAndSize (
267 &gEfiGlobalVariableGuid
,
272 // If exists, delete it to hold new DriverOrder
274 if (DriverOrderList
) {
275 EfiLibDeleteVariable (L
"DriverOrder", &gEfiGlobalVariableGuid
);
276 SafeFreePool (DriverOrderList
);
277 DriverOrderList
= NULL
;
280 DriverOrderListSize
= DriverOptionMenu
.MenuNumber
;
282 if (DriverOrderListSize
> 0) {
283 DriverOrderList
= EfiAllocateZeroPool (DriverOrderListSize
* sizeof (UINT16
));
284 ASSERT (DriverOrderList
!= NULL
);
285 DriverOrderListPtr
= DriverOrderList
;
288 // Get all current used Driver#### from DriverOptionMenu.
289 // OptionNumber in each BM_LOAD_OPTION is really its
292 for (Index
= 0; Index
< DriverOrderListSize
; Index
++) {
293 NewMenuEntry
= BOpt_GetMenuEntry (&DriverOptionMenu
, Index
);
294 *DriverOrderList
= (UINT16
) NewMenuEntry
->OptionNumber
;
298 DriverOrderList
= DriverOrderListPtr
;
301 // After building the DriverOrderList, write it back
303 Status
= gRT
->SetVariable (
305 &gEfiGlobalVariableGuid
,
307 DriverOrderListSize
* sizeof (UINT16
),
310 if (EFI_ERROR (Status
)) {
318 EDES_TODO: Add function description
320 @param VOID EDES_TODO: Add parameter description
322 @return EDES_TODO: Add description for return value
326 Var_UpdateAllConsoleOption (
330 EFI_DEVICE_PATH_PROTOCOL
*OutDevicePath
;
331 EFI_DEVICE_PATH_PROTOCOL
*InpDevicePath
;
332 EFI_DEVICE_PATH_PROTOCOL
*ErrDevicePath
;
335 OutDevicePath
= EfiLibGetVariable (L
"ConOut", &gEfiGlobalVariableGuid
);
336 InpDevicePath
= EfiLibGetVariable (L
"ConIn", &gEfiGlobalVariableGuid
);
337 ErrDevicePath
= EfiLibGetVariable (L
"ErrOut", &gEfiGlobalVariableGuid
);
339 ChangeVariableDevicePath (OutDevicePath
);
340 Status
= gRT
->SetVariable (
342 &gEfiGlobalVariableGuid
,
344 GetDevicePathSize (OutDevicePath
),
347 ASSERT (!EFI_ERROR (Status
));
351 ChangeVariableDevicePath (InpDevicePath
);
352 Status
= gRT
->SetVariable (
354 &gEfiGlobalVariableGuid
,
356 GetDevicePathSize (InpDevicePath
),
359 ASSERT (!EFI_ERROR (Status
));
363 ChangeVariableDevicePath (ErrDevicePath
);
364 Status
= gRT
->SetVariable (
366 &gEfiGlobalVariableGuid
,
368 GetDevicePathSize (ErrDevicePath
),
371 ASSERT (!EFI_ERROR (Status
));
376 EDES_TODO: Add function description
378 @param ConsoleName EDES_TODO: Add parameter description
379 @param ConsoleMenu EDES_TODO: Add parameter description
380 @param UpdatePageId EDES_TODO: Add parameter description
382 @return EDES_TODO: Add description for return value
386 Var_UpdateConsoleOption (
387 IN UINT16
*ConsoleName
,
388 IN BM_MENU_OPTION
*ConsoleMenu
,
389 IN UINT16 UpdatePageId
392 EFI_DEVICE_PATH_PROTOCOL
*ConDevicePath
;
393 BM_MENU_ENTRY
*NewMenuEntry
;
394 BM_CONSOLE_CONTEXT
*NewConsoleContext
;
395 BM_TERMINAL_CONTEXT
*NewTerminalContext
;
397 VENDOR_DEVICE_PATH Vendor
;
398 EFI_DEVICE_PATH_PROTOCOL
*TerminalDevicePath
;
401 ConDevicePath
= EfiLibGetVariable (ConsoleName
, &gEfiGlobalVariableGuid
);
402 if (ConDevicePath
!= NULL
) {
403 EfiLibDeleteVariable (ConsoleName
, &gEfiGlobalVariableGuid
);
404 SafeFreePool (ConDevicePath
);
405 ConDevicePath
= NULL
;
409 // First add all console input device to it from console input menu
411 for (Index
= 0; Index
< ConsoleMenu
->MenuNumber
; Index
++) {
412 NewMenuEntry
= BOpt_GetMenuEntry (ConsoleMenu
, Index
);
413 if (NULL
== NewMenuEntry
) {
414 return EFI_NOT_FOUND
;
417 NewConsoleContext
= (BM_CONSOLE_CONTEXT
*) NewMenuEntry
->VariableContext
;
418 if (NewConsoleContext
->IsActive
) {
419 ConDevicePath
= AppendDevicePathInstance (
421 NewConsoleContext
->DevicePath
426 for (Index
= 0; Index
< TerminalMenu
.MenuNumber
; Index
++) {
427 NewMenuEntry
= BOpt_GetMenuEntry (&TerminalMenu
, Index
);
428 if (NULL
== NewMenuEntry
) {
429 return EFI_NOT_FOUND
;
432 NewTerminalContext
= (BM_TERMINAL_CONTEXT
*) NewMenuEntry
->VariableContext
;
433 if ((NewTerminalContext
->IsConIn
&& (UpdatePageId
== FORM_CON_IN_ID
)) ||
434 (NewTerminalContext
->IsConOut
&& (UpdatePageId
== FORM_CON_OUT_ID
)) ||
435 (NewTerminalContext
->IsStdErr
&& (UpdatePageId
== FORM_CON_ERR_ID
))
437 Vendor
.Header
.Type
= MESSAGING_DEVICE_PATH
;
438 Vendor
.Header
.SubType
= MSG_VENDOR_DP
;
441 &Guid
[NewTerminalContext
->TerminalType
],
444 SetDevicePathNodeLength (&Vendor
.Header
, sizeof (VENDOR_DEVICE_PATH
));
445 TerminalDevicePath
= AppendDevicePathNode (
446 NewTerminalContext
->DevicePath
,
447 (EFI_DEVICE_PATH_PROTOCOL
*) &Vendor
449 ASSERT (TerminalDevicePath
!= NULL
);
450 ChangeTerminalDevicePath (TerminalDevicePath
, TRUE
);
451 ConDevicePath
= AppendDevicePathInstance (
459 Status
= gRT
->SetVariable (
461 &gEfiGlobalVariableGuid
,
463 GetDevicePathSize (ConDevicePath
),
466 if (EFI_ERROR (Status
)) {
476 EDES_TODO: Add function description
478 @param VOID EDES_TODO: Add parameter description
480 @return EDES_TODO: Add description for return value
484 Var_UpdateConsoleInpOption (
488 return Var_UpdateConsoleOption (L
"ConIn", &ConsoleInpMenu
, FORM_CON_IN_ID
);
492 EDES_TODO: Add function description
494 @param VOID EDES_TODO: Add parameter description
496 @return EDES_TODO: Add description for return value
500 Var_UpdateConsoleOutOption (
504 return Var_UpdateConsoleOption (L
"ConOut", &ConsoleOutMenu
, FORM_CON_OUT_ID
);
508 EDES_TODO: Add function description
510 @param VOID EDES_TODO: Add parameter description
512 @return EDES_TODO: Add description for return value
516 Var_UpdateErrorOutOption (
520 return Var_UpdateConsoleOption (L
"ErrOut", &ConsoleErrMenu
, FORM_CON_ERR_ID
);
524 EDES_TODO: Add function description
526 @param CallbackData EDES_TODO: Add parameter description
527 @param HiiHandle EDES_TODO: Add parameter description
528 @param DescriptionData EDES_TODO: Add parameter description
529 @param OptionalData EDES_TODO: Add parameter description
530 @param ForceReconnect EDES_TODO: Add parameter description
532 @return EDES_TODO: Add description for return value
536 Var_UpdateDriverOption (
537 IN BMM_CALLBACK_DATA
*CallbackData
,
538 IN EFI_HII_HANDLE HiiHandle
,
539 IN UINT16
*DescriptionData
,
540 IN UINT16
*OptionalData
,
541 IN UINT8 ForceReconnect
545 UINT16
*DriverOrderList
;
546 UINT16
*NewDriverOrderList
;
547 UINT16 DriverString
[12];
548 UINTN DriverOrderListSize
;
552 BM_MENU_ENTRY
*NewMenuEntry
;
553 BM_LOAD_CONTEXT
*NewLoadContext
;
554 BOOLEAN OptionalDataExist
;
557 OptionalDataExist
= FALSE
;
559 Index
= BOpt_GetDriverOptionNumber ();
562 sizeof (DriverString
),
567 if (*DescriptionData
== 0x0000) {
568 StrCpy (DescriptionData
, DriverString
);
571 BufferSize
= sizeof (UINT32
) + sizeof (UINT16
) + StrSize (DescriptionData
);
572 BufferSize
+= GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
);
574 if (*OptionalData
!= 0x0000) {
575 OptionalDataExist
= TRUE
;
576 BufferSize
+= StrSize (OptionalData
);
579 Buffer
= EfiAllocateZeroPool (BufferSize
);
580 if (NULL
== Buffer
) {
581 return EFI_OUT_OF_RESOURCES
;
584 NewMenuEntry
= BOpt_CreateMenuEntry (BM_LOAD_CONTEXT_SELECT
);
585 if (NULL
== NewMenuEntry
) {
586 return EFI_OUT_OF_RESOURCES
;
589 NewLoadContext
= (BM_LOAD_CONTEXT
*) NewMenuEntry
->VariableContext
;
590 NewLoadContext
->Deleted
= FALSE
;
591 NewLoadContext
->LoadOptionSize
= BufferSize
;
592 Ptr
= (UINT8
*) Buffer
;
593 NewLoadContext
->LoadOption
= Ptr
;
594 *((UINT32
*) Ptr
) = LOAD_OPTION_ACTIVE
| (ForceReconnect
<< 1);
595 NewLoadContext
->Attributes
= *((UINT32
*) Ptr
);
596 NewLoadContext
->IsActive
= TRUE
;
597 NewLoadContext
->ForceReconnect
= (BOOLEAN
) (NewLoadContext
->Attributes
& LOAD_OPTION_FORCE_RECONNECT
);
599 Ptr
+= sizeof (UINT32
);
600 *((UINT16
*) Ptr
) = (UINT16
) GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
);
601 NewLoadContext
->FilePathListLength
= *((UINT16
*) Ptr
);
603 Ptr
+= sizeof (UINT16
);
607 StrSize (DescriptionData
)
610 NewLoadContext
->Description
= EfiAllocateZeroPool (StrSize (DescriptionData
));
611 ASSERT (NewLoadContext
->Description
!= NULL
);
612 NewMenuEntry
->DisplayString
= NewLoadContext
->Description
;
614 NewLoadContext
->Description
,
616 StrSize (DescriptionData
)
619 Ptr
+= StrSize (DescriptionData
);
622 CallbackData
->LoadContext
->FilePathList
,
623 GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
)
626 NewLoadContext
->FilePathList
= EfiAllocateZeroPool (GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
));
627 ASSERT (NewLoadContext
->FilePathList
!= NULL
);
630 NewLoadContext
->FilePathList
,
632 GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
)
635 NewMenuEntry
->HelpString
= DevicePathToStr (NewLoadContext
->FilePathList
);
636 NewMenuEntry
->OptionNumber
= Index
;
637 NewMenuEntry
->DisplayStringToken
= GetStringTokenFromDepository (
639 DriverOptionStrDepository
641 HiiLibNewString (HiiHandle
, &NewMenuEntry
->DisplayStringToken
, NewMenuEntry
->DisplayString
);
643 NewMenuEntry
->HelpStringToken
= GetStringTokenFromDepository (
645 DriverOptionHelpStrDepository
647 HiiLibNewString (HiiHandle
, &NewMenuEntry
->HelpStringToken
, NewMenuEntry
->HelpString
);
649 if (OptionalDataExist
) {
650 Ptr
+= (UINT8
) GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
);
655 StrSize (OptionalData
)
659 Status
= gRT
->SetVariable (
661 &gEfiGlobalVariableGuid
,
666 ASSERT_EFI_ERROR (Status
);
667 DriverOrderList
= BdsLibGetVariableAndSize (
669 &gEfiGlobalVariableGuid
,
672 NewDriverOrderList
= EfiAllocateZeroPool (DriverOrderListSize
+ sizeof (UINT16
));
673 ASSERT (NewDriverOrderList
!= NULL
);
674 CopyMem (NewDriverOrderList
, DriverOrderList
, DriverOrderListSize
);
675 NewDriverOrderList
[DriverOrderListSize
/ sizeof (UINT16
)] = Index
;
676 if (DriverOrderList
!= NULL
) {
677 EfiLibDeleteVariable (L
"DriverOrder", &gEfiGlobalVariableGuid
);
680 Status
= gRT
->SetVariable (
682 &gEfiGlobalVariableGuid
,
684 DriverOrderListSize
+ sizeof (UINT16
),
687 ASSERT_EFI_ERROR (Status
);
688 SafeFreePool (DriverOrderList
);
689 DriverOrderList
= NULL
;
690 SafeFreePool (NewDriverOrderList
);
691 NewDriverOrderList
= NULL
;
692 InsertTailList (&DriverOptionMenu
.Head
, &NewMenuEntry
->Link
);
693 DriverOptionMenu
.MenuNumber
++;
695 *DescriptionData
= 0x0000;
696 *OptionalData
= 0x0000;
701 EDES_TODO: Add function description
703 @param CallbackData EDES_TODO: Add parameter description
704 @param NvRamMap EDES_TODO: Add parameter description
706 @return EDES_TODO: Add description for return value
710 Var_UpdateBootOption (
711 IN BMM_CALLBACK_DATA
*CallbackData
,
712 IN FILE_EXPLORER_NV_DATA
*NvRamMap
715 UINT16
*BootOrderList
;
716 UINT16
*NewBootOrderList
;
717 UINTN BootOrderListSize
;
718 UINT16 BootString
[10];
723 BM_MENU_ENTRY
*NewMenuEntry
;
724 BM_LOAD_CONTEXT
*NewLoadContext
;
725 BOOLEAN OptionalDataExist
;
728 OptionalDataExist
= FALSE
;
730 Index
= BOpt_GetBootOptionNumber () ;
731 UnicodeSPrint (BootString
, sizeof (BootString
), L
"Boot%04x", Index
);
733 if (NvRamMap
->DescriptionData
[0] == 0x0000) {
734 StrCpy (NvRamMap
->DescriptionData
, BootString
);
737 BufferSize
= sizeof (UINT32
) + sizeof (UINT16
) + StrSize (NvRamMap
->DescriptionData
);
738 BufferSize
+= GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
);
740 if (NvRamMap
->OptionalData
[0] != 0x0000) {
741 OptionalDataExist
= TRUE
;
742 BufferSize
+= StrSize (NvRamMap
->OptionalData
);
745 Buffer
= EfiAllocateZeroPool (BufferSize
);
746 if (NULL
== Buffer
) {
747 return EFI_OUT_OF_RESOURCES
;
750 NewMenuEntry
= BOpt_CreateMenuEntry (BM_LOAD_CONTEXT_SELECT
);
751 if (NULL
== NewMenuEntry
) {
752 return EFI_OUT_OF_RESOURCES
;
755 NewLoadContext
= (BM_LOAD_CONTEXT
*) NewMenuEntry
->VariableContext
;
756 NewLoadContext
->Deleted
= FALSE
;
757 NewLoadContext
->LoadOptionSize
= BufferSize
;
758 Ptr
= (UINT8
*) Buffer
;
759 NewLoadContext
->LoadOption
= Ptr
;
760 *((UINT32
*) Ptr
) = LOAD_OPTION_ACTIVE
;
761 NewLoadContext
->Attributes
= *((UINT32
*) Ptr
);
762 NewLoadContext
->IsActive
= TRUE
;
763 NewLoadContext
->ForceReconnect
= (BOOLEAN
) (NewLoadContext
->Attributes
& LOAD_OPTION_FORCE_RECONNECT
);
765 Ptr
+= sizeof (UINT32
);
766 *((UINT16
*) Ptr
) = (UINT16
) GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
);
767 NewLoadContext
->FilePathListLength
= *((UINT16
*) Ptr
);
768 Ptr
+= sizeof (UINT16
);
772 NvRamMap
->DescriptionData
,
773 StrSize (NvRamMap
->DescriptionData
)
776 NewLoadContext
->Description
= EfiAllocateZeroPool (StrSize (NvRamMap
->DescriptionData
));
777 ASSERT (NewLoadContext
->Description
!= NULL
);
779 NewMenuEntry
->DisplayString
= NewLoadContext
->Description
;
781 NewLoadContext
->Description
,
783 StrSize (NvRamMap
->DescriptionData
)
786 Ptr
+= StrSize (NvRamMap
->DescriptionData
);
789 CallbackData
->LoadContext
->FilePathList
,
790 GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
)
793 NewLoadContext
->FilePathList
= EfiAllocateZeroPool (GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
));
794 ASSERT (NewLoadContext
->FilePathList
!= NULL
);
797 NewLoadContext
->FilePathList
,
799 GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
)
802 NewMenuEntry
->HelpString
= DevicePathToStr (NewLoadContext
->FilePathList
);
803 NewMenuEntry
->OptionNumber
= Index
;
804 NewMenuEntry
->DisplayStringToken
= GetStringTokenFromDepository (
806 BootOptionStrDepository
808 HiiLibNewString (CallbackData
->FeHiiHandle
, &NewMenuEntry
->DisplayStringToken
, NewMenuEntry
->DisplayString
);
810 NewMenuEntry
->HelpStringToken
= GetStringTokenFromDepository (
812 BootOptionHelpStrDepository
814 HiiLibNewString (CallbackData
->FeHiiHandle
, &NewMenuEntry
->HelpStringToken
, NewMenuEntry
->HelpString
);
816 if (OptionalDataExist
) {
817 Ptr
+= (UINT8
) GetDevicePathSize (CallbackData
->LoadContext
->FilePathList
);
819 CopyMem (Ptr
, NvRamMap
->OptionalData
, StrSize (NvRamMap
->OptionalData
));
822 Status
= gRT
->SetVariable (
824 &gEfiGlobalVariableGuid
,
829 ASSERT_EFI_ERROR (Status
);
831 BootOrderList
= BdsLibGetVariableAndSize (
833 &gEfiGlobalVariableGuid
,
837 NewBootOrderList
= EfiAllocateZeroPool (BootOrderListSize
+ sizeof (UINT16
));
838 ASSERT (NewBootOrderList
!= NULL
);
839 CopyMem (NewBootOrderList
, BootOrderList
, BootOrderListSize
);
840 NewBootOrderList
[BootOrderListSize
/ sizeof (UINT16
)] = Index
;
842 if (BootOrderList
!= NULL
) {
843 EfiLibDeleteVariable (L
"BootOrder", &gEfiGlobalVariableGuid
);
846 Status
= gRT
->SetVariable (
848 &gEfiGlobalVariableGuid
,
850 BootOrderListSize
+ sizeof (UINT16
),
853 ASSERT_EFI_ERROR (Status
);
855 SafeFreePool (BootOrderList
);
856 BootOrderList
= NULL
;
857 SafeFreePool (NewBootOrderList
);
858 NewBootOrderList
= NULL
;
859 InsertTailList (&BootOptionMenu
.Head
, &NewMenuEntry
->Link
);
860 BootOptionMenu
.MenuNumber
++;
862 NvRamMap
->DescriptionData
[0] = 0x0000;
863 NvRamMap
->OptionalData
[0] = 0x0000;
868 EDES_TODO: Add function description
870 @param CallbackData EDES_TODO: Add parameter description
872 @return EDES_TODO: Add description for return value
877 IN BMM_CALLBACK_DATA
*CallbackData
880 BM_MENU_ENTRY
*NewMenuEntry
;
881 BM_LOAD_CONTEXT
*NewLoadContext
;
882 BMM_FAKE_NV_DATA
*CurrentFakeNVMap
;
886 Status
= EFI_SUCCESS
;
887 CurrentFakeNVMap
= &CallbackData
->BmmFakeNvData
;
888 for (Index
= 0; Index
< BootOptionMenu
.MenuNumber
; Index
++) {
889 NewMenuEntry
= BOpt_GetMenuEntry (&BootOptionMenu
, Index
);
890 if (NULL
== NewMenuEntry
) {
891 return EFI_NOT_FOUND
;
894 NewLoadContext
= (BM_LOAD_CONTEXT
*) NewMenuEntry
->VariableContext
;
895 NewLoadContext
->IsBootNext
= FALSE
;
898 if (CurrentFakeNVMap
->BootNext
== BootOptionMenu
.MenuNumber
) {
899 EfiLibDeleteVariable (L
"BootNext", &gEfiGlobalVariableGuid
);
903 NewMenuEntry
= BOpt_GetMenuEntry (
905 CurrentFakeNVMap
->BootNext
907 if (NULL
== NewMenuEntry
) {
908 return EFI_NOT_FOUND
;
911 NewLoadContext
= (BM_LOAD_CONTEXT
*) NewMenuEntry
->VariableContext
;
912 Status
= gRT
->SetVariable (
914 &gEfiGlobalVariableGuid
,
917 &NewMenuEntry
->OptionNumber
919 NewLoadContext
->IsBootNext
= TRUE
;
920 CallbackData
->BmmOldFakeNVData
.BootNext
= CurrentFakeNVMap
->BootNext
;
925 EDES_TODO: Add function description
927 @param CallbackData EDES_TODO: Add parameter description
929 @return EDES_TODO: Add description for return value
933 Var_UpdateBootOrder (
934 IN BMM_CALLBACK_DATA
*CallbackData
939 UINT16
*BootOrderList
;
940 UINT16
*NewBootOrderList
;
941 UINTN BootOrderListSize
;
944 BootOrderList
= NULL
;
945 BootOrderListSize
= 0;
948 // First check whether BootOrder is present in current configuration
950 BootOrderList
= BdsLibGetVariableAndSize (
952 &gEfiGlobalVariableGuid
,
956 NewBootOrderList
= EfiAllocateZeroPool (BootOrderListSize
);
957 if (!NewBootOrderList
) {
958 return EFI_OUT_OF_RESOURCES
;
961 Map
= EfiAllocateZeroPool (BootOrderListSize
/ sizeof (UINT16
));
963 return EFI_OUT_OF_RESOURCES
;
966 // If exists, delete it to hold new BootOrder
969 EfiLibDeleteVariable (L
"BootOrder", &gEfiGlobalVariableGuid
);
972 for (Index
= 0; Index
< BootOptionMenu
.MenuNumber
; Index
++) {
973 NewBootOrderList
[Index
] = (UINT16
) (CallbackData
->BmmFakeNvData
.OptionOrder
[Index
] - 1);
976 Status
= gRT
->SetVariable (
978 &gEfiGlobalVariableGuid
,
983 SafeFreePool (BootOrderList
);
984 SafeFreePool (NewBootOrderList
);
986 if (EFI_ERROR (Status
)) {
990 BOpt_FreeMenu (&BootOptionMenu
);
991 BOpt_GetBootOptions (CallbackData
);
998 EDES_TODO: Add function description
1000 @param CallbackData EDES_TODO: Add parameter description
1002 @return EDES_TODO: Add description for return value
1006 Var_UpdateDriverOrder (
1007 IN BMM_CALLBACK_DATA
*CallbackData
1012 UINT16
*DriverOrderList
;
1013 UINT16
*NewDriverOrderList
;
1014 UINTN DriverOrderListSize
;
1016 DriverOrderList
= NULL
;
1017 DriverOrderListSize
= 0;
1020 // First check whether DriverOrder is present in current configuration
1022 DriverOrderList
= BdsLibGetVariableAndSize (
1024 &gEfiGlobalVariableGuid
,
1025 &DriverOrderListSize
1028 NewDriverOrderList
= EfiAllocateZeroPool (DriverOrderListSize
);
1030 if (!NewDriverOrderList
) {
1031 return EFI_OUT_OF_RESOURCES
;
1034 // If exists, delete it to hold new DriverOrder
1036 if (DriverOrderList
) {
1037 EfiLibDeleteVariable (L
"DriverOrder", &gEfiGlobalVariableGuid
);
1040 for (Index
= 0; Index
< DriverOrderListSize
; Index
++) {
1041 NewDriverOrderList
[Index
] = (UINT16
) (CallbackData
->BmmFakeNvData
.OptionOrder
[Index
] - 1);
1044 Status
= gRT
->SetVariable (
1046 &gEfiGlobalVariableGuid
,
1048 DriverOrderListSize
,
1051 if (EFI_ERROR (Status
)) {
1055 SafeFreePool (DriverOrderList
);
1057 BOpt_FreeMenu (&DriverOptionMenu
);
1058 BOpt_GetDriverOptions (CallbackData
);
1063 EDES_TODO: Add function description
1065 @param CallbackData EDES_TODO: Add parameter description
1067 @return EDES_TODO: Add description for return value
1071 Var_UpdateBBSOption (
1072 IN BMM_CALLBACK_DATA
*CallbackData
1077 VOID
*BootOptionVar
;
1078 CHAR16 VarName
[100];
1082 CHAR16 DescString
[100];
1083 CHAR8 DescAsciiString
[100];
1084 UINTN NewOptionSize
;
1085 UINT8
*NewOptionPtr
;
1088 BM_MENU_OPTION
*OptionMenu
;
1089 BM_LEGACY_DEVICE_CONTEXT
*LegacyDeviceContext
;
1093 BM_MENU_ENTRY
*NewMenuEntry
;
1094 BM_LEGACY_DEV_ORDER_CONTEXT
*DevOrder
;
1102 LegacyDeviceContext
= NULL
;
1106 if (FORM_SET_FD_ORDER_ID
== CallbackData
->BmmPreviousPageId
) {
1107 OptionMenu
= (BM_MENU_OPTION
*) &LegacyFDMenu
;
1108 LegacyDev
= CallbackData
->BmmFakeNvData
.LegacyFD
;
1109 CallbackData
->BbsType
= BBS_FLOPPY
;
1111 if (FORM_SET_HD_ORDER_ID
== CallbackData
->BmmPreviousPageId
) {
1112 OptionMenu
= (BM_MENU_OPTION
*) &LegacyHDMenu
;
1113 LegacyDev
= CallbackData
->BmmFakeNvData
.LegacyHD
;
1114 CallbackData
->BbsType
= BBS_HARDDISK
;
1116 if (FORM_SET_CD_ORDER_ID
== CallbackData
->BmmPreviousPageId
) {
1117 OptionMenu
= (BM_MENU_OPTION
*) &LegacyCDMenu
;
1118 LegacyDev
= CallbackData
->BmmFakeNvData
.LegacyCD
;
1119 CallbackData
->BbsType
= BBS_CDROM
;
1121 if (FORM_SET_NET_ORDER_ID
== CallbackData
->BmmPreviousPageId
) {
1122 OptionMenu
= (BM_MENU_OPTION
*) &LegacyNETMenu
;
1123 LegacyDev
= CallbackData
->BmmFakeNvData
.LegacyNET
;
1124 CallbackData
->BbsType
= BBS_EMBED_NETWORK
;
1126 OptionMenu
= (BM_MENU_OPTION
*) &LegacyBEVMenu
;
1127 LegacyDev
= CallbackData
->BmmFakeNvData
.LegacyBEV
;
1128 CallbackData
->BbsType
= BBS_BEV_DEVICE
;
1134 DisMap
= CallbackData
->BmmOldFakeNVData
.DisableMap
;
1135 Status
= EFI_SUCCESS
;
1138 // Find the first device's context
1139 // If all devices are disabled( 0xFF == LegacyDev[0]), LegacyDeviceContext can be set to any VariableContext
1140 // because we just use it to fill the desc string, and user can not see the string in UI
1142 for (Index
= 0; Index
< OptionMenu
->MenuNumber
; Index
++) {
1143 NewMenuEntry
= BOpt_GetMenuEntry (OptionMenu
, Index
);
1144 LegacyDeviceContext
= (BM_LEGACY_DEVICE_CONTEXT
*) NewMenuEntry
->VariableContext
;
1145 if (0xFF != LegacyDev
[0] && LegacyDev
[0] == LegacyDeviceContext
->Index
) {
1146 DEBUG ((DEBUG_ERROR
, "DescStr: %s\n", LegacyDeviceContext
->Description
));
1151 // Update the Variable "LegacyDevOrder"
1153 VarData
= (UINT8
*) BdsLibGetVariableAndSize (
1155 &EfiLegacyDevOrderGuid
,
1159 if (NULL
== VarData
) {
1160 return EFI_NOT_FOUND
;
1163 OriginalPtr
= VarData
;
1164 DevOrder
= (BM_LEGACY_DEV_ORDER_CONTEXT
*) VarData
;
1166 while (VarData
< VarData
+ VarSize
) {
1167 if (DevOrder
->BbsType
== CallbackData
->BbsType
) {
1171 VarData
+= sizeof (BBS_TYPE
);
1172 VarData
+= *(UINT16
*) VarData
;
1173 DevOrder
= (BM_LEGACY_DEV_ORDER_CONTEXT
*) VarData
;
1176 if (VarData
>= VarData
+ VarSize
) {
1177 SafeFreePool (OriginalPtr
);
1178 return EFI_NOT_FOUND
;
1181 NewOrder
= (UINT16
*) EfiAllocateZeroPool (DevOrder
->Length
- sizeof (UINT16
));
1182 if (NULL
== NewOrder
) {
1183 SafeFreePool (VarData
);
1184 return EFI_OUT_OF_RESOURCES
;
1187 for (Index
= 0; Index
< OptionMenu
->MenuNumber
; Index
++) {
1188 if (0xFF == LegacyDev
[Index
]) {
1192 NewOrder
[Index
] = LegacyDev
[Index
];
1195 // Only the enable/disable state of each boot device with same device type can be changed,
1196 // so we can count on the index information in DevOrder.
1197 // DisMap bit array is the only reliable source to check a device's en/dis state,
1198 // so we use DisMap to set en/dis state of each item in NewOrder array
1200 for (Index2
= 0; Index2
< OptionMenu
->MenuNumber
; Index2
++) {
1201 Tmp
= *(UINT16
*) ((UINT8
*) DevOrder
+ sizeof (BBS_TYPE
) + sizeof (UINT16
) + Index2
* sizeof (UINT16
));
1204 Bit
= 7 - (Tmp
% 8);
1205 if (DisMap
[Pos
] & (1 << Bit
)) {
1206 NewOrder
[Index
] = (UINT16
) (0xFF00 | Tmp
);
1212 (UINT8
*) DevOrder
+ sizeof (BBS_TYPE
) + sizeof (UINT16
),
1214 DevOrder
->Length
- sizeof (UINT16
)
1216 SafeFreePool (NewOrder
);
1218 Status
= gRT
->SetVariable (
1220 &EfiLegacyDevOrderGuid
,
1226 SafeFreePool (OriginalPtr
);
1229 // Update Optional Data of Boot####
1231 BootOptionVar
= GetLegacyBootOptionVar (CallbackData
->BbsType
, &Index
, &OptionSize
);
1233 if (NULL
!= BootOptionVar
) {
1236 LegacyDeviceContext
->Description
,
1237 StrSize (LegacyDeviceContext
->Description
)
1240 UnicodeToAscii (DescString
, StrSize (DescString
), DescAsciiString
);
1242 NewOptionSize
= sizeof (UINT32
) + sizeof (UINT16
) + StrSize (DescString
) +
1243 sizeof (BBS_BBS_DEVICE_PATH
);
1244 NewOptionSize
+= AsciiStrLen (DescAsciiString
) +
1245 EFI_END_DEVICE_PATH_LENGTH
+ sizeof (BBS_TABLE
) + sizeof (UINT16
);
1247 UnicodeSPrint (VarName
, 100, L
"Boot%04x", Index
);
1249 Ptr
= BootOptionVar
;
1251 Attribute
= (UINT32
*) Ptr
;
1252 *Attribute
|= LOAD_OPTION_ACTIVE
;
1253 if (0xFF == LegacyDev
[0]) {
1255 // Disable this legacy boot option
1257 *Attribute
&= ~LOAD_OPTION_ACTIVE
;
1260 Ptr
+= sizeof (UINT32
);
1262 Ptr
+= sizeof (UINT16
);
1263 Ptr
+= StrSize ((CHAR16
*) Ptr
);
1265 NewOptionPtr
= EfiAllocateZeroPool (NewOptionSize
);
1266 if (NULL
== NewOptionPtr
) {
1267 return EFI_OUT_OF_RESOURCES
;
1270 TempPtr
= NewOptionPtr
;
1281 TempPtr
+= sizeof (UINT32
);
1284 // BBS device path Length
1286 *((UINT16
*) TempPtr
) = (UINT16
) (sizeof (BBS_BBS_DEVICE_PATH
) +
1287 AsciiStrLen (DescAsciiString
) +
1288 EFI_END_DEVICE_PATH_LENGTH
);
1290 TempPtr
+= sizeof (UINT16
);
1293 // Description string
1298 StrSize (DescString
)
1301 TempPtr
+= StrSize (DescString
);
1309 sizeof (BBS_BBS_DEVICE_PATH
)
1313 ((BBS_BBS_DEVICE_PATH
*) TempPtr
)->String
,
1315 AsciiStrSize (DescAsciiString
)
1318 SetDevicePathNodeLength (
1319 (EFI_DEVICE_PATH_PROTOCOL
*) TempPtr
,
1320 sizeof (BBS_BBS_DEVICE_PATH
) + AsciiStrLen (DescAsciiString
)
1323 TempPtr
+= sizeof (BBS_BBS_DEVICE_PATH
) + AsciiStrLen (DescAsciiString
);
1331 EFI_END_DEVICE_PATH_LENGTH
1333 TempPtr
+= EFI_END_DEVICE_PATH_LENGTH
;
1336 // Now TempPtr point to optional data, i.e. Bbs Table
1340 LegacyDeviceContext
->BbsTable
,
1345 // Now TempPtr point to BBS index
1347 TempPtr
+= sizeof (BBS_TABLE
);
1348 *((UINT16
*) TempPtr
) = (UINT16
) LegacyDeviceContext
->Index
;
1350 Status
= gRT
->SetVariable (
1352 &gEfiGlobalVariableGuid
,
1358 SafeFreePool (NewOptionPtr
);
1359 SafeFreePool (BootOptionVar
);
1362 BOpt_GetBootOptions (CallbackData
);
1367 EDES_TODO: Add function description
1369 @param CallbackData EDES_TODO: Add parameter description
1371 @return EDES_TODO: Add description for return value
1376 IN BMM_CALLBACK_DATA
*CallbackData
1381 CONSOLE_OUT_MODE ModeInfo
;
1383 Mode
= CallbackData
->BmmFakeNvData
.ConsoleOutMode
;
1385 Status
= gST
->ConOut
->QueryMode (gST
->ConOut
, Mode
, &(ModeInfo
.Column
), &(ModeInfo
.Row
));
1386 if (EFI_ERROR(Status
)) {
1387 ModeInfo
.Column
= 80;
1391 Status
= gRT
->SetVariable (
1393 &gEfiGenericPlatformVariableGuid
,
1394 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_NON_VOLATILE
,
1395 sizeof (CONSOLE_OUT_MODE
),