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