/** @file
The functions for Boot Maintainence Main menu.

Copyright (c) 2004 - 2019, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "BootMaintenanceManager.h"

#define FRONT_PAGE_KEY_OFFSET  0x4000
//
// Boot video resolution and text mode.
//
UINT32  mBmmBootHorizontalResolution = 0;
UINT32  mBmmBootVerticalResolution   = 0;
UINT32  mBmmBootTextModeColumn       = 0;
UINT32  mBmmBootTextModeRow          = 0;
//
// BIOS setup video resolution and text mode.
//
UINT32  mBmmSetupTextModeColumn       = 0;
UINT32  mBmmSetupTextModeRow          = 0;
UINT32  mBmmSetupHorizontalResolution = 0;
UINT32  mBmmSetupVerticalResolution   = 0;

BOOLEAN  mBmmModeInitialized = FALSE;

EFI_DEVICE_PATH_PROTOCOL  EndDevicePath[] = {
  {
    END_DEVICE_PATH_TYPE,
    END_ENTIRE_DEVICE_PATH_SUBTYPE,
    {
      END_DEVICE_PATH_LENGTH,
      0
    }
  }
};

HII_VENDOR_DEVICE_PATH  mBmmHiiVendorDevicePath = {
  {
    {
      HARDWARE_DEVICE_PATH,
      HW_VENDOR_DP,
      {
        (UINT8)(sizeof (VENDOR_DEVICE_PATH)),
        (UINT8)((sizeof (VENDOR_DEVICE_PATH)) >> 8)
      }
    },
    //
    // {165A028F-0BB2-4b5f-8747-77592E3F6499}
    //
    { 0x165a028f, 0xbb2, 0x4b5f, { 0x87, 0x47, 0x77, 0x59, 0x2e, 0x3f, 0x64, 0x99 }
    }
  },
  {
    END_DEVICE_PATH_TYPE,
    END_ENTIRE_DEVICE_PATH_SUBTYPE,
    {
      (UINT8)(END_DEVICE_PATH_LENGTH),
      (UINT8)((END_DEVICE_PATH_LENGTH) >> 8)
    }
  }
};

EFI_GUID  mBootMaintGuid = BOOT_MAINT_FORMSET_GUID;

CHAR16             mBootMaintStorageName[] = L"BmmData";
BMM_CALLBACK_DATA  gBootMaintenancePrivate = {
  BMM_CALLBACK_DATA_SIGNATURE,
  NULL,
  NULL,
  {
    BootMaintExtractConfig,
    BootMaintRouteConfig,
    BootMaintCallback
  }
};

BMM_CALLBACK_DATA  *mBmmCallbackInfo  = &gBootMaintenancePrivate;
BOOLEAN            mAllMenuInit       = FALSE;
BOOLEAN            mFirstEnterBMMForm = FALSE;

/**
  Init all memu.

  @param CallbackData    The BMM context data.

**/
VOID
InitAllMenu (
  IN  BMM_CALLBACK_DATA  *CallbackData
  );

/**
  Free up all Menu Option list.

**/
VOID
FreeAllMenu (
  VOID
  );

/**

  Update the menus in the BMM page.

**/
VOID
CustomizeMenus (
  VOID
  );

/**
  This function will change video resolution and text mode
  according to defined setup mode or defined boot mode

  @param  IsSetupMode   Indicate mode is changed to setup mode or boot mode.

  @retval  EFI_SUCCESS  Mode is changed successfully.
  @retval  Others       Mode failed to be changed.

**/
EFI_STATUS
BmmSetConsoleMode (
  BOOLEAN  IsSetupMode
  )
{
  EFI_GRAPHICS_OUTPUT_PROTOCOL          *GraphicsOutput;
  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL       *SimpleTextOut;
  UINTN                                 SizeOfInfo;
  EFI_GRAPHICS_OUTPUT_MODE_INFORMATION  *Info;
  UINT32                                MaxGopMode;
  UINT32                                MaxTextMode;
  UINT32                                ModeNumber;
  UINT32                                NewHorizontalResolution;
  UINT32                                NewVerticalResolution;
  UINT32                                NewColumns;
  UINT32                                NewRows;
  UINTN                                 HandleCount;
  EFI_HANDLE                            *HandleBuffer;
  EFI_STATUS                            Status;
  UINTN                                 Index;
  UINTN                                 CurrentColumn;
  UINTN                                 CurrentRow;

  MaxGopMode  = 0;
  MaxTextMode = 0;

  //
  // Get current video resolution and text mode
  //
  Status = gBS->HandleProtocol (
                  gST->ConsoleOutHandle,
                  &gEfiGraphicsOutputProtocolGuid,
                  (VOID **)&GraphicsOutput
                  );
  if (EFI_ERROR (Status)) {
    GraphicsOutput = NULL;
  }

  Status = gBS->HandleProtocol (
                  gST->ConsoleOutHandle,
                  &gEfiSimpleTextOutProtocolGuid,
                  (VOID **)&SimpleTextOut
                  );
  if (EFI_ERROR (Status)) {
    SimpleTextOut = NULL;
  }

  if ((GraphicsOutput == NULL) || (SimpleTextOut == NULL)) {
    return EFI_UNSUPPORTED;
  }

  if (IsSetupMode) {
    //
    // The required resolution and text mode is setup mode.
    //
    NewHorizontalResolution = mBmmSetupHorizontalResolution;
    NewVerticalResolution   = mBmmSetupVerticalResolution;
    NewColumns              = mBmmSetupTextModeColumn;
    NewRows                 = mBmmSetupTextModeRow;
  } else {
    //
    // The required resolution and text mode is boot mode.
    //
    NewHorizontalResolution = mBmmBootHorizontalResolution;
    NewVerticalResolution   = mBmmBootVerticalResolution;
    NewColumns              = mBmmBootTextModeColumn;
    NewRows                 = mBmmBootTextModeRow;
  }

  if (GraphicsOutput != NULL) {
    MaxGopMode = GraphicsOutput->Mode->MaxMode;
  }

  if (SimpleTextOut != NULL) {
    MaxTextMode = SimpleTextOut->Mode->MaxMode;
  }

  //
  // 1. If current video resolution is same with required video resolution,
  //    video resolution need not be changed.
  //    1.1. If current text mode is same with required text mode, text mode need not be changed.
  //    1.2. If current text mode is different from required text mode, text mode need be changed.
  // 2. If current video resolution is different from required video resolution, we need restart whole console drivers.
  //
  for (ModeNumber = 0; ModeNumber < MaxGopMode; ModeNumber++) {
    Status = GraphicsOutput->QueryMode (
                               GraphicsOutput,
                               ModeNumber,
                               &SizeOfInfo,
                               &Info
                               );
    if (!EFI_ERROR (Status)) {
      if ((Info->HorizontalResolution == NewHorizontalResolution) &&
          (Info->VerticalResolution == NewVerticalResolution))
      {
        if ((GraphicsOutput->Mode->Info->HorizontalResolution == NewHorizontalResolution) &&
            (GraphicsOutput->Mode->Info->VerticalResolution == NewVerticalResolution))
        {
          //
          // Current resolution is same with required resolution, check if text mode need be set
          //
          Status = SimpleTextOut->QueryMode (SimpleTextOut, SimpleTextOut->Mode->Mode, &CurrentColumn, &CurrentRow);
          ASSERT_EFI_ERROR (Status);
          if ((CurrentColumn == NewColumns) && (CurrentRow == NewRows)) {
            //
            // If current text mode is same with required text mode. Do nothing
            //
            FreePool (Info);
            return EFI_SUCCESS;
          } else {
            //
            // If current text mode is different from required text mode.  Set new video mode
            //
            for (Index = 0; Index < MaxTextMode; Index++) {
              Status = SimpleTextOut->QueryMode (SimpleTextOut, Index, &CurrentColumn, &CurrentRow);
              if (!EFI_ERROR (Status)) {
                if ((CurrentColumn == NewColumns) && (CurrentRow == NewRows)) {
                  //
                  // Required text mode is supported, set it.
                  //
                  Status = SimpleTextOut->SetMode (SimpleTextOut, Index);
                  ASSERT_EFI_ERROR (Status);
                  //
                  // Update text mode PCD.
                  //
                  Status = PcdSet32S (PcdConOutColumn, mBmmSetupTextModeColumn);
                  ASSERT_EFI_ERROR (Status);
                  Status = PcdSet32S (PcdConOutRow, mBmmSetupTextModeRow);
                  ASSERT_EFI_ERROR (Status);
                  FreePool (Info);
                  return EFI_SUCCESS;
                }
              }
            }

            if (Index == MaxTextMode) {
              //
              // If required text mode is not supported, return error.
              //
              FreePool (Info);
              return EFI_UNSUPPORTED;
            }
          }
        } else {
          //
          // If current video resolution is not same with the new one, set new video resolution.
          // In this case, the driver which produces simple text out need be restarted.
          //
          Status = GraphicsOutput->SetMode (GraphicsOutput, ModeNumber);
          if (!EFI_ERROR (Status)) {
            FreePool (Info);
            break;
          }
        }
      }

      FreePool (Info);
    }
  }

  if (ModeNumber == MaxGopMode) {
    //
    // If the resolution is not supported, return error.
    //
    return EFI_UNSUPPORTED;
  }

  //
  // Set PCD to Inform GraphicsConsole to change video resolution.
  // Set PCD to Inform Consplitter to change text mode.
  //
  Status = PcdSet32S (PcdVideoHorizontalResolution, NewHorizontalResolution);
  ASSERT_EFI_ERROR (Status);
  Status = PcdSet32S (PcdVideoVerticalResolution, NewVerticalResolution);
  ASSERT_EFI_ERROR (Status);
  Status = PcdSet32S (PcdConOutColumn, NewColumns);
  ASSERT_EFI_ERROR (Status);
  Status = PcdSet32S (PcdConOutRow, NewRows);
  ASSERT_EFI_ERROR (Status);

  //
  // Video mode is changed, so restart graphics console driver and higher level driver.
  // Reconnect graphics console driver and higher level driver.
  // Locate all the handles with GOP protocol and reconnect it.
  //
  Status = gBS->LocateHandleBuffer (
                  ByProtocol,
                  &gEfiSimpleTextOutProtocolGuid,
                  NULL,
                  &HandleCount,
                  &HandleBuffer
                  );
  if (!EFI_ERROR (Status)) {
    for (Index = 0; Index < HandleCount; Index++) {
      gBS->DisconnectController (HandleBuffer[Index], NULL, NULL);
    }

    for (Index = 0; Index < HandleCount; Index++) {
      gBS->ConnectController (HandleBuffer[Index], NULL, NULL, TRUE);
    }

    if (HandleBuffer != NULL) {
      FreePool (HandleBuffer);
    }
  }

  return EFI_SUCCESS;
}

