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