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