/**
  This function converts an input device structure to a Unicode string.

  @param DevPath      A pointer to the device path structure.

  @return             A new allocated Unicode string that represents the device path.

**/
CHAR16 *
UiDevicePathToStr (
  IN EFI_DEVICE_PATH_PROTOCOL  *DevPath
  )
{
  EFI_STATUS                        Status;
  CHAR16                            *ToText;
  EFI_DEVICE_PATH_TO_TEXT_PROTOCOL  *DevPathToText;

  if (DevPath == NULL) {
    return NULL;
  }

  Status = gBS->LocateProtocol (
                  &gEfiDevicePathToTextProtocolGuid,
                  NULL,
                  (VOID **)&DevPathToText
                  );
  ASSERT_EFI_ERROR (Status);
  ToText = DevPathToText->ConvertDevicePathToText (
                            DevPath,
                            FALSE,
                            TRUE
                            );
  ASSERT (ToText != NULL);
  return ToText;
}

/**
  Extract filename from device path. The returned buffer is allocated using AllocateCopyPool.
  The caller is responsible for freeing the allocated buffer using FreePool().

  @param DevicePath       Device path.

  @return                 A new allocated string that represents the file name.

**/
CHAR16 *
ExtractFileNameFromDevicePath (
  IN   EFI_DEVICE_PATH_PROTOCOL  *DevicePath
  )
{
  CHAR16  *String;
  CHAR16  *MatchString;
  CHAR16  *LastMatch;
  CHAR16  *FileName;
  UINTN   Length;

  ASSERT (DevicePath != NULL);

  String      = UiDevicePathToStr (DevicePath);
  MatchString = String;
  LastMatch   = String;
  FileName    = NULL;

  while (MatchString != NULL) {
    LastMatch   = MatchString + 1;
    MatchString = StrStr (LastMatch, L"\\");
  }

  Length   = StrLen (LastMatch);
  FileName = AllocateCopyPool ((Length + 1) * sizeof (CHAR16), LastMatch);
  if (FileName != NULL) {
    *(FileName + Length) = 0;
  }

  FreePool (String);

  return FileName;
}

/**
  Extract device path for given HII handle and class guid.

  @param Handle          The HII handle.

  @retval  NULL          Fail to get the device path string.
  @return  PathString    Get the device path string.

**/
CHAR16 *
BmmExtractDevicePathFromHiiHandle (
  IN      EFI_HII_HANDLE  Handle
  )
{
  EFI_STATUS  Status;
  EFI_HANDLE  DriverHandle;

  ASSERT (Handle != NULL);

  if (Handle == NULL) {
    return NULL;
  }

  Status = gHiiDatabase->GetPackageListHandle (gHiiDatabase, Handle, &DriverHandle);
  if (EFI_ERROR (Status)) {
    return NULL;
  }

  //
  // Get device path string.
  //
  return ConvertDevicePathToText (DevicePathFromHandle (DriverHandle), FALSE, FALSE);
}

/**
  Converts the unicode character of the string from uppercase to lowercase.
  This is a internal function.

  @param ConfigString  String to be converted

**/
VOID
HiiToLower (
  IN EFI_STRING  ConfigString
  )
{
  EFI_STRING  String;
  BOOLEAN     Lower;

  ASSERT (ConfigString != NULL);

  //
  // Convert all hex digits in range [A-F] in the configuration header to [a-f]
  //
  for (String = ConfigString, Lower = FALSE; *String != L'\0'; String++) {
    if (*String == L'=') {
      Lower = TRUE;
    } else if (*String == L'&') {
      Lower = FALSE;
    } else if (Lower && (*String >= L'A') && (*String <= L'F')) {
      *String = (CHAR16)(*String - L'A' + L'a');
    }
  }
}

/**
  Update the progress string through the offset value.

  @param Offset           The offset value
  @param Configuration    Point to the configuration string.

**/
EFI_STRING
UpdateProgress (
  IN  UINTN       Offset,
  IN  EFI_STRING  Configuration
  )
{
  UINTN       Length;
  EFI_STRING  StringPtr;
  EFI_STRING  ReturnString;

  StringPtr    = NULL;
  ReturnString = NULL;

  //
  // &OFFSET=XXXX followed by a Null-terminator.
  // Length = StrLen (L"&OFFSET=") + 4 + 1
  //
  Length = StrLen (L"&OFFSET=") + 4 + 1;

  StringPtr = AllocateZeroPool (Length * sizeof (CHAR16));

  if (StringPtr == NULL) {
    return NULL;
  }

  UnicodeSPrint (
    StringPtr,
    (8 + 4 + 1) * sizeof (CHAR16),
    L"&OFFSET=%04x",
    Offset
    );

  ReturnString = StrStr (Configuration, StringPtr);

  if (ReturnString == NULL) {
    //
    // If doesn't find the string in Configuration, convert the string to lower case then search again.
    //
    HiiToLower (StringPtr);
    ReturnString = StrStr (Configuration, StringPtr);
  }

  FreePool (StringPtr);

  return ReturnString;
}

/**
  Update the terminal content in TerminalMenu.

  @param BmmData           The BMM fake NV data.

**/
VOID
UpdateTerminalContent (
  IN BMM_FAKE_NV_DATA  *BmmData
  )
{
  UINT16               Index;
  BM_TERMINAL_CONTEXT  *NewTerminalContext;
  BM_MENU_ENTRY        *NewMenuEntry;

  for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {
    NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);
    ASSERT (NewMenuEntry != NULL);
    NewTerminalContext                = (BM_TERMINAL_CONTEXT *)NewMenuEntry->VariableContext;
    NewTerminalContext->BaudRateIndex = BmmData->COMBaudRate[Index];
    ASSERT (BmmData->COMBaudRate[Index] < (ARRAY_SIZE (BaudRateList)));
    NewTerminalContext->BaudRate      = BaudRateList[BmmData->COMBaudRate[Index]].Value;
    NewTerminalContext->DataBitsIndex = BmmData->COMDataRate[Index];
    ASSERT (BmmData->COMDataRate[Index] < (ARRAY_SIZE (DataBitsList)));
    NewTerminalContext->DataBits      = (UINT8)DataBitsList[BmmData->COMDataRate[Index]].Value;
    NewTerminalContext->StopBitsIndex = BmmData->COMStopBits[Index];
    ASSERT (BmmData->COMStopBits[Index] < (ARRAY_SIZE (StopBitsList)));
    NewTerminalContext->StopBits    = (UINT8)StopBitsList[BmmData->COMStopBits[Index]].Value;
    NewTerminalContext->ParityIndex = BmmData->COMParity[Index];
    ASSERT (BmmData->COMParity[Index] < (ARRAY_SIZE (ParityList)));
    NewTerminalContext->Parity       = (UINT8)ParityList[BmmData->COMParity[Index]].Value;
    NewTerminalContext->TerminalType = BmmData->COMTerminalType[Index];
    NewTerminalContext->FlowControl  = BmmData->COMFlowControl[Index];
    ChangeTerminalDevicePath (
      NewTerminalContext->DevicePath,
      FALSE
      );
  }
}

