]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/BdsDxe/BootMaint/BootMaint.c
Add check when use Index as Array [Index] to avoid out of Array bound.
[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
583 for (Index = 0; Index < BootOptionMenu.MenuNumber; Index++) {\r
584 NewMenuEntry = BOpt_GetMenuEntry (&BootOptionMenu, Index);\r
585 NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;\r
586 NewLoadContext->Deleted = CurrentFakeNVMap->BootOptionDel[Index];\r
587 }\r
588\r
589 Var_DelBootOption ();\r
590 break;\r
591\r
592 case FORM_DRV_DEL_ID:\r
593 for (Index = 0; Index < DriverOptionMenu.MenuNumber; Index++) {\r
594 NewMenuEntry = BOpt_GetMenuEntry (&DriverOptionMenu, Index);\r
595 NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;\r
596 NewLoadContext->Deleted = CurrentFakeNVMap->DriverOptionDel[Index];\r
597 }\r
598\r
599 Var_DelDriverOption ();\r
600 break;\r
601\r
602 case FORM_BOOT_CHG_ID:\r
603 Status = Var_UpdateBootOrder (Private);\r
604 break;\r
605\r
606 case FORM_DRV_CHG_ID:\r
607 Status = Var_UpdateDriverOrder (Private);\r
608 break;\r
609\r
610 case FORM_TIME_OUT_ID:\r
611 Status = gRT->SetVariable (\r
612 L"Timeout",\r
613 &gEfiGlobalVariableGuid,\r
614 VAR_FLAG,\r
615 sizeof (UINT16),\r
616 &(CurrentFakeNVMap->BootTimeOut)\r
617 );\r
618 if (EFI_ERROR (Status)) {\r
619 goto Error;\r
620 }\r
621\r
622 Private->BmmOldFakeNVData.BootTimeOut = CurrentFakeNVMap->BootTimeOut;\r
623 break;\r
624\r
625 case FORM_BOOT_NEXT_ID:\r
626 Status = Var_UpdateBootNext (Private);\r
627 break;\r
628\r
629 case FORM_CON_MODE_ID:\r
630 Status = Var_UpdateConMode (Private);\r
631 break;\r
632\r
633 case FORM_CON_COM_SETUP_ID:\r
634 NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Private->CurrentTerminal);\r
635\r
636 ASSERT (NewMenuEntry != NULL);\r
637\r
638 NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;\r
639\r
640 NewTerminalContext->BaudRateIndex = CurrentFakeNVMap->COMBaudRate;\r
641 NewTerminalContext->BaudRate = BaudRateList[CurrentFakeNVMap->COMBaudRate].Value;\r
642 NewTerminalContext->DataBitsIndex = CurrentFakeNVMap->COMDataRate;\r
643 NewTerminalContext->DataBits = (UINT8) DataBitsList[CurrentFakeNVMap->COMDataRate].Value;\r
644 NewTerminalContext->StopBitsIndex = CurrentFakeNVMap->COMStopBits;\r
645 NewTerminalContext->StopBits = (UINT8) StopBitsList[CurrentFakeNVMap->COMStopBits].Value;\r
646 NewTerminalContext->ParityIndex = CurrentFakeNVMap->COMParity;\r
647 NewTerminalContext->Parity = (UINT8) ParityList[CurrentFakeNVMap->COMParity].Value;\r
648 NewTerminalContext->TerminalType = CurrentFakeNVMap->COMTerminalType;\r
649\r
650 ChangeTerminalDevicePath (\r
651 NewTerminalContext->DevicePath,\r
652 FALSE\r
653 );\r
654\r
655 Var_UpdateConsoleInpOption ();\r
656 Var_UpdateConsoleOutOption ();\r
657 Var_UpdateErrorOutOption ();\r
658 break;\r
659\r
660 case FORM_CON_IN_ID:\r
661 for (Index = 0; Index < ConsoleInpMenu.MenuNumber; Index++) {\r
662 NewMenuEntry = BOpt_GetMenuEntry (&ConsoleInpMenu, Index);\r
663 NewConsoleContext = (BM_CONSOLE_CONTEXT *) NewMenuEntry->VariableContext;\r
664 NewConsoleContext->IsActive = CurrentFakeNVMap->ConsoleCheck[Index];\r
665 }\r
666\r
667 for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {\r
668 NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);\r
669 NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;\r
670 NewTerminalContext->IsConIn = CurrentFakeNVMap->ConsoleCheck[Index + ConsoleInpMenu.MenuNumber];\r
671 }\r
672\r
673 Var_UpdateConsoleInpOption ();\r
674 break;\r
675\r
676 case FORM_CON_OUT_ID:\r
677 for (Index = 0; Index < ConsoleOutMenu.MenuNumber; Index++) {\r
678 NewMenuEntry = BOpt_GetMenuEntry (&ConsoleOutMenu, Index);\r
679 NewConsoleContext = (BM_CONSOLE_CONTEXT *) NewMenuEntry->VariableContext;\r
680 NewConsoleContext->IsActive = CurrentFakeNVMap->ConsoleCheck[Index];\r
681 }\r
682\r
683 for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {\r
684 NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);\r
685 NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;\r
686 NewTerminalContext->IsConOut = CurrentFakeNVMap->ConsoleCheck[Index + ConsoleOutMenu.MenuNumber];\r
687 }\r
688\r
689 Var_UpdateConsoleOutOption ();\r
690 break;\r
691\r
692 case FORM_CON_ERR_ID:\r
693 for (Index = 0; Index < ConsoleErrMenu.MenuNumber; Index++) {\r
694 NewMenuEntry = BOpt_GetMenuEntry (&ConsoleErrMenu, Index);\r
695 NewConsoleContext = (BM_CONSOLE_CONTEXT *) NewMenuEntry->VariableContext;\r
696 NewConsoleContext->IsActive = CurrentFakeNVMap->ConsoleCheck[Index];\r
697 }\r
698\r
699 for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {\r
700 NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);\r
701 NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;\r
702 NewTerminalContext->IsStdErr = CurrentFakeNVMap->ConsoleCheck[Index + ConsoleErrMenu.MenuNumber];\r
703 }\r
704\r
705 Var_UpdateErrorOutOption ();\r
706 break;\r
707\r
708 case FORM_DRV_ADD_HANDLE_DESC_ID:\r
709 Status = Var_UpdateDriverOption (\r
710 Private,\r
711 Private->BmmHiiHandle,\r
712 CurrentFakeNVMap->DriverAddHandleDesc,\r
713 CurrentFakeNVMap->DriverAddHandleOptionalData,\r
714 CurrentFakeNVMap->DriverAddForceReconnect\r
715 );\r
716 if (EFI_ERROR (Status)) {\r
717 goto Error;\r
718 }\r
719\r
720 BOpt_GetDriverOptions (Private);\r
721 CreateMenuStringToken (Private, Private->BmmHiiHandle, &DriverOptionMenu);\r
722 break;\r
723\r
724 default:\r
725 break;\r
726 }\r
727\r
728Error:\r
729 return Status;\r
730}\r
731\r
b30312ba 732/**\r
dce655e8 733 Discard all changes done to the BMM pages such as Boot Order change,\r
734 Driver order change.\r
b30312ba 735\r
30394aa1 736 @param Private The BMM context data.\r
737 @param CurrentFakeNVMap The current Fack NV Map.\r
b30312ba 738\r
739**/\r
93e3992d 740VOID\r
741DiscardChangeHandler (\r
742 IN BMM_CALLBACK_DATA *Private,\r
743 IN BMM_FAKE_NV_DATA *CurrentFakeNVMap\r
744 )\r
745{\r
746 UINT16 Index;\r
747\r
748 switch (Private->BmmPreviousPageId) {\r
749 case FORM_BOOT_CHG_ID:\r
750 case FORM_DRV_CHG_ID:\r
751 CopyMem (CurrentFakeNVMap->OptionOrder, Private->BmmOldFakeNVData.OptionOrder, 100);\r
752 break;\r
753\r
754 case FORM_BOOT_DEL_ID:\r
755 for (Index = 0; Index < BootOptionMenu.MenuNumber; Index++) {\r
756 CurrentFakeNVMap->BootOptionDel[Index] = 0x00;\r
757 }\r
758 break;\r
759\r
760 case FORM_DRV_DEL_ID:\r
761 for (Index = 0; Index < DriverOptionMenu.MenuNumber; Index++) {\r
762 CurrentFakeNVMap->DriverOptionDel[Index] = 0x00;\r
763 }\r
764 break;\r
765\r
766 case FORM_BOOT_NEXT_ID:\r
767 CurrentFakeNVMap->BootNext = Private->BmmOldFakeNVData.BootNext;\r
768 break;\r
769\r
770 case FORM_TIME_OUT_ID:\r
771 CurrentFakeNVMap->BootTimeOut = Private->BmmOldFakeNVData.BootTimeOut;\r
772 break;\r
773\r
774 case FORM_DRV_ADD_HANDLE_DESC_ID:\r
775 case FORM_DRV_ADD_FILE_ID:\r
776 case FORM_DRV_ADD_HANDLE_ID:\r
777 CurrentFakeNVMap->DriverAddHandleDesc[0] = 0x0000;\r
778 CurrentFakeNVMap->DriverAddHandleOptionalData[0] = 0x0000;\r
779 break;\r
780\r
781 default:\r
782 break;\r
783 }\r
784}\r
785\r
b30312ba 786/**\r
744fc758 787 Initialize the Boot Maintenance Utitliy.\r
93e3992d 788\r
93e3992d 789\r
b30312ba 790 @retval EFI_SUCCESS utility ended successfully\r
791 @retval others contain some errors\r
792\r
793**/\r
794EFI_STATUS\r
795InitializeBM (\r
796 VOID\r
797 )\r
93e3992d 798{\r
799 EFI_LEGACY_BIOS_PROTOCOL *LegacyBios;\r
800 EFI_HII_PACKAGE_LIST_HEADER *PackageList;\r
801 BMM_CALLBACK_DATA *BmmCallbackInfo;\r
802 EFI_STATUS Status;\r
803 UINT8 *Ptr;\r
804\r
805 Status = EFI_SUCCESS;\r
806\r
807 //\r
808 // Create CallbackData structures for Driver Callback\r
809 //\r
dce655e8 810 BmmCallbackInfo = AllocateZeroPool (sizeof (BMM_CALLBACK_DATA));\r
93e3992d 811 if (BmmCallbackInfo == NULL) {\r
812 return EFI_OUT_OF_RESOURCES;\r
813 }\r
814\r
815 //\r
816 // Create LoadOption in BmmCallbackInfo for Driver Callback\r
817 //\r
dce655e8 818 Ptr = AllocateZeroPool (sizeof (BM_LOAD_CONTEXT) + sizeof (BM_FILE_CONTEXT) + sizeof (BM_HANDLE_CONTEXT) + sizeof (BM_MENU_ENTRY));\r
a78b08d1 819 if (Ptr == NULL) {\r
676df92c 820 FreePool (BmmCallbackInfo);\r
93e3992d 821 return EFI_OUT_OF_RESOURCES;\r
822 }\r
823\r
824 //\r
825 // Initialize Bmm callback data.\r
826 //\r
827 BmmCallbackInfo->LoadContext = (BM_LOAD_CONTEXT *) Ptr;\r
828 Ptr += sizeof (BM_LOAD_CONTEXT);\r
829\r
830 BmmCallbackInfo->FileContext = (BM_FILE_CONTEXT *) Ptr;\r
831 Ptr += sizeof (BM_FILE_CONTEXT);\r
832\r
833 BmmCallbackInfo->HandleContext = (BM_HANDLE_CONTEXT *) Ptr;\r
834 Ptr += sizeof (BM_HANDLE_CONTEXT);\r
835\r
836 BmmCallbackInfo->MenuEntry = (BM_MENU_ENTRY *) Ptr;\r
837\r
838 BmmCallbackInfo->Signature = BMM_CALLBACK_DATA_SIGNATURE;\r
839 BmmCallbackInfo->BmmConfigAccess.ExtractConfig = BootMaintExtractConfig;\r
840 BmmCallbackInfo->BmmConfigAccess.RouteConfig = FakeRouteConfig;\r
841 BmmCallbackInfo->BmmConfigAccess.Callback = BootMaintCallback;\r
842 BmmCallbackInfo->BmmPreviousPageId = FORM_MAIN_ID;\r
843 BmmCallbackInfo->BmmCurrentPageId = FORM_MAIN_ID;\r
844 BmmCallbackInfo->FeConfigAccess.ExtractConfig = FakeExtractConfig;\r
845 BmmCallbackInfo->FeConfigAccess.RouteConfig = FakeRouteConfig;\r
846 BmmCallbackInfo->FeConfigAccess.Callback = FileExplorerCallback;\r
847 BmmCallbackInfo->FeCurrentState = INACTIVE_STATE;\r
848 BmmCallbackInfo->FeDisplayContext = UNKNOWN_CONTEXT;\r
849\r
850 //\r
851 // Create driver handle used by HII database\r
852 //\r
853 Status = HiiLibCreateHiiDriverHandle (&BmmCallbackInfo->BmmDriverHandle);\r
854 if (EFI_ERROR (Status)) {\r
855 return Status;\r
856 }\r
857\r
858 //\r
859 // Install Config Access protocol to driver handle\r
860 //\r
861 Status = gBS->InstallProtocolInterface (\r
862 &BmmCallbackInfo->BmmDriverHandle,\r
863 &gEfiHiiConfigAccessProtocolGuid,\r
864 EFI_NATIVE_INTERFACE,\r
865 &BmmCallbackInfo->BmmConfigAccess\r
866 );\r
867 if (EFI_ERROR (Status)) {\r
868 return Status;\r
869 }\r
870\r
871 //\r
872 // Create driver handle used by HII database\r
873 //\r
874 Status = HiiLibCreateHiiDriverHandle (&BmmCallbackInfo->FeDriverHandle);\r
875 if (EFI_ERROR (Status)) {\r
876 return Status;\r
877 }\r
878\r
879 //\r
880 // Install Config Access protocol to driver handle\r
881 //\r
882 Status = gBS->InstallProtocolInterface (\r
883 &BmmCallbackInfo->FeDriverHandle,\r
884 &gEfiHiiConfigAccessProtocolGuid,\r
885 EFI_NATIVE_INTERFACE,\r
886 &BmmCallbackInfo->FeConfigAccess\r
887 );\r
888 if (EFI_ERROR (Status)) {\r
889 return Status;\r
890 }\r
891\r
892 //\r
893 // Post our Boot Maint VFR binnary to the HII database.\r
894 //\r
062539cf 895 PackageList = HiiLibPreparePackageList (2, &mBootMaintGuid, BmBin, BdsDxeStrings);\r
93e3992d 896 ASSERT (PackageList != NULL);\r
897\r
898 Status = gHiiDatabase->NewPackageList (\r
899 gHiiDatabase,\r
900 PackageList,\r
901 BmmCallbackInfo->BmmDriverHandle,\r
902 &BmmCallbackInfo->BmmHiiHandle\r
903 );\r
904 FreePool (PackageList);\r
905\r
906 //\r
907 // Post our File Explorer VFR binary to the HII database.\r
908 //\r
062539cf 909 PackageList = HiiLibPreparePackageList (2, &mFileExplorerGuid, FEBin, BdsDxeStrings);\r
93e3992d 910 ASSERT (PackageList != NULL);\r
911\r
912 Status = gHiiDatabase->NewPackageList (\r
913 gHiiDatabase,\r
914 PackageList,\r
915 BmmCallbackInfo->FeDriverHandle,\r
916 &BmmCallbackInfo->FeHiiHandle\r
917 );\r
918 FreePool (PackageList);\r
919\r
920 //\r
921 // Allocate space for creation of Buffer\r
922 //\r
923 gUpdateData.BufferSize = UPDATE_DATA_SIZE;\r
dce655e8 924 gUpdateData.Data = AllocateZeroPool (UPDATE_DATA_SIZE);\r
93e3992d 925 if (gUpdateData.Data == NULL) {\r
676df92c 926 FreePool (BmmCallbackInfo->LoadContext);\r
927 FreePool (BmmCallbackInfo);\r
93e3992d 928 return EFI_OUT_OF_RESOURCES;\r
929 }\r
930\r
931 InitializeStringDepository ();\r
932\r
933 InitAllMenu (BmmCallbackInfo);\r
934\r
935 CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &ConsoleInpMenu);\r
936 CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &ConsoleOutMenu);\r
937 CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &ConsoleErrMenu);\r
938 CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &BootOptionMenu);\r
939 CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &DriverOptionMenu);\r
940 CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &TerminalMenu);\r
941 CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &DriverMenu);\r
942\r
943 UpdateBootDelPage (BmmCallbackInfo);\r
944 UpdateDrvDelPage (BmmCallbackInfo);\r
945\r
946 if (TerminalMenu.MenuNumber > 0) {\r
947 BmmCallbackInfo->CurrentTerminal = 0;\r
948 UpdateTerminalPage (BmmCallbackInfo);\r
949 }\r
950\r
951 Status = EfiLibLocateProtocol (&gEfiLegacyBiosProtocolGuid, (VOID **) &LegacyBios);\r
952 if (!EFI_ERROR (Status)) {\r
953 RefreshUpdateData ();\r
954\r
955 //\r
956 // If LegacyBios Protocol is installed, add 3 tags about legacy boot option\r
957 // in BootOption form: legacy FD/HD/CD/NET/BEV\r
958 //\r
959 CreateGotoOpCode (\r
960 FORM_SET_FD_ORDER_ID,\r
961 STRING_TOKEN (STR_FORM_SET_FD_ORDER_TITLE),\r
962 STRING_TOKEN (STR_FORM_SET_FD_ORDER_TITLE),\r
963 EFI_IFR_FLAG_CALLBACK,\r
964 FORM_SET_FD_ORDER_ID,\r
965 &gUpdateData\r
966 );\r
967\r
968 CreateGotoOpCode (\r
969 FORM_SET_HD_ORDER_ID,\r
970 STRING_TOKEN (STR_FORM_SET_HD_ORDER_TITLE),\r
971 STRING_TOKEN (STR_FORM_SET_HD_ORDER_TITLE),\r
972 EFI_IFR_FLAG_CALLBACK,\r
973 FORM_SET_HD_ORDER_ID,\r
974 &gUpdateData\r
975 );\r
976\r
977 CreateGotoOpCode (\r
978 FORM_SET_CD_ORDER_ID,\r
979 STRING_TOKEN (STR_FORM_SET_CD_ORDER_TITLE),\r
980 STRING_TOKEN (STR_FORM_SET_CD_ORDER_TITLE),\r
981 EFI_IFR_FLAG_CALLBACK,\r
982 FORM_SET_CD_ORDER_ID,\r
983 &gUpdateData\r
984 );\r
985\r
986 CreateGotoOpCode (\r
987 FORM_SET_NET_ORDER_ID,\r
988 STRING_TOKEN (STR_FORM_SET_NET_ORDER_TITLE),\r
989 STRING_TOKEN (STR_FORM_SET_NET_ORDER_TITLE),\r
990 EFI_IFR_FLAG_CALLBACK,\r
991 FORM_SET_NET_ORDER_ID,\r
992 &gUpdateData\r
993 );\r
994\r
995 CreateGotoOpCode (\r
996 FORM_SET_BEV_ORDER_ID,\r
997 STRING_TOKEN (STR_FORM_SET_BEV_ORDER_TITLE),\r
998 STRING_TOKEN (STR_FORM_SET_BEV_ORDER_TITLE),\r
999 EFI_IFR_FLAG_CALLBACK,\r
1000 FORM_SET_BEV_ORDER_ID,\r
1001 &gUpdateData\r
1002 );\r
1003\r
1004 IfrLibUpdateForm (\r
1005 BmmCallbackInfo->BmmHiiHandle,\r
1006 &mBootMaintGuid,\r
1007 FORM_MAIN_ID,\r
1008 FORM_BOOT_LEGACY_DEVICE_ID,\r
1009 FALSE,\r
1010 &gUpdateData\r
1011 );\r
1012 }\r
1013\r
1014 //\r
1015 // Dispatch BMM main formset and File Explorer formset.\r
1016 //\r
1017 FormSetDispatcher (BmmCallbackInfo);\r
1018\r
1019 //\r
1020 // Remove our IFR data from HII database\r
1021 //\r
1022 gHiiDatabase->RemovePackageList (gHiiDatabase, BmmCallbackInfo->BmmHiiHandle);\r
1023 gHiiDatabase->RemovePackageList (gHiiDatabase, BmmCallbackInfo->FeHiiHandle);\r
1024\r
1025 CleanUpStringDepository ();\r
1026\r
1027 FreeAllMenu ();\r
1028\r
676df92c 1029 FreePool (BmmCallbackInfo->LoadContext);\r
1030 FreePool (BmmCallbackInfo);\r
1031 FreePool (gUpdateData.Data);\r
93e3992d 1032 gUpdateData.Data = NULL;\r
1033\r
1034 return Status;\r
1035}\r
1036\r
b30312ba 1037/**\r
dce655e8 1038 Initialized all Menu Option List.\r
b30312ba 1039\r
dce655e8 1040 @param CallbackData The BMM context data.\r
b30312ba 1041\r
b30312ba 1042**/\r
93e3992d 1043VOID\r
1044InitAllMenu (\r
1045 IN BMM_CALLBACK_DATA *CallbackData\r
1046 )\r
1047{\r
1048 InitializeListHead (&BootOptionMenu.Head);\r
1049 InitializeListHead (&DriverOptionMenu.Head);\r
1050 BOpt_GetBootOptions (CallbackData);\r
1051 BOpt_GetDriverOptions (CallbackData);\r
1052 BOpt_GetLegacyOptions ();\r
1053 InitializeListHead (&FsOptionMenu.Head);\r
1054 BOpt_FindDrivers ();\r
1055 InitializeListHead (&DirectoryMenu.Head);\r
1056 InitializeListHead (&ConsoleInpMenu.Head);\r
1057 InitializeListHead (&ConsoleOutMenu.Head);\r
1058 InitializeListHead (&ConsoleErrMenu.Head);\r
1059 InitializeListHead (&TerminalMenu.Head);\r
1060 LocateSerialIo ();\r
1061 GetAllConsoles ();\r
1062}\r
1063\r
b30312ba 1064/**\r
dce655e8 1065 Free up all Menu Option list.\r
b30312ba 1066\r
b30312ba 1067**/\r
93e3992d 1068VOID\r
1069FreeAllMenu (\r
1070 VOID\r
1071 )\r
1072{\r
1073 BOpt_FreeMenu (&DirectoryMenu);\r
1074 BOpt_FreeMenu (&FsOptionMenu);\r
1075 BOpt_FreeMenu (&BootOptionMenu);\r
1076 BOpt_FreeMenu (&DriverOptionMenu);\r
1077 BOpt_FreeMenu (&DriverMenu);\r
1078 BOpt_FreeLegacyOptions ();\r
1079 FreeAllConsoles ();\r
1080}\r
1081\r
b30312ba 1082/**\r
93e3992d 1083 Intialize all the string depositories.\r
1084\r
b30312ba 1085**/\r
1086VOID\r
1087InitializeStringDepository (\r
1088 VOID\r
1089 )\r
93e3992d 1090{\r
1091 STRING_DEPOSITORY *StringDepository;\r
dce655e8 1092 StringDepository = AllocateZeroPool (sizeof (STRING_DEPOSITORY) * STRING_DEPOSITORY_NUMBER);\r
93e3992d 1093 FileOptionStrDepository = StringDepository++;\r
1094 ConsoleOptionStrDepository = StringDepository++;\r
1095 BootOptionStrDepository = StringDepository++;\r
1096 BootOptionHelpStrDepository = StringDepository++;\r
1097 DriverOptionStrDepository = StringDepository++;\r
1098 DriverOptionHelpStrDepository = StringDepository++;\r
1099 TerminalStrDepository = StringDepository;\r
1100}\r
1101\r
b30312ba 1102/**\r
1103 Fetch a usable string node from the string depository and return the string token.\r
1104\r
2e9f9668 1105 @param CallbackData The BMM context data.\r
1106 @param StringDepository The string repository.\r
b30312ba 1107\r
1108 @retval EFI_STRING_ID String token.\r
1109\r
1110**/\r
93e3992d 1111EFI_STRING_ID\r
1112GetStringTokenFromDepository (\r
1113 IN BMM_CALLBACK_DATA *CallbackData,\r
1114 IN STRING_DEPOSITORY *StringDepository\r
1115 )\r
93e3992d 1116{\r
1117 STRING_LIST_NODE *CurrentListNode;\r
1118 STRING_LIST_NODE *NextListNode;\r
1119\r
1120 CurrentListNode = StringDepository->CurrentNode;\r
1121\r
1122 if ((NULL != CurrentListNode) && (NULL != CurrentListNode->Next)) {\r
1123 //\r
1124 // Fetch one reclaimed node from the list.\r
1125 //\r
1126 NextListNode = StringDepository->CurrentNode->Next;\r
1127 } else {\r
1128 //\r
1129 // If there is no usable node in the list, update the list.\r
1130 //\r
dce655e8 1131 NextListNode = AllocateZeroPool (sizeof (STRING_LIST_NODE));\r
93e3992d 1132\r
9226efe5 1133 HiiLibNewString (CallbackData->BmmHiiHandle, &(NextListNode->StringToken), L" ");\r
93e3992d 1134 ASSERT (NextListNode->StringToken != 0);\r
1135\r
1136 StringDepository->TotalNodeNumber++;\r
1137\r
1138 if (NULL == CurrentListNode) {\r
1139 StringDepository->ListHead = NextListNode;\r
1140 } else {\r
1141 CurrentListNode->Next = NextListNode;\r
1142 }\r
1143 }\r
1144\r
1145 StringDepository->CurrentNode = NextListNode;\r
1146\r
1147 return StringDepository->CurrentNode->StringToken;\r
1148}\r
1149\r
b30312ba 1150/**\r
93e3992d 1151 Reclaim string depositories by moving the current node pointer to list head..\r
1152\r
b30312ba 1153**/\r
1154VOID\r
1155ReclaimStringDepository (\r
1156 VOID\r
1157 )\r
93e3992d 1158{\r
1159 UINTN DepositoryIndex;\r
1160 STRING_DEPOSITORY *StringDepository;\r
1161\r
1162 StringDepository = FileOptionStrDepository;\r
1163 for (DepositoryIndex = 0; DepositoryIndex < STRING_DEPOSITORY_NUMBER; DepositoryIndex++) {\r
1164 StringDepository->CurrentNode = StringDepository->ListHead;\r
1165 StringDepository++;\r
1166 }\r
1167}\r
1168\r
b30312ba 1169/**\r
93e3992d 1170 Release resource for all the string depositories.\r
1171\r
b30312ba 1172**/\r
1173VOID\r
1174CleanUpStringDepository (\r
1175 VOID\r
1176 )\r
93e3992d 1177{\r
1178 UINTN NodeIndex;\r
1179 UINTN DepositoryIndex;\r
1180 STRING_LIST_NODE *CurrentListNode;\r
1181 STRING_LIST_NODE *NextListNode;\r
1182 STRING_DEPOSITORY *StringDepository;\r
1183\r
1184 //\r
1185 // Release string list nodes.\r
1186 //\r
1187 StringDepository = FileOptionStrDepository;\r
1188 for (DepositoryIndex = 0; DepositoryIndex < STRING_DEPOSITORY_NUMBER; DepositoryIndex++) {\r
1189 CurrentListNode = StringDepository->ListHead;\r
1190 for (NodeIndex = 0; NodeIndex < StringDepository->TotalNodeNumber; NodeIndex++) {\r
1191 NextListNode = CurrentListNode->Next;\r
676df92c 1192 FreePool (CurrentListNode);\r
93e3992d 1193 CurrentListNode = NextListNode;\r
1194 }\r
1195\r
1196 StringDepository++;\r
1197 }\r
1198 //\r
1199 // Release string depository.\r
1200 //\r
676df92c 1201 FreePool (FileOptionStrDepository);\r
93e3992d 1202}\r
1203\r
b30312ba 1204/**\r
93e3992d 1205 Start boot maintenance manager\r
1206\r
dce655e8 1207 @retval EFI_SUCCESS If BMM is invoked successfully.\r
1208 @return Other value if BMM return unsuccessfully.\r
93e3992d 1209\r
b30312ba 1210**/\r
1211EFI_STATUS\r
1212BdsStartBootMaint (\r
1213 VOID\r
1214 )\r
93e3992d 1215{\r
1216 EFI_STATUS Status;\r
1217 LIST_ENTRY BdsBootOptionList;\r
1218\r
1219 InitializeListHead (&BdsBootOptionList);\r
1220\r
1221 //\r
1222 // Connect all prior to entering the platform setup menu.\r
1223 //\r
1224 if (!gConnectAllHappened) {\r
1225 BdsLibConnectAllDriversToAllControllers ();\r
1226 gConnectAllHappened = TRUE;\r
1227 }\r
1228 //\r
1229 // Have chance to enumerate boot device\r
1230 //\r
1231 BdsLibEnumerateAllBootOption (&BdsBootOptionList);\r
1232\r
93e3992d 1233 //\r
1234 // Init the BMM\r
1235 //\r
1236 Status = InitializeBM ();\r
1237\r
93e3992d 1238 return Status;\r
1239}\r
1240\r
b30312ba 1241/**\r
93e3992d 1242 Dispatch BMM formset and FileExplorer formset.\r
1243\r
93e3992d 1244\r
dce655e8 1245 @param CallbackData The BMM context data.\r
93e3992d 1246\r
dce655e8 1247 @retval EFI_SUCCESS If function complete successfully.\r
744fc758 1248 @return Other value if the Setup Browser process BMM's pages and\r
dce655e8 1249 return unsuccessfully.\r
b30312ba 1250\r
1251**/\r
1252EFI_STATUS\r
1253FormSetDispatcher (\r
1254 IN BMM_CALLBACK_DATA *CallbackData\r
1255 )\r
93e3992d 1256{\r
1257 EFI_STATUS Status;\r
1258 EFI_BROWSER_ACTION_REQUEST ActionRequest;\r
1259\r
1260 while (TRUE) {\r
1261 UpdatePageId (CallbackData, FORM_MAIN_ID);\r
1262\r
1263 ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;\r
1264 Status = gFormBrowser2->SendForm (\r
1265 gFormBrowser2,\r
1266 &CallbackData->BmmHiiHandle,\r
1267 1,\r
1268 NULL,\r
1269 0,\r
1270 NULL,\r
1271 &ActionRequest\r
1272 );\r
1273 if (ActionRequest == EFI_BROWSER_ACTION_REQUEST_RESET) {\r
1274 EnableResetRequired ();\r
1275 }\r
1276\r
1277 ReclaimStringDepository ();\r
1278\r
1279 //\r
1280 // When this Formset returns, check if we are going to explore files.\r
1281 //\r
1282 if (INACTIVE_STATE != CallbackData->FeCurrentState) {\r
1283 UpdateFileExplorer (CallbackData, 0);\r
1284\r
1285 ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;\r
1286 Status = gFormBrowser2->SendForm (\r
1287 gFormBrowser2,\r
1288 &CallbackData->FeHiiHandle,\r
1289 1,\r
1290 NULL,\r
1291 0,\r
1292 NULL,\r
1293 &ActionRequest\r
1294 );\r
1295 if (ActionRequest == EFI_BROWSER_ACTION_REQUEST_RESET) {\r
1296 EnableResetRequired ();\r
1297 }\r
1298\r
1299 CallbackData->FeCurrentState = INACTIVE_STATE;\r
1300 CallbackData->FeDisplayContext = UNKNOWN_CONTEXT;\r
1301 ReclaimStringDepository ();\r
1302 } else {\r
1303 break;\r
1304 }\r
1305 }\r
1306\r
1307 return Status;\r
1308}\r
1309\r
dce655e8 1310\r
1311/**\r
1312 Deletete the Boot Option from EFI Variable. The Boot Order Arrray\r
1313 is also updated.\r
1314\r
2e9f9668 1315 @param OptionNumber The number of Boot option want to be deleted.\r
dce655e8 1316 @param BootOrder The Boot Order array.\r
1317 @param BootOrderSize The size of the Boot Order Array.\r
1318\r
1319 @return Other value if the Boot Option specified by OptionNumber is not deleteed succesfully.\r
1320 @retval EFI_SUCCESS If function return successfully.\r
1321\r
1322**/\r
1323EFI_STATUS\r
1324BdsDeleteBootOption (\r
1325 IN UINTN OptionNumber,\r
1326 IN OUT UINT16 *BootOrder,\r
1327 IN OUT UINTN *BootOrderSize\r
1328 )\r
1329{\r
1330 UINT16 BootOption[100];\r
1331 UINTN Index;\r
1332 EFI_STATUS Status;\r
1333 UINTN Index2Del;\r
1334\r
1335 Status = EFI_SUCCESS;\r
1336 Index2Del = 0;\r
1337\r
1338 UnicodeSPrint (BootOption, sizeof (BootOption), L"Boot%04x", OptionNumber);\r
1339 Status = EfiLibDeleteVariable (BootOption, &gEfiGlobalVariableGuid);\r
2e9f9668 1340 \r
dce655e8 1341 //\r
1342 // adjust boot order array\r
1343 //\r
1344 for (Index = 0; Index < *BootOrderSize / sizeof (UINT16); Index++) {\r
1345 if (BootOrder[Index] == OptionNumber) {\r
1346 Index2Del = Index;\r
1347 break;\r
1348 }\r
1349 }\r
1350\r
1351 if (Index != *BootOrderSize / sizeof (UINT16)) {\r
1352 for (Index = 0; Index < *BootOrderSize / sizeof (UINT16) - 1; Index++) {\r
1353 if (Index >= Index2Del) {\r
1354 BootOrder[Index] = BootOrder[Index + 1];\r
1355 }\r
1356 }\r
1357\r
1358 *BootOrderSize -= sizeof (UINT16);\r
1359 }\r
1360\r
1361 return Status;\r
1362\r
1363}\r
1364\r
1365\r