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