/**
  Update the console content in ConsoleMenu.

  @param ConsoleName       The name for the console device type.
  @param BmmData           The BMM fake NV data.

**/
VOID
UpdateConsoleContent (
  IN CHAR16            *ConsoleName,
  IN BMM_FAKE_NV_DATA  *BmmData
  )
{
  UINT16               Index;
  BM_CONSOLE_CONTEXT   *NewConsoleContext;
  BM_TERMINAL_CONTEXT  *NewTerminalContext;
  BM_MENU_ENTRY        *NewMenuEntry;

  if (StrCmp (ConsoleName, L"ConIn") == 0) {
    for (Index = 0; Index < ConsoleInpMenu.MenuNumber; Index++) {
      NewMenuEntry      = BOpt_GetMenuEntry (&ConsoleInpMenu, Index);
      NewConsoleContext = (BM_CONSOLE_CONTEXT *)NewMenuEntry->VariableContext;
      ASSERT (Index < MAX_MENU_NUMBER);
      NewConsoleContext->IsActive = BmmData->ConsoleInCheck[Index];
    }

    for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {
      NewMenuEntry       = BOpt_GetMenuEntry (&TerminalMenu, Index);
      NewTerminalContext = (BM_TERMINAL_CONTEXT *)NewMenuEntry->VariableContext;
      ASSERT (Index + ConsoleInpMenu.MenuNumber < MAX_MENU_NUMBER);
      NewTerminalContext->IsConIn = BmmData->ConsoleInCheck[Index + ConsoleInpMenu.MenuNumber];
    }
  }

  if (StrCmp (ConsoleName, L"ConOut") == 0) {
    for (Index = 0; Index < ConsoleOutMenu.MenuNumber; Index++) {
      NewMenuEntry      = BOpt_GetMenuEntry (&ConsoleOutMenu, Index);
      NewConsoleContext = (BM_CONSOLE_CONTEXT *)NewMenuEntry->VariableContext;
      ASSERT (Index < MAX_MENU_NUMBER);
      NewConsoleContext->IsActive = BmmData->ConsoleOutCheck[Index];
    }

    for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {
      NewMenuEntry       = BOpt_GetMenuEntry (&TerminalMenu, Index);
      NewTerminalContext = (BM_TERMINAL_CONTEXT *)NewMenuEntry->VariableContext;
      ASSERT (Index + ConsoleOutMenu.MenuNumber < MAX_MENU_NUMBER);
      NewTerminalContext->IsConOut = BmmData->ConsoleOutCheck[Index + ConsoleOutMenu.MenuNumber];
    }
  }

  if (StrCmp (ConsoleName, L"ErrOut") == 0) {
    for (Index = 0; Index < ConsoleErrMenu.MenuNumber; Index++) {
      NewMenuEntry      = BOpt_GetMenuEntry (&ConsoleErrMenu, Index);
      NewConsoleContext = (BM_CONSOLE_CONTEXT *)NewMenuEntry->VariableContext;
      ASSERT (Index < MAX_MENU_NUMBER);
      NewConsoleContext->IsActive = BmmData->ConsoleErrCheck[Index];
    }

    for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {
      NewMenuEntry       = BOpt_GetMenuEntry (&TerminalMenu, Index);
      NewTerminalContext = (BM_TERMINAL_CONTEXT *)NewMenuEntry->VariableContext;
      ASSERT (Index + ConsoleErrMenu.MenuNumber < MAX_MENU_NUMBER);
      NewTerminalContext->IsStdErr = BmmData->ConsoleErrCheck[Index + ConsoleErrMenu.MenuNumber];
    }
  }
}

/**
  This function allows a caller to extract the current configuration for one
  or more named elements from the target driver.

  @param This            Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
  @param Request         A null-terminated Unicode string in <ConfigRequest> format.
  @param Progress        On return, points to a character in the Request string.
                         Points to the string's null terminator if request was successful.
                         Points to the most recent '&' before the first failing name/value
                         pair (or the beginning of the string if the failure is in the
                         first name/value pair) if the request was not successful.
  @param Results         A null-terminated Unicode string in <ConfigAltResp> format which
                         has all values filled in for the names in the Request string.
                         String to be allocated by the called function.

  @retval  EFI_SUCCESS            The Results is filled with the requested values.
  @retval  EFI_OUT_OF_RESOURCES   Not enough memory to store the results.
  @retval  EFI_INVALID_PARAMETER  Request is NULL, illegal syntax, or unknown name.
  @retval  EFI_NOT_FOUND          Routing data doesn't match any storage in this driver.

**/
EFI_STATUS
EFIAPI
BootMaintExtractConfig (
  IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL  *This,
  IN  CONST EFI_STRING                      Request,
  OUT EFI_STRING                            *Progress,
  OUT EFI_STRING                            *Results
  )
{
  EFI_STATUS         Status;
  UINTN              BufferSize;
  BMM_CALLBACK_DATA  *Private;
  EFI_STRING         ConfigRequestHdr;
  EFI_STRING         ConfigRequest;
  BOOLEAN            AllocatedRequest;
  UINTN              Size;

  if ((Progress == NULL) || (Results == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  *Progress = Request;
  if ((Request != NULL) && !HiiIsConfigHdrMatch (Request, &mBootMaintGuid, mBootMaintStorageName)) {
    return EFI_NOT_FOUND;
  }

  ConfigRequestHdr = NULL;
  ConfigRequest    = NULL;
  AllocatedRequest = FALSE;
  Size             = 0;

  Private = BMM_CALLBACK_DATA_FROM_THIS (This);
  //
  // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
  //
  BufferSize    = sizeof (BMM_FAKE_NV_DATA);
  ConfigRequest = Request;
  if ((Request == NULL) || (StrStr (Request, L"OFFSET") == NULL)) {
    //
    // Request has no request element, construct full request string.
    // Allocate and fill a buffer large enough to hold the <ConfigHdr> template
    // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator
    //
    ConfigRequestHdr = HiiConstructConfigHdr (&mBootMaintGuid, mBootMaintStorageName, Private->BmmDriverHandle);
    Size             = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);
    ConfigRequest    = AllocateZeroPool (Size);
    ASSERT (ConfigRequest != NULL);
    AllocatedRequest = TRUE;
    UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, (UINT64)BufferSize);
    FreePool (ConfigRequestHdr);
  }

  Status = gHiiConfigRouting->BlockToConfig (
                                gHiiConfigRouting,
                                ConfigRequest,
                                (UINT8 *)&Private->BmmFakeNvData,
                                BufferSize,
                                Results,
                                Progress
                                );
  //
  // Free the allocated config request string.
  //
  if (AllocatedRequest) {
    FreePool (ConfigRequest);
    ConfigRequest = NULL;
  }

  //
  // Set Progress string to the original request string.
  //
  if (Request == NULL) {
    *Progress = NULL;
  } else if (StrStr (Request, L"OFFSET") == NULL) {
    *Progress = Request + StrLen (Request);
  }

  return Status;
}

