]> git.proxmox.com Git - mirror_edk2.git/blame - EdkNt32Pkg/Dxe/PlatformBds/Generic/BootMaint/Variable.c
Fix the issues,
[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
a0a1e5aa 18 Variable operation that will be used by BootMaint\r
878ddf1f 19\r
20--*/\r
21\r
22#include "Generic/Bds.h"\r
a0a1e5aa 23#include "BootMaint.h"\r
878ddf1f 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
2bbf72b0 453 ASSERT (TerminalDevicePath != NULL);\r
878ddf1f 454 ChangeTerminalDevicePath (TerminalDevicePath, TRUE);\r
455 Temp = DevicePathToStr (TerminalDevicePath);\r
456 ConDevicePath = AppendDevicePathInstance (\r
457 ConDevicePath,\r
458 TerminalDevicePath\r
459 );\r
460 }\r
461 }\r
462\r
463 if (ConDevicePath) {\r
464 Status = gRT->SetVariable (\r
465 ConsoleName,\r
466 &gEfiGlobalVariableGuid,\r
467 VAR_FLAG,\r
468 GetDevicePathSize (ConDevicePath),\r
469 ConDevicePath\r
470 );\r
471 if (EFI_ERROR (Status)) {\r
472 return Status;\r
473 }\r
474 }\r
475\r
476 return EFI_SUCCESS;\r
477\r
478}\r
479\r
480EFI_STATUS\r
481Var_UpdateConsoleInpOption (\r
482 VOID\r
483 )\r
484{\r
485 return Var_UpdateConsoleOption (L"ConIn", &ConsoleInpMenu, FORM_CON_IN_ID);\r
486}\r
487\r
488EFI_STATUS\r
489Var_UpdateConsoleOutOption (\r
490 VOID\r
491 )\r
492{\r
493 return Var_UpdateConsoleOption (L"ConOut", &ConsoleOutMenu, FORM_CON_OUT_ID);\r
494}\r
495\r
496EFI_STATUS\r
497Var_UpdateErrorOutOption (\r
498 VOID\r
499 )\r
500{\r
501 return Var_UpdateConsoleOption (L"ErrOut", &ConsoleErrMenu, FORM_CON_ERR_ID);\r
502}\r
503\r
504EFI_STATUS\r
505Var_UpdateDriverOption (\r
506 IN BMM_CALLBACK_DATA *CallbackData,\r
507 IN EFI_HII_HANDLE HiiHandle,\r
508 IN UINT16 *DescriptionData,\r
509 IN UINT16 *OptionalData,\r
510 IN UINT8 ForceReconnect\r
511 )\r
512{\r
513 UINT16 Index;\r
514 UINT16 *DriverOrderList;\r
515 UINT16 *NewDriverOrderList;\r
516 UINT16 DriverString[12];\r
517 UINTN DriverOrderListSize;\r
518 VOID *Buffer;\r
519 UINTN BufferSize;\r
520 UINT8 *Ptr;\r
521 BM_MENU_ENTRY *NewMenuEntry;\r
522 BM_LOAD_CONTEXT *NewLoadContext;\r
523 BOOLEAN OptionalDataExist;\r
524 EFI_STATUS Status;\r
525\r
526 OptionalDataExist = FALSE;\r
527\r
528 Index = BOpt_GetDriverOptionNumber ();\r
529 UnicodeSPrint (\r
530 DriverString,\r
531 sizeof (DriverString),\r
532 L"Driver%04x",\r
533 Index\r
534 );\r
535\r
536 if (*DescriptionData == 0x0000) {\r
537 StrCpy (DescriptionData, DriverString);\r
538 }\r
539\r
540 BufferSize = sizeof (UINT32) + sizeof (UINT16) + StrSize (DescriptionData) + GetDevicePathSize (CallbackData->LoadContext->FilePathList);\r
541\r
542 if (*OptionalData != 0x0000) {\r
543 OptionalDataExist = TRUE;\r
544 BufferSize += StrSize (OptionalData);\r
545 }\r
546\r
547 Buffer = AllocateZeroPool (BufferSize);\r
548 if (NULL == Buffer) {\r
549 return EFI_OUT_OF_RESOURCES;\r
550 }\r
551\r
552 NewMenuEntry = BOpt_CreateMenuEntry (BM_LOAD_CONTEXT_SELECT);\r
553 if (NULL == NewMenuEntry) {\r
554 return EFI_OUT_OF_RESOURCES;\r
555 }\r
556\r
557 NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;\r
558 NewLoadContext->Deleted = FALSE;\r
559 NewLoadContext->LoadOptionSize = BufferSize;\r
560 Ptr = (UINT8 *) Buffer;\r
561 NewLoadContext->LoadOption = Ptr;\r
562 *((UINT32 *) Ptr) = LOAD_OPTION_ACTIVE | (ForceReconnect << 1);\r
563 NewLoadContext->Attributes = *((UINT32 *) Ptr);\r
564 NewLoadContext->IsActive = TRUE;\r
565 NewLoadContext->ForceReconnect = (BOOLEAN) (NewLoadContext->Attributes & LOAD_OPTION_FORCE_RECONNECT);\r
566\r
567 Ptr += sizeof (UINT32);\r
568 *((UINT16 *) Ptr) = (UINT16) GetDevicePathSize (CallbackData->LoadContext->FilePathList);\r
569 NewLoadContext->FilePathListLength = *((UINT16 *) Ptr);\r
570\r
571 Ptr += sizeof (UINT16);\r
572 CopyMem (\r
573 Ptr,\r
574 DescriptionData,\r
575 StrSize (DescriptionData)\r
576 );\r
577\r
578 NewLoadContext->Description = AllocateZeroPool (StrSize (DescriptionData));\r
579 ASSERT (NewLoadContext->Description != NULL);\r
580 NewMenuEntry->DisplayString = NewLoadContext->Description;\r
581 CopyMem (\r
582 NewLoadContext->Description,\r
583 (VOID *) Ptr,\r
584 StrSize (DescriptionData)\r
585 );\r
586\r
587 Ptr += StrSize (DescriptionData);\r
588 CopyMem (\r
589 Ptr,\r
590 CallbackData->LoadContext->FilePathList,\r
591 GetDevicePathSize (CallbackData->LoadContext->FilePathList)\r
592 );\r
593\r
594 NewLoadContext->FilePathList = AllocateZeroPool (GetDevicePathSize (CallbackData->LoadContext->FilePathList));\r
595 ASSERT (NewLoadContext->FilePathList != NULL);\r
596\r
597 CopyMem (\r
598 NewLoadContext->FilePathList,\r
599 (VOID *) Ptr,\r
600 GetDevicePathSize (CallbackData->LoadContext->FilePathList)\r
601 );\r
602\r
603 NewMenuEntry->HelpString = DevicePathToStr (NewLoadContext->FilePathList);\r
604 NewMenuEntry->OptionNumber = Index;\r
605 NewMenuEntry->DisplayStringToken = GetStringTokenFromDepository (\r
606 CallbackData,\r
607 DriverOptionStrDepository\r
608 );\r
609 CallbackData->Hii->NewString (\r
610 CallbackData->Hii,\r
611 NULL,\r
612 HiiHandle,\r
613 &NewMenuEntry->DisplayStringToken,\r
614 NewMenuEntry->DisplayString\r
615 );\r
616\r
617 NewMenuEntry->HelpStringToken = GetStringTokenFromDepository (\r
618 CallbackData,\r
619 DriverOptionHelpStrDepository\r
620 );\r
621 CallbackData->Hii->NewString (\r
622 CallbackData->Hii,\r
623 NULL,\r
624 HiiHandle,\r
625 &NewMenuEntry->HelpStringToken,\r
626 NewMenuEntry->HelpString\r
627 );\r
628\r
629 if (OptionalDataExist) {\r
630 Ptr += (UINT8) GetDevicePathSize (CallbackData->LoadContext->FilePathList);\r
631\r
632 CopyMem (\r
633 Ptr,\r
634 OptionalData,\r
635 StrSize (OptionalData)\r
636 );\r
637 }\r
638\r
639 Status = gRT->SetVariable (\r
640 DriverString,\r
641 &gEfiGlobalVariableGuid,\r
642 VAR_FLAG,\r
643 BufferSize,\r
644 Buffer\r
645 );\r
646 DriverOrderList = BdsLibGetVariableAndSize (\r
647 L"DriverOrder",\r
648 &gEfiGlobalVariableGuid,\r
649 &DriverOrderListSize\r
650 );\r
651 NewDriverOrderList = AllocateZeroPool (DriverOrderListSize + sizeof (UINT16));\r
652 ASSERT (NewDriverOrderList != NULL);\r
653 CopyMem (NewDriverOrderList, DriverOrderList, DriverOrderListSize);\r
654 NewDriverOrderList[DriverOrderListSize / sizeof (UINT16)] = Index;\r
655 if (DriverOrderList != NULL) {\r
656 EfiLibDeleteVariable (L"DriverOrder", &gEfiGlobalVariableGuid);\r
657 }\r
658\r
659 Status = gRT->SetVariable (\r
660 L"DriverOrder",\r
661 &gEfiGlobalVariableGuid,\r
662 VAR_FLAG,\r
663 DriverOrderListSize + sizeof (UINT16),\r
664 NewDriverOrderList\r
665 );\r
666 SafeFreePool (DriverOrderList);\r
667 DriverOrderList = NULL;\r
668 SafeFreePool (NewDriverOrderList);\r
669 NewDriverOrderList = NULL;\r
670 InsertTailList (&DriverOptionMenu.Head, &NewMenuEntry->Link);\r
671 DriverOptionMenu.MenuNumber++;\r
672\r
673 *DescriptionData = 0x0000;\r
674 *OptionalData = 0x0000;\r
675 return EFI_SUCCESS;\r
676}\r
677\r
678EFI_STATUS\r
679Var_UpdateBootOption (\r
680 IN BMM_CALLBACK_DATA *CallbackData,\r
681 IN FILE_EXPLORER_NV_DATA *NvRamMap\r
682 )\r
683{\r
684 UINT16 *BootOrderList;\r
685 UINT16 *NewBootOrderList;\r
686 UINTN BootOrderListSize;\r
687 UINT16 BootString[10];\r
688 VOID *Buffer;\r
689 UINTN BufferSize;\r
690 UINT8 *Ptr;\r
691 UINT16 Index;\r
692 BM_MENU_ENTRY *NewMenuEntry;\r
693 BM_LOAD_CONTEXT *NewLoadContext;\r
694 BOOLEAN OptionalDataExist;\r
695 EFI_STATUS Status;\r
696\r
697 OptionalDataExist = FALSE;\r
698\r
699 Index = BOpt_GetBootOptionNumber ();\r
700 UnicodeSPrint (BootString, sizeof (BootString), L"Boot%04x", Index);\r
701\r
702 if (NvRamMap->DescriptionData[0] == 0x0000) {\r
703 StrCpy (NvRamMap->DescriptionData, BootString);\r
704 }\r
705\r
706 BufferSize = sizeof (UINT32) + sizeof (UINT16) + StrSize (NvRamMap->DescriptionData) + GetDevicePathSize (CallbackData->LoadContext->FilePathList);\r
707\r
708 if (NvRamMap->OptionalData[0] != 0x0000) {\r
709 OptionalDataExist = TRUE;\r
710 BufferSize += StrSize (NvRamMap->OptionalData);\r
711 }\r
712\r
713 Buffer = AllocateZeroPool (BufferSize);\r
714 if (NULL == Buffer) {\r
715 return EFI_OUT_OF_RESOURCES;\r
716 }\r
717\r
718 NewMenuEntry = BOpt_CreateMenuEntry (BM_LOAD_CONTEXT_SELECT);\r
719 if (NULL == NewMenuEntry) {\r
720 return EFI_OUT_OF_RESOURCES;\r
721 }\r
722\r
723 NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;\r
724 NewLoadContext->Deleted = FALSE;\r
725 NewLoadContext->LoadOptionSize = BufferSize;\r
726 Ptr = (UINT8 *) Buffer;\r
727 NewLoadContext->LoadOption = Ptr;\r
728 *((UINT32 *) Ptr) = LOAD_OPTION_ACTIVE;\r
729 NewLoadContext->Attributes = *((UINT32 *) Ptr);\r
730 NewLoadContext->IsActive = TRUE;\r
731 NewLoadContext->ForceReconnect = (BOOLEAN) (NewLoadContext->Attributes & LOAD_OPTION_FORCE_RECONNECT);\r
732\r
733 Ptr += sizeof (UINT32);\r
734 *((UINT16 *) Ptr) = (UINT16) GetDevicePathSize (CallbackData->LoadContext->FilePathList);\r
735 NewLoadContext->FilePathListLength = *((UINT16 *) Ptr);\r
736 Ptr += sizeof (UINT16);\r
737\r
738 CopyMem (\r
739 Ptr,\r
740 NvRamMap->DescriptionData,\r
741 StrSize (NvRamMap->DescriptionData)\r
742 );\r
743\r
744 NewLoadContext->Description = AllocateZeroPool (StrSize (NvRamMap->DescriptionData));\r
745 ASSERT (NewLoadContext->Description != NULL);\r
746\r
747 NewMenuEntry->DisplayString = NewLoadContext->Description;\r
748 CopyMem (\r
749 NewLoadContext->Description,\r
750 (VOID *) Ptr,\r
751 StrSize (NvRamMap->DescriptionData)\r
752 );\r
753\r
754 Ptr += StrSize (NvRamMap->DescriptionData);\r
755 CopyMem (\r
756 Ptr,\r
757 CallbackData->LoadContext->FilePathList,\r
758 GetDevicePathSize (CallbackData->LoadContext->FilePathList)\r
759 );\r
760\r
761 NewLoadContext->FilePathList = AllocateZeroPool (GetDevicePathSize (CallbackData->LoadContext->FilePathList));\r
762 ASSERT (NewLoadContext->FilePathList != NULL);\r
763\r
764 CopyMem (\r
765 NewLoadContext->FilePathList,\r
766 (VOID *) Ptr,\r
767 GetDevicePathSize (CallbackData->LoadContext->FilePathList)\r
768 );\r
769\r
770 NewMenuEntry->HelpString = DevicePathToStr (NewLoadContext->FilePathList);\r
771 NewMenuEntry->OptionNumber = Index;\r
772 NewMenuEntry->DisplayStringToken = GetStringTokenFromDepository (\r
773 CallbackData,\r
774 BootOptionStrDepository\r
775 );\r
776 CallbackData->Hii->NewString (\r
777 CallbackData->Hii,\r
778 NULL,\r
779 CallbackData->FeHiiHandle,\r
780 &NewMenuEntry->DisplayStringToken,\r
781 NewMenuEntry->DisplayString\r
782 );\r
783\r
784 NewMenuEntry->HelpStringToken = GetStringTokenFromDepository (\r
785 CallbackData,\r
786 BootOptionHelpStrDepository\r
787 );\r
788\r
789 CallbackData->Hii->NewString (\r
790 CallbackData->Hii,\r
791 NULL,\r
792 CallbackData->FeHiiHandle,\r
793 &NewMenuEntry->HelpStringToken,\r
794 NewMenuEntry->HelpString\r
795 );\r
796\r
797 if (OptionalDataExist) {\r
798 Ptr += (UINT8) GetDevicePathSize (CallbackData->LoadContext->FilePathList);\r
799\r
800 CopyMem (Ptr, NvRamMap->OptionalData, StrSize (NvRamMap->OptionalData));\r
801 }\r
802\r
803 Status = gRT->SetVariable (\r
804 BootString,\r
805 &gEfiGlobalVariableGuid,\r
806 VAR_FLAG,\r
807 BufferSize,\r
808 Buffer\r
809 );\r
810\r
811 BootOrderList = BdsLibGetVariableAndSize (\r
812 L"BootOrder",\r
813 &gEfiGlobalVariableGuid,\r
814 &BootOrderListSize\r
815 );\r
816\r
817 NewBootOrderList = AllocateZeroPool (BootOrderListSize + sizeof (UINT16));\r
818 ASSERT (NewBootOrderList != NULL);\r
819 CopyMem (NewBootOrderList, BootOrderList, BootOrderListSize);\r
820 NewBootOrderList[BootOrderListSize / sizeof (UINT16)] = Index;\r
821\r
822 if (BootOrderList != NULL) {\r
823 EfiLibDeleteVariable (L"BootOrder", &gEfiGlobalVariableGuid);\r
824 }\r
825\r
826 Status = gRT->SetVariable (\r
827 L"BootOrder",\r
828 &gEfiGlobalVariableGuid,\r
829 VAR_FLAG,\r
830 BootOrderListSize + sizeof (UINT16),\r
831 NewBootOrderList\r
832 );\r
833\r
834 SafeFreePool (BootOrderList);\r
835 BootOrderList = NULL;\r
836 SafeFreePool (NewBootOrderList);\r
837 NewBootOrderList = NULL;\r
838 InsertTailList (&BootOptionMenu.Head, &NewMenuEntry->Link);\r
839 BootOptionMenu.MenuNumber++;\r
840\r
841 NvRamMap->DescriptionData[0] = 0x0000;\r
842 NvRamMap->OptionalData[0] = 0x0000;\r
843 return EFI_SUCCESS;\r
844}\r
845\r
846EFI_STATUS\r
847Var_UpdateBootNext (\r
848 IN BMM_CALLBACK_DATA *CallbackData\r
849 )\r
850{\r
851 BM_MENU_ENTRY *NewMenuEntry;\r
852 BM_LOAD_CONTEXT *NewLoadContext;\r
853 BMM_FAKE_NV_DATA *CurrentFakeNVMap;\r
854 UINT16 Index;\r
855 EFI_STATUS Status;\r
856\r
857 Status = EFI_SUCCESS;\r
858 CurrentFakeNVMap = CallbackData->BmmFakeNvData;\r
859 for (Index = 0; Index < BootOptionMenu.MenuNumber; Index++) {\r
860 NewMenuEntry = BOpt_GetMenuEntry (&BootOptionMenu, Index);\r
861 if (NULL == NewMenuEntry) {\r
862 return EFI_NOT_FOUND;\r
863 }\r
864\r
865 NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;\r
866 NewLoadContext->IsBootNext = FALSE;\r
867 }\r
868\r
869 if (CurrentFakeNVMap->BootNext == BootOptionMenu.MenuNumber) {\r
870 EfiLibDeleteVariable (L"BootNext", &gEfiGlobalVariableGuid);\r
871 return EFI_SUCCESS;\r
872 }\r
873\r
874 NewMenuEntry = BOpt_GetMenuEntry (\r
875 &BootOptionMenu,\r
876 CurrentFakeNVMap->BootNext\r
877 );\r
878 if (NULL == NewMenuEntry) {\r
879 return EFI_NOT_FOUND;\r
880 }\r
881\r
882 NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;\r
883 Status = gRT->SetVariable (\r
884 L"BootNext",\r
885 &gEfiGlobalVariableGuid,\r
886 VAR_FLAG,\r
887 sizeof (UINT16),\r
888 &NewMenuEntry->OptionNumber\r
889 );\r
890 NewLoadContext->IsBootNext = TRUE;\r
891 CallbackData->BmmOldFakeNVData.BootNext = CurrentFakeNVMap->BootNext;\r
892 return Status;\r
893}\r
894\r
895EFI_STATUS\r
896Var_UpdateBootOrder (\r
897 IN BMM_CALLBACK_DATA *CallbackData\r
898 )\r
899{\r
900 EFI_STATUS Status;\r
901 UINT16 Index;\r
902 UINT16 *BootOrderList;\r
903 UINT16 *NewBootOrderList;\r
904 UINTN BootOrderListSize;\r
905 UINT8 *Map;\r
906\r
907 BootOrderList = NULL;\r
908 BootOrderListSize = 0;\r
909\r
910 //\r
911 // First check whether BootOrder is present in current configuration\r
912 //\r
913 BootOrderList = BdsLibGetVariableAndSize (\r
914 L"BootOrder",\r
915 &gEfiGlobalVariableGuid,\r
916 &BootOrderListSize\r
917 );\r
918\r
919 NewBootOrderList = AllocateZeroPool (BootOrderListSize);\r
920 if (!NewBootOrderList) {\r
921 return EFI_OUT_OF_RESOURCES;\r
922 }\r
923\r
924 Map = AllocateZeroPool (BootOrderListSize / sizeof (UINT16));\r
925 if (!Map) {\r
926 return EFI_OUT_OF_RESOURCES;\r
927 }\r
928 //\r
929 // If exists, delete it to hold new BootOrder\r
930 //\r
931 if (BootOrderList) {\r
932 EfiLibDeleteVariable (L"BootOrder", &gEfiGlobalVariableGuid);\r
933 }\r
934\r
935 for (Index = 0; Index < BootOptionMenu.MenuNumber; Index++) {\r
936 NewBootOrderList[Index] = CallbackData->BmmFakeNvData->OptionOrder[Index] - 1;\r
937 }\r
938\r
939 Status = gRT->SetVariable (\r
940 L"BootOrder",\r
941 &gEfiGlobalVariableGuid,\r
942 VAR_FLAG,\r
943 BootOrderListSize,\r
944 NewBootOrderList\r
945 );\r
946 SafeFreePool (BootOrderList);\r
947 SafeFreePool (NewBootOrderList);\r
948 SafeFreePool (Map);\r
949 if (EFI_ERROR (Status)) {\r
950 return Status;\r
951 }\r
952\r
953 BOpt_FreeMenu (&BootOptionMenu);\r
954 BOpt_GetBootOptions (CallbackData);\r
955\r
956 return EFI_SUCCESS;\r
957\r
958}\r
959\r
960EFI_STATUS\r
961Var_UpdateDriverOrder (\r
962 IN BMM_CALLBACK_DATA *CallbackData\r
963 )\r
964{\r
965 EFI_STATUS Status;\r
966 UINT16 Index;\r
967 UINT16 *DriverOrderList;\r
968 UINT16 *NewDriverOrderList;\r
969 UINTN DriverOrderListSize;\r
970\r
971 DriverOrderList = NULL;\r
972 DriverOrderListSize = 0;\r
973\r
974 //\r
975 // First check whether DriverOrder is present in current configuration\r
976 //\r
977 DriverOrderList = BdsLibGetVariableAndSize (\r
978 L"DriverOrder",\r
979 &gEfiGlobalVariableGuid,\r
980 &DriverOrderListSize\r
981 );\r
982\r
983 NewDriverOrderList = AllocateZeroPool (DriverOrderListSize);\r
984\r
985 if (!NewDriverOrderList) {\r
986 return EFI_OUT_OF_RESOURCES;\r
987 }\r
988 //\r
989 // If exists, delete it to hold new DriverOrder\r
990 //\r
991 if (DriverOrderList) {\r
992 EfiLibDeleteVariable (L"DriverOrder", &gEfiGlobalVariableGuid);\r
993 }\r
994\r
995 for (Index = 0; Index < DriverOrderListSize; Index++) {\r
996 NewDriverOrderList[Index] = CallbackData->BmmFakeNvData->OptionOrder[Index] - 1;\r
997 }\r
998\r
999 Status = gRT->SetVariable (\r
1000 L"DriverOrder",\r
1001 &gEfiGlobalVariableGuid,\r
1002 VAR_FLAG,\r
1003 DriverOrderListSize,\r
1004 NewDriverOrderList\r
1005 );\r
1006 if (EFI_ERROR (Status)) {\r
1007 return Status;\r
1008 }\r
1009\r
1010 SafeFreePool (DriverOrderList);\r
1011\r
1012 BOpt_FreeMenu (&DriverOptionMenu);\r
1013 BOpt_GetDriverOptions (CallbackData);\r
1014 return EFI_SUCCESS;\r
1015}\r
1016\r
1017EFI_STATUS\r
1018Var_UpdateBBSOption (\r
1019 IN BMM_CALLBACK_DATA *CallbackData\r
1020 )\r
1021{\r
1022 UINTN Index;\r
1023 UINTN Index2;\r
1024 VOID *BootOptionVar;\r
1025 CHAR16 VarName[100];\r
1026 UINTN OptionSize;\r
1027 UINT16 FilePathSize;\r
1028 UINT8 *Ptr;\r
1029 EFI_STATUS Status;\r
1030 CHAR16 DescString[100];\r
1031 UINTN NewOptionSize;\r
1032 UINT8 *NewOptionPtr;\r
1033 UINT8 *TempPtr;\r
1034 UINT32 *Attribute;\r
1035\r
1036 BM_MENU_OPTION *OptionMenu;\r
1037 BM_LEGACY_DEVICE_CONTEXT *LegacyDeviceContext;\r
1038 UINT8 *LegacyDev;\r
1039 UINT8 *VarData;\r
1040 UINTN VarSize;\r
1041 BM_MENU_ENTRY *NewMenuEntry;\r
1042 BM_LEGACY_DEV_ORDER_CONTEXT *DevOrder;\r
1043 UINT8 *OriginalPtr;\r
1044 UINT8 *DisMap;\r
1045 UINTN Pos;\r
1046 UINTN Bit;\r
1047 UINT16 *NewOrder;\r
1048 UINT16 Tmp;\r
1049\r
1050 LegacyDeviceContext = NULL;\r
1051 DisMap = NULL;\r
1052 NewOrder = NULL;\r
1053\r
1054 if (FORM_SET_FD_ORDER_ID == CallbackData->BmmPreviousPageId) {\r
1055 OptionMenu = (BM_MENU_OPTION *) &LegacyFDMenu;\r
1056 LegacyDev = CallbackData->BmmFakeNvData->LegacyFD;\r
1057 CallbackData->BbsType = BBS_FLOPPY;\r
1058 } else {\r
1059 if (FORM_SET_HD_ORDER_ID == CallbackData->BmmPreviousPageId) {\r
1060 OptionMenu = (BM_MENU_OPTION *) &LegacyHDMenu;\r
1061 LegacyDev = CallbackData->BmmFakeNvData->LegacyHD;\r
1062 CallbackData->BbsType = BBS_HARDDISK;\r
1063 } else {\r
1064 if (FORM_SET_CD_ORDER_ID == CallbackData->BmmPreviousPageId) {\r
1065 OptionMenu = (BM_MENU_OPTION *) &LegacyCDMenu;\r
1066 LegacyDev = CallbackData->BmmFakeNvData->LegacyCD;\r
1067 CallbackData->BbsType = BBS_CDROM;\r
1068 } else {\r
1069 if (FORM_SET_NET_ORDER_ID == CallbackData->BmmPreviousPageId) {\r
1070 OptionMenu = (BM_MENU_OPTION *) &LegacyNETMenu;\r
1071 LegacyDev = CallbackData->BmmFakeNvData->LegacyNET;\r
1072 CallbackData->BbsType = BBS_EMBED_NETWORK;\r
1073 } else {\r
1074 OptionMenu = (BM_MENU_OPTION *) &LegacyBEVMenu;\r
1075 LegacyDev = CallbackData->BmmFakeNvData->LegacyBEV;\r
1076 CallbackData->BbsType = BBS_BEV_DEVICE;\r
1077 }\r
1078 }\r
1079 }\r
1080 }\r
1081\r
1082 DisMap = CallbackData->BmmOldFakeNVData.DisableMap;\r
1083 Status = EFI_SUCCESS;\r
1084\r
1085 //\r
1086 // Find the first device's context\r
1087 // If all devices are disabled( 0xFF == LegacyDev[0]), LegacyDeviceContext can be set to any VariableContext\r
1088 // because we just use it to fill the desc string, and user can not see the string in UI\r
1089 //\r
1090 for (Index = 0; Index < OptionMenu->MenuNumber; Index++) {\r
1091 NewMenuEntry = BOpt_GetMenuEntry (OptionMenu, Index);\r
1092 LegacyDeviceContext = (BM_LEGACY_DEVICE_CONTEXT *) NewMenuEntry->VariableContext;\r
1093 if (0xFF != LegacyDev[0] && LegacyDev[0] == LegacyDeviceContext->Index) {\r
1094 DEBUG ((EFI_D_ERROR, "DescStr: %s\n", LegacyDeviceContext->Description));\r
1095 break;\r
1096 }\r
1097 }\r
1098 //\r
1099 // Update the Variable "LegacyDevOrder"\r
1100 //\r
1101 VarData = (UINT8 *) BdsLibGetVariableAndSize (\r
1102 VarLegacyDevOrder,\r
1103 &EfiLegacyDevOrderGuid,\r
1104 &VarSize\r
1105 );\r
1106\r
1107 if (NULL == VarData) {\r
1108 return EFI_NOT_FOUND;\r
1109 }\r
1110\r
1111 OriginalPtr = VarData;\r
1112 DevOrder = (BM_LEGACY_DEV_ORDER_CONTEXT *) VarData;\r
1113\r
1114 while (VarData < VarData + VarSize) {\r
1115 if (DevOrder->BbsType == CallbackData->BbsType) {\r
1116 break;\r
1117 }\r
1118\r
1119 VarData += sizeof (BBS_TYPE);\r
1120 VarData += *(UINT16 *) VarData;\r
1121 DevOrder = (BM_LEGACY_DEV_ORDER_CONTEXT *) VarData;\r
1122 }\r
1123\r
1124 if (VarData >= VarData + VarSize) {\r
1125 SafeFreePool (OriginalPtr);\r
1126 return EFI_NOT_FOUND;\r
1127 }\r
1128\r
1129 NewOrder = (UINT16 *) AllocateZeroPool (DevOrder->Length - sizeof (UINT16));\r
1130 if (NULL == NewOrder) {\r
1131 SafeFreePool (VarData);\r
1132 return EFI_OUT_OF_RESOURCES;\r
1133 }\r
1134\r
1135 for (Index = 0; Index < OptionMenu->MenuNumber; Index++) {\r
1136 if (0xFF == LegacyDev[Index]) {\r
1137 break;\r
1138 }\r
1139\r
1140 NewOrder[Index] = LegacyDev[Index];\r
1141 }\r
1142 //\r
1143 // Only the enable/disable state of each boot device with same device type can be changed,\r
1144 // so we can count on the index information in DevOrder.\r
1145 // DisMap bit array is the only reliable source to check a device's en/dis state,\r
1146 // so we use DisMap to set en/dis state of each item in NewOrder array\r
1147 //\r
1148 for (Index2 = 0; Index2 < OptionMenu->MenuNumber; Index2++) {\r
1149 Tmp = *(UINT16 *) ((UINT8 *) DevOrder + sizeof (BBS_TYPE) + sizeof (UINT16) + Index2 * sizeof (UINT16));\r
1150 Tmp &= 0xFF;\r
1151 Pos = Tmp / 8;\r
1152 Bit = 7 - (Tmp % 8);\r
1153 if (DisMap[Pos] & (1 << Bit)) {\r
1154 NewOrder[Index] = (UINT16) (0xFF00 | Tmp);\r
1155 Index++;\r
1156 }\r
1157 }\r
1158\r
1159 CopyMem (\r
1160 (UINT8 *) DevOrder + sizeof (BBS_TYPE) + sizeof (UINT16),\r
1161 NewOrder,\r
1162 DevOrder->Length - sizeof (UINT16)\r
1163 );\r
1164 SafeFreePool (NewOrder);\r
1165\r
1166 Status = gRT->SetVariable (\r
1167 VarLegacyDevOrder,\r
1168 &EfiLegacyDevOrderGuid,\r
1169 VAR_FLAG,\r
1170 VarSize,\r
1171 OriginalPtr\r
1172 );\r
1173\r
1174 SafeFreePool (OriginalPtr);\r
1175\r
1176 //\r
1177 // Update Optional Data of Boot####\r
1178 //\r
1179 BootOptionVar = GetLegacyBootOptionVar (CallbackData->BbsType, &Index, &OptionSize);\r
1180\r
1181 if (NULL != BootOptionVar) {\r
1182 CopyMem (\r
1183 DescString,\r
1184 LegacyDeviceContext->Description,\r
1185 StrSize (LegacyDeviceContext->Description)\r
1186 );\r
1187\r
1188 NewOptionSize = sizeof (UINT32) + sizeof (UINT16) + StrSize (DescString) + sizeof (BBS_TABLE) + sizeof (UINT16);\r
1189\r
1190 UnicodeSPrint (VarName, 100, L"Boot%04x", Index);\r
1191\r
1192 Ptr = BootOptionVar;\r
1193\r
1194 Attribute = (UINT32 *) Ptr;\r
1195 *Attribute |= LOAD_OPTION_ACTIVE;\r
1196 if (0xFF == LegacyDev[0]) {\r
1197 //\r
1198 // Disable this legacy boot option\r
1199 //\r
1200 *Attribute &= ~LOAD_OPTION_ACTIVE;\r
1201 }\r
1202\r
1203 Ptr += sizeof (UINT32);\r
1204\r
1205 FilePathSize = *(UINT16 *) Ptr;\r
1206 Ptr += sizeof (UINT16);\r
1207\r
1208 NewOptionSize += FilePathSize;\r
1209\r
1210 NewOptionPtr = AllocateZeroPool (NewOptionSize);\r
1211 if (NULL == NewOptionPtr) {\r
1212 return EFI_OUT_OF_RESOURCES;\r
1213 }\r
1214\r
1215 TempPtr = NewOptionPtr;\r
1216\r
1217 //\r
1218 // Copy previous option data to new option except the description string\r
1219 //\r
1220 CopyMem (\r
1221 TempPtr,\r
1222 BootOptionVar,\r
1223 sizeof (UINT32) + sizeof (UINT16)\r
1224 );\r
1225\r
1226 TempPtr += (sizeof (UINT32) + sizeof (UINT16));\r
1227\r
1228 CopyMem (\r
1229 TempPtr,\r
1230 DescString,\r
1231 StrSize (DescString)\r
1232 );\r
1233\r
1234 TempPtr += StrSize (DescString);\r
1235\r
1236 //\r
1237 // Description = (CHAR16 *)Ptr;\r
1238 //\r
1239 Ptr += StrSize ((CHAR16 *) Ptr);\r
1240\r
1241 CopyMem (\r
1242 TempPtr,\r
1243 Ptr,\r
1244 FilePathSize\r
1245 );\r
1246\r
1247 TempPtr += FilePathSize;\r
1248\r
1249 //\r
1250 // DevicePath = (EFI_DEVICE_PATH_PROTOCOL *)Ptr;\r
1251 //\r
1252 Ptr += FilePathSize;\r
1253\r
1254 //\r
1255 // Now Ptr point to optional data, i.e. Bbs Table\r
1256 //\r
1257 CopyMem (\r
1258 TempPtr,\r
1259 LegacyDeviceContext->BbsTable,\r
1260 sizeof (BBS_TABLE)\r
1261 );\r
1262\r
1263 TempPtr += sizeof (BBS_TABLE);\r
1264 *((UINT16 *) TempPtr) = (UINT16) LegacyDeviceContext->Index;\r
1265\r
1266 Status = gRT->SetVariable (\r
1267 VarName,\r
1268 &gEfiGlobalVariableGuid,\r
1269 VAR_FLAG,\r
1270 NewOptionSize,\r
1271 NewOptionPtr\r
1272 );\r
1273\r
1274 SafeFreePool (NewOptionPtr);\r
1275 SafeFreePool (BootOptionVar);\r
1276 }\r
1277\r
1278 BOpt_GetBootOptions (CallbackData);\r
1279 return Status;\r
1280}\r