]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Universal/BdsDxe/BootMaint/BootMaint.c
update file header
[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
1046 **/
1047 VOID
1048 InitAllMenu (
1049 IN BMM_CALLBACK_DATA *CallbackData
1050 )
1051 {
1052 InitializeListHead (&BootOptionMenu.Head);
1053 InitializeListHead (&DriverOptionMenu.Head);
1054 BOpt_GetBootOptions (CallbackData);
1055 BOpt_GetDriverOptions (CallbackData);
1056 BOpt_GetLegacyOptions ();
1057 InitializeListHead (&FsOptionMenu.Head);
1058 BOpt_FindDrivers ();
1059 InitializeListHead (&DirectoryMenu.Head);
1060 InitializeListHead (&ConsoleInpMenu.Head);
1061 InitializeListHead (&ConsoleOutMenu.Head);
1062 InitializeListHead (&ConsoleErrMenu.Head);
1063 InitializeListHead (&TerminalMenu.Head);
1064 LocateSerialIo ();
1065 GetAllConsoles ();
1066 }
1067
1068 /**
1069 Free up all Menu Option list.
1070
1071
1072
1073
1074
1075 **/
1076 VOID
1077 FreeAllMenu (
1078 VOID
1079 )
1080 {
1081 BOpt_FreeMenu (&DirectoryMenu);
1082 BOpt_FreeMenu (&FsOptionMenu);
1083 BOpt_FreeMenu (&BootOptionMenu);
1084 BOpt_FreeMenu (&DriverOptionMenu);
1085 BOpt_FreeMenu (&DriverMenu);
1086 BOpt_FreeLegacyOptions ();
1087 FreeAllConsoles ();
1088 }
1089
1090 /**
1091 Intialize all the string depositories.
1092
1093
1094
1095
1096
1097
1098 **/
1099 VOID
1100 InitializeStringDepository (
1101 VOID
1102 )
1103 {
1104 STRING_DEPOSITORY *StringDepository;
1105 StringDepository = AllocateZeroPool (sizeof (STRING_DEPOSITORY) * STRING_DEPOSITORY_NUMBER);
1106 FileOptionStrDepository = StringDepository++;
1107 ConsoleOptionStrDepository = StringDepository++;
1108 BootOptionStrDepository = StringDepository++;
1109 BootOptionHelpStrDepository = StringDepository++;
1110 DriverOptionStrDepository = StringDepository++;
1111 DriverOptionHelpStrDepository = StringDepository++;
1112 TerminalStrDepository = StringDepository;
1113 }
1114
1115 /**
1116 Fetch a usable string node from the string depository and return the string token.
1117
1118
1119 @param CallbackData The BMM context data.
1120 @param StringDepository The string repository.
1121
1122 @retval EFI_STRING_ID String token.
1123
1124 **/
1125 EFI_STRING_ID
1126 GetStringTokenFromDepository (
1127 IN BMM_CALLBACK_DATA *CallbackData,
1128 IN STRING_DEPOSITORY *StringDepository
1129 )
1130 {
1131 STRING_LIST_NODE *CurrentListNode;
1132 STRING_LIST_NODE *NextListNode;
1133
1134 CurrentListNode = StringDepository->CurrentNode;
1135
1136 if ((NULL != CurrentListNode) && (NULL != CurrentListNode->Next)) {
1137 //
1138 // Fetch one reclaimed node from the list.
1139 //
1140 NextListNode = StringDepository->CurrentNode->Next;
1141 } else {
1142 //
1143 // If there is no usable node in the list, update the list.
1144 //
1145 NextListNode = AllocateZeroPool (sizeof (STRING_LIST_NODE));
1146
1147 HiiLibNewString (CallbackData->BmmHiiHandle, &(NextListNode->StringToken), L" ");
1148 ASSERT (NextListNode->StringToken != 0);
1149
1150 StringDepository->TotalNodeNumber++;
1151
1152 if (NULL == CurrentListNode) {
1153 StringDepository->ListHead = NextListNode;
1154 } else {
1155 CurrentListNode->Next = NextListNode;
1156 }
1157 }
1158
1159 StringDepository->CurrentNode = NextListNode;
1160
1161 return StringDepository->CurrentNode->StringToken;
1162 }
1163
1164 /**
1165 Reclaim string depositories by moving the current node pointer to list head..
1166
1167
1168
1169
1170
1171
1172 **/
1173 VOID
1174 ReclaimStringDepository (
1175 VOID
1176 )
1177 {
1178 UINTN DepositoryIndex;
1179 STRING_DEPOSITORY *StringDepository;
1180
1181 StringDepository = FileOptionStrDepository;
1182 for (DepositoryIndex = 0; DepositoryIndex < STRING_DEPOSITORY_NUMBER; DepositoryIndex++) {
1183 StringDepository->CurrentNode = StringDepository->ListHead;
1184 StringDepository++;
1185 }
1186 }
1187
1188 /**
1189 Release resource for all the string depositories.
1190
1191
1192
1193
1194
1195
1196 **/
1197 VOID
1198 CleanUpStringDepository (
1199 VOID
1200 )
1201 {
1202 UINTN NodeIndex;
1203 UINTN DepositoryIndex;
1204 STRING_LIST_NODE *CurrentListNode;
1205 STRING_LIST_NODE *NextListNode;
1206 STRING_DEPOSITORY *StringDepository;
1207
1208 //
1209 // Release string list nodes.
1210 //
1211 StringDepository = FileOptionStrDepository;
1212 for (DepositoryIndex = 0; DepositoryIndex < STRING_DEPOSITORY_NUMBER; DepositoryIndex++) {
1213 CurrentListNode = StringDepository->ListHead;
1214 for (NodeIndex = 0; NodeIndex < StringDepository->TotalNodeNumber; NodeIndex++) {
1215 NextListNode = CurrentListNode->Next;
1216 FreePool (CurrentListNode);
1217 CurrentListNode = NextListNode;
1218 }
1219
1220 StringDepository++;
1221 }
1222 //
1223 // Release string depository.
1224 //
1225 FreePool (FileOptionStrDepository);
1226 }
1227
1228 /**
1229 Start boot maintenance manager
1230
1231
1232
1233
1234 @retval EFI_SUCCESS If BMM is invoked successfully.
1235 @return Other value if BMM return unsuccessfully.
1236
1237 **/
1238 EFI_STATUS
1239 BdsStartBootMaint (
1240 VOID
1241 )
1242 {
1243 EFI_STATUS Status;
1244 LIST_ENTRY BdsBootOptionList;
1245
1246 InitializeListHead (&BdsBootOptionList);
1247
1248 //
1249 // Connect all prior to entering the platform setup menu.
1250 //
1251 if (!gConnectAllHappened) {
1252 BdsLibConnectAllDriversToAllControllers ();
1253 gConnectAllHappened = TRUE;
1254 }
1255 //
1256 // Have chance to enumerate boot device
1257 //
1258 BdsLibEnumerateAllBootOption (&BdsBootOptionList);
1259
1260 //
1261 // Init the BMM
1262 //
1263 Status = InitializeBM ();
1264
1265 return Status;
1266 }
1267
1268 /**
1269 Dispatch BMM formset and FileExplorer formset.
1270
1271
1272 @param CallbackData The BMM context data.
1273
1274 @retval EFI_SUCCESS If function complete successfully.
1275 @return Other value if the Setup Browser process BMM's pages and
1276 return unsuccessfully.
1277
1278 **/
1279 EFI_STATUS
1280 FormSetDispatcher (
1281 IN BMM_CALLBACK_DATA *CallbackData
1282 )
1283 {
1284 EFI_STATUS Status;
1285 EFI_BROWSER_ACTION_REQUEST ActionRequest;
1286
1287 while (TRUE) {
1288 UpdatePageId (CallbackData, FORM_MAIN_ID);
1289
1290 ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;
1291 Status = gFormBrowser2->SendForm (
1292 gFormBrowser2,
1293 &CallbackData->BmmHiiHandle,
1294 1,
1295 NULL,
1296 0,
1297 NULL,
1298 &ActionRequest
1299 );
1300 if (ActionRequest == EFI_BROWSER_ACTION_REQUEST_RESET) {
1301 EnableResetRequired ();
1302 }
1303
1304 ReclaimStringDepository ();
1305
1306 //
1307 // When this Formset returns, check if we are going to explore files.
1308 //
1309 if (INACTIVE_STATE != CallbackData->FeCurrentState) {
1310 UpdateFileExplorer (CallbackData, 0);
1311
1312 ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;
1313 Status = gFormBrowser2->SendForm (
1314 gFormBrowser2,
1315 &CallbackData->FeHiiHandle,
1316 1,
1317 NULL,
1318 0,
1319 NULL,
1320 &ActionRequest
1321 );
1322 if (ActionRequest == EFI_BROWSER_ACTION_REQUEST_RESET) {
1323 EnableResetRequired ();
1324 }
1325
1326 CallbackData->FeCurrentState = INACTIVE_STATE;
1327 CallbackData->FeDisplayContext = UNKNOWN_CONTEXT;
1328 ReclaimStringDepository ();
1329 } else {
1330 break;
1331 }
1332 }
1333
1334 return Status;
1335 }
1336
1337
1338 /**
1339 Deletete the Boot Option from EFI Variable. The Boot Order Arrray
1340 is also updated.
1341
1342 @param OptionNumber EDES_TODO: Add parameter description
1343 @param BootOrder The Boot Order array.
1344 @param BootOrderSize The size of the Boot Order Array.
1345
1346 @return Other value if the Boot Option specified by OptionNumber is not deleteed succesfully.
1347 @retval EFI_SUCCESS If function return successfully.
1348
1349 **/
1350 EFI_STATUS
1351 BdsDeleteBootOption (
1352 IN UINTN OptionNumber,
1353 IN OUT UINT16 *BootOrder,
1354 IN OUT UINTN *BootOrderSize
1355 )
1356 {
1357 UINT16 BootOption[100];
1358 UINTN Index;
1359 EFI_STATUS Status;
1360 UINTN Index2Del;
1361
1362 Status = EFI_SUCCESS;
1363 Index2Del = 0;
1364
1365 UnicodeSPrint (BootOption, sizeof (BootOption), L"Boot%04x", OptionNumber);
1366 Status = EfiLibDeleteVariable (BootOption, &gEfiGlobalVariableGuid);
1367 //
1368 // adjust boot order array
1369 //
1370 for (Index = 0; Index < *BootOrderSize / sizeof (UINT16); Index++) {
1371 if (BootOrder[Index] == OptionNumber) {
1372 Index2Del = Index;
1373 break;
1374 }
1375 }
1376
1377 if (Index != *BootOrderSize / sizeof (UINT16)) {
1378 for (Index = 0; Index < *BootOrderSize / sizeof (UINT16) - 1; Index++) {
1379 if (Index >= Index2Del) {
1380 BootOrder[Index] = BootOrder[Index + 1];
1381 }
1382 }
1383
1384 *BootOrderSize -= sizeof (UINT16);
1385 }
1386
1387 return Status;
1388
1389 }
1390
1391