/**
  This function applies changes in a driver's configuration.
  Input is a Configuration, which has the routing data for this
  driver followed by name / value configuration pairs. The driver
  must apply those pairs to its configurable storage. If the
  driver's configuration is stored in a linear block of data
  and the driver's name / value pairs are in <BlockConfig>
  format, it may use the ConfigToBlock helper function (above) to
  simplify the job. Currently not implemented.

  @param[in]  This                Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
  @param[in]  Configuration       A null-terminated Unicode string in
                                  <ConfigString> format.
  @param[out] Progress            A pointer to a string filled in with the
                                  offset of the most recent '&' before the
                                  first failing name / value pair (or the
                                  beginn ing of the string if the failure
                                  is in the first name / value pair) or
                                  the terminating NULL if all was
                                  successful.

  @retval EFI_SUCCESS             The results have been distributed or are
                                  awaiting distribution.
  @retval EFI_OUT_OF_RESOURCES    Not enough memory to store the
                                  parts of the results that must be
                                  stored awaiting possible future
                                  protocols.
  @retval EFI_INVALID_PARAMETERS  Passing in a NULL for the
                                  Results parameter would result
                                  in this type of error.
  @retval EFI_NOT_FOUND           Target for the specified routing data
                                  was not found.
**/
EFI_STATUS
EFIAPI
BootMaintRouteConfig (
  IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL  *This,
  IN CONST EFI_STRING                      Configuration,
  OUT EFI_STRING                           *Progress
  )
{
  EFI_STATUS                       Status;
  UINTN                            BufferSize;
  EFI_HII_CONFIG_ROUTING_PROTOCOL  *ConfigRouting;
  BMM_FAKE_NV_DATA                 *NewBmmData;
  BMM_FAKE_NV_DATA                 *OldBmmData;
  BM_MENU_ENTRY                    *NewMenuEntry;
  BM_LOAD_CONTEXT                  *NewLoadContext;
  UINT16                           Index;
  BOOLEAN                          TerminalAttChange;
  BMM_CALLBACK_DATA                *Private;
  UINTN                            Offset;

  if (Progress == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  *Progress = Configuration;

  if (Configuration == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Check routing data in <ConfigHdr>.
  // Note: there is no name for Name/Value storage, only GUID will be checked
  //
  if (!HiiIsConfigHdrMatch (Configuration, &mBootMaintGuid, mBootMaintStorageName)) {
    return EFI_NOT_FOUND;
  }

  Status = gBS->LocateProtocol (
                  &gEfiHiiConfigRoutingProtocolGuid,
                  NULL,
                  (VOID **)&ConfigRouting
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  Private = BMM_CALLBACK_DATA_FROM_THIS (This);
  //
  // Get Buffer Storage data from EFI variable
  //
  BufferSize = sizeof (BMM_FAKE_NV_DATA);
  OldBmmData = &Private->BmmOldFakeNVData;
  NewBmmData = &Private->BmmFakeNvData;
  Offset     = 0;
  //
  // Convert <ConfigResp> to buffer data by helper function ConfigToBlock()
  //
  Status = ConfigRouting->ConfigToBlock (
                            ConfigRouting,
                            Configuration,
                            (UINT8 *)NewBmmData,
                            &BufferSize,
                            Progress
                            );
  ASSERT_EFI_ERROR (Status);
  //
  // Compare new and old BMM configuration data and only do action for modified item to
  // avoid setting unnecessary non-volatile variable
  //

  //
  // Check data which located in BMM main page and save the settings if need
  //
  if (CompareMem (&NewBmmData->BootNext, &OldBmmData->BootNext, sizeof (NewBmmData->BootNext)) != 0) {
    Status = Var_UpdateBootNext (Private);
    if (EFI_ERROR (Status)) {
      Offset = OFFSET_OF (BMM_FAKE_NV_DATA, BootNext);
      goto Exit;
    }
  }

  //
  // Check data which located in Boot Options Menu and save the settings if need
  //
  if (CompareMem (NewBmmData->BootOptionDel, OldBmmData->BootOptionDel, sizeof (NewBmmData->BootOptionDel)) != 0) {
    for (Index = 0;
         ((Index < BootOptionMenu.MenuNumber) && (Index < (sizeof (NewBmmData->BootOptionDel) / sizeof (NewBmmData->BootOptionDel[0]))));
         Index++)
    {
      NewMenuEntry                         = BOpt_GetMenuEntry (&BootOptionMenu, Index);
      NewLoadContext                       = (BM_LOAD_CONTEXT *)NewMenuEntry->VariableContext;
      NewLoadContext->Deleted              = NewBmmData->BootOptionDel[Index];
      NewBmmData->BootOptionDel[Index]     = FALSE;
      NewBmmData->BootOptionDelMark[Index] = FALSE;
    }

    Status = Var_DelBootOption ();
    if (EFI_ERROR (Status)) {
      Offset = OFFSET_OF (BMM_FAKE_NV_DATA, BootOptionDel);
      goto Exit;
    }
  }

  if (CompareMem (NewBmmData->BootOptionOrder, OldBmmData->BootOptionOrder, sizeof (NewBmmData->BootOptionOrder)) != 0) {
    Status = Var_UpdateBootOrder (Private);
    if (EFI_ERROR (Status)) {
      Offset = OFFSET_OF (BMM_FAKE_NV_DATA, BootOptionOrder);
      goto Exit;
    }
  }

  if (CompareMem (&NewBmmData->BootTimeOut, &OldBmmData->BootTimeOut, sizeof (NewBmmData->BootTimeOut)) != 0) {
    Status = gRT->SetVariable (
                    L"Timeout",
                    &gEfiGlobalVariableGuid,
                    EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
                    sizeof (UINT16),
                    &(NewBmmData->BootTimeOut)
                    );
    if (EFI_ERROR (Status)) {
      Offset = OFFSET_OF (BMM_FAKE_NV_DATA, BootTimeOut);
      goto Exit;
    }

    Private->BmmOldFakeNVData.BootTimeOut = NewBmmData->BootTimeOut;
  }

  //
  // Check data which located in Driver Options Menu and save the settings if need
  //
  if (CompareMem (NewBmmData->DriverOptionDel, OldBmmData->DriverOptionDel, sizeof (NewBmmData->DriverOptionDel)) != 0) {
    for (Index = 0;
         ((Index < DriverOptionMenu.MenuNumber) && (Index < (sizeof (NewBmmData->DriverOptionDel) / sizeof (NewBmmData->DriverOptionDel[0]))));
         Index++)
    {
      NewMenuEntry                           = BOpt_GetMenuEntry (&DriverOptionMenu, Index);
      NewLoadContext                         = (BM_LOAD_CONTEXT *)NewMenuEntry->VariableContext;
      NewLoadContext->Deleted                = NewBmmData->DriverOptionDel[Index];
      NewBmmData->DriverOptionDel[Index]     = FALSE;
      NewBmmData->DriverOptionDelMark[Index] = FALSE;
    }

    Status = Var_DelDriverOption ();
    if (EFI_ERROR (Status)) {
      Offset = OFFSET_OF (BMM_FAKE_NV_DATA, DriverOptionDel);
      goto Exit;
    }
  }

  if (CompareMem (NewBmmData->DriverOptionOrder, OldBmmData->DriverOptionOrder, sizeof (NewBmmData->DriverOptionOrder)) != 0) {
    Status = Var_UpdateDriverOrder (Private);
    if (EFI_ERROR (Status)) {
      Offset = OFFSET_OF (BMM_FAKE_NV_DATA, DriverOptionOrder);
      goto Exit;
    }
  }

  if (CompareMem (&NewBmmData->ConsoleOutMode, &OldBmmData->ConsoleOutMode, sizeof (NewBmmData->ConsoleOutMode)) != 0) {
    Status = Var_UpdateConMode (Private);
    if (EFI_ERROR (Status)) {
      Offset = OFFSET_OF (BMM_FAKE_NV_DATA, ConsoleOutMode);
      goto Exit;
    }
  }

  TerminalAttChange = FALSE;
  for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {
    //
    // only need update modified items
    //
    if ((CompareMem (&NewBmmData->COMBaudRate[Index], &OldBmmData->COMBaudRate[Index], sizeof (NewBmmData->COMBaudRate[Index])) == 0) &&
        (CompareMem (&NewBmmData->COMDataRate[Index], &OldBmmData->COMDataRate[Index], sizeof (NewBmmData->COMDataRate[Index])) == 0) &&
        (CompareMem (&NewBmmData->COMStopBits[Index], &OldBmmData->COMStopBits[Index], sizeof (NewBmmData->COMStopBits[Index])) == 0) &&
        (CompareMem (&NewBmmData->COMParity[Index], &OldBmmData->COMParity[Index], sizeof (NewBmmData->COMParity[Index])) == 0) &&
        (CompareMem (&NewBmmData->COMTerminalType[Index], &OldBmmData->COMTerminalType[Index], sizeof (NewBmmData->COMTerminalType[Index])) == 0) &&
        (CompareMem (&NewBmmData->COMFlowControl[Index], &OldBmmData->COMFlowControl[Index], sizeof (NewBmmData->COMFlowControl[Index])) == 0))
    {
      continue;
    }

    TerminalAttChange = TRUE;
  }

  if (TerminalAttChange) {
    if (CompareMem (&NewBmmData->COMBaudRate[Index], &OldBmmData->COMBaudRate[Index], sizeof (NewBmmData->COMBaudRate[Index])) != 0) {
      Offset = OFFSET_OF (BMM_FAKE_NV_DATA, COMBaudRate);
    } else if (CompareMem (&NewBmmData->COMDataRate[Index], &OldBmmData->COMDataRate[Index], sizeof (NewBmmData->COMDataRate[Index])) != 0) {
      Offset = OFFSET_OF (BMM_FAKE_NV_DATA, COMDataRate);
    } else if (CompareMem (&NewBmmData->COMStopBits[Index], &OldBmmData->COMStopBits[Index], sizeof (NewBmmData->COMStopBits[Index])) != 0) {
      Offset = OFFSET_OF (BMM_FAKE_NV_DATA, COMStopBits);
    } else if (CompareMem (&NewBmmData->COMParity[Index], &OldBmmData->COMParity[Index], sizeof (NewBmmData->COMParity[Index])) != 0) {
      Offset = OFFSET_OF (BMM_FAKE_NV_DATA, COMParity);
    } else if (CompareMem (&NewBmmData->COMTerminalType[Index], &OldBmmData->COMTerminalType[Index], sizeof (NewBmmData->COMTerminalType[Index])) != 0) {
      Offset = OFFSET_OF (BMM_FAKE_NV_DATA, COMTerminalType);
    } else if (CompareMem (&NewBmmData->COMFlowControl[Index], &OldBmmData->COMFlowControl[Index], sizeof (NewBmmData->COMFlowControl[Index])) != 0) {
      Offset = OFFSET_OF (BMM_FAKE_NV_DATA, COMFlowControl);
    }

    Status = Var_UpdateConsoleInpOption ();
    if (EFI_ERROR (Status)) {
      goto Exit;
    }

    Status = Var_UpdateConsoleOutOption ();
    if (EFI_ERROR (Status)) {
      goto Exit;
    }

    Status = Var_UpdateErrorOutOption ();
    if (EFI_ERROR (Status)) {
      goto Exit;
    }
  }

  //
  // Check data which located in Console Options Menu and save the settings if need
  //
  if (CompareMem (NewBmmData->ConsoleInCheck, OldBmmData->ConsoleInCheck, sizeof (NewBmmData->ConsoleInCheck)) != 0) {
    Status = Var_UpdateConsoleInpOption ();
    if (EFI_ERROR (Status)) {
      Offset = OFFSET_OF (BMM_FAKE_NV_DATA, ConsoleInCheck);
      goto Exit;
    }
  }

  if (CompareMem (NewBmmData->ConsoleOutCheck, OldBmmData->ConsoleOutCheck, sizeof (NewBmmData->ConsoleOutCheck)) != 0) {
    Status = Var_UpdateConsoleOutOption ();
    if (EFI_ERROR (Status)) {
      Offset = OFFSET_OF (BMM_FAKE_NV_DATA, ConsoleOutCheck);
      goto Exit;
    }
  }

  if (CompareMem (NewBmmData->ConsoleErrCheck, OldBmmData->ConsoleErrCheck, sizeof (NewBmmData->ConsoleErrCheck)) != 0) {
    Status = Var_UpdateErrorOutOption ();
    if (EFI_ERROR (Status)) {
      Offset = OFFSET_OF (BMM_FAKE_NV_DATA, ConsoleErrCheck);
      goto Exit;
    }
  }

  if ((CompareMem (NewBmmData->BootDescriptionData, OldBmmData->BootDescriptionData, sizeof (NewBmmData->BootDescriptionData)) != 0) ||
      (CompareMem (NewBmmData->BootOptionalData, OldBmmData->BootOptionalData, sizeof (NewBmmData->BootOptionalData)) != 0))
  {
    Status                        = Var_UpdateBootOption (Private);
    NewBmmData->BootOptionChanged = FALSE;
    if (EFI_ERROR (Status)) {
      if (CompareMem (NewBmmData->BootDescriptionData, OldBmmData->BootDescriptionData, sizeof (NewBmmData->BootDescriptionData)) != 0) {
        Offset = OFFSET_OF (BMM_FAKE_NV_DATA, BootDescriptionData);
      } else {
        Offset = OFFSET_OF (BMM_FAKE_NV_DATA, BootOptionalData);
      }

      goto Exit;
    }

    BOpt_GetBootOptions (Private);
  }

  if ((CompareMem (NewBmmData->DriverDescriptionData, OldBmmData->DriverDescriptionData, sizeof (NewBmmData->DriverDescriptionData)) != 0) ||
      (CompareMem (NewBmmData->DriverOptionalData, OldBmmData->DriverOptionalData, sizeof (NewBmmData->DriverOptionalData)) != 0))
  {
    Status = Var_UpdateDriverOption (
               Private,
               Private->BmmHiiHandle,
               NewBmmData->DriverDescriptionData,
               NewBmmData->DriverOptionalData,
               NewBmmData->ForceReconnect
               );
    NewBmmData->DriverOptionChanged = FALSE;
    NewBmmData->ForceReconnect      = TRUE;
    if (EFI_ERROR (Status)) {
      if (CompareMem (NewBmmData->DriverDescriptionData, OldBmmData->DriverDescriptionData, sizeof (NewBmmData->DriverDescriptionData)) != 0) {
        Offset = OFFSET_OF (BMM_FAKE_NV_DATA, DriverDescriptionData);
      } else {
        Offset = OFFSET_OF (BMM_FAKE_NV_DATA, DriverOptionalData);
      }

      goto Exit;
    }

    BOpt_GetDriverOptions (Private);
  }

  //
  // After user do the save action, need to update OldBmmData.
  //
  CopyMem (OldBmmData, NewBmmData, sizeof (BMM_FAKE_NV_DATA));

  return EFI_SUCCESS;

Exit:
  //
  // Fail to save the data, update the progress string.
  //
  *Progress = UpdateProgress (Offset, Configuration);
  if (Status == EFI_OUT_OF_RESOURCES) {
    return Status;
  } else {
    return EFI_NOT_FOUND;
  }
}

/**
  This function processes the results of changes in configuration.


  @param This               Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
  @param Action             Specifies the type of action taken by the browser.
  @param QuestionId         A unique value which is sent to the original exporting driver
                            so that it can identify the type of data to expect.
  @param Type               The type of value for the question.
  @param Value              A pointer to the data being sent to the original exporting driver.
  @param ActionRequest      On return, points to the action requested by the callback function.

  @retval EFI_SUCCESS           The callback successfully handled the action.
  @retval EFI_OUT_OF_RESOURCES  Not enough storage is available to hold the variable and its data.
  @retval EFI_DEVICE_ERROR      The variable could not be saved.
  @retval EFI_UNSUPPORTED       The specified Action is not supported by the callback.
  @retval EFI_INVALID_PARAMETER The parameter of Value or ActionRequest is invalid.
**/
EFI_STATUS
EFIAPI
BootMaintCallback (
  IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL  *This,
  IN        EFI_BROWSER_ACTION              Action,
  IN        EFI_QUESTION_ID                 QuestionId,
  IN        UINT8                           Type,
  IN        EFI_IFR_TYPE_VALUE              *Value,
  OUT       EFI_BROWSER_ACTION_REQUEST      *ActionRequest
  )
{
  BMM_CALLBACK_DATA         *Private;
  BM_MENU_ENTRY             *NewMenuEntry;
  BMM_FAKE_NV_DATA          *CurrentFakeNVMap;
  BMM_FAKE_NV_DATA          *OldFakeNVMap;
  UINTN                     Index;
  EFI_DEVICE_PATH_PROTOCOL  *File;

  if ((Action != EFI_BROWSER_ACTION_CHANGING) && (Action != EFI_BROWSER_ACTION_CHANGED) && (Action != EFI_BROWSER_ACTION_FORM_OPEN)) {
    //
    // Do nothing for other UEFI Action. Only do call back when data is changed or the form is open.
    //
    return EFI_UNSUPPORTED;
  }

  Private = BMM_CALLBACK_DATA_FROM_THIS (This);

  if (Action == EFI_BROWSER_ACTION_FORM_OPEN) {
    if (QuestionId == KEY_VALUE_TRIGGER_FORM_OPEN_ACTION) {
      if (!mFirstEnterBMMForm) {
        //
        // BMMUiLib depends on LegacyUi library to show legacy menus.
        // If we want to show Legacy menus correctly in BMM page,
        // we must do it after the LegacyUi library has already been initialized.
        // Opening the BMM form is the appropriate time that the LegacyUi library has already been initialized.
        // So we do the tasks which are related to legacy menus here.
        // 1. Update the menus (including legacy munu) show in BootMiantenanceManager page.
        // 2. Re-scan the BootOption menus (including the legacy boot option).
        //
        CustomizeMenus ();
        EfiBootManagerRefreshAllBootOption ();
        BOpt_GetBootOptions (Private);
        mFirstEnterBMMForm = TRUE;
      }
    }
  }

  //
  // Retrieve uncommitted data from Form Browser
  //
  CurrentFakeNVMap = &Private->BmmFakeNvData;
  OldFakeNVMap     = &Private->BmmOldFakeNVData;
  HiiGetBrowserData (&mBootMaintGuid, mBootMaintStorageName, sizeof (BMM_FAKE_NV_DATA), (UINT8 *)CurrentFakeNVMap);

  if (Action == EFI_BROWSER_ACTION_CHANGING) {
    if (Value == NULL) {
      return EFI_INVALID_PARAMETER;
    }

    UpdatePageId (Private, QuestionId);

    if (QuestionId < FILE_OPTION_OFFSET) {
      if (QuestionId < CONFIG_OPTION_OFFSET) {
        switch (QuestionId) {
          case FORM_BOOT_ADD_ID:
            // Leave BMM and enter FileExplorer.
            ChooseFile (NULL, L".efi", CreateBootOptionFromFile, &File);
            break;

          case FORM_DRV_ADD_FILE_ID:
            // Leave BMM and enter FileExplorer.
            ChooseFile (NULL, L".efi", CreateDriverOptionFromFile, &File);
            break;

          case FORM_DRV_ADD_HANDLE_ID:
            CleanUpPage (FORM_DRV_ADD_HANDLE_ID, Private);
            UpdateDrvAddHandlePage (Private);
            break;

          case FORM_BOOT_DEL_ID:
            CleanUpPage (FORM_BOOT_DEL_ID, Private);
            UpdateBootDelPage (Private);
            break;

          case FORM_BOOT_CHG_ID:
          case FORM_DRV_CHG_ID:
            UpdatePageBody (QuestionId, Private);
            break;

          case FORM_DRV_DEL_ID:
            CleanUpPage (FORM_DRV_DEL_ID, Private);
            UpdateDrvDelPage (Private);
            break;

          case FORM_CON_IN_ID:
          case FORM_CON_OUT_ID:
          case FORM_CON_ERR_ID:
            UpdatePageBody (QuestionId, Private);
            break;

          case FORM_CON_MODE_ID:
            CleanUpPage (FORM_CON_MODE_ID, Private);
            UpdateConModePage (Private);
            break;

          case FORM_CON_COM_ID:
            CleanUpPage (FORM_CON_COM_ID, Private);
            UpdateConCOMPage (Private);
            break;

          default:
            break;
        }
      } else if ((QuestionId >= TERMINAL_OPTION_OFFSET) && (QuestionId < CONSOLE_OPTION_OFFSET)) {
        Index                    = (UINT16)(QuestionId - TERMINAL_OPTION_OFFSET);
        Private->CurrentTerminal = Index;

        CleanUpPage (FORM_CON_COM_SETUP_ID, Private);
        UpdateTerminalPage (Private);
      } else if (QuestionId >= HANDLE_OPTION_OFFSET) {
        Index = (UINT16)(QuestionId - HANDLE_OPTION_OFFSET);

        NewMenuEntry = BOpt_GetMenuEntry (&DriverMenu, Index);
        ASSERT (NewMenuEntry != NULL);
        Private->HandleContext = (BM_HANDLE_CONTEXT *)NewMenuEntry->VariableContext;

        CleanUpPage (FORM_DRV_ADD_HANDLE_DESC_ID, Private);

        Private->MenuEntry                 = NewMenuEntry;
        Private->LoadContext->FilePathList = Private->HandleContext->DevicePath;

        UpdateDriverAddHandleDescPage (Private);
      }
    }

    if (QuestionId == KEY_VALUE_BOOT_FROM_FILE) {
      // Leave BMM and enter FileExplorer.
      ChooseFile (NULL, L".efi", BootFromFile, &File);
    }
  } else if (Action == EFI_BROWSER_ACTION_CHANGED) {
    if ((Value == NULL) || (ActionRequest == NULL)) {
      return EFI_INVALID_PARAMETER;
    }

    if (QuestionId == KEY_VALUE_SAVE_AND_EXIT_BOOT) {
      CleanUselessBeforeSubmit (Private);
      CurrentFakeNVMap->BootOptionChanged = FALSE;
      *ActionRequest                      = EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT;
    } else if (QuestionId == KEY_VALUE_SAVE_AND_EXIT_DRIVER) {
      CleanUselessBeforeSubmit (Private);
      CurrentFakeNVMap->DriverOptionChanged = FALSE;
      *ActionRequest                        = EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT;
    } else if (QuestionId == KEY_VALUE_NO_SAVE_AND_EXIT_DRIVER) {
      //
      // Discard changes and exit formset
      //
      ZeroMem (CurrentFakeNVMap->DriverOptionalData, sizeof (CurrentFakeNVMap->DriverOptionalData));
      ZeroMem (CurrentFakeNVMap->BootDescriptionData, sizeof (CurrentFakeNVMap->BootDescriptionData));
      ZeroMem (OldFakeNVMap->DriverOptionalData, sizeof (OldFakeNVMap->DriverOptionalData));
      ZeroMem (OldFakeNVMap->DriverDescriptionData, sizeof (OldFakeNVMap->DriverDescriptionData));
      CurrentFakeNVMap->DriverOptionChanged = FALSE;
      CurrentFakeNVMap->ForceReconnect      = TRUE;
      *ActionRequest                        = EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT;
    } else if (QuestionId == KEY_VALUE_NO_SAVE_AND_EXIT_BOOT) {
      //
      // Discard changes and exit formset
      //
      ZeroMem (CurrentFakeNVMap->BootOptionalData, sizeof (CurrentFakeNVMap->BootOptionalData));
      ZeroMem (CurrentFakeNVMap->BootDescriptionData, sizeof (CurrentFakeNVMap->BootDescriptionData));
      ZeroMem (OldFakeNVMap->BootOptionalData, sizeof (OldFakeNVMap->BootOptionalData));
      ZeroMem (OldFakeNVMap->BootDescriptionData, sizeof (OldFakeNVMap->BootDescriptionData));
      CurrentFakeNVMap->BootOptionChanged = FALSE;
      *ActionRequest                      = EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT;
    } else if ((QuestionId == KEY_VALUE_BOOT_DESCRIPTION) || (QuestionId == KEY_VALUE_BOOT_OPTION)) {
      CurrentFakeNVMap->BootOptionChanged = TRUE;
    } else if ((QuestionId == KEY_VALUE_DRIVER_DESCRIPTION) || (QuestionId == KEY_VALUE_DRIVER_OPTION)) {
      CurrentFakeNVMap->DriverOptionChanged = TRUE;
    }

    if ((QuestionId >= BOOT_OPTION_DEL_QUESTION_ID) && (QuestionId < BOOT_OPTION_DEL_QUESTION_ID + MAX_MENU_NUMBER)) {
      if (Value->b) {
        //
        // Means user try to delete this boot option but not press F10 or "Commit Changes and Exit" menu.
        //
        CurrentFakeNVMap->BootOptionDelMark[QuestionId - BOOT_OPTION_DEL_QUESTION_ID] = TRUE;
      } else {
        //
        // Means user remove the old check status.
        //
        CurrentFakeNVMap->BootOptionDelMark[QuestionId - BOOT_OPTION_DEL_QUESTION_ID] = FALSE;
      }
    } else if ((QuestionId >= DRIVER_OPTION_DEL_QUESTION_ID) && (QuestionId < DRIVER_OPTION_DEL_QUESTION_ID + MAX_MENU_NUMBER)) {
      if (Value->b) {
        CurrentFakeNVMap->DriverOptionDelMark[QuestionId - DRIVER_OPTION_DEL_QUESTION_ID] = TRUE;
      } else {
        CurrentFakeNVMap->DriverOptionDelMark[QuestionId - DRIVER_OPTION_DEL_QUESTION_ID] = FALSE;
      }
    } else {
      switch (QuestionId) {
        case KEY_VALUE_SAVE_AND_EXIT:
        case KEY_VALUE_NO_SAVE_AND_EXIT:
          if (QuestionId == KEY_VALUE_SAVE_AND_EXIT) {
            CleanUselessBeforeSubmit (Private);
            *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT;
          } else if (QuestionId == KEY_VALUE_NO_SAVE_AND_EXIT) {
            DiscardChangeHandler (Private, CurrentFakeNVMap);
            *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT;
          }

          break;

        case FORM_RESET:
          gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL);
          return EFI_UNSUPPORTED;

        default:
          break;
      }
    }

    //
    // Update the content in Terminal menu and Console menu here.
    //
    if ((QuestionId == COM_BAUD_RATE_QUESTION_ID + Private->CurrentTerminal) || (QuestionId == COM_DATA_RATE_QUESTION_ID + Private->CurrentTerminal) ||
        (QuestionId == COM_PARITY_QUESTION_ID + Private->CurrentTerminal) || (QuestionId == COM_STOP_BITS_QUESTION_ID + Private->CurrentTerminal) ||
        (QuestionId == COM_TERMINAL_QUESTION_ID + Private->CurrentTerminal) || (QuestionId == COM_FLOWCONTROL_QUESTION_ID + Private->CurrentTerminal)
        )
    {
      UpdateTerminalContent (CurrentFakeNVMap);
    }

    if ((QuestionId >= CON_IN_DEVICE_QUESTION_ID) && (QuestionId < CON_IN_DEVICE_QUESTION_ID + MAX_MENU_NUMBER)) {
      UpdateConsoleContent (L"ConIn", CurrentFakeNVMap);
    } else if ((QuestionId >= CON_OUT_DEVICE_QUESTION_ID) && (QuestionId < CON_OUT_DEVICE_QUESTION_ID + MAX_MENU_NUMBER)) {
      UpdateConsoleContent (L"ConOut", CurrentFakeNVMap);
    } else if ((QuestionId >= CON_ERR_DEVICE_QUESTION_ID) && (QuestionId < CON_ERR_DEVICE_QUESTION_ID + MAX_MENU_NUMBER)) {
      UpdateConsoleContent (L"ErrOut", CurrentFakeNVMap);
    }
  }

  //
  // Pass changed uncommitted data back to Form Browser
  //
  HiiSetBrowserData (&mBootMaintGuid, mBootMaintStorageName, sizeof (BMM_FAKE_NV_DATA), (UINT8 *)CurrentFakeNVMap, NULL);

  return EFI_SUCCESS;
}

/**
  Discard all changes done to the BMM pages such as Boot Order change,
  Driver order change.

  @param Private            The BMM context data.
  @param CurrentFakeNVMap   The current Fack NV Map.

**/
VOID
DiscardChangeHandler (
  IN  BMM_CALLBACK_DATA  *Private,
  IN  BMM_FAKE_NV_DATA   *CurrentFakeNVMap
  )
{
  UINT16  Index;

  switch (Private->BmmPreviousPageId) {
    case FORM_BOOT_CHG_ID:
      CopyMem (CurrentFakeNVMap->BootOptionOrder, Private->BmmOldFakeNVData.BootOptionOrder, sizeof (CurrentFakeNVMap->BootOptionOrder));
      break;

    case FORM_DRV_CHG_ID:
      CopyMem (CurrentFakeNVMap->DriverOptionOrder, Private->BmmOldFakeNVData.DriverOptionOrder, sizeof (CurrentFakeNVMap->DriverOptionOrder));
      break;

    case FORM_BOOT_DEL_ID:
      ASSERT (BootOptionMenu.MenuNumber <= (sizeof (CurrentFakeNVMap->BootOptionDel) / sizeof (CurrentFakeNVMap->BootOptionDel[0])));
      for (Index = 0; Index < BootOptionMenu.MenuNumber; Index++) {
        CurrentFakeNVMap->BootOptionDel[Index] = FALSE;
      }

      break;

    case FORM_DRV_DEL_ID:
      ASSERT (DriverOptionMenu.MenuNumber <= (sizeof (CurrentFakeNVMap->DriverOptionDel) / sizeof (CurrentFakeNVMap->DriverOptionDel[0])));
      for (Index = 0; Index < DriverOptionMenu.MenuNumber; Index++) {
        CurrentFakeNVMap->DriverOptionDel[Index] = FALSE;
      }

      break;

    case FORM_BOOT_NEXT_ID:
      CurrentFakeNVMap->BootNext = Private->BmmOldFakeNVData.BootNext;
      break;

    case FORM_TIME_OUT_ID:
      CurrentFakeNVMap->BootTimeOut = Private->BmmOldFakeNVData.BootTimeOut;
      break;

    case FORM_DRV_ADD_HANDLE_DESC_ID:
    case FORM_DRV_ADD_FILE_ID:
    case FORM_DRV_ADD_HANDLE_ID:
      CurrentFakeNVMap->DriverAddHandleDesc[0]         = 0x0000;
      CurrentFakeNVMap->DriverAddHandleOptionalData[0] = 0x0000;
      break;

    default:
      break;
  }
}

/**
  This function is to clean some useless data before submit changes.

  @param Private            The BMM context data.

**/
VOID
CleanUselessBeforeSubmit (
  IN  BMM_CALLBACK_DATA  *Private
  )
{
  UINT16  Index;

  if (Private->BmmPreviousPageId != FORM_BOOT_DEL_ID) {
    for (Index = 0; Index < BootOptionMenu.MenuNumber; Index++) {
      if (Private->BmmFakeNvData.BootOptionDel[Index] && !Private->BmmFakeNvData.BootOptionDelMark[Index]) {
        Private->BmmFakeNvData.BootOptionDel[Index]    = FALSE;
        Private->BmmOldFakeNVData.BootOptionDel[Index] = FALSE;
      }
    }
  }

  if (Private->BmmPreviousPageId != FORM_DRV_DEL_ID) {
    for (Index = 0; Index < DriverOptionMenu.MenuNumber; Index++) {
      if (Private->BmmFakeNvData.DriverOptionDel[Index] && !Private->BmmFakeNvData.DriverOptionDelMark[Index]) {
        Private->BmmFakeNvData.DriverOptionDel[Index]    = FALSE;
        Private->BmmOldFakeNVData.DriverOptionDel[Index] = FALSE;
      }
    }
  }
}

/**

  Update the menus in the BMM page.

**/
VOID
CustomizeMenus (
  VOID
  )
{
  VOID                *StartOpCodeHandle;
  VOID                *EndOpCodeHandle;
  EFI_IFR_GUID_LABEL  *StartGuidLabel;
  EFI_IFR_GUID_LABEL  *EndGuidLabel;

  //
  // Allocate space for creation of UpdateData Buffer
  //
  StartOpCodeHandle = HiiAllocateOpCodeHandle ();
  ASSERT (StartOpCodeHandle != NULL);

  EndOpCodeHandle = HiiAllocateOpCodeHandle ();
  ASSERT (EndOpCodeHandle != NULL);
  //
  // Create Hii Extend Label OpCode as the start opcode
  //
  StartGuidLabel               = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
  StartGuidLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
  StartGuidLabel->Number       = LABEL_FORM_MAIN_START;
  //
  // Create Hii Extend Label OpCode as the end opcode
  //
  EndGuidLabel               = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (EndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
  EndGuidLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
  EndGuidLabel->Number       = LABEL_FORM_MAIN_END;

  //
  // Updata Front Page form
  //
  UiCustomizeBMMPage (
    mBmmCallbackInfo->BmmHiiHandle,
    StartOpCodeHandle
    );

  HiiUpdateForm (
    mBmmCallbackInfo->BmmHiiHandle,
    &mBootMaintGuid,
    FORM_MAIN_ID,
    StartOpCodeHandle,
    EndOpCodeHandle
    );

  HiiFreeOpCodeHandle (StartOpCodeHandle);
  HiiFreeOpCodeHandle (EndOpCodeHandle);
}

/**
   Create dynamic code for BMM and initialize all of BMM configuration data in BmmFakeNvData and
   BmmOldFakeNVData member in BMM context data.

  @param CallbackData    The BMM context data.

**/
VOID
InitializeBmmConfig (
  IN  BMM_CALLBACK_DATA  *CallbackData
  )
{
  BM_MENU_ENTRY    *NewMenuEntry;
  BM_LOAD_CONTEXT  *NewLoadContext;
  UINT16           Index;

  ASSERT (CallbackData != NULL);

  //
  // Initialize data which located in BMM main page
  //
  CallbackData->BmmFakeNvData.BootNext = NONE_BOOTNEXT_VALUE;
  for (Index = 0; Index < BootOptionMenu.MenuNumber; Index++) {
    NewMenuEntry   = BOpt_GetMenuEntry (&BootOptionMenu, Index);
    NewLoadContext = (BM_LOAD_CONTEXT *)NewMenuEntry->VariableContext;

    if (NewLoadContext->IsBootNext) {
      CallbackData->BmmFakeNvData.BootNext = Index;
      break;
    }
  }

  CallbackData->BmmFakeNvData.BootTimeOut = PcdGet16 (PcdPlatformBootTimeOut);

  //
  // Initialize data which located in Boot Options Menu
  //
  GetBootOrder (CallbackData);

  //
  // Initialize data which located in Driver Options Menu
  //
  GetDriverOrder (CallbackData);

  //
  // Initialize data which located in Console Options Menu
  //
  GetConsoleOutMode (CallbackData);
  GetConsoleInCheck (CallbackData);
  GetConsoleOutCheck (CallbackData);
  GetConsoleErrCheck (CallbackData);
  GetTerminalAttribute (CallbackData);

  CallbackData->BmmFakeNvData.ForceReconnect = TRUE;

  //
  // Backup Initialize BMM configuartion data to BmmOldFakeNVData
  //
  CopyMem (&CallbackData->BmmOldFakeNVData, &CallbackData->BmmFakeNvData, sizeof (BMM_FAKE_NV_DATA));
}

/**
  Initialized all Menu Option List.

  @param CallbackData    The BMM context data.

**/
VOID
InitAllMenu (
  IN  BMM_CALLBACK_DATA  *CallbackData
  )
{
  InitializeListHead (&BootOptionMenu.Head);
  InitializeListHead (&DriverOptionMenu.Head);
  BOpt_GetBootOptions (CallbackData);
  BOpt_GetDriverOptions (CallbackData);
  BOpt_FindDrivers ();
  InitializeListHead (&ConsoleInpMenu.Head);
  InitializeListHead (&ConsoleOutMenu.Head);
  InitializeListHead (&ConsoleErrMenu.Head);
  InitializeListHead (&TerminalMenu.Head);
  LocateSerialIo ();
  GetAllConsoles ();
  mAllMenuInit = TRUE;
}

/**
  Free up all Menu Option list.

**/
VOID
FreeAllMenu (
  VOID
  )
{
  if (!mAllMenuInit) {
    return;
  }

  BOpt_FreeMenu (&BootOptionMenu);
  BOpt_FreeMenu (&DriverOptionMenu);
  BOpt_FreeMenu (&DriverMenu);
  FreeAllConsoles ();
  mAllMenuInit = FALSE;
}

/**
  Initial the boot mode related parameters.

**/
VOID
BmmInitialBootModeInfo (
  VOID
  )
{
  EFI_STATUS                       Status;
  EFI_GRAPHICS_OUTPUT_PROTOCOL     *GraphicsOutput;
  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *SimpleTextOut;
  UINTN                            BootTextColumn;
  UINTN                            BootTextRow;

  if (mBmmModeInitialized) {
    return;
  }

  //
  // After the console is ready, get current video resolution
  // and text mode before launching setup at first time.
  //
  Status = gBS->HandleProtocol (
                  gST->ConsoleOutHandle,
                  &gEfiGraphicsOutputProtocolGuid,
                  (VOID **)&GraphicsOutput
                  );
  if (EFI_ERROR (Status)) {
    GraphicsOutput = NULL;
  }

  Status = gBS->HandleProtocol (
                  gST->ConsoleOutHandle,
                  &gEfiSimpleTextOutProtocolGuid,
                  (VOID **)&SimpleTextOut
                  );
  if (EFI_ERROR (Status)) {
    SimpleTextOut = NULL;
  }

  if (GraphicsOutput != NULL) {
    //
    // Get current video resolution and text mode.
    //
    mBmmBootHorizontalResolution = GraphicsOutput->Mode->Info->HorizontalResolution;
    mBmmBootVerticalResolution   = GraphicsOutput->Mode->Info->VerticalResolution;
  }

  if (SimpleTextOut != NULL) {
    Status = SimpleTextOut->QueryMode (
                              SimpleTextOut,
                              SimpleTextOut->Mode->Mode,
                              &BootTextColumn,
                              &BootTextRow
                              );
    mBmmBootTextModeColumn = (UINT32)BootTextColumn;
    mBmmBootTextModeRow    = (UINT32)BootTextRow;
  }

  //
  // Get user defined text mode for setup.
  //
  mBmmSetupHorizontalResolution = PcdGet32 (PcdSetupVideoHorizontalResolution);
  mBmmSetupVerticalResolution   = PcdGet32 (PcdSetupVideoVerticalResolution);
  mBmmSetupTextModeColumn       = PcdGet32 (PcdSetupConOutColumn);
  mBmmSetupTextModeRow          = PcdGet32 (PcdSetupConOutRow);

  mBmmModeInitialized = TRUE;
}

/**

  Install Boot Maintenance Manager Menu driver.

  @param ImageHandle     The image handle.
  @param SystemTable     The system table.

  @retval  EFI_SUCEESS  Install Boot manager menu success.
  @retval  Other        Return error status.

**/
EFI_STATUS
EFIAPI
BootMaintenanceManagerUiLibConstructor (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )

{
  EFI_STATUS  Status;
  UINT8       *Ptr;

  Status = EFI_SUCCESS;

  //
  // Install Device Path Protocol and Config Access protocol to driver handle
  //
  Status = gBS->InstallMultipleProtocolInterfaces (
                  &mBmmCallbackInfo->BmmDriverHandle,
                  &gEfiDevicePathProtocolGuid,
                  &mBmmHiiVendorDevicePath,
                  &gEfiHiiConfigAccessProtocolGuid,
                  &mBmmCallbackInfo->BmmConfigAccess,
                  NULL
                  );
  ASSERT_EFI_ERROR (Status);

  //
  // Post our Boot Maint VFR binary to the HII database.
  //
  mBmmCallbackInfo->BmmHiiHandle = HiiAddPackages (
                                     &mBootMaintGuid,
                                     mBmmCallbackInfo->BmmDriverHandle,
                                     BootMaintenanceManagerBin,
                                     BootMaintenanceManagerUiLibStrings,
                                     NULL
                                     );
  ASSERT (mBmmCallbackInfo->BmmHiiHandle != NULL);

  //
  // Locate Formbrowser2 protocol
  //
  Status = gBS->LocateProtocol (&gEfiFormBrowser2ProtocolGuid, NULL, (VOID **)&mBmmCallbackInfo->FormBrowser2);
  ASSERT_EFI_ERROR (Status);

  //
  // Create LoadOption in BmmCallbackInfo for Driver Callback
  //
  Ptr = AllocateZeroPool (sizeof (BM_LOAD_CONTEXT) + sizeof (BM_FILE_CONTEXT) + sizeof (BM_HANDLE_CONTEXT) + sizeof (BM_MENU_ENTRY));
  ASSERT (Ptr != NULL);

  //
  // Initialize Bmm callback data.
  //
  mBmmCallbackInfo->LoadContext = (BM_LOAD_CONTEXT *)Ptr;
  Ptr                          += sizeof (BM_LOAD_CONTEXT);

  mBmmCallbackInfo->FileContext = (BM_FILE_CONTEXT *)Ptr;
  Ptr                          += sizeof (BM_FILE_CONTEXT);

  mBmmCallbackInfo->HandleContext = (BM_HANDLE_CONTEXT *)Ptr;
  Ptr                            += sizeof (BM_HANDLE_CONTEXT);

  mBmmCallbackInfo->MenuEntry = (BM_MENU_ENTRY *)Ptr;

  mBmmCallbackInfo->BmmPreviousPageId = FORM_MAIN_ID;
  mBmmCallbackInfo->BmmCurrentPageId  = FORM_MAIN_ID;

  InitAllMenu (mBmmCallbackInfo);

  CreateUpdateData ();
  //
  // Update boot maintenance manager page
  //
  InitializeBmmConfig (mBmmCallbackInfo);

  BmmInitialBootModeInfo ();

  return EFI_SUCCESS;
}

/**
  Unloads the application and its installed protocol.

  @param ImageHandle       Handle that identifies the image to be unloaded.
  @param  SystemTable      The system table.

  @retval EFI_SUCCESS      The image has been unloaded.

**/
EFI_STATUS
EFIAPI
BootMaintenanceManagerUiLibDestructor (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )

{
  if (mStartOpCodeHandle != NULL) {
    HiiFreeOpCodeHandle (mStartOpCodeHandle);
  }

  if (mEndOpCodeHandle != NULL) {
    HiiFreeOpCodeHandle (mEndOpCodeHandle);
  }

  FreeAllMenu ();

  //
  // Remove our IFR data from HII database
  //
  HiiRemovePackages (mBmmCallbackInfo->BmmHiiHandle);

  gBS->UninstallMultipleProtocolInterfaces (
         mBmmCallbackInfo->BmmDriverHandle,
         &gEfiDevicePathProtocolGuid,
         &mBmmHiiVendorDevicePath,
         &gEfiHiiConfigAccessProtocolGuid,
         &mBmmCallbackInfo->BmmConfigAccess,
         NULL
         );

  FreePool (mBmmCallbackInfo->LoadContext);
  mBmmCallbackInfo->BmmDriverHandle = NULL;

  return EFI_SUCCESS;
}
