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