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