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