]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/BdsDxe/BootMaint/BootMaint.c
DuplicateDevicePath() function use wrong comment same as AppendDevicePath() function.
[mirror_edk2.git] / MdeModulePkg / Universal / BdsDxe / BootMaint / BootMaint.c
CommitLineData
fd6a62f3 1/** @file\r
2e9f9668 2 The functions for Boot Maintainence Main menu.\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#include "FormGuid.h"\r
17#include "Bds.h"\r
18#include "FrontPage.h"\r
19\r
dce655e8 20EFI_DEVICE_PATH_PROTOCOL EndDevicePath[] = {\r
555e76f8 21 {\r
22 END_DEVICE_PATH_TYPE,\r
23 END_ENTIRE_DEVICE_PATH_SUBTYPE,\r
24 {\r
25 END_DEVICE_PATH_LENGTH,\r
26 0\r
27 }\r
28 }\r
dce655e8 29};\r
30\r
31\r
30394aa1 32EFI_GUID EfiLegacyDevOrderGuid = EFI_LEGACY_DEV_ORDER_VARIABLE_GUID;\r
33EFI_GUID mBootMaintGuid = BOOT_MAINT_FORMSET_GUID;\r
34EFI_GUID mFileExplorerGuid = FILE_EXPLORE_FORMSET_GUID;\r
93e3992d 35\r
30394aa1 36CHAR16 mBootMaintStorageName[] = L"BmData";\r
37CHAR16 mFileExplorerStorageName[] = L"FeData";\r
93e3992d 38\r
b30312ba 39/**\r
40 Init all memu.\r
41\r
744fc758 42 @param CallbackData The BMM context data.\r
b30312ba 43\r
44**/\r
93e3992d 45VOID\r
46InitAllMenu (\r
47 IN BMM_CALLBACK_DATA *CallbackData\r
48 );\r
49\r
b30312ba 50/**\r
744fc758 51 Free up all Menu Option list.\r
b30312ba 52\r
53**/\r
93e3992d 54VOID\r
55FreeAllMenu (\r
56 VOID\r
57 );\r
58\r
b30312ba 59/**\r
60 Create string tokens for a menu from its help strings and display strings\r
61\r
2e9f9668 62 @param CallbackData The BMM context data.\r
63 @param HiiHandle Hii Handle of the package to be updated.\r
64 @param MenuOption The Menu whose string tokens need to be created\r
b30312ba 65\r
2e9f9668 66 @retval EFI_SUCCESS String tokens created successfully\r
b30312ba 67 @retval others contain some errors\r
b30312ba 68**/\r
93e3992d 69EFI_STATUS\r
70CreateMenuStringToken (\r
71 IN BMM_CALLBACK_DATA *CallbackData,\r
72 IN EFI_HII_HANDLE HiiHandle,\r
73 IN BM_MENU_OPTION *MenuOption\r
74 )\r
93e3992d 75{\r
76 BM_MENU_ENTRY *NewMenuEntry;\r
77 UINTN Index;\r
78\r
79 for (Index = 0; Index < MenuOption->MenuNumber; Index++) {\r
80 NewMenuEntry = BOpt_GetMenuEntry (MenuOption, Index);\r
81\r
9226efe5 82 HiiLibNewString (\r
93e3992d 83 HiiHandle,\r
84 &NewMenuEntry->DisplayStringToken,\r
85 NewMenuEntry->DisplayString\r
86 );\r
87\r
88 if (NULL == NewMenuEntry->HelpString) {\r
89 NewMenuEntry->HelpStringToken = NewMenuEntry->DisplayStringToken;\r
90 } else {\r
9226efe5 91 HiiLibNewString (\r
93e3992d 92 HiiHandle,\r
93 &NewMenuEntry->HelpStringToken,\r
94 NewMenuEntry->HelpString\r
95 );\r
96 }\r
97 }\r
98\r
99 return EFI_SUCCESS;\r
100}\r
101\r
b30312ba 102/**\r
103 This function allows a caller to extract the current configuration for one\r
104 or more named elements from the target driver.\r
105\r
106\r
30394aa1 107 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
108 @param Request A null-terminated Unicode string in <ConfigRequest> format.\r
109 @param Progress On return, points to a character in the Request string.\r
b30312ba 110 Points to the string's null terminator if request was successful.\r
111 Points to the most recent '&' before the first failing name/value\r
112 pair (or the beginning of the string if the failure is in the\r
113 first name/value pair) if the request was not successful.\r
30394aa1 114 @param Results A null-terminated Unicode string in <ConfigAltResp> format which\r
b30312ba 115 has all values filled in for the names in the Request string.\r
116 String to be allocated by the called function.\r
117\r
118 @retval EFI_SUCCESS The Results is filled with the requested values.\r
119 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the results.\r
120 @retval EFI_INVALID_PARAMETER Request is NULL, illegal syntax, or unknown name.\r
121 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this driver.\r
122\r
123**/\r
93e3992d 124EFI_STATUS\r
125EFIAPI\r
126BootMaintExtractConfig (\r
127 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
128 IN CONST EFI_STRING Request,\r
129 OUT EFI_STRING *Progress,\r
130 OUT EFI_STRING *Results\r
131 )\r
93e3992d 132{\r
133 EFI_STATUS Status;\r
134 UINTN BufferSize;\r
135 BMM_CALLBACK_DATA *Private;\r
136\r
8d00a0f1 137 if (Request == NULL) {\r
2e9f9668 138 return EFI_INVALID_PARAMETER;\r
8d00a0f1 139 }\r
140\r
93e3992d 141 Private = BMM_CALLBACK_DATA_FROM_THIS (This);\r
142\r
143 //\r
144 // Convert buffer data to <ConfigResp> by helper function BlockToConfig()\r
145 //\r
146 BufferSize = sizeof (BMM_FAKE_NV_DATA);\r
147 Status = gHiiConfigRouting->BlockToConfig (\r
148 gHiiConfigRouting,\r
149 Request,\r
150 (UINT8 *) &Private->BmmFakeNvData,\r
151 BufferSize,\r
152 Results,\r
153 Progress\r
154 );\r
155 return Status;\r
156}\r
157\r
b30312ba 158/**\r
159 This function processes the results of changes in configuration.\r
160\r
161\r
2e9f9668 162 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
163 @param Action Specifies the type of action taken by the browser.\r
164 @param QuestionId A unique value which is sent to the original exporting driver\r
165 so that it can identify the type of data to expect.\r
166 @param Type The type of value for the question.\r
167 @param Value A pointer to the data being sent to the original exporting driver.\r
168 @param ActionRequest On return, points to the action requested by the callback function.\r
b30312ba 169\r
2e9f9668 170 @retval EFI_SUCCESS The callback successfully handled the action.\r
171 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the variable and its data.\r
172 @retval EFI_DEVICE_ERROR The variable could not be saved.\r
173 @retval EFI_UNSUPPORTED The specified Action is not supported by the callback.\r
174 @retval EFI_INVALID_PARAMETER The parameter of Value or ActionRequest is invalid.\r
b30312ba 175**/\r
93e3992d 176EFI_STATUS\r
177EFIAPI\r
178BootMaintCallback (\r
2e9f9668 179 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
180 IN EFI_BROWSER_ACTION Action,\r
181 IN EFI_QUESTION_ID QuestionId,\r
182 IN UINT8 Type,\r
183 IN EFI_IFR_TYPE_VALUE *Value,\r
184 OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest\r
93e3992d 185 )\r
93e3992d 186{\r
187 BMM_CALLBACK_DATA *Private;\r
188 BM_MENU_ENTRY *NewMenuEntry;\r
189 BMM_FAKE_NV_DATA *CurrentFakeNVMap;\r
190 EFI_STATUS Status;\r
191 UINTN OldValue;\r
192 UINTN NewValue;\r
193 UINTN Number;\r
194 UINTN Pos;\r
195 UINTN Bit;\r
196 UINT16 NewValuePos;\r
197 UINT16 Index2;\r
198 UINT16 Index;\r
199 UINT8 *OldLegacyDev;\r
200 UINT8 *NewLegacyDev;\r
201 UINT8 *DisMap;\r
202 EFI_FORM_ID FormId;\r
203 UINTN BufferSize;\r
204\r
205 if ((Value == NULL) || (ActionRequest == NULL)) {\r
206 return EFI_INVALID_PARAMETER;\r
207 }\r
208\r
209 OldValue = 0;\r
210 NewValue = 0;\r
211 Number = 0;\r
212 OldLegacyDev = NULL;\r
213 NewLegacyDev = NULL;\r
214 NewValuePos = 0;\r
215 DisMap = NULL;\r
216 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;\r
217\r
218 Private = BMM_CALLBACK_DATA_FROM_THIS (This);\r
219 UpdatePageId (Private, QuestionId);\r
220\r
221 //\r
222 // Retrive uncommitted data from Form Browser\r
223 //\r
224 CurrentFakeNVMap = &Private->BmmFakeNvData;\r
225 BufferSize = sizeof (BMM_FAKE_NV_DATA);\r
226 Status = GetBrowserData (NULL, NULL, &BufferSize, (UINT8 *) CurrentFakeNVMap);\r
227 if (EFI_ERROR (Status)) {\r
228 return Status;\r
229 }\r
230\r
231 //\r
232 // need to be subtituded.\r
233 //\r
234 // Update Select FD/HD/CD/NET/BEV Order Form\r
235 //\r
236 if (FORM_SET_FD_ORDER_ID == Private->BmmPreviousPageId ||\r
237 FORM_SET_HD_ORDER_ID == Private->BmmPreviousPageId ||\r
238 FORM_SET_CD_ORDER_ID == Private->BmmPreviousPageId ||\r
239 FORM_SET_NET_ORDER_ID == Private->BmmPreviousPageId ||\r
240 FORM_SET_BEV_ORDER_ID == Private->BmmPreviousPageId ||\r
241 ((FORM_BOOT_SETUP_ID == Private->BmmPreviousPageId) &&\r
242 (QuestionId >= LEGACY_FD_QUESTION_ID) &&\r
243 (QuestionId < (LEGACY_BEV_QUESTION_ID + 100)) )\r
244 ) {\r
245\r
246 DisMap = Private->BmmOldFakeNVData.DisableMap;\r
247\r
248 FormId = Private->BmmPreviousPageId;\r
249 if (FormId == FORM_BOOT_SETUP_ID) {\r
250 FormId = Private->BmmCurrentPageId;\r
251 }\r
252\r
253 switch (FormId) {\r
254 case FORM_SET_FD_ORDER_ID:\r
255 Number = (UINT16) LegacyFDMenu.MenuNumber;\r
256 OldLegacyDev = Private->BmmOldFakeNVData.LegacyFD;\r
257 NewLegacyDev = CurrentFakeNVMap->LegacyFD;\r
258 break;\r
259\r
260 case FORM_SET_HD_ORDER_ID:\r
261 Number = (UINT16) LegacyHDMenu.MenuNumber;\r
262 OldLegacyDev = Private->BmmOldFakeNVData.LegacyHD;\r
263 NewLegacyDev = CurrentFakeNVMap->LegacyHD;\r
264 break;\r
265\r
266 case FORM_SET_CD_ORDER_ID:\r
267 Number = (UINT16) LegacyCDMenu.MenuNumber;\r
268 OldLegacyDev = Private->BmmOldFakeNVData.LegacyCD;\r
269 NewLegacyDev = CurrentFakeNVMap->LegacyCD;\r
270 break;\r
271\r
272 case FORM_SET_NET_ORDER_ID:\r
273 Number = (UINT16) LegacyNETMenu.MenuNumber;\r
274 OldLegacyDev = Private->BmmOldFakeNVData.LegacyNET;\r
275 NewLegacyDev = CurrentFakeNVMap->LegacyNET;\r
276 break;\r
277\r
278 case FORM_SET_BEV_ORDER_ID:\r
279 Number = (UINT16) LegacyBEVMenu.MenuNumber;\r
280 OldLegacyDev = Private->BmmOldFakeNVData.LegacyBEV;\r
281 NewLegacyDev = CurrentFakeNVMap->LegacyBEV;\r
282 break;\r
283\r
284 default:\r
285 break;\r
286 }\r
287 //\r
288 // First, find the different position\r
289 // if there is change, it should be only one\r
290 //\r
291 for (Index = 0; Index < Number; Index++) {\r
292 if (OldLegacyDev[Index] != NewLegacyDev[Index]) {\r
293 OldValue = OldLegacyDev[Index];\r
294 NewValue = NewLegacyDev[Index];\r
295 break;\r
296 }\r
297 }\r
298\r
299 if (Index != Number) {\r
300 //\r
301 // there is change, now process\r
302 //\r
303 if (0xFF == NewValue) {\r
304 //\r
305 // This item will be disable\r
306 // Just move the items behind this forward to overlap it\r
307 //\r
308 Pos = OldValue / 8;\r
309 Bit = 7 - (OldValue % 8);\r
310 DisMap[Pos] = (UINT8) (DisMap[Pos] | (UINT8) (1 << Bit));\r
311 for (Index2 = Index; Index2 < Number - 1; Index2++) {\r
312 NewLegacyDev[Index2] = NewLegacyDev[Index2 + 1];\r
313 }\r
314\r
315 NewLegacyDev[Index2] = 0xFF;\r
316 } else {\r
317 for (Index2 = 0; Index2 < Number; Index2++) {\r
318 if (Index2 == Index) {\r
319 continue;\r
320 }\r
321\r
322 if (OldLegacyDev[Index2] == NewValue) {\r
323 //\r
324 // If NewValue is in OldLegacyDev array\r
325 // remember its old position\r
326 //\r
327 NewValuePos = Index2;\r
328 break;\r
329 }\r
330 }\r
331\r
332 if (Index2 != Number) {\r
333 //\r
334 // We will change current item to an existing item\r
335 // (It's hard to describe here, please read code, it's like a cycle-moving)\r
336 //\r
337 for (Index2 = NewValuePos; Index2 != Index;) {\r
338 if (NewValuePos < Index) {\r
339 NewLegacyDev[Index2] = OldLegacyDev[Index2 + 1];\r
340 Index2++;\r
341 } else {\r
342 NewLegacyDev[Index2] = OldLegacyDev[Index2 - 1];\r
343 Index2--;\r
344 }\r
345 }\r
346 } else {\r
347 //\r
348 // If NewValue is not in OldlegacyDev array, we are changing to a disabled item\r
349 // so we should modify DisMap to reflect the change\r
350 //\r
351 Pos = NewValue / 8;\r
352 Bit = 7 - (NewValue % 8);\r
353 DisMap[Pos] = (UINT8) (DisMap[Pos] & (~ (UINT8) (1 << Bit)));\r
354 if (0xFF != OldValue) {\r
355 //\r
356 // Because NewValue is a item that was disabled before\r
357 // so after changing the OldValue should be disabled\r
358 // actually we are doing a swap of enable-disable states of two items\r
359 //\r
360 Pos = OldValue / 8;\r
361 Bit = 7 - (OldValue % 8);\r
362 DisMap[Pos] = (UINT8) (DisMap[Pos] | (UINT8) (1 << Bit));\r
363 }\r
364 }\r
365 }\r
366 //\r
367 // To prevent DISABLE appears in the middle of the list\r
368 // we should perform a re-ordering\r
369 //\r
370 Index = 0;\r
371 while (Index < Number) {\r
372 if (0xFF != NewLegacyDev[Index]) {\r
373 Index++;\r
374 continue;\r
375 }\r
376\r
377 Index2 = Index;\r
378 Index2++;\r
379 while (Index2 < Number) {\r
380 if (0xFF != NewLegacyDev[Index2]) {\r
381 break;\r
382 }\r
383\r
384 Index2++;\r
385 }\r
386\r
387 if (Index2 < Number) {\r
388 NewLegacyDev[Index] = NewLegacyDev[Index2];\r
389 NewLegacyDev[Index2] = 0xFF;\r
390 }\r
391\r
392 Index++;\r
393 }\r
394\r
395 CopyMem (\r
396 OldLegacyDev,\r
397 NewLegacyDev,\r
398 Number\r
399 );\r
400 }\r
401 }\r
402\r
403 if (QuestionId < FILE_OPTION_OFFSET) {\r
404 if (QuestionId < CONFIG_OPTION_OFFSET) {\r
405 switch (QuestionId) {\r
406 case KEY_VALUE_BOOT_FROM_FILE:\r
407 Private->FeCurrentState = BOOT_FROM_FILE_STATE;\r
408\r
409 //\r
410 // Exit Bmm main formset to send File Explorer formset.\r
411 //\r
412 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;\r
413 break;\r
414\r
415 case FORM_BOOT_ADD_ID:\r
416 Private->FeCurrentState = ADD_BOOT_OPTION_STATE;\r
417\r
418 //\r
419 // Exit Bmm main formset to send File Explorer formset.\r
420 //\r
421 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;\r
422 break;\r
423\r
424 case FORM_DRV_ADD_FILE_ID:\r
425 Private->FeCurrentState = ADD_DRIVER_OPTION_STATE;\r
426\r
427 //\r
428 // Exit Bmm main formset to send File Explorer formset.\r
429 //\r
430 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;\r
431 break;\r
432\r
433 case FORM_DRV_ADD_HANDLE_ID:\r
434 CleanUpPage (FORM_DRV_ADD_HANDLE_ID, Private);\r
435 UpdateDrvAddHandlePage (Private);\r
436 break;\r
437\r
438 case FORM_BOOT_DEL_ID:\r
439 CleanUpPage (FORM_BOOT_DEL_ID, Private);\r
440 UpdateBootDelPage (Private);\r
441 break;\r
442\r
443 case FORM_BOOT_CHG_ID:\r
444 case FORM_DRV_CHG_ID:\r
445 UpdatePageBody (QuestionId, Private);\r
446 break;\r
447\r
448 case FORM_DRV_DEL_ID:\r
449 CleanUpPage (FORM_DRV_DEL_ID, Private);\r
450 UpdateDrvDelPage (Private);\r
451 break;\r
452\r
453 case FORM_BOOT_NEXT_ID:\r
454 CleanUpPage (FORM_BOOT_NEXT_ID, Private);\r
455 UpdateBootNextPage (Private);\r
456 break;\r
457\r
458 case FORM_TIME_OUT_ID:\r
459 CleanUpPage (FORM_TIME_OUT_ID, Private);\r
460 UpdateTimeOutPage (Private);\r
461 break;\r
462\r
463 case FORM_RESET:\r
464 gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL);\r
465 return EFI_UNSUPPORTED;\r
466\r
467 case FORM_CON_IN_ID:\r
468 case FORM_CON_OUT_ID:\r
469 case FORM_CON_ERR_ID:\r
470 UpdatePageBody (QuestionId, Private);\r
471 break;\r
472\r
473 case FORM_CON_MODE_ID:\r
474 CleanUpPage (FORM_CON_MODE_ID, Private);\r
475 UpdateConModePage (Private);\r
476 break;\r
477\r
478 case FORM_CON_COM_ID:\r
479 CleanUpPage (FORM_CON_COM_ID, Private);\r
480 UpdateConCOMPage (Private);\r
481 break;\r
482\r
483 case FORM_SET_FD_ORDER_ID:\r
484 case FORM_SET_HD_ORDER_ID:\r
485 case FORM_SET_CD_ORDER_ID:\r
486 case FORM_SET_NET_ORDER_ID:\r
487 case FORM_SET_BEV_ORDER_ID:\r
488 CleanUpPage (QuestionId, Private);\r
489 UpdateSetLegacyDeviceOrderPage (QuestionId, Private);\r
490 break;\r
491\r
492 case KEY_VALUE_SAVE_AND_EXIT:\r
493 case KEY_VALUE_NO_SAVE_AND_EXIT:\r
494\r
495 if (QuestionId == KEY_VALUE_SAVE_AND_EXIT) {\r
496 Status = ApplyChangeHandler (Private, CurrentFakeNVMap, Private->BmmPreviousPageId);\r
497 if (EFI_ERROR (Status)) {\r
498 return Status;\r
499 }\r
500 } else if (QuestionId == KEY_VALUE_NO_SAVE_AND_EXIT) {\r
501 DiscardChangeHandler (Private, CurrentFakeNVMap);\r
502 }\r
503\r
504 //\r
505 // Tell browser not to ask for confirmation of changes,\r
506 // since we have already applied or discarded.\r
507 //\r
508 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT;\r
509 break;\r
510\r
511 default:\r
512 break;\r
513 }\r
514 } else if ((QuestionId >= TERMINAL_OPTION_OFFSET) && (QuestionId < CONSOLE_OPTION_OFFSET)) {\r
515 Index2 = (UINT16) (QuestionId - TERMINAL_OPTION_OFFSET);\r
516 Private->CurrentTerminal = Index2;\r
517\r
518 CleanUpPage (FORM_CON_COM_SETUP_ID, Private);\r
519 UpdateTerminalPage (Private);\r
520\r
521 } else if (QuestionId >= HANDLE_OPTION_OFFSET) {\r
522 Index2 = (UINT16) (QuestionId - HANDLE_OPTION_OFFSET);\r
523\r
524 NewMenuEntry = BOpt_GetMenuEntry (&DriverMenu, Index2);\r
525 ASSERT (NewMenuEntry != NULL);\r
526 Private->HandleContext = (BM_HANDLE_CONTEXT *) NewMenuEntry->VariableContext;\r
527\r
528 CleanUpPage (FORM_DRV_ADD_HANDLE_DESC_ID, Private);\r
529\r
530 Private->MenuEntry = NewMenuEntry;\r
531 Private->LoadContext->FilePathList = Private->HandleContext->DevicePath;\r
532\r
533 UpdateDriverAddHandleDescPage (Private);\r
534 }\r
535 }\r
536\r
537 //\r
538 // Pass changed uncommitted data back to Form Browser\r
539 //\r
540 BufferSize = sizeof (BMM_FAKE_NV_DATA);\r
541 Status = SetBrowserData (NULL, NULL, BufferSize, (UINT8 *) CurrentFakeNVMap, NULL);\r
542\r
543 return Status;\r
544}\r
545\r
b30312ba 546/**\r
547 Function handling request to apply changes for BMM pages.\r
548\r
30394aa1 549 @param Private Pointer to callback data buffer.\r
550 @param CurrentFakeNVMap Pointer to buffer holding data of various values used by BMM\r
551 @param FormId ID of the form which has sent the request to apply change.\r
b30312ba 552\r
553 @retval EFI_SUCCESS Change successfully applied.\r
554 @retval Other Error occurs while trying to apply changes.\r
555\r
556**/\r
93e3992d 557EFI_STATUS\r
558ApplyChangeHandler (\r
559 IN BMM_CALLBACK_DATA *Private,\r
560 IN BMM_FAKE_NV_DATA *CurrentFakeNVMap,\r
561 IN EFI_FORM_ID FormId\r
562 )\r
93e3992d 563{\r
564 BM_CONSOLE_CONTEXT *NewConsoleContext;\r
565 BM_TERMINAL_CONTEXT *NewTerminalContext;\r
566 BM_LOAD_CONTEXT *NewLoadContext;\r
567 BM_MENU_ENTRY *NewMenuEntry;\r
568 EFI_STATUS Status;\r
569 UINT16 Index;\r
570\r
571 Status = EFI_SUCCESS;\r
572\r
573 switch (FormId) {\r
574 case FORM_SET_FD_ORDER_ID:\r
575 case FORM_SET_HD_ORDER_ID:\r
576 case FORM_SET_CD_ORDER_ID:\r
577 case FORM_SET_NET_ORDER_ID:\r
578 case FORM_SET_BEV_ORDER_ID:\r
579 Var_UpdateBBSOption (Private);\r
580 break;\r
581\r
582 case FORM_BOOT_DEL_ID:\r
cb263708 583 ASSERT (BootOptionMenu.MenuNumber <= (sizeof (CurrentFakeNVMap->BootOptionDel) / sizeof (UINT8)));\r
93e3992d 584 for (Index = 0; Index < BootOptionMenu.MenuNumber; Index++) {\r
585 NewMenuEntry = BOpt_GetMenuEntry (&BootOptionMenu, Index);\r
586 NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;\r
587 NewLoadContext->Deleted = CurrentFakeNVMap->BootOptionDel[Index];\r
588 }\r
589\r
590 Var_DelBootOption ();\r
591 break;\r
592\r
593 case FORM_DRV_DEL_ID:\r
cb263708 594 ASSERT (DriverOptionMenu.MenuNumber <= (sizeof (CurrentFakeNVMap->DriverOptionDel) / sizeof (UINT8)));\r
93e3992d 595 for (Index = 0; Index < DriverOptionMenu.MenuNumber; Index++) {\r
596 NewMenuEntry = BOpt_GetMenuEntry (&DriverOptionMenu, Index);\r
597 NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;\r
598 NewLoadContext->Deleted = CurrentFakeNVMap->DriverOptionDel[Index];\r
599 }\r
600\r
601 Var_DelDriverOption ();\r
602 break;\r
603\r
604 case FORM_BOOT_CHG_ID:\r
605 Status = Var_UpdateBootOrder (Private);\r
606 break;\r
607\r
608 case FORM_DRV_CHG_ID:\r
609 Status = Var_UpdateDriverOrder (Private);\r
610 break;\r
611\r
612 case FORM_TIME_OUT_ID:\r
613 Status = gRT->SetVariable (\r
614 L"Timeout",\r
615 &gEfiGlobalVariableGuid,\r
616 VAR_FLAG,\r
617 sizeof (UINT16),\r
618 &(CurrentFakeNVMap->BootTimeOut)\r
619 );\r
620 if (EFI_ERROR (Status)) {\r
621 goto Error;\r
622 }\r
623\r
624 Private->BmmOldFakeNVData.BootTimeOut = CurrentFakeNVMap->BootTimeOut;\r
625 break;\r
626\r
627 case FORM_BOOT_NEXT_ID:\r
628 Status = Var_UpdateBootNext (Private);\r
629 break;\r
630\r
631 case FORM_CON_MODE_ID:\r
632 Status = Var_UpdateConMode (Private);\r
633 break;\r
634\r
635 case FORM_CON_COM_SETUP_ID:\r
636 NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Private->CurrentTerminal);\r
637\r
638 ASSERT (NewMenuEntry != NULL);\r
639\r
640 NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;\r
641\r
642 NewTerminalContext->BaudRateIndex = CurrentFakeNVMap->COMBaudRate;\r
cb263708 643 ASSERT (CurrentFakeNVMap->COMBaudRate < (sizeof (BaudRateList) / sizeof (BaudRateList[0])));\r
93e3992d 644 NewTerminalContext->BaudRate = BaudRateList[CurrentFakeNVMap->COMBaudRate].Value;\r
645 NewTerminalContext->DataBitsIndex = CurrentFakeNVMap->COMDataRate;\r
cb263708 646 ASSERT (CurrentFakeNVMap->COMDataRate < (sizeof (DataBitsList) / sizeof (DataBitsList[0])));\r
93e3992d 647 NewTerminalContext->DataBits = (UINT8) DataBitsList[CurrentFakeNVMap->COMDataRate].Value;\r
648 NewTerminalContext->StopBitsIndex = CurrentFakeNVMap->COMStopBits;\r
cb263708 649 ASSERT (CurrentFakeNVMap->COMStopBits < (sizeof (StopBitsList) / sizeof (StopBitsList[0])));\r
93e3992d 650 NewTerminalContext->StopBits = (UINT8) StopBitsList[CurrentFakeNVMap->COMStopBits].Value;\r
651 NewTerminalContext->ParityIndex = CurrentFakeNVMap->COMParity;\r
cb263708 652 ASSERT (CurrentFakeNVMap->COMParity < (sizeof (ParityList) / sizeof (ParityList[0])));\r
93e3992d 653 NewTerminalContext->Parity = (UINT8) ParityList[CurrentFakeNVMap->COMParity].Value;\r
654 NewTerminalContext->TerminalType = CurrentFakeNVMap->COMTerminalType;\r
655\r
656 ChangeTerminalDevicePath (\r
657 NewTerminalContext->DevicePath,\r
658 FALSE\r
659 );\r
660\r
661 Var_UpdateConsoleInpOption ();\r
662 Var_UpdateConsoleOutOption ();\r
663 Var_UpdateErrorOutOption ();\r
664 break;\r
665\r
666 case FORM_CON_IN_ID:\r
cb263708 667 ASSERT ((ConsoleInpMenu.MenuNumber + TerminalMenu.MenuNumber) <= (sizeof (CurrentFakeNVMap->ConsoleCheck) / sizeof (UINT8)));\r
93e3992d 668 for (Index = 0; Index < ConsoleInpMenu.MenuNumber; Index++) {\r
669 NewMenuEntry = BOpt_GetMenuEntry (&ConsoleInpMenu, Index);\r
670 NewConsoleContext = (BM_CONSOLE_CONTEXT *) NewMenuEntry->VariableContext;\r
671 NewConsoleContext->IsActive = CurrentFakeNVMap->ConsoleCheck[Index];\r
672 }\r
673\r
674 for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {\r
675 NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);\r
676 NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;\r
677 NewTerminalContext->IsConIn = CurrentFakeNVMap->ConsoleCheck[Index + ConsoleInpMenu.MenuNumber];\r
678 }\r
679\r
680 Var_UpdateConsoleInpOption ();\r
681 break;\r
682\r
683 case FORM_CON_OUT_ID:\r
cb263708 684 ASSERT ((ConsoleOutMenu.MenuNumber + TerminalMenu.MenuNumber) <= (sizeof (CurrentFakeNVMap->ConsoleCheck) / sizeof (UINT8)));\r
93e3992d 685 for (Index = 0; Index < ConsoleOutMenu.MenuNumber; Index++) {\r
686 NewMenuEntry = BOpt_GetMenuEntry (&ConsoleOutMenu, Index);\r
687 NewConsoleContext = (BM_CONSOLE_CONTEXT *) NewMenuEntry->VariableContext;\r
688 NewConsoleContext->IsActive = CurrentFakeNVMap->ConsoleCheck[Index];\r
689 }\r
690\r
691 for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {\r
692 NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);\r
693 NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;\r
694 NewTerminalContext->IsConOut = CurrentFakeNVMap->ConsoleCheck[Index + ConsoleOutMenu.MenuNumber];\r
695 }\r
696\r
697 Var_UpdateConsoleOutOption ();\r
698 break;\r
699\r
700 case FORM_CON_ERR_ID:\r
cb263708 701 ASSERT ((ConsoleErrMenu.MenuNumber + TerminalMenu.MenuNumber) <= (sizeof (CurrentFakeNVMap->ConsoleCheck) / sizeof (UINT8)));\r
93e3992d 702 for (Index = 0; Index < ConsoleErrMenu.MenuNumber; Index++) {\r
703 NewMenuEntry = BOpt_GetMenuEntry (&ConsoleErrMenu, Index);\r
704 NewConsoleContext = (BM_CONSOLE_CONTEXT *) NewMenuEntry->VariableContext;\r
705 NewConsoleContext->IsActive = CurrentFakeNVMap->ConsoleCheck[Index];\r
706 }\r
707\r
708 for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {\r
709 NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);\r
710 NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;\r
711 NewTerminalContext->IsStdErr = CurrentFakeNVMap->ConsoleCheck[Index + ConsoleErrMenu.MenuNumber];\r
712 }\r
713\r
714 Var_UpdateErrorOutOption ();\r
715 break;\r
716\r
717 case FORM_DRV_ADD_HANDLE_DESC_ID:\r
718 Status = Var_UpdateDriverOption (\r
719 Private,\r
720 Private->BmmHiiHandle,\r
721 CurrentFakeNVMap->DriverAddHandleDesc,\r
722 CurrentFakeNVMap->DriverAddHandleOptionalData,\r
723 CurrentFakeNVMap->DriverAddForceReconnect\r
724 );\r
725 if (EFI_ERROR (Status)) {\r
726 goto Error;\r
727 }\r
728\r
729 BOpt_GetDriverOptions (Private);\r
730 CreateMenuStringToken (Private, Private->BmmHiiHandle, &DriverOptionMenu);\r
731 break;\r
732\r
733 default:\r
734 break;\r
735 }\r
736\r
737Error:\r
738 return Status;\r
739}\r
740\r
b30312ba 741/**\r
dce655e8 742 Discard all changes done to the BMM pages such as Boot Order change,\r
743 Driver order change.\r
b30312ba 744\r
30394aa1 745 @param Private The BMM context data.\r
746 @param CurrentFakeNVMap The current Fack NV Map.\r
b30312ba 747\r
748**/\r
93e3992d 749VOID\r
750DiscardChangeHandler (\r
751 IN BMM_CALLBACK_DATA *Private,\r
752 IN BMM_FAKE_NV_DATA *CurrentFakeNVMap\r
753 )\r
754{\r
755 UINT16 Index;\r
756\r
757 switch (Private->BmmPreviousPageId) {\r
758 case FORM_BOOT_CHG_ID:\r
759 case FORM_DRV_CHG_ID:\r
760 CopyMem (CurrentFakeNVMap->OptionOrder, Private->BmmOldFakeNVData.OptionOrder, 100);\r
761 break;\r
762\r
763 case FORM_BOOT_DEL_ID:\r
cb263708 764 ASSERT (BootOptionMenu.MenuNumber <= (sizeof (CurrentFakeNVMap->BootOptionDel) / sizeof (CurrentFakeNVMap->BootOptionDel[0])));\r
93e3992d 765 for (Index = 0; Index < BootOptionMenu.MenuNumber; Index++) {\r
766 CurrentFakeNVMap->BootOptionDel[Index] = 0x00;\r
767 }\r
768 break;\r
769\r
770 case FORM_DRV_DEL_ID:\r
cb263708 771 ASSERT (DriverOptionMenu.MenuNumber <= (sizeof (CurrentFakeNVMap->DriverOptionDel) / sizeof (CurrentFakeNVMap->DriverOptionDel[0])));\r
93e3992d 772 for (Index = 0; Index < DriverOptionMenu.MenuNumber; Index++) {\r
773 CurrentFakeNVMap->DriverOptionDel[Index] = 0x00;\r
774 }\r
775 break;\r
776\r
777 case FORM_BOOT_NEXT_ID:\r
778 CurrentFakeNVMap->BootNext = Private->BmmOldFakeNVData.BootNext;\r
779 break;\r
780\r
781 case FORM_TIME_OUT_ID:\r
782 CurrentFakeNVMap->BootTimeOut = Private->BmmOldFakeNVData.BootTimeOut;\r
783 break;\r
784\r
785 case FORM_DRV_ADD_HANDLE_DESC_ID:\r
786 case FORM_DRV_ADD_FILE_ID:\r
787 case FORM_DRV_ADD_HANDLE_ID:\r
788 CurrentFakeNVMap->DriverAddHandleDesc[0] = 0x0000;\r
789 CurrentFakeNVMap->DriverAddHandleOptionalData[0] = 0x0000;\r
790 break;\r
791\r
792 default:\r
793 break;\r
794 }\r
795}\r
796\r
b30312ba 797/**\r
744fc758 798 Initialize the Boot Maintenance Utitliy.\r
93e3992d 799\r
93e3992d 800\r
b30312ba 801 @retval EFI_SUCCESS utility ended successfully\r
802 @retval others contain some errors\r
803\r
804**/\r
805EFI_STATUS\r
806InitializeBM (\r
807 VOID\r
808 )\r
93e3992d 809{\r
810 EFI_LEGACY_BIOS_PROTOCOL *LegacyBios;\r
811 EFI_HII_PACKAGE_LIST_HEADER *PackageList;\r
812 BMM_CALLBACK_DATA *BmmCallbackInfo;\r
813 EFI_STATUS Status;\r
814 UINT8 *Ptr;\r
815\r
816 Status = EFI_SUCCESS;\r
817\r
818 //\r
819 // Create CallbackData structures for Driver Callback\r
820 //\r
dce655e8 821 BmmCallbackInfo = AllocateZeroPool (sizeof (BMM_CALLBACK_DATA));\r
93e3992d 822 if (BmmCallbackInfo == NULL) {\r
823 return EFI_OUT_OF_RESOURCES;\r
824 }\r
825\r
826 //\r
827 // Create LoadOption in BmmCallbackInfo for Driver Callback\r
828 //\r
dce655e8 829 Ptr = AllocateZeroPool (sizeof (BM_LOAD_CONTEXT) + sizeof (BM_FILE_CONTEXT) + sizeof (BM_HANDLE_CONTEXT) + sizeof (BM_MENU_ENTRY));\r
a78b08d1 830 if (Ptr == NULL) {\r
676df92c 831 FreePool (BmmCallbackInfo);\r
93e3992d 832 return EFI_OUT_OF_RESOURCES;\r
833 }\r
834\r
835 //\r
836 // Initialize Bmm callback data.\r
837 //\r
838 BmmCallbackInfo->LoadContext = (BM_LOAD_CONTEXT *) Ptr;\r
839 Ptr += sizeof (BM_LOAD_CONTEXT);\r
840\r
841 BmmCallbackInfo->FileContext = (BM_FILE_CONTEXT *) Ptr;\r
842 Ptr += sizeof (BM_FILE_CONTEXT);\r
843\r
844 BmmCallbackInfo->HandleContext = (BM_HANDLE_CONTEXT *) Ptr;\r
845 Ptr += sizeof (BM_HANDLE_CONTEXT);\r
846\r
847 BmmCallbackInfo->MenuEntry = (BM_MENU_ENTRY *) Ptr;\r
848\r
849 BmmCallbackInfo->Signature = BMM_CALLBACK_DATA_SIGNATURE;\r
850 BmmCallbackInfo->BmmConfigAccess.ExtractConfig = BootMaintExtractConfig;\r
851 BmmCallbackInfo->BmmConfigAccess.RouteConfig = FakeRouteConfig;\r
852 BmmCallbackInfo->BmmConfigAccess.Callback = BootMaintCallback;\r
853 BmmCallbackInfo->BmmPreviousPageId = FORM_MAIN_ID;\r
854 BmmCallbackInfo->BmmCurrentPageId = FORM_MAIN_ID;\r
855 BmmCallbackInfo->FeConfigAccess.ExtractConfig = FakeExtractConfig;\r
856 BmmCallbackInfo->FeConfigAccess.RouteConfig = FakeRouteConfig;\r
857 BmmCallbackInfo->FeConfigAccess.Callback = FileExplorerCallback;\r
858 BmmCallbackInfo->FeCurrentState = INACTIVE_STATE;\r
859 BmmCallbackInfo->FeDisplayContext = UNKNOWN_CONTEXT;\r
860\r
861 //\r
862 // Create driver handle used by HII database\r
863 //\r
864 Status = HiiLibCreateHiiDriverHandle (&BmmCallbackInfo->BmmDriverHandle);\r
865 if (EFI_ERROR (Status)) {\r
866 return Status;\r
867 }\r
868\r
869 //\r
870 // Install Config Access protocol to driver handle\r
871 //\r
872 Status = gBS->InstallProtocolInterface (\r
873 &BmmCallbackInfo->BmmDriverHandle,\r
874 &gEfiHiiConfigAccessProtocolGuid,\r
875 EFI_NATIVE_INTERFACE,\r
876 &BmmCallbackInfo->BmmConfigAccess\r
877 );\r
878 if (EFI_ERROR (Status)) {\r
879 return Status;\r
880 }\r
881\r
882 //\r
883 // Create driver handle used by HII database\r
884 //\r
885 Status = HiiLibCreateHiiDriverHandle (&BmmCallbackInfo->FeDriverHandle);\r
886 if (EFI_ERROR (Status)) {\r
887 return Status;\r
888 }\r
889\r
890 //\r
891 // Install Config Access protocol to driver handle\r
892 //\r
893 Status = gBS->InstallProtocolInterface (\r
894 &BmmCallbackInfo->FeDriverHandle,\r
895 &gEfiHiiConfigAccessProtocolGuid,\r
896 EFI_NATIVE_INTERFACE,\r
897 &BmmCallbackInfo->FeConfigAccess\r
898 );\r
899 if (EFI_ERROR (Status)) {\r
900 return Status;\r
901 }\r
902\r
903 //\r
904 // Post our Boot Maint VFR binnary to the HII database.\r
905 //\r
062539cf 906 PackageList = HiiLibPreparePackageList (2, &mBootMaintGuid, BmBin, BdsDxeStrings);\r
93e3992d 907 ASSERT (PackageList != NULL);\r
908\r
909 Status = gHiiDatabase->NewPackageList (\r
910 gHiiDatabase,\r
911 PackageList,\r
912 BmmCallbackInfo->BmmDriverHandle,\r
913 &BmmCallbackInfo->BmmHiiHandle\r
914 );\r
915 FreePool (PackageList);\r
916\r
917 //\r
918 // Post our File Explorer VFR binary to the HII database.\r
919 //\r
062539cf 920 PackageList = HiiLibPreparePackageList (2, &mFileExplorerGuid, FEBin, BdsDxeStrings);\r
93e3992d 921 ASSERT (PackageList != NULL);\r
922\r
923 Status = gHiiDatabase->NewPackageList (\r
924 gHiiDatabase,\r
925 PackageList,\r
926 BmmCallbackInfo->FeDriverHandle,\r
927 &BmmCallbackInfo->FeHiiHandle\r
928 );\r
929 FreePool (PackageList);\r
930\r
931 //\r
932 // Allocate space for creation of Buffer\r
933 //\r
934 gUpdateData.BufferSize = UPDATE_DATA_SIZE;\r
dce655e8 935 gUpdateData.Data = AllocateZeroPool (UPDATE_DATA_SIZE);\r
93e3992d 936 if (gUpdateData.Data == NULL) {\r
676df92c 937 FreePool (BmmCallbackInfo->LoadContext);\r
938 FreePool (BmmCallbackInfo);\r
93e3992d 939 return EFI_OUT_OF_RESOURCES;\r
940 }\r
941\r
942 InitializeStringDepository ();\r
943\r
944 InitAllMenu (BmmCallbackInfo);\r
945\r
946 CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &ConsoleInpMenu);\r
947 CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &ConsoleOutMenu);\r
948 CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &ConsoleErrMenu);\r
949 CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &BootOptionMenu);\r
950 CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &DriverOptionMenu);\r
951 CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &TerminalMenu);\r
952 CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &DriverMenu);\r
953\r
954 UpdateBootDelPage (BmmCallbackInfo);\r
955 UpdateDrvDelPage (BmmCallbackInfo);\r
956\r
957 if (TerminalMenu.MenuNumber > 0) {\r
958 BmmCallbackInfo->CurrentTerminal = 0;\r
959 UpdateTerminalPage (BmmCallbackInfo);\r
960 }\r
961\r
962 Status = EfiLibLocateProtocol (&gEfiLegacyBiosProtocolGuid, (VOID **) &LegacyBios);\r
963 if (!EFI_ERROR (Status)) {\r
964 RefreshUpdateData ();\r
965\r
966 //\r
967 // If LegacyBios Protocol is installed, add 3 tags about legacy boot option\r
968 // in BootOption form: legacy FD/HD/CD/NET/BEV\r
969 //\r
970 CreateGotoOpCode (\r
971 FORM_SET_FD_ORDER_ID,\r
972 STRING_TOKEN (STR_FORM_SET_FD_ORDER_TITLE),\r
973 STRING_TOKEN (STR_FORM_SET_FD_ORDER_TITLE),\r
974 EFI_IFR_FLAG_CALLBACK,\r
975 FORM_SET_FD_ORDER_ID,\r
976 &gUpdateData\r
977 );\r
978\r
979 CreateGotoOpCode (\r
980 FORM_SET_HD_ORDER_ID,\r
981 STRING_TOKEN (STR_FORM_SET_HD_ORDER_TITLE),\r
982 STRING_TOKEN (STR_FORM_SET_HD_ORDER_TITLE),\r
983 EFI_IFR_FLAG_CALLBACK,\r
984 FORM_SET_HD_ORDER_ID,\r
985 &gUpdateData\r
986 );\r
987\r
988 CreateGotoOpCode (\r
989 FORM_SET_CD_ORDER_ID,\r
990 STRING_TOKEN (STR_FORM_SET_CD_ORDER_TITLE),\r
991 STRING_TOKEN (STR_FORM_SET_CD_ORDER_TITLE),\r
992 EFI_IFR_FLAG_CALLBACK,\r
993 FORM_SET_CD_ORDER_ID,\r
994 &gUpdateData\r
995 );\r
996\r
997 CreateGotoOpCode (\r
998 FORM_SET_NET_ORDER_ID,\r
999 STRING_TOKEN (STR_FORM_SET_NET_ORDER_TITLE),\r
1000 STRING_TOKEN (STR_FORM_SET_NET_ORDER_TITLE),\r
1001 EFI_IFR_FLAG_CALLBACK,\r
1002 FORM_SET_NET_ORDER_ID,\r
1003 &gUpdateData\r
1004 );\r
1005\r
1006 CreateGotoOpCode (\r
1007 FORM_SET_BEV_ORDER_ID,\r
1008 STRING_TOKEN (STR_FORM_SET_BEV_ORDER_TITLE),\r
1009 STRING_TOKEN (STR_FORM_SET_BEV_ORDER_TITLE),\r
1010 EFI_IFR_FLAG_CALLBACK,\r
1011 FORM_SET_BEV_ORDER_ID,\r
1012 &gUpdateData\r
1013 );\r
1014\r
1015 IfrLibUpdateForm (\r
1016 BmmCallbackInfo->BmmHiiHandle,\r
1017 &mBootMaintGuid,\r
1018 FORM_MAIN_ID,\r
1019 FORM_BOOT_LEGACY_DEVICE_ID,\r
1020 FALSE,\r
1021 &gUpdateData\r
1022 );\r
1023 }\r
1024\r
1025 //\r
1026 // Dispatch BMM main formset and File Explorer formset.\r
1027 //\r
1028 FormSetDispatcher (BmmCallbackInfo);\r
1029\r
1030 //\r
1031 // Remove our IFR data from HII database\r
1032 //\r
1033 gHiiDatabase->RemovePackageList (gHiiDatabase, BmmCallbackInfo->BmmHiiHandle);\r
1034 gHiiDatabase->RemovePackageList (gHiiDatabase, BmmCallbackInfo->FeHiiHandle);\r
1035\r
1036 CleanUpStringDepository ();\r
1037\r
1038 FreeAllMenu ();\r
1039\r
676df92c 1040 FreePool (BmmCallbackInfo->LoadContext);\r
1041 FreePool (BmmCallbackInfo);\r
1042 FreePool (gUpdateData.Data);\r
93e3992d 1043 gUpdateData.Data = NULL;\r
1044\r
1045 return Status;\r
1046}\r
1047\r
b30312ba 1048/**\r
dce655e8 1049 Initialized all Menu Option List.\r
b30312ba 1050\r
dce655e8 1051 @param CallbackData The BMM context data.\r
b30312ba 1052\r
b30312ba 1053**/\r
93e3992d 1054VOID\r
1055InitAllMenu (\r
1056 IN BMM_CALLBACK_DATA *CallbackData\r
1057 )\r
1058{\r
1059 InitializeListHead (&BootOptionMenu.Head);\r
1060 InitializeListHead (&DriverOptionMenu.Head);\r
1061 BOpt_GetBootOptions (CallbackData);\r
1062 BOpt_GetDriverOptions (CallbackData);\r
1063 BOpt_GetLegacyOptions ();\r
1064 InitializeListHead (&FsOptionMenu.Head);\r
1065 BOpt_FindDrivers ();\r
1066 InitializeListHead (&DirectoryMenu.Head);\r
1067 InitializeListHead (&ConsoleInpMenu.Head);\r
1068 InitializeListHead (&ConsoleOutMenu.Head);\r
1069 InitializeListHead (&ConsoleErrMenu.Head);\r
1070 InitializeListHead (&TerminalMenu.Head);\r
1071 LocateSerialIo ();\r
1072 GetAllConsoles ();\r
1073}\r
1074\r
b30312ba 1075/**\r
dce655e8 1076 Free up all Menu Option list.\r
b30312ba 1077\r
b30312ba 1078**/\r
93e3992d 1079VOID\r
1080FreeAllMenu (\r
1081 VOID\r
1082 )\r
1083{\r
1084 BOpt_FreeMenu (&DirectoryMenu);\r
1085 BOpt_FreeMenu (&FsOptionMenu);\r
1086 BOpt_FreeMenu (&BootOptionMenu);\r
1087 BOpt_FreeMenu (&DriverOptionMenu);\r
1088 BOpt_FreeMenu (&DriverMenu);\r
1089 BOpt_FreeLegacyOptions ();\r
1090 FreeAllConsoles ();\r
1091}\r
1092\r
b30312ba 1093/**\r
93e3992d 1094 Intialize all the string depositories.\r
1095\r
b30312ba 1096**/\r
1097VOID\r
1098InitializeStringDepository (\r
1099 VOID\r
1100 )\r
93e3992d 1101{\r
1102 STRING_DEPOSITORY *StringDepository;\r
dce655e8 1103 StringDepository = AllocateZeroPool (sizeof (STRING_DEPOSITORY) * STRING_DEPOSITORY_NUMBER);\r
93e3992d 1104 FileOptionStrDepository = StringDepository++;\r
1105 ConsoleOptionStrDepository = StringDepository++;\r
1106 BootOptionStrDepository = StringDepository++;\r
1107 BootOptionHelpStrDepository = StringDepository++;\r
1108 DriverOptionStrDepository = StringDepository++;\r
1109 DriverOptionHelpStrDepository = StringDepository++;\r
1110 TerminalStrDepository = StringDepository;\r
1111}\r
1112\r
b30312ba 1113/**\r
1114 Fetch a usable string node from the string depository and return the string token.\r
1115\r
2e9f9668 1116 @param CallbackData The BMM context data.\r
1117 @param StringDepository The string repository.\r
b30312ba 1118\r
1119 @retval EFI_STRING_ID String token.\r
1120\r
1121**/\r
93e3992d 1122EFI_STRING_ID\r
1123GetStringTokenFromDepository (\r
1124 IN BMM_CALLBACK_DATA *CallbackData,\r
1125 IN STRING_DEPOSITORY *StringDepository\r
1126 )\r
93e3992d 1127{\r
1128 STRING_LIST_NODE *CurrentListNode;\r
1129 STRING_LIST_NODE *NextListNode;\r
1130\r
1131 CurrentListNode = StringDepository->CurrentNode;\r
1132\r
1133 if ((NULL != CurrentListNode) && (NULL != CurrentListNode->Next)) {\r
1134 //\r
1135 // Fetch one reclaimed node from the list.\r
1136 //\r
1137 NextListNode = StringDepository->CurrentNode->Next;\r
1138 } else {\r
1139 //\r
1140 // If there is no usable node in the list, update the list.\r
1141 //\r
dce655e8 1142 NextListNode = AllocateZeroPool (sizeof (STRING_LIST_NODE));\r
93e3992d 1143\r
9226efe5 1144 HiiLibNewString (CallbackData->BmmHiiHandle, &(NextListNode->StringToken), L" ");\r
93e3992d 1145 ASSERT (NextListNode->StringToken != 0);\r
1146\r
1147 StringDepository->TotalNodeNumber++;\r
1148\r
1149 if (NULL == CurrentListNode) {\r
1150 StringDepository->ListHead = NextListNode;\r
1151 } else {\r
1152 CurrentListNode->Next = NextListNode;\r
1153 }\r
1154 }\r
1155\r
1156 StringDepository->CurrentNode = NextListNode;\r
1157\r
1158 return StringDepository->CurrentNode->StringToken;\r
1159}\r
1160\r
b30312ba 1161/**\r
93e3992d 1162 Reclaim string depositories by moving the current node pointer to list head..\r
1163\r
b30312ba 1164**/\r
1165VOID\r
1166ReclaimStringDepository (\r
1167 VOID\r
1168 )\r
93e3992d 1169{\r
1170 UINTN DepositoryIndex;\r
1171 STRING_DEPOSITORY *StringDepository;\r
1172\r
1173 StringDepository = FileOptionStrDepository;\r
1174 for (DepositoryIndex = 0; DepositoryIndex < STRING_DEPOSITORY_NUMBER; DepositoryIndex++) {\r
1175 StringDepository->CurrentNode = StringDepository->ListHead;\r
1176 StringDepository++;\r
1177 }\r
1178}\r
1179\r
b30312ba 1180/**\r
93e3992d 1181 Release resource for all the string depositories.\r
1182\r
b30312ba 1183**/\r
1184VOID\r
1185CleanUpStringDepository (\r
1186 VOID\r
1187 )\r
93e3992d 1188{\r
1189 UINTN NodeIndex;\r
1190 UINTN DepositoryIndex;\r
1191 STRING_LIST_NODE *CurrentListNode;\r
1192 STRING_LIST_NODE *NextListNode;\r
1193 STRING_DEPOSITORY *StringDepository;\r
1194\r
1195 //\r
1196 // Release string list nodes.\r
1197 //\r
1198 StringDepository = FileOptionStrDepository;\r
1199 for (DepositoryIndex = 0; DepositoryIndex < STRING_DEPOSITORY_NUMBER; DepositoryIndex++) {\r
1200 CurrentListNode = StringDepository->ListHead;\r
1201 for (NodeIndex = 0; NodeIndex < StringDepository->TotalNodeNumber; NodeIndex++) {\r
1202 NextListNode = CurrentListNode->Next;\r
676df92c 1203 FreePool (CurrentListNode);\r
93e3992d 1204 CurrentListNode = NextListNode;\r
1205 }\r
1206\r
1207 StringDepository++;\r
1208 }\r
1209 //\r
1210 // Release string depository.\r
1211 //\r
676df92c 1212 FreePool (FileOptionStrDepository);\r
93e3992d 1213}\r
1214\r
b30312ba 1215/**\r
93e3992d 1216 Start boot maintenance manager\r
1217\r
dce655e8 1218 @retval EFI_SUCCESS If BMM is invoked successfully.\r
1219 @return Other value if BMM return unsuccessfully.\r
93e3992d 1220\r
b30312ba 1221**/\r
1222EFI_STATUS\r
1223BdsStartBootMaint (\r
1224 VOID\r
1225 )\r
93e3992d 1226{\r
1227 EFI_STATUS Status;\r
1228 LIST_ENTRY BdsBootOptionList;\r
1229\r
1230 InitializeListHead (&BdsBootOptionList);\r
1231\r
1232 //\r
1233 // Connect all prior to entering the platform setup menu.\r
1234 //\r
1235 if (!gConnectAllHappened) {\r
1236 BdsLibConnectAllDriversToAllControllers ();\r
1237 gConnectAllHappened = TRUE;\r
1238 }\r
1239 //\r
1240 // Have chance to enumerate boot device\r
1241 //\r
1242 BdsLibEnumerateAllBootOption (&BdsBootOptionList);\r
1243\r
93e3992d 1244 //\r
1245 // Init the BMM\r
1246 //\r
1247 Status = InitializeBM ();\r
1248\r
93e3992d 1249 return Status;\r
1250}\r
1251\r
b30312ba 1252/**\r
93e3992d 1253 Dispatch BMM formset and FileExplorer formset.\r
1254\r
93e3992d 1255\r
dce655e8 1256 @param CallbackData The BMM context data.\r
93e3992d 1257\r
dce655e8 1258 @retval EFI_SUCCESS If function complete successfully.\r
744fc758 1259 @return Other value if the Setup Browser process BMM's pages and\r
dce655e8 1260 return unsuccessfully.\r
b30312ba 1261\r
1262**/\r
1263EFI_STATUS\r
1264FormSetDispatcher (\r
1265 IN BMM_CALLBACK_DATA *CallbackData\r
1266 )\r
93e3992d 1267{\r
1268 EFI_STATUS Status;\r
1269 EFI_BROWSER_ACTION_REQUEST ActionRequest;\r
1270\r
1271 while (TRUE) {\r
1272 UpdatePageId (CallbackData, FORM_MAIN_ID);\r
1273\r
1274 ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;\r
1275 Status = gFormBrowser2->SendForm (\r
1276 gFormBrowser2,\r
1277 &CallbackData->BmmHiiHandle,\r
1278 1,\r
1279 NULL,\r
1280 0,\r
1281 NULL,\r
1282 &ActionRequest\r
1283 );\r
1284 if (ActionRequest == EFI_BROWSER_ACTION_REQUEST_RESET) {\r
1285 EnableResetRequired ();\r
1286 }\r
1287\r
1288 ReclaimStringDepository ();\r
1289\r
1290 //\r
1291 // When this Formset returns, check if we are going to explore files.\r
1292 //\r
1293 if (INACTIVE_STATE != CallbackData->FeCurrentState) {\r
1294 UpdateFileExplorer (CallbackData, 0);\r
1295\r
1296 ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;\r
1297 Status = gFormBrowser2->SendForm (\r
1298 gFormBrowser2,\r
1299 &CallbackData->FeHiiHandle,\r
1300 1,\r
1301 NULL,\r
1302 0,\r
1303 NULL,\r
1304 &ActionRequest\r
1305 );\r
1306 if (ActionRequest == EFI_BROWSER_ACTION_REQUEST_RESET) {\r
1307 EnableResetRequired ();\r
1308 }\r
1309\r
1310 CallbackData->FeCurrentState = INACTIVE_STATE;\r
1311 CallbackData->FeDisplayContext = UNKNOWN_CONTEXT;\r
1312 ReclaimStringDepository ();\r
1313 } else {\r
1314 break;\r
1315 }\r
1316 }\r
1317\r
1318 return Status;\r
1319}\r
1320\r
dce655e8 1321\r
1322/**\r
1323 Deletete the Boot Option from EFI Variable. The Boot Order Arrray\r
1324 is also updated.\r
1325\r
2e9f9668 1326 @param OptionNumber The number of Boot option want to be deleted.\r
dce655e8 1327 @param BootOrder The Boot Order array.\r
1328 @param BootOrderSize The size of the Boot Order Array.\r
1329\r
1330 @return Other value if the Boot Option specified by OptionNumber is not deleteed succesfully.\r
1331 @retval EFI_SUCCESS If function return successfully.\r
1332\r
1333**/\r
1334EFI_STATUS\r
1335BdsDeleteBootOption (\r
1336 IN UINTN OptionNumber,\r
1337 IN OUT UINT16 *BootOrder,\r
1338 IN OUT UINTN *BootOrderSize\r
1339 )\r
1340{\r
1341 UINT16 BootOption[100];\r
1342 UINTN Index;\r
1343 EFI_STATUS Status;\r
1344 UINTN Index2Del;\r
1345\r
1346 Status = EFI_SUCCESS;\r
1347 Index2Del = 0;\r
1348\r
1349 UnicodeSPrint (BootOption, sizeof (BootOption), L"Boot%04x", OptionNumber);\r
1350 Status = EfiLibDeleteVariable (BootOption, &gEfiGlobalVariableGuid);\r
2e9f9668 1351 \r
dce655e8 1352 //\r
1353 // adjust boot order array\r
1354 //\r
1355 for (Index = 0; Index < *BootOrderSize / sizeof (UINT16); Index++) {\r
1356 if (BootOrder[Index] == OptionNumber) {\r
1357 Index2Del = Index;\r
1358 break;\r
1359 }\r
1360 }\r
1361\r
1362 if (Index != *BootOrderSize / sizeof (UINT16)) {\r
1363 for (Index = 0; Index < *BootOrderSize / sizeof (UINT16) - 1; Index++) {\r
1364 if (Index >= Index2Del) {\r
1365 BootOrder[Index] = BootOrder[Index + 1];\r
1366 }\r
1367 }\r
1368\r
1369 *BootOrderSize -= sizeof (UINT16);\r
1370 }\r
1371\r
1372 return Status;\r
1373\r
1374}\r
1375\r
1376\r