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