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