/** @file
  This file also installs UEFI PLATFORM_DRIVER_OVERRIDE_PROTOCOL.
  
  The main code offers a UI interface in device manager to let user configure
  platform override protocol to override the default algorithm for matching
  drivers to controllers.

  The main flow:
  1. It dynamicly locate all controller device path.
  2. It dynamicly locate all drivers which support binding protocol.
  3. It export and dynamicly update two menu to let user select the
     mapping between drivers to controllers.
  4. It save all the mapping info in NV variables which will be consumed
     by platform override protocol driver to publish the platform override protocol.

Copyright (c) 2007 - 2017, 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 "InternalPlatDriOverrideDxe.h"
#include "PlatOverMngr.h"

#define EFI_CALLBACK_INFO_SIGNATURE SIGNATURE_32 ('C', 'l', 'b', 'k')
#define EFI_CALLBACK_INFO_FROM_THIS(a)  CR (a, EFI_CALLBACK_INFO, ConfigAccess, EFI_CALLBACK_INFO_SIGNATURE)

typedef struct {
  UINTN                           Signature;
  EFI_HANDLE                      DriverHandle;
  EFI_HII_HANDLE                  RegisteredHandle;
  PLAT_OVER_MNGR_DATA             FakeNvData;
  EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
  EFI_HII_CONFIG_ACCESS_PROTOCOL  ConfigAccess;
  EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL PlatformDriverOverride;
} EFI_CALLBACK_INFO;

#pragma pack(1)

///
/// HII specific Vendor Device Path definition.
///
typedef struct {
  VENDOR_DEVICE_PATH             VendorDevicePath;
  EFI_DEVICE_PATH_PROTOCOL       End;
} HII_VENDOR_DEVICE_PATH;

#pragma pack()

//
// uni string and Vfr Binary data.
//
extern UINT8  VfrBin[];
extern UINT8  PlatDriOverrideDxeStrings[];

//
// module global data
//
CHAR16                       mVariableName[] = L"Data";
LIST_ENTRY                   mMappingDataBase = INITIALIZE_LIST_HEAD_VARIABLE (mMappingDataBase);
BOOLEAN                      mEnvironmentVariableRead = FALSE;
EFI_HANDLE                   mCallerImageHandle = NULL;

EFI_HANDLE                   *mDevicePathHandleBuffer;
EFI_HANDLE                   *mDriverImageHandleBuffer;

INTN                         mSelectedCtrIndex;
EFI_STRING_ID                *mControllerToken;
UINTN                        mDriverImageHandleCount;
EFI_STRING_ID                *mDriverImageToken;
EFI_DEVICE_PATH_PROTOCOL     **mControllerDevicePathProtocol;
UINTN                        mSelectedDriverImageNum;
UINTN                        mLastSavedDriverImageNum;
UINT16                       mCurrentPage;
EFI_CALLBACK_INFO           *mCallbackInfo;
BOOLEAN                     *mDriSelection;
UINTN                        mMaxDeviceCount;

HII_VENDOR_DEVICE_PATH  mHiiVendorDevicePath = {
  {
    {
      HARDWARE_DEVICE_PATH,
      HW_VENDOR_DP,
      {
        (UINT8) (sizeof (VENDOR_DEVICE_PATH)),
        (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)
      }
    },
    PLAT_OVER_MNGR_GUID
  },
  {
    END_DEVICE_PATH_TYPE,
    END_ENTIRE_DEVICE_PATH_SUBTYPE,
    { 
      (UINT8) (END_DEVICE_PATH_LENGTH),
      (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)
    }
  }
};

/**
  Converting a given device to an unicode string.

  @param    DevPath     Given device path instance
  
  @return   Converted string from given device path.
  @retval   L"?" Converting failed.
**/
CHAR16 *
DevicePathToStr (
  IN EFI_DEVICE_PATH_PROTOCOL     *DevPath
  )
{
  CHAR16                          *Text;
  Text = ConvertDevicePathToText (
           DevPath,
           FALSE,
           TRUE
           );
  if (Text == NULL) {
    Text = AllocateCopyPool (sizeof (L"?"), L"?");
    ASSERT (Text != NULL);
  }

  return Text;
}

/**
  Worker function to get the driver name by ComponentName or ComponentName2 protocol 
  according to the driver binding handle.

  @param  DriverBindingHandle  The Handle of DriverBinding.
  @param  ProtocolGuid         The pointer to Component Name (2) protocol GUID.
  @param  VariableName         The name of the RFC 4646 or ISO 639-2 language variable.

  @retval !NULL               Pointer into the image name if the image name is found,
  @retval NULL                Pointer to NULL if the image name is not found.

**/
CHAR16 *
GetComponentNameWorker (
  IN EFI_HANDLE                      DriverBindingHandle,
  IN EFI_GUID                        *ProtocolGuid,
  IN CONST CHAR16                    *VariableName
  )
{
  EFI_STATUS                         Status;
  EFI_COMPONENT_NAME_PROTOCOL        *ComponentName;
  CHAR16                             *DriverName;
  CHAR8                              *Language;
  CHAR8                              *BestLanguage;

  Status = gBS->OpenProtocol (
                  DriverBindingHandle,
                  ProtocolGuid,
                  (VOID *) &ComponentName,
                  NULL,
                  NULL,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );
  if (EFI_ERROR (Status)) {
    return NULL;
  }

  //
  // Find the best matching language.
  //
  GetEfiGlobalVariable2 (VariableName, (VOID**)&Language, NULL);
  BestLanguage = GetBestLanguage (
                   ComponentName->SupportedLanguages,
                   (BOOLEAN) (ProtocolGuid == &gEfiComponentNameProtocolGuid),
                   Language,
                   NULL
                   );

  DriverName = NULL;
  if (BestLanguage != NULL) {
    ComponentName->GetDriverName (
                     ComponentName,
                     BestLanguage,
                     &DriverName
                     );
    FreePool (BestLanguage);
  }

  if (Language != NULL) {
    FreePool (Language);
  }

  return DriverName;
}


/**
  Get the driver name by ComponentName or ComponentName2 protocol 
  according to the driver binding handle

  @param DriverBindingHandle  The Handle of DriverBinding.

  @retval !NULL               Pointer into the image name if the image name is found,
  @retval NULL                Pointer to NULL if the image name is not found.

**/
CHAR16 *
GetComponentName (
  IN EFI_HANDLE                      DriverBindingHandle
  )
{
  CHAR16                    *DriverName;

  //
  // Try RFC 4646 Component Name 2 protocol first.
  //
  DriverName = GetComponentNameWorker (DriverBindingHandle, &gEfiComponentName2ProtocolGuid, L"PlatformLang");
  if (DriverName == NULL) {
    //
    // If we can not get driver name from Component Name 2 protocol, we can try ISO 639-2 Component Name protocol. 
    //
    DriverName = GetComponentNameWorker (DriverBindingHandle, &gEfiComponentNameProtocolGuid, L"Lang");
  }

  return DriverName;
}

