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