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