/**
  Get the image name from EFI UI section.
  Get FV protocol by its loaded image protocol to abstract EFI UI section.

  @param Image            Pointer to the loaded image protocol

  @retval !NULL           Pointer to the image name if the image name is found,
  @retval NULL            NULL if the image name is not found.

**/
CHAR16 *
GetImageName (
  IN EFI_LOADED_IMAGE_PROTOCOL *Image
  )
{
  EFI_STATUS                        Status;
  EFI_DEVICE_PATH_PROTOCOL          *DevPathNode;
  EFI_DEVICE_PATH_PROTOCOL          *AlignedDevPathNode;
  MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *FvFilePath;
  VOID                              *Buffer;
  UINTN                             BufferSize;
  UINT32                            AuthenticationStatus;
  EFI_GUID                          *NameGuid;
  EFI_FIRMWARE_VOLUME2_PROTOCOL     *Fv2;

  Fv2         = NULL;
  Buffer      = NULL;
  BufferSize  = 0;

  if (Image->FilePath == NULL) {
    return NULL;
  }
  DevPathNode  = Image->FilePath;

  while (!IsDevicePathEnd (DevPathNode)) {
    //
    // Make sure device path node is aligned when accessing it's FV Name Guid field.
    //
    AlignedDevPathNode = AllocateCopyPool (DevicePathNodeLength(DevPathNode), DevPathNode);
    
    //
    // Find the Fv File path
    //
    NameGuid = EfiGetNameGuidFromFwVolDevicePathNode ((MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *)AlignedDevPathNode);
    if (NameGuid != NULL) {
      FvFilePath = (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *) AlignedDevPathNode;
      Status = gBS->HandleProtocol (
                    Image->DeviceHandle,
                    &gEfiFirmwareVolume2ProtocolGuid,
                    (VOID **) &Fv2
                    );
      //
      // Locate Image EFI UI section to get the image name.
      //
      if (!EFI_ERROR (Status)) {
        Status = Fv2->ReadSection (
                        Fv2,
                        &FvFilePath->FvFileName,
                        EFI_SECTION_USER_INTERFACE,
                        0,
                        &Buffer,
                        &BufferSize,
                        &AuthenticationStatus
                        );
        if (!EFI_ERROR (Status)) {
          FreePool (AlignedDevPathNode);
          break;
        }
        Buffer = NULL;
      }
    }
    
    FreePool (AlignedDevPathNode);
    
    //
    // Next device path node
    //
    DevPathNode = NextDevicePathNode (DevPathNode);
  }

  return Buffer;
}

