]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Application/UiApp/BootMaint/Variable.c
UiApp: Update copyright info, cover old code existed in old BdsDxe driver.
[mirror_edk2.git] / MdeModulePkg / Application / UiApp / BootMaint / Variable.c
1 /** @file
2 Variable operation that will be used by bootmaint
3
4 Copyright (c) 2004 - 2015, 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 GetEfiGlobalVariable2 (L"BootOrder", (VOID **) &BootOrderList, &BootOrderListSize);
116
117 //
118 // If exists, delete it to hold new BootOrder
119 //
120 if (BootOrderList != NULL) {
121 EfiLibDeleteVariable (L"BootOrder", &gEfiGlobalVariableGuid);
122 FreePool (BootOrderList);
123 BootOrderList = NULL;
124 }
125 //
126 // Maybe here should be some check method to ensure that
127 // no new added boot options will be added
128 // but the setup engine now will give only one callback
129 // that is to say, user are granted only one chance to
130 // decide whether the boot option will be added or not
131 // there should be no indictor to show whether this
132 // is a "new" boot option
133 //
134 BootOrderListSize = BootOptionMenu.MenuNumber;
135
136 if (BootOrderListSize > 0) {
137 BootOrderList = AllocateZeroPool (BootOrderListSize * sizeof (UINT16));
138 ASSERT (BootOrderList != NULL);
139 BootOrderListPtr = BootOrderList;
140
141 //
142 // Get all current used Boot#### from BootOptionMenu.
143 // OptionNumber in each BM_LOAD_OPTION is really its
144 // #### value.
145 //
146 for (Index = 0; Index < BootOrderListSize; Index++) {
147 NewMenuEntry = BOpt_GetMenuEntry (&BootOptionMenu, Index);
148 *BootOrderList = (UINT16) NewMenuEntry->OptionNumber;
149 BootOrderList++;
150 }
151
152 BootOrderList = BootOrderListPtr;
153
154 //
155 // After building the BootOrderList, write it back
156 //
157 Status = gRT->SetVariable (
158 L"BootOrder",
159 &gEfiGlobalVariableGuid,
160 VAR_FLAG,
161 BootOrderListSize * sizeof (UINT16),
162 BootOrderList
163 );
164 if (EFI_ERROR (Status)) {
165 return Status;
166 }
167 }
168 return EFI_SUCCESS;
169 }
170
171 /**
172 Delete Load Option that represent a Deleted state in BootOptionMenu.
173 After deleting this Driver option, call Var_ChangeDriverOrder to
174 make sure DriverOrder is in valid state.
175
176 @retval EFI_SUCCESS Load Option is successfully updated.
177 @retval EFI_NOT_FOUND Fail to find the driver option want to be deleted.
178 @return Other value than EFI_SUCCESS if failed to update "Driver Order" EFI
179 Variable.
180
181 **/
182 EFI_STATUS
183 Var_DelDriverOption (
184 VOID
185 )
186 {
187 BM_MENU_ENTRY *NewMenuEntry;
188 BM_LOAD_CONTEXT *NewLoadContext;
189 UINT16 DriverString[12];
190 EFI_STATUS Status;
191 UINTN Index;
192 UINTN Index2;
193
194 Status = EFI_SUCCESS;
195 Index2 = 0;
196 for (Index = 0; Index < DriverOptionMenu.MenuNumber; Index++) {
197 NewMenuEntry = BOpt_GetMenuEntry (&DriverOptionMenu, (Index - Index2));
198 if (NULL == NewMenuEntry) {
199 return EFI_NOT_FOUND;
200 }
201
202 NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;
203 if (!NewLoadContext->Deleted) {
204 continue;
205 }
206
207 UnicodeSPrint (
208 DriverString,
209 sizeof (DriverString),
210 L"Driver%04x",
211 NewMenuEntry->OptionNumber
212 );
213
214 EfiLibDeleteVariable (DriverString, &gEfiGlobalVariableGuid);
215 Index2++;
216
217 RemoveEntryList (&NewMenuEntry->Link);
218 BOpt_DestroyMenuEntry (NewMenuEntry);
219 NewMenuEntry = NULL;
220 }
221
222 DriverOptionMenu.MenuNumber -= Index2;
223
224 Status = Var_ChangeDriverOrder ();
225 return Status;
226 }
227
228 /**
229 After any operation on Driver####, there will be a discrepancy in
230 DriverOrder. Since some are missing but in DriverOrder, while some
231 are present but are not reflected by DriverOrder. Then a function
232 rebuild DriverOrder from scratch by content from DriverOptionMenu is
233 needed.
234
235 @retval EFI_SUCCESS The driver order is updated successfully.
236 @return Other status than EFI_SUCCESS if failed to set the "DriverOrder" EFI Variable.
237
238 **/
239 EFI_STATUS
240 Var_ChangeDriverOrder (
241 VOID
242 )
243 {
244 EFI_STATUS Status;
245 BM_MENU_ENTRY *NewMenuEntry;
246 UINT16 *DriverOrderList;
247 UINT16 *DriverOrderListPtr;
248 UINTN DriverOrderListSize;
249 UINTN Index;
250
251 DriverOrderList = NULL;
252 DriverOrderListSize = 0;
253
254 //
255 // First check whether DriverOrder is present in current configuration
256 //
257 GetEfiGlobalVariable2 (L"DriverOrder", (VOID **) &DriverOrderList, &DriverOrderListSize);
258 //
259 // If exists, delete it to hold new DriverOrder
260 //
261 if (DriverOrderList != NULL) {
262 EfiLibDeleteVariable (L"DriverOrder", &gEfiGlobalVariableGuid);
263 FreePool (DriverOrderList);
264 DriverOrderList = NULL;
265 }
266
267 DriverOrderListSize = DriverOptionMenu.MenuNumber;
268
269 if (DriverOrderListSize > 0) {
270 DriverOrderList = AllocateZeroPool (DriverOrderListSize * sizeof (UINT16));
271 ASSERT (DriverOrderList != NULL);
272 DriverOrderListPtr = DriverOrderList;
273
274 //
275 // Get all current used Driver#### from DriverOptionMenu.
276 // OptionNumber in each BM_LOAD_OPTION is really its
277 // #### value.
278 //
279 for (Index = 0; Index < DriverOrderListSize; Index++) {
280 NewMenuEntry = BOpt_GetMenuEntry (&DriverOptionMenu, Index);
281 *DriverOrderList = (UINT16) NewMenuEntry->OptionNumber;
282 DriverOrderList++;
283 }
284
285 DriverOrderList = DriverOrderListPtr;
286
287 //
288 // After building the DriverOrderList, write it back
289 //
290 Status = gRT->SetVariable (
291 L"DriverOrder",
292 &gEfiGlobalVariableGuid,
293 VAR_FLAG,
294 DriverOrderListSize * sizeof (UINT16),
295 DriverOrderList
296 );
297 if (EFI_ERROR (Status)) {
298 return Status;
299 }
300 }
301 return EFI_SUCCESS;
302 }
303
304 /**
305 Update the device path of "ConOut", "ConIn" and "ErrOut"
306 based on the new BaudRate, Data Bits, parity and Stop Bits
307 set.
308
309 **/
310 VOID
311 Var_UpdateAllConsoleOption (
312 VOID
313 )
314 {
315 EFI_DEVICE_PATH_PROTOCOL *OutDevicePath;
316 EFI_DEVICE_PATH_PROTOCOL *InpDevicePath;
317 EFI_DEVICE_PATH_PROTOCOL *ErrDevicePath;
318 EFI_STATUS Status;
319
320 OutDevicePath = GetEfiGlobalVariable (L"ConOut");
321 InpDevicePath = GetEfiGlobalVariable (L"ConIn");
322 ErrDevicePath = GetEfiGlobalVariable (L"ErrOut");
323 if (OutDevicePath != NULL) {
324 ChangeVariableDevicePath (OutDevicePath);
325 Status = gRT->SetVariable (
326 L"ConOut",
327 &gEfiGlobalVariableGuid,
328 VAR_FLAG,
329 GetDevicePathSize (OutDevicePath),
330 OutDevicePath
331 );
332 ASSERT (!EFI_ERROR (Status));
333 }
334
335 if (InpDevicePath != NULL) {
336 ChangeVariableDevicePath (InpDevicePath);
337 Status = gRT->SetVariable (
338 L"ConIn",
339 &gEfiGlobalVariableGuid,
340 VAR_FLAG,
341 GetDevicePathSize (InpDevicePath),
342 InpDevicePath
343 );
344 ASSERT (!EFI_ERROR (Status));
345 }
346
347 if (ErrDevicePath != NULL) {
348 ChangeVariableDevicePath (ErrDevicePath);
349 Status = gRT->SetVariable (
350 L"ErrOut",
351 &gEfiGlobalVariableGuid,
352 VAR_FLAG,
353 GetDevicePathSize (ErrDevicePath),
354 ErrDevicePath
355 );
356 ASSERT (!EFI_ERROR (Status));
357 }
358 }
359
360 /**
361 This function delete and build multi-instance device path for
362 specified type of console device.
363
364 This function clear the EFI variable defined by ConsoleName and
365 gEfiGlobalVariableGuid. It then build the multi-instance device
366 path by appending the device path of the Console (In/Out/Err) instance
367 in ConsoleMenu. Then it scan all corresponding console device by
368 scanning Terminal (built from device supporting Serial I/O instances)
369 devices in TerminalMenu. At last, it save a EFI variable specifed
370 by ConsoleName and gEfiGlobalVariableGuid.
371
372 @param ConsoleName The name for the console device type. They are
373 usually "ConIn", "ConOut" and "ErrOut".
374 @param ConsoleMenu The console memu which is a list of console devices.
375 @param UpdatePageId The flag specifying which type of console device
376 to be processed.
377
378 @retval EFI_SUCCESS The function complete successfully.
379 @return The EFI variable can not be saved. See gRT->SetVariable for detail return information.
380
381 **/
382 EFI_STATUS
383 Var_UpdateConsoleOption (
384 IN UINT16 *ConsoleName,
385 IN BM_MENU_OPTION *ConsoleMenu,
386 IN UINT16 UpdatePageId
387 )
388 {
389 EFI_DEVICE_PATH_PROTOCOL *ConDevicePath;
390 BM_MENU_ENTRY *NewMenuEntry;
391 BM_CONSOLE_CONTEXT *NewConsoleContext;
392 BM_TERMINAL_CONTEXT *NewTerminalContext;
393 EFI_STATUS Status;
394 VENDOR_DEVICE_PATH Vendor;
395 EFI_DEVICE_PATH_PROTOCOL *TerminalDevicePath;
396 UINTN Index;
397
398 ConDevicePath = GetEfiGlobalVariable (ConsoleName);
399 if (ConDevicePath != NULL) {
400 EfiLibDeleteVariable (ConsoleName, &gEfiGlobalVariableGuid);
401 FreePool (ConDevicePath);
402 ConDevicePath = NULL;
403 };
404
405 //
406 // First add all console input device from console input menu
407 //
408 for (Index = 0; Index < ConsoleMenu->MenuNumber; Index++) {
409 NewMenuEntry = BOpt_GetMenuEntry (ConsoleMenu, Index);
410
411 NewConsoleContext = (BM_CONSOLE_CONTEXT *) NewMenuEntry->VariableContext;
412 if (NewConsoleContext->IsActive) {
413 ConDevicePath = AppendDevicePathInstance (
414 ConDevicePath,
415 NewConsoleContext->DevicePath
416 );
417 }
418 }
419
420 for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {
421 NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);
422
423 NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;
424 if (((NewTerminalContext->IsConIn != 0) && (UpdatePageId == FORM_CON_IN_ID)) ||
425 ((NewTerminalContext->IsConOut != 0) && (UpdatePageId == FORM_CON_OUT_ID)) ||
426 ((NewTerminalContext->IsStdErr != 0) && (UpdatePageId == FORM_CON_ERR_ID))
427 ) {
428 Vendor.Header.Type = MESSAGING_DEVICE_PATH;
429 Vendor.Header.SubType = MSG_VENDOR_DP;
430
431 ASSERT (NewTerminalContext->TerminalType < (sizeof (TerminalTypeGuid) / sizeof (TerminalTypeGuid[0])));
432 CopyMem (
433 &Vendor.Guid,
434 &TerminalTypeGuid[NewTerminalContext->TerminalType],
435 sizeof (EFI_GUID)
436 );
437 SetDevicePathNodeLength (&Vendor.Header, sizeof (VENDOR_DEVICE_PATH));
438 TerminalDevicePath = AppendDevicePathNode (
439 NewTerminalContext->DevicePath,
440 (EFI_DEVICE_PATH_PROTOCOL *) &Vendor
441 );
442 ASSERT (TerminalDevicePath != NULL);
443 ChangeTerminalDevicePath (TerminalDevicePath, TRUE);
444 ConDevicePath = AppendDevicePathInstance (
445 ConDevicePath,
446 TerminalDevicePath
447 );
448 }
449 }
450
451 if (ConDevicePath != NULL) {
452 Status = gRT->SetVariable (
453 ConsoleName,
454 &gEfiGlobalVariableGuid,
455 VAR_FLAG,
456 GetDevicePathSize (ConDevicePath),
457 ConDevicePath
458 );
459 if (EFI_ERROR (Status)) {
460 return Status;
461 }
462 }
463
464 return EFI_SUCCESS;
465
466 }
467
468 /**
469 This function delete and build multi-instance device path ConIn
470 console device.
471
472 @retval EFI_SUCCESS The function complete successfully.
473 @return The EFI variable can not be saved. See gRT->SetVariable for detail return information.
474 **/
475 EFI_STATUS
476 Var_UpdateConsoleInpOption (
477 VOID
478 )
479 {
480 return Var_UpdateConsoleOption (L"ConIn", &ConsoleInpMenu, FORM_CON_IN_ID);
481 }
482
483 /**
484 This function delete and build multi-instance device path ConOut
485 console device.
486
487 @retval EFI_SUCCESS The function complete successfully.
488 @return The EFI variable can not be saved. See gRT->SetVariable for detail return information.
489 **/
490 EFI_STATUS
491 Var_UpdateConsoleOutOption (
492 VOID
493 )
494 {
495 return Var_UpdateConsoleOption (L"ConOut", &ConsoleOutMenu, FORM_CON_OUT_ID);
496 }
497
498 /**
499 This function delete and build multi-instance device path ErrOut
500 console device.
501
502 @retval EFI_SUCCESS The function complete successfully.
503 @return The EFI variable can not be saved. See gRT->SetVariable for detail return information.
504 **/
505 EFI_STATUS
506 Var_UpdateErrorOutOption (
507 VOID
508 )
509 {
510 return Var_UpdateConsoleOption (L"ErrOut", &ConsoleErrMenu, FORM_CON_ERR_ID);
511 }
512
513 /**
514 This function create a currently loaded Drive Option from
515 the BMM. It then appends this Driver Option to the end of
516 the "DriverOrder" list. It append this Driver Opotion to the end
517 of DriverOptionMenu.
518
519 @param CallbackData The BMM context data.
520 @param HiiHandle The HII handle associated with the BMM formset.
521 @param DescriptionData The description of this driver option.
522 @param OptionalData The optional load option.
523 @param ForceReconnect If to force reconnect.
524
525 @retval EFI_OUT_OF_RESOURCES If not enought memory to complete the operation.
526 @retval EFI_SUCCESS If function completes successfully.
527
528 **/
529 EFI_STATUS
530 Var_UpdateDriverOption (
531 IN BMM_CALLBACK_DATA *CallbackData,
532 IN EFI_HII_HANDLE HiiHandle,
533 IN UINT16 *DescriptionData,
534 IN UINT16 *OptionalData,
535 IN UINT8 ForceReconnect
536 )
537 {
538 UINT16 Index;
539 UINT16 *DriverOrderList;
540 UINT16 *NewDriverOrderList;
541 UINT16 DriverString[12];
542 UINTN DriverOrderListSize;
543 VOID *Buffer;
544 UINTN BufferSize;
545 UINT8 *Ptr;
546 BM_MENU_ENTRY *NewMenuEntry;
547 BM_LOAD_CONTEXT *NewLoadContext;
548 BOOLEAN OptionalDataExist;
549 EFI_STATUS Status;
550
551 OptionalDataExist = FALSE;
552
553 Index = BOpt_GetDriverOptionNumber ();
554 UnicodeSPrint (
555 DriverString,
556 sizeof (DriverString),
557 L"Driver%04x",
558 Index
559 );
560
561 if (*DescriptionData == 0x0000) {
562 StrCpy (DescriptionData, DriverString);
563 }
564
565 BufferSize = sizeof (UINT32) + sizeof (UINT16) + StrSize (DescriptionData);
566 BufferSize += GetDevicePathSize (CallbackData->LoadContext->FilePathList);
567
568 if (*OptionalData != 0x0000) {
569 OptionalDataExist = TRUE;
570 BufferSize += StrSize (OptionalData);
571 }
572
573 Buffer = AllocateZeroPool (BufferSize);
574 if (NULL == Buffer) {
575 return EFI_OUT_OF_RESOURCES;
576 }
577
578 NewMenuEntry = BOpt_CreateMenuEntry (BM_LOAD_CONTEXT_SELECT);
579 if (NULL == NewMenuEntry) {
580 FreePool (Buffer);
581 return EFI_OUT_OF_RESOURCES;
582 }
583
584 NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;
585 NewLoadContext->Deleted = FALSE;
586 NewLoadContext->LoadOptionSize = BufferSize;
587 Ptr = (UINT8 *) Buffer;
588 NewLoadContext->LoadOption = Ptr;
589 *((UINT32 *) Ptr) = LOAD_OPTION_ACTIVE | (ForceReconnect << 1);
590 NewLoadContext->Attributes = *((UINT32 *) Ptr);
591 NewLoadContext->IsActive = TRUE;
592 NewLoadContext->ForceReconnect = (BOOLEAN) (NewLoadContext->Attributes & LOAD_OPTION_FORCE_RECONNECT);
593
594 Ptr += sizeof (UINT32);
595 *((UINT16 *) Ptr) = (UINT16) GetDevicePathSize (CallbackData->LoadContext->FilePathList);
596 NewLoadContext->FilePathListLength = *((UINT16 *) Ptr);
597
598 Ptr += sizeof (UINT16);
599 CopyMem (
600 Ptr,
601 DescriptionData,
602 StrSize (DescriptionData)
603 );
604
605 NewLoadContext->Description = AllocateZeroPool (StrSize (DescriptionData));
606 ASSERT (NewLoadContext->Description != NULL);
607 NewMenuEntry->DisplayString = NewLoadContext->Description;
608 CopyMem (
609 NewLoadContext->Description,
610 (VOID *) Ptr,
611 StrSize (DescriptionData)
612 );
613
614 Ptr += StrSize (DescriptionData);
615 CopyMem (
616 Ptr,
617 CallbackData->LoadContext->FilePathList,
618 GetDevicePathSize (CallbackData->LoadContext->FilePathList)
619 );
620
621 NewLoadContext->FilePathList = AllocateZeroPool (GetDevicePathSize (CallbackData->LoadContext->FilePathList));
622 ASSERT (NewLoadContext->FilePathList != NULL);
623
624 CopyMem (
625 NewLoadContext->FilePathList,
626 (VOID *) Ptr,
627 GetDevicePathSize (CallbackData->LoadContext->FilePathList)
628 );
629
630 NewMenuEntry->HelpString = UiDevicePathToStr (NewLoadContext->FilePathList);
631 NewMenuEntry->OptionNumber = Index;
632 NewMenuEntry->DisplayStringToken = GetStringTokenFromDepository (
633 CallbackData,
634 DriverOptionStrDepository
635 );
636 NewMenuEntry->DisplayStringToken = HiiSetString (HiiHandle, 0, NewMenuEntry->DisplayString, NULL);
637
638 NewMenuEntry->HelpStringToken = GetStringTokenFromDepository (
639 CallbackData,
640 DriverOptionHelpStrDepository
641 );
642 NewMenuEntry->HelpStringToken = HiiSetString (HiiHandle, 0, NewMenuEntry->HelpString, NULL);
643
644 if (OptionalDataExist) {
645 Ptr += (UINT8) GetDevicePathSize (CallbackData->LoadContext->FilePathList);
646
647 CopyMem (
648 Ptr,
649 OptionalData,
650 StrSize (OptionalData)
651 );
652 }
653
654 Status = gRT->SetVariable (
655 DriverString,
656 &gEfiGlobalVariableGuid,
657 VAR_FLAG,
658 BufferSize,
659 Buffer
660 );
661 ASSERT_EFI_ERROR (Status);
662 GetEfiGlobalVariable2 (L"DriverOrder", (VOID **) &DriverOrderList, &DriverOrderListSize);
663 NewDriverOrderList = AllocateZeroPool (DriverOrderListSize + sizeof (UINT16));
664 ASSERT (NewDriverOrderList != NULL);
665 CopyMem (NewDriverOrderList, DriverOrderList, DriverOrderListSize);
666 NewDriverOrderList[DriverOrderListSize / sizeof (UINT16)] = Index;
667 if (DriverOrderList != NULL) {
668 EfiLibDeleteVariable (L"DriverOrder", &gEfiGlobalVariableGuid);
669 }
670
671 Status = gRT->SetVariable (
672 L"DriverOrder",
673 &gEfiGlobalVariableGuid,
674 VAR_FLAG,
675 DriverOrderListSize + sizeof (UINT16),
676 NewDriverOrderList
677 );
678 ASSERT_EFI_ERROR (Status);
679 if (DriverOrderList != NULL) {
680 FreePool (DriverOrderList);
681 }
682 DriverOrderList = NULL;
683 FreePool (NewDriverOrderList);
684 InsertTailList (&DriverOptionMenu.Head, &NewMenuEntry->Link);
685 DriverOptionMenu.MenuNumber++;
686
687 *DescriptionData = 0x0000;
688 *OptionalData = 0x0000;
689 return EFI_SUCCESS;
690 }
691
692 /**
693 This function create a currently loaded Boot Option from
694 the BMM. It then appends this Boot Option to the end of
695 the "BootOrder" list. It also append this Boot Opotion to the end
696 of BootOptionMenu.
697
698 @param CallbackData The BMM context data.
699 @param NvRamMap The file explorer formset internal state.
700
701 @retval EFI_OUT_OF_RESOURCES If not enought memory to complete the operation.
702 @retval EFI_SUCCESS If function completes successfully.
703
704 **/
705 EFI_STATUS
706 Var_UpdateBootOption (
707 IN BMM_CALLBACK_DATA *CallbackData,
708 IN FILE_EXPLORER_NV_DATA *NvRamMap
709 )
710 {
711 UINT16 *BootOrderList;
712 UINT16 *NewBootOrderList;
713 UINTN BootOrderListSize;
714 UINT16 BootString[10];
715 VOID *Buffer;
716 UINTN BufferSize;
717 UINT8 *Ptr;
718 UINT16 Index;
719 BM_MENU_ENTRY *NewMenuEntry;
720 BM_LOAD_CONTEXT *NewLoadContext;
721 BOOLEAN OptionalDataExist;
722 EFI_STATUS Status;
723
724 OptionalDataExist = FALSE;
725
726 Index = BOpt_GetBootOptionNumber () ;
727 UnicodeSPrint (BootString, sizeof (BootString), L"Boot%04x", Index);
728
729 if (NvRamMap->DescriptionData[0] == 0x0000) {
730 StrCpy (NvRamMap->DescriptionData, BootString);
731 }
732
733 BufferSize = sizeof (UINT32) + sizeof (UINT16) + StrSize (NvRamMap->DescriptionData);
734 BufferSize += GetDevicePathSize (CallbackData->LoadContext->FilePathList);
735
736 if (NvRamMap->OptionalData[0] != 0x0000) {
737 OptionalDataExist = TRUE;
738 BufferSize += StrSize (NvRamMap->OptionalData);
739 }
740
741 Buffer = AllocateZeroPool (BufferSize);
742 if (NULL == Buffer) {
743 return EFI_OUT_OF_RESOURCES;
744 }
745
746 NewMenuEntry = BOpt_CreateMenuEntry (BM_LOAD_CONTEXT_SELECT);
747 if (NULL == NewMenuEntry) {
748 return EFI_OUT_OF_RESOURCES;
749 }
750
751 NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;
752 NewLoadContext->Deleted = FALSE;
753 NewLoadContext->LoadOptionSize = BufferSize;
754 Ptr = (UINT8 *) Buffer;
755 NewLoadContext->LoadOption = Ptr;
756 *((UINT32 *) Ptr) = LOAD_OPTION_ACTIVE;
757 NewLoadContext->Attributes = *((UINT32 *) Ptr);
758 NewLoadContext->IsActive = TRUE;
759 NewLoadContext->ForceReconnect = (BOOLEAN) (NewLoadContext->Attributes & LOAD_OPTION_FORCE_RECONNECT);
760
761 Ptr += sizeof (UINT32);
762 *((UINT16 *) Ptr) = (UINT16) GetDevicePathSize (CallbackData->LoadContext->FilePathList);
763 NewLoadContext->FilePathListLength = *((UINT16 *) Ptr);
764 Ptr += sizeof (UINT16);
765
766 CopyMem (
767 Ptr,
768 NvRamMap->DescriptionData,
769 StrSize (NvRamMap->DescriptionData)
770 );
771
772 NewLoadContext->Description = AllocateZeroPool (StrSize (NvRamMap->DescriptionData));
773 ASSERT (NewLoadContext->Description != NULL);
774
775 NewMenuEntry->DisplayString = NewLoadContext->Description;
776 CopyMem (
777 NewLoadContext->Description,
778 (VOID *) Ptr,
779 StrSize (NvRamMap->DescriptionData)
780 );
781
782 Ptr += StrSize (NvRamMap->DescriptionData);
783 CopyMem (
784 Ptr,
785 CallbackData->LoadContext->FilePathList,
786 GetDevicePathSize (CallbackData->LoadContext->FilePathList)
787 );
788
789 NewLoadContext->FilePathList = AllocateZeroPool (GetDevicePathSize (CallbackData->LoadContext->FilePathList));
790 ASSERT (NewLoadContext->FilePathList != NULL);
791
792 CopyMem (
793 NewLoadContext->FilePathList,
794 (VOID *) Ptr,
795 GetDevicePathSize (CallbackData->LoadContext->FilePathList)
796 );
797
798 NewMenuEntry->HelpString = UiDevicePathToStr (NewLoadContext->FilePathList);
799 NewMenuEntry->OptionNumber = Index;
800 NewMenuEntry->DisplayStringToken = GetStringTokenFromDepository (
801 CallbackData,
802 BootOptionStrDepository
803 );
804 NewMenuEntry->DisplayStringToken = HiiSetString (CallbackData->FeHiiHandle, 0, NewMenuEntry->DisplayString, NULL);
805
806 NewMenuEntry->HelpStringToken = GetStringTokenFromDepository (
807 CallbackData,
808 BootOptionHelpStrDepository
809 );
810 NewMenuEntry->HelpStringToken = HiiSetString (CallbackData->FeHiiHandle, 0, NewMenuEntry->HelpString, NULL);
811
812 if (OptionalDataExist) {
813 Ptr += (UINT8) GetDevicePathSize (CallbackData->LoadContext->FilePathList);
814
815 CopyMem (Ptr, NvRamMap->OptionalData, StrSize (NvRamMap->OptionalData));
816 }
817
818 Status = gRT->SetVariable (
819 BootString,
820 &gEfiGlobalVariableGuid,
821 VAR_FLAG,
822 BufferSize,
823 Buffer
824 );
825 ASSERT_EFI_ERROR (Status);
826
827 GetEfiGlobalVariable2 (L"BootOrder", (VOID **) &BootOrderList, &BootOrderListSize);
828 NewBootOrderList = AllocateZeroPool (BootOrderListSize + sizeof (UINT16));
829 ASSERT (NewBootOrderList != NULL);
830 CopyMem (NewBootOrderList, BootOrderList, BootOrderListSize);
831 NewBootOrderList[BootOrderListSize / sizeof (UINT16)] = Index;
832
833 if (BootOrderList != NULL) {
834 FreePool (BootOrderList);
835 }
836
837 Status = gRT->SetVariable (
838 L"BootOrder",
839 &gEfiGlobalVariableGuid,
840 VAR_FLAG,
841 BootOrderListSize + sizeof (UINT16),
842 NewBootOrderList
843 );
844 ASSERT_EFI_ERROR (Status);
845
846 FreePool (NewBootOrderList);
847 NewBootOrderList = NULL;
848 InsertTailList (&BootOptionMenu.Head, &NewMenuEntry->Link);
849 BootOptionMenu.MenuNumber++;
850
851 NvRamMap->DescriptionData[0] = 0x0000;
852 NvRamMap->OptionalData[0] = 0x0000;
853 return EFI_SUCCESS;
854 }
855
856 /**
857 This function update the "BootNext" EFI Variable. If there is
858 no "BootNext" specified in BMM, this EFI Variable is deleted.
859 It also update the BMM context data specified the "BootNext"
860 vaule.
861
862 @param CallbackData The BMM context data.
863
864 @retval EFI_SUCCESS The function complete successfully.
865 @return The EFI variable can be saved. See gRT->SetVariable
866 for detail return information.
867
868 **/
869 EFI_STATUS
870 Var_UpdateBootNext (
871 IN BMM_CALLBACK_DATA *CallbackData
872 )
873 {
874 BM_MENU_ENTRY *NewMenuEntry;
875 BM_LOAD_CONTEXT *NewLoadContext;
876 BMM_FAKE_NV_DATA *CurrentFakeNVMap;
877 UINT16 Index;
878 EFI_STATUS Status;
879
880 Status = EFI_SUCCESS;
881 CurrentFakeNVMap = &CallbackData->BmmFakeNvData;
882 for (Index = 0; Index < BootOptionMenu.MenuNumber; Index++) {
883 NewMenuEntry = BOpt_GetMenuEntry (&BootOptionMenu, Index);
884 ASSERT (NULL != NewMenuEntry);
885
886 NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;
887 NewLoadContext->IsBootNext = FALSE;
888 }
889
890 if (CurrentFakeNVMap->BootNext == BootOptionMenu.MenuNumber) {
891 EfiLibDeleteVariable (L"BootNext", &gEfiGlobalVariableGuid);
892 return EFI_SUCCESS;
893 }
894
895 NewMenuEntry = BOpt_GetMenuEntry (
896 &BootOptionMenu,
897 CurrentFakeNVMap->BootNext
898 );
899 ASSERT (NewMenuEntry != NULL);
900
901 NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;
902 Status = gRT->SetVariable (
903 L"BootNext",
904 &gEfiGlobalVariableGuid,
905 VAR_FLAG,
906 sizeof (UINT16),
907 &NewMenuEntry->OptionNumber
908 );
909 NewLoadContext->IsBootNext = TRUE;
910 CallbackData->BmmOldFakeNVData.BootNext = CurrentFakeNVMap->BootNext;
911 return Status;
912 }
913
914 /**
915 This function update the "BootOrder" EFI Variable based on
916 BMM Formset's NV map. It then refresh BootOptionMenu
917 with the new "BootOrder" list.
918
919 @param CallbackData The BMM context data.
920
921 @retval EFI_SUCCESS The function complete successfully.
922 @retval EFI_OUT_OF_RESOURCES Not enough memory to complete the function.
923 @return The EFI variable can not be saved. See gRT->SetVariable for detail return information.
924
925 **/
926 EFI_STATUS
927 Var_UpdateBootOrder (
928 IN BMM_CALLBACK_DATA *CallbackData
929 )
930 {
931 EFI_STATUS Status;
932 UINT16 Index;
933 UINT16 OrderIndex;
934 UINT16 *BootOrder;
935 UINTN BootOrderSize;
936 UINT16 OptionNumber;
937
938 //
939 // First check whether BootOrder is present in current configuration
940 //
941 GetEfiGlobalVariable2 (L"BootOrder", (VOID **) &BootOrder, &BootOrderSize);
942 if (BootOrder == NULL) {
943 return EFI_OUT_OF_RESOURCES;
944 }
945
946 ASSERT (BootOptionMenu.MenuNumber <= (sizeof (CallbackData->BmmFakeNvData.BootOptionOrder) / sizeof (CallbackData->BmmFakeNvData.BootOptionOrder[0])));
947
948 //
949 // OptionOrder is subset of BootOrder
950 //
951 for (OrderIndex = 0; (OrderIndex < BootOptionMenu.MenuNumber) && (CallbackData->BmmFakeNvData.BootOptionOrder[OrderIndex] != 0); OrderIndex++) {
952 for (Index = OrderIndex; Index < BootOrderSize / sizeof (UINT16); Index++) {
953 if ((BootOrder[Index] == (UINT16) (CallbackData->BmmFakeNvData.BootOptionOrder[OrderIndex] - 1)) && (OrderIndex != Index)) {
954 OptionNumber = BootOrder[Index];
955 CopyMem (&BootOrder[OrderIndex + 1], &BootOrder[OrderIndex], (Index - OrderIndex) * sizeof (UINT16));
956 BootOrder[OrderIndex] = OptionNumber;
957 }
958 }
959 }
960
961 Status = gRT->SetVariable (
962 L"BootOrder",
963 &gEfiGlobalVariableGuid,
964 VAR_FLAG,
965 BootOrderSize,
966 BootOrder
967 );
968 FreePool (BootOrder);
969
970 BOpt_FreeMenu (&BootOptionMenu);
971 BOpt_GetBootOptions (CallbackData);
972
973 return Status;
974
975 }
976
977 /**
978 This function update the "DriverOrder" EFI Variable based on
979 BMM Formset's NV map. It then refresh DriverOptionMenu
980 with the new "DriverOrder" list.
981
982 @param CallbackData The BMM context data.
983
984 @retval EFI_SUCCESS The function complete successfully.
985 @retval EFI_OUT_OF_RESOURCES Not enough memory to complete the function.
986 @return The EFI variable can not be saved. See gRT->SetVariable for detail return information.
987
988 **/
989 EFI_STATUS
990 Var_UpdateDriverOrder (
991 IN BMM_CALLBACK_DATA *CallbackData
992 )
993 {
994 EFI_STATUS Status;
995 UINT16 Index;
996 UINT16 *DriverOrderList;
997 UINT16 *NewDriverOrderList;
998 UINTN DriverOrderListSize;
999
1000 DriverOrderList = NULL;
1001 DriverOrderListSize = 0;
1002
1003 //
1004 // First check whether DriverOrder is present in current configuration
1005 //
1006 GetEfiGlobalVariable2 (L"DriverOrder", (VOID **) &DriverOrderList, &DriverOrderListSize);
1007 NewDriverOrderList = AllocateZeroPool (DriverOrderListSize);
1008
1009 if (NewDriverOrderList == NULL) {
1010 return EFI_OUT_OF_RESOURCES;
1011 }
1012 //
1013 // If exists, delete it to hold new DriverOrder
1014 //
1015 if (DriverOrderList != NULL) {
1016 EfiLibDeleteVariable (L"DriverOrder", &gEfiGlobalVariableGuid);
1017 FreePool (DriverOrderList);
1018 }
1019
1020 ASSERT (DriverOptionMenu.MenuNumber <= (sizeof (CallbackData->BmmFakeNvData.DriverOptionOrder) / sizeof (CallbackData->BmmFakeNvData.DriverOptionOrder[0])));
1021 for (Index = 0; Index < DriverOptionMenu.MenuNumber; Index++) {
1022 NewDriverOrderList[Index] = (UINT16) (CallbackData->BmmFakeNvData.DriverOptionOrder[Index] - 1);
1023 }
1024
1025 Status = gRT->SetVariable (
1026 L"DriverOrder",
1027 &gEfiGlobalVariableGuid,
1028 VAR_FLAG,
1029 DriverOrderListSize,
1030 NewDriverOrderList
1031 );
1032 if (EFI_ERROR (Status)) {
1033 return Status;
1034 }
1035
1036 BOpt_FreeMenu (&DriverOptionMenu);
1037 BOpt_GetDriverOptions (CallbackData);
1038 return EFI_SUCCESS;
1039 }
1040
1041 /**
1042 Update the Text Mode of Console.
1043
1044 @param CallbackData The context data for BMM.
1045
1046 @retval EFI_SUCCSS If the Text Mode of Console is updated.
1047 @return Other value if the Text Mode of Console is not updated.
1048
1049 **/
1050 EFI_STATUS
1051 Var_UpdateConMode (
1052 IN BMM_CALLBACK_DATA *CallbackData
1053 )
1054 {
1055 EFI_STATUS Status;
1056 UINTN Mode;
1057 CONSOLE_OUT_MODE ModeInfo;
1058
1059 Mode = CallbackData->BmmFakeNvData.ConsoleOutMode;
1060
1061 Status = gST->ConOut->QueryMode (gST->ConOut, Mode, &(ModeInfo.Column), &(ModeInfo.Row));
1062 if (!EFI_ERROR(Status)) {
1063 PcdSet32 (PcdSetupConOutColumn, (UINT32) ModeInfo.Column);
1064 PcdSet32 (PcdSetupConOutRow, (UINT32) ModeInfo.Row);
1065 }
1066
1067 return EFI_SUCCESS;
1068 }