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