/**
  Prepare the first page to let user select the device controller which need to
  add mapping drivers if user select 'Refresh' in first page.
  During first page, user will see all currnet controller device path in system,
  select any device path will go to second page to select its overrides drivers.

  @param  Private        Pointer to EFI_CALLBACK_INFO.
  @param  KeyValue       The callback key value of device controller item in first page.
  @param  FakeNvData     Pointer to PLAT_OVER_MNGR_DATA.

  @retval EFI_SUCCESS    Always returned.

**/
EFI_STATUS
UpdateDeviceSelectPage (
  IN EFI_CALLBACK_INFO                *Private,
  IN UINT16                           KeyValue,
  IN PLAT_OVER_MNGR_DATA              *FakeNvData
  )
{
  EFI_STATUS                                Status;
  UINTN                                     Index;
  UINTN                                     DevicePathHandleCount;
  UINTN                                     NewStrSize;
  CHAR16                                    *NewString;
  EFI_STRING_ID                             NewStringToken;
  CHAR16                                    *ControllerName;
  EFI_DEVICE_PATH_PROTOCOL                  *ControllerDevicePath;
  EFI_PCI_IO_PROTOCOL                       *PciIo;
  EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL *BusSpecificDriverOverride;
  UINTN                                     Len;
  VOID                                      *StartOpCodeHandle;
  VOID                                      *EndOpCodeHandle;
  EFI_IFR_GUID_LABEL                        *StartLabel;
  EFI_IFR_GUID_LABEL                        *EndLabel;  

  //
  // Set current page form ID.
  //
  mCurrentPage = FORM_ID_DEVICE;  
  
  //
  // Initial the mapping database in memory
  //
  FreeMappingDatabase (&mMappingDataBase);
  InitOverridesMapping (&mMappingDataBase);

  //
  // Init OpCode Handle
  //
  StartOpCodeHandle = HiiAllocateOpCodeHandle ();
  ASSERT (StartOpCodeHandle != NULL);

  EndOpCodeHandle = HiiAllocateOpCodeHandle ();
  ASSERT (EndOpCodeHandle != NULL);

  //
  // Create Hii Extend Label OpCode as the start opcode
  //
  StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
  StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
  StartLabel->Number = FORM_ID_DEVICE;

  //
  // Create Hii Extend Label OpCode as the end opcode
  //
  EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (EndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
  EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
  EndLabel->Number       = LABEL_END;

  //
  // Clear first page form
  //
  HiiUpdateForm (
    Private->RegisteredHandle,
    &gPlatformOverridesManagerGuid,
    FORM_ID_DEVICE,
    StartOpCodeHandle, // Label FORM_ID_DEVICE
    EndOpCodeHandle    // LABEL_END
    );

  //
  // When user enter the page at first time, the 'first refresh' string is given to notify user to refresh all the drivers,
  // then the 'first refresh' string will be replaced by the 'refresh' string, and the two strings content are same after the replacement
  //
  NewStringToken = STRING_TOKEN (STR_FIRST_REFRESH);
  NewString = HiiGetString (Private->RegisteredHandle, STRING_TOKEN (STR_REFRESH), NULL);
  ASSERT (NewString != NULL);
  if (HiiSetString (Private->RegisteredHandle, NewStringToken, NewString, NULL) == 0) {
    ASSERT (FALSE);
  }
  FreePool (NewString);

  NewStringToken = STRING_TOKEN (STR_FIRST_REFRESH_HELP);
  NewString = HiiGetString (Private->RegisteredHandle, STRING_TOKEN (STR_REFRESH_HELP), NULL);
  ASSERT (NewString != NULL);
  if (HiiSetString (Private->RegisteredHandle, NewStringToken, NewString, NULL) == 0) {
    ASSERT (FALSE);
  }
  FreePool (NewString);

  //
  // created needed controller device item in first page
  //
  DevicePathHandleCount  = 0;
  Status = gBS->LocateHandleBuffer (
                  ByProtocol,
                  &gEfiDevicePathProtocolGuid,
                  NULL,
                  &DevicePathHandleCount,
                  &mDevicePathHandleBuffer
                  );
  if (EFI_ERROR (Status) || (DevicePathHandleCount == 0)) {
    return EFI_SUCCESS;
  }

  mMaxDeviceCount = DevicePathHandleCount;
  mControllerDevicePathProtocol = AllocateZeroPool (DevicePathHandleCount * sizeof (EFI_DEVICE_PATH_PROTOCOL *));
  ASSERT (mControllerDevicePathProtocol != NULL);
  mControllerToken = AllocateZeroPool (DevicePathHandleCount * sizeof (EFI_STRING_ID));
  ASSERT (mControllerToken != NULL);

  for (Index = 0; Index < DevicePathHandleCount; Index++) {
    if (FakeNvData->PciDeviceFilter == 0x01) {
      //
      // Only care PCI device which contain efi driver in its option rom.
      //

      //
      // Check whether it is a pci device
      //
      ControllerDevicePath = NULL;
      Status = gBS->OpenProtocol (
                      mDevicePathHandleBuffer[Index],
                      &gEfiPciIoProtocolGuid,
                      (VOID **) &PciIo,
                      NULL,
                      NULL,
                      EFI_OPEN_PROTOCOL_GET_PROTOCOL
                      );
      if (EFI_ERROR (Status)) {
        continue;
      }
      //
      // Check whether it contain efi driver in its option rom
      //
      Status = gBS->HandleProtocol(
                       mDevicePathHandleBuffer[Index],
                       &gEfiBusSpecificDriverOverrideProtocolGuid,
                       (VOID **) &BusSpecificDriverOverride
                       );
      if (EFI_ERROR (Status) || BusSpecificDriverOverride == NULL) {
        continue;
      }
    }

    ControllerDevicePath = NULL;
    Status = gBS->OpenProtocol (
                    mDevicePathHandleBuffer[Index],
                    &gEfiDevicePathProtocolGuid,
                    (VOID **) &ControllerDevicePath,
                    NULL,
                    NULL,
                    EFI_OPEN_PROTOCOL_GET_PROTOCOL
                    );
    ASSERT_EFI_ERROR (Status);
    //
    // Save the device path protocol interface
    //
    mControllerDevicePathProtocol[Index] = ControllerDevicePath;

    //
    // Get the driver name
    //
    ControllerName = DevicePathToStr (ControllerDevicePath);

    //
    // Export the driver name string and create item in set options page
    //
    Len = StrSize (ControllerName);
    NewStrSize = Len + StrSize (L"--");
    NewString = AllocateZeroPool (NewStrSize);
    ASSERT (NewString != NULL);
    if (EFI_ERROR (CheckMapping (ControllerDevicePath,NULL, &mMappingDataBase, NULL, NULL))) {
      StrCatS (NewString, NewStrSize/sizeof(CHAR16), L"--");
    } else {
      StrCatS (NewString, NewStrSize/sizeof(CHAR16), L"**");
    }
    StrCatS (NewString, NewStrSize/sizeof(CHAR16), ControllerName);

    NewStringToken = HiiSetString (Private->RegisteredHandle, mControllerToken[Index], NewString, NULL);
    ASSERT (NewStringToken != 0);
    FreePool (NewString);
    //
    // Save the device path string toke for next access use
    //
    mControllerToken[Index] = NewStringToken;
      
    HiiCreateGotoOpCode (
      StartOpCodeHandle,
      FORM_ID_DRIVER,
      NewStringToken,
      STRING_TOKEN (STR_GOTO_HELP_DRIVER),
      EFI_IFR_FLAG_CALLBACK,
      (UINT16) (Index + KEY_VALUE_DEVICE_OFFSET)
      );
  }

  //
  // Update first page form
  //
  HiiUpdateForm (
    Private->RegisteredHandle,
    &gPlatformOverridesManagerGuid,
    FORM_ID_DEVICE,
    StartOpCodeHandle, // Label FORM_ID_DEVICE
    EndOpCodeHandle    // LABEL_END
    );

  HiiFreeOpCodeHandle (StartOpCodeHandle);
  HiiFreeOpCodeHandle (EndOpCodeHandle);

  return EFI_SUCCESS;
}

/**
  Get the first Driver Binding handle which has the specific image handle.

  @param  ImageHandle          The Image handle

  @return                      Handle to Driver binding
  @retval NULL                 The parameter is not valid or the driver binding handle is not found.

**/
EFI_HANDLE
GetDriverBindingHandleFromImageHandle (
  IN  EFI_HANDLE   ImageHandle
  )
{
  EFI_STATUS                        Status;
  UINTN                             Index;
  UINTN                             DriverBindingHandleCount;
  EFI_HANDLE                        *DriverBindingHandleBuffer;
  EFI_DRIVER_BINDING_PROTOCOL       *DriverBindingInterface;
  EFI_HANDLE                        DriverBindingHandle;

  DriverBindingHandle = NULL;

  if (ImageHandle == NULL) {
    return NULL;
  }
  //
  // Get all drivers which support driver binding protocol
  //
  DriverBindingHandleCount  = 0;
  Status = gBS->LocateHandleBuffer (
                  ByProtocol,
                  &gEfiDriverBindingProtocolGuid,
                  NULL,
                  &DriverBindingHandleCount,
                  &DriverBindingHandleBuffer
                  );
  if (EFI_ERROR (Status) || (DriverBindingHandleCount == 0)) {
    return NULL;
  }
  
  //
  // Get the first Driver Binding handle which has the specific image handle.
  //
  for (Index = 0; Index < DriverBindingHandleCount; Index++) {
    DriverBindingInterface = NULL;
    Status = gBS->OpenProtocol (
                    DriverBindingHandleBuffer[Index],
                    &gEfiDriverBindingProtocolGuid,
                    (VOID **) &DriverBindingInterface,
                    NULL,
                    NULL,
                    EFI_OPEN_PROTOCOL_GET_PROTOCOL
                    );
    if (EFI_ERROR (Status)) {
      continue;
    }

    if (DriverBindingInterface->ImageHandle == ImageHandle) {
      DriverBindingHandle = DriverBindingHandleBuffer[Index];
      break;
    }
  }

  FreePool (DriverBindingHandleBuffer);
  return DriverBindingHandle;
}

/**
  Prepare to let user select the drivers which need mapping with the device controller
  selected in first page.

  @param  Private        Pointer to EFI_CALLBACK_INFO.
  @param  KeyValue       The callback key value of device controller item in first page.
                         KeyValue is larger than or equal to KEY_VALUE_DEVICE_OFFSET.
  @param  FakeNvData     Pointer to PLAT_OVER_MNGR_DATA.

  @retval EFI_SUCCESS    Always returned.

**/
EFI_STATUS
UpdateBindingDriverSelectPage (
  IN EFI_CALLBACK_INFO                *Private,
  IN UINT16                           KeyValue,
  IN PLAT_OVER_MNGR_DATA              *FakeNvData
  )
{
  EFI_STATUS                                Status;
  UINTN                                     Index;
  UINTN                                     NewStrSize;
  CHAR16                                    *NewString;
  EFI_STRING_ID                             NewStringToken;
  EFI_STRING_ID                             NewStringHelpToken;
  UINTN                                     DriverImageHandleCount;
  EFI_LOADED_IMAGE_PROTOCOL                 *LoadedImage;
  CHAR16                                    *DriverName;
  BOOLEAN                                   FreeDriverName;
  EFI_DEVICE_PATH_PROTOCOL                  *LoadedImageDevicePath;
  EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL *BusSpecificDriverOverride;
  EFI_HANDLE                                DriverBindingHandle;
  VOID                                      *StartOpCodeHandle;
  VOID                                      *EndOpCodeHandle;
  EFI_IFR_GUID_LABEL                        *StartLabel;
  EFI_IFR_GUID_LABEL                        *EndLabel;
  EFI_LOADED_IMAGE_PROTOCOL                 **DriverImageProtocol;
  EFI_STRING_ID                             *DriverImageFilePathToken;
  UINT8                                     CheckFlags;

  //
  // If user select a controller item in the first page  the following code will be run.
  // During second page, user will see all currnet driver bind protocol driver, the driver name and its device path will be shown
  //
  //First acquire the list of Loaded Image Protocols, and then when  want the name of the driver, look up all the Driver Binding Protocols
  // and find the first one whose ImageHandle field matches the image handle of the Loaded Image Protocol.
  // then use the Component Name Protocol on the same handle as the first matching Driver Binding Protocol to look up the name of the driver.
  //

  mCurrentPage = FORM_ID_DRIVER;
  //
  // Switch the item callback key value to its NO. in mDevicePathHandleBuffer
  //
  mSelectedCtrIndex = KeyValue - KEY_VALUE_DEVICE_OFFSET;
  ASSERT (mSelectedCtrIndex >= 0 && mSelectedCtrIndex < MAX_CHOICE_NUM);

  mLastSavedDriverImageNum = 0;

  //
  // Init OpCode Handle
  //
  StartOpCodeHandle = HiiAllocateOpCodeHandle ();
  ASSERT (StartOpCodeHandle != NULL);

  EndOpCodeHandle = HiiAllocateOpCodeHandle ();
  ASSERT (EndOpCodeHandle != NULL);

  //
  // Create Hii Extend Label OpCode as the start opcode
  //
  StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
  StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
  StartLabel->Number       = FORM_ID_DRIVER;

  //
  // Create Hii Extend Label OpCode as the end opcode
  //
  EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (EndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
  EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
  EndLabel->Number       = LABEL_END;

  //
  // Clear second page form
  //
  HiiUpdateForm (
    Private->RegisteredHandle,
    &gPlatformOverridesManagerGuid,
    FORM_ID_DRIVER,
    StartOpCodeHandle,
    EndOpCodeHandle
    );

  //
  // Show all driver which support loaded image protocol in second page
  //
  DriverImageHandleCount  = 0;
  Status = gBS->LocateHandleBuffer (
                  ByProtocol,
                  &gEfiLoadedImageProtocolGuid,
                  NULL,
                  &DriverImageHandleCount,
                  &mDriverImageHandleBuffer
                  );
  if (EFI_ERROR (Status) || (DriverImageHandleCount == 0)) {
    return EFI_NOT_FOUND;
  }

  mDriverImageToken = AllocateZeroPool (DriverImageHandleCount * sizeof (EFI_STRING_ID));
  ASSERT (mDriverImageToken != NULL);
  mDriSelection = AllocateZeroPool (DriverImageHandleCount * sizeof (BOOLEAN));
  ASSERT (mDriSelection != NULL);

  DriverImageProtocol = AllocateZeroPool (DriverImageHandleCount * sizeof (EFI_LOADED_IMAGE_PROTOCOL *));
  ASSERT (DriverImageProtocol != NULL);
  DriverImageFilePathToken = AllocateZeroPool (DriverImageHandleCount * sizeof (EFI_STRING_ID));
  ASSERT (DriverImageFilePathToken != NULL);

  mDriverImageHandleCount = DriverImageHandleCount;
  for (Index = 0; Index < DriverImageHandleCount; Index++) {
    //
    // Step1: Get the driver image total file path for help string and the driver name.
    //

    //
    // Find driver's Loaded Image protocol
    //
    LoadedImage =NULL;

    Status = gBS->OpenProtocol (
                    mDriverImageHandleBuffer[Index],
                    &gEfiLoadedImageProtocolGuid,
                    (VOID **) &LoadedImage,
                    NULL,
                    NULL,
                    EFI_OPEN_PROTOCOL_GET_PROTOCOL
                    );
    if (EFI_ERROR (Status)) {
      mDriSelection[Index] = FALSE;
      continue;
    }
    DriverImageProtocol[Index] = LoadedImage;
    //
    // Find its related driver binding protocol
    //
    DriverBindingHandle = GetDriverBindingHandleFromImageHandle (mDriverImageHandleBuffer[Index]);
    if (DriverBindingHandle == NULL) {
      mDriSelection[Index] = FALSE;
      continue;
    }

    //
    // Get the EFI Loaded Image Device Path Protocol
    //
    LoadedImageDevicePath = NULL;
    Status = gBS->HandleProtocol (
                        mDriverImageHandleBuffer[Index],
                        &gEfiLoadedImageDevicePathProtocolGuid,
                        (VOID **) &LoadedImageDevicePath
                        );
    if (LoadedImageDevicePath == NULL) {
      mDriSelection[Index] = FALSE;
      continue;
    }

    if (FakeNvData->PciDeviceFilter == 0x01) {
      //
      // only care the driver which is in a Pci device option rom,
      // and the driver's LoadedImage->DeviceHandle must point to a pci device which has efi option rom
      //
      if (!EFI_ERROR (Status)) {
        Status = gBS->HandleProtocol(
                         LoadedImage->DeviceHandle,
                         &gEfiBusSpecificDriverOverrideProtocolGuid,
                         (VOID **) &BusSpecificDriverOverride
                         );
        if (EFI_ERROR (Status) || BusSpecificDriverOverride == NULL) {
          mDriSelection[Index] = FALSE;
          continue;
        }
      } else {
        mDriSelection[Index] = FALSE;
        continue;
      }
    }

    //
    // For driver name, try to get its component name, if fail, get its image name,
    // if also fail, give a default name.
    //
    FreeDriverName = FALSE;
    DriverName = GetComponentName (DriverBindingHandle);
    if (DriverName == NULL) {
      //
      // get its image name
      //
      DriverName = GetImageName (LoadedImage);
    }
    if (DriverName == NULL) {
      //
      // give a default name
      //
      DriverName = HiiGetString (Private->RegisteredHandle, STRING_TOKEN (STR_DRIVER_DEFAULT_NAME), NULL);
      ASSERT (DriverName != NULL);
      FreeDriverName = TRUE;  // the DriverName string need to free pool
    }


    //
    // Step2 Export the driver name string and create check box item in second page
    //

    //
    // First create the driver image name
    //
    NewStrSize = StrSize (DriverName);
    NewString = AllocateZeroPool (NewStrSize);
    ASSERT (NewString != NULL); 
    if (EFI_ERROR (CheckMapping (mControllerDevicePathProtocol[mSelectedCtrIndex], LoadedImageDevicePath, &mMappingDataBase, NULL, NULL))) {
      mDriSelection[Index] = FALSE;
    } else {
      mDriSelection[Index] = TRUE;
      mLastSavedDriverImageNum++;
    }
    StrCatS (NewString, NewStrSize/sizeof(CHAR16), DriverName);
    NewStringToken = HiiSetString (Private->RegisteredHandle, mDriverImageToken[Index], NewString, NULL);
    ASSERT (NewStringToken != 0);
    mDriverImageToken[Index] = NewStringToken;
    FreePool (NewString);
    if (FreeDriverName) {
      FreePool (DriverName);
    }

    //
    // Second create the driver image device path as item help string
    //
    DriverName = DevicePathToStr (LoadedImageDevicePath);

    NewStrSize = StrSize (DriverName);
    NewString = AllocateZeroPool (NewStrSize);
    ASSERT (NewString != NULL); 
    StrCatS (NewString, NewStrSize/sizeof(CHAR16), DriverName);
    NewStringHelpToken = HiiSetString (Private->RegisteredHandle, DriverImageFilePathToken[Index], NewString, NULL);
    ASSERT (NewStringHelpToken != 0);
    DriverImageFilePathToken[Index] = NewStringHelpToken;
    FreePool (NewString);
    FreePool (DriverName);

    CheckFlags        = 0;
    if (mDriSelection[Index]) {
      CheckFlags |= EFI_IFR_CHECKBOX_DEFAULT;
    }

    HiiCreateCheckBoxOpCode (
      StartOpCodeHandle,
      (UINT16) (KEY_VALUE_DRIVER_OFFSET + Index),
      0,
      0,
      NewStringToken,
      NewStringHelpToken,
      EFI_IFR_FLAG_CALLBACK,
      CheckFlags,
      NULL
      );
  }

  //
  // Update second page form
  //
  HiiUpdateForm (
    Private->RegisteredHandle,
    &gPlatformOverridesManagerGuid,
    FORM_ID_DRIVER,
    StartOpCodeHandle, // Label FORM_ID_DRIVER
    EndOpCodeHandle    // LABEL_END
    );

  HiiFreeOpCodeHandle (StartOpCodeHandle);
  HiiFreeOpCodeHandle (EndOpCodeHandle);

  if (DriverImageProtocol != NULL) {
    FreePool (DriverImageProtocol);
  }

  if (DriverImageFilePathToken != NULL) {
    FreePool (DriverImageFilePathToken);
  }

  return EFI_SUCCESS;
}

/**
  Prepare to let user select the priority order of the drivers which are
  selected in second page.

  @param  Private        Pointer to EFI_CALLBACK_INFO.
  @param  KeyValue       The callback key value of device controller item in first page.
  @param  FakeNvData     Pointer to PLAT_OVER_MNGR_DATA.

  @retval EFI_SUCCESS    Always returned.

**/
EFI_STATUS
UpdatePrioritySelectPage (
  IN EFI_CALLBACK_INFO                *Private,
  IN UINT16                           KeyValue,
  IN PLAT_OVER_MNGR_DATA              *FakeNvData
  )
{
  UINTN                                     Index;
  EFI_DEVICE_PATH_PROTOCOL                  *LoadedImageDevicePath;
  UINTN                                     SelectedDriverImageNum;
  UINT32                                    DriverImageNO;
  UINTN                                     MinNO;
  UINTN                                     Index1;
  UINTN                                     TempNO[100];
  UINTN                                     OrderNO[100];
  VOID                                      *StartOpCodeHandle;
  VOID                                      *EndOpCodeHandle;
  VOID                                      *OptionsOpCodeHandle;
  EFI_IFR_GUID_LABEL                        *StartLabel;
  EFI_IFR_GUID_LABEL                        *EndLabel;

  //
  // Following code will be run if user select 'order ... priority' item in second page
  // Prepare third page.  In third page, user will order the  drivers priority which are selected in second page
  //
  mCurrentPage = FORM_ID_ORDER;

  //
  // Init OpCode Handle
  //
  StartOpCodeHandle = HiiAllocateOpCodeHandle ();
  ASSERT (StartOpCodeHandle != NULL);

  EndOpCodeHandle = HiiAllocateOpCodeHandle ();
  ASSERT (EndOpCodeHandle != NULL);

  //
  // Create Hii Extend Label OpCode as the start opcode
  //
  StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
  StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
  StartLabel->Number       = FORM_ID_ORDER;

  //
  // Create Hii Extend Label OpCode as the end opcode
  //
  EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (EndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
  EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
  EndLabel->Number       = LABEL_END;

  //
  // Clear third page form
  //
  HiiUpdateForm (
    Private->RegisteredHandle,
    &gPlatformOverridesManagerGuid,
    FORM_ID_ORDER,
    StartOpCodeHandle,
    EndOpCodeHandle
    );

  //
  // Check how many drivers have been selected
  //
  SelectedDriverImageNum = 0;
  for (Index = 0; Index < mDriverImageHandleCount; Index++) {
    if (mDriSelection[Index]) {
      SelectedDriverImageNum ++;
    }
  }

  mSelectedDriverImageNum = SelectedDriverImageNum;
  if (SelectedDriverImageNum == 0) {
    return EFI_SUCCESS;
  }

  OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();
  ASSERT (OptionsOpCodeHandle != NULL);

  //
  // Create order list for those selected drivers
  //
  SelectedDriverImageNum = 0;
  for (Index = 0; Index < mDriverImageHandleCount; Index++) {
    if (mDriSelection[Index]) {
      //
      // Use the NO. in driver binding buffer as value, will use it later
      //
      HiiCreateOneOfOptionOpCode (
        OptionsOpCodeHandle,
        mDriverImageToken[Index],
        0,
        EFI_IFR_NUMERIC_SIZE_1,
        Index + 1
        );

      //
      // Get the EFI Loaded Image Device Path Protocol
      //
      LoadedImageDevicePath = NULL;
      gBS->HandleProtocol (
                 mDriverImageHandleBuffer[Index],
                 &gEfiLoadedImageDevicePathProtocolGuid,
                 (VOID **) &LoadedImageDevicePath
                 );
      ASSERT (LoadedImageDevicePath != NULL);

      //
      // Check the driver DriverImage's order number in mapping database
      //
      DriverImageNO = 0;
      CheckMapping (
              mControllerDevicePathProtocol[mSelectedCtrIndex],
              LoadedImageDevicePath,
              &mMappingDataBase,
              NULL,
              &DriverImageNO
              );
      if (DriverImageNO == 0) {
        DriverImageNO = (UINT32) mLastSavedDriverImageNum + 1;
        mLastSavedDriverImageNum++;
      }
      TempNO[SelectedDriverImageNum] = DriverImageNO;
      OrderNO[SelectedDriverImageNum] = Index + 1;
      SelectedDriverImageNum ++;
    }
  }

  ASSERT (SelectedDriverImageNum == mSelectedDriverImageNum);
  //
  // NvRamMap Must be clear firstly
  //
  ZeroMem (FakeNvData->DriOrder, sizeof (FakeNvData->DriOrder));

  //
  // Order the selected drivers according to the info already in mapping database
  // the less order number in mapping database the less order number in NvRamMap
  //
  for (Index=0; Index < SelectedDriverImageNum; Index++) {
    //
    // Find the minimal order number in TempNO array,  its index in TempNO is same as IfrOptionList array
    //
    MinNO = 0;
    for (Index1=0; Index1 < SelectedDriverImageNum; Index1++) {
      if (TempNO[Index1] < TempNO[MinNO]) {
        MinNO = Index1;
      }
    }
    //
    // the IfrOptionList[MinNO].Value = the driver NO. in driver binding buffer
    //
    FakeNvData->DriOrder[Index] = (UINT8) OrderNO[MinNO];
    TempNO[MinNO] = MAX_CHOICE_NUM + 1;
  }
  
  //
  // Create Order List OpCode
  //
  HiiCreateOrderedListOpCode (
    StartOpCodeHandle,
    (UINT16) DRIVER_ORDER_QUESTION_ID,
    VARSTORE_ID_PLAT_OVER_MNGR,
    (UINT16) DRIVER_ORDER_VAR_OFFSET,
    mControllerToken[mSelectedCtrIndex],
    mControllerToken[mSelectedCtrIndex],
    EFI_IFR_FLAG_RESET_REQUIRED,
    0,
    EFI_IFR_NUMERIC_SIZE_1,
    (UINT8) MAX_CHOICE_NUM,
    OptionsOpCodeHandle,
    NULL
    );

  //
  // Update third page form
  //
  HiiUpdateForm (
    Private->RegisteredHandle,
    &gPlatformOverridesManagerGuid,
    FORM_ID_ORDER,
    StartOpCodeHandle, // Label FORM_ID_ORDER
    EndOpCodeHandle    // LABEL_END
    );

  HiiFreeOpCodeHandle (StartOpCodeHandle);
  HiiFreeOpCodeHandle (EndOpCodeHandle);
  HiiFreeOpCodeHandle (OptionsOpCodeHandle);

  return EFI_SUCCESS;
}

/**
  Save the save the mapping database to NV variable.

  @param  Private        Pointer to EFI_CALLBACK_INFO.
  @param  KeyValue       The callback key value of device controller item in first page.
  @param  FakeNvData     Pointer to PLAT_OVER_MNGR_DATA.

  @retval EFI_SUCCESS    Always returned.

**/
EFI_STATUS
CommitChanges (
  IN EFI_CALLBACK_INFO                *Private,
  IN UINT16                           KeyValue,
  IN PLAT_OVER_MNGR_DATA              *FakeNvData
  )
{
  EFI_STATUS                                Status;
  UINTN                                     Index;
  UINTN                                     SelectedDriverImageNum;
  EFI_DEVICE_PATH_PROTOCOL                  *LoadedImageDevicePath;
  //
  //  Following code will be run if user select 'commint changes' in third page
  //  user enter 'Commit Changes' to save the mapping database
  //
  DeleteDriverImage (mControllerDevicePathProtocol[mSelectedCtrIndex], NULL, &mMappingDataBase);
  for (SelectedDriverImageNum = 0; SelectedDriverImageNum < mSelectedDriverImageNum; SelectedDriverImageNum++) {
    //
    // DriOrder[SelectedDriverImageNum] = the driver NO. in driver binding buffer
    //
    Index = FakeNvData->DriOrder[SelectedDriverImageNum] - 1;

    //
    // Get the EFI Loaded Image Device Path Protocol
    //
    LoadedImageDevicePath = NULL;
    Status = gBS->HandleProtocol (
                        mDriverImageHandleBuffer[Index],
                        &gEfiLoadedImageDevicePathProtocolGuid,
                        (VOID **) &LoadedImageDevicePath
                        );
    ASSERT (LoadedImageDevicePath != NULL);

    InsertDriverImage (
            mControllerDevicePathProtocol[mSelectedCtrIndex],
            LoadedImageDevicePath,
            &mMappingDataBase,
            (UINT32)SelectedDriverImageNum + 1
            );
  }
  Status = SaveOverridesMapping (&mMappingDataBase);

  return Status;
}

/**
  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 illegal syntax, or unknown name.
  @retval EFI_NOT_FOUND          Routing data doesn't match any storage in this driver.

**/
EFI_STATUS
EFIAPI
PlatOverMngrExtractConfig (
  IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL   *This,
  IN  CONST EFI_STRING                       Request,
  OUT EFI_STRING                             *Progress,
  OUT EFI_STRING                             *Results
  )
{
  EFI_STATUS                       Status;
  EFI_CALLBACK_INFO                *Private;
  EFI_HII_CONFIG_ROUTING_PROTOCOL  *HiiConfigRouting;
  EFI_STRING                       ConfigRequestHdr;
  EFI_STRING                       ConfigRequest;
  BOOLEAN                          AllocatedRequest;
  UINTN                            Size;
  UINTN                            BufferSize;

  if (Progress == NULL || Results == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  *Progress = Request;
  if ((Request != NULL) && !HiiIsConfigHdrMatch (Request, &gPlatformOverridesManagerGuid, mVariableName)) {
    return EFI_NOT_FOUND;
  }

  ConfigRequestHdr = NULL;
  ConfigRequest    = NULL;
  Size             = 0;
  AllocatedRequest = FALSE;

  Private          = EFI_CALLBACK_INFO_FROM_THIS (This);
  HiiConfigRouting = Private->HiiConfigRouting;
  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 (&gPlatformOverridesManagerGuid, mVariableName, Private->DriverHandle);
    Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);
    ConfigRequest = AllocateZeroPool (Size);
    ASSERT (ConfigRequest != NULL);
    AllocatedRequest = TRUE;
    BufferSize = sizeof (PLAT_OVER_MNGR_DATA);
    UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, (UINT64)BufferSize);
    FreePool (ConfigRequestHdr);
  }

  //
  // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
  //
  Status = HiiConfigRouting->BlockToConfig (
                                HiiConfigRouting,
                                ConfigRequest,
                                (UINT8 *) &Private->FakeNvData,
                                sizeof (PLAT_OVER_MNGR_DATA),
                                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 processes the results of changes in configuration.

  @param  This            Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
  @param  Configuration   A null-terminated Unicode string in <ConfigRequest> format.
  @param  Progress        A pointer to a string filled in with the offset of 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) or the terminating NULL if all was successful.

  @retval EFI_SUCCESS            The Results is processed successfully.
  @retval EFI_INVALID_PARAMETER  Configuration is NULL.
  @retval EFI_NOT_FOUND          Routing data doesn't match any storage in this driver.

**/
EFI_STATUS
EFIAPI
PlatOverMngrRouteConfig (
  IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL   *This,
  IN  CONST EFI_STRING                       Configuration,
  OUT EFI_STRING                             *Progress
  )
{
  EFI_CALLBACK_INFO                         *Private;
  UINT16                                    KeyValue;
  PLAT_OVER_MNGR_DATA                       *FakeNvData;
  EFI_STATUS                                Status;

  if (Configuration == NULL || Progress == NULL) {
    return EFI_INVALID_PARAMETER;
  }
  *Progress = Configuration;

  if (!HiiIsConfigHdrMatch (Configuration, &gPlatformOverridesManagerGuid, mVariableName)) {
    return EFI_NOT_FOUND;
  }
  
  *Progress = Configuration + StrLen (Configuration);
  Private    = EFI_CALLBACK_INFO_FROM_THIS (This);
  FakeNvData = &Private->FakeNvData;
  if (!HiiGetBrowserData (&gPlatformOverridesManagerGuid, mVariableName, sizeof (PLAT_OVER_MNGR_DATA), (UINT8 *) FakeNvData)) {
    //
    // FakeNvData can't be got from SetupBrowser, which doesn't need to be set.
    //
    return EFI_SUCCESS;
  }

  Status = EFI_SUCCESS;

  if (mCurrentPage == FORM_ID_ORDER) {
    KeyValue = KEY_VALUE_ORDER_SAVE_AND_EXIT;
    Status = CommitChanges (Private, KeyValue, FakeNvData);
  }

  return Status;
}

/**
  This is the function that is called to provide results data to the driver.  This data
  consists of a unique key which is used to identify what data is either being passed back
  or being asked for.

  @param  This           Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
  @param  Action         A null-terminated Unicode string in <ConfigRequest> format.
  @param  KeyValue       A unique Goto OpCode callback value which record user's selection.
                         0x100 <= KeyValue <0x500 : user select a controller item in the first page;
                         KeyValue == 0x1234       : user select 'Refresh' in first page, or user select 'Go to Previous Menu' in second page
                         KeyValue == 0x1235       : user select 'Pci device filter' in first page
                         KeyValue == 0x1500       : user select 'order ... priority' item in second page
                         KeyValue == 0x1800       : user select 'commint changes' in third page
                         KeyValue == 0x2000       : user select 'Go to Previous Menu' in third page
  @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    Always returned.

**/
EFI_STATUS
EFIAPI
PlatOverMngrCallback (
  IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL   *This,
  IN  EFI_BROWSER_ACTION                     Action,
  IN  EFI_QUESTION_ID                        KeyValue,
  IN  UINT8                                  Type,
  IN  EFI_IFR_TYPE_VALUE                     *Value,
  OUT EFI_BROWSER_ACTION_REQUEST             *ActionRequest
  )
{
  EFI_CALLBACK_INFO                         *Private;
  EFI_STATUS                                Status;
  EFI_STRING_ID                             NewStringToken;
  EFI_INPUT_KEY                             Key;
  PLAT_OVER_MNGR_DATA                       *FakeNvData;

  if ((Action != EFI_BROWSER_ACTION_CHANGING) && (Action != EFI_BROWSER_ACTION_CHANGED)) {
    //
    // All other action return unsupported.
    //
    return EFI_UNSUPPORTED;
  }

  Private = EFI_CALLBACK_INFO_FROM_THIS (This);
  FakeNvData = &Private->FakeNvData;
  if (!HiiGetBrowserData (&gPlatformOverridesManagerGuid, mVariableName, sizeof (PLAT_OVER_MNGR_DATA), (UINT8 *) FakeNvData)) {
    return EFI_NOT_FOUND;
  }

  if (Action == EFI_BROWSER_ACTION_CHANGING) {
    if (Value == NULL) {
      return EFI_INVALID_PARAMETER;
    }
    
    if (KeyValue == KEY_VALUE_DRIVER_GOTO_PREVIOUS) {
      UpdateDeviceSelectPage (Private, KeyValue, FakeNvData);
      //
      // Update page title string
      //
      NewStringToken = STRING_TOKEN (STR_TITLE);
      if (HiiSetString (Private->RegisteredHandle, NewStringToken, L"First, Select the controller by device path", NULL) == 0) {
        ASSERT (FALSE);
      }
    }

    if (((KeyValue >= KEY_VALUE_DEVICE_OFFSET) && (KeyValue < KEY_VALUE_DEVICE_OFFSET + mMaxDeviceCount)) || (KeyValue == KEY_VALUE_ORDER_GOTO_PREVIOUS)) {
      if (KeyValue == KEY_VALUE_ORDER_GOTO_PREVIOUS) {
        KeyValue = (EFI_QUESTION_ID) (mSelectedCtrIndex + KEY_VALUE_DEVICE_OFFSET);
      }
      UpdateBindingDriverSelectPage (Private, KeyValue, FakeNvData);
      //
      // Update page title string
      //
      NewStringToken = STRING_TOKEN (STR_TITLE);
      if (HiiSetString (Private->RegisteredHandle, NewStringToken, L"Second, Select drivers for the previous selected controller", NULL) == 0) {
        ASSERT (FALSE);
      }
    }

    if (KeyValue == KEY_VALUE_DRIVER_GOTO_ORDER) {
      UpdatePrioritySelectPage (Private, KeyValue, FakeNvData);
      //
      // Update page title string
      //
      NewStringToken = STRING_TOKEN (STR_TITLE);
      if (HiiSetString (Private->RegisteredHandle, NewStringToken, L"Finally, Set the priority order for the drivers and save them", NULL) == 0) {
        ASSERT (FALSE);
      }
    }

    if (KeyValue == KEY_VALUE_DEVICE_CLEAR) {
      //
      // Deletes all environment variable(s) that contain the override mappings info
      //
      FreeMappingDatabase (&mMappingDataBase);
      Status = SaveOverridesMapping (&mMappingDataBase);
      UpdateDeviceSelectPage (Private, KeyValue, FakeNvData);
    }
  } else if (Action == EFI_BROWSER_ACTION_CHANGED) {
    if ((KeyValue >= KEY_VALUE_DRIVER_OFFSET) && (KeyValue < KEY_VALUE_DRIVER_OFFSET + mDriverImageHandleCount)) {
      mDriSelection[KeyValue - KEY_VALUE_DRIVER_OFFSET] = Value->b;
    } else {
      switch (KeyValue) {
      case KEY_VALUE_DEVICE_REFRESH:
      case KEY_VALUE_DEVICE_FILTER:
        UpdateDeviceSelectPage (Private, KeyValue, FakeNvData);
        //
        // Update page title string
        //
        NewStringToken = STRING_TOKEN (STR_TITLE);
        if (HiiSetString (Private->RegisteredHandle, NewStringToken, L"First, Select the controller by device path", NULL) == 0) {
          ASSERT (FALSE);
        }
      break;
      
      case KEY_VALUE_ORDER_SAVE_AND_EXIT:
        Status = CommitChanges (Private, KeyValue, FakeNvData);
        *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT;
        if (EFI_ERROR (Status)) {
          CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Single Override Info too large, Saving Error!", NULL);
          return EFI_DEVICE_ERROR;
        }
      break;

      default:
      break;
      }
    }
  }

  //
  // Pass changed uncommitted data back to Form Browser
  //
  HiiSetBrowserData (&gPlatformOverridesManagerGuid, mVariableName, sizeof (PLAT_OVER_MNGR_DATA), (UINT8 *) FakeNvData, NULL);

  return EFI_SUCCESS;
}

/**
  Retrieves the image handle of the platform override driver for a controller in the system.

  @param  This                   A pointer to the
                                 EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL instance.
  @param  ControllerHandle       The device handle of the controller to check if a
                                 driver override exists.
  @param  DriverImageHandle      On input, a pointer to the previous driver image
                                 handle returned by GetDriver().  On output, a
                                 pointer to the next driver image handle. Passing
                                 in a NULL,  will return the first driver image
                                 handle for ControllerHandle.

  @retval EFI_SUCCESS            The driver override for ControllerHandle was
                                 returned in DriverImageHandle.
  @retval EFI_NOT_FOUND          A driver override for ControllerHandle was not
                                 found.
  @retval EFI_INVALID_PARAMETER  The handle specified by ControllerHandle is NULL.
                                 DriverImageHandle is not a handle that was returned
                                 on a previous  call to GetDriver().

**/
EFI_STATUS
EFIAPI
GetDriver (
  IN EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL              *This,
  IN     EFI_HANDLE                                     ControllerHandle,
  IN OUT EFI_HANDLE                                     *DriverImageHandle
  )
{
  EFI_STATUS  Status;

  //
  // Check that ControllerHandle is a valid handle
  //
  if (ControllerHandle == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Read the environment variable(s) that contain the override mappings from Controller Device Path to
  // a set of Driver Device Paths, and  initialize in memory database of the overrides that map Controller
  // Device Paths to an ordered set of Driver Device Paths and Driver Handles. This action is only performed
  // once and finished in first call.
  //
  if (!mEnvironmentVariableRead) {
    mEnvironmentVariableRead = TRUE;

    Status = InitOverridesMapping (&mMappingDataBase);
    if (EFI_ERROR (Status)){
      DEBUG ((DEBUG_INFO, "The status to Get Platform Driver Override Variable is %r\n", Status));
      InitializeListHead (&mMappingDataBase);
      return EFI_NOT_FOUND;
    }
  }

  //
  // if the environment variable does not exist, just return not found
  //
  if (IsListEmpty (&mMappingDataBase)) {
    return EFI_NOT_FOUND;
  }

  return GetDriverFromMapping (
            ControllerHandle,
            DriverImageHandle,
            &mMappingDataBase,
            mCallerImageHandle
            );
}

/**
  Retrieves the device path of the platform override driver for a controller in the system.
  This driver doesn't support this API.

  @param  This                  A pointer to the EFI_PLATFORM_DRIVER_OVERRIDE_
                                PROTOCOL instance.                            
  @param  ControllerHandle      The device handle of the controller to check if a driver override
                                exists.                                                          
  @param  DriverImagePath       On input, a pointer to the previous driver device path returned by
                                GetDriverPath(). On output, a pointer to the next driver
                                device path. Passing in a pointer to NULL, will return the first
                                driver device path for ControllerHandle.
  
  @retval EFI_UNSUPPORTED
**/
EFI_STATUS
EFIAPI
GetDriverPath (
  IN EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL              *This,
  IN     EFI_HANDLE                                     ControllerHandle,
  IN OUT EFI_DEVICE_PATH_PROTOCOL                       **DriverImagePath
  )
{
  return EFI_UNSUPPORTED;
}


/**
  Used to associate a driver image handle with a device path that was returned on a prior call to the
  GetDriverPath() service. This driver image handle will then be available through the               
  GetDriver() service. This driver doesn't support this API.

  @param  This                  A pointer to the EFI_PLATFORM_DRIVER_OVERRIDE_
                                PROTOCOL instance.                            
  @param  ControllerHandle      The device handle of the controller.                                                             
  @param  DriverImagePath       A pointer to the driver device path that was returned in a prior
                                call to GetDriverPath().                                                                        
  @param  DriverImageHandle     The driver image handle that was returned by LoadImage()
                                when the driver specified by DriverImagePath was loaded 
                                into memory. 
  
  @retval EFI_UNSUPPORTED
**/
EFI_STATUS
EFIAPI
DriverLoaded (
  IN EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL          *This,
  IN EFI_HANDLE                                     ControllerHandle,
  IN EFI_DEVICE_PATH_PROTOCOL                       *DriverImagePath,
  IN EFI_HANDLE                                     DriverImageHandle
  )
{
  return EFI_UNSUPPORTED;
}

/**
  The driver Entry Point. The function will export a disk device class formset and
  its callback function to hii database.

  @param  ImageHandle    The firmware allocated handle for the EFI image.
  @param  SystemTable    A pointer to the EFI System Table.

  @retval EFI_SUCCESS    The entry point is executed successfully.
  @retval other          Some error occurs when executing this entry point.

**/
EFI_STATUS
EFIAPI
PlatDriOverrideDxeInit (
  IN EFI_HANDLE                   ImageHandle,
  IN EFI_SYSTEM_TABLE             *SystemTable
  )
{
  EFI_STATUS                  Status;
  EFI_FORM_BROWSER2_PROTOCOL  *FormBrowser2;
  VOID                        *Instance;
  
  //
  // There should only be one Form Configuration protocol
  //
  Status = gBS->LocateProtocol (
                 &gEfiFormBrowser2ProtocolGuid,
                 NULL,
                 (VOID **) &FormBrowser2
                 );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // According to UEFI spec, there can be at most a single instance
  // in the system of the EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL.
  // So here we check the existence.
  //
  Status = gBS->LocateProtocol (
                  &gEfiPlatformDriverOverrideProtocolGuid,
                  NULL,
                  &Instance
                  );
  //
  // If there was no error, assume there is an installation and return error
  //
  if (!EFI_ERROR (Status)) {
    return EFI_ALREADY_STARTED;
  }
  
  mCallerImageHandle = ImageHandle;
  mCallbackInfo = AllocateZeroPool (sizeof (EFI_CALLBACK_INFO));
  if (mCallbackInfo == NULL) {
    return EFI_BAD_BUFFER_SIZE;
  }

  mCallbackInfo->Signature = EFI_CALLBACK_INFO_SIGNATURE;
  mCallbackInfo->ConfigAccess.ExtractConfig = PlatOverMngrExtractConfig;
  mCallbackInfo->ConfigAccess.RouteConfig   = PlatOverMngrRouteConfig;
  mCallbackInfo->ConfigAccess.Callback      = PlatOverMngrCallback;
  mCallbackInfo->PlatformDriverOverride.GetDriver      = GetDriver;
  mCallbackInfo->PlatformDriverOverride.GetDriverPath  = GetDriverPath;
  mCallbackInfo->PlatformDriverOverride.DriverLoaded   = DriverLoaded;

  //
  // Locate ConfigRouting protocol
  //
  Status = gBS->LocateProtocol (
                  &gEfiHiiConfigRoutingProtocolGuid,
                  NULL,
                  (VOID **) &mCallbackInfo->HiiConfigRouting
                  );
  if (EFI_ERROR (Status)) {
    goto Finish;
  }

  //
  // Install Device Path Protocol and Config Access protocol to driver handle
  // Install Platform Driver Override Protocol to driver handle
  //
  Status = gBS->InstallMultipleProtocolInterfaces (
                  &mCallbackInfo->DriverHandle,
                  &gEfiDevicePathProtocolGuid,
                  &mHiiVendorDevicePath,
                  &gEfiHiiConfigAccessProtocolGuid,
                  &mCallbackInfo->ConfigAccess,
                  &gEfiPlatformDriverOverrideProtocolGuid,
                  &mCallbackInfo->PlatformDriverOverride,
                  NULL
                  );
  if (EFI_ERROR (Status)) {
    goto Finish;
  }

  //
  // Publish our HII data
  //
  mCallbackInfo->RegisteredHandle = HiiAddPackages (
                                     &gPlatformOverridesManagerGuid,
                                     mCallbackInfo->DriverHandle,
                                     VfrBin,
                                     PlatDriOverrideDxeStrings,
                                     NULL
                                     );
  if (mCallbackInfo->RegisteredHandle == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto Finish;
  }

  //
  // Clear all the globle variable
  //
  mDriverImageHandleCount = 0;
  mCurrentPage = 0;
  
  return EFI_SUCCESS;

Finish:
  PlatDriOverrideDxeUnload (ImageHandle);

  return Status;
}

/**
  Unload its installed protocol.

  @param[in]  ImageHandle       Handle that identifies the image to be unloaded.

  @retval EFI_SUCCESS           The image has been unloaded.
**/
EFI_STATUS
EFIAPI
PlatDriOverrideDxeUnload (
  IN EFI_HANDLE  ImageHandle
  )
{
  ASSERT (mCallbackInfo != NULL);

  if (mCallbackInfo->DriverHandle != NULL) {
    gBS->UninstallMultipleProtocolInterfaces (
           mCallbackInfo->DriverHandle,
           &gEfiDevicePathProtocolGuid,
           &mHiiVendorDevicePath,
           &gEfiHiiConfigAccessProtocolGuid,
           &mCallbackInfo->ConfigAccess,
           &gEfiPlatformDriverOverrideProtocolGuid,
           &mCallbackInfo->PlatformDriverOverride,
           NULL
           );
  }

  if (mCallbackInfo->RegisteredHandle != NULL) {
    HiiRemovePackages (mCallbackInfo->RegisteredHandle);
  }

  FreePool (mCallbackInfo);

  if (mControllerToken != NULL) {
    FreePool (mControllerToken);
  }

  if (mControllerDevicePathProtocol != NULL) {
    FreePool (mControllerDevicePathProtocol);
  }

  if (mDriverImageToken != NULL) {
    FreePool (mDriverImageToken);
  }

  return EFI_SUCCESS;
}
