]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Library/BootMaintenanceManagerUiLib/Variable.c
MdeModulePkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / MdeModulePkg / Library / BootMaintenanceManagerUiLib / 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 "BootMaintenanceManager.h"
10
11 /**
12 Delete Boot Option that represent a Deleted state in BootOptionMenu.
13
14 @retval EFI_SUCCESS If all boot load option EFI Variables corresponding to
15 BM_LOAD_CONTEXT marked for deletion is deleted.
16 @retval EFI_NOT_FOUND If can not find the boot option want to be deleted.
17 @return Others If failed to update the "BootOrder" variable after deletion.
18
19 **/
20 EFI_STATUS
21 Var_DelBootOption (
22 VOID
23 )
24 {
25 BM_MENU_ENTRY *NewMenuEntry;
26 BM_LOAD_CONTEXT *NewLoadContext;
27 EFI_STATUS Status;
28 UINTN Index;
29 UINTN Index2;
30
31 Index2 = 0;
32 for (Index = 0; Index < BootOptionMenu.MenuNumber; Index++) {
33 NewMenuEntry = BOpt_GetMenuEntry (&BootOptionMenu, (Index - Index2));
34 if (NULL == NewMenuEntry) {
35 return EFI_NOT_FOUND;
36 }
37
38 NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;
39 if (!NewLoadContext->Deleted) {
40 continue;
41 }
42
43 Status = EfiBootManagerDeleteLoadOptionVariable (NewMenuEntry->OptionNumber,LoadOptionTypeBoot);
44 if (EFI_ERROR (Status)) {
45 return Status;
46 }
47 Index2++;
48 //
49 // If current Load Option is the same as BootNext,
50 // must delete BootNext in order to make sure
51 // there will be no panic on next boot
52 //
53 if (NewLoadContext->IsBootNext) {
54 EfiLibDeleteVariable (L"BootNext", &gEfiGlobalVariableGuid);
55 }
56
57 RemoveEntryList (&NewMenuEntry->Link);
58 BOpt_DestroyMenuEntry (NewMenuEntry);
59 NewMenuEntry = NULL;
60 }
61
62 BootOptionMenu.MenuNumber -= Index2;
63
64 return EFI_SUCCESS;
65 }
66
67 /**
68 Delete Load Option that represent a Deleted state in DriverOptionMenu.
69
70 @retval EFI_SUCCESS Load Option is successfully updated.
71 @retval EFI_NOT_FOUND Fail to find the driver option want to be deleted.
72 @return Other value than EFI_SUCCESS if failed to update "Driver Order" EFI
73 Variable.
74
75 **/
76 EFI_STATUS
77 Var_DelDriverOption (
78 VOID
79 )
80 {
81 BM_MENU_ENTRY *NewMenuEntry;
82 BM_LOAD_CONTEXT *NewLoadContext;
83 EFI_STATUS Status;
84 UINTN Index;
85 UINTN Index2;
86
87 Index2 = 0;
88 for (Index = 0; Index < DriverOptionMenu.MenuNumber; Index++) {
89 NewMenuEntry = BOpt_GetMenuEntry (&DriverOptionMenu, (Index - Index2));
90 if (NULL == NewMenuEntry) {
91 return EFI_NOT_FOUND;
92 }
93
94 NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;
95 if (!NewLoadContext->Deleted) {
96 continue;
97 }
98 Status = EfiBootManagerDeleteLoadOptionVariable (NewMenuEntry->OptionNumber,LoadOptionTypeDriver);
99 if (EFI_ERROR (Status)) {
100 return Status;
101 }
102
103 Index2++;
104
105 RemoveEntryList (&NewMenuEntry->Link);
106 BOpt_DestroyMenuEntry (NewMenuEntry);
107 NewMenuEntry = NULL;
108 }
109
110 DriverOptionMenu.MenuNumber -= Index2;
111
112 return EFI_SUCCESS;
113 }
114
115 /**
116 This function delete and build multi-instance device path for
117 specified type of console device.
118
119 This function clear the EFI variable defined by ConsoleName and
120 gEfiGlobalVariableGuid. It then build the multi-instance device
121 path by appending the device path of the Console (In/Out/Err) instance
122 in ConsoleMenu. Then it scan all corresponding console device by
123 scanning Terminal (built from device supporting Serial I/O instances)
124 devices in TerminalMenu. At last, it save a EFI variable specifed
125 by ConsoleName and gEfiGlobalVariableGuid.
126
127 @param ConsoleName The name for the console device type. They are
128 usually "ConIn", "ConOut" and "ErrOut".
129 @param ConsoleMenu The console memu which is a list of console devices.
130 @param UpdatePageId The flag specifying which type of console device
131 to be processed.
132
133 @retval EFI_SUCCESS The function complete successfully.
134 @return The EFI variable can not be saved. See gRT->SetVariable for detail return information.
135
136 **/
137 EFI_STATUS
138 Var_UpdateConsoleOption (
139 IN UINT16 *ConsoleName,
140 IN BM_MENU_OPTION *ConsoleMenu,
141 IN UINT16 UpdatePageId
142 )
143 {
144 EFI_DEVICE_PATH_PROTOCOL *ConDevicePath;
145 BM_MENU_ENTRY *NewMenuEntry;
146 BM_CONSOLE_CONTEXT *NewConsoleContext;
147 BM_TERMINAL_CONTEXT *NewTerminalContext;
148 EFI_STATUS Status;
149 VENDOR_DEVICE_PATH Vendor;
150 EFI_DEVICE_PATH_PROTOCOL *TerminalDevicePath;
151 UINTN Index;
152
153 GetEfiGlobalVariable2 (ConsoleName, (VOID**)&ConDevicePath, NULL);
154 if (ConDevicePath != NULL) {
155 EfiLibDeleteVariable (ConsoleName, &gEfiGlobalVariableGuid);
156 FreePool (ConDevicePath);
157 ConDevicePath = NULL;
158 };
159
160 //
161 // First add all console input device from console input menu
162 //
163 for (Index = 0; Index < ConsoleMenu->MenuNumber; Index++) {
164 NewMenuEntry = BOpt_GetMenuEntry (ConsoleMenu, Index);
165
166 NewConsoleContext = (BM_CONSOLE_CONTEXT *) NewMenuEntry->VariableContext;
167 if (NewConsoleContext->IsActive) {
168 ConDevicePath = AppendDevicePathInstance (
169 ConDevicePath,
170 NewConsoleContext->DevicePath
171 );
172 }
173 }
174
175 for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {
176 NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);
177
178 NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;
179 if (((NewTerminalContext->IsConIn != 0) && (UpdatePageId == FORM_CON_IN_ID)) ||
180 ((NewTerminalContext->IsConOut != 0) && (UpdatePageId == FORM_CON_OUT_ID)) ||
181 ((NewTerminalContext->IsStdErr != 0) && (UpdatePageId == FORM_CON_ERR_ID))
182 ) {
183 Vendor.Header.Type = MESSAGING_DEVICE_PATH;
184 Vendor.Header.SubType = MSG_VENDOR_DP;
185
186 ASSERT (NewTerminalContext->TerminalType < (ARRAY_SIZE (TerminalTypeGuid)));
187 CopyMem (
188 &Vendor.Guid,
189 &TerminalTypeGuid[NewTerminalContext->TerminalType],
190 sizeof (EFI_GUID)
191 );
192 SetDevicePathNodeLength (&Vendor.Header, sizeof (VENDOR_DEVICE_PATH));
193 TerminalDevicePath = AppendDevicePathNode (
194 NewTerminalContext->DevicePath,
195 (EFI_DEVICE_PATH_PROTOCOL *) &Vendor
196 );
197 ASSERT (TerminalDevicePath != NULL);
198 ChangeTerminalDevicePath (TerminalDevicePath, TRUE);
199 ConDevicePath = AppendDevicePathInstance (
200 ConDevicePath,
201 TerminalDevicePath
202 );
203 }
204 }
205
206 if (ConDevicePath != NULL) {
207 Status = gRT->SetVariable (
208 ConsoleName,
209 &gEfiGlobalVariableGuid,
210 VAR_FLAG,
211 GetDevicePathSize (ConDevicePath),
212 ConDevicePath
213 );
214 if (EFI_ERROR (Status)) {
215 return Status;
216 }
217 }
218
219 return EFI_SUCCESS;
220
221 }
222
223 /**
224 This function delete and build multi-instance device path ConIn
225 console device.
226
227 @retval EFI_SUCCESS The function complete successfully.
228 @return The EFI variable can not be saved. See gRT->SetVariable for detail return information.
229 **/
230 EFI_STATUS
231 Var_UpdateConsoleInpOption (
232 VOID
233 )
234 {
235 return Var_UpdateConsoleOption (L"ConIn", &ConsoleInpMenu, FORM_CON_IN_ID);
236 }
237
238 /**
239 This function delete and build multi-instance device path ConOut
240 console device.
241
242 @retval EFI_SUCCESS The function complete successfully.
243 @return The EFI variable can not be saved. See gRT->SetVariable for detail return information.
244 **/
245 EFI_STATUS
246 Var_UpdateConsoleOutOption (
247 VOID
248 )
249 {
250 return Var_UpdateConsoleOption (L"ConOut", &ConsoleOutMenu, FORM_CON_OUT_ID);
251 }
252
253 /**
254 This function delete and build multi-instance device path ErrOut
255 console device.
256
257 @retval EFI_SUCCESS The function complete successfully.
258 @return The EFI variable can not be saved. See gRT->SetVariable for detail return information.
259 **/
260 EFI_STATUS
261 Var_UpdateErrorOutOption (
262 VOID
263 )
264 {
265 return Var_UpdateConsoleOption (L"ErrOut", &ConsoleErrMenu, FORM_CON_ERR_ID);
266 }
267
268 /**
269 This function create a currently loaded Drive Option from
270 the BMM. It then appends this Driver Option to the end of
271 the "DriverOrder" list. It append this Driver Opotion to the end
272 of DriverOptionMenu.
273
274 @param CallbackData The BMM context data.
275 @param HiiHandle The HII handle associated with the BMM formset.
276 @param DescriptionData The description of this driver option.
277 @param OptionalData The optional load option.
278 @param ForceReconnect If to force reconnect.
279
280 @retval other Contain some errors when excuting this function.See function
281 EfiBootManagerInitializeLoadOption/EfiBootManagerAddLoadOptionVariabl
282 for detail return information.
283 @retval EFI_SUCCESS If function completes successfully.
284
285 **/
286 EFI_STATUS
287 Var_UpdateDriverOption (
288 IN BMM_CALLBACK_DATA *CallbackData,
289 IN EFI_HII_HANDLE HiiHandle,
290 IN UINT16 *DescriptionData,
291 IN UINT16 *OptionalData,
292 IN UINT8 ForceReconnect
293 )
294 {
295 UINT16 Index;
296 UINT16 DriverString[12];
297 BM_MENU_ENTRY *NewMenuEntry;
298 BM_LOAD_CONTEXT *NewLoadContext;
299 BOOLEAN OptionalDataExist;
300 EFI_STATUS Status;
301 EFI_BOOT_MANAGER_LOAD_OPTION LoadOption;
302 UINT8 *OptionalDesData;
303 UINT32 OptionalDataSize;
304
305 OptionalDataExist = FALSE;
306 OptionalDesData = NULL;
307 OptionalDataSize = 0;
308
309 Index = BOpt_GetDriverOptionNumber ();
310 UnicodeSPrint (
311 DriverString,
312 sizeof (DriverString),
313 L"Driver%04x",
314 Index
315 );
316
317 if (*DescriptionData == 0x0000) {
318 StrCpyS (DescriptionData, MAX_MENU_NUMBER, DriverString);
319 }
320
321 if (*OptionalData != 0x0000) {
322 OptionalDataExist = TRUE;
323 OptionalDesData = (UINT8 *)OptionalData;
324 OptionalDataSize = (UINT32)StrSize (OptionalData);
325 }
326
327 NewMenuEntry = BOpt_CreateMenuEntry (BM_LOAD_CONTEXT_SELECT);
328 if (NULL == NewMenuEntry) {
329 return EFI_OUT_OF_RESOURCES;
330 }
331
332 Status = EfiBootManagerInitializeLoadOption (
333 &LoadOption,
334 Index,
335 LoadOptionTypeDriver,
336 LOAD_OPTION_ACTIVE | (ForceReconnect << 1),
337 DescriptionData,
338 CallbackData->LoadContext->FilePathList,
339 OptionalDesData,
340 OptionalDataSize
341 );
342 if (EFI_ERROR (Status)){
343 return Status;
344 }
345
346 Status = EfiBootManagerAddLoadOptionVariable (&LoadOption,(UINTN) -1 );
347 if (EFI_ERROR (Status)) {
348 EfiBootManagerFreeLoadOption(&LoadOption);
349 return Status;
350 }
351
352 NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;
353 NewLoadContext->Deleted = FALSE;
354 NewLoadContext->Attributes = LoadOption.Attributes;
355 NewLoadContext->FilePathListLength = (UINT16)GetDevicePathSize (LoadOption.FilePath);
356
357 NewLoadContext->Description = AllocateZeroPool (StrSize (DescriptionData));
358 ASSERT (NewLoadContext->Description != NULL);
359 NewMenuEntry->DisplayString = NewLoadContext->Description;
360 CopyMem (
361 NewLoadContext->Description,
362 LoadOption.Description,
363 StrSize (DescriptionData)
364 );
365
366 NewLoadContext->FilePathList = AllocateZeroPool (GetDevicePathSize (CallbackData->LoadContext->FilePathList));
367 ASSERT (NewLoadContext->FilePathList != NULL);
368 CopyMem (
369 NewLoadContext->FilePathList,
370 LoadOption.FilePath,
371 GetDevicePathSize (CallbackData->LoadContext->FilePathList)
372 );
373
374 NewMenuEntry->HelpString = UiDevicePathToStr (NewLoadContext->FilePathList);
375 NewMenuEntry->OptionNumber = Index;
376 NewMenuEntry->DisplayStringToken = HiiSetString (HiiHandle, 0, NewMenuEntry->DisplayString, NULL);
377 NewMenuEntry->HelpStringToken = HiiSetString (HiiHandle, 0, NewMenuEntry->HelpString, NULL);
378
379 if (OptionalDataExist) {
380 NewLoadContext->OptionalData = AllocateZeroPool (LoadOption.OptionalDataSize);
381 ASSERT (NewLoadContext->OptionalData != NULL);
382 CopyMem (
383 NewLoadContext->OptionalData,
384 LoadOption.OptionalData,
385 LoadOption.OptionalDataSize
386 );
387 }
388
389 InsertTailList (&DriverOptionMenu.Head, &NewMenuEntry->Link);
390 DriverOptionMenu.MenuNumber++;
391
392 EfiBootManagerFreeLoadOption(&LoadOption);
393
394 return EFI_SUCCESS;
395 }
396
397 /**
398 This function create a currently loaded Boot Option from
399 the BMM. It then appends this Boot Option to the end of
400 the "BootOrder" list. It also append this Boot Opotion to the end
401 of BootOptionMenu.
402
403 @param CallbackData The BMM context data.
404
405 @retval other Contain some errors when excuting this function. See function
406 EfiBootManagerInitializeLoadOption/EfiBootManagerAddLoadOptionVariabl
407 for detail return information.
408 @retval EFI_SUCCESS If function completes successfully.
409
410 **/
411 EFI_STATUS
412 Var_UpdateBootOption (
413 IN BMM_CALLBACK_DATA *CallbackData
414 )
415 {
416 UINT16 BootString[10];
417 UINT16 Index;
418 BM_MENU_ENTRY *NewMenuEntry;
419 BM_LOAD_CONTEXT *NewLoadContext;
420 BOOLEAN OptionalDataExist;
421 EFI_STATUS Status;
422 BMM_FAKE_NV_DATA *NvRamMap;
423 EFI_BOOT_MANAGER_LOAD_OPTION LoadOption;
424 UINT8 *OptionalData;
425 UINT32 OptionalDataSize;
426
427 OptionalDataExist = FALSE;
428 NvRamMap = &CallbackData->BmmFakeNvData;
429 OptionalData = NULL;
430 OptionalDataSize = 0;
431
432 Index = BOpt_GetBootOptionNumber () ;
433 UnicodeSPrint (BootString, sizeof (BootString), L"Boot%04x", Index);
434
435 if (NvRamMap->BootDescriptionData[0] == 0x0000) {
436 StrCpyS (NvRamMap->BootDescriptionData, sizeof (NvRamMap->BootDescriptionData) / sizeof (NvRamMap->BootDescriptionData[0]), BootString);
437 }
438
439 if (NvRamMap->BootOptionalData[0] != 0x0000) {
440 OptionalDataExist = TRUE;
441 OptionalData = (UINT8 *)NvRamMap->BootOptionalData;
442 OptionalDataSize = (UINT32)StrSize (NvRamMap->BootOptionalData);
443 }
444
445 NewMenuEntry = BOpt_CreateMenuEntry (BM_LOAD_CONTEXT_SELECT);
446 if (NULL == NewMenuEntry) {
447 return EFI_OUT_OF_RESOURCES;
448 }
449
450 Status = EfiBootManagerInitializeLoadOption (
451 &LoadOption,
452 Index,
453 LoadOptionTypeBoot,
454 LOAD_OPTION_ACTIVE,
455 NvRamMap->BootDescriptionData,
456 CallbackData->LoadContext->FilePathList,
457 OptionalData,
458 OptionalDataSize
459 );
460 if (EFI_ERROR (Status)){
461 return Status;
462 }
463
464 Status = EfiBootManagerAddLoadOptionVariable (&LoadOption,(UINTN) -1 );
465 if (EFI_ERROR (Status)) {
466 EfiBootManagerFreeLoadOption(&LoadOption);
467 return Status;
468 }
469
470 NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;
471 NewLoadContext->Deleted = FALSE;
472 NewLoadContext->Attributes = LoadOption.Attributes;
473 NewLoadContext->FilePathListLength = (UINT16) GetDevicePathSize (LoadOption.FilePath);
474
475 NewLoadContext->Description = AllocateZeroPool (StrSize (NvRamMap->BootDescriptionData));
476 ASSERT (NewLoadContext->Description != NULL);
477
478 NewMenuEntry->DisplayString = NewLoadContext->Description;
479
480 CopyMem (
481 NewLoadContext->Description,
482 LoadOption.Description,
483 StrSize (NvRamMap->BootDescriptionData)
484 );
485
486 NewLoadContext->FilePathList = AllocateZeroPool (GetDevicePathSize (CallbackData->LoadContext->FilePathList));
487 ASSERT (NewLoadContext->FilePathList != NULL);
488 CopyMem (
489 NewLoadContext->FilePathList,
490 LoadOption.FilePath,
491 GetDevicePathSize (CallbackData->LoadContext->FilePathList)
492 );
493
494 NewMenuEntry->HelpString = UiDevicePathToStr (NewLoadContext->FilePathList);
495 NewMenuEntry->OptionNumber = Index;
496 NewMenuEntry->DisplayStringToken = HiiSetString (CallbackData->BmmHiiHandle, 0, NewMenuEntry->DisplayString, NULL);
497 NewMenuEntry->HelpStringToken = HiiSetString (CallbackData->BmmHiiHandle, 0, NewMenuEntry->HelpString, NULL);
498
499 if (OptionalDataExist) {
500 NewLoadContext->OptionalData = AllocateZeroPool (LoadOption.OptionalDataSize);
501 ASSERT (NewLoadContext->OptionalData != NULL);
502 CopyMem (
503 NewLoadContext->OptionalData,
504 LoadOption.OptionalData,
505 LoadOption.OptionalDataSize
506 );
507 }
508
509 InsertTailList (&BootOptionMenu.Head, &NewMenuEntry->Link);
510 BootOptionMenu.MenuNumber++;
511
512 EfiBootManagerFreeLoadOption(&LoadOption);
513
514 return EFI_SUCCESS;
515 }
516
517 /**
518 This function update the "BootNext" EFI Variable. If there is
519 no "BootNext" specified in BMM, this EFI Variable is deleted.
520 It also update the BMM context data specified the "BootNext"
521 vaule.
522
523 @param CallbackData The BMM context data.
524
525 @retval EFI_SUCCESS The function complete successfully.
526 @return The EFI variable can be saved. See gRT->SetVariable
527 for detail return information.
528
529 **/
530 EFI_STATUS
531 Var_UpdateBootNext (
532 IN BMM_CALLBACK_DATA *CallbackData
533 )
534 {
535 BM_MENU_ENTRY *NewMenuEntry;
536 BM_LOAD_CONTEXT *NewLoadContext;
537 BMM_FAKE_NV_DATA *CurrentFakeNVMap;
538 UINT16 Index;
539 EFI_STATUS Status;
540
541 Status = EFI_SUCCESS;
542 CurrentFakeNVMap = &CallbackData->BmmFakeNvData;
543 for (Index = 0; Index < BootOptionMenu.MenuNumber; Index++) {
544 NewMenuEntry = BOpt_GetMenuEntry (&BootOptionMenu, Index);
545 ASSERT (NULL != NewMenuEntry);
546
547 NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;
548 NewLoadContext->IsBootNext = FALSE;
549 }
550
551 if (CurrentFakeNVMap->BootNext == NONE_BOOTNEXT_VALUE) {
552 EfiLibDeleteVariable (L"BootNext", &gEfiGlobalVariableGuid);
553 return EFI_SUCCESS;
554 }
555
556 NewMenuEntry = BOpt_GetMenuEntry (
557 &BootOptionMenu,
558 CurrentFakeNVMap->BootNext
559 );
560 ASSERT (NewMenuEntry != NULL);
561
562 NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;
563 Status = gRT->SetVariable (
564 L"BootNext",
565 &gEfiGlobalVariableGuid,
566 VAR_FLAG,
567 sizeof (UINT16),
568 &NewMenuEntry->OptionNumber
569 );
570 NewLoadContext->IsBootNext = TRUE;
571 CallbackData->BmmOldFakeNVData.BootNext = CurrentFakeNVMap->BootNext;
572 return Status;
573 }
574
575 /**
576 This function update the "BootOrder" EFI Variable based on
577 BMM Formset's NV map. It then refresh BootOptionMenu
578 with the new "BootOrder" list.
579
580 @param CallbackData The BMM context data.
581
582 @retval EFI_SUCCESS The function complete successfully.
583 @retval EFI_OUT_OF_RESOURCES Not enough memory to complete the function.
584 @return The EFI variable can not be saved. See gRT->SetVariable for detail return information.
585
586 **/
587 EFI_STATUS
588 Var_UpdateBootOrder (
589 IN BMM_CALLBACK_DATA *CallbackData
590 )
591 {
592 EFI_STATUS Status;
593 UINT16 Index;
594 UINT16 OrderIndex;
595 UINT16 *BootOrder;
596 UINTN BootOrderSize;
597 UINT16 OptionNumber;
598
599 //
600 // First check whether BootOrder is present in current configuration
601 //
602 GetEfiGlobalVariable2 (L"BootOrder", (VOID **) &BootOrder, &BootOrderSize);
603 if (BootOrder == NULL) {
604 return EFI_OUT_OF_RESOURCES;
605 }
606
607 ASSERT (BootOptionMenu.MenuNumber <= (sizeof (CallbackData->BmmFakeNvData.BootOptionOrder) / sizeof (CallbackData->BmmFakeNvData.BootOptionOrder[0])));
608
609 //
610 // OptionOrder is subset of BootOrder
611 //
612 for (OrderIndex = 0; (OrderIndex < BootOptionMenu.MenuNumber) && (CallbackData->BmmFakeNvData.BootOptionOrder[OrderIndex] != 0); OrderIndex++) {
613 for (Index = OrderIndex; Index < BootOrderSize / sizeof (UINT16); Index++) {
614 if ((BootOrder[Index] == (UINT16) (CallbackData->BmmFakeNvData.BootOptionOrder[OrderIndex] - 1)) && (OrderIndex != Index)) {
615 OptionNumber = BootOrder[Index];
616 CopyMem (&BootOrder[OrderIndex + 1], &BootOrder[OrderIndex], (Index - OrderIndex) * sizeof (UINT16));
617 BootOrder[OrderIndex] = OptionNumber;
618 }
619 }
620 }
621
622 Status = gRT->SetVariable (
623 L"BootOrder",
624 &gEfiGlobalVariableGuid,
625 VAR_FLAG,
626 BootOrderSize,
627 BootOrder
628 );
629 FreePool (BootOrder);
630
631 BOpt_FreeMenu (&BootOptionMenu);
632 BOpt_GetBootOptions (CallbackData);
633
634 return Status;
635
636 }
637
638 /**
639 This function update the "DriverOrder" EFI Variable based on
640 BMM Formset's NV map. It then refresh DriverOptionMenu
641 with the new "DriverOrder" list.
642
643 @param CallbackData The BMM context data.
644
645 @retval EFI_SUCCESS The function complete successfully.
646 @retval EFI_OUT_OF_RESOURCES Not enough memory to complete the function.
647 @return The EFI variable can not be saved. See gRT->SetVariable for detail return information.
648
649 **/
650 EFI_STATUS
651 Var_UpdateDriverOrder (
652 IN BMM_CALLBACK_DATA *CallbackData
653 )
654 {
655 EFI_STATUS Status;
656 UINT16 Index;
657 UINT16 *DriverOrderList;
658 UINT16 *NewDriverOrderList;
659 UINTN DriverOrderListSize;
660
661 DriverOrderList = NULL;
662 DriverOrderListSize = 0;
663
664 //
665 // First check whether DriverOrder is present in current configuration
666 //
667 GetEfiGlobalVariable2 (L"DriverOrder", (VOID **) &DriverOrderList, &DriverOrderListSize);
668 NewDriverOrderList = AllocateZeroPool (DriverOrderListSize);
669
670 if (NewDriverOrderList == NULL) {
671 return EFI_OUT_OF_RESOURCES;
672 }
673 //
674 // If exists, delete it to hold new DriverOrder
675 //
676 if (DriverOrderList != NULL) {
677 EfiLibDeleteVariable (L"DriverOrder", &gEfiGlobalVariableGuid);
678 FreePool (DriverOrderList);
679 }
680
681 ASSERT (DriverOptionMenu.MenuNumber <= (sizeof (CallbackData->BmmFakeNvData.DriverOptionOrder) / sizeof (CallbackData->BmmFakeNvData.DriverOptionOrder[0])));
682 for (Index = 0; Index < DriverOptionMenu.MenuNumber; Index++) {
683 NewDriverOrderList[Index] = (UINT16) (CallbackData->BmmFakeNvData.DriverOptionOrder[Index] - 1);
684 }
685
686 Status = gRT->SetVariable (
687 L"DriverOrder",
688 &gEfiGlobalVariableGuid,
689 VAR_FLAG,
690 DriverOrderListSize,
691 NewDriverOrderList
692 );
693 if (EFI_ERROR (Status)) {
694 return Status;
695 }
696
697 BOpt_FreeMenu (&DriverOptionMenu);
698 BOpt_GetDriverOptions (CallbackData);
699 return EFI_SUCCESS;
700 }
701
702 /**
703 Update the Text Mode of Console.
704
705 @param CallbackData The context data for BMM.
706
707 @retval EFI_SUCCSS If the Text Mode of Console is updated.
708 @return Other value if the Text Mode of Console is not updated.
709
710 **/
711 EFI_STATUS
712 Var_UpdateConMode (
713 IN BMM_CALLBACK_DATA *CallbackData
714 )
715 {
716 EFI_STATUS Status;
717 UINTN Mode;
718 CONSOLE_OUT_MODE ModeInfo;
719
720 Mode = CallbackData->BmmFakeNvData.ConsoleOutMode;
721
722 Status = gST->ConOut->QueryMode (gST->ConOut, Mode, &(ModeInfo.Column), &(ModeInfo.Row));
723 if (!EFI_ERROR(Status)) {
724 Status = PcdSet32S (PcdSetupConOutColumn, (UINT32) ModeInfo.Column);
725 if (!EFI_ERROR (Status)) {
726 Status = PcdSet32S (PcdSetupConOutRow, (UINT32) ModeInfo.Row);
727 }
728 }
729
730 return Status;
731 }