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