]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Universal/BdsDxe/BootMaint/BootMaint.c
Remove SafeFreePool from MemoryAllocationLib as this API's name is misleading. Its...
[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 @param Private Pointer to callback data buffer.
544 @param CurrentFakeNVMap Pointer to buffer holding data of various values used by BMM
545 @param FormId ID of the form which has sent the request to apply change.
546
547 @retval EFI_SUCCESS Change successfully applied.
548 @retval Other Error occurs while trying to apply changes.
549
550 **/
551 EFI_STATUS
552 ApplyChangeHandler (
553 IN BMM_CALLBACK_DATA *Private,
554 IN BMM_FAKE_NV_DATA *CurrentFakeNVMap,
555 IN EFI_FORM_ID FormId
556 )
557 {
558 BM_CONSOLE_CONTEXT *NewConsoleContext;
559 BM_TERMINAL_CONTEXT *NewTerminalContext;
560 BM_LOAD_CONTEXT *NewLoadContext;
561 BM_MENU_ENTRY *NewMenuEntry;
562 EFI_STATUS Status;
563 UINT16 Index;
564
565 Status = EFI_SUCCESS;
566
567 switch (FormId) {
568 case FORM_SET_FD_ORDER_ID:
569 case FORM_SET_HD_ORDER_ID:
570 case FORM_SET_CD_ORDER_ID:
571 case FORM_SET_NET_ORDER_ID:
572 case FORM_SET_BEV_ORDER_ID:
573 Var_UpdateBBSOption (Private);
574 break;
575
576 case FORM_BOOT_DEL_ID:
577 for (Index = 0; Index < BootOptionMenu.MenuNumber; Index++) {
578 NewMenuEntry = BOpt_GetMenuEntry (&BootOptionMenu, Index);
579 NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;
580 NewLoadContext->Deleted = CurrentFakeNVMap->BootOptionDel[Index];
581 }
582
583 Var_DelBootOption ();
584 break;
585
586 case FORM_DRV_DEL_ID:
587 for (Index = 0; Index < DriverOptionMenu.MenuNumber; Index++) {
588 NewMenuEntry = BOpt_GetMenuEntry (&DriverOptionMenu, Index);
589 NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;
590 NewLoadContext->Deleted = CurrentFakeNVMap->DriverOptionDel[Index];
591 }
592
593 Var_DelDriverOption ();
594 break;
595
596 case FORM_BOOT_CHG_ID:
597 Status = Var_UpdateBootOrder (Private);
598 break;
599
600 case FORM_DRV_CHG_ID:
601 Status = Var_UpdateDriverOrder (Private);
602 break;
603
604 case FORM_TIME_OUT_ID:
605 Status = gRT->SetVariable (
606 L"Timeout",
607 &gEfiGlobalVariableGuid,
608 VAR_FLAG,
609 sizeof (UINT16),
610 &(CurrentFakeNVMap->BootTimeOut)
611 );
612 if (EFI_ERROR (Status)) {
613 goto Error;
614 }
615
616 Private->BmmOldFakeNVData.BootTimeOut = CurrentFakeNVMap->BootTimeOut;
617 break;
618
619 case FORM_BOOT_NEXT_ID:
620 Status = Var_UpdateBootNext (Private);
621 break;
622
623 case FORM_CON_MODE_ID:
624 Status = Var_UpdateConMode (Private);
625 break;
626
627 case FORM_CON_COM_SETUP_ID:
628 NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Private->CurrentTerminal);
629
630 ASSERT (NewMenuEntry != NULL);
631
632 NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;
633
634 NewTerminalContext->BaudRateIndex = CurrentFakeNVMap->COMBaudRate;
635 NewTerminalContext->BaudRate = BaudRateList[CurrentFakeNVMap->COMBaudRate].Value;
636 NewTerminalContext->DataBitsIndex = CurrentFakeNVMap->COMDataRate;
637 NewTerminalContext->DataBits = (UINT8) DataBitsList[CurrentFakeNVMap->COMDataRate].Value;
638 NewTerminalContext->StopBitsIndex = CurrentFakeNVMap->COMStopBits;
639 NewTerminalContext->StopBits = (UINT8) StopBitsList[CurrentFakeNVMap->COMStopBits].Value;
640 NewTerminalContext->ParityIndex = CurrentFakeNVMap->COMParity;
641 NewTerminalContext->Parity = (UINT8) ParityList[CurrentFakeNVMap->COMParity].Value;
642 NewTerminalContext->TerminalType = CurrentFakeNVMap->COMTerminalType;
643
644 ChangeTerminalDevicePath (
645 NewTerminalContext->DevicePath,
646 FALSE
647 );
648
649 Var_UpdateConsoleInpOption ();
650 Var_UpdateConsoleOutOption ();
651 Var_UpdateErrorOutOption ();
652 break;
653
654 case FORM_CON_IN_ID:
655 for (Index = 0; Index < ConsoleInpMenu.MenuNumber; Index++) {
656 NewMenuEntry = BOpt_GetMenuEntry (&ConsoleInpMenu, Index);
657 NewConsoleContext = (BM_CONSOLE_CONTEXT *) NewMenuEntry->VariableContext;
658 NewConsoleContext->IsActive = CurrentFakeNVMap->ConsoleCheck[Index];
659 }
660
661 for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {
662 NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);
663 NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;
664 NewTerminalContext->IsConIn = CurrentFakeNVMap->ConsoleCheck[Index + ConsoleInpMenu.MenuNumber];
665 }
666
667 Var_UpdateConsoleInpOption ();
668 break;
669
670 case FORM_CON_OUT_ID:
671 for (Index = 0; Index < ConsoleOutMenu.MenuNumber; Index++) {
672 NewMenuEntry = BOpt_GetMenuEntry (&ConsoleOutMenu, Index);
673 NewConsoleContext = (BM_CONSOLE_CONTEXT *) NewMenuEntry->VariableContext;
674 NewConsoleContext->IsActive = CurrentFakeNVMap->ConsoleCheck[Index];
675 }
676
677 for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {
678 NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);
679 NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;
680 NewTerminalContext->IsConOut = CurrentFakeNVMap->ConsoleCheck[Index + ConsoleOutMenu.MenuNumber];
681 }
682
683 Var_UpdateConsoleOutOption ();
684 break;
685
686 case FORM_CON_ERR_ID:
687 for (Index = 0; Index < ConsoleErrMenu.MenuNumber; Index++) {
688 NewMenuEntry = BOpt_GetMenuEntry (&ConsoleErrMenu, Index);
689 NewConsoleContext = (BM_CONSOLE_CONTEXT *) NewMenuEntry->VariableContext;
690 NewConsoleContext->IsActive = CurrentFakeNVMap->ConsoleCheck[Index];
691 }
692
693 for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {
694 NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);
695 NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;
696 NewTerminalContext->IsStdErr = CurrentFakeNVMap->ConsoleCheck[Index + ConsoleErrMenu.MenuNumber];
697 }
698
699 Var_UpdateErrorOutOption ();
700 break;
701
702 case FORM_DRV_ADD_HANDLE_DESC_ID:
703 Status = Var_UpdateDriverOption (
704 Private,
705 Private->BmmHiiHandle,
706 CurrentFakeNVMap->DriverAddHandleDesc,
707 CurrentFakeNVMap->DriverAddHandleOptionalData,
708 CurrentFakeNVMap->DriverAddForceReconnect
709 );
710 if (EFI_ERROR (Status)) {
711 goto Error;
712 }
713
714 BOpt_GetDriverOptions (Private);
715 CreateMenuStringToken (Private, Private->BmmHiiHandle, &DriverOptionMenu);
716 break;
717
718 default:
719 break;
720 }
721
722 Error:
723 return Status;
724 }
725
726 /**
727 Discard all changes done to the BMM pages such as Boot Order change,
728 Driver order change.
729
730 @param Private The BMM context data.
731 @param CurrentFakeNVMap The current Fack NV Map.
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 @retval EFI_SUCCESS utility ended successfully
785 @retval others contain some errors
786
787 **/
788 EFI_STATUS
789 InitializeBM (
790 VOID
791 )
792 {
793 EFI_LEGACY_BIOS_PROTOCOL *LegacyBios;
794 EFI_HII_PACKAGE_LIST_HEADER *PackageList;
795 BMM_CALLBACK_DATA *BmmCallbackInfo;
796 EFI_STATUS Status;
797 UINT8 *Ptr;
798
799 Status = EFI_SUCCESS;
800
801 //
802 // Create CallbackData structures for Driver Callback
803 //
804 BmmCallbackInfo = AllocateZeroPool (sizeof (BMM_CALLBACK_DATA));
805 if (BmmCallbackInfo == NULL) {
806 return EFI_OUT_OF_RESOURCES;
807 }
808
809 //
810 // Create LoadOption in BmmCallbackInfo for Driver Callback
811 //
812 Ptr = AllocateZeroPool (sizeof (BM_LOAD_CONTEXT) + sizeof (BM_FILE_CONTEXT) + sizeof (BM_HANDLE_CONTEXT) + sizeof (BM_MENU_ENTRY));
813 if (Ptr == NULL) {
814 FreePool (BmmCallbackInfo);
815 return EFI_OUT_OF_RESOURCES;
816 }
817
818 //
819 // Initialize Bmm callback data.
820 //
821 BmmCallbackInfo->LoadContext = (BM_LOAD_CONTEXT *) Ptr;
822 Ptr += sizeof (BM_LOAD_CONTEXT);
823
824 BmmCallbackInfo->FileContext = (BM_FILE_CONTEXT *) Ptr;
825 Ptr += sizeof (BM_FILE_CONTEXT);
826
827 BmmCallbackInfo->HandleContext = (BM_HANDLE_CONTEXT *) Ptr;
828 Ptr += sizeof (BM_HANDLE_CONTEXT);
829
830 BmmCallbackInfo->MenuEntry = (BM_MENU_ENTRY *) Ptr;
831
832 BmmCallbackInfo->Signature = BMM_CALLBACK_DATA_SIGNATURE;
833 BmmCallbackInfo->BmmConfigAccess.ExtractConfig = BootMaintExtractConfig;
834 BmmCallbackInfo->BmmConfigAccess.RouteConfig = FakeRouteConfig;
835 BmmCallbackInfo->BmmConfigAccess.Callback = BootMaintCallback;
836 BmmCallbackInfo->BmmPreviousPageId = FORM_MAIN_ID;
837 BmmCallbackInfo->BmmCurrentPageId = FORM_MAIN_ID;
838 BmmCallbackInfo->FeConfigAccess.ExtractConfig = FakeExtractConfig;
839 BmmCallbackInfo->FeConfigAccess.RouteConfig = FakeRouteConfig;
840 BmmCallbackInfo->FeConfigAccess.Callback = FileExplorerCallback;
841 BmmCallbackInfo->FeCurrentState = INACTIVE_STATE;
842 BmmCallbackInfo->FeDisplayContext = UNKNOWN_CONTEXT;
843
844 //
845 // Create driver handle used by HII database
846 //
847 Status = HiiLibCreateHiiDriverHandle (&BmmCallbackInfo->BmmDriverHandle);
848 if (EFI_ERROR (Status)) {
849 return Status;
850 }
851
852 //
853 // Install Config Access protocol to driver handle
854 //
855 Status = gBS->InstallProtocolInterface (
856 &BmmCallbackInfo->BmmDriverHandle,
857 &gEfiHiiConfigAccessProtocolGuid,
858 EFI_NATIVE_INTERFACE,
859 &BmmCallbackInfo->BmmConfigAccess
860 );
861 if (EFI_ERROR (Status)) {
862 return Status;
863 }
864
865 //
866 // Create driver handle used by HII database
867 //
868 Status = HiiLibCreateHiiDriverHandle (&BmmCallbackInfo->FeDriverHandle);
869 if (EFI_ERROR (Status)) {
870 return Status;
871 }
872
873 //
874 // Install Config Access protocol to driver handle
875 //
876 Status = gBS->InstallProtocolInterface (
877 &BmmCallbackInfo->FeDriverHandle,
878 &gEfiHiiConfigAccessProtocolGuid,
879 EFI_NATIVE_INTERFACE,
880 &BmmCallbackInfo->FeConfigAccess
881 );
882 if (EFI_ERROR (Status)) {
883 return Status;
884 }
885
886 //
887 // Post our Boot Maint VFR binnary to the HII database.
888 //
889 PackageList = HiiLibPreparePackageList (2, &mBootMaintGuid, BmBin, BdsDxeStrings);
890 ASSERT (PackageList != NULL);
891
892 Status = gHiiDatabase->NewPackageList (
893 gHiiDatabase,
894 PackageList,
895 BmmCallbackInfo->BmmDriverHandle,
896 &BmmCallbackInfo->BmmHiiHandle
897 );
898 FreePool (PackageList);
899
900 //
901 // Post our File Explorer VFR binary to the HII database.
902 //
903 PackageList = HiiLibPreparePackageList (2, &mFileExplorerGuid, FEBin, BdsDxeStrings);
904 ASSERT (PackageList != NULL);
905
906 Status = gHiiDatabase->NewPackageList (
907 gHiiDatabase,
908 PackageList,
909 BmmCallbackInfo->FeDriverHandle,
910 &BmmCallbackInfo->FeHiiHandle
911 );
912 FreePool (PackageList);
913
914 //
915 // Allocate space for creation of Buffer
916 //
917 gUpdateData.BufferSize = UPDATE_DATA_SIZE;
918 gUpdateData.Data = AllocateZeroPool (UPDATE_DATA_SIZE);
919 if (gUpdateData.Data == NULL) {
920 FreePool (BmmCallbackInfo->LoadContext);
921 FreePool (BmmCallbackInfo);
922 return EFI_OUT_OF_RESOURCES;
923 }
924
925 InitializeStringDepository ();
926
927 InitAllMenu (BmmCallbackInfo);
928
929 CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &ConsoleInpMenu);
930 CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &ConsoleOutMenu);
931 CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &ConsoleErrMenu);
932 CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &BootOptionMenu);
933 CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &DriverOptionMenu);
934 CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &TerminalMenu);
935 CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &DriverMenu);
936
937 UpdateBootDelPage (BmmCallbackInfo);
938 UpdateDrvDelPage (BmmCallbackInfo);
939
940 if (TerminalMenu.MenuNumber > 0) {
941 BmmCallbackInfo->CurrentTerminal = 0;
942 UpdateTerminalPage (BmmCallbackInfo);
943 }
944
945 Status = EfiLibLocateProtocol (&gEfiLegacyBiosProtocolGuid, (VOID **) &LegacyBios);
946 if (!EFI_ERROR (Status)) {
947 RefreshUpdateData ();
948
949 //
950 // If LegacyBios Protocol is installed, add 3 tags about legacy boot option
951 // in BootOption form: legacy FD/HD/CD/NET/BEV
952 //
953 CreateGotoOpCode (
954 FORM_SET_FD_ORDER_ID,
955 STRING_TOKEN (STR_FORM_SET_FD_ORDER_TITLE),
956 STRING_TOKEN (STR_FORM_SET_FD_ORDER_TITLE),
957 EFI_IFR_FLAG_CALLBACK,
958 FORM_SET_FD_ORDER_ID,
959 &gUpdateData
960 );
961
962 CreateGotoOpCode (
963 FORM_SET_HD_ORDER_ID,
964 STRING_TOKEN (STR_FORM_SET_HD_ORDER_TITLE),
965 STRING_TOKEN (STR_FORM_SET_HD_ORDER_TITLE),
966 EFI_IFR_FLAG_CALLBACK,
967 FORM_SET_HD_ORDER_ID,
968 &gUpdateData
969 );
970
971 CreateGotoOpCode (
972 FORM_SET_CD_ORDER_ID,
973 STRING_TOKEN (STR_FORM_SET_CD_ORDER_TITLE),
974 STRING_TOKEN (STR_FORM_SET_CD_ORDER_TITLE),
975 EFI_IFR_FLAG_CALLBACK,
976 FORM_SET_CD_ORDER_ID,
977 &gUpdateData
978 );
979
980 CreateGotoOpCode (
981 FORM_SET_NET_ORDER_ID,
982 STRING_TOKEN (STR_FORM_SET_NET_ORDER_TITLE),
983 STRING_TOKEN (STR_FORM_SET_NET_ORDER_TITLE),
984 EFI_IFR_FLAG_CALLBACK,
985 FORM_SET_NET_ORDER_ID,
986 &gUpdateData
987 );
988
989 CreateGotoOpCode (
990 FORM_SET_BEV_ORDER_ID,
991 STRING_TOKEN (STR_FORM_SET_BEV_ORDER_TITLE),
992 STRING_TOKEN (STR_FORM_SET_BEV_ORDER_TITLE),
993 EFI_IFR_FLAG_CALLBACK,
994 FORM_SET_BEV_ORDER_ID,
995 &gUpdateData
996 );
997
998 IfrLibUpdateForm (
999 BmmCallbackInfo->BmmHiiHandle,
1000 &mBootMaintGuid,
1001 FORM_MAIN_ID,
1002 FORM_BOOT_LEGACY_DEVICE_ID,
1003 FALSE,
1004 &gUpdateData
1005 );
1006 }
1007
1008 //
1009 // Dispatch BMM main formset and File Explorer formset.
1010 //
1011 FormSetDispatcher (BmmCallbackInfo);
1012
1013 //
1014 // Remove our IFR data from HII database
1015 //
1016 gHiiDatabase->RemovePackageList (gHiiDatabase, BmmCallbackInfo->BmmHiiHandle);
1017 gHiiDatabase->RemovePackageList (gHiiDatabase, BmmCallbackInfo->FeHiiHandle);
1018
1019 CleanUpStringDepository ();
1020
1021 FreeAllMenu ();
1022
1023 FreePool (BmmCallbackInfo->LoadContext);
1024 FreePool (BmmCallbackInfo);
1025 FreePool (gUpdateData.Data);
1026 gUpdateData.Data = NULL;
1027
1028 return Status;
1029 }
1030
1031 /**
1032 Initialized all Menu Option List.
1033
1034 @param CallbackData The BMM context data.
1035
1036
1037
1038 **/
1039 VOID
1040 InitAllMenu (
1041 IN BMM_CALLBACK_DATA *CallbackData
1042 )
1043 {
1044 InitializeListHead (&BootOptionMenu.Head);
1045 InitializeListHead (&DriverOptionMenu.Head);
1046 BOpt_GetBootOptions (CallbackData);
1047 BOpt_GetDriverOptions (CallbackData);
1048 BOpt_GetLegacyOptions ();
1049 InitializeListHead (&FsOptionMenu.Head);
1050 BOpt_FindDrivers ();
1051 InitializeListHead (&DirectoryMenu.Head);
1052 InitializeListHead (&ConsoleInpMenu.Head);
1053 InitializeListHead (&ConsoleOutMenu.Head);
1054 InitializeListHead (&ConsoleErrMenu.Head);
1055 InitializeListHead (&TerminalMenu.Head);
1056 LocateSerialIo ();
1057 GetAllConsoles ();
1058 }
1059
1060 /**
1061 Free up all Menu Option list.
1062
1063
1064
1065
1066
1067 **/
1068 VOID
1069 FreeAllMenu (
1070 VOID
1071 )
1072 {
1073 BOpt_FreeMenu (&DirectoryMenu);
1074 BOpt_FreeMenu (&FsOptionMenu);
1075 BOpt_FreeMenu (&BootOptionMenu);
1076 BOpt_FreeMenu (&DriverOptionMenu);
1077 BOpt_FreeMenu (&DriverMenu);
1078 BOpt_FreeLegacyOptions ();
1079 FreeAllConsoles ();
1080 }
1081
1082 /**
1083 Intialize all the string depositories.
1084
1085
1086
1087
1088
1089
1090 **/
1091 VOID
1092 InitializeStringDepository (
1093 VOID
1094 )
1095 {
1096 STRING_DEPOSITORY *StringDepository;
1097 StringDepository = AllocateZeroPool (sizeof (STRING_DEPOSITORY) * STRING_DEPOSITORY_NUMBER);
1098 FileOptionStrDepository = StringDepository++;
1099 ConsoleOptionStrDepository = StringDepository++;
1100 BootOptionStrDepository = StringDepository++;
1101 BootOptionHelpStrDepository = StringDepository++;
1102 DriverOptionStrDepository = StringDepository++;
1103 DriverOptionHelpStrDepository = StringDepository++;
1104 TerminalStrDepository = StringDepository;
1105 }
1106
1107 /**
1108 Fetch a usable string node from the string depository and return the string token.
1109
1110
1111 @param CallbackData The BMM context data.
1112 @param StringDepository The string repository.
1113
1114 @retval EFI_STRING_ID String token.
1115
1116 **/
1117 EFI_STRING_ID
1118 GetStringTokenFromDepository (
1119 IN BMM_CALLBACK_DATA *CallbackData,
1120 IN STRING_DEPOSITORY *StringDepository
1121 )
1122 {
1123 STRING_LIST_NODE *CurrentListNode;
1124 STRING_LIST_NODE *NextListNode;
1125
1126 CurrentListNode = StringDepository->CurrentNode;
1127
1128 if ((NULL != CurrentListNode) && (NULL != CurrentListNode->Next)) {
1129 //
1130 // Fetch one reclaimed node from the list.
1131 //
1132 NextListNode = StringDepository->CurrentNode->Next;
1133 } else {
1134 //
1135 // If there is no usable node in the list, update the list.
1136 //
1137 NextListNode = AllocateZeroPool (sizeof (STRING_LIST_NODE));
1138
1139 HiiLibNewString (CallbackData->BmmHiiHandle, &(NextListNode->StringToken), L" ");
1140 ASSERT (NextListNode->StringToken != 0);
1141
1142 StringDepository->TotalNodeNumber++;
1143
1144 if (NULL == CurrentListNode) {
1145 StringDepository->ListHead = NextListNode;
1146 } else {
1147 CurrentListNode->Next = NextListNode;
1148 }
1149 }
1150
1151 StringDepository->CurrentNode = NextListNode;
1152
1153 return StringDepository->CurrentNode->StringToken;
1154 }
1155
1156 /**
1157 Reclaim string depositories by moving the current node pointer to list head..
1158
1159
1160
1161
1162
1163
1164 **/
1165 VOID
1166 ReclaimStringDepository (
1167 VOID
1168 )
1169 {
1170 UINTN DepositoryIndex;
1171 STRING_DEPOSITORY *StringDepository;
1172
1173 StringDepository = FileOptionStrDepository;
1174 for (DepositoryIndex = 0; DepositoryIndex < STRING_DEPOSITORY_NUMBER; DepositoryIndex++) {
1175 StringDepository->CurrentNode = StringDepository->ListHead;
1176 StringDepository++;
1177 }
1178 }
1179
1180 /**
1181 Release resource for all the string depositories.
1182
1183
1184
1185
1186
1187
1188 **/
1189 VOID
1190 CleanUpStringDepository (
1191 VOID
1192 )
1193 {
1194 UINTN NodeIndex;
1195 UINTN DepositoryIndex;
1196 STRING_LIST_NODE *CurrentListNode;
1197 STRING_LIST_NODE *NextListNode;
1198 STRING_DEPOSITORY *StringDepository;
1199
1200 //
1201 // Release string list nodes.
1202 //
1203 StringDepository = FileOptionStrDepository;
1204 for (DepositoryIndex = 0; DepositoryIndex < STRING_DEPOSITORY_NUMBER; DepositoryIndex++) {
1205 CurrentListNode = StringDepository->ListHead;
1206 for (NodeIndex = 0; NodeIndex < StringDepository->TotalNodeNumber; NodeIndex++) {
1207 NextListNode = CurrentListNode->Next;
1208 FreePool (CurrentListNode);
1209 CurrentListNode = NextListNode;
1210 }
1211
1212 StringDepository++;
1213 }
1214 //
1215 // Release string depository.
1216 //
1217 FreePool (FileOptionStrDepository);
1218 }
1219
1220 /**
1221 Start boot maintenance manager
1222
1223
1224
1225
1226 @retval EFI_SUCCESS If BMM is invoked successfully.
1227 @return Other value if BMM return unsuccessfully.
1228
1229 **/
1230 EFI_STATUS
1231 BdsStartBootMaint (
1232 VOID
1233 )
1234 {
1235 EFI_STATUS Status;
1236 LIST_ENTRY BdsBootOptionList;
1237
1238 InitializeListHead (&BdsBootOptionList);
1239
1240 //
1241 // Connect all prior to entering the platform setup menu.
1242 //
1243 if (!gConnectAllHappened) {
1244 BdsLibConnectAllDriversToAllControllers ();
1245 gConnectAllHappened = TRUE;
1246 }
1247 //
1248 // Have chance to enumerate boot device
1249 //
1250 BdsLibEnumerateAllBootOption (&BdsBootOptionList);
1251
1252 //
1253 // Init the BMM
1254 //
1255 Status = InitializeBM ();
1256
1257 return Status;
1258 }
1259
1260 /**
1261 Dispatch BMM formset and FileExplorer formset.
1262
1263
1264 @param CallbackData The BMM context data.
1265
1266 @retval EFI_SUCCESS If function complete successfully.
1267 @return Other value if the Setup Browser process BMM's pages and
1268 return unsuccessfully.
1269
1270 **/
1271 EFI_STATUS
1272 FormSetDispatcher (
1273 IN BMM_CALLBACK_DATA *CallbackData
1274 )
1275 {
1276 EFI_STATUS Status;
1277 EFI_BROWSER_ACTION_REQUEST ActionRequest;
1278
1279 while (TRUE) {
1280 UpdatePageId (CallbackData, FORM_MAIN_ID);
1281
1282 ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;
1283 Status = gFormBrowser2->SendForm (
1284 gFormBrowser2,
1285 &CallbackData->BmmHiiHandle,
1286 1,
1287 NULL,
1288 0,
1289 NULL,
1290 &ActionRequest
1291 );
1292 if (ActionRequest == EFI_BROWSER_ACTION_REQUEST_RESET) {
1293 EnableResetRequired ();
1294 }
1295
1296 ReclaimStringDepository ();
1297
1298 //
1299 // When this Formset returns, check if we are going to explore files.
1300 //
1301 if (INACTIVE_STATE != CallbackData->FeCurrentState) {
1302 UpdateFileExplorer (CallbackData, 0);
1303
1304 ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;
1305 Status = gFormBrowser2->SendForm (
1306 gFormBrowser2,
1307 &CallbackData->FeHiiHandle,
1308 1,
1309 NULL,
1310 0,
1311 NULL,
1312 &ActionRequest
1313 );
1314 if (ActionRequest == EFI_BROWSER_ACTION_REQUEST_RESET) {
1315 EnableResetRequired ();
1316 }
1317
1318 CallbackData->FeCurrentState = INACTIVE_STATE;
1319 CallbackData->FeDisplayContext = UNKNOWN_CONTEXT;
1320 ReclaimStringDepository ();
1321 } else {
1322 break;
1323 }
1324 }
1325
1326 return Status;
1327 }
1328
1329
1330 /**
1331 Deletete the Boot Option from EFI Variable. The Boot Order Arrray
1332 is also updated.
1333
1334 @param OptionNumber EDES_TODO: Add parameter description
1335 @param BootOrder The Boot Order array.
1336 @param BootOrderSize The size of the Boot Order Array.
1337
1338 @return Other value if the Boot Option specified by OptionNumber is not deleteed succesfully.
1339 @retval EFI_SUCCESS If function return successfully.
1340
1341 **/
1342 EFI_STATUS
1343 BdsDeleteBootOption (
1344 IN UINTN OptionNumber,
1345 IN OUT UINT16 *BootOrder,
1346 IN OUT UINTN *BootOrderSize
1347 )
1348 {
1349 UINT16 BootOption[100];
1350 UINTN Index;
1351 EFI_STATUS Status;
1352 UINTN Index2Del;
1353
1354 Status = EFI_SUCCESS;
1355 Index2Del = 0;
1356
1357 UnicodeSPrint (BootOption, sizeof (BootOption), L"Boot%04x", OptionNumber);
1358 Status = EfiLibDeleteVariable (BootOption, &gEfiGlobalVariableGuid);
1359 //
1360 // adjust boot order array
1361 //
1362 for (Index = 0; Index < *BootOrderSize / sizeof (UINT16); Index++) {
1363 if (BootOrder[Index] == OptionNumber) {
1364 Index2Del = Index;
1365 break;
1366 }
1367 }
1368
1369 if (Index != *BootOrderSize / sizeof (UINT16)) {
1370 for (Index = 0; Index < *BootOrderSize / sizeof (UINT16) - 1; Index++) {
1371 if (Index >= Index2Del) {
1372 BootOrder[Index] = BootOrder[Index + 1];
1373 }
1374 }
1375
1376 *BootOrderSize -= sizeof (UINT16);
1377 }
1378
1379 return Status;
1380
1381 }
1382
1383