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