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