/**@file
  This file implements functions related to Config Access Protocols installed by
  by HII Thunk Modules. These Config access Protocols are used to thunk UEFI Config 
  Access Callback to Framework HII Callback and EFI Variable Set/Get operations.
  
Copyright (c) 2008, Intel Corporation
All rights reserved. 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 "HiiDatabase.h"
#include "UefiIfrParser.h"

BOOLEAN            mHiiPackageListUpdated = FALSE;

HII_VENDOR_DEVICE_PATH  mUefiHiiVendorDevicePath = {
  {
    {
      {
        HARDWARE_DEVICE_PATH,
        HW_VENDOR_DP,
        {
          (UINT8) (sizeof (HII_VENDOR_DEVICE_PATH_NODE)),
          (UINT8) ((sizeof (HII_VENDOR_DEVICE_PATH_NODE)) >> 8)
        }
      },
      EFI_CALLER_ID_GUID
    },
    0,
    0
  },
  {
    END_DEVICE_PATH_TYPE,
    END_ENTIRE_DEVICE_PATH_SUBTYPE,
    { 
      (UINT8) (sizeof (EFI_DEVICE_PATH_PROTOCOL)),
      (UINT8) ((sizeof (EFI_DEVICE_PATH_PROTOCOL)) >> 8)
    }
  }
};

CONFIG_ACCESS_PRIVATE gConfigAccessPrivateTempate = {
  CONFIG_ACCESS_PRIVATE_SIGNATURE,
  {
    ThunkExtractConfig,
    ThunkRouteConfig,
    ThunkCallback
  }, //ConfigAccessProtocol
  NULL, //FormCallbackProtocol
  NULL 
};

/**
  Get the first EFI_IFR_VARSTORE from the FormSet. 
    
  @param FormSet                  The Form Set.
   
  @retval FORMSET_STORAGE *       Return the first EFI_IFR_VARSTORE.
  @retval NULL                    If the Form Set does not have EFI_IFR_VARSTORE.
**/
FORMSET_STORAGE *
GetFirstStorageOfFormSet (
  IN CONST FORM_BROWSER_FORMSET * FormSet
  ) 
{
  LIST_ENTRY             *StorageList;
  FORMSET_STORAGE        *Storage;

  StorageList = GetFirstNode (&FormSet->StorageListHead);

  if (!IsNull (&FormSet->StorageListHead, StorageList)) {
    Storage = FORMSET_STORAGE_FROM_LINK (StorageList);
    return Storage;
  }
  
  return NULL;
}

/**
  Get the FORM_BROWSER_STATEMENT that matches the Question's value.
    
  @param FormSet                  The Form Set.
  @param QuestionId               QuestionId
   
  @retval FORM_BROWSER_STATEMENT*   FORM_BROWSER_STATEMENT that match Question's value.
  @retval NULL                      If the Form Set does not have EFI_IFR_VARSTORE.
**/
FORM_BROWSER_STATEMENT *
GetStorageFromQuestionId (
  IN CONST FORM_BROWSER_FORMSET * FormSet,
  IN       EFI_QUESTION_ID        QuestionId
  )
{
  LIST_ENTRY             *FormList;
  LIST_ENTRY             *StatementList;
  FORM_BROWSER_FORM      *Form;
  FORM_BROWSER_STATEMENT *Statement;

  FormList = GetFirstNode (&FormSet->FormListHead);

  while (!IsNull (&FormSet->FormListHead, FormList)) {
    Form = FORM_BROWSER_FORM_FROM_LINK (FormList);

    StatementList = GetFirstNode (&Form->StatementListHead);

    while (!IsNull (&Form->StatementListHead, StatementList)) {
      Statement = FORM_BROWSER_STATEMENT_FROM_LINK (StatementList);
      if ((QuestionId == Statement->QuestionId) && (Statement->Storage != NULL)) {
        //
        // UEFI Question ID is unique in a FormSet.
        //
        ASSERT (Statement->Storage->Type == EFI_HII_VARSTORE_BUFFER);
        return Statement;
      }
      StatementList = GetNextNode (&Form->StatementListHead, StatementList);
    }

    FormList = GetNextNode (&FormSet->FormListHead, FormList);
  }
  
  return NULL;
}

/**
  Get the EFI_IFR_VARSTORE based the ID.
    
  @param FormSet                  The Form Set.
   
  @retval FORMSET_STORAGE *       The EFI_IFR_VARSTORE with the ID.
  @retval NULL                    If the Form Set does not have EFI_IFR_VARSTORE with such ID.
**/
FORMSET_STORAGE *
GetStorageFromVarStoreId (
  IN CONST FORM_BROWSER_FORMSET * FormSet,
  IN       EFI_VARSTORE_ID        VarStoreId
  )
{
  LIST_ENTRY             *StorageList;
  FORMSET_STORAGE        *Storage;

  StorageList = GetFirstNode (&FormSet->StorageListHead);

  while (!IsNull (&FormSet->StorageListHead, StorageList)) {
    Storage = FORMSET_STORAGE_FROM_LINK (StorageList);

    if (VarStoreId == Storage->VarStoreId) {
      return Storage;
    }

    StorageList = GetNextNode (&FormSet->StorageListHead, StorageList);
  }
  
  return NULL;
}

