mirror of https://github.com/acidanthera/audk.git
1141 lines
32 KiB
C
1141 lines
32 KiB
C
/** @file
|
|
Dynamically update the pages.
|
|
|
|
Copyright (c) 2004 - 2016, Intel Corporation. All rights reserved.<BR>
|
|
This program and the accompanying materials
|
|
are licensed and made available under the terms and conditions of the BSD License
|
|
which accompanies this distribution. The full text of the license may be found at
|
|
http://opensource.org/licenses/bsd-license.php
|
|
|
|
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|
|
|
**/
|
|
|
|
#include "BootMaintenanceManager.h"
|
|
|
|
/**
|
|
Create the global UpdateData structure.
|
|
|
|
**/
|
|
VOID
|
|
CreateUpdateData (
|
|
VOID
|
|
)
|
|
{
|
|
//
|
|
// Init OpCode Handle and Allocate space for creation of Buffer
|
|
//
|
|
mStartOpCodeHandle = HiiAllocateOpCodeHandle ();
|
|
ASSERT (mStartOpCodeHandle != NULL);
|
|
|
|
mEndOpCodeHandle = HiiAllocateOpCodeHandle ();
|
|
ASSERT (mEndOpCodeHandle != NULL);
|
|
|
|
//
|
|
// Create Hii Extend Label OpCode as the start opcode
|
|
//
|
|
mStartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (mStartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
|
|
mStartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
|
|
|
|
//
|
|
// Create Hii Extend Label OpCode as the end opcode
|
|
//
|
|
mEndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (mEndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
|
|
mEndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
|
|
mEndLabel->Number = LABEL_END;
|
|
}
|
|
|
|
/**
|
|
Refresh the global UpdateData structure.
|
|
|
|
**/
|
|
VOID
|
|
RefreshUpdateData (
|
|
VOID
|
|
)
|
|
{
|
|
//
|
|
// Free current updated date
|
|
//
|
|
if (mStartOpCodeHandle != NULL) {
|
|
HiiFreeOpCodeHandle (mStartOpCodeHandle);
|
|
}
|
|
|
|
//
|
|
// Create new OpCode Handle
|
|
//
|
|
mStartOpCodeHandle = HiiAllocateOpCodeHandle ();
|
|
|
|
//
|
|
// Create Hii Extend Label OpCode as the start opcode
|
|
//
|
|
mStartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (mStartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
|
|
mStartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
|
|
|
|
}
|
|
|
|
/**
|
|
Add a "Go back to main page" tag in front of the form when there are no
|
|
"Apply changes" and "Discard changes" tags in the end of the form.
|
|
|
|
@param CallbackData The BMM context data.
|
|
|
|
**/
|
|
VOID
|
|
UpdatePageStart (
|
|
IN BMM_CALLBACK_DATA *CallbackData
|
|
)
|
|
{
|
|
RefreshUpdateData ();
|
|
mStartLabel->Number = CallbackData->BmmCurrentPageId;
|
|
|
|
if (!(CallbackData->BmmAskSaveOrNot)) {
|
|
//
|
|
// Add a "Go back to main page" tag in front of the form when there are no
|
|
// "Apply changes" and "Discard changes" tags in the end of the form.
|
|
//
|
|
HiiCreateGotoOpCode (
|
|
mStartOpCodeHandle,
|
|
FORM_MAIN_ID,
|
|
STRING_TOKEN (STR_FORM_GOTO_MAIN),
|
|
STRING_TOKEN (STR_FORM_GOTO_MAIN),
|
|
0,
|
|
FORM_MAIN_ID
|
|
);
|
|
}
|
|
}
|
|
|
|
/**
|
|
Create the "Apply changes" and "Discard changes" tags. And
|
|
ensure user can return to the main page.
|
|
|
|
@param CallbackData The BMM context data.
|
|
|
|
**/
|
|
VOID
|
|
UpdatePageEnd (
|
|
IN BMM_CALLBACK_DATA *CallbackData
|
|
)
|
|
{
|
|
//
|
|
// Create the "Apply changes" and "Discard changes" tags.
|
|
//
|
|
if (CallbackData->BmmAskSaveOrNot) {
|
|
HiiCreateSubTitleOpCode (
|
|
mStartOpCodeHandle,
|
|
STRING_TOKEN (STR_NULL_STRING),
|
|
0,
|
|
0,
|
|
0
|
|
);
|
|
|
|
HiiCreateActionOpCode (
|
|
mStartOpCodeHandle,
|
|
KEY_VALUE_SAVE_AND_EXIT,
|
|
STRING_TOKEN (STR_SAVE_AND_EXIT),
|
|
STRING_TOKEN (STR_NULL_STRING),
|
|
EFI_IFR_FLAG_CALLBACK,
|
|
0
|
|
);
|
|
}
|
|
|
|
//
|
|
// Ensure user can return to the main page.
|
|
//
|
|
HiiCreateActionOpCode (
|
|
mStartOpCodeHandle,
|
|
KEY_VALUE_NO_SAVE_AND_EXIT,
|
|
STRING_TOKEN (STR_NO_SAVE_AND_EXIT),
|
|
STRING_TOKEN (STR_NULL_STRING),
|
|
EFI_IFR_FLAG_CALLBACK,
|
|
0
|
|
);
|
|
|
|
HiiUpdateForm (
|
|
CallbackData->BmmHiiHandle,
|
|
&mBootMaintGuid,
|
|
CallbackData->BmmCurrentPageId,
|
|
mStartOpCodeHandle, // Label CallbackData->BmmCurrentPageId
|
|
mEndOpCodeHandle // LABEL_END
|
|
);
|
|
}
|
|
|
|
/**
|
|
Clean up the dynamic opcode at label and form specified by both LabelId.
|
|
|
|
@param LabelId It is both the Form ID and Label ID for opcode deletion.
|
|
@param CallbackData The BMM context data.
|
|
|
|
**/
|
|
VOID
|
|
CleanUpPage (
|
|
IN UINT16 LabelId,
|
|
IN BMM_CALLBACK_DATA *CallbackData
|
|
)
|
|
{
|
|
RefreshUpdateData ();
|
|
|
|
//
|
|
// Remove all op-codes from dynamic page
|
|
//
|
|
mStartLabel->Number = LabelId;
|
|
HiiUpdateForm (
|
|
CallbackData->BmmHiiHandle,
|
|
&mBootMaintGuid,
|
|
LabelId,
|
|
mStartOpCodeHandle, // Label LabelId
|
|
mEndOpCodeHandle // LABEL_END
|
|
);
|
|
}
|
|
|
|
/**
|
|
Create a list of Goto Opcode for all terminal devices logged
|
|
by TerminaMenu. This list will be inserted to form FORM_CON_COM_SETUP_ID.
|
|
|
|
@param CallbackData The BMM context data.
|
|
**/
|
|
VOID
|
|
UpdateConCOMPage (
|
|
IN BMM_CALLBACK_DATA *CallbackData
|
|
)
|
|
{
|
|
BM_MENU_ENTRY *NewMenuEntry;
|
|
UINT16 Index;
|
|
|
|
CallbackData->BmmAskSaveOrNot = TRUE;
|
|
|
|
UpdatePageStart (CallbackData);
|
|
|
|
for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {
|
|
NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);
|
|
|
|
HiiCreateGotoOpCode (
|
|
mStartOpCodeHandle,
|
|
FORM_CON_COM_SETUP_ID,
|
|
NewMenuEntry->DisplayStringToken,
|
|
STRING_TOKEN (STR_NULL_STRING),
|
|
EFI_IFR_FLAG_CALLBACK,
|
|
(UINT16) (TERMINAL_OPTION_OFFSET + Index)
|
|
);
|
|
}
|
|
|
|
UpdatePageEnd (CallbackData);
|
|
}
|
|
|
|
|
|
/**
|
|
Create a list of boot option from global BootOptionMenu. It
|
|
allow user to delete the boot option.
|
|
|
|
@param CallbackData The BMM context data.
|
|
|
|
**/
|
|
VOID
|
|
UpdateBootDelPage (
|
|
IN BMM_CALLBACK_DATA *CallbackData
|
|
)
|
|
{
|
|
BM_MENU_ENTRY *NewMenuEntry;
|
|
BM_LOAD_CONTEXT *NewLoadContext;
|
|
UINT16 Index;
|
|
|
|
CallbackData->BmmAskSaveOrNot = TRUE;
|
|
|
|
UpdatePageStart (CallbackData);
|
|
|
|
ASSERT (BootOptionMenu.MenuNumber <= (sizeof (CallbackData->BmmFakeNvData.BootOptionDel) / sizeof (CallbackData->BmmFakeNvData.BootOptionDel[0])));
|
|
for (Index = 0; Index < BootOptionMenu.MenuNumber; Index++) {
|
|
NewMenuEntry = BOpt_GetMenuEntry (&BootOptionMenu, Index);
|
|
NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;
|
|
if (NewLoadContext->IsLegacy) {
|
|
continue;
|
|
}
|
|
|
|
NewLoadContext->Deleted = FALSE;
|
|
|
|
if (CallbackData->BmmFakeNvData.BootOptionDel[Index] && !CallbackData->BmmFakeNvData.BootOptionDelMark[Index]) {
|
|
//
|
|
// CallbackData->BmmFakeNvData.BootOptionDel[Index] == TRUE means browser knows this boot option is selected
|
|
// CallbackData->BmmFakeNvData.BootOptionDelMark[Index] = FALSE means BDS knows the selected boot option has
|
|
// deleted, browser maintains old useless info. So clear this info here, and later update this info to browser
|
|
// through HiiSetBrowserData function.
|
|
//
|
|
CallbackData->BmmFakeNvData.BootOptionDel[Index] = FALSE;
|
|
}
|
|
|
|
HiiCreateCheckBoxOpCode (
|
|
mStartOpCodeHandle,
|
|
(EFI_QUESTION_ID) (BOOT_OPTION_DEL_QUESTION_ID + Index),
|
|
VARSTORE_ID_BOOT_MAINT,
|
|
(UINT16) (BOOT_OPTION_DEL_VAR_OFFSET + Index),
|
|
NewMenuEntry->DisplayStringToken,
|
|
NewMenuEntry->HelpStringToken,
|
|
EFI_IFR_FLAG_CALLBACK,
|
|
0,
|
|
NULL
|
|
);
|
|
}
|
|
UpdatePageEnd (CallbackData);
|
|
}
|
|
|
|
/**
|
|
Create a lit of driver option from global DriverMenu.
|
|
|
|
@param CallbackData The BMM context data.
|
|
|
|
**/
|
|
VOID
|
|
UpdateDrvAddHandlePage (
|
|
IN BMM_CALLBACK_DATA *CallbackData
|
|
)
|
|
{
|
|
BM_MENU_ENTRY *NewMenuEntry;
|
|
UINT16 Index;
|
|
|
|
CallbackData->BmmAskSaveOrNot = FALSE;
|
|
|
|
UpdatePageStart (CallbackData);
|
|
|
|
for (Index = 0; Index < DriverMenu.MenuNumber; Index++) {
|
|
NewMenuEntry = BOpt_GetMenuEntry (&DriverMenu, Index);
|
|
|
|
HiiCreateGotoOpCode (
|
|
mStartOpCodeHandle,
|
|
FORM_DRV_ADD_HANDLE_DESC_ID,
|
|
NewMenuEntry->DisplayStringToken,
|
|
STRING_TOKEN (STR_NULL_STRING),
|
|
EFI_IFR_FLAG_CALLBACK,
|
|
(UINT16) (HANDLE_OPTION_OFFSET + Index)
|
|
);
|
|
}
|
|
|
|
UpdatePageEnd (CallbackData);
|
|
}
|
|
|
|
/**
|
|
Create a lit of driver option from global DriverOptionMenu. It
|
|
allow user to delete the driver option.
|
|
|
|
@param CallbackData The BMM context data.
|
|
|
|
**/
|
|
VOID
|
|
UpdateDrvDelPage (
|
|
IN BMM_CALLBACK_DATA *CallbackData
|
|
)
|
|
{
|
|
BM_MENU_ENTRY *NewMenuEntry;
|
|
BM_LOAD_CONTEXT *NewLoadContext;
|
|
UINT16 Index;
|
|
|
|
CallbackData->BmmAskSaveOrNot = TRUE;
|
|
|
|
UpdatePageStart (CallbackData);
|
|
|
|
ASSERT (DriverOptionMenu.MenuNumber <= (sizeof (CallbackData->BmmFakeNvData.DriverOptionDel) / sizeof (CallbackData->BmmFakeNvData.DriverOptionDel[0])));
|
|
for (Index = 0; Index < DriverOptionMenu.MenuNumber; Index++) {
|
|
NewMenuEntry = BOpt_GetMenuEntry (&DriverOptionMenu, Index);
|
|
|
|
NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;
|
|
NewLoadContext->Deleted = FALSE;
|
|
|
|
if (CallbackData->BmmFakeNvData.DriverOptionDel[Index] && !CallbackData->BmmFakeNvData.DriverOptionDelMark[Index]) {
|
|
//
|
|
// CallbackData->BmmFakeNvData.BootOptionDel[Index] == TRUE means browser knows this boot option is selected
|
|
// CallbackData->BmmFakeNvData.BootOptionDelMark[Index] = FALSE means BDS knows the selected boot option has
|
|
// deleted, browser maintains old useless info. So clear this info here, and later update this info to browser
|
|
// through HiiSetBrowserData function.
|
|
//
|
|
CallbackData->BmmFakeNvData.DriverOptionDel[Index] = FALSE;
|
|
}
|
|
HiiCreateCheckBoxOpCode (
|
|
mStartOpCodeHandle,
|
|
(EFI_QUESTION_ID) (DRIVER_OPTION_DEL_QUESTION_ID + Index),
|
|
VARSTORE_ID_BOOT_MAINT,
|
|
(UINT16) (DRIVER_OPTION_DEL_VAR_OFFSET + Index),
|
|
NewMenuEntry->DisplayStringToken,
|
|
NewMenuEntry->HelpStringToken,
|
|
EFI_IFR_FLAG_CALLBACK,
|
|
0,
|
|
NULL
|
|
);
|
|
}
|
|
|
|
UpdatePageEnd (CallbackData);
|
|
}
|
|
|
|
/**
|
|
Prepare the page to allow user to add description for
|
|
a Driver Option.
|
|
|
|
@param CallbackData The BMM context data.
|
|
|
|
**/
|
|
VOID
|
|
UpdateDriverAddHandleDescPage (
|
|
IN BMM_CALLBACK_DATA *CallbackData
|
|
)
|
|
{
|
|
BM_MENU_ENTRY *NewMenuEntry;
|
|
|
|
CallbackData->BmmFakeNvData.DriverAddActive = 0x01;
|
|
CallbackData->BmmFakeNvData.DriverAddForceReconnect = 0x00;
|
|
CallbackData->BmmAskSaveOrNot = TRUE;
|
|
NewMenuEntry = CallbackData->MenuEntry;
|
|
|
|
UpdatePageStart (CallbackData);
|
|
|
|
HiiCreateSubTitleOpCode (
|
|
mStartOpCodeHandle,
|
|
NewMenuEntry->DisplayStringToken,
|
|
0,
|
|
0,
|
|
0
|
|
);
|
|
|
|
HiiCreateStringOpCode (
|
|
mStartOpCodeHandle,
|
|
(EFI_QUESTION_ID) DRV_ADD_HANDLE_DESC_QUESTION_ID,
|
|
VARSTORE_ID_BOOT_MAINT,
|
|
DRV_ADD_HANDLE_DESC_VAR_OFFSET,
|
|
STRING_TOKEN (STR_LOAD_OPTION_DESC),
|
|
STRING_TOKEN (STR_NULL_STRING),
|
|
0,
|
|
0,
|
|
6,
|
|
75,
|
|
NULL
|
|
);
|
|
|
|
HiiCreateCheckBoxOpCode (
|
|
mStartOpCodeHandle,
|
|
(EFI_QUESTION_ID) DRV_ADD_RECON_QUESTION_ID,
|
|
VARSTORE_ID_BOOT_MAINT,
|
|
DRV_ADD_RECON_VAR_OFFSET,
|
|
STRING_TOKEN (STR_LOAD_OPTION_FORCE_RECON),
|
|
STRING_TOKEN (STR_LOAD_OPTION_FORCE_RECON),
|
|
0,
|
|
0,
|
|
NULL
|
|
);
|
|
|
|
HiiCreateStringOpCode (
|
|
mStartOpCodeHandle,
|
|
(EFI_QUESTION_ID) DRIVER_ADD_OPTION_QUESTION_ID,
|
|
VARSTORE_ID_BOOT_MAINT,
|
|
DRIVER_ADD_OPTION_VAR_OFFSET,
|
|
STRING_TOKEN (STR_OPTIONAL_DATA),
|
|
STRING_TOKEN (STR_NULL_STRING),
|
|
0,
|
|
0,
|
|
6,
|
|
75,
|
|
NULL
|
|
);
|
|
|
|
UpdatePageEnd (CallbackData);
|
|
}
|
|
|
|
/**
|
|
Update console page.
|
|
|
|
@param UpdatePageId The form ID to be updated.
|
|
@param ConsoleMenu The console menu list.
|
|
@param CallbackData The BMM context data.
|
|
|
|
**/
|
|
VOID
|
|
UpdateConsolePage (
|
|
IN UINT16 UpdatePageId,
|
|
IN BM_MENU_OPTION *ConsoleMenu,
|
|
IN BMM_CALLBACK_DATA *CallbackData
|
|
)
|
|
{
|
|
BM_MENU_ENTRY *NewMenuEntry;
|
|
BM_CONSOLE_CONTEXT *NewConsoleContext;
|
|
BM_TERMINAL_CONTEXT *NewTerminalContext;
|
|
UINT16 Index;
|
|
UINT16 Index2;
|
|
UINT8 CheckFlags;
|
|
UINT8 *ConsoleCheck;
|
|
UINT8 *OldConsoleCheck;
|
|
UINTN ConsoleCheckSize;
|
|
EFI_QUESTION_ID QuestionIdBase;
|
|
UINT16 VariableOffsetBase;
|
|
|
|
CallbackData->BmmAskSaveOrNot = TRUE;
|
|
|
|
UpdatePageStart (CallbackData);
|
|
|
|
ConsoleCheck = NULL;
|
|
OldConsoleCheck = NULL;
|
|
QuestionIdBase = 0;
|
|
VariableOffsetBase = 0;
|
|
ConsoleCheckSize = 0;
|
|
|
|
switch (UpdatePageId) {
|
|
case FORM_CON_IN_ID:
|
|
ConsoleCheck = &CallbackData->BmmFakeNvData.ConsoleInCheck[0];
|
|
OldConsoleCheck = &CallbackData->BmmOldFakeNVData.ConsoleInCheck[0];
|
|
ConsoleCheckSize = sizeof (CallbackData->BmmFakeNvData.ConsoleInCheck);
|
|
QuestionIdBase = CON_IN_DEVICE_QUESTION_ID;
|
|
VariableOffsetBase = CON_IN_DEVICE_VAR_OFFSET;
|
|
break;
|
|
|
|
case FORM_CON_OUT_ID:
|
|
ConsoleCheck = &CallbackData->BmmFakeNvData.ConsoleOutCheck[0];
|
|
OldConsoleCheck = &CallbackData->BmmOldFakeNVData.ConsoleOutCheck[0];
|
|
ConsoleCheckSize = sizeof (CallbackData->BmmFakeNvData.ConsoleOutCheck);
|
|
QuestionIdBase = CON_OUT_DEVICE_QUESTION_ID;
|
|
VariableOffsetBase = CON_OUT_DEVICE_VAR_OFFSET;
|
|
break;
|
|
|
|
case FORM_CON_ERR_ID:
|
|
ConsoleCheck = &CallbackData->BmmFakeNvData.ConsoleErrCheck[0];
|
|
OldConsoleCheck = &CallbackData->BmmOldFakeNVData.ConsoleErrCheck[0];
|
|
ConsoleCheckSize = sizeof (CallbackData->BmmFakeNvData.ConsoleErrCheck);
|
|
QuestionIdBase = CON_ERR_DEVICE_QUESTION_ID;
|
|
VariableOffsetBase = CON_ERR_DEVICE_VAR_OFFSET;
|
|
break;
|
|
}
|
|
ASSERT (ConsoleCheck != NULL);
|
|
|
|
for (Index = 0; ((Index < ConsoleMenu->MenuNumber) && \
|
|
(Index < MAX_MENU_NUMBER)) ; Index++) {
|
|
CheckFlags = 0;
|
|
NewMenuEntry = BOpt_GetMenuEntry (ConsoleMenu, Index);
|
|
NewConsoleContext = (BM_CONSOLE_CONTEXT *) NewMenuEntry->VariableContext;
|
|
if (NewConsoleContext->IsActive) {
|
|
CheckFlags |= EFI_IFR_CHECKBOX_DEFAULT;
|
|
ConsoleCheck[Index] = TRUE;
|
|
} else {
|
|
ConsoleCheck[Index] = FALSE;
|
|
}
|
|
HiiCreateCheckBoxOpCode (
|
|
mStartOpCodeHandle,
|
|
(EFI_QUESTION_ID) (QuestionIdBase + Index),
|
|
VARSTORE_ID_BOOT_MAINT,
|
|
(UINT16) (VariableOffsetBase + Index),
|
|
NewMenuEntry->DisplayStringToken,
|
|
NewMenuEntry->HelpStringToken,
|
|
0,
|
|
CheckFlags,
|
|
NULL
|
|
);
|
|
}
|
|
|
|
for (Index2 = 0; ((Index2 < TerminalMenu.MenuNumber) && \
|
|
(Index2 < MAX_MENU_NUMBER)); Index2++) {
|
|
CheckFlags = 0;
|
|
NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index2);
|
|
NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;
|
|
|
|
ASSERT (Index < MAX_MENU_NUMBER);
|
|
if (((NewTerminalContext->IsConIn != 0) && (UpdatePageId == FORM_CON_IN_ID)) ||
|
|
((NewTerminalContext->IsConOut != 0) && (UpdatePageId == FORM_CON_OUT_ID)) ||
|
|
((NewTerminalContext->IsStdErr != 0) && (UpdatePageId == FORM_CON_ERR_ID))
|
|
) {
|
|
CheckFlags |= EFI_IFR_CHECKBOX_DEFAULT;
|
|
ConsoleCheck[Index] = TRUE;
|
|
} else {
|
|
ConsoleCheck[Index] = FALSE;
|
|
}
|
|
HiiCreateCheckBoxOpCode (
|
|
mStartOpCodeHandle,
|
|
(EFI_QUESTION_ID) (QuestionIdBase + Index),
|
|
VARSTORE_ID_BOOT_MAINT,
|
|
(UINT16) (VariableOffsetBase + Index),
|
|
NewMenuEntry->DisplayStringToken,
|
|
NewMenuEntry->HelpStringToken,
|
|
0,
|
|
CheckFlags,
|
|
NULL
|
|
);
|
|
|
|
Index++;
|
|
}
|
|
|
|
CopyMem (OldConsoleCheck, ConsoleCheck, ConsoleCheckSize);
|
|
|
|
UpdatePageEnd (CallbackData);
|
|
}
|
|
|
|
/**
|
|
Update the page's NV Map if user has changed the order
|
|
a list. This list can be Boot Order or Driver Order.
|
|
|
|
@param UpdatePageId The form ID to be updated.
|
|
@param OptionMenu The new list.
|
|
@param CallbackData The BMM context data.
|
|
|
|
**/
|
|
VOID
|
|
UpdateOrderPage (
|
|
IN UINT16 UpdatePageId,
|
|
IN BM_MENU_OPTION *OptionMenu,
|
|
IN BMM_CALLBACK_DATA *CallbackData
|
|
)
|
|
{
|
|
BM_MENU_ENTRY *NewMenuEntry;
|
|
UINT16 Index;
|
|
UINT16 OptionIndex;
|
|
VOID *OptionsOpCodeHandle;
|
|
BOOLEAN BootOptionFound;
|
|
UINT32 *OptionOrder;
|
|
EFI_QUESTION_ID QuestionId;
|
|
UINT16 VarOffset;
|
|
|
|
CallbackData->BmmAskSaveOrNot = TRUE;
|
|
UpdatePageStart (CallbackData);
|
|
|
|
OptionOrder = NULL;
|
|
QuestionId = 0;
|
|
VarOffset = 0;
|
|
switch (UpdatePageId) {
|
|
|
|
case FORM_BOOT_CHG_ID:
|
|
GetBootOrder (CallbackData);
|
|
OptionOrder = CallbackData->BmmFakeNvData.BootOptionOrder;
|
|
QuestionId = BOOT_OPTION_ORDER_QUESTION_ID;
|
|
VarOffset = BOOT_OPTION_ORDER_VAR_OFFSET;
|
|
break;
|
|
|
|
case FORM_DRV_CHG_ID:
|
|
GetDriverOrder (CallbackData);
|
|
OptionOrder = CallbackData->BmmFakeNvData.DriverOptionOrder;
|
|
QuestionId = DRIVER_OPTION_ORDER_QUESTION_ID;
|
|
VarOffset = DRIVER_OPTION_ORDER_VAR_OFFSET;
|
|
break;
|
|
}
|
|
ASSERT (OptionOrder != NULL);
|
|
|
|
OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();
|
|
ASSERT (OptionsOpCodeHandle != NULL);
|
|
|
|
NewMenuEntry = NULL;
|
|
for (OptionIndex = 0; (OptionOrder[OptionIndex] != 0 && OptionIndex < MAX_MENU_NUMBER); OptionIndex++) {
|
|
BootOptionFound = FALSE;
|
|
for (Index = 0; Index < OptionMenu->MenuNumber; Index++) {
|
|
NewMenuEntry = BOpt_GetMenuEntry (OptionMenu, Index);
|
|
if ((UINT32) (NewMenuEntry->OptionNumber + 1) == OptionOrder[OptionIndex]) {
|
|
BootOptionFound = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
if (BootOptionFound) {
|
|
HiiCreateOneOfOptionOpCode (
|
|
OptionsOpCodeHandle,
|
|
NewMenuEntry->DisplayStringToken,
|
|
0,
|
|
EFI_IFR_TYPE_NUM_SIZE_32,
|
|
OptionOrder[OptionIndex]
|
|
);
|
|
}
|
|
}
|
|
|
|
if (OptionMenu->MenuNumber > 0) {
|
|
HiiCreateOrderedListOpCode (
|
|
mStartOpCodeHandle, // Container for dynamic created opcodes
|
|
QuestionId, // Question ID
|
|
VARSTORE_ID_BOOT_MAINT, // VarStore ID
|
|
VarOffset, // Offset in Buffer Storage
|
|
STRING_TOKEN (STR_CHANGE_ORDER), // Question prompt text
|
|
STRING_TOKEN (STR_CHANGE_ORDER), // Question help text
|
|
0, // Question flag
|
|
0, // Ordered list flag, e.g. EFI_IFR_UNIQUE_SET
|
|
EFI_IFR_TYPE_NUM_SIZE_32, // Data type of Question value
|
|
100, // Maximum container
|
|
OptionsOpCodeHandle, // Option Opcode list
|
|
NULL // Default Opcode is NULL
|
|
);
|
|
}
|
|
|
|
HiiFreeOpCodeHandle (OptionsOpCodeHandle);
|
|
|
|
UpdatePageEnd (CallbackData);
|
|
|
|
}
|
|
|
|
/**
|
|
Refresh the text mode page.
|
|
|
|
@param CallbackData The BMM context data.
|
|
|
|
**/
|
|
VOID
|
|
UpdateConModePage (
|
|
IN BMM_CALLBACK_DATA *CallbackData
|
|
)
|
|
{
|
|
UINTN Mode;
|
|
UINTN Index;
|
|
UINTN Col;
|
|
UINTN Row;
|
|
CHAR16 ModeString[50];
|
|
CHAR16 *PStr;
|
|
UINTN MaxMode;
|
|
UINTN ValidMode;
|
|
EFI_STRING_ID *ModeToken;
|
|
EFI_STATUS Status;
|
|
VOID *OptionsOpCodeHandle;
|
|
EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *ConOut;
|
|
|
|
ConOut = gST->ConOut;
|
|
Index = 0;
|
|
ValidMode = 0;
|
|
MaxMode = (UINTN) (ConOut->Mode->MaxMode);
|
|
|
|
CallbackData->BmmAskSaveOrNot = TRUE;
|
|
|
|
UpdatePageStart (CallbackData);
|
|
|
|
//
|
|
// Check valid mode
|
|
//
|
|
for (Mode = 0; Mode < MaxMode; Mode++) {
|
|
Status = ConOut->QueryMode (ConOut, Mode, &Col, &Row);
|
|
if (EFI_ERROR (Status)) {
|
|
continue;
|
|
}
|
|
ValidMode++;
|
|
}
|
|
|
|
if (ValidMode == 0) {
|
|
return;
|
|
}
|
|
|
|
OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();
|
|
ASSERT (OptionsOpCodeHandle != NULL);
|
|
|
|
ModeToken = AllocateZeroPool (sizeof (EFI_STRING_ID) * ValidMode);
|
|
ASSERT(ModeToken != NULL);
|
|
|
|
//
|
|
// Determin which mode should be the first entry in menu
|
|
//
|
|
GetConsoleOutMode (CallbackData);
|
|
|
|
//
|
|
// Build text mode options
|
|
//
|
|
for (Mode = 0; Mode < MaxMode; Mode++) {
|
|
Status = ConOut->QueryMode (ConOut, Mode, &Col, &Row);
|
|
if (EFI_ERROR (Status)) {
|
|
continue;
|
|
}
|
|
|
|
//
|
|
// Build mode string Column x Row
|
|
//
|
|
UnicodeValueToString (ModeString, 0, Col, 0);
|
|
PStr = &ModeString[0];
|
|
StrnCatS (PStr, sizeof (ModeString) / sizeof (ModeString[0]), L" x ", StrLen(L" x ") + 1);
|
|
PStr = PStr + StrLen (PStr);
|
|
UnicodeValueToString (PStr , 0, Row, 0);
|
|
|
|
ModeToken[Index] = HiiSetString (CallbackData->BmmHiiHandle, 0, ModeString, NULL);
|
|
|
|
if (Mode == CallbackData->BmmFakeNvData.ConsoleOutMode) {
|
|
HiiCreateOneOfOptionOpCode (
|
|
OptionsOpCodeHandle,
|
|
ModeToken[Index],
|
|
EFI_IFR_OPTION_DEFAULT,
|
|
EFI_IFR_TYPE_NUM_SIZE_16,
|
|
(UINT16) Mode
|
|
);
|
|
} else {
|
|
HiiCreateOneOfOptionOpCode (
|
|
OptionsOpCodeHandle,
|
|
ModeToken[Index],
|
|
0,
|
|
EFI_IFR_TYPE_NUM_SIZE_16,
|
|
(UINT16) Mode
|
|
);
|
|
}
|
|
Index++;
|
|
}
|
|
|
|
HiiCreateOneOfOpCode (
|
|
mStartOpCodeHandle,
|
|
(EFI_QUESTION_ID) CON_MODE_QUESTION_ID,
|
|
VARSTORE_ID_BOOT_MAINT,
|
|
CON_MODE_VAR_OFFSET,
|
|
STRING_TOKEN (STR_CON_MODE_SETUP),
|
|
STRING_TOKEN (STR_CON_MODE_SETUP),
|
|
EFI_IFR_FLAG_RESET_REQUIRED,
|
|
EFI_IFR_NUMERIC_SIZE_2,
|
|
OptionsOpCodeHandle,
|
|
NULL
|
|
);
|
|
|
|
HiiFreeOpCodeHandle (OptionsOpCodeHandle);
|
|
FreePool (ModeToken);
|
|
|
|
UpdatePageEnd (CallbackData);
|
|
}
|
|
|
|
/**
|
|
Create the dynamic page which allows user to set the property such as Baud Rate, Data Bits,
|
|
Parity, Stop Bits, Terminal Type.
|
|
|
|
@param CallbackData The BMM context data.
|
|
|
|
**/
|
|
VOID
|
|
UpdateTerminalPage (
|
|
IN BMM_CALLBACK_DATA *CallbackData
|
|
)
|
|
{
|
|
UINT8 Index;
|
|
UINT8 CheckFlags;
|
|
BM_MENU_ENTRY *NewMenuEntry;
|
|
VOID *OptionsOpCodeHandle;
|
|
UINTN CurrentTerminal;
|
|
|
|
CallbackData->BmmAskSaveOrNot = TRUE;
|
|
|
|
UpdatePageStart (CallbackData);
|
|
|
|
CurrentTerminal = CallbackData->CurrentTerminal;
|
|
NewMenuEntry = BOpt_GetMenuEntry (
|
|
&TerminalMenu,
|
|
CurrentTerminal
|
|
);
|
|
|
|
if (NewMenuEntry == NULL) {
|
|
return ;
|
|
}
|
|
|
|
OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();
|
|
ASSERT (OptionsOpCodeHandle != NULL);
|
|
|
|
for (Index = 0; Index < sizeof (BaudRateList) / sizeof (BaudRateList [0]); Index++) {
|
|
CheckFlags = 0;
|
|
if (BaudRateList[Index].Value == 115200) {
|
|
CheckFlags |= EFI_IFR_OPTION_DEFAULT;
|
|
}
|
|
HiiCreateOneOfOptionOpCode (
|
|
OptionsOpCodeHandle,
|
|
BaudRateList[Index].StringToken,
|
|
CheckFlags,
|
|
EFI_IFR_TYPE_NUM_SIZE_8,
|
|
Index
|
|
);
|
|
}
|
|
|
|
HiiCreateOneOfOpCode (
|
|
mStartOpCodeHandle,
|
|
(EFI_QUESTION_ID) (COM_BAUD_RATE_QUESTION_ID + CurrentTerminal),
|
|
VARSTORE_ID_BOOT_MAINT,
|
|
(UINT16) (COM_BAUD_RATE_VAR_OFFSET + CurrentTerminal),
|
|
STRING_TOKEN (STR_COM_BAUD_RATE),
|
|
STRING_TOKEN (STR_COM_BAUD_RATE),
|
|
0,
|
|
EFI_IFR_NUMERIC_SIZE_1,
|
|
OptionsOpCodeHandle,
|
|
NULL
|
|
);
|
|
|
|
HiiFreeOpCodeHandle (OptionsOpCodeHandle);
|
|
OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();
|
|
ASSERT (OptionsOpCodeHandle != NULL);
|
|
|
|
for (Index = 0; Index < sizeof (DataBitsList) / sizeof (DataBitsList[0]); Index++) {
|
|
CheckFlags = 0;
|
|
|
|
if (DataBitsList[Index].Value == 8) {
|
|
CheckFlags |= EFI_IFR_OPTION_DEFAULT;
|
|
}
|
|
|
|
HiiCreateOneOfOptionOpCode (
|
|
OptionsOpCodeHandle,
|
|
DataBitsList[Index].StringToken,
|
|
CheckFlags,
|
|
EFI_IFR_TYPE_NUM_SIZE_8,
|
|
Index
|
|
);
|
|
}
|
|
|
|
HiiCreateOneOfOpCode (
|
|
mStartOpCodeHandle,
|
|
(EFI_QUESTION_ID) (COM_DATA_RATE_QUESTION_ID + CurrentTerminal),
|
|
VARSTORE_ID_BOOT_MAINT,
|
|
(UINT16) (COM_DATA_RATE_VAR_OFFSET + CurrentTerminal),
|
|
STRING_TOKEN (STR_COM_DATA_BITS),
|
|
STRING_TOKEN (STR_COM_DATA_BITS),
|
|
0,
|
|
EFI_IFR_NUMERIC_SIZE_1,
|
|
OptionsOpCodeHandle,
|
|
NULL
|
|
);
|
|
|
|
HiiFreeOpCodeHandle (OptionsOpCodeHandle);
|
|
OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();
|
|
ASSERT (OptionsOpCodeHandle != NULL);
|
|
|
|
for (Index = 0; Index < sizeof (ParityList) / sizeof (ParityList[0]); Index++) {
|
|
CheckFlags = 0;
|
|
if (ParityList[Index].Value == NoParity) {
|
|
CheckFlags |= EFI_IFR_OPTION_DEFAULT;
|
|
}
|
|
|
|
HiiCreateOneOfOptionOpCode (
|
|
OptionsOpCodeHandle,
|
|
ParityList[Index].StringToken,
|
|
CheckFlags,
|
|
EFI_IFR_TYPE_NUM_SIZE_8,
|
|
Index
|
|
);
|
|
}
|
|
|
|
HiiCreateOneOfOpCode (
|
|
mStartOpCodeHandle,
|
|
(EFI_QUESTION_ID) (COM_PARITY_QUESTION_ID + CurrentTerminal),
|
|
VARSTORE_ID_BOOT_MAINT,
|
|
(UINT16) (COM_PARITY_VAR_OFFSET + CurrentTerminal),
|
|
STRING_TOKEN (STR_COM_PARITY),
|
|
STRING_TOKEN (STR_COM_PARITY),
|
|
0,
|
|
EFI_IFR_NUMERIC_SIZE_1,
|
|
OptionsOpCodeHandle,
|
|
NULL
|
|
);
|
|
|
|
HiiFreeOpCodeHandle (OptionsOpCodeHandle);
|
|
OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();
|
|
ASSERT (OptionsOpCodeHandle != NULL);
|
|
|
|
for (Index = 0; Index < sizeof (StopBitsList) / sizeof (StopBitsList[0]); Index++) {
|
|
CheckFlags = 0;
|
|
if (StopBitsList[Index].Value == OneStopBit) {
|
|
CheckFlags |= EFI_IFR_OPTION_DEFAULT;
|
|
}
|
|
|
|
HiiCreateOneOfOptionOpCode (
|
|
OptionsOpCodeHandle,
|
|
StopBitsList[Index].StringToken,
|
|
CheckFlags,
|
|
EFI_IFR_TYPE_NUM_SIZE_8,
|
|
Index
|
|
);
|
|
}
|
|
|
|
HiiCreateOneOfOpCode (
|
|
mStartOpCodeHandle,
|
|
(EFI_QUESTION_ID) (COM_STOP_BITS_QUESTION_ID + CurrentTerminal),
|
|
VARSTORE_ID_BOOT_MAINT,
|
|
(UINT16) (COM_STOP_BITS_VAR_OFFSET + CurrentTerminal),
|
|
STRING_TOKEN (STR_COM_STOP_BITS),
|
|
STRING_TOKEN (STR_COM_STOP_BITS),
|
|
0,
|
|
EFI_IFR_NUMERIC_SIZE_1,
|
|
OptionsOpCodeHandle,
|
|
NULL
|
|
);
|
|
|
|
HiiFreeOpCodeHandle (OptionsOpCodeHandle);
|
|
OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();
|
|
ASSERT (OptionsOpCodeHandle != NULL);
|
|
|
|
for (Index = 0; Index < sizeof (TerminalType) / sizeof (TerminalType[0]); Index++) {
|
|
CheckFlags = 0;
|
|
if (Index == 0) {
|
|
CheckFlags |= EFI_IFR_OPTION_DEFAULT;
|
|
}
|
|
|
|
HiiCreateOneOfOptionOpCode (
|
|
OptionsOpCodeHandle,
|
|
(EFI_STRING_ID) TerminalType[Index],
|
|
CheckFlags,
|
|
EFI_IFR_TYPE_NUM_SIZE_8,
|
|
Index
|
|
);
|
|
}
|
|
|
|
HiiCreateOneOfOpCode (
|
|
mStartOpCodeHandle,
|
|
(EFI_QUESTION_ID) (COM_TERMINAL_QUESTION_ID + CurrentTerminal),
|
|
VARSTORE_ID_BOOT_MAINT,
|
|
(UINT16) (COM_TERMINAL_VAR_OFFSET + CurrentTerminal),
|
|
STRING_TOKEN (STR_COM_TERMI_TYPE),
|
|
STRING_TOKEN (STR_COM_TERMI_TYPE),
|
|
0,
|
|
EFI_IFR_NUMERIC_SIZE_1,
|
|
OptionsOpCodeHandle,
|
|
NULL
|
|
);
|
|
|
|
HiiFreeOpCodeHandle (OptionsOpCodeHandle);
|
|
OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();
|
|
ASSERT (OptionsOpCodeHandle != NULL);
|
|
|
|
for (Index = 0; Index < sizeof (mFlowControlType) / sizeof (mFlowControlType[0]); Index++) {
|
|
CheckFlags = 0;
|
|
if (Index == 0) {
|
|
CheckFlags |= EFI_IFR_OPTION_DEFAULT;
|
|
}
|
|
HiiCreateOneOfOptionOpCode (
|
|
OptionsOpCodeHandle,
|
|
(EFI_STRING_ID) mFlowControlType[Index],
|
|
CheckFlags,
|
|
EFI_IFR_TYPE_NUM_SIZE_8,
|
|
mFlowControlValue[Index]
|
|
);
|
|
}
|
|
|
|
HiiCreateOneOfOpCode (
|
|
mStartOpCodeHandle,
|
|
(EFI_QUESTION_ID) (COM_FLOWCONTROL_QUESTION_ID + CurrentTerminal),
|
|
VARSTORE_ID_BOOT_MAINT,
|
|
(UINT16) (COM_FLOWCONTROL_VAR_OFFSET + CurrentTerminal),
|
|
STRING_TOKEN (STR_COM_FLOW_CONTROL),
|
|
STRING_TOKEN (STR_COM_FLOW_CONTROL),
|
|
0,
|
|
EFI_IFR_NUMERIC_SIZE_1,
|
|
OptionsOpCodeHandle,
|
|
NULL
|
|
);
|
|
|
|
HiiFreeOpCodeHandle (OptionsOpCodeHandle);
|
|
|
|
UpdatePageEnd (CallbackData);
|
|
}
|
|
|
|
/**
|
|
Update add boot/driver option page.
|
|
|
|
@param CallbackData The BMM context data.
|
|
@param FormId The form ID to be updated.
|
|
@param DevicePath Device path.
|
|
|
|
**/
|
|
VOID
|
|
UpdateOptionPage(
|
|
IN BMM_CALLBACK_DATA *CallbackData,
|
|
IN EFI_FORM_ID FormId,
|
|
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
|
|
)
|
|
{
|
|
CHAR16 *String;
|
|
EFI_STRING_ID StringToken;
|
|
|
|
String = NULL;
|
|
|
|
if (DevicePath != NULL){
|
|
String = ExtractFileNameFromDevicePath(DevicePath);
|
|
}
|
|
if (String == NULL) {
|
|
String = HiiGetString (CallbackData->BmmHiiHandle, STRING_TOKEN (STR_NULL_STRING), NULL);
|
|
ASSERT (String != NULL);
|
|
}
|
|
|
|
StringToken = HiiSetString (CallbackData->BmmHiiHandle, 0, String, NULL);
|
|
FreePool (String);
|
|
|
|
if(FormId == FORM_BOOT_ADD_ID){
|
|
if (!CallbackData->BmmFakeNvData.BootOptionChanged) {
|
|
ZeroMem (CallbackData->BmmFakeNvData.BootOptionalData, sizeof (CallbackData->BmmFakeNvData.BootOptionalData));
|
|
ZeroMem (CallbackData->BmmFakeNvData.BootDescriptionData, sizeof (CallbackData->BmmFakeNvData.BootDescriptionData));
|
|
}
|
|
} else if (FormId == FORM_DRV_ADD_FILE_ID){
|
|
if (!CallbackData->BmmFakeNvData.DriverOptionChanged) {
|
|
ZeroMem (CallbackData->BmmFakeNvData.DriverOptionalData, sizeof (CallbackData->BmmFakeNvData.DriverOptionalData));
|
|
ZeroMem (CallbackData->BmmFakeNvData.DriverDescriptionData, sizeof (CallbackData->BmmFakeNvData.DriverDescriptionData));
|
|
}
|
|
}
|
|
|
|
RefreshUpdateData();
|
|
mStartLabel->Number = FormId;
|
|
|
|
HiiCreateSubTitleOpCode (
|
|
mStartOpCodeHandle,
|
|
StringToken,
|
|
0,
|
|
0,
|
|
0
|
|
);
|
|
|
|
HiiUpdateForm (
|
|
CallbackData->BmmHiiHandle,
|
|
&mBootMaintGuid,
|
|
FormId,
|
|
mStartOpCodeHandle,// Label FormId
|
|
mEndOpCodeHandle // LABEL_END
|
|
);
|
|
}
|
|
|
|
/**
|
|
Dispatch the correct update page function to call based on
|
|
the UpdatePageId.
|
|
|
|
@param UpdatePageId The form ID.
|
|
@param CallbackData The BMM context data.
|
|
|
|
**/
|
|
VOID
|
|
UpdatePageBody (
|
|
IN UINT16 UpdatePageId,
|
|
IN BMM_CALLBACK_DATA *CallbackData
|
|
)
|
|
{
|
|
CleanUpPage (UpdatePageId, CallbackData);
|
|
switch (UpdatePageId) {
|
|
case FORM_CON_IN_ID:
|
|
UpdateConsolePage (UpdatePageId, &ConsoleInpMenu, CallbackData);
|
|
break;
|
|
|
|
case FORM_CON_OUT_ID:
|
|
UpdateConsolePage (UpdatePageId, &ConsoleOutMenu, CallbackData);
|
|
break;
|
|
|
|
case FORM_CON_ERR_ID:
|
|
UpdateConsolePage (UpdatePageId, &ConsoleErrMenu, CallbackData);
|
|
break;
|
|
|
|
case FORM_BOOT_CHG_ID:
|
|
UpdateOrderPage (UpdatePageId, &BootOptionMenu, CallbackData);
|
|
break;
|
|
|
|
case FORM_DRV_CHG_ID:
|
|
UpdateOrderPage (UpdatePageId, &DriverOptionMenu, CallbackData);
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
/**
|
|
Dispatch the display to the next page based on NewPageId.
|
|
|
|
@param Private The BMM context data.
|
|
@param NewPageId The original page ID.
|
|
|
|
**/
|
|
VOID
|
|
UpdatePageId (
|
|
BMM_CALLBACK_DATA *Private,
|
|
UINT16 NewPageId
|
|
)
|
|
{
|
|
if ((NewPageId < FILE_OPTION_OFFSET) && (NewPageId >= HANDLE_OPTION_OFFSET)) {
|
|
//
|
|
// If we select a handle to add driver option, advance to the add handle description page.
|
|
//
|
|
NewPageId = FORM_DRV_ADD_HANDLE_DESC_ID;
|
|
} else if ((NewPageId == KEY_VALUE_SAVE_AND_EXIT) || (NewPageId == KEY_VALUE_NO_SAVE_AND_EXIT)) {
|
|
//
|
|
// Return to main page after "Save Changes" or "Discard Changes".
|
|
//
|
|
NewPageId = FORM_MAIN_ID;
|
|
} else if ((NewPageId >= TERMINAL_OPTION_OFFSET) && (NewPageId < CONSOLE_OPTION_OFFSET)) {
|
|
NewPageId = FORM_CON_COM_SETUP_ID;
|
|
}
|
|
|
|
if ((NewPageId > 0) && (NewPageId < MAXIMUM_FORM_ID)) {
|
|
Private->BmmPreviousPageId = Private->BmmCurrentPageId;
|
|
Private->BmmCurrentPageId = NewPageId;
|
|
}
|
|
}
|