]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - MdeModulePkg/Library/BootMaintenanceManagerUiLib/Variable.c
MdeModulePkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / MdeModulePkg / Library / BootMaintenanceManagerUiLib / Variable.c
... / ...
CommitLineData
1/** @file\r
2Variable operation that will be used by bootmaint\r
3\r
4Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>\r
5SPDX-License-Identifier: BSD-2-Clause-Patent\r
6\r
7**/\r
8\r
9#include "BootMaintenanceManager.h"\r
10\r
11/**\r
12 Delete Boot Option that represent a Deleted state in BootOptionMenu.\r
13\r
14 @retval EFI_SUCCESS If all boot load option EFI Variables corresponding to\r
15 BM_LOAD_CONTEXT marked for deletion is deleted.\r
16 @retval EFI_NOT_FOUND If can not find the boot option want to be deleted.\r
17 @return Others If failed to update the "BootOrder" variable after deletion.\r
18\r
19**/\r
20EFI_STATUS\r
21Var_DelBootOption (\r
22 VOID\r
23 )\r
24{\r
25 BM_MENU_ENTRY *NewMenuEntry;\r
26 BM_LOAD_CONTEXT *NewLoadContext;\r
27 EFI_STATUS Status;\r
28 UINTN Index;\r
29 UINTN Index2;\r
30\r
31 Index2 = 0;\r
32 for (Index = 0; Index < BootOptionMenu.MenuNumber; Index++) {\r
33 NewMenuEntry = BOpt_GetMenuEntry (&BootOptionMenu, (Index - Index2));\r
34 if (NULL == NewMenuEntry) {\r
35 return EFI_NOT_FOUND;\r
36 }\r
37\r
38 NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;\r
39 if (!NewLoadContext->Deleted) {\r
40 continue;\r
41 }\r
42\r
43 Status = EfiBootManagerDeleteLoadOptionVariable (NewMenuEntry->OptionNumber,LoadOptionTypeBoot);\r
44 if (EFI_ERROR (Status)) {\r
45 return Status;\r
46 }\r
47 Index2++;\r
48 //\r
49 // If current Load Option is the same as BootNext,\r
50 // must delete BootNext in order to make sure\r
51 // there will be no panic on next boot\r
52 //\r
53 if (NewLoadContext->IsBootNext) {\r
54 EfiLibDeleteVariable (L"BootNext", &gEfiGlobalVariableGuid);\r
55 }\r
56\r
57 RemoveEntryList (&NewMenuEntry->Link);\r
58 BOpt_DestroyMenuEntry (NewMenuEntry);\r
59 NewMenuEntry = NULL;\r
60 }\r
61\r
62 BootOptionMenu.MenuNumber -= Index2;\r
63\r
64 return EFI_SUCCESS;\r
65}\r
66\r
67/**\r
68 Delete Load Option that represent a Deleted state in DriverOptionMenu.\r
69\r
70 @retval EFI_SUCCESS Load Option is successfully updated.\r
71 @retval EFI_NOT_FOUND Fail to find the driver option want to be deleted.\r
72 @return Other value than EFI_SUCCESS if failed to update "Driver Order" EFI\r
73 Variable.\r
74\r
75**/\r
76EFI_STATUS\r
77Var_DelDriverOption (\r
78 VOID\r
79 )\r
80{\r
81 BM_MENU_ENTRY *NewMenuEntry;\r
82 BM_LOAD_CONTEXT *NewLoadContext;\r
83 EFI_STATUS Status;\r
84 UINTN Index;\r
85 UINTN Index2;\r
86\r
87 Index2 = 0;\r
88 for (Index = 0; Index < DriverOptionMenu.MenuNumber; Index++) {\r
89 NewMenuEntry = BOpt_GetMenuEntry (&DriverOptionMenu, (Index - Index2));\r
90 if (NULL == NewMenuEntry) {\r
91 return EFI_NOT_FOUND;\r
92 }\r
93\r
94 NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;\r
95 if (!NewLoadContext->Deleted) {\r
96 continue;\r
97 }\r
98 Status = EfiBootManagerDeleteLoadOptionVariable (NewMenuEntry->OptionNumber,LoadOptionTypeDriver);\r
99 if (EFI_ERROR (Status)) {\r
100 return Status;\r
101 }\r
102\r
103 Index2++;\r
104\r
105 RemoveEntryList (&NewMenuEntry->Link);\r
106 BOpt_DestroyMenuEntry (NewMenuEntry);\r
107 NewMenuEntry = NULL;\r
108 }\r
109\r
110 DriverOptionMenu.MenuNumber -= Index2;\r
111\r
112 return EFI_SUCCESS;\r
113}\r
114\r
115/**\r
116 This function delete and build multi-instance device path for\r
117 specified type of console device.\r
118\r
119 This function clear the EFI variable defined by ConsoleName and\r
120 gEfiGlobalVariableGuid. It then build the multi-instance device\r
121 path by appending the device path of the Console (In/Out/Err) instance\r
122 in ConsoleMenu. Then it scan all corresponding console device by\r
123 scanning Terminal (built from device supporting Serial I/O instances)\r
124 devices in TerminalMenu. At last, it save a EFI variable specifed\r
125 by ConsoleName and gEfiGlobalVariableGuid.\r
126\r
127 @param ConsoleName The name for the console device type. They are\r
128 usually "ConIn", "ConOut" and "ErrOut".\r
129 @param ConsoleMenu The console memu which is a list of console devices.\r
130 @param UpdatePageId The flag specifying which type of console device\r
131 to be processed.\r
132\r
133 @retval EFI_SUCCESS The function complete successfully.\r
134 @return The EFI variable can not be saved. See gRT->SetVariable for detail return information.\r
135\r
136**/\r
137EFI_STATUS\r
138Var_UpdateConsoleOption (\r
139 IN UINT16 *ConsoleName,\r
140 IN BM_MENU_OPTION *ConsoleMenu,\r
141 IN UINT16 UpdatePageId\r
142 )\r
143{\r
144 EFI_DEVICE_PATH_PROTOCOL *ConDevicePath;\r
145 BM_MENU_ENTRY *NewMenuEntry;\r
146 BM_CONSOLE_CONTEXT *NewConsoleContext;\r
147 BM_TERMINAL_CONTEXT *NewTerminalContext;\r
148 EFI_STATUS Status;\r
149 VENDOR_DEVICE_PATH Vendor;\r
150 EFI_DEVICE_PATH_PROTOCOL *TerminalDevicePath;\r
151 UINTN Index;\r
152\r
153 GetEfiGlobalVariable2 (ConsoleName, (VOID**)&ConDevicePath, NULL);\r
154 if (ConDevicePath != NULL) {\r
155 EfiLibDeleteVariable (ConsoleName, &gEfiGlobalVariableGuid);\r
156 FreePool (ConDevicePath);\r
157 ConDevicePath = NULL;\r
158 };\r
159\r
160 //\r
161 // First add all console input device from console input menu\r
162 //\r
163 for (Index = 0; Index < ConsoleMenu->MenuNumber; Index++) {\r
164 NewMenuEntry = BOpt_GetMenuEntry (ConsoleMenu, Index);\r
165\r
166 NewConsoleContext = (BM_CONSOLE_CONTEXT *) NewMenuEntry->VariableContext;\r
167 if (NewConsoleContext->IsActive) {\r
168 ConDevicePath = AppendDevicePathInstance (\r
169 ConDevicePath,\r
170 NewConsoleContext->DevicePath\r
171 );\r
172 }\r
173 }\r
174\r
175 for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {\r
176 NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);\r
177\r
178 NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;\r
179 if (((NewTerminalContext->IsConIn != 0) && (UpdatePageId == FORM_CON_IN_ID)) ||\r
180 ((NewTerminalContext->IsConOut != 0) && (UpdatePageId == FORM_CON_OUT_ID)) ||\r
181 ((NewTerminalContext->IsStdErr != 0) && (UpdatePageId == FORM_CON_ERR_ID))\r
182 ) {\r
183 Vendor.Header.Type = MESSAGING_DEVICE_PATH;\r
184 Vendor.Header.SubType = MSG_VENDOR_DP;\r
185\r
186 ASSERT (NewTerminalContext->TerminalType < (ARRAY_SIZE (TerminalTypeGuid)));\r
187 CopyMem (\r
188 &Vendor.Guid,\r
189 &TerminalTypeGuid[NewTerminalContext->TerminalType],\r
190 sizeof (EFI_GUID)\r
191 );\r
192 SetDevicePathNodeLength (&Vendor.Header, sizeof (VENDOR_DEVICE_PATH));\r
193 TerminalDevicePath = AppendDevicePathNode (\r
194 NewTerminalContext->DevicePath,\r
195 (EFI_DEVICE_PATH_PROTOCOL *) &Vendor\r
196 );\r
197 ASSERT (TerminalDevicePath != NULL);\r
198 ChangeTerminalDevicePath (TerminalDevicePath, TRUE);\r
199 ConDevicePath = AppendDevicePathInstance (\r
200 ConDevicePath,\r
201 TerminalDevicePath\r
202 );\r
203 }\r
204 }\r
205\r
206 if (ConDevicePath != NULL) {\r
207 Status = gRT->SetVariable (\r
208 ConsoleName,\r
209 &gEfiGlobalVariableGuid,\r
210 VAR_FLAG,\r
211 GetDevicePathSize (ConDevicePath),\r
212 ConDevicePath\r
213 );\r
214 if (EFI_ERROR (Status)) {\r
215 return Status;\r
216 }\r
217 }\r
218\r
219 return EFI_SUCCESS;\r
220\r
221}\r
222\r
223/**\r
224 This function delete and build multi-instance device path ConIn\r
225 console device.\r
226\r
227 @retval EFI_SUCCESS The function complete successfully.\r
228 @return The EFI variable can not be saved. See gRT->SetVariable for detail return information.\r
229**/\r
230EFI_STATUS\r
231Var_UpdateConsoleInpOption (\r
232 VOID\r
233 )\r
234{\r
235 return Var_UpdateConsoleOption (L"ConIn", &ConsoleInpMenu, FORM_CON_IN_ID);\r
236}\r
237\r
238/**\r
239 This function delete and build multi-instance device path ConOut\r
240 console device.\r
241\r
242 @retval EFI_SUCCESS The function complete successfully.\r
243 @return The EFI variable can not be saved. See gRT->SetVariable for detail return information.\r
244**/\r
245EFI_STATUS\r
246Var_UpdateConsoleOutOption (\r
247 VOID\r
248 )\r
249{\r
250 return Var_UpdateConsoleOption (L"ConOut", &ConsoleOutMenu, FORM_CON_OUT_ID);\r
251}\r
252\r
253/**\r
254 This function delete and build multi-instance device path ErrOut\r
255 console device.\r
256\r
257 @retval EFI_SUCCESS The function complete successfully.\r
258 @return The EFI variable can not be saved. See gRT->SetVariable for detail return information.\r
259**/\r
260EFI_STATUS\r
261Var_UpdateErrorOutOption (\r
262 VOID\r
263 )\r
264{\r
265 return Var_UpdateConsoleOption (L"ErrOut", &ConsoleErrMenu, FORM_CON_ERR_ID);\r
266}\r
267\r
268/**\r
269 This function create a currently loaded Drive Option from\r
270 the BMM. It then appends this Driver Option to the end of\r
271 the "DriverOrder" list. It append this Driver Opotion to the end\r
272 of DriverOptionMenu.\r
273\r
274 @param CallbackData The BMM context data.\r
275 @param HiiHandle The HII handle associated with the BMM formset.\r
276 @param DescriptionData The description of this driver option.\r
277 @param OptionalData The optional load option.\r
278 @param ForceReconnect If to force reconnect.\r
279\r
280 @retval other Contain some errors when excuting this function.See function\r
281 EfiBootManagerInitializeLoadOption/EfiBootManagerAddLoadOptionVariabl\r
282 for detail return information.\r
283 @retval EFI_SUCCESS If function completes successfully.\r
284\r
285**/\r
286EFI_STATUS\r
287Var_UpdateDriverOption (\r
288 IN BMM_CALLBACK_DATA *CallbackData,\r
289 IN EFI_HII_HANDLE HiiHandle,\r
290 IN UINT16 *DescriptionData,\r
291 IN UINT16 *OptionalData,\r
292 IN UINT8 ForceReconnect\r
293 )\r
294{\r
295 UINT16 Index;\r
296 UINT16 DriverString[12];\r
297 BM_MENU_ENTRY *NewMenuEntry;\r
298 BM_LOAD_CONTEXT *NewLoadContext;\r
299 BOOLEAN OptionalDataExist;\r
300 EFI_STATUS Status;\r
301 EFI_BOOT_MANAGER_LOAD_OPTION LoadOption;\r
302 UINT8 *OptionalDesData;\r
303 UINT32 OptionalDataSize;\r
304\r
305 OptionalDataExist = FALSE;\r
306 OptionalDesData = NULL;\r
307 OptionalDataSize = 0;\r
308\r
309 Index = BOpt_GetDriverOptionNumber ();\r
310 UnicodeSPrint (\r
311 DriverString,\r
312 sizeof (DriverString),\r
313 L"Driver%04x",\r
314 Index\r
315 );\r
316\r
317 if (*DescriptionData == 0x0000) {\r
318 StrCpyS (DescriptionData, MAX_MENU_NUMBER, DriverString);\r
319 }\r
320\r
321 if (*OptionalData != 0x0000) {\r
322 OptionalDataExist = TRUE;\r
323 OptionalDesData = (UINT8 *)OptionalData;\r
324 OptionalDataSize = (UINT32)StrSize (OptionalData);\r
325 }\r
326\r
327 NewMenuEntry = BOpt_CreateMenuEntry (BM_LOAD_CONTEXT_SELECT);\r
328 if (NULL == NewMenuEntry) {\r
329 return EFI_OUT_OF_RESOURCES;\r
330 }\r
331\r
332 Status = EfiBootManagerInitializeLoadOption (\r
333 &LoadOption,\r
334 Index,\r
335 LoadOptionTypeDriver,\r
336 LOAD_OPTION_ACTIVE | (ForceReconnect << 1),\r
337 DescriptionData,\r
338 CallbackData->LoadContext->FilePathList,\r
339 OptionalDesData,\r
340 OptionalDataSize\r
341 );\r
342 if (EFI_ERROR (Status)){\r
343 return Status;\r
344 }\r
345\r
346 Status = EfiBootManagerAddLoadOptionVariable (&LoadOption,(UINTN) -1 );\r
347 if (EFI_ERROR (Status)) {\r
348 EfiBootManagerFreeLoadOption(&LoadOption);\r
349 return Status;\r
350 }\r
351\r
352 NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;\r
353 NewLoadContext->Deleted = FALSE;\r
354 NewLoadContext->Attributes = LoadOption.Attributes;\r
355 NewLoadContext->FilePathListLength = (UINT16)GetDevicePathSize (LoadOption.FilePath);\r
356\r
357 NewLoadContext->Description = AllocateZeroPool (StrSize (DescriptionData));\r
358 ASSERT (NewLoadContext->Description != NULL);\r
359 NewMenuEntry->DisplayString = NewLoadContext->Description;\r
360 CopyMem (\r
361 NewLoadContext->Description,\r
362 LoadOption.Description,\r
363 StrSize (DescriptionData)\r
364 );\r
365\r
366 NewLoadContext->FilePathList = AllocateZeroPool (GetDevicePathSize (CallbackData->LoadContext->FilePathList));\r
367 ASSERT (NewLoadContext->FilePathList != NULL);\r
368 CopyMem (\r
369 NewLoadContext->FilePathList,\r
370 LoadOption.FilePath,\r
371 GetDevicePathSize (CallbackData->LoadContext->FilePathList)\r
372 );\r
373\r
374 NewMenuEntry->HelpString = UiDevicePathToStr (NewLoadContext->FilePathList);\r
375 NewMenuEntry->OptionNumber = Index;\r
376 NewMenuEntry->DisplayStringToken = HiiSetString (HiiHandle, 0, NewMenuEntry->DisplayString, NULL);\r
377 NewMenuEntry->HelpStringToken = HiiSetString (HiiHandle, 0, NewMenuEntry->HelpString, NULL);\r
378\r
379 if (OptionalDataExist) {\r
380 NewLoadContext->OptionalData = AllocateZeroPool (LoadOption.OptionalDataSize);\r
381 ASSERT (NewLoadContext->OptionalData != NULL);\r
382 CopyMem (\r
383 NewLoadContext->OptionalData,\r
384 LoadOption.OptionalData,\r
385 LoadOption.OptionalDataSize\r
386 );\r
387 }\r
388\r
389 InsertTailList (&DriverOptionMenu.Head, &NewMenuEntry->Link);\r
390 DriverOptionMenu.MenuNumber++;\r
391\r
392 EfiBootManagerFreeLoadOption(&LoadOption);\r
393\r
394 return EFI_SUCCESS;\r
395}\r
396\r
397/**\r
398 This function create a currently loaded Boot Option from\r
399 the BMM. It then appends this Boot Option to the end of\r
400 the "BootOrder" list. It also append this Boot Opotion to the end\r
401 of BootOptionMenu.\r
402\r
403 @param CallbackData The BMM context data.\r
404\r
405 @retval other Contain some errors when excuting this function. See function\r
406 EfiBootManagerInitializeLoadOption/EfiBootManagerAddLoadOptionVariabl\r
407 for detail return information.\r
408 @retval EFI_SUCCESS If function completes successfully.\r
409\r
410**/\r
411EFI_STATUS\r
412Var_UpdateBootOption (\r
413 IN BMM_CALLBACK_DATA *CallbackData\r
414 )\r
415{\r
416 UINT16 BootString[10];\r
417 UINT16 Index;\r
418 BM_MENU_ENTRY *NewMenuEntry;\r
419 BM_LOAD_CONTEXT *NewLoadContext;\r
420 BOOLEAN OptionalDataExist;\r
421 EFI_STATUS Status;\r
422 BMM_FAKE_NV_DATA *NvRamMap;\r
423 EFI_BOOT_MANAGER_LOAD_OPTION LoadOption;\r
424 UINT8 *OptionalData;\r
425 UINT32 OptionalDataSize;\r
426\r
427 OptionalDataExist = FALSE;\r
428 NvRamMap = &CallbackData->BmmFakeNvData;\r
429 OptionalData = NULL;\r
430 OptionalDataSize = 0;\r
431\r
432 Index = BOpt_GetBootOptionNumber () ;\r
433 UnicodeSPrint (BootString, sizeof (BootString), L"Boot%04x", Index);\r
434\r
435 if (NvRamMap->BootDescriptionData[0] == 0x0000) {\r
436 StrCpyS (NvRamMap->BootDescriptionData, sizeof (NvRamMap->BootDescriptionData) / sizeof (NvRamMap->BootDescriptionData[0]), BootString);\r
437 }\r
438\r
439 if (NvRamMap->BootOptionalData[0] != 0x0000) {\r
440 OptionalDataExist = TRUE;\r
441 OptionalData = (UINT8 *)NvRamMap->BootOptionalData;\r
442 OptionalDataSize = (UINT32)StrSize (NvRamMap->BootOptionalData);\r
443 }\r
444\r
445 NewMenuEntry = BOpt_CreateMenuEntry (BM_LOAD_CONTEXT_SELECT);\r
446 if (NULL == NewMenuEntry) {\r
447 return EFI_OUT_OF_RESOURCES;\r
448 }\r
449\r
450 Status = EfiBootManagerInitializeLoadOption (\r
451 &LoadOption,\r
452 Index,\r
453 LoadOptionTypeBoot,\r
454 LOAD_OPTION_ACTIVE,\r
455 NvRamMap->BootDescriptionData,\r
456 CallbackData->LoadContext->FilePathList,\r
457 OptionalData,\r
458 OptionalDataSize\r
459 );\r
460 if (EFI_ERROR (Status)){\r
461 return Status;\r
462 }\r
463\r
464 Status = EfiBootManagerAddLoadOptionVariable (&LoadOption,(UINTN) -1 );\r
465 if (EFI_ERROR (Status)) {\r
466 EfiBootManagerFreeLoadOption(&LoadOption);\r
467 return Status;\r
468 }\r
469\r
470 NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;\r
471 NewLoadContext->Deleted = FALSE;\r
472 NewLoadContext->Attributes = LoadOption.Attributes;\r
473 NewLoadContext->FilePathListLength = (UINT16) GetDevicePathSize (LoadOption.FilePath);\r
474\r
475 NewLoadContext->Description = AllocateZeroPool (StrSize (NvRamMap->BootDescriptionData));\r
476 ASSERT (NewLoadContext->Description != NULL);\r
477\r
478 NewMenuEntry->DisplayString = NewLoadContext->Description;\r
479\r
480 CopyMem (\r
481 NewLoadContext->Description,\r
482 LoadOption.Description,\r
483 StrSize (NvRamMap->BootDescriptionData)\r
484 );\r
485\r
486 NewLoadContext->FilePathList = AllocateZeroPool (GetDevicePathSize (CallbackData->LoadContext->FilePathList));\r
487 ASSERT (NewLoadContext->FilePathList != NULL);\r
488 CopyMem (\r
489 NewLoadContext->FilePathList,\r
490 LoadOption.FilePath,\r
491 GetDevicePathSize (CallbackData->LoadContext->FilePathList)\r
492 );\r
493\r
494 NewMenuEntry->HelpString = UiDevicePathToStr (NewLoadContext->FilePathList);\r
495 NewMenuEntry->OptionNumber = Index;\r
496 NewMenuEntry->DisplayStringToken = HiiSetString (CallbackData->BmmHiiHandle, 0, NewMenuEntry->DisplayString, NULL);\r
497 NewMenuEntry->HelpStringToken = HiiSetString (CallbackData->BmmHiiHandle, 0, NewMenuEntry->HelpString, NULL);\r
498\r
499 if (OptionalDataExist) {\r
500 NewLoadContext->OptionalData = AllocateZeroPool (LoadOption.OptionalDataSize);\r
501 ASSERT (NewLoadContext->OptionalData != NULL);\r
502 CopyMem (\r
503 NewLoadContext->OptionalData,\r
504 LoadOption.OptionalData,\r
505 LoadOption.OptionalDataSize\r
506 );\r
507 }\r
508\r
509 InsertTailList (&BootOptionMenu.Head, &NewMenuEntry->Link);\r
510 BootOptionMenu.MenuNumber++;\r
511\r
512 EfiBootManagerFreeLoadOption(&LoadOption);\r
513\r
514 return EFI_SUCCESS;\r
515}\r
516\r
517/**\r
518 This function update the "BootNext" EFI Variable. If there is\r
519 no "BootNext" specified in BMM, this EFI Variable is deleted.\r
520 It also update the BMM context data specified the "BootNext"\r
521 vaule.\r
522\r
523 @param CallbackData The BMM context data.\r
524\r
525 @retval EFI_SUCCESS The function complete successfully.\r
526 @return The EFI variable can be saved. See gRT->SetVariable\r
527 for detail return information.\r
528\r
529**/\r
530EFI_STATUS\r
531Var_UpdateBootNext (\r
532 IN BMM_CALLBACK_DATA *CallbackData\r
533 )\r
534{\r
535 BM_MENU_ENTRY *NewMenuEntry;\r
536 BM_LOAD_CONTEXT *NewLoadContext;\r
537 BMM_FAKE_NV_DATA *CurrentFakeNVMap;\r
538 UINT16 Index;\r
539 EFI_STATUS Status;\r
540\r
541 Status = EFI_SUCCESS;\r
542 CurrentFakeNVMap = &CallbackData->BmmFakeNvData;\r
543 for (Index = 0; Index < BootOptionMenu.MenuNumber; Index++) {\r
544 NewMenuEntry = BOpt_GetMenuEntry (&BootOptionMenu, Index);\r
545 ASSERT (NULL != NewMenuEntry);\r
546\r
547 NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;\r
548 NewLoadContext->IsBootNext = FALSE;\r
549 }\r
550\r
551 if (CurrentFakeNVMap->BootNext == NONE_BOOTNEXT_VALUE) {\r
552 EfiLibDeleteVariable (L"BootNext", &gEfiGlobalVariableGuid);\r
553 return EFI_SUCCESS;\r
554 }\r
555\r
556 NewMenuEntry = BOpt_GetMenuEntry (\r
557 &BootOptionMenu,\r
558 CurrentFakeNVMap->BootNext\r
559 );\r
560 ASSERT (NewMenuEntry != NULL);\r
561\r
562 NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;\r
563 Status = gRT->SetVariable (\r
564 L"BootNext",\r
565 &gEfiGlobalVariableGuid,\r
566 VAR_FLAG,\r
567 sizeof (UINT16),\r
568 &NewMenuEntry->OptionNumber\r
569 );\r
570 NewLoadContext->IsBootNext = TRUE;\r
571 CallbackData->BmmOldFakeNVData.BootNext = CurrentFakeNVMap->BootNext;\r
572 return Status;\r
573}\r
574\r
575/**\r
576 This function update the "BootOrder" EFI Variable based on\r
577 BMM Formset's NV map. It then refresh BootOptionMenu\r
578 with the new "BootOrder" list.\r
579\r
580 @param CallbackData The BMM context data.\r
581\r
582 @retval EFI_SUCCESS The function complete successfully.\r
583 @retval EFI_OUT_OF_RESOURCES Not enough memory to complete the function.\r
584 @return The EFI variable can not be saved. See gRT->SetVariable for detail return information.\r
585\r
586**/\r
587EFI_STATUS\r
588Var_UpdateBootOrder (\r
589 IN BMM_CALLBACK_DATA *CallbackData\r
590 )\r
591{\r
592 EFI_STATUS Status;\r
593 UINT16 Index;\r
594 UINT16 OrderIndex;\r
595 UINT16 *BootOrder;\r
596 UINTN BootOrderSize;\r
597 UINT16 OptionNumber;\r
598\r
599 //\r
600 // First check whether BootOrder is present in current configuration\r
601 //\r
602 GetEfiGlobalVariable2 (L"BootOrder", (VOID **) &BootOrder, &BootOrderSize);\r
603 if (BootOrder == NULL) {\r
604 return EFI_OUT_OF_RESOURCES;\r
605 }\r
606\r
607 ASSERT (BootOptionMenu.MenuNumber <= (sizeof (CallbackData->BmmFakeNvData.BootOptionOrder) / sizeof (CallbackData->BmmFakeNvData.BootOptionOrder[0])));\r
608\r
609 //\r
610 // OptionOrder is subset of BootOrder\r
611 //\r
612 for (OrderIndex = 0; (OrderIndex < BootOptionMenu.MenuNumber) && (CallbackData->BmmFakeNvData.BootOptionOrder[OrderIndex] != 0); OrderIndex++) {\r
613 for (Index = OrderIndex; Index < BootOrderSize / sizeof (UINT16); Index++) {\r
614 if ((BootOrder[Index] == (UINT16) (CallbackData->BmmFakeNvData.BootOptionOrder[OrderIndex] - 1)) && (OrderIndex != Index)) {\r
615 OptionNumber = BootOrder[Index];\r
616 CopyMem (&BootOrder[OrderIndex + 1], &BootOrder[OrderIndex], (Index - OrderIndex) * sizeof (UINT16));\r
617 BootOrder[OrderIndex] = OptionNumber;\r
618 }\r
619 }\r
620 }\r
621\r
622 Status = gRT->SetVariable (\r
623 L"BootOrder",\r
624 &gEfiGlobalVariableGuid,\r
625 VAR_FLAG,\r
626 BootOrderSize,\r
627 BootOrder\r
628 );\r
629 FreePool (BootOrder);\r
630\r
631 BOpt_FreeMenu (&BootOptionMenu);\r
632 BOpt_GetBootOptions (CallbackData);\r
633\r
634 return Status;\r
635\r
636}\r
637\r
638/**\r
639 This function update the "DriverOrder" EFI Variable based on\r
640 BMM Formset's NV map. It then refresh DriverOptionMenu\r
641 with the new "DriverOrder" list.\r
642\r
643 @param CallbackData The BMM context data.\r
644\r
645 @retval EFI_SUCCESS The function complete successfully.\r
646 @retval EFI_OUT_OF_RESOURCES Not enough memory to complete the function.\r
647 @return The EFI variable can not be saved. See gRT->SetVariable for detail return information.\r
648\r
649**/\r
650EFI_STATUS\r
651Var_UpdateDriverOrder (\r
652 IN BMM_CALLBACK_DATA *CallbackData\r
653 )\r
654{\r
655 EFI_STATUS Status;\r
656 UINT16 Index;\r
657 UINT16 *DriverOrderList;\r
658 UINT16 *NewDriverOrderList;\r
659 UINTN DriverOrderListSize;\r
660\r
661 DriverOrderList = NULL;\r
662 DriverOrderListSize = 0;\r
663\r
664 //\r
665 // First check whether DriverOrder is present in current configuration\r
666 //\r
667 GetEfiGlobalVariable2 (L"DriverOrder", (VOID **) &DriverOrderList, &DriverOrderListSize);\r
668 NewDriverOrderList = AllocateZeroPool (DriverOrderListSize);\r
669\r
670 if (NewDriverOrderList == NULL) {\r
671 return EFI_OUT_OF_RESOURCES;\r
672 }\r
673 //\r
674 // If exists, delete it to hold new DriverOrder\r
675 //\r
676 if (DriverOrderList != NULL) {\r
677 EfiLibDeleteVariable (L"DriverOrder", &gEfiGlobalVariableGuid);\r
678 FreePool (DriverOrderList);\r
679 }\r
680\r
681 ASSERT (DriverOptionMenu.MenuNumber <= (sizeof (CallbackData->BmmFakeNvData.DriverOptionOrder) / sizeof (CallbackData->BmmFakeNvData.DriverOptionOrder[0])));\r
682 for (Index = 0; Index < DriverOptionMenu.MenuNumber; Index++) {\r
683 NewDriverOrderList[Index] = (UINT16) (CallbackData->BmmFakeNvData.DriverOptionOrder[Index] - 1);\r
684 }\r
685\r
686 Status = gRT->SetVariable (\r
687 L"DriverOrder",\r
688 &gEfiGlobalVariableGuid,\r
689 VAR_FLAG,\r
690 DriverOrderListSize,\r
691 NewDriverOrderList\r
692 );\r
693 if (EFI_ERROR (Status)) {\r
694 return Status;\r
695 }\r
696\r
697 BOpt_FreeMenu (&DriverOptionMenu);\r
698 BOpt_GetDriverOptions (CallbackData);\r
699 return EFI_SUCCESS;\r
700}\r
701\r
702/**\r
703 Update the Text Mode of Console.\r
704\r
705 @param CallbackData The context data for BMM.\r
706\r
707 @retval EFI_SUCCSS If the Text Mode of Console is updated.\r
708 @return Other value if the Text Mode of Console is not updated.\r
709\r
710**/\r
711EFI_STATUS\r
712Var_UpdateConMode (\r
713 IN BMM_CALLBACK_DATA *CallbackData\r
714 )\r
715{\r
716 EFI_STATUS Status;\r
717 UINTN Mode;\r
718 CONSOLE_OUT_MODE ModeInfo;\r
719\r
720 Mode = CallbackData->BmmFakeNvData.ConsoleOutMode;\r
721\r
722 Status = gST->ConOut->QueryMode (gST->ConOut, Mode, &(ModeInfo.Column), &(ModeInfo.Row));\r
723 if (!EFI_ERROR(Status)) {\r
724 Status = PcdSet32S (PcdSetupConOutColumn, (UINT32) ModeInfo.Column);\r
725 if (!EFI_ERROR (Status)) {\r
726 Status = PcdSet32S (PcdSetupConOutRow, (UINT32) ModeInfo.Row);\r
727 }\r
728 }\r
729\r
730 return Status;\r
731}\r