/**
  Get the EFI_IFR_VARSTORE based the <ConfigHdr> string in a <ConfigRequest>
  or a <ConfigResp> string.
    
  @param FormSet                  The Form Set.
  @param ConfigString             The Configuration String which is defined by UEFI HII.
   
  @retval FORMSET_STORAGE *       The EFI_IFR_VARSTORE where the Question's value is stored.
  @retval NULL                    If the Form Set does not have EFI_IFR_VARSTORE with such ID.
**/
FORMSET_STORAGE *
GetStorageFromConfigString (
  IN CONST FORM_BROWSER_FORMSET *FormSet,
  IN  CONST EFI_STRING          ConfigString
  )
{
  LIST_ENTRY             *StorageList;
  FORMSET_STORAGE        *Storage;
  CHAR16                 *Name;

  StorageList = GetFirstNode (&FormSet->StorageListHead);

  while (!IsNull (&FormSet->StorageListHead, StorageList)) {
    Storage = FORMSET_STORAGE_FROM_LINK (StorageList);

    if ((Storage->VarStoreId == FormSet->DefaultVarStoreId) && (FormSet->OriginalDefaultVarStoreName != NULL)) {
      Name = FormSet->OriginalDefaultVarStoreName;
    } else {
      Name = Storage->Name;
    }
    
    if (HiiIsConfigHdrMatch (ConfigString, &Storage->Guid, Name)) {
      return Storage;
    }

    StorageList = GetNextNode (&FormSet->StorageListHead, StorageList);
  }

   return NULL;
}

/**
  This function installs a EFI_CONFIG_ACCESS_PROTOCOL instance for a form package registered
  by a module using Framework HII Protocol Interfaces.

  UEFI HII require EFI_HII_CONFIG_ACCESS_PROTOCOL to be installed on a EFI_HANDLE, so
  that Setup Utility can load the Buffer Storage using this protocol.
   
  @param Packages             The Package List.
  @param ThunkContext         The Thunk Context.
   
  @retval  EFI_SUCCESS        The Config Access Protocol is installed successfully.
  @retval  EFI_OUT_RESOURCE   There is not enough memory.
   
**/
EFI_STATUS
InstallDefaultConfigAccessProtocol (
  IN  CONST EFI_HII_PACKAGES                    *Packages,
  IN  OUT   HII_THUNK_CONTEXT                   *ThunkContext
  )
{
  EFI_STATUS                                  Status;
  CONFIG_ACCESS_PRIVATE                       *ConfigAccessInstance;
  HII_VENDOR_DEVICE_PATH                      *HiiVendorPath;

  ASSERT (ThunkContext->IfrPackageCount != 0);

  ConfigAccessInstance = AllocateCopyPool (
                           sizeof (CONFIG_ACCESS_PRIVATE), 
                           &gConfigAccessPrivateTempate
                           );
  ASSERT (ConfigAccessInstance != NULL);

  //
  // Use memory address as unique ID to distinguish from different device paths
  // This function may be called multi times by the framework HII driver.
  //
  HiiVendorPath = AllocateCopyPool (
                           sizeof (HII_VENDOR_DEVICE_PATH), 
                           &mUefiHiiVendorDevicePath
                           );
  ASSERT (HiiVendorPath != NULL);

  HiiVendorPath->Node.UniqueId = (UINT64) ((UINTN) HiiVendorPath);

  Status = gBS->InstallMultipleProtocolInterfaces (
          &ThunkContext->UefiHiiDriverHandle,
          &gEfiDevicePathProtocolGuid,          
          HiiVendorPath,
          &gEfiHiiConfigAccessProtocolGuid,
          &ConfigAccessInstance->ConfigAccessProtocol,
          NULL
          );
  ASSERT_EFI_ERROR (Status);
  
  ConfigAccessInstance->ThunkContext = ThunkContext;
  
  return EFI_SUCCESS;
}

/**
  This function un-installs the EFI_CONFIG_ACCESS_PROTOCOL instance for a form package registered
  by a module using Framework HII Protocol Interfaces.

  ASSERT if no Config Access is found for such pakcage list or failed to uninstall the protocol.

  @param ThunkContext         The Thunk Context.
   
**/
VOID
UninstallDefaultConfigAccessProtocol (
  IN  HII_THUNK_CONTEXT                   *ThunkContext
  )
{
  EFI_STATUS                      Status;
  EFI_HII_CONFIG_ACCESS_PROTOCOL  *ConfigAccess;
  HII_VENDOR_DEVICE_PATH          *HiiVendorPath;

  Status = gBS->HandleProtocol (
                  ThunkContext->UefiHiiDriverHandle,
                  &gEfiHiiConfigAccessProtocolGuid,
                  (VOID **) &ConfigAccess
                  );
  ASSERT_EFI_ERROR (Status);

  Status = gBS->HandleProtocol (
                  ThunkContext->UefiHiiDriverHandle,
                  &gEfiDevicePathProtocolGuid,
                  (VOID **) &HiiVendorPath
                  );
  ASSERT_EFI_ERROR (Status);

  Status = gBS->UninstallMultipleProtocolInterfaces (
                  ThunkContext->UefiHiiDriverHandle,
                  &gEfiDevicePathProtocolGuid,
                  HiiVendorPath,
                  &gEfiHiiConfigAccessProtocolGuid,
                  ConfigAccess,
                  NULL
                  );
  ASSERT_EFI_ERROR (Status);

}
  

