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