UpdatePage.c revision 67013151bafeef044920e457aa275f617b5c6485
1/** @file
2Dynamically update the pages.
3
4Copyright (c) 2004 - 2015, Intel Corporation. All rights reserved.<BR>
5This program and the accompanying materials
6are licensed and made available under the terms and conditions of the BSD License
7which accompanies this distribution.  The full text of the license may be found at
8http://opensource.org/licenses/bsd-license.php
9
10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12
13**/
14
15#include "BootMaintenanceManager.h"
16
17/**
18 Create the global UpdateData structure.
19
20**/
21VOID
22CreateUpdateData (
23  VOID
24  )
25{
26  //
27  // Init OpCode Handle and Allocate space for creation of Buffer
28  //
29  mStartOpCodeHandle = HiiAllocateOpCodeHandle ();
30  ASSERT (mStartOpCodeHandle != NULL);
31
32  mEndOpCodeHandle = HiiAllocateOpCodeHandle ();
33  ASSERT (mEndOpCodeHandle != NULL);
34
35  //
36  // Create Hii Extend Label OpCode as the start opcode
37  //
38  mStartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (mStartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
39  mStartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
40
41  //
42  // Create Hii Extend Label OpCode as the end opcode
43  //
44  mEndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (mEndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
45  mEndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
46  mEndLabel->Number       = LABEL_END;
47}
48
49/**
50  Refresh the global UpdateData structure.
51
52**/
53VOID
54RefreshUpdateData (
55  VOID
56  )
57{
58  //
59  // Free current updated date
60  //
61  if (mStartOpCodeHandle != NULL) {
62    HiiFreeOpCodeHandle (mStartOpCodeHandle);
63  }
64
65  //
66  // Create new OpCode Handle
67  //
68  mStartOpCodeHandle = HiiAllocateOpCodeHandle ();
69
70  //
71  // Create Hii Extend Label OpCode as the start opcode
72  //
73  mStartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (mStartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
74  mStartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
75
76}
77
78/**
79  Add a "Go back to main page" tag in front of the form when there are no
80  "Apply changes" and "Discard changes" tags in the end of the form.
81
82  @param CallbackData    The BMM context data.
83
84**/
85VOID
86UpdatePageStart (
87  IN BMM_CALLBACK_DATA                *CallbackData
88  )
89{
90  RefreshUpdateData ();
91  mStartLabel->Number = CallbackData->BmmCurrentPageId;
92
93  if (!(CallbackData->BmmAskSaveOrNot)) {
94    //
95    // Add a "Go back to main page" tag in front of the form when there are no
96    // "Apply changes" and "Discard changes" tags in the end of the form.
97    //
98    HiiCreateGotoOpCode (
99      mStartOpCodeHandle,
100      FORM_MAIN_ID,
101      STRING_TOKEN (STR_FORM_GOTO_MAIN),
102      STRING_TOKEN (STR_FORM_GOTO_MAIN),
103      0,
104      FORM_MAIN_ID
105      );
106  }
107}
108
109/**
110  Create the "Apply changes" and "Discard changes" tags. And
111  ensure user can return to the main page.
112
113  @param CallbackData    The BMM context data.
114
115**/
116VOID
117UpdatePageEnd (
118  IN BMM_CALLBACK_DATA                *CallbackData
119  )
120{
121  //
122  // Create the "Apply changes" and "Discard changes" tags.
123  //
124  if (CallbackData->BmmAskSaveOrNot) {
125    HiiCreateSubTitleOpCode (
126      mStartOpCodeHandle,
127      STRING_TOKEN (STR_NULL_STRING),
128      0,
129      0,
130      0
131      );
132
133    HiiCreateActionOpCode (
134      mStartOpCodeHandle,
135      KEY_VALUE_SAVE_AND_EXIT,
136      STRING_TOKEN (STR_SAVE_AND_EXIT),
137      STRING_TOKEN (STR_NULL_STRING),
138      EFI_IFR_FLAG_CALLBACK,
139      0
140      );
141  }
142
143  //
144  // Ensure user can return to the main page.
145  //
146  HiiCreateActionOpCode (
147    mStartOpCodeHandle,
148    KEY_VALUE_NO_SAVE_AND_EXIT,
149    STRING_TOKEN (STR_NO_SAVE_AND_EXIT),
150    STRING_TOKEN (STR_NULL_STRING),
151    EFI_IFR_FLAG_CALLBACK,
152    0
153    );
154
155  HiiUpdateForm (
156    CallbackData->BmmHiiHandle,
157    &mBootMaintGuid,
158    CallbackData->BmmCurrentPageId,
159    mStartOpCodeHandle, // Label CallbackData->BmmCurrentPageId
160    mEndOpCodeHandle    // LABEL_END
161    );
162}
163
164/**
165  Clean up the dynamic opcode at label and form specified by both LabelId.
166
167  @param LabelId         It is both the Form ID and Label ID for opcode deletion.
168  @param CallbackData    The BMM context data.
169
170**/
171VOID
172CleanUpPage (
173  IN UINT16                           LabelId,
174  IN BMM_CALLBACK_DATA                *CallbackData
175  )
176{
177  RefreshUpdateData ();
178
179  //
180  // Remove all op-codes from dynamic page
181  //
182  mStartLabel->Number = LabelId;
183  HiiUpdateForm (
184    CallbackData->BmmHiiHandle,
185    &mBootMaintGuid,
186    LabelId,
187    mStartOpCodeHandle, // Label LabelId
188    mEndOpCodeHandle    // LABEL_END
189    );
190}
191
192/**
193  Create a list of Goto Opcode for all terminal devices logged
194  by TerminaMenu. This list will be inserted to form FORM_CON_COM_SETUP_ID.
195
196  @param CallbackData    The BMM context data.
197**/
198VOID
199UpdateConCOMPage (
200  IN BMM_CALLBACK_DATA                *CallbackData
201  )
202{
203  BM_MENU_ENTRY       *NewMenuEntry;
204  UINT16              Index;
205
206  CallbackData->BmmAskSaveOrNot = TRUE;
207
208  UpdatePageStart (CallbackData);
209
210  for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {
211    NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);
212
213    HiiCreateGotoOpCode (
214      mStartOpCodeHandle,
215      FORM_CON_COM_SETUP_ID,
216      NewMenuEntry->DisplayStringToken,
217      STRING_TOKEN (STR_NULL_STRING),
218      EFI_IFR_FLAG_CALLBACK,
219      (UINT16) (TERMINAL_OPTION_OFFSET + Index)
220      );
221  }
222
223  UpdatePageEnd (CallbackData);
224}
225
226
227/**
228  Create a list of boot option from global BootOptionMenu. It
229  allow user to delete the boot option.
230
231  @param CallbackData    The BMM context data.
232
233**/
234VOID
235UpdateBootDelPage (
236  IN BMM_CALLBACK_DATA                *CallbackData
237  )
238{
239  BM_MENU_ENTRY   *NewMenuEntry;
240  BM_LOAD_CONTEXT *NewLoadContext;
241  UINT16          Index;
242
243  CallbackData->BmmAskSaveOrNot = TRUE;
244
245  UpdatePageStart (CallbackData);
246
247  ASSERT (BootOptionMenu.MenuNumber <= (sizeof (CallbackData->BmmFakeNvData.BootOptionDel) / sizeof (CallbackData->BmmFakeNvData.BootOptionDel[0])));
248  for (Index = 0; Index < BootOptionMenu.MenuNumber; Index++) {
249    NewMenuEntry    = BOpt_GetMenuEntry (&BootOptionMenu, Index);
250    NewLoadContext  = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;
251    if (NewLoadContext->IsLegacy) {
252      continue;
253    }
254
255    NewLoadContext->Deleted = FALSE;
256
257    if (CallbackData->BmmFakeNvData.BootOptionDel[Index] && !CallbackData->BmmFakeNvData.BootOptionDelMark[Index]) {
258      //
259      // CallbackData->BmmFakeNvData.BootOptionDel[Index] == TRUE means browser knows this boot option is selected
260      // CallbackData->BmmFakeNvData.BootOptionDelMark[Index] = FALSE means BDS knows the selected boot option has
261      // deleted, browser maintains old useless info. So clear this info here, and later update this info to browser
262      // through HiiSetBrowserData function.
263      //
264      CallbackData->BmmFakeNvData.BootOptionDel[Index] = FALSE;
265    }
266
267    HiiCreateCheckBoxOpCode (
268      mStartOpCodeHandle,
269      (EFI_QUESTION_ID) (BOOT_OPTION_DEL_QUESTION_ID + Index),
270      VARSTORE_ID_BOOT_MAINT,
271      (UINT16) (BOOT_OPTION_DEL_VAR_OFFSET + Index),
272      NewMenuEntry->DisplayStringToken,
273      NewMenuEntry->HelpStringToken,
274      EFI_IFR_FLAG_CALLBACK,
275      0,
276      NULL
277      );
278  }
279  UpdatePageEnd (CallbackData);
280}
281
282/**
283  Create a lit of driver option from global DriverMenu.
284
285  @param CallbackData    The BMM context data.
286
287**/
288VOID
289UpdateDrvAddHandlePage (
290  IN BMM_CALLBACK_DATA                *CallbackData
291  )
292{
293  BM_MENU_ENTRY *NewMenuEntry;
294  UINT16        Index;
295
296  CallbackData->BmmAskSaveOrNot = FALSE;
297
298  UpdatePageStart (CallbackData);
299
300  for (Index = 0; Index < DriverMenu.MenuNumber; Index++) {
301    NewMenuEntry = BOpt_GetMenuEntry (&DriverMenu, Index);
302
303    HiiCreateGotoOpCode (
304      mStartOpCodeHandle,
305      FORM_DRV_ADD_HANDLE_DESC_ID,
306      NewMenuEntry->DisplayStringToken,
307      STRING_TOKEN (STR_NULL_STRING),
308      EFI_IFR_FLAG_CALLBACK,
309      (UINT16) (HANDLE_OPTION_OFFSET + Index)
310      );
311  }
312
313  UpdatePageEnd (CallbackData);
314}
315
316/**
317  Create a lit of driver option from global DriverOptionMenu. It
318  allow user to delete the driver option.
319
320  @param CallbackData    The BMM context data.
321
322**/
323VOID
324UpdateDrvDelPage (
325  IN BMM_CALLBACK_DATA                *CallbackData
326  )
327{
328  BM_MENU_ENTRY   *NewMenuEntry;
329  BM_LOAD_CONTEXT *NewLoadContext;
330  UINT16          Index;
331
332  CallbackData->BmmAskSaveOrNot = TRUE;
333
334  UpdatePageStart (CallbackData);
335
336  ASSERT (DriverOptionMenu.MenuNumber <= (sizeof (CallbackData->BmmFakeNvData.DriverOptionDel) / sizeof (CallbackData->BmmFakeNvData.DriverOptionDel[0])));
337  for (Index = 0; Index < DriverOptionMenu.MenuNumber; Index++) {
338    NewMenuEntry            = BOpt_GetMenuEntry (&DriverOptionMenu, Index);
339
340    NewLoadContext          = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;
341    NewLoadContext->Deleted = FALSE;
342
343    if (CallbackData->BmmFakeNvData.DriverOptionDel[Index] && !CallbackData->BmmFakeNvData.DriverOptionDelMark[Index]) {
344      //
345      // CallbackData->BmmFakeNvData.BootOptionDel[Index] == TRUE means browser knows this boot option is selected
346      // CallbackData->BmmFakeNvData.BootOptionDelMark[Index] = FALSE means BDS knows the selected boot option has
347      // deleted, browser maintains old useless info. So clear this info here, and later update this info to browser
348      // through HiiSetBrowserData function.
349      //
350      CallbackData->BmmFakeNvData.DriverOptionDel[Index] = FALSE;
351    }
352    HiiCreateCheckBoxOpCode (
353      mStartOpCodeHandle,
354      (EFI_QUESTION_ID) (DRIVER_OPTION_DEL_QUESTION_ID + Index),
355      VARSTORE_ID_BOOT_MAINT,
356      (UINT16) (DRIVER_OPTION_DEL_VAR_OFFSET + Index),
357      NewMenuEntry->DisplayStringToken,
358      NewMenuEntry->HelpStringToken,
359      EFI_IFR_FLAG_CALLBACK,
360      0,
361      NULL
362      );
363  }
364
365  UpdatePageEnd (CallbackData);
366}
367
368/**
369  Prepare the page to allow user to add description for
370  a Driver Option.
371
372  @param CallbackData    The BMM context data.
373
374**/
375VOID
376UpdateDriverAddHandleDescPage (
377  IN BMM_CALLBACK_DATA                *CallbackData
378  )
379{
380  BM_MENU_ENTRY *NewMenuEntry;
381
382  CallbackData->BmmFakeNvData.DriverAddActive          = 0x01;
383  CallbackData->BmmFakeNvData.DriverAddForceReconnect  = 0x00;
384  CallbackData->BmmAskSaveOrNot                        = TRUE;
385  NewMenuEntry = CallbackData->MenuEntry;
386
387  UpdatePageStart (CallbackData);
388
389  HiiCreateSubTitleOpCode (
390    mStartOpCodeHandle,
391    NewMenuEntry->DisplayStringToken,
392    0,
393    0,
394    0
395    );
396
397  HiiCreateStringOpCode (
398    mStartOpCodeHandle,
399    (EFI_QUESTION_ID) DRV_ADD_HANDLE_DESC_QUESTION_ID,
400    VARSTORE_ID_BOOT_MAINT,
401    DRV_ADD_HANDLE_DESC_VAR_OFFSET,
402    STRING_TOKEN (STR_LOAD_OPTION_DESC),
403    STRING_TOKEN (STR_NULL_STRING),
404    0,
405    0,
406    6,
407    75,
408    NULL
409    );
410
411  HiiCreateCheckBoxOpCode (
412    mStartOpCodeHandle,
413    (EFI_QUESTION_ID) DRV_ADD_RECON_QUESTION_ID,
414    VARSTORE_ID_BOOT_MAINT,
415    DRV_ADD_RECON_VAR_OFFSET,
416    STRING_TOKEN (STR_LOAD_OPTION_FORCE_RECON),
417    STRING_TOKEN (STR_LOAD_OPTION_FORCE_RECON),
418    0,
419    0,
420    NULL
421    );
422
423  HiiCreateStringOpCode (
424    mStartOpCodeHandle,
425    (EFI_QUESTION_ID) DRIVER_ADD_OPTION_QUESTION_ID,
426    VARSTORE_ID_BOOT_MAINT,
427    DRIVER_ADD_OPTION_VAR_OFFSET,
428    STRING_TOKEN (STR_OPTIONAL_DATA),
429    STRING_TOKEN (STR_NULL_STRING),
430    0,
431    0,
432    6,
433    75,
434    NULL
435    );
436
437  UpdatePageEnd (CallbackData);
438}
439
440/**
441  Update console page.
442
443  @param UpdatePageId    The form ID to be updated.
444  @param ConsoleMenu     The console menu list.
445  @param CallbackData    The BMM context data.
446
447**/
448VOID
449UpdateConsolePage (
450  IN UINT16                           UpdatePageId,
451  IN BM_MENU_OPTION                   *ConsoleMenu,
452  IN BMM_CALLBACK_DATA                *CallbackData
453  )
454{
455  BM_MENU_ENTRY       *NewMenuEntry;
456  BM_CONSOLE_CONTEXT  *NewConsoleContext;
457  BM_TERMINAL_CONTEXT *NewTerminalContext;
458  UINT16              Index;
459  UINT16              Index2;
460  UINT8               CheckFlags;
461  UINT8               *ConsoleCheck;
462  UINT8               *OldConsoleCheck;
463  UINTN               ConsoleCheckSize;
464  EFI_QUESTION_ID     QuestionIdBase;
465  UINT16              VariableOffsetBase;
466
467  CallbackData->BmmAskSaveOrNot = TRUE;
468
469  UpdatePageStart (CallbackData);
470
471  ConsoleCheck       = NULL;
472  OldConsoleCheck    = NULL;
473  QuestionIdBase     = 0;
474  VariableOffsetBase = 0;
475  ConsoleCheckSize   = 0;
476
477  switch (UpdatePageId) {
478  case FORM_CON_IN_ID:
479    ConsoleCheck       = &CallbackData->BmmFakeNvData.ConsoleInCheck[0];
480    OldConsoleCheck    = &CallbackData->BmmOldFakeNVData.ConsoleInCheck[0];
481    ConsoleCheckSize   = sizeof (CallbackData->BmmFakeNvData.ConsoleInCheck);
482    QuestionIdBase     = CON_IN_DEVICE_QUESTION_ID;
483    VariableOffsetBase = CON_IN_DEVICE_VAR_OFFSET;
484    break;
485
486  case FORM_CON_OUT_ID:
487    ConsoleCheck       = &CallbackData->BmmFakeNvData.ConsoleOutCheck[0];
488    OldConsoleCheck    = &CallbackData->BmmOldFakeNVData.ConsoleOutCheck[0];
489    ConsoleCheckSize   = sizeof (CallbackData->BmmFakeNvData.ConsoleOutCheck);
490    QuestionIdBase     = CON_OUT_DEVICE_QUESTION_ID;
491    VariableOffsetBase = CON_OUT_DEVICE_VAR_OFFSET;
492    break;
493
494  case FORM_CON_ERR_ID:
495    ConsoleCheck       = &CallbackData->BmmFakeNvData.ConsoleErrCheck[0];
496    OldConsoleCheck    = &CallbackData->BmmOldFakeNVData.ConsoleErrCheck[0];
497    ConsoleCheckSize   = sizeof (CallbackData->BmmFakeNvData.ConsoleErrCheck);
498    QuestionIdBase     = CON_ERR_DEVICE_QUESTION_ID;
499    VariableOffsetBase = CON_ERR_DEVICE_VAR_OFFSET;
500    break;
501  }
502  ASSERT (ConsoleCheck != NULL);
503
504  for (Index = 0; ((Index < ConsoleMenu->MenuNumber) && \
505       (Index < MAX_MENU_NUMBER)) ; Index++) {
506    CheckFlags = 0;
507    NewMenuEntry = BOpt_GetMenuEntry (ConsoleMenu, Index);
508    NewConsoleContext = (BM_CONSOLE_CONTEXT *) NewMenuEntry->VariableContext;
509    if (NewConsoleContext->IsActive) {
510      CheckFlags |= EFI_IFR_CHECKBOX_DEFAULT;
511      ConsoleCheck[Index] = TRUE;
512    } else {
513      ConsoleCheck[Index] = FALSE;
514    }
515    HiiCreateCheckBoxOpCode (
516      mStartOpCodeHandle,
517      (EFI_QUESTION_ID) (QuestionIdBase + Index),
518      VARSTORE_ID_BOOT_MAINT,
519      (UINT16) (VariableOffsetBase + Index),
520      NewMenuEntry->DisplayStringToken,
521      NewMenuEntry->HelpStringToken,
522      0,
523      CheckFlags,
524      NULL
525      );
526  }
527
528  for (Index2 = 0; ((Index2 < TerminalMenu.MenuNumber) && \
529       (Index2 < MAX_MENU_NUMBER)); Index2++) {
530    CheckFlags          = 0;
531    NewMenuEntry        = BOpt_GetMenuEntry (&TerminalMenu, Index2);
532    NewTerminalContext  = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;
533
534    ASSERT (Index < MAX_MENU_NUMBER);
535    if (((NewTerminalContext->IsConIn != 0) && (UpdatePageId == FORM_CON_IN_ID)) ||
536        ((NewTerminalContext->IsConOut != 0) && (UpdatePageId == FORM_CON_OUT_ID)) ||
537        ((NewTerminalContext->IsStdErr != 0) && (UpdatePageId == FORM_CON_ERR_ID))
538        ) {
539      CheckFlags |= EFI_IFR_CHECKBOX_DEFAULT;
540      ConsoleCheck[Index] = TRUE;
541    } else {
542      ConsoleCheck[Index] = FALSE;
543    }
544    HiiCreateCheckBoxOpCode (
545      mStartOpCodeHandle,
546      (EFI_QUESTION_ID) (QuestionIdBase + Index),
547      VARSTORE_ID_BOOT_MAINT,
548      (UINT16) (VariableOffsetBase + Index),
549      NewMenuEntry->DisplayStringToken,
550      NewMenuEntry->HelpStringToken,
551      0,
552      CheckFlags,
553      NULL
554      );
555
556    Index++;
557  }
558
559  CopyMem (OldConsoleCheck, ConsoleCheck, ConsoleCheckSize);
560
561  UpdatePageEnd (CallbackData);
562}
563
564/**
565  Update the page's NV Map if user has changed the order
566  a list. This list can be Boot Order or Driver Order.
567
568  @param UpdatePageId    The form ID to be updated.
569  @param OptionMenu      The new list.
570  @param CallbackData    The BMM context data.
571
572**/
573VOID
574UpdateOrderPage (
575  IN UINT16                           UpdatePageId,
576  IN BM_MENU_OPTION                   *OptionMenu,
577  IN BMM_CALLBACK_DATA                *CallbackData
578  )
579{
580  BM_MENU_ENTRY     *NewMenuEntry;
581  UINT16            Index;
582  UINT16            OptionIndex;
583  VOID              *OptionsOpCodeHandle;
584  BM_LOAD_CONTEXT   *NewLoadContext;
585  BOOLEAN           BootOptionFound;
586  UINT32            *OptionOrder;
587  EFI_QUESTION_ID   QuestionId;
588  UINT16            VarOffset;
589
590  CallbackData->BmmAskSaveOrNot = TRUE;
591  UpdatePageStart (CallbackData);
592
593  OptionOrder = NULL;
594  QuestionId = 0;
595  VarOffset = 0;
596  switch (UpdatePageId) {
597
598  case FORM_BOOT_CHG_ID:
599    GetBootOrder (CallbackData);
600    OptionOrder = CallbackData->BmmFakeNvData.BootOptionOrder;
601    QuestionId = BOOT_OPTION_ORDER_QUESTION_ID;
602    VarOffset = BOOT_OPTION_ORDER_VAR_OFFSET;
603    break;
604
605  case FORM_DRV_CHG_ID:
606    GetDriverOrder (CallbackData);
607    OptionOrder = CallbackData->BmmFakeNvData.DriverOptionOrder;
608    QuestionId = DRIVER_OPTION_ORDER_QUESTION_ID;
609    VarOffset = DRIVER_OPTION_ORDER_VAR_OFFSET;
610    break;
611  }
612  ASSERT (OptionOrder != NULL);
613
614  OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();
615  ASSERT (OptionsOpCodeHandle != NULL);
616
617  NewMenuEntry = NULL;
618  for (OptionIndex = 0; (OptionOrder[OptionIndex] != 0 && OptionIndex < MAX_MENU_NUMBER); OptionIndex++) {
619    BootOptionFound = FALSE;
620    for (Index = 0; Index < OptionMenu->MenuNumber; Index++) {
621      NewMenuEntry   = BOpt_GetMenuEntry (OptionMenu, Index);
622      NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;
623      if ((UINT32) (NewMenuEntry->OptionNumber + 1) == OptionOrder[OptionIndex]) {
624        BootOptionFound = TRUE;
625        break;
626      }
627    }
628    if (BootOptionFound) {
629      HiiCreateOneOfOptionOpCode (
630        OptionsOpCodeHandle,
631        NewMenuEntry->DisplayStringToken,
632        0,
633        EFI_IFR_TYPE_NUM_SIZE_32,
634        OptionOrder[OptionIndex]
635        );
636    }
637  }
638
639  if (OptionMenu->MenuNumber > 0) {
640    HiiCreateOrderedListOpCode (
641      mStartOpCodeHandle,                          // Container for dynamic created opcodes
642      QuestionId,                                  // Question ID
643      VARSTORE_ID_BOOT_MAINT,                      // VarStore ID
644      VarOffset,                                   // Offset in Buffer Storage
645      STRING_TOKEN (STR_CHANGE_ORDER),             // Question prompt text
646      STRING_TOKEN (STR_CHANGE_ORDER),             // Question help text
647      0,                                           // Question flag
648      0,                                           // Ordered list flag, e.g. EFI_IFR_UNIQUE_SET
649      EFI_IFR_TYPE_NUM_SIZE_32,                    // Data type of Question value
650      100,                                         // Maximum container
651      OptionsOpCodeHandle,                         // Option Opcode list
652      NULL                                         // Default Opcode is NULL
653      );
654  }
655
656  HiiFreeOpCodeHandle (OptionsOpCodeHandle);
657
658  UpdatePageEnd (CallbackData);
659
660}
661
662/**
663  Create the dynamic page to allow user to set
664  the "BootNext" value.
665
666  @param CallbackData    The BMM context data.
667
668**/
669VOID
670UpdateBootNextPage (
671  IN BMM_CALLBACK_DATA                *CallbackData
672  )
673{
674  BM_MENU_ENTRY   *NewMenuEntry;
675  BM_LOAD_CONTEXT *NewLoadContext;
676  UINTN           NumberOfOptions;
677  UINT16          Index;
678  VOID            *OptionsOpCodeHandle;
679
680  NumberOfOptions               = BootOptionMenu.MenuNumber;
681  CallbackData->BmmAskSaveOrNot = TRUE;
682
683  UpdatePageStart (CallbackData);
684
685  if (NumberOfOptions > 0) {
686    OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();
687    ASSERT (OptionsOpCodeHandle != NULL);
688
689    CallbackData->BmmFakeNvData.BootNext = NONE_BOOTNEXT_VALUE;
690
691    for (Index = 0; Index < BootOptionMenu.MenuNumber; Index++) {
692      NewMenuEntry    = BOpt_GetMenuEntry (&BootOptionMenu, Index);
693      NewLoadContext  = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;
694
695      if (NewLoadContext->IsBootNext) {
696        HiiCreateOneOfOptionOpCode (
697          OptionsOpCodeHandle,
698          NewMenuEntry->DisplayStringToken,
699          EFI_IFR_OPTION_DEFAULT,
700          EFI_IFR_TYPE_NUM_SIZE_32,
701          Index
702          );
703        CallbackData->BmmFakeNvData.BootNext = Index;
704      } else {
705        HiiCreateOneOfOptionOpCode (
706          OptionsOpCodeHandle,
707          NewMenuEntry->DisplayStringToken,
708          0,
709          EFI_IFR_TYPE_NUM_SIZE_32,
710          Index
711          );
712      }
713    }
714
715    if (CallbackData->BmmFakeNvData.BootNext == NONE_BOOTNEXT_VALUE) {
716      HiiCreateOneOfOptionOpCode (
717        OptionsOpCodeHandle,
718        STRING_TOKEN (STR_NONE),
719        EFI_IFR_OPTION_DEFAULT,
720        EFI_IFR_TYPE_NUM_SIZE_32,
721        NONE_BOOTNEXT_VALUE
722        );
723    } else {
724      HiiCreateOneOfOptionOpCode (
725        OptionsOpCodeHandle,
726        STRING_TOKEN (STR_NONE),
727        0,
728        EFI_IFR_TYPE_NUM_SIZE_32,
729        NONE_BOOTNEXT_VALUE
730        );
731    }
732
733    HiiCreateOneOfOpCode (
734      mStartOpCodeHandle,
735      (EFI_QUESTION_ID) BOOT_NEXT_QUESTION_ID,
736      VARSTORE_ID_BOOT_MAINT,
737      BOOT_NEXT_VAR_OFFSET,
738      STRING_TOKEN (STR_BOOT_NEXT),
739      STRING_TOKEN (STR_BOOT_NEXT_HELP),
740      0,
741      EFI_IFR_NUMERIC_SIZE_4,
742      OptionsOpCodeHandle,
743      NULL
744      );
745
746    HiiFreeOpCodeHandle (OptionsOpCodeHandle);
747  }
748
749  UpdatePageEnd (CallbackData);
750}
751
752/**
753  Create the dynamic page to allow user to set the "TimeOut" value.
754
755  @param CallbackData    The BMM context data.
756
757**/
758VOID
759UpdateTimeOutPage (
760  IN BMM_CALLBACK_DATA                *CallbackData
761  )
762{
763  VOID    *DefaultOpCodeHandle;
764
765  CallbackData->BmmAskSaveOrNot = TRUE;
766
767  UpdatePageStart (CallbackData);
768
769  DefaultOpCodeHandle = HiiAllocateOpCodeHandle ();
770  ASSERT (DefaultOpCodeHandle != NULL);
771  HiiCreateDefaultOpCode (DefaultOpCodeHandle, EFI_HII_DEFAULT_CLASS_STANDARD, EFI_IFR_TYPE_NUM_SIZE_16, CallbackData->BmmFakeNvData.BootTimeOut);
772
773  HiiCreateNumericOpCode (
774    mStartOpCodeHandle,
775    (EFI_QUESTION_ID) BOOT_TIME_OUT_QUESTION_ID,
776    VARSTORE_ID_BOOT_MAINT,
777    BOOT_TIME_OUT_VAR_OFFSET,
778    STRING_TOKEN (STR_NUM_AUTO_BOOT),
779    STRING_TOKEN (STR_HLP_AUTO_BOOT),
780    0,
781    EFI_IFR_NUMERIC_SIZE_2 | EFI_IFR_DISPLAY_UINT_DEC,
782    0,
783    65535,
784    0,
785    DefaultOpCodeHandle
786    );
787
788  HiiFreeOpCodeHandle (DefaultOpCodeHandle);
789
790  UpdatePageEnd (CallbackData);
791}
792
793
794/**
795  Refresh the text mode page.
796
797  @param CallbackData    The BMM context data.
798
799**/
800VOID
801UpdateConModePage (
802  IN BMM_CALLBACK_DATA                *CallbackData
803  )
804{
805  UINTN                         Mode;
806  UINTN                         Index;
807  UINTN                         Col;
808  UINTN                         Row;
809  CHAR16                        ModeString[50];
810  CHAR16                        *PStr;
811  UINTN                         MaxMode;
812  UINTN                         ValidMode;
813  EFI_STRING_ID                 *ModeToken;
814  EFI_STATUS                    Status;
815  VOID                          *OptionsOpCodeHandle;
816  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *ConOut;
817
818  ConOut    = gST->ConOut;
819  Index     = 0;
820  ValidMode = 0;
821  MaxMode   = (UINTN) (ConOut->Mode->MaxMode);
822
823  CallbackData->BmmAskSaveOrNot = TRUE;
824
825  UpdatePageStart (CallbackData);
826
827  //
828  // Check valid mode
829  //
830  for (Mode = 0; Mode < MaxMode; Mode++) {
831    Status = ConOut->QueryMode (ConOut, Mode, &Col, &Row);
832    if (EFI_ERROR (Status)) {
833      continue;
834    }
835    ValidMode++;
836  }
837
838  if (ValidMode == 0) {
839    return;
840  }
841
842  OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();
843  ASSERT (OptionsOpCodeHandle != NULL);
844
845  ModeToken           = AllocateZeroPool (sizeof (EFI_STRING_ID) * ValidMode);
846  ASSERT(ModeToken != NULL);
847
848  //
849  // Determin which mode should be the first entry in menu
850  //
851  GetConsoleOutMode (CallbackData);
852
853  //
854  // Build text mode options
855  //
856  for (Mode = 0; Mode < MaxMode; Mode++) {
857    Status = ConOut->QueryMode (ConOut, Mode, &Col, &Row);
858    if (EFI_ERROR (Status)) {
859      continue;
860    }
861
862    //
863    // Build mode string Column x Row
864    //
865    UnicodeValueToString (ModeString, 0, Col, 0);
866    PStr = &ModeString[0];
867    StrnCatS (PStr, sizeof (ModeString) / sizeof (ModeString[0]), L" x ", StrLen(L" x ") + 1);
868    PStr = PStr + StrLen (PStr);
869    UnicodeValueToString (PStr , 0, Row, 0);
870
871    ModeToken[Index] = HiiSetString (CallbackData->BmmHiiHandle, 0, ModeString, NULL);
872
873    if (Mode == CallbackData->BmmFakeNvData.ConsoleOutMode) {
874      HiiCreateOneOfOptionOpCode (
875        OptionsOpCodeHandle,
876        ModeToken[Index],
877        EFI_IFR_OPTION_DEFAULT,
878        EFI_IFR_TYPE_NUM_SIZE_16,
879        (UINT16) Mode
880        );
881    } else {
882      HiiCreateOneOfOptionOpCode (
883        OptionsOpCodeHandle,
884        ModeToken[Index],
885        0,
886        EFI_IFR_TYPE_NUM_SIZE_16,
887        (UINT16) Mode
888        );
889    }
890    Index++;
891  }
892
893  HiiCreateOneOfOpCode (
894    mStartOpCodeHandle,
895    (EFI_QUESTION_ID) CON_MODE_QUESTION_ID,
896    VARSTORE_ID_BOOT_MAINT,
897    CON_MODE_VAR_OFFSET,
898    STRING_TOKEN (STR_CON_MODE_SETUP),
899    STRING_TOKEN (STR_CON_MODE_SETUP),
900    EFI_IFR_FLAG_RESET_REQUIRED,
901    EFI_IFR_NUMERIC_SIZE_2,
902    OptionsOpCodeHandle,
903    NULL
904    );
905
906  HiiFreeOpCodeHandle (OptionsOpCodeHandle);
907  FreePool (ModeToken);
908
909  UpdatePageEnd (CallbackData);
910}
911
912 /**
913  Create the dynamic page which allows user to set the property such as Baud Rate, Data Bits,
914  Parity, Stop Bits, Terminal Type.
915
916  @param CallbackData    The BMM context data.
917
918**/
919VOID
920UpdateTerminalPage (
921  IN BMM_CALLBACK_DATA                *CallbackData
922  )
923{
924  UINT8               Index;
925  UINT8               CheckFlags;
926  BM_MENU_ENTRY       *NewMenuEntry;
927  VOID                *OptionsOpCodeHandle;
928  UINTN               CurrentTerminal;
929
930  CallbackData->BmmAskSaveOrNot = TRUE;
931
932  UpdatePageStart (CallbackData);
933
934  CurrentTerminal = CallbackData->CurrentTerminal;
935  NewMenuEntry = BOpt_GetMenuEntry (
936                  &TerminalMenu,
937                  CurrentTerminal
938                  );
939
940  if (NewMenuEntry == NULL) {
941    return ;
942  }
943
944  OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();
945  ASSERT (OptionsOpCodeHandle != NULL);
946
947  for (Index = 0; Index < sizeof (BaudRateList) / sizeof (BaudRateList [0]); Index++) {
948    CheckFlags = 0;
949    if (BaudRateList[Index].Value == 115200) {
950      CheckFlags |= EFI_IFR_OPTION_DEFAULT;
951    }
952    HiiCreateOneOfOptionOpCode (
953      OptionsOpCodeHandle,
954      BaudRateList[Index].StringToken,
955      CheckFlags,
956      EFI_IFR_TYPE_NUM_SIZE_8,
957      Index
958      );
959  }
960
961  HiiCreateOneOfOpCode (
962    mStartOpCodeHandle,
963    (EFI_QUESTION_ID) (COM_BAUD_RATE_QUESTION_ID + CurrentTerminal),
964    VARSTORE_ID_BOOT_MAINT,
965    (UINT16) (COM_BAUD_RATE_VAR_OFFSET + CurrentTerminal),
966    STRING_TOKEN (STR_COM_BAUD_RATE),
967    STRING_TOKEN (STR_COM_BAUD_RATE),
968    0,
969    EFI_IFR_NUMERIC_SIZE_1,
970    OptionsOpCodeHandle,
971    NULL
972    );
973
974  HiiFreeOpCodeHandle (OptionsOpCodeHandle);
975  OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();
976  ASSERT (OptionsOpCodeHandle != NULL);
977
978  for (Index = 0; Index < sizeof (DataBitsList) / sizeof (DataBitsList[0]); Index++) {
979    CheckFlags = 0;
980
981    if (DataBitsList[Index].Value == 8) {
982      CheckFlags |= EFI_IFR_OPTION_DEFAULT;
983    }
984
985    HiiCreateOneOfOptionOpCode (
986      OptionsOpCodeHandle,
987      DataBitsList[Index].StringToken,
988      CheckFlags,
989      EFI_IFR_TYPE_NUM_SIZE_8,
990      Index
991      );
992  }
993
994  HiiCreateOneOfOpCode (
995    mStartOpCodeHandle,
996    (EFI_QUESTION_ID) (COM_DATA_RATE_QUESTION_ID + CurrentTerminal),
997    VARSTORE_ID_BOOT_MAINT,
998    (UINT16) (COM_DATA_RATE_VAR_OFFSET + CurrentTerminal),
999    STRING_TOKEN (STR_COM_DATA_BITS),
1000    STRING_TOKEN (STR_COM_DATA_BITS),
1001    0,
1002    EFI_IFR_NUMERIC_SIZE_1,
1003    OptionsOpCodeHandle,
1004    NULL
1005    );
1006
1007  HiiFreeOpCodeHandle (OptionsOpCodeHandle);
1008  OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();
1009  ASSERT (OptionsOpCodeHandle != NULL);
1010
1011  for (Index = 0; Index < sizeof (ParityList) / sizeof (ParityList[0]); Index++) {
1012    CheckFlags = 0;
1013    if (ParityList[Index].Value ==  NoParity) {
1014      CheckFlags |= EFI_IFR_OPTION_DEFAULT;
1015    }
1016
1017    HiiCreateOneOfOptionOpCode (
1018      OptionsOpCodeHandle,
1019      ParityList[Index].StringToken,
1020      CheckFlags,
1021      EFI_IFR_TYPE_NUM_SIZE_8,
1022      Index
1023      );
1024  }
1025
1026  HiiCreateOneOfOpCode (
1027    mStartOpCodeHandle,
1028    (EFI_QUESTION_ID) (COM_PARITY_QUESTION_ID + CurrentTerminal),
1029    VARSTORE_ID_BOOT_MAINT,
1030    (UINT16) (COM_PARITY_VAR_OFFSET + CurrentTerminal),
1031    STRING_TOKEN (STR_COM_PARITY),
1032    STRING_TOKEN (STR_COM_PARITY),
1033    0,
1034    EFI_IFR_NUMERIC_SIZE_1,
1035    OptionsOpCodeHandle,
1036    NULL
1037    );
1038
1039  HiiFreeOpCodeHandle (OptionsOpCodeHandle);
1040  OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();
1041  ASSERT (OptionsOpCodeHandle != NULL);
1042
1043  for (Index = 0; Index < sizeof (StopBitsList) / sizeof (StopBitsList[0]); Index++) {
1044    CheckFlags = 0;
1045    if (StopBitsList[Index].Value == OneStopBit) {
1046      CheckFlags |= EFI_IFR_OPTION_DEFAULT;
1047    }
1048
1049    HiiCreateOneOfOptionOpCode (
1050      OptionsOpCodeHandle,
1051      StopBitsList[Index].StringToken,
1052      CheckFlags,
1053      EFI_IFR_TYPE_NUM_SIZE_8,
1054      Index
1055      );
1056  }
1057
1058  HiiCreateOneOfOpCode (
1059    mStartOpCodeHandle,
1060    (EFI_QUESTION_ID) (COM_STOP_BITS_QUESTION_ID + CurrentTerminal),
1061    VARSTORE_ID_BOOT_MAINT,
1062    (UINT16) (COM_STOP_BITS_VAR_OFFSET + CurrentTerminal),
1063    STRING_TOKEN (STR_COM_STOP_BITS),
1064    STRING_TOKEN (STR_COM_STOP_BITS),
1065    0,
1066    EFI_IFR_NUMERIC_SIZE_1,
1067    OptionsOpCodeHandle,
1068    NULL
1069    );
1070
1071  HiiFreeOpCodeHandle (OptionsOpCodeHandle);
1072  OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();
1073  ASSERT (OptionsOpCodeHandle != NULL);
1074
1075  for (Index = 0; Index < sizeof (TerminalType) / sizeof (TerminalType[0]); Index++) {
1076    CheckFlags = 0;
1077    if (Index == 0) {
1078      CheckFlags |= EFI_IFR_OPTION_DEFAULT;
1079    }
1080
1081    HiiCreateOneOfOptionOpCode (
1082      OptionsOpCodeHandle,
1083      (EFI_STRING_ID) TerminalType[Index],
1084      CheckFlags,
1085      EFI_IFR_TYPE_NUM_SIZE_8,
1086      Index
1087      );
1088  }
1089
1090  HiiCreateOneOfOpCode (
1091    mStartOpCodeHandle,
1092    (EFI_QUESTION_ID) (COM_TERMINAL_QUESTION_ID + CurrentTerminal),
1093    VARSTORE_ID_BOOT_MAINT,
1094    (UINT16) (COM_TERMINAL_VAR_OFFSET + CurrentTerminal),
1095    STRING_TOKEN (STR_COM_TERMI_TYPE),
1096    STRING_TOKEN (STR_COM_TERMI_TYPE),
1097    0,
1098    EFI_IFR_NUMERIC_SIZE_1,
1099    OptionsOpCodeHandle,
1100    NULL
1101    );
1102
1103  HiiFreeOpCodeHandle (OptionsOpCodeHandle);
1104  OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();
1105  ASSERT (OptionsOpCodeHandle != NULL);
1106
1107  for (Index = 0; Index < sizeof (mFlowControlType) / sizeof (mFlowControlType[0]); Index++) {
1108  CheckFlags = 0;
1109    if (Index == 0) {
1110      CheckFlags |= EFI_IFR_OPTION_DEFAULT;
1111    }
1112    HiiCreateOneOfOptionOpCode (
1113      OptionsOpCodeHandle,
1114      (EFI_STRING_ID) mFlowControlType[Index],
1115      CheckFlags,
1116      EFI_IFR_TYPE_NUM_SIZE_8,
1117      mFlowControlValue[Index]
1118      );
1119  }
1120
1121  HiiCreateOneOfOpCode (
1122    mStartOpCodeHandle,
1123    (EFI_QUESTION_ID) (COM_FLOWCONTROL_QUESTION_ID + CurrentTerminal),
1124    VARSTORE_ID_BOOT_MAINT,
1125    (UINT16) (COM_FLOWCONTROL_VAR_OFFSET + CurrentTerminal),
1126    STRING_TOKEN (STR_COM_FLOW_CONTROL),
1127    STRING_TOKEN (STR_COM_FLOW_CONTROL),
1128    0,
1129    EFI_IFR_NUMERIC_SIZE_1,
1130    OptionsOpCodeHandle,
1131    NULL
1132    );
1133
1134  HiiFreeOpCodeHandle (OptionsOpCodeHandle);
1135
1136  UpdatePageEnd (CallbackData);
1137}
1138
1139/**
1140Update add boot/driver option page.
1141
1142@param CallbackData    The BMM context data.
1143@param FormId             The form ID to be updated.
1144@param DevicePath       Device path.
1145
1146**/
1147VOID
1148UpdateOptionPage(
1149  IN   BMM_CALLBACK_DATA        *CallbackData,
1150  IN   EFI_FORM_ID              FormId,
1151  IN   EFI_DEVICE_PATH_PROTOCOL *DevicePath
1152  )
1153{
1154  CHAR16                *String;
1155  EFI_STRING_ID         StringToken;
1156
1157  if (DevicePath != NULL){
1158    String = ExtractFileNameFromDevicePath(DevicePath);
1159    StringToken = HiiSetString (CallbackData->BmmHiiHandle, 0, String, NULL);
1160    FreePool(String);
1161  } else {
1162    String = HiiGetString (CallbackData->BmmHiiHandle, STRING_TOKEN (STR_NULL_STRING), NULL);
1163    ASSERT (String != NULL);
1164    StringToken =  HiiSetString (CallbackData->BmmHiiHandle, 0, String, NULL);
1165    FreePool (String);
1166  }
1167
1168  if(FormId == FORM_BOOT_ADD_ID){
1169    if (!CallbackData->BmmFakeNvData.BootOptionChanged) {
1170      ZeroMem (CallbackData->BmmFakeNvData.BootOptionalData, sizeof (CallbackData->BmmFakeNvData.BootOptionalData));
1171      ZeroMem (CallbackData->BmmFakeNvData.BootDescriptionData, sizeof (CallbackData->BmmFakeNvData.BootDescriptionData));
1172    }
1173  } else if (FormId == FORM_DRV_ADD_FILE_ID){
1174    if (!CallbackData->BmmFakeNvData.DriverOptionChanged) {
1175      ZeroMem (CallbackData->BmmFakeNvData.DriverOptionalData, sizeof (CallbackData->BmmFakeNvData.DriverOptionalData));
1176      ZeroMem (CallbackData->BmmFakeNvData.DriverDescriptionData, sizeof (CallbackData->BmmFakeNvData.DriverDescriptionData));
1177    }
1178  }
1179
1180  RefreshUpdateData();
1181  mStartLabel->Number = FormId;
1182
1183  HiiCreateSubTitleOpCode (
1184    mStartOpCodeHandle,
1185    StringToken,
1186    0,
1187    0,
1188    0
1189    );
1190
1191  HiiUpdateForm (
1192    CallbackData->BmmHiiHandle,
1193    &mBootMaintGuid,
1194    FormId,
1195    mStartOpCodeHandle,// Label FormId
1196    mEndOpCodeHandle   // LABEL_END
1197    );
1198}
1199
1200/**
1201  Dispatch the correct update page function to call based on
1202  the UpdatePageId.
1203
1204  @param UpdatePageId    The form ID.
1205  @param CallbackData    The BMM context data.
1206
1207**/
1208VOID
1209UpdatePageBody (
1210  IN UINT16                           UpdatePageId,
1211  IN BMM_CALLBACK_DATA                *CallbackData
1212  )
1213{
1214  CleanUpPage (UpdatePageId, CallbackData);
1215  switch (UpdatePageId) {
1216  case FORM_CON_IN_ID:
1217    UpdateConsolePage (UpdatePageId, &ConsoleInpMenu, CallbackData);
1218    break;
1219
1220  case FORM_CON_OUT_ID:
1221    UpdateConsolePage (UpdatePageId, &ConsoleOutMenu, CallbackData);
1222    break;
1223
1224  case FORM_CON_ERR_ID:
1225    UpdateConsolePage (UpdatePageId, &ConsoleErrMenu, CallbackData);
1226    break;
1227
1228  case FORM_BOOT_CHG_ID:
1229    UpdateOrderPage (UpdatePageId, &BootOptionMenu, CallbackData);
1230    break;
1231
1232  case FORM_DRV_CHG_ID:
1233    UpdateOrderPage (UpdatePageId, &DriverOptionMenu, CallbackData);
1234    break;
1235
1236  default:
1237    break;
1238  }
1239}
1240
1241/**
1242  Dispatch the display to the next page based on NewPageId.
1243
1244  @param Private         The BMM context data.
1245  @param NewPageId       The original page ID.
1246
1247**/
1248VOID
1249UpdatePageId (
1250  BMM_CALLBACK_DATA              *Private,
1251  UINT16                         NewPageId
1252  )
1253{
1254  if ((NewPageId < FILE_OPTION_OFFSET) && (NewPageId >= HANDLE_OPTION_OFFSET)) {
1255    //
1256    // If we select a handle to add driver option, advance to the add handle description page.
1257    //
1258    NewPageId = FORM_DRV_ADD_HANDLE_DESC_ID;
1259  } else if ((NewPageId == KEY_VALUE_SAVE_AND_EXIT) || (NewPageId == KEY_VALUE_NO_SAVE_AND_EXIT)) {
1260    //
1261    // Return to main page after "Save Changes" or "Discard Changes".
1262    //
1263    NewPageId = FORM_MAIN_ID;
1264  } else if ((NewPageId >= TERMINAL_OPTION_OFFSET) && (NewPageId < CONSOLE_OPTION_OFFSET)) {
1265    NewPageId = FORM_CON_COM_SETUP_ID;
1266  }
1267
1268  if ((NewPageId > 0) && (NewPageId < MAXIMUM_FORM_ID)) {
1269    Private->BmmPreviousPageId  = Private->BmmCurrentPageId;
1270    Private->BmmCurrentPageId   = NewPageId;
1271  }
1272}
1273