]> git.proxmox.com Git - mirror_edk2.git/blob - IntelFrameworkModulePkg/Universal/BdsDxe/BootMaint/Variable.c
ac7e61496f8d62b79357768ebc5712ce8a048c33
[mirror_edk2.git] / IntelFrameworkModulePkg / Universal / BdsDxe / BootMaint / Variable.c
1 /** @file
2 Variable operation that will be used by bootmaint
3
4 Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.<BR>
5 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
9
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.
12
13 **/
14
15 #include "BootMaint.h"
16
17 /**
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.
21
22 @retval EFI_SUCCESS If all boot load option EFI Variables corresponding to
23 BM_LOAD_CONTEXT marked for deletion is deleted.
24 @retval EFI_NOT_FOUND If can not find the boot option want to be deleted.
25 @return Others If failed to update the "BootOrder" variable after deletion.
26
27 **/
28 EFI_STATUS
29 Var_DelBootOption (
30 VOID
31 )
32 {
33 BM_MENU_ENTRY *NewMenuEntry;
34 BM_LOAD_CONTEXT *NewLoadContext;
35 UINT16 BootString[10];
36 EFI_STATUS Status;
37 UINTN Index;
38 UINTN Index2;
39
40 Status = EFI_SUCCESS;
41 Index2 = 0;
42 for (Index = 0; Index < BootOptionMenu.MenuNumber; Index++) {
43 NewMenuEntry = BOpt_GetMenuEntry (&BootOptionMenu, (Index - Index2));
44 if (NULL == NewMenuEntry) {
45 return EFI_NOT_FOUND;
46 }
47
48 NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;
49 if (!NewLoadContext->Deleted) {
50 continue;
51 }
52
53 UnicodeSPrint (
54 BootString,
55 sizeof (BootString),
56 L"Boot%04x",
57 NewMenuEntry->OptionNumber
58 );
59
60 EfiLibDeleteVariable (BootString, &gEfiGlobalVariableGuid);
61 Index2++;
62 //
63 // If current Load Option is the same as BootNext,
64 // must delete BootNext in order to make sure
65 // there will be no panic on next boot
66 //
67 if (NewLoadContext->IsBootNext) {
68 EfiLibDeleteVariable (L"BootNext", &gEfiGlobalVariableGuid);
69 }
70
71 RemoveEntryList (&NewMenuEntry->Link);
72 BOpt_DestroyMenuEntry (NewMenuEntry);
73 NewMenuEntry = NULL;
74 }
75
76 BootOptionMenu.MenuNumber -= Index2;
77
78 Status = Var_ChangeBootOrder ();
79 return Status;
80 }
81
82 /**
83 After any operation on Boot####, there will be a discrepancy in BootOrder.
84 Since some are missing but in BootOrder, while some are present but are
85 not reflected by BootOrder. Then a function rebuild BootOrder from
86 scratch by content from BootOptionMenu is needed.
87
88
89
90
91 @retval EFI_SUCCESS The boot order is updated successfully.
92 @return EFI_STATUS other than EFI_SUCCESS if failed to
93 Set the "BootOrder" EFI Variable.
94
95 **/
96 EFI_STATUS
97 Var_ChangeBootOrder (
98 VOID
99 )
100 {
101
102 EFI_STATUS Status;
103 BM_MENU_ENTRY *NewMenuEntry;
104 UINT16 *BootOrderList;
105 UINT16 *BootOrderListPtr;
106 UINTN BootOrderListSize;
107 UINTN Index;
108
109 BootOrderList = NULL;
110 BootOrderListSize = 0;
111
112 //
113 // First check whether BootOrder is present in current configuration
114 //
115 BootOrderList = BdsLibGetVariableAndSize (
116 L"BootOrder",
117 &gEfiGlobalVariableGuid,
118 &BootOrderListSize
119 );
120
121 //
122 // If exists, delete it to hold new BootOrder
123 //
124 if (BootOrderList != NULL) {
125 EfiLibDeleteVariable (L"BootOrder", &gEfiGlobalVariableGuid);
126 FreePool (BootOrderList);
127 BootOrderList = NULL;
128 }
129 //
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
137 //
138 BootOrderListSize = BootOptionMenu.MenuNumber;
139
140 if (BootOrderListSize > 0) {
141 BootOrderList = AllocateZeroPool (BootOrderListSize * sizeof (UINT16));
142 ASSERT (BootOrderList != NULL);
143 BootOrderListPtr = BootOrderList;
144
145 //
146 // Get all current used Boot#### from BootOptionMenu.
147 // OptionNumber in each BM_LOAD_OPTION is really its
148 // #### value.
149 //
150 for (Index = 0; Index < BootOrderListSize; Index++) {
151 NewMenuEntry = BOpt_GetMenuEntry (&BootOptionMenu, Index);
152 *BootOrderList = (UINT16) NewMenuEntry->OptionNumber;
153 BootOrderList++;
154 }
155
156 BootOrderList = BootOrderListPtr;
157
158 //
159 // After building the BootOrderList, write it back
160 //
161 Status = gRT->SetVariable (
162 L"BootOrder",
163 &gEfiGlobalVariableGuid,
164 VAR_FLAG,
165 BootOrderListSize * sizeof (UINT16),
166 BootOrderList
167 );
168 if (EFI_ERROR (Status)) {
169 return Status;
170 }
171 }
172 return EFI_SUCCESS;
173 }
174
175 /**
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.
179
180 @retval EFI_SUCCESS Load Option is successfully updated.
181 @retval EFI_NOT_FOUND Fail to find the driver option want to be deleted.
182 @return Other value than EFI_SUCCESS if failed to update "Driver Order" EFI
183 Variable.
184
185 **/
186 EFI_STATUS
187 Var_DelDriverOption (
188 VOID
189 )
190 {
191 BM_MENU_ENTRY *NewMenuEntry;
192 BM_LOAD_CONTEXT *NewLoadContext;
193 UINT16 DriverString[12];
194 EFI_STATUS Status;
195 UINTN Index;
196 UINTN Index2;
197
198 Status = EFI_SUCCESS;
199 Index2 = 0;
200 for (Index = 0; Index < DriverOptionMenu.MenuNumber; Index++) {
201 NewMenuEntry = BOpt_GetMenuEntry (&DriverOptionMenu, (Index - Index2));
202 if (NULL == NewMenuEntry) {
203 return EFI_NOT_FOUND;
204 }
205
206 NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;
207 if (!NewLoadContext->Deleted) {
208 continue;
209 }
210
211 UnicodeSPrint (
212 DriverString,
213 sizeof (DriverString),
214 L"Driver%04x",
215 NewMenuEntry->OptionNumber
216 );
217
218 EfiLibDeleteVariable (DriverString, &gEfiGlobalVariableGuid);
219 Index2++;
220
221 RemoveEntryList (&NewMenuEntry->Link);
222 BOpt_DestroyMenuEntry (NewMenuEntry);
223 NewMenuEntry = NULL;
224 }
225
226 DriverOptionMenu.MenuNumber -= Index2;
227
228 Status = Var_ChangeDriverOrder ();
229 return Status;
230 }
231
232 /**
233 After any operation on Driver####, there will be a discrepancy in
234 DriverOrder. Since some are missing but in DriverOrder, while some
235 are present but are not reflected by DriverOrder. Then a function
236 rebuild DriverOrder from scratch by content from DriverOptionMenu is
237 needed.
238
239 @retval EFI_SUCCESS The driver order is updated successfully.
240 @return Other status than EFI_SUCCESS if failed to set the "DriverOrder" EFI Variable.
241
242 **/
243 EFI_STATUS
244 Var_ChangeDriverOrder (
245 VOID
246 )
247 {
248 EFI_STATUS Status;
249 BM_MENU_ENTRY *NewMenuEntry;
250 UINT16 *DriverOrderList;
251 UINT16 *DriverOrderListPtr;
252 UINTN DriverOrderListSize;
253 UINTN Index;
254
255 DriverOrderList = NULL;
256 DriverOrderListSize = 0;
257
258 //
259 // First check whether DriverOrder is present in current configuration
260 //
261 DriverOrderList = BdsLibGetVariableAndSize (
262 L"DriverOrder",
263 &gEfiGlobalVariableGuid,
264 &DriverOrderListSize
265 );
266
267 //
268 // If exists, delete it to hold new DriverOrder
269 //
270 if (DriverOrderList != NULL) {
271 EfiLibDeleteVariable (L"DriverOrder", &gEfiGlobalVariableGuid);
272 FreePool (DriverOrderList);
273 DriverOrderList = NULL;
274 }
275
276 DriverOrderListSize = DriverOptionMenu.MenuNumber;
277
278 if (DriverOrderListSize > 0) {
279 DriverOrderList = AllocateZeroPool (DriverOrderListSize * sizeof (UINT16));
280 ASSERT (DriverOrderList != NULL);
281 DriverOrderListPtr = DriverOrderList;
282
283 //
284 // Get all current used Driver#### from DriverOptionMenu.
285 // OptionNumber in each BM_LOAD_OPTION is really its
286 // #### value.
287 //
288 for (Index = 0; Index < DriverOrderListSize; Index++) {
289 NewMenuEntry = BOpt_GetMenuEntry (&DriverOptionMenu, Index);
290 *DriverOrderList = (UINT16) NewMenuEntry->OptionNumber;
291 DriverOrderList++;
292 }
293
294 DriverOrderList = DriverOrderListPtr;
295
296 //
297 // After building the DriverOrderList, write it back
298 //
299 Status = gRT->SetVariable (
300 L"DriverOrder",
301 &gEfiGlobalVariableGuid,
302 VAR_FLAG,
303 DriverOrderListSize * sizeof (UINT16),
304 DriverOrderList
305 );
306 if (EFI_ERROR (Status)) {
307 return Status;
308 }
309 }
310 return EFI_SUCCESS;
311 }
312
313 /**
314 Update the device path of "ConOut", "ConIn" and "ErrOut"
315 based on the new BaudRate, Data Bits, parity and Stop Bits
316 set.
317
318 **/
319 VOID
320 Var_UpdateAllConsoleOption (
321 VOID
322 )
323 {
324 EFI_DEVICE_PATH_PROTOCOL *OutDevicePath;
325 EFI_DEVICE_PATH_PROTOCOL *InpDevicePath;
326 EFI_DEVICE_PATH_PROTOCOL *ErrDevicePath;
327 EFI_STATUS Status;
328
329 OutDevicePath = EfiLibGetVariable (L"ConOut", &gEfiGlobalVariableGuid);
330 InpDevicePath = EfiLibGetVariable (L"ConIn", &gEfiGlobalVariableGuid);
331 ErrDevicePath = EfiLibGetVariable (L"ErrOut", &gEfiGlobalVariableGuid);
332 if (OutDevicePath != NULL) {
333 ChangeVariableDevicePath (OutDevicePath);
334 Status = gRT->SetVariable (
335 L"ConOut",
336 &gEfiGlobalVariableGuid,
337 VAR_FLAG,
338 GetDevicePathSize (OutDevicePath),
339 OutDevicePath
340 );
341 ASSERT (!EFI_ERROR (Status));
342 }
343
344 if (InpDevicePath != NULL) {
345 ChangeVariableDevicePath (InpDevicePath);
346 Status = gRT->SetVariable (
347 L"ConIn",
348 &gEfiGlobalVariableGuid,
349 VAR_FLAG,
350 GetDevicePathSize (InpDevicePath),
351 InpDevicePath
352 );
353 ASSERT (!EFI_ERROR (Status));
354 }
355
356 if (ErrDevicePath != NULL) {
357 ChangeVariableDevicePath (ErrDevicePath);
358 Status = gRT->SetVariable (
359 L"ErrOut",
360 &gEfiGlobalVariableGuid,
361 VAR_FLAG,
362 GetDevicePathSize (ErrDevicePath),
363 ErrDevicePath
364 );
365 ASSERT (!EFI_ERROR (Status));
366 }
367 }
368
369 /**
370 This function delete and build multi-instance device path for
371 specified type of console device.
372
373 This function clear the EFI variable defined by ConsoleName and
374 gEfiGlobalVariableGuid. It then build the multi-instance device
375 path by appending the device path of the Console (In/Out/Err) instance
376 in ConsoleMenu. Then it scan all corresponding console device by
377 scanning Terminal (built from device supporting Serial I/O instances)
378 devices in TerminalMenu. At last, it save a EFI variable specifed
379 by ConsoleName and gEfiGlobalVariableGuid.
380
381 @param ConsoleName The name for the console device type. They are
382 usually "ConIn", "ConOut" and "ErrOut".
383 @param ConsoleMenu The console memu which is a list of console devices.
384 @param UpdatePageId The flag specifying which type of console device
385 to be processed.
386
387 @retval EFI_SUCCESS The function complete successfully.
388 @return The EFI variable can not be saved. See gRT->SetVariable for detail return information.
389
390 **/
391 EFI_STATUS
392 Var_UpdateConsoleOption (
393 IN UINT16 *ConsoleName,
394 IN BM_MENU_OPTION *ConsoleMenu,
395 IN UINT16 UpdatePageId
396 )
397 {
398 EFI_DEVICE_PATH_PROTOCOL *ConDevicePath;
399 BM_MENU_ENTRY *NewMenuEntry;
400 BM_CONSOLE_CONTEXT *NewConsoleContext;
401 BM_TERMINAL_CONTEXT *NewTerminalContext;
402 EFI_STATUS Status;
403 VENDOR_DEVICE_PATH Vendor;
404 EFI_DEVICE_PATH_PROTOCOL *TerminalDevicePath;
405 UINTN Index;
406
407 ConDevicePath = EfiLibGetVariable (ConsoleName, &gEfiGlobalVariableGuid);
408 if (ConDevicePath != NULL) {
409 EfiLibDeleteVariable (ConsoleName, &gEfiGlobalVariableGuid);
410 FreePool (ConDevicePath);
411 ConDevicePath = NULL;
412 };
413
414 //
415 // First add all console input device from console input menu
416 //
417 for (Index = 0; Index < ConsoleMenu->MenuNumber; Index++) {
418 NewMenuEntry = BOpt_GetMenuEntry (ConsoleMenu, Index);
419
420 NewConsoleContext = (BM_CONSOLE_CONTEXT *) NewMenuEntry->VariableContext;
421 if (NewConsoleContext->IsActive) {
422 ConDevicePath = AppendDevicePathInstance (
423 ConDevicePath,
424 NewConsoleContext->DevicePath
425 );
426 }
427 }
428
429 for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {
430 NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);
431
432 NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;
433 if (((NewTerminalContext->IsConIn != 0) && (UpdatePageId == FORM_CON_IN_ID)) ||
434 ((NewTerminalContext->IsConOut != 0) && (UpdatePageId == FORM_CON_OUT_ID)) ||
435 ((NewTerminalContext->IsStdErr != 0) && (UpdatePageId == FORM_CON_ERR_ID))
436 ) {
437 Vendor.Header.Type = MESSAGING_DEVICE_PATH;
438 Vendor.Header.SubType = MSG_VENDOR_DP;
439
440 ASSERT (NewTerminalContext->TerminalType < (sizeof (TerminalTypeGuid) / sizeof (TerminalTypeGuid[0])));
441 CopyMem (
442 &Vendor.Guid,
443 &TerminalTypeGuid[NewTerminalContext->TerminalType],
444 sizeof (EFI_GUID)
445 );
446 SetDevicePathNodeLength (&Vendor.Header, sizeof (VENDOR_DEVICE_PATH));
447 TerminalDevicePath = AppendDevicePathNode (
448 NewTerminalContext->DevicePath,
449 (EFI_DEVICE_PATH_PROTOCOL *) &Vendor
450 );
451 ASSERT (TerminalDevicePath != NULL);
452 ChangeTerminalDevicePath (&TerminalDevicePath, TRUE);
453 ConDevicePath = AppendDevicePathInstance (
454 ConDevicePath,
455 TerminalDevicePath
456 );
457 }
458 }
459
460 if (ConDevicePath != NULL) {
461 Status = gRT->SetVariable (
462 ConsoleName,
463 &gEfiGlobalVariableGuid,
464 VAR_FLAG,
465 GetDevicePathSize (ConDevicePath),
466 ConDevicePath
467 );
468 if (EFI_ERROR (Status)) {
469 return Status;
470 }
471 }
472
473 return EFI_SUCCESS;
474
475 }
476
477 /**
478 This function delete and build multi-instance device path ConIn
479 console device.
480
481 @retval EFI_SUCCESS The function complete successfully.
482 @return The EFI variable can not be saved. See gRT->SetVariable for detail return information.
483 **/
484 EFI_STATUS
485 Var_UpdateConsoleInpOption (
486 VOID
487 )
488 {
489 return Var_UpdateConsoleOption (L"ConIn", &ConsoleInpMenu, FORM_CON_IN_ID);
490 }
491
492 /**
493 This function delete and build multi-instance device path ConOut
494 console device.
495
496 @retval EFI_SUCCESS The function complete successfully.
497 @return The EFI variable can not be saved. See gRT->SetVariable for detail return information.
498 **/
499 EFI_STATUS
500 Var_UpdateConsoleOutOption (
501 VOID
502 )
503 {
504 return Var_UpdateConsoleOption (L"ConOut", &ConsoleOutMenu, FORM_CON_OUT_ID);
505 }
506
507 /**
508 This function delete and build multi-instance device path ErrOut
509 console device.
510
511 @retval EFI_SUCCESS The function complete successfully.
512 @return The EFI variable can not be saved. See gRT->SetVariable for detail return information.
513 **/
514 EFI_STATUS
515 Var_UpdateErrorOutOption (
516 VOID
517 )
518 {
519 return Var_UpdateConsoleOption (L"ErrOut", &ConsoleErrMenu, FORM_CON_ERR_ID);
520 }
521
522 /**
523 This function create a currently loaded Drive Option from
524 the BMM. It then appends this Driver Option to the end of
525 the "DriverOrder" list. It append this Driver Opotion to the end
526 of DriverOptionMenu.
527
528 @param CallbackData The BMM context data.
529 @param HiiHandle The HII handle associated with the BMM formset.
530 @param DescriptionData The description of this driver option.
531 @param OptionalData The optional load option.
532 @param ForceReconnect If to force reconnect.
533
534 @retval EFI_OUT_OF_RESOURCES If not enought memory to complete the operation.
535 @retval EFI_SUCCESS If function completes successfully.
536
537 **/
538 EFI_STATUS
539 Var_UpdateDriverOption (
540 IN BMM_CALLBACK_DATA *CallbackData,
541 IN EFI_HII_HANDLE HiiHandle,
542 IN UINT16 *DescriptionData,
543 IN UINT16 *OptionalData,
544 IN UINT8 ForceReconnect
545 )
546 {
547 UINT16 Index;
548 UINT16 *DriverOrderList;
549 UINT16 *NewDriverOrderList;
550 UINT16 DriverString[12];
551 UINTN DriverOrderListSize;
552 VOID *Buffer;
553 UINTN BufferSize;
554 UINT8 *Ptr;
555 BM_MENU_ENTRY *NewMenuEntry;
556 BM_LOAD_CONTEXT *NewLoadContext;
557 BOOLEAN OptionalDataExist;
558 EFI_STATUS Status;
559
560 OptionalDataExist = FALSE;
561
562 Index = BOpt_GetDriverOptionNumber ();
563 UnicodeSPrint (
564 DriverString,
565 sizeof (DriverString),
566 L"Driver%04x",
567 Index
568 );
569
570 if (*DescriptionData == 0x0000) {
571 StrCpy (DescriptionData, DriverString);
572 }
573
574 BufferSize = sizeof (UINT32) + sizeof (UINT16) + StrSize (DescriptionData);
575 BufferSize += GetDevicePathSize (CallbackData->LoadContext->FilePathList);
576
577 if (*OptionalData != 0x0000) {
578 OptionalDataExist = TRUE;
579 BufferSize += StrSize (OptionalData);
580 }
581
582 Buffer = AllocateZeroPool (BufferSize);
583 if (NULL == Buffer) {
584 return EFI_OUT_OF_RESOURCES;
585 }
586
587 NewMenuEntry = BOpt_CreateMenuEntry (BM_LOAD_CONTEXT_SELECT);
588 if (NULL == NewMenuEntry) {
589 FreePool (Buffer);
590 return EFI_OUT_OF_RESOURCES;
591 }
592
593 NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;
594 NewLoadContext->Deleted = FALSE;
595 NewLoadContext->LoadOptionSize = BufferSize;
596 Ptr = (UINT8 *) Buffer;
597 NewLoadContext->LoadOption = Ptr;
598 *((UINT32 *) Ptr) = LOAD_OPTION_ACTIVE | (ForceReconnect << 1);
599 NewLoadContext->Attributes = *((UINT32 *) Ptr);
600 NewLoadContext->IsActive = TRUE;
601 NewLoadContext->ForceReconnect = (BOOLEAN) (NewLoadContext->Attributes & LOAD_OPTION_FORCE_RECONNECT);
602
603 Ptr += sizeof (UINT32);
604 *((UINT16 *) Ptr) = (UINT16) GetDevicePathSize (CallbackData->LoadContext->FilePathList);
605 NewLoadContext->FilePathListLength = *((UINT16 *) Ptr);
606
607 Ptr += sizeof (UINT16);
608 CopyMem (
609 Ptr,
610 DescriptionData,
611 StrSize (DescriptionData)
612 );
613
614 NewLoadContext->Description = AllocateZeroPool (StrSize (DescriptionData));
615 ASSERT (NewLoadContext->Description != NULL);
616 NewMenuEntry->DisplayString = NewLoadContext->Description;
617 CopyMem (
618 NewLoadContext->Description,
619 (VOID *) Ptr,
620 StrSize (DescriptionData)
621 );
622
623 Ptr += StrSize (DescriptionData);
624 CopyMem (
625 Ptr,
626 CallbackData->LoadContext->FilePathList,
627 GetDevicePathSize (CallbackData->LoadContext->FilePathList)
628 );
629
630 NewLoadContext->FilePathList = AllocateZeroPool (GetDevicePathSize (CallbackData->LoadContext->FilePathList));
631 ASSERT (NewLoadContext->FilePathList != NULL);
632
633 CopyMem (
634 NewLoadContext->FilePathList,
635 (VOID *) Ptr,
636 GetDevicePathSize (CallbackData->LoadContext->FilePathList)
637 );
638
639 NewMenuEntry->HelpString = DevicePathToStr (NewLoadContext->FilePathList);
640 NewMenuEntry->OptionNumber = Index;
641 NewMenuEntry->DisplayStringToken = GetStringTokenFromDepository (
642 CallbackData,
643 DriverOptionStrDepository
644 );
645 NewMenuEntry->DisplayStringToken = HiiSetString (HiiHandle, 0, NewMenuEntry->DisplayString, NULL);
646
647 NewMenuEntry->HelpStringToken = GetStringTokenFromDepository (
648 CallbackData,
649 DriverOptionHelpStrDepository
650 );
651 NewMenuEntry->HelpStringToken = HiiSetString (HiiHandle, 0, NewMenuEntry->HelpString, NULL);
652
653 if (OptionalDataExist) {
654 Ptr += (UINT8) GetDevicePathSize (CallbackData->LoadContext->FilePathList);
655
656 CopyMem (
657 Ptr,
658 OptionalData,
659 StrSize (OptionalData)
660 );
661 }
662
663 Status = gRT->SetVariable (
664 DriverString,
665 &gEfiGlobalVariableGuid,
666 VAR_FLAG,
667 BufferSize,
668 Buffer
669 );
670 ASSERT_EFI_ERROR (Status);
671 DriverOrderList = BdsLibGetVariableAndSize (
672 L"DriverOrder",
673 &gEfiGlobalVariableGuid,
674 &DriverOrderListSize
675 );
676 ASSERT (DriverOrderList != NULL);
677 NewDriverOrderList = AllocateZeroPool (DriverOrderListSize + sizeof (UINT16));
678 ASSERT (NewDriverOrderList != NULL);
679 CopyMem (NewDriverOrderList, DriverOrderList, DriverOrderListSize);
680 NewDriverOrderList[DriverOrderListSize / sizeof (UINT16)] = Index;
681 if (DriverOrderList != NULL) {
682 EfiLibDeleteVariable (L"DriverOrder", &gEfiGlobalVariableGuid);
683 }
684
685 Status = gRT->SetVariable (
686 L"DriverOrder",
687 &gEfiGlobalVariableGuid,
688 VAR_FLAG,
689 DriverOrderListSize + sizeof (UINT16),
690 NewDriverOrderList
691 );
692 ASSERT_EFI_ERROR (Status);
693 if (DriverOrderList != NULL) {
694 FreePool (DriverOrderList);
695 }
696 DriverOrderList = NULL;
697 FreePool (NewDriverOrderList);
698 InsertTailList (&DriverOptionMenu.Head, &NewMenuEntry->Link);
699 DriverOptionMenu.MenuNumber++;
700
701 *DescriptionData = 0x0000;
702 *OptionalData = 0x0000;
703 return EFI_SUCCESS;
704 }
705
706 /**
707 This function create a currently loaded Boot Option from
708 the BMM. It then appends this Boot Option to the end of
709 the "BootOrder" list. It also append this Boot Opotion to the end
710 of BootOptionMenu.
711
712 @param CallbackData The BMM context data.
713 @param NvRamMap The file explorer formset internal state.
714
715 @retval EFI_OUT_OF_RESOURCES If not enought memory to complete the operation.
716 @retval EFI_SUCCESS If function completes successfully.
717
718 **/
719 EFI_STATUS
720 Var_UpdateBootOption (
721 IN BMM_CALLBACK_DATA *CallbackData,
722 IN FILE_EXPLORER_NV_DATA *NvRamMap
723 )
724 {
725 UINT16 *BootOrderList;
726 UINT16 *NewBootOrderList;
727 UINTN BootOrderListSize;
728 UINT16 BootString[10];
729 VOID *Buffer;
730 UINTN BufferSize;
731 UINT8 *Ptr;
732 UINT16 Index;
733 BM_MENU_ENTRY *NewMenuEntry;
734 BM_LOAD_CONTEXT *NewLoadContext;
735 BOOLEAN OptionalDataExist;
736 EFI_STATUS Status;
737
738 OptionalDataExist = FALSE;
739
740 Index = BOpt_GetBootOptionNumber () ;
741 UnicodeSPrint (BootString, sizeof (BootString), L"Boot%04x", Index);
742
743 if (NvRamMap->DescriptionData[0] == 0x0000) {
744 StrCpy (NvRamMap->DescriptionData, BootString);
745 }
746
747 BufferSize = sizeof (UINT32) + sizeof (UINT16) + StrSize (NvRamMap->DescriptionData);
748 BufferSize += GetDevicePathSize (CallbackData->LoadContext->FilePathList);
749
750 if (NvRamMap->OptionalData[0] != 0x0000) {
751 OptionalDataExist = TRUE;
752 BufferSize += StrSize (NvRamMap->OptionalData);
753 }
754
755 Buffer = AllocateZeroPool (BufferSize);
756 if (NULL == Buffer) {
757 return EFI_OUT_OF_RESOURCES;
758 }
759
760 NewMenuEntry = BOpt_CreateMenuEntry (BM_LOAD_CONTEXT_SELECT);
761 if (NULL == NewMenuEntry) {
762 return EFI_OUT_OF_RESOURCES;
763 }
764
765 NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;
766 NewLoadContext->Deleted = FALSE;
767 NewLoadContext->LoadOptionSize = BufferSize;
768 Ptr = (UINT8 *) Buffer;
769 NewLoadContext->LoadOption = Ptr;
770 *((UINT32 *) Ptr) = LOAD_OPTION_ACTIVE;
771 NewLoadContext->Attributes = *((UINT32 *) Ptr);
772 NewLoadContext->IsActive = TRUE;
773 NewLoadContext->ForceReconnect = (BOOLEAN) (NewLoadContext->Attributes & LOAD_OPTION_FORCE_RECONNECT);
774
775 Ptr += sizeof (UINT32);
776 *((UINT16 *) Ptr) = (UINT16) GetDevicePathSize (CallbackData->LoadContext->FilePathList);
777 NewLoadContext->FilePathListLength = *((UINT16 *) Ptr);
778 Ptr += sizeof (UINT16);
779
780 CopyMem (
781 Ptr,
782 NvRamMap->DescriptionData,
783 StrSize (NvRamMap->DescriptionData)
784 );
785
786 NewLoadContext->Description = AllocateZeroPool (StrSize (NvRamMap->DescriptionData));
787 ASSERT (NewLoadContext->Description != NULL);
788
789 NewMenuEntry->DisplayString = NewLoadContext->Description;
790 CopyMem (
791 NewLoadContext->Description,
792 (VOID *) Ptr,
793 StrSize (NvRamMap->DescriptionData)
794 );
795
796 Ptr += StrSize (NvRamMap->DescriptionData);
797 CopyMem (
798 Ptr,
799 CallbackData->LoadContext->FilePathList,
800 GetDevicePathSize (CallbackData->LoadContext->FilePathList)
801 );
802
803 NewLoadContext->FilePathList = AllocateZeroPool (GetDevicePathSize (CallbackData->LoadContext->FilePathList));
804 ASSERT (NewLoadContext->FilePathList != NULL);
805
806 CopyMem (
807 NewLoadContext->FilePathList,
808 (VOID *) Ptr,
809 GetDevicePathSize (CallbackData->LoadContext->FilePathList)
810 );
811
812 NewMenuEntry->HelpString = DevicePathToStr (NewLoadContext->FilePathList);
813 NewMenuEntry->OptionNumber = Index;
814 NewMenuEntry->DisplayStringToken = GetStringTokenFromDepository (
815 CallbackData,
816 BootOptionStrDepository
817 );
818 NewMenuEntry->DisplayStringToken = HiiSetString (CallbackData->FeHiiHandle, 0, NewMenuEntry->DisplayString, NULL);
819
820 NewMenuEntry->HelpStringToken = GetStringTokenFromDepository (
821 CallbackData,
822 BootOptionHelpStrDepository
823 );
824 NewMenuEntry->HelpStringToken = HiiSetString (CallbackData->FeHiiHandle, 0, NewMenuEntry->HelpString, NULL);
825
826 if (OptionalDataExist) {
827 Ptr += (UINT8) GetDevicePathSize (CallbackData->LoadContext->FilePathList);
828
829 CopyMem (Ptr, NvRamMap->OptionalData, StrSize (NvRamMap->OptionalData));
830 }
831
832 Status = gRT->SetVariable (
833 BootString,
834 &gEfiGlobalVariableGuid,
835 VAR_FLAG,
836 BufferSize,
837 Buffer
838 );
839 ASSERT_EFI_ERROR (Status);
840
841 BootOrderList = BdsLibGetVariableAndSize (
842 L"BootOrder",
843 &gEfiGlobalVariableGuid,
844 &BootOrderListSize
845 );
846 ASSERT (BootOrderList != NULL);
847 NewBootOrderList = AllocateZeroPool (BootOrderListSize + sizeof (UINT16));
848 ASSERT (NewBootOrderList != NULL);
849 CopyMem (NewBootOrderList, BootOrderList, BootOrderListSize);
850 NewBootOrderList[BootOrderListSize / sizeof (UINT16)] = Index;
851
852 if (BootOrderList != NULL) {
853 FreePool (BootOrderList);
854 }
855
856 Status = gRT->SetVariable (
857 L"BootOrder",
858 &gEfiGlobalVariableGuid,
859 VAR_FLAG,
860 BootOrderListSize + sizeof (UINT16),
861 NewBootOrderList
862 );
863 ASSERT_EFI_ERROR (Status);
864
865 FreePool (NewBootOrderList);
866 NewBootOrderList = NULL;
867 InsertTailList (&BootOptionMenu.Head, &NewMenuEntry->Link);
868 BootOptionMenu.MenuNumber++;
869
870 NvRamMap->DescriptionData[0] = 0x0000;
871 NvRamMap->OptionalData[0] = 0x0000;
872 return EFI_SUCCESS;
873 }
874
875 /**
876 This function update the "BootNext" EFI Variable. If there is
877 no "BootNext" specified in BMM, this EFI Variable is deleted.
878 It also update the BMM context data specified the "BootNext"
879 vaule.
880
881 @param CallbackData The BMM context data.
882
883 @retval EFI_SUCCESS The function complete successfully.
884 @return The EFI variable can be saved. See gRT->SetVariable
885 for detail return information.
886
887 **/
888 EFI_STATUS
889 Var_UpdateBootNext (
890 IN BMM_CALLBACK_DATA *CallbackData
891 )
892 {
893 BM_MENU_ENTRY *NewMenuEntry;
894 BM_LOAD_CONTEXT *NewLoadContext;
895 BMM_FAKE_NV_DATA *CurrentFakeNVMap;
896 UINT16 Index;
897 EFI_STATUS Status;
898
899 Status = EFI_SUCCESS;
900 CurrentFakeNVMap = &CallbackData->BmmFakeNvData;
901 for (Index = 0; Index < BootOptionMenu.MenuNumber; Index++) {
902 NewMenuEntry = BOpt_GetMenuEntry (&BootOptionMenu, Index);
903 ASSERT (NULL != NewMenuEntry);
904
905 NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;
906 NewLoadContext->IsBootNext = FALSE;
907 }
908
909 if (CurrentFakeNVMap->BootNext == BootOptionMenu.MenuNumber) {
910 EfiLibDeleteVariable (L"BootNext", &gEfiGlobalVariableGuid);
911 return EFI_SUCCESS;
912 }
913
914 NewMenuEntry = BOpt_GetMenuEntry (
915 &BootOptionMenu,
916 CurrentFakeNVMap->BootNext
917 );
918 ASSERT (NewMenuEntry != NULL);
919
920 NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;
921 Status = gRT->SetVariable (
922 L"BootNext",
923 &gEfiGlobalVariableGuid,
924 VAR_FLAG,
925 sizeof (UINT16),
926 &NewMenuEntry->OptionNumber
927 );
928 NewLoadContext->IsBootNext = TRUE;
929 CallbackData->BmmOldFakeNVData.BootNext = CurrentFakeNVMap->BootNext;
930 return Status;
931 }
932
933 /**
934 This function update the "BootOrder" EFI Variable based on
935 BMM Formset's NV map. It then refresh BootOptionMenu
936 with the new "BootOrder" list.
937
938 @param CallbackData The BMM context data.
939
940 @retval EFI_SUCCESS The function complete successfully.
941 @retval EFI_OUT_OF_RESOURCES Not enough memory to complete the function.
942 @return The EFI variable can not be saved. See gRT->SetVariable for detail return information.
943
944 **/
945 EFI_STATUS
946 Var_UpdateBootOrder (
947 IN BMM_CALLBACK_DATA *CallbackData
948 )
949 {
950 EFI_STATUS Status;
951 UINT16 Index;
952 UINT16 OrderIndex;
953 UINT16 *BootOrderList;
954 UINTN BootOrderListSize;
955 UINT16 OptionNumber;
956
957 BootOrderList = NULL;
958 BootOrderListSize = 0;
959
960 //
961 // First check whether BootOrder is present in current configuration
962 //
963 BootOrderList = BdsLibGetVariableAndSize (
964 L"BootOrder",
965 &gEfiGlobalVariableGuid,
966 &BootOrderListSize
967 );
968 if (BootOrderList == NULL) {
969 return EFI_OUT_OF_RESOURCES;
970 }
971
972 ASSERT (BootOptionMenu.MenuNumber <= (sizeof (CallbackData->BmmFakeNvData.OptionOrder) / sizeof (CallbackData->BmmFakeNvData.OptionOrder[0])));
973
974 for (OrderIndex = 0; (OrderIndex < BootOptionMenu.MenuNumber) && (CallbackData->BmmFakeNvData.OptionOrder[OrderIndex] != 0); OrderIndex++) {
975 for (Index = OrderIndex; Index < BootOrderListSize / sizeof (UINT16); Index++) {
976 if ((BootOrderList[Index] == (UINT16) (CallbackData->BmmFakeNvData.OptionOrder[OrderIndex] - 1)) && (OrderIndex != Index)) {
977 OptionNumber = BootOrderList[Index];
978 CopyMem (&BootOrderList[OrderIndex + 1], &BootOrderList[OrderIndex], (Index - OrderIndex) * sizeof (UINT16));
979 BootOrderList[OrderIndex] = OptionNumber;
980 }
981 }
982 }
983
984 GroupMultipleLegacyBootOption4SameType (
985 BootOrderList,
986 BootOrderListSize / sizeof (UINT16)
987 );
988
989 Status = gRT->SetVariable (
990 L"BootOrder",
991 &gEfiGlobalVariableGuid,
992 VAR_FLAG,
993 BootOrderListSize,
994 BootOrderList
995 );
996 FreePool (BootOrderList);
997
998 BOpt_FreeMenu (&BootOptionMenu);
999 BOpt_GetBootOptions (CallbackData);
1000
1001 return Status;
1002
1003 }
1004
1005 /**
1006 This function update the "DriverOrder" EFI Variable based on
1007 BMM Formset's NV map. It then refresh DriverOptionMenu
1008 with the new "DriverOrder" list.
1009
1010 @param CallbackData The BMM context data.
1011
1012 @retval EFI_SUCCESS The function complete successfully.
1013 @retval EFI_OUT_OF_RESOURCES Not enough memory to complete the function.
1014 @return The EFI variable can not be saved. See gRT->SetVariable for detail return information.
1015
1016 **/
1017 EFI_STATUS
1018 Var_UpdateDriverOrder (
1019 IN BMM_CALLBACK_DATA *CallbackData
1020 )
1021 {
1022 EFI_STATUS Status;
1023 UINT16 Index;
1024 UINT16 *DriverOrderList;
1025 UINT16 *NewDriverOrderList;
1026 UINTN DriverOrderListSize;
1027
1028 DriverOrderList = NULL;
1029 DriverOrderListSize = 0;
1030
1031 //
1032 // First check whether DriverOrder is present in current configuration
1033 //
1034 DriverOrderList = BdsLibGetVariableAndSize (
1035 L"DriverOrder",
1036 &gEfiGlobalVariableGuid,
1037 &DriverOrderListSize
1038 );
1039
1040 NewDriverOrderList = AllocateZeroPool (DriverOrderListSize);
1041
1042 if (NewDriverOrderList == NULL) {
1043 return EFI_OUT_OF_RESOURCES;
1044 }
1045 //
1046 // If exists, delete it to hold new DriverOrder
1047 //
1048 if (DriverOrderList != NULL) {
1049 EfiLibDeleteVariable (L"DriverOrder", &gEfiGlobalVariableGuid);
1050 FreePool (DriverOrderList);
1051 }
1052
1053 ASSERT (DriverOptionMenu.MenuNumber <= (sizeof (CallbackData->BmmFakeNvData.OptionOrder) / sizeof (CallbackData->BmmFakeNvData.OptionOrder[0])));
1054 for (Index = 0; Index < DriverOptionMenu.MenuNumber; Index++) {
1055 NewDriverOrderList[Index] = (UINT16) (CallbackData->BmmFakeNvData.OptionOrder[Index] - 1);
1056 }
1057
1058 Status = gRT->SetVariable (
1059 L"DriverOrder",
1060 &gEfiGlobalVariableGuid,
1061 VAR_FLAG,
1062 DriverOrderListSize,
1063 NewDriverOrderList
1064 );
1065 if (EFI_ERROR (Status)) {
1066 return Status;
1067 }
1068
1069 BOpt_FreeMenu (&DriverOptionMenu);
1070 BOpt_GetDriverOptions (CallbackData);
1071 return EFI_SUCCESS;
1072 }
1073
1074 /**
1075 Update the legacy BBS boot option. VAR_LEGACY_DEV_ORDER and gEfiLegacyDevOrderVariableGuid EFI Variable
1076 is udpated with the new Legacy Boot order. The EFI Variable of "Boot####" and gEfiGlobalVariableGuid
1077 is also updated.
1078
1079 @param CallbackData The context data for BMM.
1080
1081 @return EFI_SUCCESS The function completed successfully.
1082 @retval EFI_NOT_FOUND If VAR_LEGACY_DEV_ORDER and gEfiLegacyDevOrderVariableGuid EFI Variable can be found.
1083 @retval EFI_OUT_OF_RESOURCES Fail to allocate memory resource
1084 **/
1085 EFI_STATUS
1086 Var_UpdateBBSOption (
1087 IN BMM_CALLBACK_DATA *CallbackData
1088 )
1089 {
1090 UINTN Index;
1091 UINTN Index2;
1092 VOID *BootOptionVar;
1093 CHAR16 VarName[100];
1094 UINTN OptionSize;
1095 EFI_STATUS Status;
1096 UINT32 *Attribute;
1097 BM_MENU_OPTION *OptionMenu;
1098 UINT8 *LegacyDev;
1099 UINT8 *VarData;
1100 UINTN VarSize;
1101 LEGACY_DEV_ORDER_ENTRY *DevOrder;
1102 UINT8 *OriginalPtr;
1103 UINT8 *DisMap;
1104 UINTN Pos;
1105 UINTN Bit;
1106 UINT16 *NewOrder;
1107 UINT16 Tmp;
1108 UINT16 *EnBootOption;
1109 UINTN EnBootOptionCount;
1110 UINT16 *DisBootOption;
1111 UINTN DisBootOptionCount;
1112 UINT16 *BootOrder;
1113
1114 DisMap = NULL;
1115 NewOrder = NULL;
1116
1117 switch (CallbackData->BmmPreviousPageId) {
1118 case FORM_SET_FD_ORDER_ID:
1119 OptionMenu = (BM_MENU_OPTION *) &LegacyFDMenu;
1120 LegacyDev = CallbackData->BmmFakeNvData.LegacyFD;
1121 CallbackData->BbsType = BBS_FLOPPY;
1122 break;
1123
1124 case FORM_SET_HD_ORDER_ID:
1125 OptionMenu = (BM_MENU_OPTION *) &LegacyHDMenu;
1126 LegacyDev = CallbackData->BmmFakeNvData.LegacyHD;
1127 CallbackData->BbsType = BBS_HARDDISK;
1128 break;
1129
1130 case FORM_SET_CD_ORDER_ID:
1131 OptionMenu = (BM_MENU_OPTION *) &LegacyCDMenu;
1132 LegacyDev = CallbackData->BmmFakeNvData.LegacyCD;
1133 CallbackData->BbsType = BBS_CDROM;
1134 break;
1135
1136 case FORM_SET_NET_ORDER_ID:
1137 OptionMenu = (BM_MENU_OPTION *) &LegacyNETMenu;
1138 LegacyDev = CallbackData->BmmFakeNvData.LegacyNET;
1139 CallbackData->BbsType = BBS_EMBED_NETWORK;
1140 break;
1141
1142 default:
1143 ASSERT (FORM_SET_BEV_ORDER_ID == CallbackData->BmmPreviousPageId);
1144 OptionMenu = (BM_MENU_OPTION *) &LegacyBEVMenu;
1145 LegacyDev = CallbackData->BmmFakeNvData.LegacyBEV;
1146 CallbackData->BbsType = BBS_BEV_DEVICE;
1147 break;
1148 }
1149
1150 DisMap = CallbackData->BmmOldFakeNVData.DisableMap;
1151 Status = EFI_SUCCESS;
1152
1153
1154 //
1155 // Update the Variable "LegacyDevOrder"
1156 //
1157 VarData = (UINT8 *) BdsLibGetVariableAndSize (
1158 VAR_LEGACY_DEV_ORDER,
1159 &gEfiLegacyDevOrderVariableGuid,
1160 &VarSize
1161 );
1162
1163 if (VarData == NULL) {
1164 return EFI_NOT_FOUND;
1165 }
1166
1167 OriginalPtr = VarData;
1168 DevOrder = (LEGACY_DEV_ORDER_ENTRY *) VarData;
1169
1170 while (VarData < OriginalPtr + VarSize) {
1171 if (DevOrder->BbsType == CallbackData->BbsType) {
1172 break;
1173 }
1174
1175 VarData += sizeof (BBS_TYPE) + DevOrder->Length;
1176 DevOrder = (LEGACY_DEV_ORDER_ENTRY *) VarData;
1177 }
1178
1179 if (VarData >= OriginalPtr + VarSize) {
1180 FreePool (OriginalPtr);
1181 return EFI_NOT_FOUND;
1182 }
1183
1184 NewOrder = AllocateZeroPool (DevOrder->Length - sizeof (DevOrder->Length));
1185 if (NewOrder == NULL) {
1186 FreePool (OriginalPtr);
1187 return EFI_OUT_OF_RESOURCES;
1188 }
1189
1190 for (Index = 0; Index < OptionMenu->MenuNumber; Index++) {
1191 if (0xFF == LegacyDev[Index]) {
1192 break;
1193 }
1194
1195 NewOrder[Index] = LegacyDev[Index];
1196 }
1197 //
1198 // Only the enable/disable state of each boot device with same device type can be changed,
1199 // so we can count on the index information in DevOrder.
1200 // DisMap bit array is the only reliable source to check a device's en/dis state,
1201 // so we use DisMap to set en/dis state of each item in NewOrder array
1202 //
1203 for (Index2 = 0; Index2 < OptionMenu->MenuNumber; Index2++) {
1204 Tmp = (UINT16) (DevOrder->Data[Index2] & 0xFF);
1205 Pos = Tmp / 8;
1206 Bit = 7 - (Tmp % 8);
1207 if ((DisMap[Pos] & (1 << Bit)) != 0) {
1208 NewOrder[Index] = (UINT16) (0xFF00 | Tmp);
1209 Index++;
1210 }
1211 }
1212
1213 CopyMem (
1214 DevOrder->Data,
1215 NewOrder,
1216 DevOrder->Length - sizeof (DevOrder->Length)
1217 );
1218 FreePool (NewOrder);
1219
1220 Status = gRT->SetVariable (
1221 VAR_LEGACY_DEV_ORDER,
1222 &gEfiLegacyDevOrderVariableGuid,
1223 VAR_FLAG,
1224 VarSize,
1225 OriginalPtr
1226 );
1227
1228
1229 //
1230 // Update BootOrder and Boot####.Attribute
1231 //
1232 // 1. Re-order the Option Number in BootOrder according to Legacy Dev Order
1233 //
1234 ASSERT (OptionMenu->MenuNumber == DevOrder->Length / sizeof (UINT16) - 1);
1235 BootOrder = BdsLibGetVariableAndSize (
1236 L"BootOrder",
1237 &gEfiGlobalVariableGuid,
1238 &VarSize
1239 );
1240 ASSERT (BootOrder != NULL);
1241
1242 DisBootOption = AllocatePool (VarSize);
1243 ASSERT (DisBootOption != NULL);
1244 EnBootOption = AllocatePool (VarSize);
1245 ASSERT (EnBootOption != NULL);
1246
1247 OrderLegacyBootOption4SameType (
1248 BootOrder,
1249 VarSize / sizeof (UINT16),
1250 DevOrder->Data,
1251 DevOrder->Length / sizeof (UINT16) - 1,
1252 EnBootOption,
1253 &EnBootOptionCount,
1254 DisBootOption,
1255 &DisBootOptionCount
1256 );
1257
1258 Status = gRT->SetVariable (
1259 L"BootOrder",
1260 &gEfiGlobalVariableGuid,
1261 VAR_FLAG,
1262 VarSize,
1263 BootOrder
1264 );
1265 ASSERT_EFI_ERROR (Status);
1266
1267 FreePool (BootOrder);
1268
1269 //
1270 // 2. Deactivate the DisBootOption and activate the EnBootOption
1271 //
1272 for (Index = 0; Index < DisBootOptionCount; Index++) {
1273 UnicodeSPrint (VarName, sizeof (VarName), L"Boot%04x", DisBootOption[Index]);
1274 BootOptionVar = BdsLibGetVariableAndSize (
1275 VarName,
1276 &gEfiGlobalVariableGuid,
1277 &OptionSize
1278 );
1279 if (BootOptionVar != NULL) {
1280 Attribute = (UINT32 *) BootOptionVar;
1281 *Attribute &= ~LOAD_OPTION_ACTIVE;
1282
1283 Status = gRT->SetVariable (
1284 VarName,
1285 &gEfiGlobalVariableGuid,
1286 VAR_FLAG,
1287 OptionSize,
1288 BootOptionVar
1289 );
1290
1291 FreePool (BootOptionVar);
1292 }
1293 }
1294
1295 for (Index = 0; Index < EnBootOptionCount; Index++) {
1296 UnicodeSPrint (VarName, sizeof (VarName), L"Boot%04x", EnBootOption[Index]);
1297 BootOptionVar = BdsLibGetVariableAndSize (
1298 VarName,
1299 &gEfiGlobalVariableGuid,
1300 &OptionSize
1301 );
1302 if (BootOptionVar != NULL) {
1303 Attribute = (UINT32 *) BootOptionVar;
1304 *Attribute |= LOAD_OPTION_ACTIVE;
1305
1306 Status = gRT->SetVariable (
1307 VarName,
1308 &gEfiGlobalVariableGuid,
1309 VAR_FLAG,
1310 OptionSize,
1311 BootOptionVar
1312 );
1313
1314 FreePool (BootOptionVar);
1315 }
1316 }
1317
1318 BOpt_GetBootOptions (CallbackData);
1319
1320 FreePool (OriginalPtr);
1321 FreePool (EnBootOption);
1322 FreePool (DisBootOption);
1323 return Status;
1324 }
1325
1326 /**
1327 Update the Text Mode of Console.
1328
1329 @param CallbackData The context data for BMM.
1330
1331 @retval EFI_SUCCSS If the Text Mode of Console is updated.
1332 @return Other value if the Text Mode of Console is not updated.
1333
1334 **/
1335 EFI_STATUS
1336 Var_UpdateConMode (
1337 IN BMM_CALLBACK_DATA *CallbackData
1338 )
1339 {
1340 EFI_STATUS Status;
1341 UINTN Mode;
1342 CONSOLE_OUT_MODE ModeInfo;
1343
1344 Mode = CallbackData->BmmFakeNvData.ConsoleOutMode;
1345
1346 Status = gST->ConOut->QueryMode (gST->ConOut, Mode, &(ModeInfo.Column), &(ModeInfo.Row));
1347 if (!EFI_ERROR(Status)) {
1348 PcdSet32 (PcdSetupConOutColumn, (UINT32) ModeInfo.Column);
1349 PcdSet32 (PcdSetupConOutRow, (UINT32) ModeInfo.Row);
1350 }
1351
1352 return EFI_SUCCESS;
1353 }