/**
   Wrap the EFI_HII_CONFIG_ACCESS_PROTOCOL.ExtractConfig to a call to EFI_FORM_CALLBACK_PROTOCOL.NvRead.
   
   @param BufferStorage         The key with all attributes needed to call EFI_FORM_CALLBACK_PROTOCOL.NvRead.
   @param FwFormCallBack    The EFI_FORM_CALLBACK_PROTOCOL registered by Framework HII module.
   @param Data                     The data read.
   @param DataSize                 The size of data.
   
   @retval EFI_STATUS              The status returned by the EFI_FORM_CALLBACK_PROTOCOL.NvWrite.
   @retval EFI_INVALID_PARAMETER   If the EFI_FORM_CALLBACK_PROTOCOL.NvRead return the size information of the data
                                   does not match what has been recorded early in he BUFFER_STORAGE_ENTRY.
 **/
EFI_STATUS
CallFormCallBack (
  IN       FORMSET_STORAGE                            *BufferStorage,
  IN       EFI_FORM_CALLBACK_PROTOCOL                 *FwFormCallBack,
  OUT      VOID                                       **Data,
  OUT      UINTN                                      *DataSize
  )
{
  EFI_STATUS          Status;

  *DataSize = 0;
  *Data     = NULL;
  
  Status = FwFormCallBack->NvRead (
              FwFormCallBack,  
              BufferStorage->Name,
              &BufferStorage->Guid,
              NULL,
              DataSize,
              *Data
              );
  if (Status == EFI_BUFFER_TOO_SMALL) {
    if (BufferStorage->Size != *DataSize) {
      ASSERT (FALSE);
      return EFI_INVALID_PARAMETER;
    }

    *Data = AllocateZeroPool (*DataSize);
    if (*Data == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }

    Status = FwFormCallBack->NvRead (
                  FwFormCallBack,  
                  BufferStorage->Name,
                  &BufferStorage->Guid,
                  NULL,
                  DataSize,
                  *Data
                  );
  }

  return Status;
}


/**
   Wrap the EFI_HII_CONFIG_ACCESS_PROTOCOL.ExtractConfig to a call to UEFI Variable Get Service.
   
   @param BufferStorage        The key with all attributes needed to call a UEFI Variable Get Service.
   @param Data                    The data read.
   @param DataSize                The size of data.

   If the UEFI Variable Get Service return the size information of the data
   does not match what has been recorded early in he BUFFER_STORAGE_ENTRY.
   then ASSERT.
                                                        
   @retval EFI_STATUS              The status returned by the UEFI Variable Get Service.
   @retval EFI_INVALID_PARAMETER   If the UEFI Variable Get Service return the size information of the data
                                   does not match what has been recorded early in he BUFFER_STORAGE_ENTRY.
 **/

EFI_STATUS
GetUefiVariable (
  IN       FORMSET_STORAGE                            *BufferStorage,
  OUT      VOID                                       **Data,
  OUT      UINTN                                      *DataSize
  )
{
  EFI_STATUS          Status;

  *DataSize = 0;
  *Data = NULL;
  Status = gRT->GetVariable (
              BufferStorage->Name,
              &BufferStorage->Guid,
              NULL,
              DataSize,
              *Data
              );
  if (Status == EFI_BUFFER_TOO_SMALL) {

    if (BufferStorage->Size != *DataSize) {
      ASSERT (FALSE);
      return EFI_INVALID_PARAMETER;
    }

    *Data = AllocateZeroPool (*DataSize);
    if (*Data == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }

    Status = gRT->GetVariable (
                BufferStorage->Name,
                &BufferStorage->Guid,
                NULL,
                DataSize,
                *Data
                );
  }

  return Status;
}

/**

  This function implement the EFI_HII_CONFIG_ACCESS_PROTOCOL.ExtractConfig
  so that data can be read from the data storage such as UEFI Variable or module's
  customized storage exposed by EFI_FRAMEWORK_CALLBACK.

   @param This        Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL
   @param Request     A null-terminated Unicode string in <ConfigRequest> format. Note that this
                      includes the routing information as well as the configurable name / value pairs. It is
                      invalid for this string to be in <MultiConfigRequest> 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_INVALID_PARAMETER   If there is no Buffer Storage for this Config Access instance.
   @retval EFI_SUCCESS             The setting is retrived successfully.
   @retval !EFI_SUCCESS            The error returned by UEFI Get Variable or Framework Form Callback Nvread.
 **/
