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