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