]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Library/BootMaintenanceManagerUiLib/Variable.c
MdeModulePkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / MdeModulePkg / Library / BootMaintenanceManagerUiLib / Variable.c
CommitLineData
4af04335
DB
1/** @file\r
2Variable operation that will be used by bootmaint\r
3\r
d1102dba 4Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>\r
9d510e61 5SPDX-License-Identifier: BSD-2-Clause-Patent\r
4af04335
DB
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
4af04335 13\r
d1102dba 14 @retval EFI_SUCCESS If all boot load option EFI Variables corresponding to\r
4af04335
DB
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
d1102dba 17 @return Others If failed to update the "BootOrder" variable after deletion.\r
4af04335
DB
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
4af04335
DB
27 EFI_STATUS Status;\r
28 UINTN Index;\r
29 UINTN Index2;\r
30\r
4af04335
DB
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
bdc8cb0d
DB
43 Status = EfiBootManagerDeleteLoadOptionVariable (NewMenuEntry->OptionNumber,LoadOptionTypeBoot);\r
44 if (EFI_ERROR (Status)) {\r
45 return Status;\r
46 }\r
4af04335
DB
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
4af04335
DB
64 return EFI_SUCCESS;\r
65}\r
66\r
67/**\r
bdc8cb0d 68 Delete Load Option that represent a Deleted state in DriverOptionMenu.\r
4af04335
DB
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
4af04335
DB
83 EFI_STATUS Status;\r
84 UINTN Index;\r
85 UINTN Index2;\r
86\r
4af04335
DB
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
bdc8cb0d
DB
98 Status = EfiBootManagerDeleteLoadOptionVariable (NewMenuEntry->OptionNumber,LoadOptionTypeDriver);\r
99 if (EFI_ERROR (Status)) {\r
100 return Status;\r
101 }\r
4af04335 102\r
4af04335
DB
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
4af04335
DB
112 return EFI_SUCCESS;\r
113}\r
114\r
4af04335
DB
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
d1102dba 121 path by appending the device path of the Console (In/Out/Err) instance\r
4af04335
DB
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
d1102dba 185\r
6eeeb288 186 ASSERT (NewTerminalContext->TerminalType < (ARRAY_SIZE (TerminalTypeGuid)));\r
4af04335
DB
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
d1102dba 258 @return The EFI variable can not be saved. See gRT->SetVariable for detail return information.\r
4af04335
DB
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
d1102dba
LG
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
4af04335
DB
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
201fbce6
DB
280 @retval other Contain some errors when excuting this function.See function\r
281 EfiBootManagerInitializeLoadOption/EfiBootManagerAddLoadOptionVariabl\r
282 for detail return information.\r
4af04335
DB
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
4af04335 296 UINT16 DriverString[12];\r
4af04335
DB
297 BM_MENU_ENTRY *NewMenuEntry;\r
298 BM_LOAD_CONTEXT *NewLoadContext;\r
299 BOOLEAN OptionalDataExist;\r
300 EFI_STATUS Status;\r
2ba36b2f
DB
301 EFI_BOOT_MANAGER_LOAD_OPTION LoadOption;\r
302 UINT8 *OptionalDesData;\r
303 UINT32 OptionalDataSize;\r
4af04335
DB
304\r
305 OptionalDataExist = FALSE;\r
2ba36b2f
DB
306 OptionalDesData = NULL;\r
307 OptionalDataSize = 0;\r
4af04335
DB
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
4af04335
DB
321 if (*OptionalData != 0x0000) {\r
322 OptionalDataExist = TRUE;\r
2ba36b2f
DB
323 OptionalDesData = (UINT8 *)OptionalData;\r
324 OptionalDataSize = (UINT32)StrSize (OptionalData);\r
4af04335
DB
325 }\r
326\r
327 NewMenuEntry = BOpt_CreateMenuEntry (BM_LOAD_CONTEXT_SELECT);\r
328 if (NULL == NewMenuEntry) {\r
4af04335
DB
329 return EFI_OUT_OF_RESOURCES;\r
330 }\r
331\r
2ba36b2f
DB
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
201fbce6
DB
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
2ba36b2f
DB
350 }\r
351\r
4af04335
DB
352 NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;\r
353 NewLoadContext->Deleted = FALSE;\r
2ba36b2f
DB
354 NewLoadContext->Attributes = LoadOption.Attributes;\r
355 NewLoadContext->FilePathListLength = (UINT16)GetDevicePathSize (LoadOption.FilePath);\r
4af04335
DB
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
2ba36b2f 362 LoadOption.Description,\r
4af04335
DB
363 StrSize (DescriptionData)\r
364 );\r
365\r
4af04335
DB
366 NewLoadContext->FilePathList = AllocateZeroPool (GetDevicePathSize (CallbackData->LoadContext->FilePathList));\r
367 ASSERT (NewLoadContext->FilePathList != NULL);\r
4af04335
DB
368 CopyMem (\r
369 NewLoadContext->FilePathList,\r
2ba36b2f 370 LoadOption.FilePath,\r
4af04335
DB
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
2ba36b2f 380 NewLoadContext->OptionalData = AllocateZeroPool (LoadOption.OptionalDataSize);\r
48c18bd1 381 ASSERT (NewLoadContext->OptionalData != NULL);\r
4af04335 382 CopyMem (\r
2ba36b2f
DB
383 NewLoadContext->OptionalData,\r
384 LoadOption.OptionalData,\r
385 LoadOption.OptionalDataSize\r
4af04335
DB
386 );\r
387 }\r
388\r
4af04335
DB
389 InsertTailList (&DriverOptionMenu.Head, &NewMenuEntry->Link);\r
390 DriverOptionMenu.MenuNumber++;\r
391\r
2ba36b2f
DB
392 EfiBootManagerFreeLoadOption(&LoadOption);\r
393\r
4af04335
DB
394 return EFI_SUCCESS;\r
395}\r
396\r
397/**\r
d1102dba
LG
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
4af04335
DB
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
201fbce6
DB
405 @retval other Contain some errors when excuting this function. See function\r
406 EfiBootManagerInitializeLoadOption/EfiBootManagerAddLoadOptionVariabl\r
407 for detail return information.\r
4af04335
DB
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
4af04335 416 UINT16 BootString[10];\r
4af04335
DB
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
2ba36b2f
DB
423 EFI_BOOT_MANAGER_LOAD_OPTION LoadOption;\r
424 UINT8 *OptionalData;\r
425 UINT32 OptionalDataSize;\r
4af04335
DB
426\r
427 OptionalDataExist = FALSE;\r
428 NvRamMap = &CallbackData->BmmFakeNvData;\r
2ba36b2f
DB
429 OptionalData = NULL;\r
430 OptionalDataSize = 0;\r
4af04335
DB
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
4af04335
DB
439 if (NvRamMap->BootOptionalData[0] != 0x0000) {\r
440 OptionalDataExist = TRUE;\r
2ba36b2f
DB
441 OptionalData = (UINT8 *)NvRamMap->BootOptionalData;\r
442 OptionalDataSize = (UINT32)StrSize (NvRamMap->BootOptionalData);\r
4af04335
DB
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
2ba36b2f
DB
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
201fbce6
DB
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
2ba36b2f
DB
468 }\r
469\r
4af04335
DB
470 NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;\r
471 NewLoadContext->Deleted = FALSE;\r
2ba36b2f
DB
472 NewLoadContext->Attributes = LoadOption.Attributes;\r
473 NewLoadContext->FilePathListLength = (UINT16) GetDevicePathSize (LoadOption.FilePath);\r
4af04335
DB
474\r
475 NewLoadContext->Description = AllocateZeroPool (StrSize (NvRamMap->BootDescriptionData));\r
476 ASSERT (NewLoadContext->Description != NULL);\r
477\r
478 NewMenuEntry->DisplayString = NewLoadContext->Description;\r
2ba36b2f 479\r
4af04335
DB
480 CopyMem (\r
481 NewLoadContext->Description,\r
2ba36b2f 482 LoadOption.Description,\r
4af04335
DB
483 StrSize (NvRamMap->BootDescriptionData)\r
484 );\r
485\r
4af04335
DB
486 NewLoadContext->FilePathList = AllocateZeroPool (GetDevicePathSize (CallbackData->LoadContext->FilePathList));\r
487 ASSERT (NewLoadContext->FilePathList != NULL);\r
4af04335
DB
488 CopyMem (\r
489 NewLoadContext->FilePathList,\r
2ba36b2f 490 LoadOption.FilePath,\r
4af04335
DB
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
2ba36b2f 500 NewLoadContext->OptionalData = AllocateZeroPool (LoadOption.OptionalDataSize);\r
48c18bd1 501 ASSERT (NewLoadContext->OptionalData != NULL);\r
2ba36b2f
DB
502 CopyMem (\r
503 NewLoadContext->OptionalData,\r
504 LoadOption.OptionalData,\r
505 LoadOption.OptionalDataSize\r
506 );\r
4af04335
DB
507 }\r
508\r
4af04335
DB
509 InsertTailList (&BootOptionMenu.Head, &NewMenuEntry->Link);\r
510 BootOptionMenu.MenuNumber++;\r
511\r
2ba36b2f
DB
512 EfiBootManagerFreeLoadOption(&LoadOption);\r
513\r
4af04335
DB
514 return EFI_SUCCESS;\r
515}\r
516\r
517/**\r
d1102dba 518 This function update the "BootNext" EFI Variable. If there is\r
4af04335
DB
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
d1102dba 526 @return The EFI variable can be saved. See gRT->SetVariable\r
4af04335
DB
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
f7986526 551 if (CurrentFakeNVMap->BootNext == NONE_BOOTNEXT_VALUE) {\r
4af04335
DB
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
d1102dba 630\r
4af04335
DB
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