EFI_STATUS
EFIAPI
ThunkExtractConfig (
  IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL   *This,
  IN  CONST EFI_STRING                       Request,
  OUT EFI_STRING                             *Progress,
  OUT EFI_STRING                             *Results
  )
{
  EFI_STATUS                                  Status;
  CONFIG_ACCESS_PRIVATE                       *ConfigAccess;
  FORMSET_STORAGE                             *BufferStorage;
  VOID                                        *Data;
  UINTN                                       DataSize;

  if (Request == NULL) {
    return EFI_NOT_FOUND;
  }

  Data = NULL;
  ConfigAccess = CONFIG_ACCESS_PRIVATE_FROM_PROTOCOL (This);

  BufferStorage = GetStorageFromConfigString (ConfigAccess->ThunkContext->FormSet, Request);

  if (BufferStorage == NULL) {
    *Progress = (EFI_STRING) Request;
    return EFI_NOT_FOUND;
  }

  if (ConfigAccess->ThunkContext->NvMapOverride == NULL) {
    //
    // NvMapOverride is not used. Get the Storage data from EFI Variable or Framework Form Callback.
    //
    if (ConfigAccess->FormCallbackProtocol == NULL ||
        ConfigAccess->FormCallbackProtocol->NvRead == NULL) {
      Status = GetUefiVariable (
                 BufferStorage,
                 &Data,
                 &DataSize
                 );
    } else {
      Status = CallFormCallBack (
                 BufferStorage,
                 ConfigAccess->FormCallbackProtocol,
                  &Data,
                  &DataSize
                 );
    }
  } else {
    //
    // Use the NvMapOverride.
    //
    DataSize = BufferStorage->Size;
    Data = AllocateCopyPool (DataSize, ConfigAccess->ThunkContext->NvMapOverride);
    
    if (Data != NULL) {
      Status = EFI_SUCCESS;
    } else {
      Status = EFI_OUT_OF_RESOURCES;
    }
  }
  
  if (!EFI_ERROR (Status)) {
    Status = mHiiConfigRoutingProtocol->BlockToConfig (
                                            mHiiConfigRoutingProtocol,
                                            Request,
                                            Data,
                                            DataSize,
                                            Results,
                                            Progress
                                            );
  }

  if (Data != NULL) {
    FreePool (Data);
  }
  return Status;
}

