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