/**
  This function implement the EFI_HII_CONFIG_ACCESS_PROTOCOL.RouteConfig
  so that data can be written to the data storage such as UEFI Variable or module's
  customized storage exposed by EFI_FRAMEWORK_CALLBACK.
   
   @param This             Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL
   @param Configuration    A null-terminated Unicode string in <ConfigResp> 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_INVALID_PARAMETER   If there is no Buffer Storage for this Config Access instance.
   @retval EFI_SUCCESS             The setting is saved successfully.
   @retval !EFI_SUCCESS            The error returned by UEFI Set Variable or Framework Form Callback Nvwrite.
**/   
EFI_STATUS
EFIAPI
ThunkRouteConfig (
  IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL   *This,
  IN  CONST EFI_STRING                       Configuration,
  OUT EFI_STRING                             *Progress
  )
{
  EFI_STATUS                                  Status;
  CONFIG_ACCESS_PRIVATE                       *ConfigAccess;
  FORMSET_STORAGE                             *BufferStorage;
  VOID                                        *Data;
  UINTN                                       DataSize;
  UINTN                                       DataSize2;
  BOOLEAN                                     ResetRequired;
  BOOLEAN                                     DataAllocated;

  if (Configuration == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  Data = NULL;
  ConfigAccess = CONFIG_ACCESS_PRIVATE_FROM_PROTOCOL (This);

  BufferStorage = GetStorageFromConfigString (ConfigAccess->ThunkContext->FormSet, Configuration);

  if (BufferStorage == NULL) {
    *Progress = Configuration;
    return EFI_NOT_FOUND;
  }

  DataSize2     = BufferStorage->Size;
  if (ConfigAccess->ThunkContext->NvMapOverride == NULL) {
    DataAllocated = TRUE;
    if (ConfigAccess->FormCallbackProtocol == NULL ||
        ConfigAccess->FormCallbackProtocol->NvRead == NULL) {
      Status = GetUefiVariable (
                 BufferStorage,
                 &Data,
                 &DataSize
                 );
    } else {
      Status = CallFormCallBack (
                 BufferStorage,
                 ConfigAccess->FormCallbackProtocol,
                  &Data,
                  &DataSize
                 );
    }
  } else {
    //
    // ConfigToBlock will convert the Config String and update the NvMapOverride accordingly.
    //
    Status = EFI_SUCCESS;
    Data = ConfigAccess->ThunkContext->NvMapOverride;
    DataSize      = DataSize2;
    DataAllocated = FALSE;
  }  
  if (EFI_ERROR (Status) || (DataSize2 != DataSize)) {
    if (Data == NULL) {
      Data = AllocateZeroPool (DataSize2);
    }
  }

  DataSize = DataSize2;
  Status = mHiiConfigRoutingProtocol->ConfigToBlock (
                                          mHiiConfigRoutingProtocol,
                                          Configuration,
                                          Data,
                                          &DataSize,
                                          Progress
                                          );
  if (EFI_ERROR (Status)) {
    goto Done;
  }
  
  if (ConfigAccess->ThunkContext->NvMapOverride == NULL) {
    if (ConfigAccess->FormCallbackProtocol == NULL ||
        ConfigAccess->FormCallbackProtocol->NvWrite == NULL) {
      Status = gRT->SetVariable (
                    BufferStorage->Name,
                    &BufferStorage->Guid,
                    EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
                    DataSize2,
                    Data
                    );
    } else {
      Status = ConfigAccess->FormCallbackProtocol->NvWrite (
                    ConfigAccess->FormCallbackProtocol,  
                    BufferStorage->Name,
                    &BufferStorage->Guid,
                    EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
                    DataSize2,
                    Data,
                    &ResetRequired
                    );
    }
  }

Done: 
  if (DataAllocated && (Data != NULL)) {
    FreePool (Data);
  }
  
  return Status;
}

/**
  Build the EFI_IFR_DATA_ARRAY which will be used to pass to 
  EFI_FORM_CALLBACK_PROTOCOL.Callback. Check definition of EFI_IFR_DATA_ARRAY
  for details.

  ASSERT if the Question Type is not EFI_IFR_TYPE_NUM_SIZE_* or EFI_IFR_TYPE_STRING.
  
   @param This             Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL
   @param QuestionId       The Question ID.
   @param Type             The Question Type.
   @param Value            The Question Value.
   @param NvMapAllocated   On output indicates if a buffer is allocated for NvMap.
   
   @return A pointer to EFI_IFR_DATA_ARRAY. The caller must free this buffer allocated.
**/   
EFI_IFR_DATA_ARRAY *
CreateIfrDataArray (
  IN    CONFIG_ACCESS_PRIVATE         *ConfigAccess,
  IN    EFI_QUESTION_ID               QuestionId,
  IN    UINT8                         Type,
  IN    EFI_IFR_TYPE_VALUE            *Value,
  OUT   BOOLEAN                       *NvMapAllocated
  )
{
  EFI_IFR_DATA_ARRAY                *IfrDataArray;
  EFI_IFR_DATA_ENTRY                *IfrDataEntry;
  UINTN                             BrowserDataSize;
  FORMSET_STORAGE                   *BufferStorage;
  UINTN                             Size;
  EFI_STRING                        String;
  FORM_BROWSER_STATEMENT            *Statement;

  *NvMapAllocated = FALSE;

  String = NULL;

  switch (Type) {
    case EFI_IFR_TYPE_NUM_SIZE_8:
    case EFI_IFR_TYPE_NUM_SIZE_16:
    case EFI_IFR_TYPE_NUM_SIZE_32:
    case EFI_IFR_TYPE_NUM_SIZE_64:
    case EFI_IFR_TYPE_BOOLEAN:
      Size = sizeof (*Value);
      break;

    case EFI_IFR_TYPE_STRING:
      if (Value->string == 0) {
        Size = 0;
      } else {
        String = HiiGetString (ConfigAccess->ThunkContext->UefiHiiHandle, Value->string, NULL);
        ASSERT (String != NULL);

        Size = StrSize (String);
      }
      break;
      
    default:
      ASSERT (FALSE);
      Size = 0;
      break;
  }

  IfrDataArray = AllocateZeroPool (sizeof (EFI_IFR_DATA_ARRAY) + sizeof (EFI_IFR_DATA_ENTRY) + Size);
  ASSERT (IfrDataArray != NULL);
  IfrDataArray->EntryCount = 1;
  IfrDataEntry             = (EFI_IFR_DATA_ENTRY *) (IfrDataArray + 1);

  Statement = GetStorageFromQuestionId (ConfigAccess->ThunkContext->FormSet, QuestionId);

  if (Statement == NULL || Statement->Storage == NULL) {
    //
    // The QuestionId is not associated with a Buffer Storage.
    // Try to get the first Buffer Storage then.
    //
    BufferStorage = GetFirstStorageOfFormSet (ConfigAccess->ThunkContext->FormSet);
  } else {
    BufferStorage        = Statement->Storage;
    IfrDataEntry->OpCode = Statement->Operand;
  }
  
  if (BufferStorage != NULL) {
    BrowserDataSize      = BufferStorage->Size;
    IfrDataEntry->Length = (UINT8) (sizeof (EFI_IFR_DATA_ENTRY) + Size);

    if (ConfigAccess->ThunkContext->NvMapOverride == NULL) {
      *NvMapAllocated = TRUE;
      IfrDataArray->NvRamMap = AllocateZeroPool (BrowserDataSize);
    } else {
      *NvMapAllocated = FALSE;
      IfrDataArray->NvRamMap = ConfigAccess->ThunkContext->NvMapOverride;
    }
    
    ASSERT (HiiGetBrowserData (&BufferStorage->Guid, BufferStorage->Name, BrowserDataSize, (UINT8 *) IfrDataArray->NvRamMap));

    switch (Type) {
      case EFI_IFR_TYPE_NUM_SIZE_8:
      case EFI_IFR_TYPE_NUM_SIZE_16:
      case EFI_IFR_TYPE_NUM_SIZE_32:
      case EFI_IFR_TYPE_NUM_SIZE_64:
      case EFI_IFR_TYPE_BOOLEAN:
        CopyMem (&IfrDataEntry->Data, &(Value->u8), sizeof (*Value));
        break;

      case EFI_IFR_TYPE_STRING:
        if (Size != 0) {
          ASSERT (String != NULL);
          StrCpy ((CHAR16 *) &IfrDataEntry->Data, String);
          FreePool (String);
        }
        break;
      default:
        ASSERT (FALSE);
        break;
    }

    //
    // Need to fiil in the information for the rest of field for EFI_IFR_DATA_ENTRY.
    // It seems that no implementation is found to use other fields. Leave them uninitialized for now.
    //
    //UINT8   OpCode;           // Likely a string, numeric, or one-of
    //UINT8   Length;           // Length of the EFI_IFR_DATA_ENTRY packet
    //UINT16  Flags;            // Flags settings to determine what behavior is desired from the browser after the callback
    //VOID    *Data;            // The data in the form based on the op-code type - this is not a pointer to the data, the data follows immediately
    // If the OpCode is a OneOf or Numeric type - Data is a UINT16 value
    // If the OpCode is a String type - Data is a CHAR16[x] type
    // If the OpCode is a Checkbox type - Data is a UINT8 value
    // If the OpCode is a NV Access type - Data is a FRAMEWORK_EFI_IFR_NV_DATA structure
  }

  return IfrDataArray;
}

/**
  If a NvMapOverride is passed in to EFI_FORM_BROWSER_PROTOCOL.SendForm, the Form Browser
  needs to be informed when data changed in NvMapOverride. This function will invoke
  SetBrowserData () to set internal data of Form Browser.

  @param  ConfigAccess   The Config Access Private Context.
  @param  QuestionId     The Question Id that invokes the callback.
  

**/
VOID
SyncBrowserDataForNvMapOverride (
  IN    CONST CONFIG_ACCESS_PRIVATE         *ConfigAccess,
  IN          EFI_QUESTION_ID               QuestionId
  )
{
  FORMSET_STORAGE   *BufferStorage;
  BOOLEAN           CheckFlag;
  UINTN             BrowserDataSize;
  FORM_BROWSER_STATEMENT *Statement;

  if (ConfigAccess->ThunkContext->NvMapOverride != NULL) {

    Statement = GetStorageFromQuestionId (ConfigAccess->ThunkContext->FormSet, QuestionId);

    if (Statement == NULL || Statement->Storage == NULL) {
      //
      // QuestionId is a statement without Storage.
      // 1) It is a Goto. 
      // 
      //
      BufferStorage = GetFirstStorageOfFormSet (ConfigAccess->ThunkContext->FormSet);
    } else {
      BufferStorage = Statement->Storage;
    }

    //
    // If NvMapOverride is not NULL, this Form must have at least one Buffer Type Variable Storage.
    //
    ASSERT (BufferStorage != NULL);
    
    BrowserDataSize = BufferStorage->Size;

    CheckFlag = HiiSetBrowserData (&BufferStorage->Guid, BufferStorage->Name, BrowserDataSize, ConfigAccess->ThunkContext->NvMapOverride, NULL);
    ASSERT (CheckFlag);
  }

}

/**
  Free up resource allocated for a EFI_IFR_DATA_ARRAY by CreateIfrDataArray ().

  @param Array              The EFI_IFR_DATA_ARRAY allocated.
  @param NvMapAllocated     If the NvRamMap is allocated for EFI_IFR_DATA_ARRAY.

**/
VOID
DestroyIfrDataArray (
  IN  EFI_IFR_DATA_ARRAY           *Array,
  IN  BOOLEAN                      NvMapAllocated
  )
{
  if (Array != NULL) {
    if (NvMapAllocated) {
      FreePool (Array->NvRamMap);
    }

    FreePool (Array);
  }
}

/**
  Get the ONE_OF_OPTION_MAP_ENTRY for a QuestionId that invokes the 
  EFI_FORM_CALLBACK_PROTOCOL.Callback. The information is needed as
  the callback mechanism for EFI_IFR_ONE_OF_OPTION is changed from 
  EFI_IFR_ONE_OF_OPTION in Framework IFR. Check EFI_IFR_GUID_OPTIONKEY
  for detailed information.

  @param ThunkContext   The Thunk Context.
  @param QuestionId     The Question Id.
  @param Type           The Question Type.
  @param Value          The One Of Option's value.

  @return The ONE_OF_OPTION_MAP_ENTRY found.
  @retval NULL If no entry is found.
**/
ONE_OF_OPTION_MAP_ENTRY *
GetOneOfOptionMapEntry (
  IN  HII_THUNK_CONTEXT              *ThunkContext,
  IN  EFI_QUESTION_ID                QuestionId,
  IN  UINT8                          Type,
  IN  EFI_IFR_TYPE_VALUE             *Value
  )
{
  LIST_ENTRY              *Link;
  LIST_ENTRY              *Link2;
  ONE_OF_OPTION_MAP_ENTRY *OneOfOptionMapEntry;
  ONE_OF_OPTION_MAP       *OneOfOptionMap;
  FORM_BROWSER_FORMSET    *FormSet;

  FormSet = ThunkContext->FormSet;

  Link = GetFirstNode (&FormSet->OneOfOptionMapListHead);

  while (!IsNull (&FormSet->OneOfOptionMapListHead, Link)) {
    OneOfOptionMap = ONE_OF_OPTION_MAP_FROM_LINK(Link);
    if (OneOfOptionMap->QuestionId == QuestionId) {
      ASSERT (OneOfOptionMap->ValueType == Type);

      Link2 = GetFirstNode (&OneOfOptionMap->OneOfOptionMapEntryListHead);

      while (!IsNull (&OneOfOptionMap->OneOfOptionMapEntryListHead, Link2)) {
        OneOfOptionMapEntry = ONE_OF_OPTION_MAP_ENTRY_FROM_LINK (Link2);

        if (CompareMem (Value, &OneOfOptionMapEntry->Value, sizeof (EFI_IFR_TYPE_VALUE)) == 0) {
          return OneOfOptionMapEntry;
        }

        Link2 = GetNextNode (&OneOfOptionMap->OneOfOptionMapEntryListHead, Link2);
      }
    }

    Link = GetNextNode (&FormSet->OneOfOptionMapListHead, Link);
  }


  return NULL;
}

/**
  Functions which are registered to receive notification of
  database events have this prototype. The actual event is encoded
  in NotifyType. The following table describes how PackageType,
  PackageGuid, Handle, and Package are used for each of the
  notification types.

  If any Pakcage List in database is updated, mHiiPackageListUpdated
  will be set. If mHiiPackageListUpdated is set, Framework ThunkCallback()
  will force the UEFI Setup Browser to save the uncommitted data. This
  is needed as Framework's Callback function may dynamically update
  opcode in a Package List. UEFI Setup Browser will quit itself and reparse
  the Package List's IFR and display it. UEFI Config Access's implementation
  is required to save the modified (SetBrowserData or directly save the data
  to NV storage). But Framework HII Modules is not aware of this rule. Therefore,
  we will enforce the rule in ThunkCallback (). The side effect of force saving
  of NV data is the NV flag in browser may not flag a update as data has already
  been saved to NV storage.

  @param PackageType  Package type of the notification.

  @param PackageGuid  If PackageType is
                      EFI_HII_PACKAGE_TYPE_GUID, then this is
                      the pointer to the GUID from the Guid
                      field of EFI_HII_PACKAGE_GUID_HEADER.
                      Otherwise, it must be NULL.

  @param Package  Points to the package referred to by the
                  notification Handle The handle of the package
                  list which contains the specified package.

  @param Handle       The HII handle.

  @param NotifyType   The type of change concerning the
                      database. See
                      EFI_HII_DATABASE_NOTIFY_TYPE.

**/
EFI_STATUS
EFIAPI
FormUpdateNotify (
  IN UINT8                              PackageType,
  IN CONST EFI_GUID                     *PackageGuid,
  IN CONST EFI_HII_PACKAGE_HEADER       *Package,
  IN EFI_HII_HANDLE                     Handle,
  IN EFI_HII_DATABASE_NOTIFY_TYPE       NotifyType
  )
{
  mHiiPackageListUpdated = TRUE;

  return EFI_SUCCESS;
}

/**
  Wrap the EFI_HII_CONFIG_ACCESS_PROTOCOL.CallBack to EFI_FORM_CALLBACK_PROTOCOL.Callback. Therefor,
  the framework HII module willl do no porting and work with a UEFI HII SetupBrowser.
   
   @param This                      Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
   @param Action                    Specifies the type of action taken by the browser. See EFI_BROWSER_ACTION_x.
   @param QuestionId                A unique value which is sent to the original exporting driver so that it can identify the
                                    type of data to expect. The format of the data tends to vary based on the opcode that
                                    generated the callback.
   @param Type                      The type of value for the question. See EFI_IFR_TYPE_x in
                                    EFI_IFR_ONE_OF_OPTION.
   @param Value                     A pointer to the data being sent to the original exporting driver. The type is specified
                                    by Type. Type EFI_IFR_TYPE_VALUE is defined in
                                    EFI_IFR_ONE_OF_OPTION.
   @param ActionRequest             On return, points to the action requested by the callback function. Type
                                    EFI_BROWSER_ACTION_REQUEST is specified in SendForm() in the Form
                                    Browser Protocol.
   
   @retval EFI_UNSUPPORTED        If the Framework HII module does not register Callback although it specify the opcode under
                                  focuse to be INTERRACTIVE.
   @retval EFI_SUCCESS            The callback complete successfully.
   @retval !EFI_SUCCESS           The error code returned by EFI_FORM_CALLBACK_PROTOCOL.Callback.
   
 **/
EFI_STATUS
EFIAPI
ThunkCallback (
  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
  )
{
  EFI_STATUS                                  Status;
  CONFIG_ACCESS_PRIVATE                       *ConfigAccess;
  EFI_FORM_CALLBACK_PROTOCOL                  *FormCallbackProtocol;
  EFI_HII_CALLBACK_PACKET                     *Packet;
  EFI_IFR_DATA_ARRAY                          *Data;
  EFI_IFR_DATA_ENTRY                          *DataEntry;
  UINT16                                      KeyValue;
  ONE_OF_OPTION_MAP_ENTRY                     *OneOfOptionMapEntry;
  EFI_HANDLE                                  NotifyHandle;
  EFI_INPUT_KEY                               Key;  
  BOOLEAN                                     NvMapAllocated;

  ASSERT (This != NULL);
  ASSERT (Value != NULL);
  ASSERT (ActionRequest != NULL);

  *ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;

  ConfigAccess = CONFIG_ACCESS_PRIVATE_FROM_PROTOCOL (This);

  FormCallbackProtocol = ConfigAccess->FormCallbackProtocol;
  if (FormCallbackProtocol == NULL) {
    ASSERT (FALSE);
    return EFI_UNSUPPORTED;
  }

  //
  // Check if the QuestionId match a OneOfOption.
  //
  OneOfOptionMapEntry = GetOneOfOptionMapEntry (ConfigAccess->ThunkContext, QuestionId, Type, Value);

  if (OneOfOptionMapEntry == NULL) {
    //
    // This is not a One-Of-Option opcode. QuestionId is the KeyValue
    //
    KeyValue = QuestionId;
  } else {
    //
    // Otherwise, use the original Key specified in One Of Option in the Framework VFR syntax.
    //
    KeyValue = OneOfOptionMapEntry->FwKey;
  }

  //
  // Build the EFI_IFR_DATA_ARRAY
  //
  Data = CreateIfrDataArray (ConfigAccess, QuestionId, Type, Value, &NvMapAllocated);

  Status = mHiiDatabase->RegisterPackageNotify (
                           mHiiDatabase,
                           EFI_HII_PACKAGE_FORMS,
                           NULL,
                           FormUpdateNotify,
                           EFI_HII_DATABASE_NOTIFY_REMOVE_PACK,
                           &NotifyHandle
                           );
  //
  //Call the Framework Callback function.
  //
  Packet =  NULL;
  Status =  FormCallbackProtocol->Callback (
              FormCallbackProtocol,
              KeyValue,
              Data,
              &Packet
              );
  SyncBrowserDataForNvMapOverride (ConfigAccess, QuestionId);

  //
  // Callback require browser to perform action
  //
  if (EFI_ERROR (Status)) {
    if (Packet != NULL) {
      do {
        CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, Packet->String, NULL);
      } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
    }
    //
    // Error Code in Status is discarded.
    //
  } else {
    if (Packet != NULL) {
        if (Packet->DataArray.EntryCount  == 1 && Packet->DataArray.NvRamMap == NULL) {
          DataEntry = (EFI_IFR_DATA_ENTRY *) ((UINT8 *) Packet + sizeof (EFI_IFR_DATA_ARRAY));
          if ((DataEntry->Flags & EXIT_REQUIRED) == EXIT_REQUIRED) {
              *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;
          }

          if ((DataEntry->Flags & SAVE_REQUIRED) == SAVE_REQUIRED) {
            Status = ConfigAccess->ConfigAccessProtocol.RouteConfig (
                                      &ConfigAccess->ConfigAccessProtocol,
                                      NULL,
                                      NULL
                                      );
          }
        }
        FreePool (Packet);
    }
  }

  //
  // Unregister notify for Form package update
  //
  Status = mHiiDatabase->UnregisterPackageNotify (
                           mHiiDatabase,
                           NotifyHandle
                           );
  //
  // UEFI SetupBrowser behaves differently with Framework SetupBrowser when call back function 
  // update any forms in HII database. UEFI SetupBrowser will re-parse the displaying form package and load
  // the values from variable storages. Framework SetupBrowser will only re-parse the displaying form packages.
  // To make sure customer's previous changes is saved and the changing question behaves as expected, we
  // issue a EFI_BROWSER_ACTION_REQUEST_SUBMIT to ask UEFI SetupBrowser to save the changes proceed to re-parse
  // the form and load all the variable storages.
  //
  if (*ActionRequest == EFI_BROWSER_ACTION_REQUEST_NONE && mHiiPackageListUpdated) {
    mHiiPackageListUpdated= FALSE;
    *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT;
  } else {
    if (ConfigAccess->ThunkContext->FormSet->SubClass == EFI_FRONT_PAGE_SUBCLASS ||
        ConfigAccess->ThunkContext->FormSet->SubClass == EFI_SINGLE_USE_SUBCLASS) {
      *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;
    }
  }


  //
  // Clean up.
  //
  DestroyIfrDataArray (Data, NvMapAllocated);
  
  return Status;
}

