/** @file
Implementation of interfaces function for EFI_HII_CONFIG_ROUTING_PROTOCOL.

Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2025, Loongson Technology Corporation Limited. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "HiiDatabase.h"
extern HII_DATABASE_PRIVATE_DATA  mPrivate;

/**
  Calculate the number of Unicode characters of the incoming Configuration string,
  not including NULL terminator.

  This is a internal function.

  @param  String                 String in <MultiConfigRequest> or
                                 <MultiConfigResp> format.

  @return The number of Unicode characters.

**/
UINTN
CalculateConfigStringLen (
  IN EFI_STRING  String
  )
{
  EFI_STRING  TmpPtr;

  //
  // "GUID=" should be the first element of incoming string.
  //
  ASSERT (String != NULL);
  ASSERT (StrnCmp (String, L"GUID=", StrLen (L"GUID=")) == 0);

  //
  // The beginning of next <ConfigRequest>/<ConfigResp> should be "&GUID=".
  // Will meet '\0' if there is only one <ConfigRequest>/<ConfigResp>.
  //
  TmpPtr = StrStr (String, L"&GUID=");
  if (TmpPtr == NULL) {
    return StrLen (String);
  }

  return (TmpPtr - String);
}

/**
  Convert the hex UNICODE %02x encoding of a UEFI device path to binary
  from <PathHdr> of <ConfigHdr>.

  This is a internal function.

  @param  String                 UEFI configuration string
  @param  DevicePathData         Binary of a UEFI device path.

  @retval EFI_NOT_FOUND          The device path is not invalid.
  @retval EFI_INVALID_PARAMETER  Any incoming parameter is invalid.
  @retval EFI_OUT_OF_RESOURCES   Lake of resources to store necessary structures.
  @retval EFI_SUCCESS            The device path is retrieved and translated to
                                 binary format.

**/
EFI_STATUS
GetDevicePath (
  IN  EFI_STRING  String,
  OUT UINT8       **DevicePathData
  )
{
  UINTN                     Length;
  EFI_STRING                PathHdr;
  UINT8                     *DevicePathBuffer;
  CHAR16                    TemStr[2];
  UINTN                     Index;
  UINT8                     DigitUint8;
  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;

  if ((String == NULL) || (DevicePathData == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Find the 'PATH=' of <PathHdr> and skip it.
  //
  for ( ; (*String != 0 && StrnCmp (String, L"PATH=", StrLen (L"PATH=")) != 0); String++) {
  }

  if (*String == 0) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Check whether path data does exist.
  //
  String += StrLen (L"PATH=");
  if (*String == 0) {
    return EFI_INVALID_PARAMETER;
  }

  PathHdr = String;

  //
  // The content between 'PATH=' of <ConfigHdr> and '&' of next element
  // or '\0' (end of configuration string) is the UNICODE %02x bytes encoding
  // of UEFI device path.
  //
  for (Length = 0; *String != 0 && *String != L'&'; String++, Length++) {
  }

  //
  // Check DevicePath Length
  //
  if (((Length + 1) / 2) < sizeof (EFI_DEVICE_PATH_PROTOCOL)) {
    return EFI_NOT_FOUND;
  }

  //
  // The data in <PathHdr> is encoded as hex UNICODE %02x bytes in the same order
  // as the device path resides in RAM memory.
  // Translate the data into binary.
  //
  DevicePathBuffer = (UINT8 *)AllocateZeroPool ((Length + 1) / 2);
  if (DevicePathBuffer == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  //
  // Convert DevicePath
  //
  ZeroMem (TemStr, sizeof (TemStr));
  for (Index = 0; Index < Length; Index++) {
    TemStr[0]  = PathHdr[Index];
    DigitUint8 = (UINT8)StrHexToUint64 (TemStr);
    if ((Index & 1) == 0) {
      DevicePathBuffer[Index/2] = DigitUint8;
    } else {
      DevicePathBuffer[Index/2] = (UINT8)((DevicePathBuffer[Index/2] << 4) + DigitUint8);
    }
  }

  //
  // Validate DevicePath
  //
  DevicePath = (EFI_DEVICE_PATH_PROTOCOL *)DevicePathBuffer;
  while (!IsDevicePathEnd (DevicePath)) {
    if ((DevicePath->Type == 0) || (DevicePath->SubType == 0) || (DevicePathNodeLength (DevicePath) < sizeof (EFI_DEVICE_PATH_PROTOCOL))) {
      //
      // Invalid device path
      //
      FreePool (DevicePathBuffer);
      return EFI_NOT_FOUND;
    }

    DevicePath = NextDevicePathNode (DevicePath);
  }

  //
  // return the device path
  //
  *DevicePathData = DevicePathBuffer;
  return EFI_SUCCESS;
}

/**
  Converts the unicode character of the string from uppercase to lowercase.
  This is a internal function.

  @param ConfigString  String to be converted

**/
VOID
EFIAPI
HiiToLower (
  IN EFI_STRING  ConfigString
  )
{
  EFI_STRING  String;
  BOOLEAN     Lower;

  ASSERT (ConfigString != NULL);

  //
  // Convert all hex digits in range [A-F] in the configuration header to [a-f]
  //
  for (String = ConfigString, Lower = FALSE; *String != L'\0'; String++) {
    if (*String == L'=') {
      Lower = TRUE;
    } else if (*String == L'&') {
      Lower = FALSE;
    } else if (Lower && (*String >= L'A') && (*String <= L'F')) {
      *String = (CHAR16)(*String - L'A' + L'a');
    }
  }

  return;
}

/**
  Generate a sub string then output it.

  This is a internal function.

  @param  String                 A constant string which is the prefix of the to be
                                 generated string, e.g. GUID=

  @param  BufferLen              The length of the Buffer in bytes.

  @param  Buffer                 Points to a buffer which will be converted to be the
                                 content of the generated string.

  @param  Flag                   If 1, the buffer contains data for the value of GUID or PATH stored in
                                 UINT8 *; if 2, the buffer contains unicode string for the value of NAME;
                                 if 3, the buffer contains other data.

  @param  SubStr                 Points to the output string. It's caller's
                                 responsibility to free this buffer.


**/
VOID
GenerateSubStr (
  IN CONST EFI_STRING  String,
  IN  UINTN            BufferLen,
  IN  VOID             *Buffer,
  IN  UINT8            Flag,
  OUT EFI_STRING       *SubStr
  )
{
  UINTN       Length;
  EFI_STRING  Str;
  EFI_STRING  StringHeader;
  CHAR16      *TemString;
  CHAR16      *TemName;
  UINT8       *TemBuffer;
  UINTN       Index;

  ASSERT (String != NULL && SubStr != NULL);

  if (Buffer == NULL) {
    *SubStr = AllocateCopyPool (StrSize (String), String);
    ASSERT (*SubStr != NULL);
    return;
  }

  //
  // Header + Data + '&' + '\0'
  //
  Length = StrLen (String) + BufferLen * 2 + 1 + 1;
  Str    = AllocateZeroPool (Length * sizeof (CHAR16));
  ASSERT (Str != NULL);

  StrCpyS (Str, Length, String);

  StringHeader = Str + StrLen (String);
  TemString    = (CHAR16 *)StringHeader;

  switch (Flag) {
    case 1:
      //
      // Convert Buffer to Hex String in reverse order
      //
      TemBuffer = ((UINT8 *)Buffer);
      for (Index = 0; Index < BufferLen; Index++, TemBuffer++) {
        UnicodeValueToStringS (
          TemString,
          sizeof (CHAR16) * (Length - StrnLenS (Str, Length)),
          PREFIX_ZERO | RADIX_HEX,
          *TemBuffer,
          2
          );
        TemString += StrnLenS (TemString, Length - StrnLenS (Str, Length));
      }

      break;
    case 2:
      //
      // Check buffer is enough
      //
      TemName = (CHAR16 *)Buffer;
      ASSERT ((BufferLen * 2 + 1) >= (StrLen (TemName) * 4 + 1));
      //
      // Convert Unicode String to Config String, e.g. "ABCD" => "0041004200430044"
      //
      for ( ; *TemName != L'\0'; TemName++) {
        UnicodeValueToStringS (
          TemString,
          sizeof (CHAR16) * (Length - StrnLenS (Str, Length)),
          PREFIX_ZERO | RADIX_HEX,
          *TemName,
          4
          );
        TemString += StrnLenS (TemString, Length - StrnLenS (Str, Length));
      }

      break;
    case 3:
      //
      // Convert Buffer to Hex String
      //
      TemBuffer = ((UINT8 *)Buffer) + BufferLen - 1;
      for (Index = 0; Index < BufferLen; Index++, TemBuffer--) {
        UnicodeValueToStringS (
          TemString,
          sizeof (CHAR16) * (Length - StrnLenS (Str, Length)),
          PREFIX_ZERO | RADIX_HEX,
          *TemBuffer,
          2
          );
        TemString += StrnLenS (TemString, Length - StrnLenS (Str, Length));
      }

      break;
    default:
      break;
  }

  //
  // Convert the uppercase to lowercase since <HexAf> is defined in lowercase format.
  //
  StrCatS (Str, Length, L"&");
  HiiToLower (Str);

  *SubStr = Str;
}

/**
  Retrieve the <ConfigBody> from String then output it.

  This is a internal function.

  @param  String                 A sub string of a configuration string in
                                 <MultiConfigAltResp> format.
  @param  ConfigBody             Points to the output string. It's caller's
                                 responsibility to free this buffer.

  @retval EFI_INVALID_PARAMETER  There is no form package in current hii database.
  @retval EFI_OUT_OF_RESOURCES   Not enough memory to finish this operation.
  @retval EFI_SUCCESS            All existing storage is exported.

**/
EFI_STATUS
OutputConfigBody (
  IN  EFI_STRING  String,
  OUT EFI_STRING  *ConfigBody
  )
{
  EFI_STRING  TmpPtr;
  EFI_STRING  Result;
  UINTN       Length;

  if ((String == NULL) || (ConfigBody == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // The setting information should start OFFSET, not ALTCFG.
  //
  if (StrnCmp (String, L"&ALTCFG=", StrLen (L"&ALTCFG=")) == 0) {
    return EFI_INVALID_PARAMETER;
  }

  TmpPtr = StrStr (String, L"GUID=");
  if (TmpPtr == NULL) {
    //
    // It is the last <ConfigResp> of the incoming configuration string.
    //
    Result = AllocateCopyPool (StrSize (String), String);
    if (Result == NULL) {
      return EFI_OUT_OF_RESOURCES;
    } else {
      *ConfigBody = Result;
      return EFI_SUCCESS;
    }
  }

  Length = TmpPtr - String;
  if (Length == 0) {
    return EFI_NOT_FOUND;
  }

  Result = AllocateCopyPool (Length * sizeof (CHAR16), String);
  if (Result == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  *(Result + Length - 1) = 0;
  *ConfigBody            = Result;
  return EFI_SUCCESS;
}

/**
  Append a string to a multi-string format.

  This is a internal function.

  @param  MultiString            String in <MultiConfigRequest>,
                                 <MultiConfigAltResp>, or <MultiConfigResp>. On
                                 input, the buffer length of  this string is
                                 MAX_STRING_LENGTH. On output, the  buffer length
                                 might be updated.
  @param  AppendString           NULL-terminated Unicode string.

  @retval EFI_INVALID_PARAMETER  Any incoming parameter is invalid.
  @retval EFI_SUCCESS            AppendString is append to the end of MultiString

**/
EFI_STATUS
AppendToMultiString (
  IN OUT EFI_STRING  *MultiString,
  IN EFI_STRING      AppendString
  )
{
  UINTN  AppendStringSize;
  UINTN  MultiStringSize;
  UINTN  MaxLen;

  if ((MultiString == NULL) || (*MultiString == NULL) || (AppendString == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  AppendStringSize = StrSize (AppendString);
  MultiStringSize  = StrSize (*MultiString);
  MaxLen           = MAX_STRING_LENGTH / sizeof (CHAR16);

  //
  // Enlarge the buffer each time when length exceeds MAX_STRING_LENGTH.
  //
  if ((MultiStringSize + AppendStringSize > MAX_STRING_LENGTH) ||
      (MultiStringSize > MAX_STRING_LENGTH))
  {
    *MultiString = (EFI_STRING)ReallocatePool (
                                 MultiStringSize,
                                 MultiStringSize + AppendStringSize,
                                 (VOID *)(*MultiString)
                                 );
    MaxLen = (MultiStringSize + AppendStringSize) / sizeof (CHAR16);
    ASSERT (*MultiString != NULL);
  }

  //
  // Append the incoming string
  //
  StrCatS (*MultiString, MaxLen, AppendString);

  return EFI_SUCCESS;
}

/**
  Get the value of <Number> in <BlockConfig> format, i.e. the value of OFFSET
  or WIDTH or VALUE.
  <BlockConfig> ::= 'OFFSET='<Number>&'WIDTH='<Number>&'VALUE'=<Number>

  This is a internal function.

  @param  StringPtr              String in <BlockConfig> format and points to the
                                 first character of <Number>.
  @param  Number                 The output value. Caller takes the responsibility
                                 to free memory.
  @param  Len                    Length of the <Number>, in characters.

  @retval EFI_OUT_OF_RESOURCES   Insufficient resources to store necessary
                                 structures.
  @retval EFI_SUCCESS            Value of <Number> is outputted in Number
                                 successfully.

**/
EFI_STATUS
GetValueOfNumber (
  IN EFI_STRING  StringPtr,
  OUT UINT8      **Number,
  OUT UINTN      *Len
  )
{
  EFI_STRING  TmpPtr;
  UINTN       Length;
  EFI_STRING  Str;
  UINT8       *Buf;
  EFI_STATUS  Status;
  UINT8       DigitUint8;
  UINTN       Index;
  CHAR16      TemStr[2];

  if ((StringPtr == NULL) || (*StringPtr == L'\0') || (Number == NULL) || (Len == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  Buf = NULL;

  TmpPtr = StringPtr;
  while (*StringPtr != L'\0' && *StringPtr != L'&') {
    StringPtr++;
  }

  *Len   = StringPtr - TmpPtr;
  Length = *Len + 1;

  Str = (EFI_STRING)AllocateZeroPool (Length * sizeof (CHAR16));
  if (Str == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto Exit;
  }

  CopyMem (Str, TmpPtr, *Len * sizeof (CHAR16));
  *(Str + *Len) = L'\0';

  Length = (Length + 1) / 2;
  Buf    = (UINT8 *)AllocateZeroPool (Length);
  if (Buf == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto Exit;
  }

  Length = *Len;
  ZeroMem (TemStr, sizeof (TemStr));
  for (Index = 0; Index < Length; Index++) {
    TemStr[0]  = Str[Length - Index - 1];
    DigitUint8 = (UINT8)StrHexToUint64 (TemStr);
    if ((Index & 1) == 0) {
      Buf[Index/2] = DigitUint8;
    } else {
      Buf[Index/2] = (UINT8)((DigitUint8 << 4) + Buf[Index/2]);
    }
  }

  *Number = Buf;
  Status  = EFI_SUCCESS;

Exit:
  if (Str != NULL) {
    FreePool (Str);
  }

  return Status;
}

/**
 To find the BlockName in the string with same value.

  @param  String                 Pointer to a Null-terminated Unicode string.
  @param  BlockName              Pointer to a Null-terminated Unicode string to search for.
  @param  Buffer                 Pointer to the value correspond to the BlockName.
  @param  Found                  The Block whether has been found.
  @param  BufferLen              The length of the buffer.

  @retval EFI_OUT_OF_RESOURCES   Insufficient resources to store necessary structures.
  @retval EFI_SUCCESS            The function finishes successfully.

**/
EFI_STATUS
FindSameBlockElement (
  IN  EFI_STRING  String,
  IN  EFI_STRING  BlockName,
  IN  UINT8       *Buffer,
  OUT BOOLEAN     *Found,
  IN  UINTN       BufferLen
  )
{
  EFI_STRING  BlockPtr;
  UINTN       Length;
  UINT8       *TempBuffer;
  EFI_STATUS  Status;

  TempBuffer = NULL;
  *Found     = FALSE;
  BlockPtr   = StrStr (String, BlockName);

  while (BlockPtr != NULL) {
    BlockPtr += StrLen (BlockName);
    Status    = GetValueOfNumber (BlockPtr, &TempBuffer, &Length);
    if (EFI_ERROR (Status)) {
      return Status;
    }

    ASSERT (TempBuffer != NULL);
    if ((BufferLen == Length) && (0 == CompareMem (Buffer, TempBuffer, Length))) {
      *Found = TRUE;
      FreePool (TempBuffer);
      TempBuffer = NULL;
      return EFI_SUCCESS;
    } else {
      FreePool (TempBuffer);
      TempBuffer = NULL;
      BlockPtr   = StrStr (BlockPtr + 1, BlockName);
    }
  }

  return EFI_SUCCESS;
}

/**
  Compare the <AltResp> in ConfigAltResp and DefaultAltCfgResp, if the <AltResp>
  in DefaultAltCfgResp but not in ConfigAltResp,add it to the ConfigAltResp.

  @param  DefaultAltCfgResp      Pointer to a null-terminated Unicode string in
                                 <MultiConfigAltResp> format. The default value
                                 string may contain more than one ConfigAltResp
                                 string for the different varstore buffer.
  @param  ConfigAltResp          Pointer to a null-terminated Unicode string in
                                 <ConfigAltResp> format.
  @param  AltConfigHdr           Pointer to a Unicode string in <AltConfigHdr> format.
  @param  ConfigAltRespChanged   Whether the ConfigAltResp has been changed.

  @retval EFI_OUT_OF_RESOURCES   Insufficient resources to store necessary structures.
  @retval EFI_SUCCESS            The function finishes  successfully.

**/
EFI_STATUS
CompareBlockElementDefault (
  IN      EFI_STRING  DefaultAltCfgResp,
  IN OUT  EFI_STRING  *ConfigAltResp,
  IN      EFI_STRING  AltConfigHdr,
  IN OUT  BOOLEAN     *ConfigAltRespChanged
  )
{
  EFI_STATUS  Status;
  EFI_STRING  BlockPtr;
  EFI_STRING  BlockPtrStart;
  EFI_STRING  StringPtr;
  EFI_STRING  AppendString;
  EFI_STRING  AltConfigHdrPtr;
  UINT8       *TempBuffer;
  UINTN       OffsetLength;
  UINTN       AppendSize;
  UINTN       TotalSize;
  BOOLEAN     FoundOffset;

  AppendString = NULL;
  TempBuffer   = NULL;
  //
  // Make BlockPtr point to the first <BlockConfig> with AltConfigHdr in DefaultAltCfgResp.
  //
  AltConfigHdrPtr = StrStr (DefaultAltCfgResp, AltConfigHdr);
  if (AltConfigHdrPtr == NULL ) {
    ASSERT (AltConfigHdrPtr != NULL);
    Status = EFI_OUT_OF_RESOURCES;
    goto Exit;
  }

  BlockPtr = StrStr (AltConfigHdrPtr, L"&OFFSET=");
  if (BlockPtr == NULL) {
    ASSERT (BlockPtr != NULL);
    Status = EFI_OUT_OF_RESOURCES;
    goto Exit;
  }

  //
  // Make StringPtr point to the AltConfigHdr in ConfigAltResp.
  //
  StringPtr = StrStr (*ConfigAltResp, AltConfigHdr);
  if (StringPtr == NULL) {
    ASSERT (StringPtr != NULL);
    Status = EFI_OUT_OF_RESOURCES;
    goto Exit;
  }

  while (BlockPtr != NULL) {
    //
    // Find the "&OFFSET=<Number>" block and get the value of the Number with AltConfigHdr in DefaultAltCfgResp.
    //
    BlockPtrStart = BlockPtr;
    BlockPtr     += StrLen (L"&OFFSET=");
    Status        = GetValueOfNumber (BlockPtr, &TempBuffer, &OffsetLength);
    if (EFI_ERROR (Status)) {
      Status = EFI_OUT_OF_RESOURCES;
      goto Exit;
    }

    //
    // To find the same "&OFFSET=<Number>" block in ConfigAltResp.
    //
    Status = FindSameBlockElement (StringPtr, L"&OFFSET=", TempBuffer, &FoundOffset, OffsetLength);
    if (TempBuffer != NULL) {
      FreePool (TempBuffer);
      TempBuffer = NULL;
    }

    if (EFI_ERROR (Status)) {
      Status = EFI_OUT_OF_RESOURCES;
      goto Exit;
    }

    if (!FoundOffset) {
      //
      // Don't find the same "&OFFSET=<Number>" block in ConfigAltResp.
      // Calculate the size of <BlockConfig>.
      // <BlockConfig>::='OFFSET='<Number>'&WIDTH='<Number>'&VALUE='<Number>.
      //
      BlockPtr = StrStr (BlockPtr + 1, L"&OFFSET=");
      if (BlockPtr != NULL) {
        AppendSize = (BlockPtr - BlockPtrStart) * sizeof (CHAR16);
      } else {
        AppendSize = StrSize (BlockPtrStart);
      }

      //
      // Copy the <BlockConfig> to AppendString.
      //
      if (AppendString == NULL) {
        AppendString = (EFI_STRING)AllocateZeroPool (AppendSize + sizeof (CHAR16));
        if (AppendString == NULL) {
          ASSERT (AppendString != NULL);
          Status = EFI_OUT_OF_RESOURCES;
          goto Exit;
        }

        StrnCatS (AppendString, AppendSize / sizeof (CHAR16) + 1, BlockPtrStart, AppendSize / sizeof (CHAR16));
      } else {
        TotalSize    = StrSize (AppendString) + AppendSize + sizeof (CHAR16);
        AppendString = (EFI_STRING)ReallocatePool (
                                     StrSize (AppendString),
                                     TotalSize,
                                     AppendString
                                     );
        if (AppendString == NULL) {
          Status = EFI_OUT_OF_RESOURCES;
          goto Exit;
        }

        StrnCatS (AppendString, TotalSize / sizeof (CHAR16), BlockPtrStart, AppendSize / sizeof (CHAR16));
      }
    } else {
      //
      // To find next "&OFFSET=<Number>" block with AltConfigHdr in DefaultAltCfgResp.
      //
      BlockPtr = StrStr (BlockPtr + 1, L"&OFFSET=");
    }
  }

  if (AppendString != NULL) {
    //
    // Reallocate ConfigAltResp to copy the AppendString.
    //
    TotalSize      = StrSize (*ConfigAltResp) + StrSize (AppendString) + sizeof (CHAR16);
    *ConfigAltResp = (EFI_STRING)ReallocatePool (
                                   StrSize (*ConfigAltResp),
                                   TotalSize,
                                   *ConfigAltResp
                                   );
    if (*ConfigAltResp == NULL) {
      Status = EFI_OUT_OF_RESOURCES;
      goto Exit;
    }

    StrCatS (*ConfigAltResp, TotalSize / sizeof (CHAR16), AppendString);
    *ConfigAltRespChanged = TRUE;
  }

  Status = EFI_SUCCESS;

Exit:
  if (AppendString != NULL) {
    FreePool (AppendString);
  }

  return Status;
}

/**
  Compare the <AltResp> in ConfigAltResp and DefaultAltCfgResp, if the <AltResp>
  in DefaultAltCfgResp but not in ConfigAltResp,add it to the ConfigAltResp.

  @param  DefaultAltCfgResp      Pointer to a null-terminated Unicode string in
                                 <MultiConfigAltResp> format. The default value
                                 string may contain more than one ConfigAltResp
                                 string for the different varstore buffer.
  @param  ConfigAltResp          Pointer to a null-terminated Unicode string in
                                 <ConfigAltResp> format.
  @param  AltConfigHdr           Pointer to a Unicode string in <AltConfigHdr> format.
  @param  ConfigAltRespChanged   Whether the ConfigAltResp has been changed.

  @retval EFI_OUT_OF_RESOURCES   Insufficient resources to store necessary structures.
  @retval EFI_SUCCESS            The function finishes  successfully.

**/
EFI_STATUS
CompareNameElementDefault (
  IN     EFI_STRING  DefaultAltCfgResp,
  IN OUT EFI_STRING  *ConfigAltResp,
  IN     EFI_STRING  AltConfigHdr,
  IN OUT BOOLEAN     *ConfigAltRespChanged
  )
{
  EFI_STATUS  Status;
  EFI_STRING  NvConfigPtr;
  EFI_STRING  NvConfigStart;
  EFI_STRING  NvConfigValuePtr;
  EFI_STRING  StringPtr;
  EFI_STRING  NvConfigExist;
  EFI_STRING  AppendString;
  CHAR16      TempChar;
  UINTN       AppendSize;
  UINTN       TotalSize;

  AppendString  = NULL;
  NvConfigExist = NULL;
  Status        = EFI_OUT_OF_RESOURCES;
  //
  // Make NvConfigPtr point to the first <NvConfig> with AltConfigHdr in DefaultAltCfgResp.
  //
  NvConfigPtr = StrStr (DefaultAltCfgResp, AltConfigHdr);
  if (NvConfigPtr == NULL) {
    ASSERT (NvConfigPtr != NULL);
    goto Exit;
  }

  NvConfigPtr = StrStr (NvConfigPtr + StrLen (AltConfigHdr), L"&");
  //
  // Make StringPtr point to the first <NvConfig> with AltConfigHdr in ConfigAltResp.
  //
  StringPtr = StrStr (*ConfigAltResp, AltConfigHdr);
  if (StringPtr == NULL) {
    ASSERT (StringPtr != NULL);
    goto Exit;
  }

  StringPtr = StrStr (StringPtr + StrLen (AltConfigHdr), L"&");
  if (StringPtr == NULL) {
    ASSERT (StringPtr != NULL);
    goto Exit;
  }

  while (NvConfigPtr != NULL) {
    //
    // <NvConfig> ::= <Label>'='<String> | <Label>'='<Number>.
    // Get the <Label> with AltConfigHdr in DefaultAltCfgResp.
    //
    NvConfigStart    = NvConfigPtr;
    NvConfigValuePtr = StrStr (NvConfigPtr + 1, L"=");
    if (NvConfigValuePtr == NULL) {
      ASSERT (NvConfigValuePtr != NULL);
      goto Exit;
    }

    TempChar          = *NvConfigValuePtr;
    *NvConfigValuePtr = L'\0';
    //
    // Get the <Label> with AltConfigHdr in ConfigAltResp.
    //
    NvConfigExist = StrStr (StringPtr, NvConfigPtr);
    if (NvConfigExist == NULL) {
      //
      // Don't find same <Label> in ConfigAltResp.
      // Calculate the size of <NvConfig>.
      //
      *NvConfigValuePtr = TempChar;
      NvConfigPtr       = StrStr (NvConfigPtr + 1, L"&");
      if (NvConfigPtr != NULL) {
        AppendSize = (NvConfigPtr - NvConfigStart) * sizeof (CHAR16);
      } else {
        AppendSize = StrSize (NvConfigStart);
      }

      //
      // Copy the <NvConfig> to AppendString.
      //
      if (AppendString == NULL) {
        AppendString = (EFI_STRING)AllocateZeroPool (AppendSize + sizeof (CHAR16));
        StrnCatS (AppendString, AppendSize / sizeof (CHAR16) + 1, NvConfigStart, AppendSize / sizeof (CHAR16));
      } else {
        TotalSize    = StrSize (AppendString) + AppendSize + sizeof (CHAR16);
        AppendString = (EFI_STRING)ReallocatePool (
                                     StrSize (AppendString),
                                     TotalSize,
                                     AppendString
                                     );
        if (AppendString == NULL) {
          Status = EFI_OUT_OF_RESOURCES;
          goto Exit;
        }

        StrnCatS (AppendString, TotalSize / sizeof (CHAR16), NvConfigStart, AppendSize / sizeof (CHAR16));
      }
    } else {
      //
      // To find next <Label> in DefaultAltCfgResp.
      //
      *NvConfigValuePtr = TempChar;
      NvConfigPtr       = StrStr (NvConfigPtr + 1, L"&");
    }
  }

  if (AppendString != NULL) {
    //
    // Reallocate ConfigAltResp to copy the AppendString.
    //
    TotalSize      = StrSize (*ConfigAltResp) + StrSize (AppendString) + sizeof (CHAR16);
    *ConfigAltResp = (EFI_STRING)ReallocatePool (
                                   StrSize (*ConfigAltResp),
                                   StrSize (*ConfigAltResp) + StrSize (AppendString) + sizeof (CHAR16),
                                   *ConfigAltResp
                                   );
    if (*ConfigAltResp == NULL) {
      Status = EFI_OUT_OF_RESOURCES;
      goto Exit;
    }

    StrCatS (*ConfigAltResp, TotalSize / sizeof (CHAR16), AppendString);
    *ConfigAltRespChanged = TRUE;
  }

  Status = EFI_SUCCESS;

Exit:
  if (AppendString != NULL) {
    FreePool (AppendString);
  }

  return Status;
}

/**
  Compare the <AltResp> in AltCfgResp and DefaultAltCfgResp, if the <AltResp>
  in DefaultAltCfgResp but not in AltCfgResp,add it to the AltCfgResp.

  @param  AltCfgResp             Pointer to a null-terminated Unicode string in
                                 <ConfigAltResp> format.
  @param  DefaultAltCfgResp      Pointer to a null-terminated Unicode string in
                                 <MultiConfigAltResp> format. The default value
                                 string may contain more than one ConfigAltResp
                                 string for the different varstore buffer.
  @param  AltConfigHdr           Pointer to a Unicode string in <AltConfigHdr> format.

  @retval EFI_OUT_OF_RESOURCES   Insufficient resources to store necessary
                                 structures.
  @retval EFI_SUCCESS            The function finishes  successfully.

**/
EFI_STATUS
CompareAndMergeDefaultString (
  IN OUT EFI_STRING  *AltCfgResp,
  IN     EFI_STRING  DefaultAltCfgResp,
  IN     EFI_STRING  AltConfigHdr
  )
{
  EFI_STATUS  Status;
  EFI_STRING  AltCfgRespBackup;
  EFI_STRING  AltConfigHdrPtr;
  EFI_STRING  AltConfigHdrPtrNext;
  EFI_STRING  ConfigAltResp;
  EFI_STRING  StringPtr;
  EFI_STRING  StringPtrNext;
  EFI_STRING  BlockPtr;
  UINTN       ReallocateSize;
  CHAR16      TempChar;
  CHAR16      TempCharA;
  BOOLEAN     ConfigAltRespChanged;

  Status               = EFI_OUT_OF_RESOURCES;
  BlockPtr             = NULL;
  AltConfigHdrPtrNext  = NULL;
  StringPtrNext        = NULL;
  ConfigAltResp        = NULL;
  AltCfgRespBackup     = NULL;
  TempChar             = L'\0';
  TempCharA            = L'\0';
  ConfigAltRespChanged = FALSE;

  //
  // To find the <AltResp> with AltConfigHdr in DefaultAltCfgResp, ignore other <AltResp> which follow it.
  //
  AltConfigHdrPtr = StrStr (DefaultAltCfgResp, AltConfigHdr);
  if (AltConfigHdrPtr == NULL) {
    ASSERT (AltConfigHdrPtr != NULL);
    goto Exit;
  }

  AltConfigHdrPtrNext = StrStr (AltConfigHdrPtr + 1, L"&GUID");
  if (AltConfigHdrPtrNext != NULL) {
    TempChar             = *AltConfigHdrPtrNext;
    *AltConfigHdrPtrNext = L'\0';
  }

  //
  // To find the <AltResp> with AltConfigHdr in AltCfgResp, ignore other <AltResp> which follow it.
  //
  StringPtr = StrStr (*AltCfgResp, AltConfigHdr);
  ASSERT (StringPtr != NULL);
  StringPtrNext = StrStr (StringPtr + 1, L"&GUID");
  if (StringPtrNext != NULL) {
    TempCharA      = *StringPtrNext;
    *StringPtrNext = L'\0';
  }

  //
  // Copy the content of <ConfigAltResp> which contain current AltConfigHdr in AltCfgResp.
  //
  ConfigAltResp = AllocateCopyPool (StrSize (*AltCfgResp), *AltCfgResp);
  if (ConfigAltResp == NULL) {
    goto Exit;
  }

  //
  // To find the <ConfigBody> with AltConfigHdr in DefaultAltCfgResp.
  //
  BlockPtr = StrStr (AltConfigHdrPtr, L"&OFFSET=");
  if (BlockPtr != NULL) {
    //
    // <BlockConfig>::='OFFSET='<Number>'&WIDTH='<Number>'&VALUE='<Number> style.
    // Call function CompareBlockElementDefault to compare the <BlockConfig> in DefaultAltCfgResp and ConfigAltResp.
    // The ConfigAltResp which may contain the new <BlockConfig> get from DefaultAltCfgResp.
    //
    Status = CompareBlockElementDefault (DefaultAltCfgResp, &ConfigAltResp, AltConfigHdr, &ConfigAltRespChanged);
    if (EFI_ERROR (Status)) {
      goto Exit;
    }
  } else {
    //
    // <NvConfig> ::= <Label>'='<String> | <Label>'='<Number> style.
    // Call function CompareNameElementDefault to compare the <NvConfig> in DefaultAltCfgResp and ConfigAltResp.
    // The ConfigAltResp which may contain the new <NvConfig> get from DefaultAltCfgResp.
    //
    Status = CompareNameElementDefault (DefaultAltCfgResp, &ConfigAltResp, AltConfigHdr, &ConfigAltRespChanged);
    if (EFI_ERROR (Status)) {
      goto Exit;
    }
  }

  //
  // Restore the AltCfgResp.
  //
  if (StringPtrNext != NULL) {
    *StringPtrNext = TempCharA;
  }

  //
  // If the ConfigAltResp has no change,no need to update the content in AltCfgResp.
  //
  if (!ConfigAltRespChanged) {
    Status = EFI_SUCCESS;
    goto Exit;
  }

  //
  // ConfigAltResp has been changed, need to update the content in AltCfgResp.
  //
  if (StringPtrNext != NULL) {
    ReallocateSize = StrSize (ConfigAltResp) + StrSize (StringPtrNext) + sizeof (CHAR16);
  } else {
    ReallocateSize = StrSize (ConfigAltResp) + sizeof (CHAR16);
  }

  AltCfgRespBackup = (EFI_STRING)AllocateZeroPool (ReallocateSize);
  if (AltCfgRespBackup == NULL) {
    goto Exit;
  }

  StrCatS (AltCfgRespBackup, ReallocateSize / sizeof (CHAR16), ConfigAltResp);
  if (StringPtrNext != NULL) {
    StrCatS (AltCfgRespBackup, ReallocateSize / sizeof (CHAR16), StringPtrNext);
  }

  FreePool (*AltCfgResp);
  *AltCfgResp = AltCfgRespBackup;

  Status = EFI_SUCCESS;

Exit:
  if (ConfigAltResp != NULL) {
    FreePool (ConfigAltResp);
  }

  //
  // Restore the DefaultAltCfgResp.
  //
  if ( AltConfigHdrPtrNext != NULL) {
    *AltConfigHdrPtrNext = TempChar;
    AltConfigHdrPtrNext  = NULL;
  }

  return Status;
}

/**
  This function merges DefaultAltCfgResp string into AltCfgResp string for
  the missing AltCfgId in AltCfgResq.

  @param  AltCfgResp             Pointer to a null-terminated Unicode string in
                                 <ConfigAltResp> format. The default value string
                                 will be merged into it.
  @param  DefaultAltCfgResp      Pointer to a null-terminated Unicode string in
                                 <MultiConfigAltResp> format. The default value
                                 string may contain more than one ConfigAltResp
                                 string for the different varstore buffer.

  @retval EFI_SUCCESS            The merged string returns.
  @retval EFI_INVALID_PARAMETER  *AltCfgResp is to NULL.
**/
EFI_STATUS
EFIAPI
MergeDefaultString (
  IN OUT EFI_STRING  *AltCfgResp,
  IN     EFI_STRING  DefaultAltCfgResp
  )
{
  EFI_STRING  StringPtrDefault;
  EFI_STRING  StringPtrEnd;
  CHAR16      TempChar;
  EFI_STRING  StringPtr;
  EFI_STRING  AltConfigHdr;
  UINTN       HeaderLength;
  UINTN       SizeAltCfgResp;
  UINTN       MaxLen;
  UINTN       TotalSize;

  if (*AltCfgResp == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Get the request ConfigHdr
  //
  SizeAltCfgResp = 0;
  StringPtr      = *AltCfgResp;

  //
  // Find <ConfigHdr> GUID=...&NAME=...&PATH=...
  //
  if (StrnCmp (StringPtr, L"GUID=", StrLen (L"GUID=")) != 0) {
    return EFI_INVALID_PARAMETER;
  }

  while (*StringPtr != L'\0' && StrnCmp (StringPtr, L"&NAME=", StrLen (L"&NAME=")) != 0) {
    StringPtr++;
  }

  while (*StringPtr != L'\0' && StrnCmp (StringPtr, L"&PATH=", StrLen (L"&PATH=")) != 0) {
    StringPtr++;
  }

  if (*StringPtr == L'\0') {
    return EFI_INVALID_PARAMETER;
  }

  StringPtr += StrLen (L"&PATH=");
  while (*StringPtr != L'\0' && *StringPtr != L'&') {
    StringPtr++;
  }

  HeaderLength = StringPtr - *AltCfgResp;

  //
  // Construct AltConfigHdr string  "&<ConfigHdr>&ALTCFG=XXXX\0"
  //                                  |1| StrLen (ConfigHdr) | 8 | 4 | 1 |
  //
  MaxLen       = 1 + HeaderLength + 8 + 4 + 1;
  AltConfigHdr = AllocateZeroPool (MaxLen * sizeof (CHAR16));
  if (AltConfigHdr == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  StrCpyS (AltConfigHdr, MaxLen, L"&");
  StrnCatS (AltConfigHdr, MaxLen, *AltCfgResp, HeaderLength);
  StrCatS (AltConfigHdr, MaxLen, L"&ALTCFG=");
  HeaderLength = StrLen (AltConfigHdr);

  StringPtrDefault = StrStr (DefaultAltCfgResp, AltConfigHdr);
  while (StringPtrDefault != NULL) {
    //
    // Get AltCfg Name
    //
    StrnCatS (AltConfigHdr, MaxLen, StringPtrDefault + HeaderLength, 4);
    StringPtr = StrStr (*AltCfgResp, AltConfigHdr);

    //
    // Append the found default value string to the input AltCfgResp
    //
    if (StringPtr == NULL) {
      StringPtrEnd   = StrStr (StringPtrDefault + 1, L"&GUID");
      SizeAltCfgResp = StrSize (*AltCfgResp);
      if (StringPtrEnd == NULL) {
        //
        // No more default string is found.
        //
        TotalSize   = SizeAltCfgResp + StrSize (StringPtrDefault);
        *AltCfgResp = (EFI_STRING)ReallocatePool (
                                    SizeAltCfgResp,
                                    TotalSize,
                                    (VOID *)(*AltCfgResp)
                                    );
        if (*AltCfgResp == NULL) {
          FreePool (AltConfigHdr);
          return EFI_OUT_OF_RESOURCES;
        }

        StrCatS (*AltCfgResp, TotalSize / sizeof (CHAR16), StringPtrDefault);
        break;
      } else {
        TempChar      = *StringPtrEnd;
        *StringPtrEnd = L'\0';
        TotalSize     = SizeAltCfgResp + StrSize (StringPtrDefault);
        *AltCfgResp   = (EFI_STRING)ReallocatePool (
                                      SizeAltCfgResp,
                                      TotalSize,
                                      (VOID *)(*AltCfgResp)
                                      );
        if (*AltCfgResp == NULL) {
          FreePool (AltConfigHdr);
          return EFI_OUT_OF_RESOURCES;
        }

        StrCatS (*AltCfgResp, TotalSize / sizeof (CHAR16), StringPtrDefault);
        *StringPtrEnd = TempChar;
      }
    } else {
      //
      // The AltCfgResp contains <AltCfgResp>.
      // If the <ConfigElement> in <AltCfgResp> in the DefaultAltCfgResp but not in the
      // related <AltCfgResp> in AltCfgResp, merge it to AltCfgResp. else no need to merge.
      //
      CompareAndMergeDefaultString (AltCfgResp, DefaultAltCfgResp, AltConfigHdr);
    }

    //
    // Find next AltCfg String
    //
    *(AltConfigHdr + HeaderLength) = L'\0';
    StringPtrDefault               = StrStr (StringPtrDefault + 1, AltConfigHdr);
  }

  FreePool (AltConfigHdr);
  return EFI_SUCCESS;
}

/**
  This function inserts new DefaultValueData into the BlockData DefaultValue array.

  @param  BlockData         The BlockData is updated to add new default value.
  @param  DefaultValueData  The DefaultValue is added.

**/
VOID
InsertDefaultValue (
  IN IFR_BLOCK_DATA    *BlockData,
  IN IFR_DEFAULT_DATA  *DefaultValueData
  )
{
  LIST_ENTRY        *Link;
  IFR_DEFAULT_DATA  *DefaultValueArray;
  LIST_ENTRY        *DefaultLink;

  DefaultLink = &BlockData->DefaultValueEntry;

  for (Link = DefaultLink->ForwardLink; Link != DefaultLink; Link = Link->ForwardLink) {
    DefaultValueArray = BASE_CR (Link, IFR_DEFAULT_DATA, Entry);
    if (DefaultValueArray->DefaultId == DefaultValueData->DefaultId) {
      //
      // DEFAULT_VALUE_FROM_OPCODE has high priority, DEFAULT_VALUE_FROM_DEFAULT has low priority.
      // When default types are DEFAULT_VALUE_FROM_OTHER_DEFAULT, the default value can be overrode.
      //
      if ((DefaultValueData->Type > DefaultValueArray->Type) || ((DefaultValueData->Type == DefaultValueArray->Type) && (DefaultValueData->Type == DefaultValueFromOtherDefault))) {
        //
        // Update the default value array in BlockData.
        //
        CopyMem (&DefaultValueArray->Value, &DefaultValueData->Value, sizeof (EFI_IFR_TYPE_VALUE));
        DefaultValueArray->Type    = DefaultValueData->Type;
        DefaultValueArray->Cleaned = DefaultValueData->Cleaned;
      }

      return;
    }
  }

  //
  // Insert new default value data in tail.
  //
  DefaultValueArray = AllocateZeroPool (sizeof (IFR_DEFAULT_DATA));
  ASSERT (DefaultValueArray != NULL);
  CopyMem (DefaultValueArray, DefaultValueData, sizeof (IFR_DEFAULT_DATA));
  InsertTailList (Link, &DefaultValueArray->Entry);
}

/**
  This function inserts new BlockData into the block link

  @param  BlockLink      The list entry points to block array.
  @param  BlockData      The point to BlockData is added.

**/
VOID
InsertBlockData (
  IN LIST_ENTRY      *BlockLink,
  IN IFR_BLOCK_DATA  **BlockData
  )
{
  LIST_ENTRY      *Link;
  IFR_BLOCK_DATA  *BlockArray;
  IFR_BLOCK_DATA  *BlockSingleData;

  BlockSingleData = *BlockData;

  if (BlockSingleData->Name != NULL) {
    InsertTailList (BlockLink, &BlockSingleData->Entry);
    return;
  }

  //
  // Insert block data in its Offset and Width order.
  //
  for (Link = BlockLink->ForwardLink; Link != BlockLink; Link = Link->ForwardLink) {
    BlockArray = BASE_CR (Link, IFR_BLOCK_DATA, Entry);
    if (BlockArray->Offset == BlockSingleData->Offset) {
      if ((BlockArray->Width > BlockSingleData->Width) || (BlockSingleData->IsBitVar && (BlockArray->Width == BlockSingleData->Width))) {
        //
        // Insert this block data in the front of block array
        //
        InsertTailList (Link, &BlockSingleData->Entry);
        return;
      }

      if ((!BlockSingleData->IsBitVar) && (BlockArray->Width == BlockSingleData->Width)) {
        //
        // The same block array has been added.
        //
        if (BlockSingleData != BlockArray) {
          FreePool (BlockSingleData);
          *BlockData = BlockArray;
        }

        return;
      }
    } else if (BlockArray->Offset > BlockSingleData->Offset) {
      //
      // Insert new block data in the front of block array
      //
      InsertTailList (Link, &BlockSingleData->Entry);
      return;
    }
  }

  //
  // Add new block data into the tail.
  //
  InsertTailList (Link, &BlockSingleData->Entry);
}

/**
  Retrieves a pointer to the a Null-terminated ASCII string containing the list
  of languages that an HII handle in the HII Database supports.  The returned
  string is allocated using AllocatePool().  The caller is responsible for freeing
  the returned string using FreePool().  The format of the returned string follows
  the language format assumed the HII Database.

  If HiiHandle is NULL, then ASSERT().

  @param[in]  HiiHandle  A handle that was previously registered in the HII Database.

  @retval NULL   HiiHandle is not registered in the HII database
  @retval NULL   There are not enough resources available to retrieve the supported
                 languages.
  @retval NULL   The list of supported languages could not be retrieved.
  @retval Other  A pointer to the Null-terminated ASCII string of supported languages.

**/
CHAR8 *
GetSupportedLanguages (
  IN EFI_HII_HANDLE  HiiHandle
  )
{
  EFI_STATUS  Status;
  UINTN       LanguageSize;
  CHAR8       TempSupportedLanguages;
  CHAR8       *SupportedLanguages;

  ASSERT (HiiHandle != NULL);

  //
  // Retrieve the size required for the supported languages buffer.
  //
  LanguageSize = 0;
  Status       = mPrivate.HiiString.GetLanguages (&mPrivate.HiiString, HiiHandle, &TempSupportedLanguages, &LanguageSize);

  //
  // If GetLanguages() returns EFI_SUCCESS for a zero size,
  // then there are no supported languages registered for HiiHandle.  If GetLanguages()
  // returns an error other than EFI_BUFFER_TOO_SMALL, then HiiHandle is not present
  // in the HII Database
  //
  if (Status != EFI_BUFFER_TOO_SMALL) {
    //
    // Return NULL if the size can not be retrieved, or if HiiHandle is not in the HII Database
    //
    return NULL;
  }

  //
  // Allocate the supported languages buffer.
  //
  SupportedLanguages = AllocateZeroPool (LanguageSize);
  if (SupportedLanguages == NULL) {
    //
    // Return NULL if allocation fails.
    //
    return NULL;
  }

  //
  // Retrieve the supported languages string
  //
  Status = mPrivate.HiiString.GetLanguages (&mPrivate.HiiString, HiiHandle, SupportedLanguages, &LanguageSize);
  if (EFI_ERROR (Status)) {
    //
    // Free the buffer and return NULL if the supported languages can not be retrieved.
    //
    FreePool (SupportedLanguages);
    return NULL;
  }

  //
  // Return the Null-terminated ASCII string of supported languages
  //
  return SupportedLanguages;
}

/**
  This function create a new string in String Package or updates an existing
  string in a String Package.  If StringId is 0, then a new string is added to
  a String Package.  If StringId is not zero, then a string in String Package is
  updated.  If SupportedLanguages is NULL, then the string is added or updated
  for all the languages that the String Package supports.  If SupportedLanguages
  is not NULL, then the string is added or updated for the set of languages
  specified by SupportedLanguages.

  If HiiHandle is NULL, then ASSERT().
  If String is NULL, then ASSERT().

  @param[in]  HiiHandle           A handle that was previously registered in the
                                  HII Database.
  @param[in]  StringId            If zero, then a new string is created in the
                                  String Package associated with HiiHandle.  If
                                  non-zero, then the string specified by StringId
                                  is updated in the String Package  associated
                                  with HiiHandle.
  @param[in]  String              A pointer to the Null-terminated Unicode string
                                  to add or update in the String Package associated
                                  with HiiHandle.
  @param[in]  SupportedLanguages  A pointer to a Null-terminated ASCII string of
                                  language codes.  If this parameter is NULL, then
                                  String is added or updated in the String Package
                                  associated with HiiHandle for all the languages
                                  that the String Package supports.  If this
                                  parameter is not NULL, then then String is added
                                  or updated in the String Package associated with
                                  HiiHandle for the set oflanguages specified by
                                  SupportedLanguages.  The format of
                                  SupportedLanguages must follow the language
                                  format assumed the HII Database.

  @retval 0      The string could not be added or updated in the String Package.
  @retval Other  The EFI_STRING_ID of the newly added or updated string.

**/
EFI_STRING_ID
InternalHiiSetString (
  IN EFI_HII_HANDLE    HiiHandle,
  IN EFI_STRING_ID     StringId             OPTIONAL,
  IN CONST EFI_STRING  String,
  IN CONST CHAR8       *SupportedLanguages  OPTIONAL
  )
{
  EFI_STATUS  Status;
  CHAR8       *AllocatedLanguages;
  CHAR8       *Supported;
  CHAR8       *Language;

  ASSERT (HiiHandle != NULL);

  if (SupportedLanguages == NULL) {
    //
    // Retrieve the languages that the package specified by HiiHandle supports
    //
    AllocatedLanguages = GetSupportedLanguages (HiiHandle);
  } else {
    //
    // Allocate a copy of the SupportLanguages string that passed in
    //
    AllocatedLanguages = AllocateCopyPool (AsciiStrSize (SupportedLanguages), SupportedLanguages);
  }

  //
  // If there are not enough resources for the supported languages string, then return a StringId of 0
  //
  if (AllocatedLanguages == NULL) {
    return (EFI_STRING_ID)(0);
  }

  Status = EFI_INVALID_PARAMETER;
  //
  // Loop through each language that the string supports
  //
  for (Supported = AllocatedLanguages; *Supported != '\0'; ) {
    //
    // Cache a pointer to the beginning of the current language in the list of languages
    //
    Language = Supported;

    //
    // Search for the next language separator and replace it with a Null-terminator
    //
    for ( ; *Supported != 0 && *Supported != ';'; Supported++) {
    }

    if (*Supported != 0) {
      *(Supported++) = '\0';
    }

    if ((SupportedLanguages == NULL) && (AsciiStrnCmp (Language, UEFI_CONFIG_LANG, AsciiStrLen (UEFI_CONFIG_LANG)) == 0)) {
      //
      // Skip string package used for keyword protocol.
      //
      continue;
    }

    //
    // If StringId is 0, then call NewString().  Otherwise, call SetString()
    //
    if (StringId == (EFI_STRING_ID)(0)) {
      Status = mPrivate.HiiString.NewString (
                                    &mPrivate.HiiString,
                                    HiiHandle,
                                    &StringId,
                                    Language,
                                    NULL,
                                    String,
                                    NULL
                                    );
    } else {
      Status = mPrivate.HiiString.SetString (
                                    &mPrivate.HiiString,
                                    HiiHandle,
                                    StringId,
                                    Language,
                                    String,
                                    NULL
                                    );
    }

    //
    // If there was an error, then break out of the loop and return a StringId of 0
    //
    if (EFI_ERROR (Status)) {
      break;
    }
  }

  //
  // Free the buffer of supported languages
  //
  FreePool (AllocatedLanguages);

  if (EFI_ERROR (Status)) {
    return (EFI_STRING_ID)(0);
  } else {
    return StringId;
  }
}

/**
  Retrieves a string from a string package.

  If HiiHandle is NULL, then ASSERT().
  If StringId is 0, then ASSET.

  @param[in]  HiiHandle  A handle that was previously registered in the HII Database.
  @param[in]  StringId   The identifier of the string to retrieved from the string
                         package associated with HiiHandle.

  @retval NULL   The string specified by StringId is not present in the string package.
  @retval Other  The string was returned.

**/
EFI_STRING
InternalGetString (
  IN EFI_HII_HANDLE  HiiHandle,
  IN EFI_STRING_ID   StringId
  )
{
  EFI_STATUS  Status;
  UINTN       StringSize;
  CHAR16      TempString;
  EFI_STRING  String;
  CHAR8       *SupportedLanguages;
  CHAR8       *PlatformLanguage;
  CHAR8       *BestLanguage;
  CHAR8       *Language;

  ASSERT (HiiHandle != NULL);
  ASSERT (StringId != 0);

  //
  // Initialize all allocated buffers to NULL
  //
  SupportedLanguages = NULL;
  PlatformLanguage   = NULL;
  BestLanguage       = NULL;
  String             = NULL;
  Language           = "";

  //
  // Get the languages that the package specified by HiiHandle supports
  //
  SupportedLanguages = GetSupportedLanguages (HiiHandle);
  if (SupportedLanguages == NULL) {
    goto Error;
  }

  //
  // Get the current platform language setting
  //
  GetEfiGlobalVariable2 (L"PlatformLang", (VOID **)&PlatformLanguage, NULL);

  //
  // Get the best matching language from SupportedLanguages
  //
  BestLanguage = GetBestLanguage (
                   SupportedLanguages,
                   FALSE,                                             // RFC 4646 mode
                   Language,                                          // Highest priority
                   PlatformLanguage != NULL ? PlatformLanguage : "",  // Next highest priority
                   SupportedLanguages,                                // Lowest priority
                   NULL
                   );
  if (BestLanguage == NULL) {
    goto Error;
  }

  //
  // Retrieve the size of the string in the string package for the BestLanguage
  //
  StringSize = 0;
  Status     = mPrivate.HiiString.GetString (
                                    &mPrivate.HiiString,
                                    BestLanguage,
                                    HiiHandle,
                                    StringId,
                                    &TempString,
                                    &StringSize,
                                    NULL
                                    );
  //
  // If GetString() returns EFI_SUCCESS for a zero size,
  // then there are no supported languages registered for HiiHandle.  If GetString()
  // returns an error other than EFI_BUFFER_TOO_SMALL, then HiiHandle is not present
  // in the HII Database
  //
  if (Status != EFI_BUFFER_TOO_SMALL) {
    goto Error;
  }

  //
  // Allocate a buffer for the return string
  //
  String = AllocateZeroPool (StringSize);
  if (String == NULL) {
    goto Error;
  }

  //
  // Retrieve the string from the string package
  //
  Status = mPrivate.HiiString.GetString (
                                &mPrivate.HiiString,
                                BestLanguage,
                                HiiHandle,
                                StringId,
                                String,
                                &StringSize,
                                NULL
                                );
  if (EFI_ERROR (Status)) {
    //
    // Free the buffer and return NULL if the supported languages can not be retrieved.
    //
    FreePool (String);
    String = NULL;
  }

Error:
  //
  // Free allocated buffers
  //
  if (SupportedLanguages != NULL) {
    FreePool (SupportedLanguages);
  }

  if (PlatformLanguage != NULL) {
    FreePool (PlatformLanguage);
  }

  if (BestLanguage != NULL) {
    FreePool (BestLanguage);
  }

  //
  // Return the Null-terminated Unicode string
  //
  return String;
}

/**
  This function checks VarOffset and VarWidth is in the block range.

  @param  RequestBlockArray  The block array is to be checked.
  @param  VarOffset          Offset of var to the structure
  @param  VarWidth           Width of var.
  @param  IsNameValueType    Whether this varstore is name/value varstore or not.
  @param  HiiHandle          Hii handle for this hii package.

  @retval TRUE   This Var is in the block range.
  @retval FALSE  This Var is not in the block range.
**/
BOOLEAN
BlockArrayCheck (
  IN IFR_BLOCK_DATA  *RequestBlockArray,
  IN UINT16          VarOffset,
  IN UINT16          VarWidth,
  IN BOOLEAN         IsNameValueType,
  IN EFI_HII_HANDLE  HiiHandle
  )
{
  LIST_ENTRY      *Link;
  IFR_BLOCK_DATA  *BlockData;
  EFI_STRING      Name;

  //
  // No Request Block array, all vars are got.
  //
  if (RequestBlockArray == NULL) {
    return TRUE;
  }

  //
  // Check the input var is in the request block range.
  //
  for (Link = RequestBlockArray->Entry.ForwardLink; Link != &RequestBlockArray->Entry; Link = Link->ForwardLink) {
    BlockData = BASE_CR (Link, IFR_BLOCK_DATA, Entry);

    if (IsNameValueType) {
      Name = InternalGetString (HiiHandle, VarOffset);
      ASSERT (Name != NULL);

      if (StrnCmp (BlockData->Name, Name, StrLen (Name)) == 0) {
        FreePool (Name);
        return TRUE;
      }

      FreePool (Name);
    } else {
      if ((VarOffset >= BlockData->Offset) && ((VarOffset + VarWidth) <= (BlockData->Offset + BlockData->Width))) {
        return TRUE;
      }
    }
  }

  return FALSE;
}

/**
  Get form package data from data base.

  @param  DataBaseRecord         The DataBaseRecord instance contains the found Hii handle and package.
  @param  HiiFormPackage         The buffer saves the package data.
  @param  PackageSize            The buffer size of the package data.

**/
EFI_STATUS
GetFormPackageData (
  IN     HII_DATABASE_RECORD  *DataBaseRecord,
  IN OUT UINT8                **HiiFormPackage,
  OUT    UINTN                *PackageSize
  )
{
  EFI_STATUS  Status;
  UINTN       Size;
  UINTN       ResultSize;

  if ((DataBaseRecord == NULL) || (HiiFormPackage == NULL) || (PackageSize == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  Size       = 0;
  ResultSize = 0;
  //
  // 0. Get Hii Form Package by HiiHandle
  //
  Status = ExportFormPackages (
             &mPrivate,
             DataBaseRecord->Handle,
             DataBaseRecord->PackageList,
             0,
             Size,
             HiiFormPackage,
             &ResultSize
             );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  (*HiiFormPackage) = AllocatePool (ResultSize);
  if (*HiiFormPackage == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    return Status;
  }

  //
  // Get HiiFormPackage by HiiHandle
  //
  Size       = ResultSize;
  ResultSize = 0;
  Status     = ExportFormPackages (
                 &mPrivate,
                 DataBaseRecord->Handle,
                 DataBaseRecord->PackageList,
                 0,
                 Size,
                 *HiiFormPackage,
                 &ResultSize
                 );
  if (EFI_ERROR (Status)) {
    FreePool (*HiiFormPackage);
  }

  *PackageSize = Size;

  return Status;
}

/**
  This function parses Form Package to get the efi varstore info according to the request ConfigHdr.

  @param  DataBaseRecord        The DataBaseRecord instance contains the found Hii handle and package.
  @param  ConfigHdr             Request string ConfigHdr. If it is NULL,
                                the first found varstore will be as ConfigHdr.
  @param  IsEfiVarstore         Whether the request storage type is efi varstore type.
  @param  EfiVarStore           The efi varstore info which will return.
**/
EFI_STATUS
GetVarStoreType (
  IN     HII_DATABASE_RECORD   *DataBaseRecord,
  IN     EFI_STRING            ConfigHdr,
  OUT    BOOLEAN               *IsEfiVarstore,
  OUT    EFI_IFR_VARSTORE_EFI  **EfiVarStore
  )
{
  EFI_STATUS              Status;
  UINTN                   IfrOffset;
  UINTN                   PackageOffset;
  EFI_IFR_OP_HEADER       *IfrOpHdr;
  CHAR16                  *VarStoreName;
  UINTN                   NameSize;
  EFI_STRING              GuidStr;
  EFI_STRING              NameStr;
  EFI_STRING              TempStr;
  UINTN                   LengthString;
  UINT8                   *HiiFormPackage;
  UINTN                   PackageSize;
  EFI_IFR_VARSTORE_EFI    *IfrEfiVarStore;
  EFI_HII_PACKAGE_HEADER  *PackageHeader;

  HiiFormPackage = NULL;
  LengthString   = 0;
  Status         = EFI_SUCCESS;
  GuidStr        = NULL;
  NameStr        = NULL;
  TempStr        = NULL;
  *IsEfiVarstore = FALSE;

  Status = GetFormPackageData (DataBaseRecord, &HiiFormPackage, &PackageSize);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  IfrOffset     = sizeof (EFI_HII_PACKAGE_HEADER);
  PackageOffset = IfrOffset;
  PackageHeader = (EFI_HII_PACKAGE_HEADER *)HiiFormPackage;

  while (IfrOffset < PackageSize) {
    //
    // More than one form packages exist.
    //
    if (PackageOffset >= PackageHeader->Length) {
      //
      // Process the new form package.
      //
      PackageOffset = sizeof (EFI_HII_PACKAGE_HEADER);
      IfrOffset    += PackageOffset;
      PackageHeader = (EFI_HII_PACKAGE_HEADER *)(HiiFormPackage + IfrOffset);
    }

    IfrOpHdr       = (EFI_IFR_OP_HEADER *)(HiiFormPackage + IfrOffset);
    IfrOffset     += IfrOpHdr->Length;
    PackageOffset += IfrOpHdr->Length;

    if (IfrOpHdr->OpCode == EFI_IFR_VARSTORE_EFI_OP ) {
      IfrEfiVarStore = (EFI_IFR_VARSTORE_EFI *)IfrOpHdr;
      //
      // If the length is small than the structure, this is from old efi
      // varstore definition. Old efi varstore get config directly from
      // GetVariable function.
      //
      if (IfrOpHdr->Length < sizeof (EFI_IFR_VARSTORE_EFI)) {
        continue;
      }

      NameSize     = AsciiStrSize ((CHAR8 *)IfrEfiVarStore->Name);
      VarStoreName = AllocateZeroPool (NameSize * sizeof (CHAR16));
      if (VarStoreName == NULL) {
        Status = EFI_OUT_OF_RESOURCES;
        goto Done;
      }

      AsciiStrToUnicodeStrS ((CHAR8 *)IfrEfiVarStore->Name, VarStoreName, NameSize);

      GenerateSubStr (L"GUID=", sizeof (EFI_GUID), (VOID *)&IfrEfiVarStore->Guid, 1, &GuidStr);
      GenerateSubStr (L"NAME=", StrLen (VarStoreName) * sizeof (CHAR16), (VOID *)VarStoreName, 2, &NameStr);
      LengthString = StrLen (GuidStr);
      LengthString = LengthString + StrLen (NameStr) + 1;
      TempStr      = AllocateZeroPool (LengthString * sizeof (CHAR16));
      if (TempStr == NULL) {
        FreePool (GuidStr);
        FreePool (NameStr);
        FreePool (VarStoreName);
        Status = EFI_OUT_OF_RESOURCES;
        goto Done;
      }

      StrCpyS (TempStr, LengthString, GuidStr);
      StrCatS (TempStr, LengthString, NameStr);
      if ((ConfigHdr == NULL) || (StrnCmp (ConfigHdr, TempStr, StrLen (TempStr)) == 0)) {
        *EfiVarStore = (EFI_IFR_VARSTORE_EFI *)AllocateZeroPool (IfrOpHdr->Length);
        if (*EfiVarStore == NULL) {
          FreePool (VarStoreName);
          FreePool (GuidStr);
          FreePool (NameStr);
          FreePool (TempStr);
          Status = EFI_OUT_OF_RESOURCES;
          goto Done;
        }

        *IsEfiVarstore = TRUE;
        CopyMem (*EfiVarStore, IfrEfiVarStore, IfrOpHdr->Length);
      }

      //
      // Free allocated temp string.
      //
      FreePool (VarStoreName);
      FreePool (GuidStr);
      FreePool (NameStr);
      FreePool (TempStr);

      //
      // Already found the varstore, break;
      //
      if (*IsEfiVarstore) {
        break;
      }
    }
  }

Done:
  if (HiiFormPackage != NULL) {
    FreePool (HiiFormPackage);
  }

  return Status;
}

/**
  Check whether the ConfigRequest string has the request elements.
  For EFI_HII_VARSTORE_BUFFER type, the request has "&OFFSET=****&WIDTH=****..." format.
  For EFI_HII_VARSTORE_NAME_VALUE type, the request has "&NAME1**&NAME2..." format.

  @param  ConfigRequest      The input config request string.

  @retval  TRUE              The input include config request elements.
  @retval  FALSE             The input string not includes.

**/
BOOLEAN
GetElementsFromRequest (
  IN EFI_STRING  ConfigRequest
  )
{
  EFI_STRING  TmpRequest;

  TmpRequest = StrStr (ConfigRequest, L"PATH=");
  ASSERT (TmpRequest != NULL);
  if (TmpRequest != NULL) {
    if ((StrStr (TmpRequest, L"&OFFSET=") != NULL) || (StrStr (TmpRequest, L"&") != NULL)) {
      return TRUE;
    }
  }

  return FALSE;
}

/**
  Check whether the this varstore is the request varstore.

  @param  VarstoreGuid      Varstore guid.
  @param  Name              Varstore name.
  @param  ConfigHdr         Current configRequest info.

  @retval  TRUE              This varstore is the request one.
  @retval  FALSE             This varstore is not the request one.

**/
BOOLEAN
IsThisVarstore (
  IN EFI_GUID  *VarstoreGuid,
  IN CHAR16    *Name,
  IN CHAR16    *ConfigHdr
  )
{
  EFI_STRING  GuidStr;
  EFI_STRING  NameStr;
  EFI_STRING  TempStr;
  UINTN       LengthString;
  BOOLEAN     RetVal;

  RetVal  = FALSE;
  GuidStr = NULL;
  TempStr = NULL;

  //
  // If ConfigHdr has name field and varstore not has name, return FALSE.
  //
  if ((Name == NULL) && (ConfigHdr != NULL) && (StrStr (ConfigHdr, L"NAME=&") == NULL)) {
    return FALSE;
  }

  GenerateSubStr (L"GUID=", sizeof (EFI_GUID), (VOID *)VarstoreGuid, 1, &GuidStr);
  if (Name != NULL) {
    GenerateSubStr (L"NAME=", StrLen (Name) * sizeof (CHAR16), (VOID *)Name, 2, &NameStr);
  } else {
    GenerateSubStr (L"NAME=", 0, NULL, 2, &NameStr);
  }

  LengthString = StrLen (GuidStr);
  LengthString = LengthString + StrLen (NameStr) + 1;
  TempStr      = AllocateZeroPool (LengthString * sizeof (CHAR16));
  if (TempStr == NULL) {
    goto Done;
  }

  StrCpyS (TempStr, LengthString, GuidStr);
  StrCatS (TempStr, LengthString, NameStr);

  if ((ConfigHdr == NULL) || (StrnCmp (ConfigHdr, TempStr, StrLen (TempStr)) == 0)) {
    RetVal = TRUE;
  }

Done:
  if (GuidStr != NULL) {
    FreePool (GuidStr);
  }

  if (NameStr != NULL) {
    FreePool (NameStr);
  }

  if (TempStr != NULL) {
    FreePool (TempStr);
  }

  return RetVal;
}

/**
  This function parses Form Package to get the efi varstore info according to the request ConfigHdr.

  @param  DataBaseRecord        The DataBaseRecord instance contains the found Hii handle and package.
  @param  ConfigHdr             Request string ConfigHdr. If it is NULL,
                                the first found varstore will be as ConfigHdr.
  @retval  TRUE                 This hii package is the request one.
  @retval  FALSE                This hii package is not the request one.
**/
BOOLEAN
IsThisPackageList (
  IN     HII_DATABASE_RECORD  *DataBaseRecord,
  IN     EFI_STRING           ConfigHdr
  )
{
  EFI_STATUS                   Status;
  UINTN                        IfrOffset;
  UINTN                        PackageOffset;
  EFI_IFR_OP_HEADER            *IfrOpHdr;
  CHAR16                       *VarStoreName;
  UINTN                        NameSize;
  UINT8                        *HiiFormPackage;
  UINTN                        PackageSize;
  EFI_IFR_VARSTORE_EFI         *IfrEfiVarStore;
  EFI_HII_PACKAGE_HEADER       *PackageHeader;
  EFI_IFR_VARSTORE             *IfrVarStore;
  EFI_IFR_VARSTORE_NAME_VALUE  *IfrNameValueVarStore;
  BOOLEAN                      FindVarstore;

  HiiFormPackage = NULL;
  VarStoreName   = NULL;
  Status         = EFI_SUCCESS;
  FindVarstore   = FALSE;

  Status = GetFormPackageData (DataBaseRecord, &HiiFormPackage, &PackageSize);
  if (EFI_ERROR (Status)) {
    return FALSE;
  }

  IfrOffset     = sizeof (EFI_HII_PACKAGE_HEADER);
  PackageOffset = IfrOffset;
  PackageHeader = (EFI_HII_PACKAGE_HEADER *)HiiFormPackage;

  while (IfrOffset < PackageSize) {
    //
    // More than one form packages exist.
    //
    if (PackageOffset >= PackageHeader->Length) {
      //
      // Process the new form package.
      //
      PackageOffset = sizeof (EFI_HII_PACKAGE_HEADER);
      IfrOffset    += PackageOffset;
      PackageHeader = (EFI_HII_PACKAGE_HEADER *)(HiiFormPackage + IfrOffset);
    }

    IfrOpHdr       = (EFI_IFR_OP_HEADER *)(HiiFormPackage + IfrOffset);
    IfrOffset     += IfrOpHdr->Length;
    PackageOffset += IfrOpHdr->Length;

    switch (IfrOpHdr->OpCode) {
      case EFI_IFR_VARSTORE_OP:
        IfrVarStore = (EFI_IFR_VARSTORE *)IfrOpHdr;

        NameSize     = AsciiStrSize ((CHAR8 *)IfrVarStore->Name);
        VarStoreName = AllocateZeroPool (NameSize * sizeof (CHAR16));
        if (VarStoreName == NULL) {
          goto Done;
        }

        AsciiStrToUnicodeStrS ((CHAR8 *)IfrVarStore->Name, VarStoreName, NameSize);

        if (IsThisVarstore ((VOID *)&IfrVarStore->Guid, VarStoreName, ConfigHdr)) {
          FindVarstore = TRUE;
          goto Done;
        } else {
          FreePool (VarStoreName);
          VarStoreName = NULL;
        }

        break;

      case EFI_IFR_VARSTORE_EFI_OP:
        IfrEfiVarStore = (EFI_IFR_VARSTORE_EFI *)IfrOpHdr;
        NameSize       = AsciiStrSize ((CHAR8 *)IfrEfiVarStore->Name);
        VarStoreName   = AllocateZeroPool (NameSize * sizeof (CHAR16));
        if (VarStoreName == NULL) {
          goto Done;
        }

        AsciiStrToUnicodeStrS ((CHAR8 *)IfrEfiVarStore->Name, VarStoreName, NameSize);

        if (IsThisVarstore (&IfrEfiVarStore->Guid, VarStoreName, ConfigHdr)) {
          FindVarstore = TRUE;
          goto Done;
        } else {
          FreePool (VarStoreName);
          VarStoreName = NULL;
        }

        break;

      case EFI_IFR_VARSTORE_NAME_VALUE_OP:
        IfrNameValueVarStore = (EFI_IFR_VARSTORE_NAME_VALUE *)IfrOpHdr;

        if (IsThisVarstore (&IfrNameValueVarStore->Guid, NULL, ConfigHdr)) {
          FindVarstore = TRUE;
          goto Done;
        }

        break;

      case EFI_IFR_FORM_OP:
      case EFI_IFR_FORM_MAP_OP:
        //
        // No matched varstore is found and directly return.
        //
        goto Done;

      default:
        break;
    }
  }

Done:
  if (HiiFormPackage != NULL) {
    FreePool (HiiFormPackage);
  }

  if (VarStoreName != NULL) {
    FreePool (VarStoreName);
  }

  return FindVarstore;
}

/**
  Check whether the this op code is required.

  @param  RequestBlockArray      The array includes all the request info or NULL.
  @param  HiiHandle              The hii handle for this form package.
  @param  VarStorageData         The varstore data structure.
  @param  IfrOpHdr               Ifr opcode header for this opcode.
  @param  VarWidth               The buffer width for this opcode.
  @param  ReturnData             The data block added for this opcode.
  @param  IsBitVar               Whether the the opcode refers to bit storage.

  @retval  EFI_SUCCESS           This opcode is required.
  @retval  EFI_NOT_FOUND         This opcode is not required.
  @retval  Others                Contain some error.

**/
EFI_STATUS
IsThisOpcodeRequired (
  IN     IFR_BLOCK_DATA       *RequestBlockArray,
  IN     EFI_HII_HANDLE       HiiHandle,
  IN OUT IFR_VARSTORAGE_DATA  *VarStorageData,
  IN     EFI_IFR_OP_HEADER    *IfrOpHdr,
  IN     UINT16               VarWidth,
  OUT    IFR_BLOCK_DATA       **ReturnData,
  IN     BOOLEAN              IsBitVar
  )
{
  IFR_BLOCK_DATA           *BlockData;
  UINT16                   VarOffset;
  EFI_STRING_ID            NameId;
  EFI_IFR_QUESTION_HEADER  *IfrQuestionHdr;
  UINT16                   BitOffset;
  UINT16                   BitWidth;
  UINT16                   TotalBits;

  NameId         = 0;
  VarOffset      = 0;
  BitOffset      = 0;
  BitWidth       = 0;
  IfrQuestionHdr = (EFI_IFR_QUESTION_HEADER  *)((CHAR8 *)IfrOpHdr + sizeof (EFI_IFR_OP_HEADER));

  if (VarStorageData->Type == EFI_HII_VARSTORE_NAME_VALUE) {
    NameId = IfrQuestionHdr->VarStoreInfo.VarName;

    //
    // Check whether this question is in requested block array.
    //
    if (!BlockArrayCheck (RequestBlockArray, NameId, 0, TRUE, HiiHandle)) {
      //
      // This question is not in the requested string. Skip it.
      //
      return EFI_NOT_FOUND;
    }
  } else {
    //
    // Get the byte offset/with and bit offset/width
    //
    if (IsBitVar) {
      BitOffset = IfrQuestionHdr->VarStoreInfo.VarOffset;
      BitWidth  = VarWidth;
      VarOffset = BitOffset / 8;
      //
      // Use current bit width and the bit width before current bit (with same byte offset) to calculate the byte width.
      //
      TotalBits = BitOffset % 8 + BitWidth;
      VarWidth  = (TotalBits % 8 == 0 ? TotalBits / 8 : TotalBits / 8 + 1);
    } else {
      VarOffset = IfrQuestionHdr->VarStoreInfo.VarOffset;
      BitWidth  = VarWidth;
      BitOffset = VarOffset * 8;
    }

    //
    // Check whether this question is in requested block array.
    //
    if (!BlockArrayCheck (RequestBlockArray, VarOffset, VarWidth, FALSE, HiiHandle)) {
      //
      // This question is not in the requested string. Skip it.
      //
      return EFI_NOT_FOUND;
    }

    //
    // Check this var question is in the var storage
    //
    if (((VarOffset + VarWidth) > VarStorageData->Size)) {
      return EFI_INVALID_PARAMETER;
    }
  }

  BlockData = (IFR_BLOCK_DATA *)AllocateZeroPool (sizeof (IFR_BLOCK_DATA));
  if (BlockData == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  if (VarStorageData->Type == EFI_HII_VARSTORE_NAME_VALUE) {
    BlockData->Name = InternalGetString (HiiHandle, NameId);
  } else {
    BlockData->Offset = VarOffset;
  }

  BlockData->Width      = VarWidth;
  BlockData->QuestionId = IfrQuestionHdr->QuestionId;
  BlockData->OpCode     = IfrOpHdr->OpCode;
  BlockData->Scope      = IfrOpHdr->Scope;
  BlockData->IsBitVar   = IsBitVar;
  BlockData->BitOffset  = BitOffset;
  BlockData->BitWidth   = BitWidth;
  InitializeListHead (&BlockData->DefaultValueEntry);
  //
  // Add Block Data into VarStorageData BlockEntry
  //
  InsertBlockData (&VarStorageData->BlockEntry, &BlockData);
  *ReturnData = BlockData;

  return EFI_SUCCESS;
}

/**
  This function parses Form Package to get the block array and the default
  value array according to the request ConfigHdr.

  @param  HiiHandle             Hii Handle for this hii package.
  @param  Package               Pointer to the form package data.
  @param  PackageLength         Length of the package.
  @param  ConfigHdr             Request string ConfigHdr. If it is NULL,
                                the first found varstore will be as ConfigHdr.
  @param  RequestBlockArray     The block array is retrieved from the request string.
  @param  VarStorageData        VarStorage structure contains the got block and default value.
  @param  DefaultIdArray        Point to the got default id and default name array.

  @retval EFI_SUCCESS           The block array and the default value array are got.
  @retval EFI_INVALID_PARAMETER The varstore definition in the different form packages
                                are conflicted.
  @retval EFI_OUT_OF_RESOURCES  No enough memory.
**/
EFI_STATUS
EFIAPI
ParseIfrData (
  IN     EFI_HII_HANDLE       HiiHandle,
  IN     UINT8                *Package,
  IN     UINT32               PackageLength,
  IN     EFI_STRING           ConfigHdr,
  IN     IFR_BLOCK_DATA       *RequestBlockArray,
  IN OUT IFR_VARSTORAGE_DATA  *VarStorageData,
  OUT    IFR_DEFAULT_DATA     *DefaultIdArray
  )
{
  EFI_STATUS                   Status;
  UINTN                        IfrOffset;
  UINTN                        PackageOffset;
  EFI_IFR_VARSTORE             *IfrVarStore;
  EFI_IFR_VARSTORE_EFI         *IfrEfiVarStore;
  EFI_IFR_VARSTORE_EFI         *IfrEfiVarStoreTmp;
  EFI_IFR_OP_HEADER            *IfrOpHdr;
  EFI_IFR_ONE_OF               *IfrOneOf;
  EFI_IFR_REF4                 *IfrRef;
  EFI_IFR_ONE_OF_OPTION        *IfrOneOfOption;
  EFI_IFR_DEFAULT              *IfrDefault;
  EFI_IFR_ORDERED_LIST         *IfrOrderedList;
  EFI_IFR_CHECKBOX             *IfrCheckBox;
  EFI_IFR_PASSWORD             *IfrPassword;
  EFI_IFR_STRING               *IfrString;
  EFI_IFR_DATE                 *IfrDate;
  EFI_IFR_TIME                 *IfrTime;
  IFR_DEFAULT_DATA             DefaultData;
  IFR_DEFAULT_DATA             *DefaultDataPtr;
  IFR_BLOCK_DATA               *BlockData;
  CHAR16                       *VarStoreName;
  UINTN                        NameSize;
  UINTN                        NvDefaultStoreSize;
  UINT16                       VarWidth;
  UINT16                       VarDefaultId;
  BOOLEAN                      FirstOneOfOption;
  BOOLEAN                      FirstOrderedList;
  LIST_ENTRY                   *LinkData;
  LIST_ENTRY                   *LinkDefault;
  EFI_IFR_VARSTORE_NAME_VALUE  *IfrNameValueVarStore;
  EFI_HII_PACKAGE_HEADER       *PackageHeader;
  EFI_VARSTORE_ID              VarStoreId;
  UINT16                       SmallestDefaultId;
  BOOLEAN                      SmallestIdFromFlag;
  BOOLEAN                      FromOtherDefaultOpcode;
  BOOLEAN                      QuestionReferBitField;
  UINT16                       *StringData;

  Status           = EFI_SUCCESS;
  BlockData        = NULL;
  DefaultDataPtr   = NULL;
  FirstOneOfOption = FALSE;
  VarStoreId       = 0;
  FirstOrderedList = FALSE;
  VarStoreName     = NULL;
  ZeroMem (&DefaultData, sizeof (IFR_DEFAULT_DATA));
  SmallestDefaultId      = 0xFFFF;
  FromOtherDefaultOpcode = FALSE;
  QuestionReferBitField  = FALSE;
  IfrEfiVarStoreTmp      = NULL;
  StringData             = NULL;

  //
  // Go through the form package to parse OpCode one by one.
  //
  PackageOffset = sizeof (EFI_HII_PACKAGE_HEADER);
  PackageHeader = (EFI_HII_PACKAGE_HEADER *)Package;
  IfrOffset     = PackageOffset;
  while (IfrOffset < PackageLength) {
    //
    // More than one form package found.
    //
    if (PackageOffset >= PackageHeader->Length) {
      //
      // Already found varstore for this request, break;
      //
      if (VarStoreId != 0) {
        VarStoreId = 0;
      }

      //
      // Get next package header info.
      //
      IfrOffset    += sizeof (EFI_HII_PACKAGE_HEADER);
      PackageOffset = sizeof (EFI_HII_PACKAGE_HEADER);
      PackageHeader = (EFI_HII_PACKAGE_HEADER *)(Package + IfrOffset);
    }

    IfrOpHdr = (EFI_IFR_OP_HEADER *)(Package + IfrOffset);
    switch (IfrOpHdr->OpCode) {
      case EFI_IFR_VARSTORE_OP:
        //
        // VarStore is found. Don't need to search any more.
        //
        if (VarStoreId != 0) {
          break;
        }

        IfrVarStore = (EFI_IFR_VARSTORE *)IfrOpHdr;

        NameSize     = AsciiStrSize ((CHAR8 *)IfrVarStore->Name);
        VarStoreName = AllocateZeroPool (NameSize * sizeof (CHAR16));
        if (VarStoreName == NULL) {
          Status = EFI_OUT_OF_RESOURCES;
          goto Done;
        }

        AsciiStrToUnicodeStrS ((CHAR8 *)IfrVarStore->Name, VarStoreName, NameSize);

        if (IsThisVarstore ((VOID *)&IfrVarStore->Guid, VarStoreName, ConfigHdr)) {
          //
          // Find the matched VarStore
          //
          CopyGuid (&VarStorageData->Guid, (EFI_GUID *)(VOID *)&IfrVarStore->Guid);
          VarStorageData->Size = IfrVarStore->Size;
          VarStorageData->Name = VarStoreName;
          VarStorageData->Type = EFI_HII_VARSTORE_BUFFER;
          VarStoreId           = IfrVarStore->VarStoreId;
        } else {
          FreePool (VarStoreName);
          VarStoreName = NULL;
        }

        break;

      case EFI_IFR_VARSTORE_EFI_OP:
        //
        // VarStore is found. Don't need to search any more.
        //
        if (VarStoreId != 0) {
          break;
        }

        IfrEfiVarStore = (EFI_IFR_VARSTORE_EFI *)IfrOpHdr;

        //
        // If the length is small than the structure, this is from old efi
        // varstore definition. Old efi varstore get config directly from
        // GetVariable function.
        //
        if (IfrOpHdr->Length < sizeof (EFI_IFR_VARSTORE_EFI)) {
          break;
        }

        NameSize     = AsciiStrSize ((CHAR8 *)IfrEfiVarStore->Name);
        VarStoreName = AllocateZeroPool (NameSize * sizeof (CHAR16));
        if (VarStoreName == NULL) {
          Status = EFI_OUT_OF_RESOURCES;
          goto Done;
        }

        AsciiStrToUnicodeStrS ((CHAR8 *)IfrEfiVarStore->Name, VarStoreName, NameSize);
        if (IfrEfiVarStoreTmp != NULL) {
          FreePool (IfrEfiVarStoreTmp);
        }

        IfrEfiVarStoreTmp = AllocatePool (IfrEfiVarStore->Header.Length + AsciiStrSize ((CHAR8 *)IfrEfiVarStore->Name));
        if (IfrEfiVarStoreTmp == NULL) {
          Status = EFI_OUT_OF_RESOURCES;
          goto Done;
        }

        CopyMem (IfrEfiVarStoreTmp, IfrEfiVarStore, IfrEfiVarStore->Header.Length);
        AsciiStrToUnicodeStrS ((CHAR8 *)IfrEfiVarStore->Name, (CHAR16 *)&(IfrEfiVarStoreTmp->Name[0]), AsciiStrSize ((CHAR8 *)IfrEfiVarStore->Name) * sizeof (CHAR16));

        if (IsThisVarstore (&IfrEfiVarStore->Guid, VarStoreName, ConfigHdr)) {
          //
          // Find the matched VarStore
          //
          CopyGuid (&VarStorageData->Guid, (EFI_GUID *)(VOID *)&IfrEfiVarStore->Guid);
          VarStorageData->Size = IfrEfiVarStore->Size;
          VarStorageData->Name = VarStoreName;
          VarStorageData->Type = EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER;
          VarStoreId           = IfrEfiVarStore->VarStoreId;
        } else {
          FreePool (VarStoreName);
          VarStoreName = NULL;
        }

        break;

      case EFI_IFR_VARSTORE_NAME_VALUE_OP:
        //
        // VarStore is found. Don't need to search any more.
        //
        if (VarStoreId != 0) {
          break;
        }

        IfrNameValueVarStore = (EFI_IFR_VARSTORE_NAME_VALUE *)IfrOpHdr;

        if (IsThisVarstore (&IfrNameValueVarStore->Guid, NULL, ConfigHdr)) {
          //
          // Find the matched VarStore
          //
          CopyGuid (&VarStorageData->Guid, (EFI_GUID *)(VOID *)&IfrNameValueVarStore->Guid);
          VarStorageData->Type = EFI_HII_VARSTORE_NAME_VALUE;
          VarStoreId           = IfrNameValueVarStore->VarStoreId;
        }

        break;

      case EFI_IFR_DEFAULTSTORE_OP:
        //
        // Add new the map between default id and default name.
        //
        DefaultDataPtr = (IFR_DEFAULT_DATA *)AllocateZeroPool (sizeof (IFR_DEFAULT_DATA));
        if (DefaultDataPtr == NULL) {
          Status = EFI_OUT_OF_RESOURCES;
          goto Done;
        }

        DefaultDataPtr->DefaultId = ((EFI_IFR_DEFAULTSTORE *)IfrOpHdr)->DefaultId;
        InsertTailList (&DefaultIdArray->Entry, &DefaultDataPtr->Entry);
        DefaultDataPtr = NULL;
        break;

      case EFI_IFR_FORM_OP:
      case EFI_IFR_FORM_MAP_OP:
        //
        // No matched varstore is found and directly return.
        //
        if ( VarStoreId == 0) {
          Status = EFI_SUCCESS;
          goto Done;
        }

        break;

      case EFI_IFR_REF_OP:
        //
        // Ref question is not in IFR Form. This IFR form is not valid.
        //
        if ( VarStoreId == 0) {
          Status = EFI_INVALID_PARAMETER;
          goto Done;
        }

        //
        // Check whether this question is for the requested varstore.
        //
        IfrRef = (EFI_IFR_REF4 *)IfrOpHdr;
        if (IfrRef->Question.VarStoreId != VarStoreId) {
          break;
        }

        VarWidth = (UINT16)(sizeof (EFI_HII_REF));

        //
        // The BlockData may allocate by other opcode,need to clean.
        //
        if (BlockData != NULL) {
          BlockData = NULL;
        }

        Status = IsThisOpcodeRequired (RequestBlockArray, HiiHandle, VarStorageData, IfrOpHdr, VarWidth, &BlockData, FALSE);
        if (EFI_ERROR (Status)) {
          if (Status == EFI_NOT_FOUND) {
            //
            // The opcode is not required,exit and parse other opcode.
            //
            break;
          }

          goto Done;
        }

        break;

      case EFI_IFR_ONE_OF_OP:
      case EFI_IFR_NUMERIC_OP:
        //
        // Numeric and OneOf has the same opcode structure.
        //

        //
        // Numeric and OneOf question is not in IFR Form. This IFR form is not valid.
        //
        if (VarStoreId == 0) {
          Status = EFI_INVALID_PARAMETER;
          goto Done;
        }

        //
        // Check whether this question is for the requested varstore.
        //
        IfrOneOf = (EFI_IFR_ONE_OF *)IfrOpHdr;
        if (IfrOneOf->Question.VarStoreId != VarStoreId) {
          break;
        }

        if (QuestionReferBitField) {
          VarWidth = IfrOneOf->Flags & EDKII_IFR_NUMERIC_SIZE_BIT;
        } else {
          VarWidth = (UINT16)(1 << (IfrOneOf->Flags & EFI_IFR_NUMERIC_SIZE));
        }

        //
        // The BlockData may allocate by other opcode,need to clean.
        //
        if (BlockData != NULL) {
          BlockData = NULL;
        }

        Status = IsThisOpcodeRequired (RequestBlockArray, HiiHandle, VarStorageData, IfrOpHdr, VarWidth, &BlockData, QuestionReferBitField);
        if (EFI_ERROR (Status)) {
          if (Status == EFI_NOT_FOUND) {
            //
            // The opcode is not required,exit and parse other opcode.
            //
            break;
          }

          goto Done;
        }

        //
        // when go to there,BlockData can't be NULLL.
        //
        ASSERT (BlockData != NULL);

        if (IfrOpHdr->OpCode == EFI_IFR_ONE_OF_OP) {
          //
          // Set this flag to TRUE for the first oneof option.
          //
          FirstOneOfOption = TRUE;
        } else if (IfrOpHdr->OpCode == EFI_IFR_NUMERIC_OP) {
          //
          // Numeric minimum value will be used as default value when no default is specified.
          //
          DefaultData.Type = DefaultValueFromDefault;
          if (QuestionReferBitField) {
            //
            // Since default value in bit field was stored as UINT32 type.
            //
            CopyMem (&DefaultData.Value.u32, &IfrOneOf->data.u32.MinValue, sizeof (UINT32));
          } else {
            switch (IfrOneOf->Flags & EFI_IFR_NUMERIC_SIZE) {
              case EFI_IFR_NUMERIC_SIZE_1:
                DefaultData.Value.u8 = IfrOneOf->data.u8.MinValue;
                break;

              case EFI_IFR_NUMERIC_SIZE_2:
                CopyMem (&DefaultData.Value.u16, &IfrOneOf->data.u16.MinValue, sizeof (UINT16));
                break;

              case EFI_IFR_NUMERIC_SIZE_4:
                CopyMem (&DefaultData.Value.u32, &IfrOneOf->data.u32.MinValue, sizeof (UINT32));
                break;

              case EFI_IFR_NUMERIC_SIZE_8:
                CopyMem (&DefaultData.Value.u64, &IfrOneOf->data.u64.MinValue, sizeof (UINT64));
                break;

              default:
                Status = EFI_INVALID_PARAMETER;
                goto Done;
            }
          }

          //
          // Set default value base on the DefaultId list get from IFR data.
          //
          NvDefaultStoreSize = PcdGetSize (PcdNvStoreDefaultValueBuffer);
          for (LinkData = DefaultIdArray->Entry.ForwardLink; LinkData != &DefaultIdArray->Entry; LinkData = LinkData->ForwardLink) {
            DefaultDataPtr        = BASE_CR (LinkData, IFR_DEFAULT_DATA, Entry);
            DefaultData.DefaultId = DefaultDataPtr->DefaultId;
            if (NvDefaultStoreSize > sizeof (PCD_NV_STORE_DEFAULT_BUFFER_HEADER)) {
              FindQuestionDefaultSetting (DefaultData.DefaultId, IfrEfiVarStoreTmp, &(IfrOneOf->Question), &DefaultData.Value, VarWidth, QuestionReferBitField);
            }

            InsertDefaultValue (BlockData, &DefaultData);
          }
        }

        break;

      case EFI_IFR_ORDERED_LIST_OP:
        //
        // offset by question header
        // width by EFI_IFR_ORDERED_LIST MaxContainers * OneofOption Type
        //

        FirstOrderedList = TRUE;
        //
        // OrderedList question is not in IFR Form. This IFR form is not valid.
        //
        if (VarStoreId == 0) {
          Status = EFI_INVALID_PARAMETER;
          goto Done;
        }

        //
        // Check whether this question is for the requested varstore.
        //
        IfrOrderedList = (EFI_IFR_ORDERED_LIST *)IfrOpHdr;
        if (IfrOrderedList->Question.VarStoreId != VarStoreId) {
          BlockData = NULL;
          break;
        }

        VarWidth = IfrOrderedList->MaxContainers;

        //
        // The BlockData may allocate by other opcode,need to clean.
        //
        if (BlockData != NULL) {
          BlockData = NULL;
        }

        Status = IsThisOpcodeRequired (RequestBlockArray, HiiHandle, VarStorageData, IfrOpHdr, VarWidth, &BlockData, FALSE);
        if (EFI_ERROR (Status)) {
          if (Status == EFI_NOT_FOUND) {
            //
            // The opcode is not required,exit and parse other opcode.
            //
            break;
          }

          goto Done;
        }

        break;

      case EFI_IFR_CHECKBOX_OP:
        //
        // EFI_IFR_DEFAULT_OP
        // offset by question header
        // width is 1 sizeof (BOOLEAN)
        // default id by CheckBox Flags if CheckBox flags (Default or Mau) is set, the default value is 1 to be set.
        // value by DefaultOption
        // default id by DeaultOption DefaultId can override CheckBox Flags and Default value.
        //

        //
        // CheckBox question is not in IFR Form. This IFR form is not valid.
        //
        if (VarStoreId == 0) {
          Status = EFI_INVALID_PARAMETER;
          goto Done;
        }

        //
        // Check whether this question is for the requested varstore.
        //
        IfrCheckBox = (EFI_IFR_CHECKBOX *)IfrOpHdr;
        if (IfrCheckBox->Question.VarStoreId != VarStoreId) {
          break;
        }

        VarWidth = (UINT16)sizeof (BOOLEAN);

        //
        // The BlockData may allocate by other opcode,need to clean.
        //
        if (BlockData != NULL) {
          BlockData = NULL;
        }

        if (QuestionReferBitField) {
          VarWidth = 1;
        }

        Status = IsThisOpcodeRequired (RequestBlockArray, HiiHandle, VarStorageData, IfrOpHdr, VarWidth, &BlockData, QuestionReferBitField);
        if (EFI_ERROR (Status)) {
          if (Status == EFI_NOT_FOUND) {
            //
            // The opcode is not required,exit and parse other opcode.
            //
            break;
          }

          goto Done;
        }

        //
        // when go to there,BlockData can't be NULLL.
        //
        ASSERT (BlockData != NULL);

        SmallestIdFromFlag = FALSE;

        //
        // Add default value for standard ID by CheckBox Flag
        //
        VarDefaultId = EFI_HII_DEFAULT_CLASS_STANDARD;
        //
        // Prepare new DefaultValue
        //
        DefaultData.DefaultId = VarDefaultId;
        if ((IfrCheckBox->Flags & EFI_IFR_CHECKBOX_DEFAULT) == EFI_IFR_CHECKBOX_DEFAULT) {
          //
          // When flag is set, default value is TRUE.
          //
          DefaultData.Type = DefaultValueFromFlag;
          if (QuestionReferBitField) {
            DefaultData.Value.u32 = TRUE;
          } else {
            DefaultData.Value.b = TRUE;
          }

          InsertDefaultValue (BlockData, &DefaultData);

          if (SmallestDefaultId > EFI_HII_DEFAULT_CLASS_STANDARD) {
            //
            // Record the SmallestDefaultId and update the SmallestIdFromFlag.
            //
            SmallestDefaultId  = EFI_HII_DEFAULT_CLASS_STANDARD;
            SmallestIdFromFlag = TRUE;
          }
        }

        //
        // Add default value for Manufacture ID by CheckBox Flag
        //
        VarDefaultId = EFI_HII_DEFAULT_CLASS_MANUFACTURING;
        //
        // Prepare new DefaultValue
        //
        DefaultData.DefaultId = VarDefaultId;
        if ((IfrCheckBox->Flags & EFI_IFR_CHECKBOX_DEFAULT_MFG) == EFI_IFR_CHECKBOX_DEFAULT_MFG) {
          //
          // When flag is set, default value is TRUE.
          //
          DefaultData.Type = DefaultValueFromFlag;
          if (QuestionReferBitField) {
            DefaultData.Value.u32 = TRUE;
          } else {
            DefaultData.Value.b = TRUE;
          }

          InsertDefaultValue (BlockData, &DefaultData);

          if (SmallestDefaultId > EFI_HII_DEFAULT_CLASS_MANUFACTURING) {
            //
            // Record the SmallestDefaultId and update the SmallestIdFromFlag.
            //
            SmallestDefaultId  = EFI_HII_DEFAULT_CLASS_MANUFACTURING;
            SmallestIdFromFlag = TRUE;
          }
        }

        if (SmallestIdFromFlag) {
          //
          // When smallest default Id is given by the  flag of CheckBox, set default value with TRUE for other default Id in the DefaultId list.
          //
          DefaultData.Type = DefaultValueFromOtherDefault;
          if (QuestionReferBitField) {
            DefaultData.Value.u32 = TRUE;
          } else {
            DefaultData.Value.b = TRUE;
          }

          //
          // Set default value for all the default id in the DefaultId list.
          //
          for (LinkData = DefaultIdArray->Entry.ForwardLink; LinkData != &DefaultIdArray->Entry; LinkData = LinkData->ForwardLink) {
            DefaultDataPtr        = BASE_CR (LinkData, IFR_DEFAULT_DATA, Entry);
            DefaultData.DefaultId = DefaultDataPtr->DefaultId;
            InsertDefaultValue (BlockData, &DefaultData);
          }
        } else {
          //
          // When flag is not set, default value is FALSE.
          //
          DefaultData.Type = DefaultValueFromDefault;
          if (QuestionReferBitField) {
            DefaultData.Value.u32 = FALSE;
          } else {
            DefaultData.Value.b = FALSE;
          }

          //
          // Set default value for all the default id in the DefaultId list.
          //
          for (LinkData = DefaultIdArray->Entry.ForwardLink; LinkData != &DefaultIdArray->Entry; LinkData = LinkData->ForwardLink) {
            DefaultDataPtr        = BASE_CR (LinkData, IFR_DEFAULT_DATA, Entry);
            DefaultData.DefaultId = DefaultDataPtr->DefaultId;
            InsertDefaultValue (BlockData, &DefaultData);
          }
        }

        break;

      case EFI_IFR_DATE_OP:
        //
        // offset by question header
        // width MaxSize * sizeof (CHAR16)
        // no default value, only block array
        //

        //
        // Date question is not in IFR Form. This IFR form is not valid.
        //
        if (VarStoreId == 0) {
          Status = EFI_INVALID_PARAMETER;
          goto Done;
        }

        //
        // Check whether this question is for the requested varstore.
        //
        IfrDate = (EFI_IFR_DATE *)IfrOpHdr;
        if (IfrDate->Question.VarStoreId != VarStoreId) {
          break;
        }

        //
        // The BlockData may allocate by other opcode,need to clean.
        //
        if (BlockData != NULL) {
          BlockData = NULL;
        }

        VarWidth = (UINT16)sizeof (EFI_HII_DATE);
        Status   = IsThisOpcodeRequired (RequestBlockArray, HiiHandle, VarStorageData, IfrOpHdr, VarWidth, &BlockData, FALSE);
        if (EFI_ERROR (Status)) {
          if (Status == EFI_NOT_FOUND) {
            //
            // The opcode is not required,exit and parse other opcode.
            //
            break;
          }

          goto Done;
        }

        break;

      case EFI_IFR_TIME_OP:
        //
        // offset by question header
        // width MaxSize * sizeof (CHAR16)
        // no default value, only block array
        //

        //
        // Time question is not in IFR Form. This IFR form is not valid.
        //
        if (VarStoreId == 0) {
          Status = EFI_INVALID_PARAMETER;
          goto Done;
        }

        //
        // Check whether this question is for the requested varstore.
        //
        IfrTime = (EFI_IFR_TIME *)IfrOpHdr;
        if (IfrTime->Question.VarStoreId != VarStoreId) {
          break;
        }

        //
        // The BlockData may allocate by other opcode,need to clean.
        //
        if (BlockData != NULL) {
          BlockData = NULL;
        }

        VarWidth = (UINT16)sizeof (EFI_HII_TIME);
        Status   = IsThisOpcodeRequired (RequestBlockArray, HiiHandle, VarStorageData, IfrOpHdr, VarWidth, &BlockData, FALSE);
        if (EFI_ERROR (Status)) {
          if (Status == EFI_NOT_FOUND) {
            //
            // The opcode is not required,exit and parse other opcode.
            //
            break;
          }

          goto Done;
        }

        break;

      case EFI_IFR_STRING_OP:
        //
        // offset by question header
        // width MaxSize * sizeof (CHAR16)
        // no default value, only block array
        //

        //
        // String question is not in IFR Form. This IFR form is not valid.
        //
        if (VarStoreId == 0) {
          Status = EFI_INVALID_PARAMETER;
          goto Done;
        }

        //
        // Check whether this question is for the requested varstore.
        //
        IfrString = (EFI_IFR_STRING *)IfrOpHdr;
        if (IfrString->Question.VarStoreId != VarStoreId) {
          break;
        }

        //
        // The BlockData may allocate by other opcode,need to clean.
        //
        if (BlockData != NULL) {
          BlockData = NULL;
        }

        VarWidth = (UINT16)(IfrString->MaxSize * sizeof (UINT16));
        Status   = IsThisOpcodeRequired (RequestBlockArray, HiiHandle, VarStorageData, IfrOpHdr, VarWidth, &BlockData, FALSE);
        if (EFI_ERROR (Status)) {
          if (Status == EFI_NOT_FOUND) {
            //
            // The opcode is not required,exit and parse other opcode.
            //
            break;
          }

          goto Done;
        }

        if (IfrEfiVarStoreTmp == NULL) {
          break;
        }

        //
        // Set default value base on the DefaultId list get from IFR data.
        //
        NvDefaultStoreSize = PcdGetSize (PcdNvStoreDefaultValueBuffer);
        for (LinkData = DefaultIdArray->Entry.ForwardLink; LinkData != &DefaultIdArray->Entry; LinkData = LinkData->ForwardLink) {
          DefaultDataPtr        = BASE_CR (LinkData, IFR_DEFAULT_DATA, Entry);
          DefaultData.DefaultId = DefaultDataPtr->DefaultId;
          if (NvDefaultStoreSize > sizeof (PCD_NV_STORE_DEFAULT_BUFFER_HEADER)) {
            StringData = AllocateZeroPool (VarWidth*2);
            if (StringData == NULL) {
              Status = EFI_OUT_OF_RESOURCES;
              goto Done;
            }

            FindQuestionDefaultSetting (DefaultData.DefaultId, IfrEfiVarStoreTmp, &(IfrString->Question), (VOID *)StringData, VarWidth, QuestionReferBitField);
            if ((DefaultData.Value.string != 0) && (StringData != NULL)) {
              DefaultData.Value.string = InternalHiiSetString (HiiHandle, 0, StringData, NULL);
              InsertDefaultValue (BlockData, &DefaultData);
              FreePool (StringData);
            }
          }
        }

        break;

      case EFI_IFR_PASSWORD_OP:
        //
        // offset by question header
        // width MaxSize * sizeof (CHAR16)
        // no default value, only block array
        //

        //
        // Password question is not in IFR Form. This IFR form is not valid.
        //
        if (VarStoreId == 0) {
          Status = EFI_INVALID_PARAMETER;
          goto Done;
        }

        //
        // Check whether this question is for the requested varstore.
        //
        IfrPassword = (EFI_IFR_PASSWORD *)IfrOpHdr;
        if (IfrPassword->Question.VarStoreId != VarStoreId) {
          break;
        }

        //
        // The BlockData may allocate by other opcode,need to clean.
        //
        if (BlockData != NULL) {
          BlockData = NULL;
        }

        VarWidth = (UINT16)(IfrPassword->MaxSize * sizeof (UINT16));
        Status   = IsThisOpcodeRequired (RequestBlockArray, HiiHandle, VarStorageData, IfrOpHdr, VarWidth, &BlockData, FALSE);
        if (EFI_ERROR (Status)) {
          if (Status == EFI_NOT_FOUND) {
            //
            // The opcode is not required,exit and parse other opcode.
            //
            break;
          }

          goto Done;
        }

        //
        // No default value for string.
        //
        BlockData = NULL;
        break;

      case EFI_IFR_ONE_OF_OPTION_OP:
        //
        // No matched block data is ignored.
        //
        if ((BlockData == NULL) || (BlockData->Scope == 0)) {
          break;
        }

        IfrOneOfOption = (EFI_IFR_ONE_OF_OPTION *)IfrOpHdr;
        if (BlockData->OpCode == EFI_IFR_ORDERED_LIST_OP) {
          if (!FirstOrderedList) {
            break;
          }

          //
          // Get ordered list option data type.
          //
          if ((IfrOneOfOption->Type == EFI_IFR_TYPE_NUM_SIZE_8) || (IfrOneOfOption->Type == EFI_IFR_TYPE_BOOLEAN)) {
            VarWidth = 1;
          } else if (IfrOneOfOption->Type == EFI_IFR_TYPE_NUM_SIZE_16) {
            VarWidth = 2;
          } else if (IfrOneOfOption->Type == EFI_IFR_TYPE_NUM_SIZE_32) {
            VarWidth = 4;
          } else if (IfrOneOfOption->Type == EFI_IFR_TYPE_NUM_SIZE_64) {
            VarWidth = 8;
          } else {
            //
            // Invalid ordered list option data type.
            //
            Status = EFI_INVALID_PARAMETER;
            if (BlockData->Name != NULL) {
              FreePool (BlockData->Name);
            }

            FreePool (BlockData);
            goto Done;
          }

          //
          // Calculate Ordered list QuestionId width.
          //
          BlockData->Width = (UINT16)(BlockData->Width * VarWidth);
          //
          // Check whether this question is in requested block array.
          //
          if (!BlockArrayCheck (RequestBlockArray, BlockData->Offset, BlockData->Width, (BOOLEAN)(BlockData->Name != NULL), HiiHandle)) {
            //
            // This question is not in the requested string. Skip it.
            //
            if (BlockData->Name != NULL) {
              FreePool (BlockData->Name);
            }

            FreePool (BlockData);
            BlockData = NULL;
            break;
          }

          //
          // Check this var question is in the var storage
          //
          if ((BlockData->Name == NULL) && ((BlockData->Offset + BlockData->Width) > VarStorageData->Size)) {
            Status = EFI_INVALID_PARAMETER;
            FreePool (BlockData);
            goto Done;
          }

          //
          // Add Block Data into VarStorageData BlockEntry
          //
          InsertBlockData (&VarStorageData->BlockEntry, &BlockData);

          FirstOrderedList = FALSE;

          break;
        }

        //
        // 1. Set default value for OneOf option when flag field has default attribute.
        //    And set the default value with the smallest default id for other default id in the DefaultId list.
        //
        if (((IfrOneOfOption->Flags & EFI_IFR_OPTION_DEFAULT) == EFI_IFR_OPTION_DEFAULT) ||
            ((IfrOneOfOption->Flags & EFI_IFR_OPTION_DEFAULT_MFG) == EFI_IFR_OPTION_DEFAULT_MFG))
        {
          //
          // This flag is used to specify whether this option is the first. Set it to FALSE for the following options.
          // The first oneof option value will be used as default value when no default value is specified.
          //
          FirstOneOfOption = FALSE;

          SmallestIdFromFlag = FALSE;

          // Prepare new DefaultValue
          //
          DefaultData.Type = DefaultValueFromFlag;
          CopyMem (&DefaultData.Value, &IfrOneOfOption->Value, IfrOneOfOption->Header.Length - OFFSET_OF (EFI_IFR_ONE_OF_OPTION, Value));
          if ((IfrOneOfOption->Flags & EFI_IFR_OPTION_DEFAULT) == EFI_IFR_OPTION_DEFAULT) {
            DefaultData.DefaultId = EFI_HII_DEFAULT_CLASS_STANDARD;
            InsertDefaultValue (BlockData, &DefaultData);
            if (SmallestDefaultId > EFI_HII_DEFAULT_CLASS_STANDARD) {
              //
              // Record the SmallestDefaultId and update the SmallestIdFromFlag.
              //
              SmallestDefaultId  = EFI_HII_DEFAULT_CLASS_STANDARD;
              SmallestIdFromFlag = TRUE;
            }
          }

          if ((IfrOneOfOption->Flags & EFI_IFR_OPTION_DEFAULT_MFG) == EFI_IFR_OPTION_DEFAULT_MFG) {
            DefaultData.DefaultId = EFI_HII_DEFAULT_CLASS_MANUFACTURING;
            InsertDefaultValue (BlockData, &DefaultData);
            if (SmallestDefaultId > EFI_HII_DEFAULT_CLASS_MANUFACTURING) {
              //
              // Record the SmallestDefaultId and update the SmallestIdFromFlag.
              //
              SmallestDefaultId  = EFI_HII_DEFAULT_CLASS_MANUFACTURING;
              SmallestIdFromFlag = TRUE;
            }
          }

          if (SmallestIdFromFlag) {
            //
            // When smallest default Id is given by the flag of oneofOption, set this option value for other default Id in the DefaultId list.
            //
            DefaultData.Type = DefaultValueFromOtherDefault;
            //
            // Set default value for other default id in the DefaultId list.
            //
            for (LinkData = DefaultIdArray->Entry.ForwardLink; LinkData != &DefaultIdArray->Entry; LinkData = LinkData->ForwardLink) {
              DefaultDataPtr        = BASE_CR (LinkData, IFR_DEFAULT_DATA, Entry);
              DefaultData.DefaultId = DefaultDataPtr->DefaultId;
              InsertDefaultValue (BlockData, &DefaultData);
            }
          }
        }

        //
        // 2. Set as the default value when this is the first option.
        // The first oneof option value will be used as default value when no default value is specified.
        //
        if (FirstOneOfOption) {
          // This flag is used to specify whether this option is the first. Set it to FALSE for the following options.
          FirstOneOfOption = FALSE;

          //
          // Prepare new DefaultValue
          //
          DefaultData.Type = DefaultValueFromDefault;
          CopyMem (&DefaultData.Value, &IfrOneOfOption->Value, IfrOneOfOption->Header.Length - OFFSET_OF (EFI_IFR_ONE_OF_OPTION, Value));
          for (LinkData = DefaultIdArray->Entry.ForwardLink; LinkData != &DefaultIdArray->Entry; LinkData = LinkData->ForwardLink) {
            DefaultDataPtr        = BASE_CR (LinkData, IFR_DEFAULT_DATA, Entry);
            DefaultData.DefaultId = DefaultDataPtr->DefaultId;
            InsertDefaultValue (BlockData, &DefaultData);
          }
        }

        break;

      case EFI_IFR_DEFAULT_OP:
        //
        // Update Current BlockData to the default value.
        //
        if ((BlockData == NULL) || (BlockData->Scope == 0)) {
          //
          // No matched block data is ignored.
          //
          break;
        }

        //
        // Get the DefaultId
        //
        IfrDefault   = (EFI_IFR_DEFAULT *)IfrOpHdr;
        VarDefaultId = IfrDefault->DefaultId;
        //
        // Prepare new DefaultValue
        //
        DefaultData.Type      = DefaultValueFromOpcode;
        DefaultData.DefaultId = VarDefaultId;
        if (QuestionReferBitField) {
          CopyMem (&DefaultData.Value.u32, &IfrDefault->Value.u32, sizeof (UINT32));
        } else {
          CopyMem (&DefaultData.Value, &IfrDefault->Value, IfrDefault->Header.Length - OFFSET_OF (EFI_IFR_DEFAULT, Value));
        }

        // If the value field is expression, set the cleaned flag.
        if (IfrDefault->Type ==  EFI_IFR_TYPE_OTHER) {
          DefaultData.Cleaned = TRUE;
        }

        //
        // Add DefaultValue into current BlockData
        //
        InsertDefaultValue (BlockData, &DefaultData);

        //
        // Set default value for other default id in the DefaultId list.
        // when SmallestDefaultId == VarDefaultId means there are two defaults with same default Id.
        // If the two defaults are both from default opcode, use the first default as the default value of other default Id.
        // If one from flag and the other form default opcode, use the default opcode value as the default value of other default Id.
        //
        if ((SmallestDefaultId > VarDefaultId) || ((SmallestDefaultId == VarDefaultId) && !FromOtherDefaultOpcode)) {
          FromOtherDefaultOpcode = TRUE;
          SmallestDefaultId      = VarDefaultId;
          for (LinkData = DefaultIdArray->Entry.ForwardLink; LinkData != &DefaultIdArray->Entry; LinkData = LinkData->ForwardLink) {
            DefaultDataPtr = BASE_CR (LinkData, IFR_DEFAULT_DATA, Entry);
            if (DefaultDataPtr->DefaultId != DefaultData.DefaultId) {
              DefaultData.Type      = DefaultValueFromOtherDefault;
              DefaultData.DefaultId = DefaultDataPtr->DefaultId;
              InsertDefaultValue (BlockData, &DefaultData);
            }
          }
        }

        //
        // After insert the default value, reset the cleaned value for next
        // time used. If not set here, need to set the value before every time.
        // use it.
        //
        DefaultData.Cleaned = FALSE;
        break;

      case EFI_IFR_END_OP:
        //
        // End Opcode is for Var question.
        //
        QuestionReferBitField = FALSE;
        if (BlockData != NULL) {
          if (BlockData->Scope > 0) {
            BlockData->Scope--;
          }

          if (BlockData->Scope == 0) {
            BlockData = NULL;
            //
            // when finishing parsing a question, clean the SmallestDefaultId and GetDefaultFromDefaultOpcode.
            //
            SmallestDefaultId      = 0xFFFF;
            FromOtherDefaultOpcode = FALSE;
          }
        }

        break;

      case EFI_IFR_GUID_OP:
        if (CompareGuid ((EFI_GUID *)((UINT8 *)IfrOpHdr + sizeof (EFI_IFR_OP_HEADER)), &gEdkiiIfrBitVarstoreGuid)) {
          QuestionReferBitField = TRUE;
        }

        break;

      default:
        if (BlockData != NULL) {
          if (BlockData->Scope > 0) {
            BlockData->Scope = (UINT8)(BlockData->Scope + IfrOpHdr->Scope);
          }

          if (BlockData->Scope == 0) {
            BlockData = NULL;
          }
        }

        break;
    }

    IfrOffset     += IfrOpHdr->Length;
    PackageOffset += IfrOpHdr->Length;
  }

  //
  // if Status == EFI_NOT_FOUND, just means the opcode is not required,not contain any error,
  // so set the Status to EFI_SUCCESS.
  //
  if (Status == EFI_NOT_FOUND) {
    Status = EFI_SUCCESS;
  }

Done:
  for (LinkData = VarStorageData->BlockEntry.ForwardLink; LinkData != &VarStorageData->BlockEntry; LinkData = LinkData->ForwardLink) {
    BlockData = BASE_CR (LinkData, IFR_BLOCK_DATA, Entry);
    for (LinkDefault = BlockData->DefaultValueEntry.ForwardLink; LinkDefault != &BlockData->DefaultValueEntry; ) {
      DefaultDataPtr = BASE_CR (LinkDefault, IFR_DEFAULT_DATA, Entry);
      LinkDefault    = LinkDefault->ForwardLink;
      if (DefaultDataPtr->Cleaned == TRUE) {
        RemoveEntryList (&DefaultDataPtr->Entry);
        FreePool (DefaultDataPtr);
      }
    }
  }

  if (IfrEfiVarStoreTmp != NULL) {
    FreePool (IfrEfiVarStoreTmp);
  }

  return Status;
}

/**
  parse the configrequest string, get the elements.

  @param      ConfigRequest         The input configrequest string.
  @param      Progress              Return the progress data.

  @retval     Block data pointer.
**/
IFR_BLOCK_DATA *
GetBlockElement (
  IN  EFI_STRING  ConfigRequest,
  OUT EFI_STRING  *Progress
  )
{
  EFI_STRING      StringPtr;
  IFR_BLOCK_DATA  *BlockData;
  IFR_BLOCK_DATA  *RequestBlockArray;
  EFI_STATUS      Status;
  UINT8           *TmpBuffer;
  UINT16          Offset;
  UINT16          Width;
  LIST_ENTRY      *Link;
  IFR_BLOCK_DATA  *NextBlockData;
  UINTN           Length;

  TmpBuffer = NULL;

  //
  // Init RequestBlockArray
  //
  RequestBlockArray = (IFR_BLOCK_DATA *)AllocateZeroPool (sizeof (IFR_BLOCK_DATA));
  if (RequestBlockArray == NULL) {
    goto Done;
  }

  InitializeListHead (&RequestBlockArray->Entry);

  //
  // Get the request Block array from the request string
  // Offset and Width
  //

  //
  // Parse each <RequestElement> if exists
  // Only <BlockName> format is supported by this help function.
  // <BlockName> ::= &'OFFSET='<Number>&'WIDTH='<Number>
  //
  StringPtr = ConfigRequest;
  while (*StringPtr != 0 && StrnCmp (StringPtr, L"&OFFSET=", StrLen (L"&OFFSET=")) == 0) {
    //
    // Skip the OFFSET string
    //
    *Progress  = StringPtr;
    StringPtr += StrLen (L"&OFFSET=");
    //
    // Get Offset
    //
    Status = GetValueOfNumber (StringPtr, &TmpBuffer, &Length);
    if (EFI_ERROR (Status)) {
      goto Done;
    }

    Offset = 0;
    CopyMem (
      &Offset,
      TmpBuffer,
      (((Length + 1) / 2) < sizeof (UINT16)) ? ((Length + 1) / 2) : sizeof (UINT16)
      );
    FreePool (TmpBuffer);

    StringPtr += Length;
    if (StrnCmp (StringPtr, L"&WIDTH=", StrLen (L"&WIDTH=")) != 0) {
      goto Done;
    }

    StringPtr += StrLen (L"&WIDTH=");

    //
    // Get Width
    //
    Status = GetValueOfNumber (StringPtr, &TmpBuffer, &Length);
    if (EFI_ERROR (Status)) {
      goto Done;
    }

    Width = 0;
    CopyMem (
      &Width,
      TmpBuffer,
      (((Length + 1) / 2) < sizeof (UINT16)) ? ((Length + 1) / 2) : sizeof (UINT16)
      );
    FreePool (TmpBuffer);

    StringPtr += Length;
    if ((*StringPtr != 0) && (*StringPtr != L'&')) {
      goto Done;
    }

    //
    // Set Block Data
    //
    BlockData = (IFR_BLOCK_DATA *)AllocateZeroPool (sizeof (IFR_BLOCK_DATA));
    if (BlockData == NULL) {
      goto Done;
    }

    BlockData->Offset = Offset;
    BlockData->Width  = Width;
    InsertBlockData (&RequestBlockArray->Entry, &BlockData);

    //
    // Skip &VALUE string if &VALUE does exists.
    //
    if (StrnCmp (StringPtr, L"&VALUE=", StrLen (L"&VALUE=")) == 0) {
      StringPtr += StrLen (L"&VALUE=");

      //
      // Get Value
      //
      Status = GetValueOfNumber (StringPtr, &TmpBuffer, &Length);
      if (EFI_ERROR (Status)) {
        goto Done;
      }

      FreePool (TmpBuffer);
      StringPtr += Length;
      if ((*StringPtr != 0) && (*StringPtr != L'&')) {
        goto Done;
      }
    }

    //
    // If '\0', parsing is finished.
    //
    if (*StringPtr == 0) {
      break;
    }
  }

  //
  // Merge the requested block data.
  //
  Link = RequestBlockArray->Entry.ForwardLink;
  while ((Link != &RequestBlockArray->Entry) && (Link->ForwardLink != &RequestBlockArray->Entry)) {
    BlockData     = BASE_CR (Link, IFR_BLOCK_DATA, Entry);
    NextBlockData = BASE_CR (Link->ForwardLink, IFR_BLOCK_DATA, Entry);
    if ((NextBlockData->Offset >= BlockData->Offset) && (NextBlockData->Offset <= (BlockData->Offset + BlockData->Width))) {
      if ((NextBlockData->Offset + NextBlockData->Width) > (BlockData->Offset + BlockData->Width)) {
        BlockData->Width = (UINT16)(NextBlockData->Offset + NextBlockData->Width - BlockData->Offset);
      }

      RemoveEntryList (Link->ForwardLink);
      FreePool (NextBlockData);
      continue;
    }

    Link = Link->ForwardLink;
  }

  return RequestBlockArray;

Done:
  if (RequestBlockArray != NULL) {
    //
    // Free Link Array RequestBlockArray
    //
    while (!IsListEmpty (&RequestBlockArray->Entry)) {
      BlockData = BASE_CR (RequestBlockArray->Entry.ForwardLink, IFR_BLOCK_DATA, Entry);
      RemoveEntryList (&BlockData->Entry);
      FreePool (BlockData);
    }

    FreePool (RequestBlockArray);
  }

  return NULL;
}

/**
  parse the configrequest string, get the elements.

  @param      ConfigRequest         The input config request string.
  @param      Progress              Return the progress data.

  @retval     return data block array.
**/
IFR_BLOCK_DATA *
GetNameElement (
  IN  EFI_STRING  ConfigRequest,
  OUT EFI_STRING  *Progress
  )
{
  EFI_STRING      StringPtr;
  EFI_STRING      NextTag;
  IFR_BLOCK_DATA  *BlockData;
  IFR_BLOCK_DATA  *RequestBlockArray;
  BOOLEAN         HasValue;

  if (ConfigRequest == NULL) {
    return NULL;
  }

  StringPtr = ConfigRequest;

  //
  // Init RequestBlockArray
  //
  RequestBlockArray = (IFR_BLOCK_DATA *)AllocateZeroPool (sizeof (IFR_BLOCK_DATA));
  if (RequestBlockArray == NULL) {
    goto Done;
  }

  InitializeListHead (&RequestBlockArray->Entry);

  //
  // Get the request Block array from the request string
  //

  //
  // Parse each <RequestElement> if exists
  // Only <BlockName> format is supported by this help function.
  // <BlockName> ::= &'Name***=***
  //
  while (StringPtr != NULL && *StringPtr == L'&') {
    *Progress = StringPtr;
    //
    // Skip the L"&" string
    //
    StringPtr += 1;

    HasValue = FALSE;
    if ((NextTag = StrStr (StringPtr, L"=")) != NULL) {
      *NextTag = L'\0';
      HasValue = TRUE;
    } else if ((NextTag = StrStr (StringPtr, L"&")) != NULL) {
      *NextTag = L'\0';
    } else {
      goto Done;
    }

    //
    // Set Block Data
    //
    BlockData = (IFR_BLOCK_DATA *)AllocateZeroPool (sizeof (IFR_BLOCK_DATA));
    if (BlockData == NULL) {
      goto Done;
    }

    //
    // Get Name
    //
    BlockData->Name = AllocateCopyPool (StrSize (StringPtr), StringPtr);
    InsertBlockData (&RequestBlockArray->Entry, &BlockData);

    if (HasValue) {
      //
      // If has value, skip the value.
      //
      StringPtr = NextTag + 1;
      *NextTag  = L'=';
      StringPtr = StrStr (StringPtr, L"&");
    } else if (NextTag != NULL) {
      //
      // restore the '&' text.
      //
      StringPtr = NextTag;
      *NextTag  = L'&';
    }
  }

  return RequestBlockArray;

Done:
  if (RequestBlockArray != NULL) {
    //
    // Free Link Array RequestBlockArray
    //
    while (!IsListEmpty (&RequestBlockArray->Entry)) {
      BlockData = BASE_CR (RequestBlockArray->Entry.ForwardLink, IFR_BLOCK_DATA, Entry);
      RemoveEntryList (&BlockData->Entry);
      if (BlockData->Name != NULL) {
        FreePool (BlockData->Name);
      }

      FreePool (BlockData);
    }

    FreePool (RequestBlockArray);
  }

  return NULL;
}

/**
  Generate ConfigRequest string base on the varstore info.

  @param      ConfigHdr             The config header for this varstore.
  @param      VarStorageData        The varstore info.
  @param      Status                Return Status.
  @param      ConfigRequest         The ConfigRequest info may be return.

  @retval     TRUE                  Need to continue
  @retval     Others                NO need to continue or error occur.
**/
BOOLEAN
GenerateConfigRequest (
  IN  CHAR16               *ConfigHdr,
  IN  IFR_VARSTORAGE_DATA  *VarStorageData,
  OUT EFI_STATUS           *Status,
  IN OUT EFI_STRING        *ConfigRequest
  )
{
  BOOLEAN         DataExist;
  UINTN           Length;
  LIST_ENTRY      *Link;
  CHAR16          *FullConfigRequest;
  CHAR16          *StringPtr;
  IFR_BLOCK_DATA  *BlockData;

  //
  // Append VarStorageData BlockEntry into *Request string
  // Now support only one varstore in a form package.
  //

  //
  // Go through all VarStorageData Entry and get BlockEntry for each one for the multiple varstore in a single form package
  // Then construct them all to return MultiRequest string : ConfigHdr BlockConfig
  //

  //
  // Compute the length of the entire request starting with <ConfigHdr> and a
  // Null-terminator
  //
  DataExist = FALSE;
  Length    = StrLen (ConfigHdr) + 1;

  for (Link = VarStorageData->BlockEntry.ForwardLink; Link != &VarStorageData->BlockEntry; Link = Link->ForwardLink) {
    DataExist = TRUE;
    BlockData = BASE_CR (Link, IFR_BLOCK_DATA, Entry);
    if (VarStorageData->Type == EFI_HII_VARSTORE_NAME_VALUE) {
      //
      // Add <BlockName> length for each Name
      //
      // <BlockName> ::= &Name1&Name2&...
      //                 |1| StrLen(Name1)
      //
      Length = Length + (1 + StrLen (BlockData->Name));
    } else {
      //
      // Add <BlockName> length for each Offset/Width pair
      //
      // <BlockName> ::= &OFFSET=1234&WIDTH=1234
      //                 |  8   | 4 |   7  | 4 |
      //
      Length = Length + (8 + 4 + 7 + 4);
    }
  }

  //
  // No any request block data is found. The request string can't be constructed.
  //
  if (!DataExist) {
    *Status = EFI_SUCCESS;
    return FALSE;
  }

  //
  // Allocate buffer for the entire <ConfigRequest>
  //
  FullConfigRequest = AllocateZeroPool (Length * sizeof (CHAR16));
  if (FullConfigRequest == NULL) {
    *Status = EFI_OUT_OF_RESOURCES;
    return FALSE;
  }

  StringPtr = FullConfigRequest;

  //
  // Start with <ConfigHdr>
  //
  StrCpyS (StringPtr, Length, ConfigHdr);
  StringPtr += StrLen (StringPtr);

  //
  // Loop through all the Offset/Width pairs and append them to ConfigRequest
  //
  for (Link = VarStorageData->BlockEntry.ForwardLink; Link != &VarStorageData->BlockEntry; Link = Link->ForwardLink) {
    BlockData = BASE_CR (Link, IFR_BLOCK_DATA, Entry);
    if (VarStorageData->Type == EFI_HII_VARSTORE_NAME_VALUE) {
      //
      // Append &Name1\0
      //
      UnicodeSPrint (
        StringPtr,
        (1 + StrLen (BlockData->Name) + 1) * sizeof (CHAR16),
        L"&%s",
        BlockData->Name
        );
    } else {
      //
      // Append &OFFSET=XXXX&WIDTH=YYYY\0
      //
      UnicodeSPrint (
        StringPtr,
        (8 + 4 + 7 + 4 + 1) * sizeof (CHAR16),
        L"&OFFSET=%04X&WIDTH=%04X",
        BlockData->Offset,
        BlockData->Width
        );
    }

    StringPtr += StrLen (StringPtr);
  }

  //
  // Set to the got full request string.
  //
  HiiToLower (FullConfigRequest);

  if (*ConfigRequest != NULL) {
    FreePool (*ConfigRequest);
  }

  *ConfigRequest = FullConfigRequest;

  return TRUE;
}

/**
  Generate ConfigRequest Header base on the varstore info.

  @param      VarStorageData        The varstore info.
  @param      DevicePath            Device path for this varstore.
  @param      ConfigHdr             The config header for this varstore.

  @retval     EFI_SUCCESS           Generate the header success.
  @retval     EFI_OUT_OF_RESOURCES  Allocate buffer fail.
**/
EFI_STATUS
GenerateHdr (
  IN   IFR_VARSTORAGE_DATA       *VarStorageData,
  IN   EFI_DEVICE_PATH_PROTOCOL  *DevicePath,
  OUT  EFI_STRING                *ConfigHdr
  )
{
  EFI_STRING  GuidStr;
  EFI_STRING  NameStr;
  EFI_STRING  PathStr;
  UINTN       Length;
  EFI_STATUS  Status;

  Status  = EFI_SUCCESS;
  NameStr = NULL;
  GuidStr = NULL;
  PathStr = NULL;

  //
  // Construct <ConfigHdr> : "GUID=...&NAME=...&PATH=..." by VarStorageData Guid, Name and DriverHandle
  //
  GenerateSubStr (L"GUID=", sizeof (EFI_GUID), (VOID *)&VarStorageData->Guid, 1, &GuidStr);
  if (VarStorageData->Name != NULL) {
    GenerateSubStr (L"NAME=", StrLen (VarStorageData->Name) * sizeof (CHAR16), (VOID *)VarStorageData->Name, 2, &NameStr);
  } else {
    GenerateSubStr (L"NAME=", 0, NULL, 2, &NameStr);
  }

  GenerateSubStr (
    L"PATH=",
    GetDevicePathSize ((EFI_DEVICE_PATH_PROTOCOL *)DevicePath),
    (VOID *)DevicePath,
    1,
    &PathStr
    );
  Length = StrLen (GuidStr) + StrLen (NameStr) + StrLen (PathStr) + 1;
  if (VarStorageData->Name == NULL) {
    Length += 1;
  }

  *ConfigHdr = AllocateZeroPool (Length * sizeof (CHAR16));
  if (*ConfigHdr == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto Done;
  }

  StrCpyS (*ConfigHdr, Length, GuidStr);
  StrCatS (*ConfigHdr, Length, NameStr);
  if (VarStorageData->Name == NULL) {
    StrCatS (*ConfigHdr, Length, L"&");
  }

  StrCatS (*ConfigHdr, Length, PathStr);

  //
  // Remove the last character L'&'
  //
  *(*ConfigHdr + StrLen (*ConfigHdr) - 1) = L'\0';

Done:
  if (GuidStr != NULL) {
    FreePool (GuidStr);
  }

  if (NameStr != NULL) {
    FreePool (NameStr);
  }

  if (PathStr != NULL) {
    FreePool (PathStr);
  }

  return Status;
}

/**
  Update the default value in the block data which is used as bit var store.

  For example:
  A question value saved in a bit fied: bitoffset = 1; bitwidth = 2;default value = 1.
  And corresponding block data info: offset==0; width==1;currently the default value
  is saved as 1.Actually the default value 1 need to be set to bit field 1, so the
  default value of this block data shuold be:2.

  typedef struct {
    UINT8  Bit1 : 1; //
    UINT8  Bit2 : 2; // Question saved in Bit2,so originalBlock info: offset = 0; width = 1;(byte level) defaul = 1.
                     // (default value record for the bit field)
    ......
  }ExampleData;

  After function UpdateDefaultValue,the Block info is: offset = 0; width = 1;(byte level) default = 2.
                                                       (default value record for the Block)

  UpdateDefaultValue function update default value of bit var block based on the bit field info in the block.

  @param  BlockLink     The Link of the block data.

**/
VOID
UpdateDefaultValue (
  IN LIST_ENTRY  *BlockLink
  )
{
  LIST_ENTRY        *Link;
  LIST_ENTRY        *ListEntry;
  LIST_ENTRY        *LinkDefault;
  IFR_BLOCK_DATA    *BlockData;
  IFR_DEFAULT_DATA  *DefaultValueData;
  UINTN             StartBit;
  UINTN             EndBit;
  UINT32            BitFieldDefaultValue;

  for ( Link = BlockLink->ForwardLink; Link != BlockLink; Link = Link->ForwardLink) {
    BlockData = BASE_CR (Link, IFR_BLOCK_DATA, Entry);
    if (!BlockData->IsBitVar) {
      continue;
    }

    ListEntry = &BlockData->DefaultValueEntry;
    //
    // Update the default value in the block data with all existing default id.
    //
    for (LinkDefault = ListEntry->ForwardLink; LinkDefault != ListEntry; LinkDefault = LinkDefault->ForwardLink) {
      //
      // Get the default data, and the value of the default data is for some field in the block.
      // Note: Default value for bit field question is stored as UINT32.
      //
      DefaultValueData     = BASE_CR (LinkDefault, IFR_DEFAULT_DATA, Entry);
      BitFieldDefaultValue = DefaultValueData->Value.u32;

      StartBit = BlockData->BitOffset % 8;
      EndBit   = StartBit + BlockData->BitWidth - 1;

      //
      // Set the bit field default value to related bit filed, then we will got the new default vaule for the block data.
      //
      DefaultValueData->Value.u32 = BitFieldWrite32 (0, StartBit, EndBit, BitFieldDefaultValue);
    }
  }
}

/**
Merge the default value in two block datas which have overlap region.

For bit fields, their related block data may have overlap region, such as:

typedef struct {
  UINT16  Bit1 : 6;  // Question1 refer Bit1, Block1: offset = 0; width = 1;(byte level) default = 1
  UINT16  Bit2 : 5;  // Question2 refer Bit2, Block2: offset = 0; width = 2;(byte level) default = 5
                     // (default value record for the bit field)
  ......
}ExampleData;

After function UpdateDefaultValue:
Block1: offset = 0; width = 1;(byte level) default = 1
Block2: offset = 0; width = 2;(byte level) default = 320 (5 * (2 << 6))
(default value record for block)

After function MergeBlockDefaultValue:
Block1: offset = 0; width = 1;(byte level) default = 65
Block2: offset = 0; width = 2;(byte level) default = 321
(Block1 and Block2 has overlap region, merge the overlap value to Block1 and Blcok2)

Block1 and Block2 have overlap byte region, but currntly the default value of Block1 only contains
value of Bit1 (low 6 bits),the default value of Block2 only contains the value of Bit2 (middle 5 bits).

This fuction merge the default value of these two blocks, and make the default value of block1
also contain the value of lower 2 bits of the Bit2. And make the default value of Block2 also
contain the default value of Bit1.

We can get the total value of the whole block that just cover these two blocks(in this case is:
block: offset =0; width =2;) then the value of block2 is same as block, the value of block1 is
the first byte value of block.

@param  FirstBlock     Point to the block date whose default value need to be merged.
@param  SecondBlock    Point to the block date whose default value need to be merged.

**/
VOID
MergeBlockDefaultValue (
  IN OUT IFR_BLOCK_DATA  *FirstBlock,
  IN OUT IFR_BLOCK_DATA  *SecondBlock
  )
{
  LIST_ENTRY        *FirstListEntry;
  LIST_ENTRY        *SecondListEntry;
  LIST_ENTRY        *FirstDefaultLink;
  LIST_ENTRY        *SecondDefaultLink;
  IFR_DEFAULT_DATA  *FirstDefaultValueData;
  IFR_DEFAULT_DATA  *SecondDefaultValueData;
  UINT32            *FirstDefaultValue;
  UINT32            *SecondDefaultValue;
  UINT64            TotalValue;
  UINT64            ShiftedValue;
  UINT16            OffsetShift;

  FirstListEntry = &FirstBlock->DefaultValueEntry;
  for (FirstDefaultLink = FirstListEntry->ForwardLink; FirstDefaultLink != FirstListEntry; FirstDefaultLink = FirstDefaultLink->ForwardLink) {
    FirstDefaultValueData = BASE_CR (FirstDefaultLink, IFR_DEFAULT_DATA, Entry);
    SecondListEntry       = &SecondBlock->DefaultValueEntry;
    for (SecondDefaultLink = SecondListEntry->ForwardLink; SecondDefaultLink != SecondListEntry; SecondDefaultLink = SecondDefaultLink->ForwardLink) {
      SecondDefaultValueData = BASE_CR (SecondDefaultLink, IFR_DEFAULT_DATA, Entry);
      if (FirstDefaultValueData->DefaultId != SecondDefaultValueData->DefaultId) {
        continue;
      }

      //
      // Find default value with same default id in the two blocks.
      // Note: Default value for bit field question is stored as UINT32 type.
      //
      FirstDefaultValue  = &FirstDefaultValueData->Value.u32;
      SecondDefaultValue = &SecondDefaultValueData->Value.u32;
      //
      // 1. Get the default value of the whole blcok that can just cover FirstBlock and SecondBlock.
      // 2. Get the default value of FirstBlock and SecondBlock form the value of whole block based
      //    on the offset and width of FirstBlock and SecondBlock.
      //
      if (FirstBlock->Offset > SecondBlock->Offset) {
        OffsetShift         = FirstBlock->Offset - SecondBlock->Offset;
        ShiftedValue        = LShiftU64 ((UINT64)(*FirstDefaultValue), OffsetShift * 8);
        TotalValue          = ShiftedValue | (UINT64)(*SecondDefaultValue);
        *SecondDefaultValue = (UINT32)BitFieldRead64 (TotalValue, 0, SecondBlock->Width * 8 -1);
        *FirstDefaultValue  = (UINT32)BitFieldRead64 (TotalValue, OffsetShift * 8, OffsetShift * 8 + FirstBlock->Width *8 -1);
      } else {
        OffsetShift         = SecondBlock->Offset -FirstBlock->Offset;
        ShiftedValue        = LShiftU64 ((UINT64)(*SecondDefaultValue), OffsetShift * 8);
        TotalValue          = ShiftedValue | (UINT64)(*FirstDefaultValue);
        *FirstDefaultValue  = (UINT32)BitFieldRead64 (TotalValue, 0, FirstBlock->Width * 8 -1);
        *SecondDefaultValue = (UINT32)BitFieldRead64 (TotalValue, OffsetShift * 8, OffsetShift * 8 + SecondBlock->Width *8 -1);
      }
    }
  }
}

/**

Update the default value in the block data which used as Bit VarStore

@param  BlockLink     The Link of the block data.

**/
VOID
UpdateBlockDataArray (
  IN LIST_ENTRY  *BlockLink
  )
{
  LIST_ENTRY      *Link;
  LIST_ENTRY      *TempLink;
  IFR_BLOCK_DATA  *BlockData;
  IFR_BLOCK_DATA  *NextBlockData;

  //
  // 1. Update default value in BitVar block data.
  // Sine some block datas are used as BitVarStore, then the default value recored in the block
  // is for related bit field in the block. so we need to set the default value to the related bit
  // fields in the block data if the block data is used as bit varstore, then the default value of
  // the block will be updated.
  //
  UpdateDefaultValue (BlockLink);

  //
  // 2.Update default value for overlap BitVar blcok datas.
  // For block datas have overlap region, we need to merge the default value in different blocks.
  //
  for (Link = BlockLink->ForwardLink; Link != BlockLink; Link = Link->ForwardLink) {
    BlockData = BASE_CR (Link, IFR_BLOCK_DATA, Entry);
    if (!BlockData->IsBitVar) {
      continue;
    }

    for (TempLink = Link->ForwardLink; TempLink != BlockLink; TempLink = TempLink->ForwardLink) {
      NextBlockData = BASE_CR (TempLink, IFR_BLOCK_DATA, Entry);
      if (!NextBlockData->IsBitVar || (NextBlockData->Offset >= BlockData->Offset + BlockData->Width) || (BlockData->Offset >= NextBlockData->Offset + NextBlockData->Width)) {
        continue;
      }

      //
      // Find two blocks are used as bit VarStore and have overlap region, so need to merge default value of these two blocks.
      //
      MergeBlockDefaultValue (BlockData, NextBlockData);
    }
  }
}

/**
  Generate ConfigAltResp string base on the varstore info.

  @param      HiiHandle             Hii Handle for this hii package.
  @param      ConfigHdr             The config header for this varstore.
  @param      VarStorageData        The varstore info.
  @param      DefaultIdArray        The Default id array.
  @param      DefaultAltCfgResp     The DefaultAltCfgResp info may be return.

  @retval     TRUE                  Need to continue
  @retval     Others                NO need to continue or error occur.
**/
EFI_STATUS
GenerateAltConfigResp (
  IN  EFI_HII_HANDLE       HiiHandle,
  IN  CHAR16               *ConfigHdr,
  IN  IFR_VARSTORAGE_DATA  *VarStorageData,
  IN  IFR_DEFAULT_DATA     *DefaultIdArray,
  IN OUT EFI_STRING        *DefaultAltCfgResp
  )
{
  BOOLEAN           DataExist;
  UINTN             Length;
  LIST_ENTRY        *Link;
  LIST_ENTRY        *LinkData;
  LIST_ENTRY        *LinkDefault;
  LIST_ENTRY        *ListEntry;
  CHAR16            *StringPtr;
  IFR_BLOCK_DATA    *BlockData;
  IFR_DEFAULT_DATA  *DefaultId;
  IFR_DEFAULT_DATA  *DefaultValueData;
  UINTN             Width;
  UINT8             *TmpBuffer;
  CHAR16            *DefaultString;
  UINTN             StrSize;

  BlockData     = NULL;
  DataExist     = FALSE;
  DefaultString = NULL;
  //
  // Add length for <ConfigHdr> + '\0'
  //
  Length = StrLen (ConfigHdr) + 1;

  UpdateBlockDataArray (&VarStorageData->BlockEntry);

  for (Link = DefaultIdArray->Entry.ForwardLink; Link != &DefaultIdArray->Entry; Link = Link->ForwardLink) {
    DefaultId = BASE_CR (Link, IFR_DEFAULT_DATA, Entry);
    //
    // Add length for "&<ConfigHdr>&ALTCFG=XXXX"
    //                |1| StrLen (ConfigHdr) | 8 | 4 |
    //
    Length += (1 + StrLen (ConfigHdr) + 8 + 4);

    for (LinkData = VarStorageData->BlockEntry.ForwardLink; LinkData != &VarStorageData->BlockEntry; LinkData = LinkData->ForwardLink) {
      BlockData = BASE_CR (LinkData, IFR_BLOCK_DATA, Entry);
      ListEntry = &BlockData->DefaultValueEntry;
      for (LinkDefault = ListEntry->ForwardLink; LinkDefault != ListEntry; LinkDefault = LinkDefault->ForwardLink) {
        DefaultValueData = BASE_CR (LinkDefault, IFR_DEFAULT_DATA, Entry);
        if (DefaultValueData->DefaultId != DefaultId->DefaultId) {
          continue;
        }

        if (VarStorageData->Type == EFI_HII_VARSTORE_NAME_VALUE) {
          //
          // Add length for "&Name1=zzzzzzzzzzzz"
          //                |1|Name|1|Value|
          //
          Length += (1 + StrLen (BlockData->Name) + 1 + BlockData->Width * 2);
        } else {
          //
          // Add length for "&OFFSET=XXXX&WIDTH=YYYY&VALUE=zzzzzzzzzzzz"
          //                |    8  | 4 |   7  | 4 |   7  | Width * 2 |
          //
          Length += (8 + 4 + 7 + 4 + 7 + BlockData->Width * 2);
        }

        DataExist = TRUE;
      }
    }
  }

  //
  // No default value is found. The default string doesn't exist.
  //
  if (!DataExist) {
    return EFI_SUCCESS;
  }

  //
  // Allocate buffer for the entire <DefaultAltCfgResp>
  //
  *DefaultAltCfgResp = AllocateZeroPool (Length * sizeof (CHAR16));
  if (*DefaultAltCfgResp == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  StringPtr = *DefaultAltCfgResp;

  //
  // Start with <ConfigHdr>
  //
  StrCpyS (StringPtr, Length, ConfigHdr);
  StringPtr += StrLen (StringPtr);

  for (Link = DefaultIdArray->Entry.ForwardLink; Link != &DefaultIdArray->Entry; Link = Link->ForwardLink) {
    DefaultId = BASE_CR (Link, IFR_DEFAULT_DATA, Entry);
    //
    // Add <AltConfigHdr> of the form "&<ConfigHdr>&ALTCFG=XXXX\0"
    //                                |1| StrLen (ConfigHdr) | 8 | 4 |
    //
    UnicodeSPrint (
      StringPtr,
      (1 + StrLen (ConfigHdr) + 8 + 4 + 1) * sizeof (CHAR16),
      L"&%s&ALTCFG=%04X",
      ConfigHdr,
      DefaultId->DefaultId
      );
    StringPtr += StrLen (StringPtr);

    for (LinkData = VarStorageData->BlockEntry.ForwardLink; LinkData != &VarStorageData->BlockEntry; LinkData = LinkData->ForwardLink) {
      BlockData = BASE_CR (LinkData, IFR_BLOCK_DATA, Entry);
      ListEntry = &BlockData->DefaultValueEntry;
      for (LinkDefault = ListEntry->ForwardLink; LinkDefault != ListEntry; LinkDefault = LinkDefault->ForwardLink) {
        DefaultValueData = BASE_CR (LinkDefault, IFR_DEFAULT_DATA, Entry);
        if (DefaultValueData->DefaultId != DefaultId->DefaultId) {
          continue;
        }

        if (VarStorageData->Type == EFI_HII_VARSTORE_NAME_VALUE) {
          UnicodeSPrint (
            StringPtr,
            (1 + StrLen (ConfigHdr) + 1) * sizeof (CHAR16),
            L"&%s=",
            BlockData->Name
            );
          StringPtr += StrLen (StringPtr);
        } else {
          //
          // Add <BlockConfig>
          // <BlockConfig> ::= 'OFFSET='<Number>&'WIDTH='<Number>&'VALUE'=<Number>
          //
          UnicodeSPrint (
            StringPtr,
            (8 + 4 + 7 + 4 + 7 + 1) * sizeof (CHAR16),
            L"&OFFSET=%04X&WIDTH=%04X&VALUE=",
            BlockData->Offset,
            BlockData->Width
            );
          StringPtr += StrLen (StringPtr);
        }

        Width = BlockData->Width;
        //
        // Convert Value to a hex string in "%x" format
        // NOTE: This is in the opposite byte that GUID and PATH use
        //
        if ((BlockData->OpCode == EFI_IFR_STRING_OP) && (DefaultValueData->Value.string != 0)) {
          DefaultString = InternalGetString (HiiHandle, DefaultValueData->Value.string);
          TmpBuffer     = AllocateZeroPool (Width);
          ASSERT (TmpBuffer != NULL);
          if (DefaultString != NULL) {
            StrSize = StrLen (DefaultString)* sizeof (CHAR16);
            if (StrSize > Width) {
              StrSize = Width;
            }

            CopyMem (TmpBuffer, (UINT8 *)DefaultString, StrSize);
          }
        } else {
          TmpBuffer = (UINT8 *)&(DefaultValueData->Value);
        }

        for ( ; Width > 0 && (TmpBuffer != NULL); Width--) {
          UnicodeValueToStringS (
            StringPtr,
            Length * sizeof (CHAR16) - ((UINTN)StringPtr - (UINTN)*DefaultAltCfgResp),
            PREFIX_ZERO | RADIX_HEX,
            TmpBuffer[Width - 1],
            2
            );
          StringPtr += StrnLenS (StringPtr, Length - ((UINTN)StringPtr - (UINTN)*DefaultAltCfgResp) / sizeof (CHAR16));
        }

        if (DefaultString != NULL) {
          FreePool (DefaultString);
          DefaultString = NULL;
        }

        if ((BlockData->OpCode == EFI_IFR_STRING_OP) && (DefaultValueData->Value.string != 0) && (TmpBuffer != NULL)) {
          FreePool (TmpBuffer);
          TmpBuffer = NULL;
        }
      }
    }
  }

  HiiToLower (*DefaultAltCfgResp);

  return EFI_SUCCESS;
}

/**
  This function gets the full request string and full default value string by
  parsing IFR data in HII form packages.

  When Request points to NULL string, the request string and default value string
  for each varstore in form package will return.

  @param  DataBaseRecord         The DataBaseRecord instance contains the found Hii handle and package.
  @param  DevicePath             Device Path which Hii Config Access Protocol is registered.
  @param  Request                Pointer to a null-terminated Unicode string in
                                 <ConfigRequest> format. When it doesn't contain
                                 any RequestElement, it will be updated to return
                                 the full RequestElement retrieved from IFR data.
                                 If it points to NULL, the request string for the first
                                 varstore in form package will be merged into a
                                 <MultiConfigRequest> format string and return.
  @param  AltCfgResp             Pointer to a null-terminated Unicode string in
                                 <ConfigAltResp> format. When the pointer is to NULL,
                                 the full default value string retrieved from IFR data
                                 will return. When the pinter is to a string, the
                                 full default value string retrieved from IFR data
                                 will be merged into the input string and return.
                                 When Request points to NULL, the default value string
                                 for each varstore in form package will be merged into
                                 a <MultiConfigAltResp> format string and return.
  @param  PointerProgress        Optional parameter, it can be NULL.
                                 When it is not NULL, if Request is NULL, it returns NULL.
                                 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.
  @retval EFI_SUCCESS            The Results string is set to the full request string.
                                 And AltCfgResp contains all default value string.
  @retval EFI_OUT_OF_RESOURCES   Not enough memory for the return string.
  @retval EFI_NOT_FOUND          The varstore (Guid and Name) in Request string
                                 can't be found in Form package.
  @retval EFI_NOT_FOUND          HiiPackage can't be got on the input HiiHandle.
  @retval EFI_INVALID_PARAMETER  Request points to NULL.

**/
EFI_STATUS
EFIAPI
GetFullStringFromHiiFormPackages (
  IN     HII_DATABASE_RECORD       *DataBaseRecord,
  IN     EFI_DEVICE_PATH_PROTOCOL  *DevicePath,
  IN OUT EFI_STRING                *Request,
  IN OUT EFI_STRING                *AltCfgResp,
  OUT    EFI_STRING                *PointerProgress OPTIONAL
  )
{
  EFI_STATUS           Status;
  UINT8                *HiiFormPackage;
  UINTN                PackageSize;
  IFR_BLOCK_DATA       *RequestBlockArray;
  IFR_BLOCK_DATA       *BlockData;
  IFR_DEFAULT_DATA     *DefaultValueData;
  IFR_DEFAULT_DATA     *DefaultId;
  IFR_DEFAULT_DATA     *DefaultIdArray;
  IFR_VARSTORAGE_DATA  *VarStorageData;
  EFI_STRING           DefaultAltCfgResp;
  EFI_STRING           ConfigHdr;
  EFI_STRING           StringPtr;
  EFI_STRING           Progress;

  if ((DataBaseRecord == NULL) || (DevicePath == NULL) || (Request == NULL) || (AltCfgResp == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Initialize the local variables.
  //
  RequestBlockArray = NULL;
  DefaultIdArray    = NULL;
  VarStorageData    = NULL;
  DefaultAltCfgResp = NULL;
  ConfigHdr         = NULL;
  HiiFormPackage    = NULL;
  PackageSize       = 0;
  Progress          = *Request;

  Status = GetFormPackageData (DataBaseRecord, &HiiFormPackage, &PackageSize);
  if (EFI_ERROR (Status)) {
    goto Done;
  }

  //
  // 1. Get the request block array by Request String when Request string contains the block array.
  //
  StringPtr = NULL;
  if (*Request != NULL) {
    StringPtr = *Request;
    //
    // Jump <ConfigHdr>
    //
    if (StrnCmp (StringPtr, L"GUID=", StrLen (L"GUID=")) != 0) {
      Status = EFI_INVALID_PARAMETER;
      goto Done;
    }

    StringPtr += StrLen (L"GUID=");
    while (*StringPtr != L'\0' && StrnCmp (StringPtr, L"&NAME=", StrLen (L"&NAME=")) != 0) {
      StringPtr++;
    }

    if (*StringPtr == L'\0') {
      Status = EFI_INVALID_PARAMETER;
      goto Done;
    }

    StringPtr += StrLen (L"&NAME=");
    while (*StringPtr != L'\0' && StrnCmp (StringPtr, L"&PATH=", StrLen (L"&PATH=")) != 0) {
      StringPtr++;
    }

    if (*StringPtr == L'\0') {
      Status = EFI_INVALID_PARAMETER;
      goto Done;
    }

    StringPtr += StrLen (L"&PATH=");
    while (*StringPtr != L'\0' && *StringPtr != L'&') {
      StringPtr++;
    }

    if (*StringPtr == L'\0') {
      //
      // No request block is found.
      //
      StringPtr = NULL;
    }
  }

  //
  // If StringPtr != NULL, get the request elements.
  //
  if (StringPtr != NULL) {
    if (StrStr (StringPtr, L"&OFFSET=") != NULL) {
      RequestBlockArray = GetBlockElement (StringPtr, &Progress);
    } else {
      RequestBlockArray = GetNameElement (StringPtr, &Progress);
    }

    if (RequestBlockArray == NULL) {
      Status = EFI_INVALID_PARAMETER;
      goto Done;
    }
  }

  //
  // Initialize DefaultIdArray to store the map between DeaultId and DefaultName
  //
  DefaultIdArray = (IFR_DEFAULT_DATA *)AllocateZeroPool (sizeof (IFR_DEFAULT_DATA));
  if (DefaultIdArray == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto Done;
  }

  InitializeListHead (&DefaultIdArray->Entry);

  //
  // Initialize VarStorageData to store the var store Block and Default value information.
  //
  VarStorageData = (IFR_VARSTORAGE_DATA *)AllocateZeroPool (sizeof (IFR_VARSTORAGE_DATA));
  if (VarStorageData == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto Done;
  }

  InitializeListHead (&VarStorageData->Entry);
  InitializeListHead (&VarStorageData->BlockEntry);

  //
  // 2. Parse FormPackage to get BlockArray and DefaultId Array for the request BlockArray.
  //

  //
  // Parse the opcode in form package to get the default setting.
  //
  Status = ParseIfrData (
             DataBaseRecord->Handle,
             HiiFormPackage,
             (UINT32)PackageSize,
             *Request,
             RequestBlockArray,
             VarStorageData,
             DefaultIdArray
             );
  if (EFI_ERROR (Status)) {
    goto Done;
  }

  //
  // No requested varstore in IFR data and directly return
  //
  if ((VarStorageData->Type == 0) && (VarStorageData->Name == NULL)) {
    Status = EFI_SUCCESS;
    goto Done;
  }

  //
  // 3. Construct Request Element (Block Name) for 2.1 and 2.2 case.
  //
  Status = GenerateHdr (VarStorageData, DevicePath, &ConfigHdr);
  if (EFI_ERROR (Status)) {
    goto Done;
  }

  if (RequestBlockArray == NULL) {
    if (!GenerateConfigRequest (ConfigHdr, VarStorageData, &Status, Request)) {
      goto Done;
    }
  }

  //
  // 4. Construct Default Value string in AltResp according to request element.
  // Go through all VarStorageData Entry and get the DefaultId array for each one
  // Then construct them all to : ConfigHdr AltConfigHdr ConfigBody AltConfigHdr ConfigBody
  //
  Status = GenerateAltConfigResp (DataBaseRecord->Handle, ConfigHdr, VarStorageData, DefaultIdArray, &DefaultAltCfgResp);
  if (EFI_ERROR (Status)) {
    goto Done;
  }

  //
  // 5. Merge string into the input AltCfgResp if the input *AltCfgResp is not NULL.
  //
  if ((*AltCfgResp != NULL) && (DefaultAltCfgResp != NULL)) {
    Status = MergeDefaultString (AltCfgResp, DefaultAltCfgResp);
    FreePool (DefaultAltCfgResp);
  } else if (*AltCfgResp == NULL) {
    *AltCfgResp = DefaultAltCfgResp;
  }

Done:
  if (RequestBlockArray != NULL) {
    //
    // Free Link Array RequestBlockArray
    //
    while (!IsListEmpty (&RequestBlockArray->Entry)) {
      BlockData = BASE_CR (RequestBlockArray->Entry.ForwardLink, IFR_BLOCK_DATA, Entry);
      RemoveEntryList (&BlockData->Entry);
      if (BlockData->Name != NULL) {
        FreePool (BlockData->Name);
      }

      FreePool (BlockData);
    }

    FreePool (RequestBlockArray);
  }

  if (VarStorageData != NULL) {
    //
    // Free link array VarStorageData
    //
    while (!IsListEmpty (&VarStorageData->BlockEntry)) {
      BlockData = BASE_CR (VarStorageData->BlockEntry.ForwardLink, IFR_BLOCK_DATA, Entry);
      RemoveEntryList (&BlockData->Entry);
      if (BlockData->Name != NULL) {
        FreePool (BlockData->Name);
      }

      //
      // Free default value link array
      //
      while (!IsListEmpty (&BlockData->DefaultValueEntry)) {
        DefaultValueData = BASE_CR (BlockData->DefaultValueEntry.ForwardLink, IFR_DEFAULT_DATA, Entry);
        RemoveEntryList (&DefaultValueData->Entry);
        FreePool (DefaultValueData);
      }

      FreePool (BlockData);
    }

    if (VarStorageData->Name != NULL) {
      FreePool (VarStorageData->Name);
      VarStorageData->Name = NULL;
    }

    FreePool (VarStorageData);
  }

  if (DefaultIdArray != NULL) {
    //
    // Free DefaultId Array
    //
    while (!IsListEmpty (&DefaultIdArray->Entry)) {
      DefaultId = BASE_CR (DefaultIdArray->Entry.ForwardLink, IFR_DEFAULT_DATA, Entry);
      RemoveEntryList (&DefaultId->Entry);
      FreePool (DefaultId);
    }

    FreePool (DefaultIdArray);
  }

  //
  // Free the allocated string
  //
  if (ConfigHdr != NULL) {
    FreePool (ConfigHdr);
  }

  //
  // Free Package data
  //
  if (HiiFormPackage != NULL) {
    FreePool (HiiFormPackage);
  }

  if (PointerProgress != NULL) {
    if (*Request == NULL) {
      *PointerProgress = NULL;
    } else if (EFI_ERROR (Status)) {
      *PointerProgress = *Request;
    } else {
      *PointerProgress = *Request + StrLen (*Request);
    }
  }

  return Status;
}

/**
  This function gets the full request resp string by
  parsing IFR data in HII form packages.

  @param  This                   A pointer to the EFI_HII_CONFIG_ROUTING_PROTOCOL
                                 instance.
  @param  EfiVarStoreInfo        The efi varstore info which is save in the EFI
                                 varstore data structure.
  @param  Request                Pointer to a null-terminated Unicode string in
                                 <ConfigRequest> format.
  @param  RequestResp            Pointer to a null-terminated Unicode string in
                                 <ConfigResp> format.
  @param  AccessProgress         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.

  @retval EFI_SUCCESS            The Results string is set to the full request string.
                                 And AltCfgResp contains all default value string.
  @retval EFI_OUT_OF_RESOURCES   Not enough memory for the return string.
  @retval EFI_INVALID_PARAMETER  Request points to NULL.

**/
EFI_STATUS
GetConfigRespFromEfiVarStore (
  IN  CONST EFI_HII_CONFIG_ROUTING_PROTOCOL  *This,
  IN  EFI_IFR_VARSTORE_EFI                   *EfiVarStoreInfo,
  IN  EFI_STRING                             Request,
  OUT EFI_STRING                             *RequestResp,
  OUT EFI_STRING                             *AccessProgress
  )
{
  EFI_STATUS  Status;
  EFI_STRING  VarStoreName;
  UINTN       NameSize;
  UINT8       *VarStore;
  UINTN       BufferSize;

  Status          = EFI_SUCCESS;
  BufferSize      = 0;
  VarStore        = NULL;
  VarStoreName    = NULL;
  *AccessProgress = Request;

  NameSize     = AsciiStrSize ((CHAR8 *)EfiVarStoreInfo->Name);
  VarStoreName = AllocateZeroPool (NameSize * sizeof (CHAR16));
  if (VarStoreName == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto Done;
  }

  AsciiStrToUnicodeStrS ((CHAR8 *)EfiVarStoreInfo->Name, VarStoreName, NameSize);

  Status = gRT->GetVariable (VarStoreName, &EfiVarStoreInfo->Guid, NULL, &BufferSize, NULL);
  if (Status != EFI_BUFFER_TOO_SMALL) {
    goto Done;
  }

  VarStore = AllocateZeroPool (BufferSize);
  ASSERT (VarStore != NULL);
  Status = gRT->GetVariable (VarStoreName, &EfiVarStoreInfo->Guid, NULL, &BufferSize, VarStore);
  if (EFI_ERROR (Status)) {
    goto Done;
  }

  Status = HiiBlockToConfig (This, Request, VarStore, BufferSize, RequestResp, AccessProgress);
  if (EFI_ERROR (Status)) {
    goto Done;
  }

Done:
  if (VarStoreName != NULL) {
    FreePool (VarStoreName);
  }

  if (VarStore != NULL) {
    FreePool (VarStore);
  }

  return Status;
}

/**
  This function route the full request resp string for efi varstore.

  @param  This                   A pointer to the EFI_HII_CONFIG_ROUTING_PROTOCOL
                                 instance.
  @param  EfiVarStoreInfo        The efi varstore info which is save in the EFI
                                 varstore data structure.
  @param  RequestResp            Pointer to a null-terminated Unicode string in
                                 <ConfigResp> format.
  @param  Result                 Pointer to a null-terminated Unicode string in
                                 <ConfigResp> format.

  @retval EFI_SUCCESS            The Results string is set to the full request string.
                                 And AltCfgResp contains all default value string.
  @retval EFI_OUT_OF_RESOURCES   Not enough memory for the return string.
  @retval EFI_INVALID_PARAMETER  Request points to NULL.

**/
EFI_STATUS
RouteConfigRespForEfiVarStore (
  IN  CONST EFI_HII_CONFIG_ROUTING_PROTOCOL  *This,
  IN  EFI_IFR_VARSTORE_EFI                   *EfiVarStoreInfo,
  IN  EFI_STRING                             RequestResp,
  OUT EFI_STRING                             *Result
  )
{
  EFI_STATUS  Status;
  EFI_STRING  VarStoreName;
  UINTN       NameSize;
  UINT8       *VarStore;
  UINTN       BufferSize;
  UINTN       BlockSize;

  Status       = EFI_SUCCESS;
  BufferSize   = 0;
  VarStore     = NULL;
  VarStoreName = NULL;
  *Result      = RequestResp;

  NameSize     = AsciiStrSize ((CHAR8 *)EfiVarStoreInfo->Name);
  VarStoreName = AllocateZeroPool (NameSize * sizeof (CHAR16));
  if (VarStoreName == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto Done;
  }

  AsciiStrToUnicodeStrS ((CHAR8 *)EfiVarStoreInfo->Name, VarStoreName, NameSize);

  Status = gRT->GetVariable (VarStoreName, &EfiVarStoreInfo->Guid, NULL, &BufferSize, NULL);
  if (Status != EFI_BUFFER_TOO_SMALL) {
    DEBUG ((DEBUG_ERROR, "The variable does not exist!"));
    goto Done;
  }

  BlockSize = BufferSize;
  VarStore  = AllocateZeroPool (BufferSize);
  ASSERT (VarStore != NULL);
  Status = gRT->GetVariable (VarStoreName, &EfiVarStoreInfo->Guid, NULL, &BufferSize, VarStore);
  if (EFI_ERROR (Status)) {
    goto Done;
  }

  Status = HiiConfigToBlock (This, RequestResp, VarStore, &BlockSize, Result);
  if (EFI_ERROR (Status)) {
    goto Done;
  }

  Status = gRT->SetVariable (VarStoreName, &EfiVarStoreInfo->Guid, EfiVarStoreInfo->Attributes, BufferSize, VarStore);
  if (EFI_ERROR (Status)) {
    *Result = RequestResp;
    goto Done;
  }

Done:
  if (VarStoreName != NULL) {
    FreePool (VarStoreName);
  }

  if (VarStore != NULL) {
    FreePool (VarStore);
  }

  return Status;
}

/**
  Validate the config request elements.

  @param  ConfigElements                A null-terminated Unicode string in <ConfigRequest> format,
                                        without configHdr field.

  @retval     CHAR16 *    THE first Name/value pair not correct.
  @retval     NULL        Success parse the name/value pair
**/
CHAR16 *
OffsetWidthValidate (
  CHAR16  *ConfigElements
  )
{
  CHAR16  *StringPtr;
  CHAR16  *RetVal;

  StringPtr = ConfigElements;

  while (1) {
    RetVal = StringPtr;
    if (StrnCmp (StringPtr, L"&OFFSET=", StrLen (L"&OFFSET=")) != 0) {
      return RetVal;
    }

    while (*StringPtr != L'\0' && StrnCmp (StringPtr, L"&WIDTH=", StrLen (L"&WIDTH=")) != 0) {
      StringPtr++;
    }

    if (*StringPtr == L'\0') {
      return RetVal;
    }

    StringPtr += StrLen (L"&WIDTH=");
    while (*StringPtr != L'\0' && StrnCmp (StringPtr, L"&OFFSET=", StrLen (L"&OFFSET=")) != 0) {
      StringPtr++;
    }

    if (*StringPtr == L'\0') {
      return NULL;
    }
  }
}

/**
  Validate the config request elements.

  @param  ConfigElements                A null-terminated Unicode string in <ConfigRequest> format,
                                        without configHdr field.

  @retval     CHAR16 *    THE first Name/value pair not correct.
  @retval     NULL        Success parse the name/value pair

**/
CHAR16 *
NameValueValidate (
  CHAR16  *ConfigElements
  )
{
  CHAR16  *StringPtr;
  CHAR16  *RetVal;

  StringPtr = ConfigElements;

  while (1) {
    RetVal = StringPtr;
    if (*StringPtr != L'&') {
      return RetVal;
    }

    StringPtr += 1;

    StringPtr = StrStr (StringPtr, L"&");

    if (StringPtr == NULL) {
      return NULL;
    }
  }
}

/**
  Validate the config request string.

  @param  ConfigRequest                A null-terminated Unicode string in <ConfigRequest> format.

  @retval     CHAR16 *    THE first element not correct.
  @retval     NULL        Success parse the name/value pair

**/
CHAR16 *
ConfigRequestValidate (
  CHAR16  *ConfigRequest
  )
{
  BOOLEAN  HasNameField;
  CHAR16   *StringPtr;

  HasNameField = TRUE;
  StringPtr    = ConfigRequest;

  //
  // Check <ConfigHdr>
  //
  if (StrnCmp (StringPtr, L"GUID=", StrLen (L"GUID=")) != 0) {
    return ConfigRequest;
  }

  StringPtr += StrLen (L"GUID=");
  while (*StringPtr != L'\0' && StrnCmp (StringPtr, L"&NAME=", StrLen (L"&NAME=")) != 0) {
    StringPtr++;
  }

  if (*StringPtr == L'\0') {
    return ConfigRequest;
  }

  StringPtr += StrLen (L"&NAME=");
  if (*StringPtr == L'&') {
    HasNameField = FALSE;
  }

  while (*StringPtr != L'\0' && StrnCmp (StringPtr, L"&PATH=", StrLen (L"&PATH=")) != 0) {
    StringPtr++;
  }

  if (*StringPtr == L'\0') {
    return ConfigRequest;
  }

  StringPtr += StrLen (L"&PATH=");
  while (*StringPtr != L'\0' && *StringPtr != L'&') {
    StringPtr++;
  }

  if (*StringPtr == L'\0') {
    return NULL;
  }

  if (HasNameField) {
    //
    // Should be Buffer varstore, config request should be "OFFSET/Width" pairs.
    //
    return OffsetWidthValidate (StringPtr);
  } else {
    //
    // Should be Name/Value varstore, config request should be "&name1&name2..." pairs.
    //
    return NameValueValidate (StringPtr);
  }
}

/**
  This function allows a caller to extract the current configuration
  for one or more named elements from one or more drivers.

  @param  This                   A pointer to the EFI_HII_CONFIG_ROUTING_PROTOCOL
                                 instance.
  @param  Request                A null-terminated Unicode string 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                Null-terminated Unicode string in
                                 <MultiConfigAltResp> 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 string is filled with the values
                                 corresponding to all requested names.
  @retval EFI_OUT_OF_RESOURCES   Not enough memory to store the parts of the
                                 results that must be stored awaiting possible
                                 future        protocols.
  @retval EFI_NOT_FOUND          Routing data doesn't match any known driver.
                                   Progress set to the "G" in "GUID" of the routing
                                  header that doesn't match. Note: There is no
                                    requirement that all routing data be validated
                                 before any configuration extraction.
  @retval EFI_INVALID_PARAMETER  For example, passing in a NULL for the Request
                                 parameter would result in this type of error. The
                                 Progress parameter is set to NULL.
  @retval EFI_INVALID_PARAMETER  Illegal syntax. Progress set to most recent &
                                 before the error or the beginning of the string.
  @retval EFI_INVALID_PARAMETER  The ExtractConfig function of the underlying HII
                                 Configuration Access Protocol returned
                                 EFI_INVALID_PARAMETER. Progress set to most recent
                                 & before the error or the beginning of the string.

**/
EFI_STATUS
EFIAPI
HiiConfigRoutingExtractConfig (
  IN  CONST EFI_HII_CONFIG_ROUTING_PROTOCOL  *This,
  IN  CONST EFI_STRING                       Request,
  OUT EFI_STRING                             *Progress,
  OUT EFI_STRING                             *Results
  )
{
  HII_DATABASE_PRIVATE_DATA       *Private;
  EFI_STRING                      StringPtr;
  EFI_STRING                      ConfigRequest;
  UINTN                           Length;
  EFI_DEVICE_PATH_PROTOCOL        *DevicePath;
  EFI_DEVICE_PATH_PROTOCOL        *TempDevicePath;
  EFI_STATUS                      Status;
  LIST_ENTRY                      *Link;
  HII_DATABASE_RECORD             *Database;
  UINT8                           *DevicePathPkg;
  UINT8                           *CurrentDevicePath;
  EFI_HANDLE                      DriverHandle;
  EFI_HII_HANDLE                  HiiHandle;
  EFI_HII_CONFIG_ACCESS_PROTOCOL  *ConfigAccess;
  EFI_STRING                      AccessProgress;
  EFI_STRING                      AccessResults;
  EFI_STRING                      AccessProgressBackup;
  EFI_STRING                      AccessResultsBackup;
  EFI_STRING                      DefaultResults;
  BOOLEAN                         FirstElement;
  BOOLEAN                         IfrDataParsedFlag;
  BOOLEAN                         IsEfiVarStore;
  EFI_IFR_VARSTORE_EFI            *EfiVarStoreInfo;
  EFI_STRING                      ErrorPtr;
  UINTN                           DevicePathSize;
  UINTN                           ConigStringSize;
  UINTN                           ConigStringSizeNewsize;
  EFI_STRING                      ConfigStringPtr;

  if ((This == NULL) || (Progress == NULL) || (Results == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  if (Request == NULL) {
    *Progress = NULL;
    return EFI_INVALID_PARAMETER;
  }

  Private              = CONFIG_ROUTING_DATABASE_PRIVATE_DATA_FROM_THIS (This);
  StringPtr            = Request;
  *Progress            = StringPtr;
  DefaultResults       = NULL;
  ConfigRequest        = NULL;
  Status               = EFI_SUCCESS;
  AccessResults        = NULL;
  AccessProgress       = NULL;
  AccessResultsBackup  = NULL;
  AccessProgressBackup = NULL;
  DevicePath           = NULL;
  IfrDataParsedFlag    = FALSE;
  IsEfiVarStore        = FALSE;
  EfiVarStoreInfo      = NULL;

  //
  // The first element of <MultiConfigRequest> should be
  // <GuidHdr>, which is in 'GUID='<Guid> syntax.
  //
  if (StrnCmp (StringPtr, L"GUID=", StrLen (L"GUID=")) != 0) {
    return EFI_INVALID_PARAMETER;
  }

  FirstElement = TRUE;

  //
  // Allocate a fix length of memory to store Results. Reallocate memory for
  // Results if this fix length is insufficient.
  //
  *Results = (EFI_STRING)AllocateZeroPool (MAX_STRING_LENGTH);
  if (*Results == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  while (*StringPtr != 0 && StrnCmp (StringPtr, L"GUID=", StrLen (L"GUID=")) == 0) {
    //
    // If parsing error, set Progress to the beginning of the <MultiConfigRequest>
    // or most recent & before the error.
    //
    if (StringPtr == Request) {
      *Progress = StringPtr;
    } else {
      *Progress = StringPtr - 1;
    }

    //
    // Process each <ConfigRequest> of <MultiConfigRequest>
    //
    Length        = CalculateConfigStringLen (StringPtr);
    ConfigRequest = AllocateCopyPool ((Length + 1) * sizeof (CHAR16), StringPtr);
    if (ConfigRequest == NULL) {
      Status = EFI_OUT_OF_RESOURCES;
      goto Done;
    }

    *(ConfigRequest + Length) = 0;

    //
    // Get the UEFI device path
    //
    Status = GetDevicePath (ConfigRequest, (UINT8 **)&DevicePath);
    if (EFI_ERROR (Status)) {
      goto Done;
    }

    //
    // Find driver which matches the routing data.
    //
    DriverHandle = NULL;
    HiiHandle    = NULL;
    Database     = NULL;
    for (Link = Private->DatabaseList.ForwardLink;
         Link != &Private->DatabaseList;
         Link = Link->ForwardLink
         )
    {
      Database = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);
      if ((DevicePathPkg = Database->PackageList->DevicePathPkg) != NULL) {
        CurrentDevicePath = DevicePathPkg + sizeof (EFI_HII_PACKAGE_HEADER);
        DevicePathSize    = GetDevicePathSize ((EFI_DEVICE_PATH_PROTOCOL *)CurrentDevicePath);
        if ((CompareMem (DevicePath, CurrentDevicePath, DevicePathSize) == 0) && IsThisPackageList (Database, ConfigRequest)) {
          DriverHandle = Database->DriverHandle;
          HiiHandle    = Database->Handle;
          break;
        }
      }
    }

    //
    // Try to find driver handle by device path.
    //
    if (DriverHandle == NULL) {
      TempDevicePath = DevicePath;
      Status         = gBS->LocateDevicePath (
                              &gEfiDevicePathProtocolGuid,
                              &TempDevicePath,
                              &DriverHandle
                              );
      if (EFI_ERROR (Status) || (DriverHandle == NULL)) {
        //
        // Routing data does not match any known driver.
        // Set Progress to the 'G' in "GUID" of the routing header.
        //
        *Progress = StringPtr;
        Status    = EFI_NOT_FOUND;
        goto Done;
      }
    }

    //
    // Validate ConfigRequest String.
    //
    ErrorPtr = ConfigRequestValidate (ConfigRequest);
    if (ErrorPtr != NULL) {
      *Progress = StrStr (StringPtr, ErrorPtr);
      Status    = EFI_INVALID_PARAMETER;
      goto Done;
    }

    //
    // Check whether ConfigRequest contains request string.
    //
    IfrDataParsedFlag = FALSE;
    if ((HiiHandle != NULL) && !GetElementsFromRequest (ConfigRequest)) {
      //
      // Get the full request string from IFR when HiiPackage is registered to HiiHandle
      //
      IfrDataParsedFlag = TRUE;
      Status            = GetFullStringFromHiiFormPackages (Database, DevicePath, &ConfigRequest, &DefaultResults, &AccessProgress);
      if (EFI_ERROR (Status)) {
        //
        // AccessProgress indicates the parsing progress on <ConfigRequest>.
        // Map it to the progress on <MultiConfigRequest> then return it.
        //
        ASSERT (AccessProgress != NULL);
        *Progress = StrStr (StringPtr, AccessProgress);
        goto Done;
      }

      //
      // Not any request block is found.
      //
      if (!GetElementsFromRequest (ConfigRequest)) {
        AccessResults = AllocateCopyPool (StrSize (ConfigRequest), ConfigRequest);
        goto NextConfigString;
      }
    }

    //
    // Check whether this ConfigRequest is search from Efi varstore type storage.
    //
    Status = GetVarStoreType (Database, ConfigRequest, &IsEfiVarStore, &EfiVarStoreInfo);
    if (EFI_ERROR (Status)) {
      goto Done;
    }

    if (IsEfiVarStore) {
      //
      // Call the GetVariable function to extract settings.
      //
      Status = GetConfigRespFromEfiVarStore (This, EfiVarStoreInfo, ConfigRequest, &AccessResults, &AccessProgress);
      FreePool (EfiVarStoreInfo);
      if (EFI_ERROR (Status)) {
        //
        // AccessProgress indicates the parsing progress on <ConfigRequest>.
        // Map it to the progress on <MultiConfigRequest> then return it.
        //
        *Progress = StrStr (StringPtr, AccessProgress);
        goto Done;
      }

      //
      // For EfiVarstore, call corresponding ConfigAccess protocol to get the AltCfgResp from driver.
      //
      Status = gBS->HandleProtocol (
                      DriverHandle,
                      &gEfiHiiConfigAccessProtocolGuid,
                      (VOID **)&ConfigAccess
                      );
      if (EFI_ERROR (Status)) {
        //
        // The driver has EfiVarStore, may not install ConfigAccess protocol.
        // So ignore the error status in this case.
        //
        Status = EFI_SUCCESS;
      } else {
        Status = ConfigAccess->ExtractConfig (
                                 ConfigAccess,
                                 ConfigRequest,
                                 &AccessProgressBackup,
                                 &AccessResultsBackup
                                 );
        if (!EFI_ERROR (Status)) {
          //
          // Merge the AltCfgResp in AccessResultsBackup to AccessResults
          //
          if ((AccessResultsBackup != NULL) && (StrStr (AccessResultsBackup, L"&ALTCFG=") != NULL)) {
            ConigStringSize        = StrSize (AccessResults);
            ConfigStringPtr        = StrStr (AccessResultsBackup, L"&GUID=");
            ConigStringSizeNewsize = StrSize (ConfigStringPtr) + ConigStringSize + sizeof (CHAR16);
            AccessResults          = (EFI_STRING)ReallocatePool (
                                                   ConigStringSize,
                                                   ConigStringSizeNewsize,
                                                   AccessResults
                                                   );
            StrCatS (AccessResults, ConigStringSizeNewsize / sizeof (CHAR16), ConfigStringPtr);
          }
        } else {
          //
          // In the ExtractConfig function of some driver may not support EfiVarStore,
          // may return error status, just ignore the error status in this case.
          //
          Status = EFI_SUCCESS;
        }

        if (AccessResultsBackup != NULL) {
          FreePool (AccessResultsBackup);
          AccessResultsBackup = NULL;
        }
      }
    } else {
      //
      // Call corresponding ConfigAccess protocol to extract settings
      //
      Status = gBS->HandleProtocol (
                      DriverHandle,
                      &gEfiHiiConfigAccessProtocolGuid,
                      (VOID **)&ConfigAccess
                      );
      if (EFI_ERROR (Status)) {
        goto Done;
      }

      Status = ConfigAccess->ExtractConfig (
                               ConfigAccess,
                               ConfigRequest,
                               &AccessProgress,
                               &AccessResults
                               );
    }

    if (EFI_ERROR (Status)) {
      //
      // AccessProgress indicates the parsing progress on <ConfigRequest>.
      // Map it to the progress on <MultiConfigRequest> then return it.
      //
      *Progress = StrStr (StringPtr, AccessProgress);
      goto Done;
    }

    //
    // Attach this <ConfigAltResp> to a <MultiConfigAltResp>. There is a '&'
    // which separates the first <ConfigAltResp> and the following ones.
    //
    ASSERT (*AccessProgress == 0);

    //
    // Update AccessResults by getting default setting from IFR when HiiPackage is registered to HiiHandle
    //
    if (!IfrDataParsedFlag && (HiiHandle != NULL)) {
      Status = GetFullStringFromHiiFormPackages (Database, DevicePath, &ConfigRequest, &DefaultResults, NULL);
      ASSERT_EFI_ERROR (Status);
    }

    FreePool (DevicePath);
    DevicePath = NULL;

    if (DefaultResults != NULL) {
      Status = MergeDefaultString (&AccessResults, DefaultResults);
      ASSERT_EFI_ERROR (Status);
      FreePool (DefaultResults);
      DefaultResults = NULL;
    }

NextConfigString:
    if (!FirstElement) {
      Status = AppendToMultiString (Results, L"&");
      ASSERT_EFI_ERROR (Status);
    }

    Status = AppendToMultiString (Results, AccessResults);
    ASSERT_EFI_ERROR (Status);

    FirstElement = FALSE;

    FreePool (AccessResults);
    AccessResults = NULL;
    FreePool (ConfigRequest);
    ConfigRequest = NULL;

    //
    // Go to next <ConfigRequest> (skip '&').
    //
    StringPtr += Length;
    if (*StringPtr == 0) {
      *Progress = StringPtr;
      break;
    }

    StringPtr++;
  }

Done:
  if (EFI_ERROR (Status)) {
    FreePool (*Results);
    *Results = NULL;
  }

  if (ConfigRequest != NULL) {
    FreePool (ConfigRequest);
  }

  if (AccessResults != NULL) {
    FreePool (AccessResults);
  }

  if (DefaultResults != NULL) {
    FreePool (DefaultResults);
  }

  if (DevicePath != NULL) {
    FreePool (DevicePath);
  }

  return Status;
}

/**
  This function allows the caller to request the current configuration for the
  entirety of the current HII database and returns the data in a
  null-terminated Unicode string.

  @param  This                   A pointer to the EFI_HII_CONFIG_ROUTING_PROTOCOL
                                 instance.
  @param  Results                Null-terminated Unicode string in
                                 <MultiConfigAltResp> format which has all values
                                 filled in for the entirety of the current HII
                                 database. String to be allocated by the  called
                                 function. De-allocation is up to the caller.

  @retval EFI_SUCCESS            The Results string is filled with the values
                                 corresponding to all requested names.
  @retval EFI_OUT_OF_RESOURCES   Not enough memory to store the parts of the
                                 results that must be stored awaiting possible
                                 future        protocols.
  @retval EFI_INVALID_PARAMETER  For example, passing in a NULL for the Results
                                 parameter would result in this type of error.

**/
EFI_STATUS
EFIAPI
HiiConfigRoutingExportConfig (
  IN  CONST EFI_HII_CONFIG_ROUTING_PROTOCOL  *This,
  OUT EFI_STRING                             *Results
  )
{
  EFI_STATUS                      Status;
  EFI_HII_CONFIG_ACCESS_PROTOCOL  *ConfigAccess;
  EFI_STRING                      AccessResults;
  EFI_STRING                      Progress;
  EFI_STRING                      StringPtr;
  EFI_STRING                      ConfigRequest;
  UINTN                           Index;
  EFI_HANDLE                      *ConfigAccessHandles;
  UINTN                           NumberConfigAccessHandles;
  BOOLEAN                         FirstElement;
  EFI_DEVICE_PATH_PROTOCOL        *DevicePath;
  EFI_HII_HANDLE                  HiiHandle;
  EFI_STRING                      DefaultResults;
  HII_DATABASE_PRIVATE_DATA       *Private;
  LIST_ENTRY                      *Link;
  HII_DATABASE_RECORD             *Database;
  UINT8                           *DevicePathPkg;
  UINT8                           *CurrentDevicePath;
  BOOLEAN                         IfrDataParsedFlag;

  if ((This == NULL) || (Results == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  Private = CONFIG_ROUTING_DATABASE_PRIVATE_DATA_FROM_THIS (This);

  //
  // Allocate a fix length of memory to store Results. Reallocate memory for
  // Results if this fix length is insufficient.
  //
  *Results = (EFI_STRING)AllocateZeroPool (MAX_STRING_LENGTH);
  if (*Results == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  NumberConfigAccessHandles = 0;
  Status                    = gBS->LocateHandleBuffer (
                                     ByProtocol,
                                     &gEfiHiiConfigAccessProtocolGuid,
                                     NULL,
                                     &NumberConfigAccessHandles,
                                     &ConfigAccessHandles
                                     );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  FirstElement = TRUE;

  for (Index = 0; Index < NumberConfigAccessHandles; Index++) {
    Status = gBS->HandleProtocol (
                    ConfigAccessHandles[Index],
                    &gEfiHiiConfigAccessProtocolGuid,
                    (VOID **)&ConfigAccess
                    );
    if (EFI_ERROR (Status)) {
      continue;
    }

    //
    // Get DevicePath and HiiHandle for this ConfigAccess driver handle
    //
    IfrDataParsedFlag = FALSE;
    Progress          = NULL;
    HiiHandle         = NULL;
    DefaultResults    = NULL;
    Database          = NULL;
    ConfigRequest     = NULL;
    DevicePath        = DevicePathFromHandle (ConfigAccessHandles[Index]);
    if (DevicePath != NULL) {
      for (Link = Private->DatabaseList.ForwardLink;
           Link != &Private->DatabaseList;
           Link = Link->ForwardLink
           )
      {
        Database = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);
        if ((DevicePathPkg = Database->PackageList->DevicePathPkg) != NULL) {
          CurrentDevicePath = DevicePathPkg + sizeof (EFI_HII_PACKAGE_HEADER);
          if (CompareMem (
                DevicePath,
                CurrentDevicePath,
                GetDevicePathSize ((EFI_DEVICE_PATH_PROTOCOL *)CurrentDevicePath)
                ) == 0)
          {
            HiiHandle = Database->Handle;
            break;
          }
        }
      }
    }

    Status = ConfigAccess->ExtractConfig (
                             ConfigAccess,
                             NULL,
                             &Progress,
                             &AccessResults
                             );
    if (EFI_ERROR (Status)) {
      //
      // Update AccessResults by getting default setting from IFR when HiiPackage is registered to HiiHandle
      //
      if ((HiiHandle != NULL) && (DevicePath != NULL)) {
        IfrDataParsedFlag = TRUE;
        Status            = GetFullStringFromHiiFormPackages (Database, DevicePath, &ConfigRequest, &DefaultResults, NULL);
        //
        // Get the full request string to get the Current setting again.
        //
        if (!EFI_ERROR (Status) && (ConfigRequest != NULL)) {
          Status = ConfigAccess->ExtractConfig (
                                   ConfigAccess,
                                   ConfigRequest,
                                   &Progress,
                                   &AccessResults
                                   );
          FreePool (ConfigRequest);
        } else {
          Status = EFI_NOT_FOUND;
        }
      }
    }

    if (!EFI_ERROR (Status)) {
      //
      // Update AccessResults by getting default setting from IFR when HiiPackage is registered to HiiHandle
      //
      if (!IfrDataParsedFlag && (HiiHandle != NULL) && (DevicePath != NULL)) {
        StringPtr = StrStr (AccessResults, L"&GUID=");
        if (StringPtr != NULL) {
          *StringPtr = 0;
        }

        if (GetElementsFromRequest (AccessResults)) {
          Status = GetFullStringFromHiiFormPackages (Database, DevicePath, &AccessResults, &DefaultResults, NULL);
          ASSERT_EFI_ERROR (Status);
        }

        if (StringPtr != NULL) {
          *StringPtr = L'&';
        }
      }

      //
      // Merge the default sting from IFR code into the got setting from driver.
      //
      if (DefaultResults != NULL) {
        Status = MergeDefaultString (&AccessResults, DefaultResults);
        ASSERT_EFI_ERROR (Status);
        FreePool (DefaultResults);
        DefaultResults = NULL;
      }

      //
      // Attach this <ConfigAltResp> to a <MultiConfigAltResp>. There is a '&'
      // which separates the first <ConfigAltResp> and the following ones.
      //
      if (!FirstElement) {
        Status = AppendToMultiString (Results, L"&");
        ASSERT_EFI_ERROR (Status);
      }

      Status = AppendToMultiString (Results, AccessResults);
      ASSERT_EFI_ERROR (Status);

      FirstElement = FALSE;

      FreePool (AccessResults);
      AccessResults = NULL;
    }
  }

  FreePool (ConfigAccessHandles);

  return EFI_SUCCESS;
}

/**
  This function processes the results of processing forms and routes it to the
  appropriate handlers or storage.

  @param  This                   A pointer to the EFI_HII_CONFIG_ROUTING_PROTOCOL
                                 instance.
  @param  Configuration          A null-terminated Unicode string in
                                 <MulltiConfigResp> 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 have been distributed or are awaiting
                                 distribution.
  @retval EFI_OUT_OF_RESOURCES   Not enough memory to store the parts of the
                                 results that must be stored awaiting possible
                                 future        protocols.
  @retval EFI_INVALID_PARAMETER  Passing in a NULL for the Configuration parameter
                                 would result in this type of error.
  @retval EFI_NOT_FOUND          Target for the specified routing data was not
                                 found.

**/
EFI_STATUS
EFIAPI
HiiConfigRoutingRouteConfig (
  IN  CONST EFI_HII_CONFIG_ROUTING_PROTOCOL  *This,
  IN  CONST EFI_STRING                       Configuration,
  OUT EFI_STRING                             *Progress
  )
{
  HII_DATABASE_PRIVATE_DATA       *Private;
  EFI_STRING                      StringPtr;
  EFI_STRING                      ConfigResp;
  UINTN                           Length;
  EFI_STATUS                      Status;
  EFI_DEVICE_PATH_PROTOCOL        *DevicePath;
  EFI_DEVICE_PATH_PROTOCOL        *TempDevicePath;
  LIST_ENTRY                      *Link;
  HII_DATABASE_RECORD             *Database;
  UINT8                           *DevicePathPkg;
  UINT8                           *CurrentDevicePath;
  EFI_HANDLE                      DriverHandle;
  EFI_HII_CONFIG_ACCESS_PROTOCOL  *ConfigAccess;
  EFI_STRING                      AccessProgress;
  EFI_IFR_VARSTORE_EFI            *EfiVarStoreInfo;
  BOOLEAN                         IsEfiVarstore;
  UINTN                           DevicePathSize;

  if ((This == NULL) || (Progress == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  if (Configuration == NULL) {
    *Progress = NULL;
    return EFI_INVALID_PARAMETER;
  }

  Private         = CONFIG_ROUTING_DATABASE_PRIVATE_DATA_FROM_THIS (This);
  StringPtr       = Configuration;
  *Progress       = StringPtr;
  Database        = NULL;
  AccessProgress  = NULL;
  EfiVarStoreInfo = NULL;
  IsEfiVarstore   = FALSE;

  //
  // The first element of <MultiConfigResp> should be
  // <GuidHdr>, which is in 'GUID='<Guid> syntax.
  //
  if (StrnCmp (StringPtr, L"GUID=", StrLen (L"GUID=")) != 0) {
    return EFI_INVALID_PARAMETER;
  }

  while (*StringPtr != 0 && StrnCmp (StringPtr, L"GUID=", StrLen (L"GUID=")) == 0) {
    //
    // If parsing error, set Progress to the beginning of the <MultiConfigResp>
    // or most recent & before the error.
    //
    if (StringPtr == Configuration) {
      *Progress = StringPtr;
    } else {
      *Progress = StringPtr - 1;
    }

    //
    // Process each <ConfigResp> of <MultiConfigResp>
    //
    Length     = CalculateConfigStringLen (StringPtr);
    ConfigResp = AllocateCopyPool ((Length + 1) * sizeof (CHAR16), StringPtr);
    if (ConfigResp == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }

    //
    // Append '\0' to the end of ConfigRequest
    //
    *(ConfigResp + Length) = 0;

    //
    // Get the UEFI device path
    //
    Status = GetDevicePath (ConfigResp, (UINT8 **)&DevicePath);
    if (EFI_ERROR (Status)) {
      FreePool (ConfigResp);
      return Status;
    }

    //
    // Find driver which matches the routing data.
    //
    DriverHandle = NULL;
    for (Link = Private->DatabaseList.ForwardLink;
         Link != &Private->DatabaseList;
         Link = Link->ForwardLink
         )
    {
      Database = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);

      if ((DevicePathPkg = Database->PackageList->DevicePathPkg) != NULL) {
        CurrentDevicePath = DevicePathPkg + sizeof (EFI_HII_PACKAGE_HEADER);
        DevicePathSize    = GetDevicePathSize ((EFI_DEVICE_PATH_PROTOCOL *)CurrentDevicePath);
        if ((CompareMem (DevicePath, CurrentDevicePath, DevicePathSize) == 0) && IsThisPackageList (Database, ConfigResp)) {
          DriverHandle = Database->DriverHandle;
          break;
        }
      }
    }

    //
    // Try to find driver handle by device path.
    //
    if (DriverHandle == NULL) {
      TempDevicePath = DevicePath;
      Status         = gBS->LocateDevicePath (
                              &gEfiDevicePathProtocolGuid,
                              &TempDevicePath,
                              &DriverHandle
                              );
      if (EFI_ERROR (Status) || (DriverHandle == NULL)) {
        //
        // Routing data does not match any known driver.
        // Set Progress to the 'G' in "GUID" of the routing header.
        //
        FreePool (DevicePath);
        *Progress = StringPtr;
        FreePool (ConfigResp);
        return EFI_NOT_FOUND;
      }
    }

    FreePool (DevicePath);

    //
    // Check whether this ConfigRequest is search from Efi varstore type storage.
    //
    Status = GetVarStoreType (Database, ConfigResp, &IsEfiVarstore, &EfiVarStoreInfo);
    if (EFI_ERROR (Status)) {
      return Status;
    }

    if (IsEfiVarstore) {
      //
      // Call the SetVariable function to route settings.
      //
      Status = RouteConfigRespForEfiVarStore (This, EfiVarStoreInfo, ConfigResp, &AccessProgress);
      FreePool (EfiVarStoreInfo);
    } else {
      //
      // Call corresponding ConfigAccess protocol to route settings
      //
      Status = gBS->HandleProtocol (
                      DriverHandle,
                      &gEfiHiiConfigAccessProtocolGuid,
                      (VOID **)&ConfigAccess
                      );
      if (EFI_ERROR (Status)) {
        *Progress = StringPtr;
        FreePool (ConfigResp);
        return EFI_NOT_FOUND;
      }

      Status = ConfigAccess->RouteConfig (
                               ConfigAccess,
                               ConfigResp,
                               &AccessProgress
                               );
    }

    if (EFI_ERROR (Status)) {
      ASSERT (AccessProgress != NULL);
      //
      // AccessProgress indicates the parsing progress on <ConfigResp>.
      // Map it to the progress on <MultiConfigResp> then return it.
      //
      *Progress = StrStr (StringPtr, AccessProgress);

      FreePool (ConfigResp);
      return Status;
    }

    FreePool (ConfigResp);
    ConfigResp = NULL;

    //
    // Go to next <ConfigResp> (skip '&').
    //
    StringPtr += Length;
    if (*StringPtr == 0) {
      *Progress = StringPtr;
      break;
    }

    StringPtr++;
  }

  return EFI_SUCCESS;
}

/**
  This helper function is to be called by drivers to map configuration data
  stored in byte array ("block") formats such as UEFI Variables into current
  configuration strings.

  @param  This                   A pointer to the EFI_HII_CONFIG_ROUTING_PROTOCOL
                                 instance.
  @param  ConfigRequest          A null-terminated Unicode string in
                                 <ConfigRequest> format.
  @param  Block                  Array of bytes defining the block's configuration.
  @param  BlockSize              Length in bytes of Block.
  @param  Config                 Filled-in configuration string. String allocated
                                 by  the function. Returned only if call is
                                 successful. It is <ConfigResp> string 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 request succeeded. Progress points to the null
                                 terminator at the end of the ConfigRequest
                                 string.
  @retval EFI_OUT_OF_RESOURCES   Not enough memory to allocate Config.     Progress
                                 points to the first character of ConfigRequest.
  @retval EFI_INVALID_PARAMETER  Passing in a NULL for the ConfigRequest or
                                 Block parameter would result in this type of
                                 error. Progress points to the first character of
                                 ConfigRequest.
  @retval EFI_DEVICE_ERROR       Block not large enough. Progress undefined.
  @retval EFI_INVALID_PARAMETER  Encountered non <BlockName> formatted string.
                                     Block is left updated and Progress points at
                                 the "&" preceding the first non-<BlockName>.

**/
EFI_STATUS
EFIAPI
HiiBlockToConfig (
  IN  CONST EFI_HII_CONFIG_ROUTING_PROTOCOL  *This,
  IN  CONST EFI_STRING                       ConfigRequest,
  IN  CONST UINT8                            *Block,
  IN  CONST UINTN                            BlockSize,
  OUT EFI_STRING                             *Config,
  OUT EFI_STRING                             *Progress
  )
{
  HII_DATABASE_PRIVATE_DATA  *Private;
  EFI_STRING                 StringPtr;
  UINTN                      Length;
  EFI_STATUS                 Status;
  EFI_STRING                 TmpPtr;
  UINT8                      *TmpBuffer;
  UINTN                      Offset;
  UINTN                      Width;
  UINT8                      *Value;
  EFI_STRING                 ValueStr;
  EFI_STRING                 ConfigElement;
  UINTN                      Index;
  UINT8                      *TemBuffer;
  CHAR16                     *TemString;

  TmpBuffer = NULL;

  if ((This == NULL) || (Progress == NULL) || (Config == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  if ((Block == NULL) || (ConfigRequest == NULL)) {
    *Progress = ConfigRequest;
    return EFI_INVALID_PARAMETER;
  }

  Private = CONFIG_ROUTING_DATABASE_PRIVATE_DATA_FROM_THIS (This);
  ASSERT (Private != NULL);

  StringPtr     = ConfigRequest;
  ValueStr      = NULL;
  Value         = NULL;
  ConfigElement = NULL;

  //
  // Allocate a fix length of memory to store Results. Reallocate memory for
  // Results if this fix length is insufficient.
  //
  *Config = (EFI_STRING)AllocateZeroPool (MAX_STRING_LENGTH);
  if (*Config == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  //
  // Jump <ConfigHdr>
  //
  if (StrnCmp (StringPtr, L"GUID=", StrLen (L"GUID=")) != 0) {
    *Progress = StringPtr;
    Status    = EFI_INVALID_PARAMETER;
    goto Exit;
  }

  while (*StringPtr != 0 && StrnCmp (StringPtr, L"PATH=", StrLen (L"PATH=")) != 0) {
    StringPtr++;
  }

  if (*StringPtr == 0) {
    *Progress = StringPtr - 1;
    Status    = EFI_INVALID_PARAMETER;
    goto Exit;
  }

  while (*StringPtr != L'&' && *StringPtr != 0) {
    StringPtr++;
  }

  if (*StringPtr == 0) {
    *Progress = StringPtr;

    AppendToMultiString (Config, ConfigRequest);
    HiiToLower (*Config);

    return EFI_SUCCESS;
  }

  //
  // Skip '&'
  //
  StringPtr++;

  //
  // Copy <ConfigHdr> and an additional '&' to <ConfigResp>
  //
  TemString = AllocateCopyPool (sizeof (CHAR16) * (StringPtr - ConfigRequest + 1), ConfigRequest);
  if (TemString == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  TemString[StringPtr - ConfigRequest] = '\0';
  AppendToMultiString (Config, TemString);
  FreePool (TemString);

  //
  // Parse each <RequestElement> if exists
  // Only <BlockName> format is supported by this help function.
  // <BlockName> ::= 'OFFSET='<Number>&'WIDTH='<Number>
  //
  while (*StringPtr != 0 && StrnCmp (StringPtr, L"OFFSET=", StrLen (L"OFFSET=")) == 0) {
    //
    // Back up the header of one <BlockName>
    //
    TmpPtr = StringPtr;

    StringPtr += StrLen (L"OFFSET=");
    //
    // Get Offset
    //
    Status = GetValueOfNumber (StringPtr, &TmpBuffer, &Length);
    if (EFI_ERROR (Status)) {
      *Progress = TmpPtr - 1;
      goto Exit;
    }

    Offset = 0;
    CopyMem (
      &Offset,
      TmpBuffer,
      (((Length + 1) / 2) < sizeof (UINTN)) ? ((Length + 1) / 2) : sizeof (UINTN)
      );
    FreePool (TmpBuffer);

    StringPtr += Length;
    if (StrnCmp (StringPtr, L"&WIDTH=", StrLen (L"&WIDTH=")) != 0) {
      *Progress = TmpPtr - 1;
      Status    = EFI_INVALID_PARAMETER;
      goto Exit;
    }

    StringPtr += StrLen (L"&WIDTH=");

    //
    // Get Width
    //
    Status = GetValueOfNumber (StringPtr, &TmpBuffer, &Length);
    if (EFI_ERROR (Status)) {
      *Progress =  TmpPtr - 1;
      goto Exit;
    }

    Width = 0;
    CopyMem (
      &Width,
      TmpBuffer,
      (((Length + 1) / 2) < sizeof (UINTN)) ? ((Length + 1) / 2) : sizeof (UINTN)
      );
    FreePool (TmpBuffer);

    StringPtr += Length;
    if ((*StringPtr != 0) && (*StringPtr != L'&')) {
      *Progress =  TmpPtr - 1;
      Status    = EFI_INVALID_PARAMETER;
      goto Exit;
    }

    //
    // Calculate Value and convert it to hex string.
    //
    if (Offset + Width > BlockSize) {
      *Progress = StringPtr;
      Status    = EFI_DEVICE_ERROR;
      goto Exit;
    }

    Value = (UINT8 *)AllocateZeroPool (Width);
    if (Value == NULL) {
      *Progress = ConfigRequest;
      Status    = EFI_OUT_OF_RESOURCES;
      goto Exit;
    }

    CopyMem (Value, (UINT8 *)Block + Offset, Width);

    Length   = Width * 2 + 1;
    ValueStr = (EFI_STRING)AllocateZeroPool (Length  * sizeof (CHAR16));
    if (ValueStr == NULL) {
      *Progress = ConfigRequest;
      Status    = EFI_OUT_OF_RESOURCES;
      goto Exit;
    }

    TemString = ValueStr;
    TemBuffer = Value + Width - 1;
    for (Index = 0; Index < Width; Index++, TemBuffer--) {
      UnicodeValueToStringS (
        TemString,
        Length  * sizeof (CHAR16) - ((UINTN)TemString - (UINTN)ValueStr),
        PREFIX_ZERO | RADIX_HEX,
        *TemBuffer,
        2
        );
      TemString += StrnLenS (TemString, Length - ((UINTN)TemString - (UINTN)ValueStr) / sizeof (CHAR16));
    }

    FreePool (Value);
    Value = NULL;

    //
    // Build a ConfigElement
    //
    Length       += StringPtr - TmpPtr + 1 + StrLen (L"VALUE=");
    ConfigElement = (EFI_STRING)AllocateZeroPool (Length * sizeof (CHAR16));
    if (ConfigElement == NULL) {
      Status = EFI_OUT_OF_RESOURCES;
      goto Exit;
    }

    CopyMem (ConfigElement, TmpPtr, (StringPtr - TmpPtr + 1) * sizeof (CHAR16));
    if (*StringPtr == 0) {
      *(ConfigElement + (StringPtr - TmpPtr)) = L'&';
    }

    *(ConfigElement + (StringPtr - TmpPtr) + 1) = 0;
    StrCatS (ConfigElement, Length, L"VALUE=");
    StrCatS (ConfigElement, Length, ValueStr);

    AppendToMultiString (Config, ConfigElement);

    FreePool (ConfigElement);
    FreePool (ValueStr);
    ConfigElement = NULL;
    ValueStr      = NULL;

    //
    // If '\0', parsing is finished. Otherwise skip '&' to continue
    //
    if (*StringPtr == 0) {
      break;
    }

    AppendToMultiString (Config, L"&");
    StringPtr++;
  }

  if (*StringPtr != 0) {
    *Progress = StringPtr - 1;
    Status    = EFI_INVALID_PARAMETER;
    goto Exit;
  }

  HiiToLower (*Config);
  *Progress = StringPtr;
  return EFI_SUCCESS;

Exit:
  if (*Config != NULL) {
    FreePool (*Config);
    *Config = NULL;
  }

  if (ValueStr != NULL) {
    FreePool (ValueStr);
  }

  if (Value != NULL) {
    FreePool (Value);
  }

  if (ConfigElement != NULL) {
    FreePool (ConfigElement);
  }

  return Status;
}

/**
  This helper function is to be called by drivers to map configuration strings
  to configurations stored in byte array ("block") formats such as UEFI Variables.

  @param  This                   A pointer to the EFI_HII_CONFIG_ROUTING_PROTOCOL
                                 instance.
  @param  ConfigResp             A null-terminated Unicode string in <ConfigResp>
                                 format.
  @param  Block                  A possibly null array of bytes representing the
                                 current  block. Only bytes referenced in the
                                 ConfigResp string  in the block are modified. If
                                 this parameter is null or if the *BlockSize
                                 parameter is (on input) shorter than required by
                                 the Configuration string, only the BlockSize
                                 parameter is updated and an appropriate status
                                 (see below)  is returned.
  @param  BlockSize              The length of the Block in units of UINT8.  On
                                 input, this is the size of the Block. On output,
                                 if successful, contains the largest index of the
                                 modified byte in the Block, or the required buffer
                                 size if the Block is not large enough.
  @param  Progress               On return, points to an element of the ConfigResp
                                 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 request succeeded. Progress points to the null
                                 terminator at the end of the ConfigResp string.
  @retval EFI_OUT_OF_RESOURCES   Not enough memory to allocate Config.     Progress
                                 points to the first character of ConfigResp.
  @retval EFI_INVALID_PARAMETER  Passing in a NULL for the ConfigResp or
                                 Block parameter would result in this type of
                                 error. Progress points to the first character of
                                         ConfigResp.
  @retval EFI_INVALID_PARAMETER  Encountered non <BlockName> formatted name /
                                 value pair. Block is left updated and
                                 Progress points at the '&' preceding the first
                                 non-<BlockName>.
  @retval EFI_BUFFER_TOO_SMALL   Block not large enough. Progress undefined.
                                 BlockSize is updated with the required buffer size.
  @retval EFI_NOT_FOUND          Target for the specified routing data was not found.
                                 Progress points to the "G" in "GUID" of the errant
                                 routing data.

**/
EFI_STATUS
EFIAPI
HiiConfigToBlock (
  IN     CONST EFI_HII_CONFIG_ROUTING_PROTOCOL  *This,
  IN     CONST EFI_STRING                       ConfigResp,
  IN OUT UINT8                                  *Block,
  IN OUT UINTN                                  *BlockSize,
  OUT    EFI_STRING                             *Progress
  )
{
  HII_DATABASE_PRIVATE_DATA  *Private;
  EFI_STRING                 StringPtr;
  EFI_STRING                 TmpPtr;
  UINTN                      Length;
  EFI_STATUS                 Status;
  UINT8                      *TmpBuffer;
  UINTN                      Offset;
  UINTN                      Width;
  UINT8                      *Value;
  UINTN                      BufferSize;
  UINTN                      MaxBlockSize;

  TmpBuffer = NULL;

  if ((This == NULL) || (BlockSize == NULL) || (Progress == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  *Progress = ConfigResp;
  if (ConfigResp == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  Private = CONFIG_ROUTING_DATABASE_PRIVATE_DATA_FROM_THIS (This);
  ASSERT (Private != NULL);

  StringPtr    = ConfigResp;
  BufferSize   = *BlockSize;
  Value        = NULL;
  MaxBlockSize = 0;

  //
  // Jump <ConfigHdr>
  //
  if (StrnCmp (StringPtr, L"GUID=", StrLen (L"GUID=")) != 0) {
    *Progress = StringPtr;
    Status    = EFI_INVALID_PARAMETER;
    goto Exit;
  }

  while (*StringPtr != 0 && StrnCmp (StringPtr, L"PATH=", StrLen (L"PATH=")) != 0) {
    StringPtr++;
  }

  if (*StringPtr == 0) {
    *Progress = StringPtr;
    Status    = EFI_INVALID_PARAMETER;
    goto Exit;
  }

  while (*StringPtr != L'&' && *StringPtr != 0) {
    StringPtr++;
  }

  if (*StringPtr == 0) {
    *Progress = StringPtr;
    Status    = EFI_INVALID_PARAMETER;
    goto Exit;
  }

  //
  // Parse each <ConfigElement> if exists
  // Only '&'<BlockConfig> format is supported by this help function.
  // <BlockConfig> ::= 'OFFSET='<Number>&'WIDTH='<Number>&'VALUE='<Number>
  //
  while (*StringPtr != 0 && StrnCmp (StringPtr, L"&OFFSET=", StrLen (L"&OFFSET=")) == 0) {
    TmpPtr     = StringPtr;
    StringPtr += StrLen (L"&OFFSET=");
    //
    // Get Offset
    //
    Status = GetValueOfNumber (StringPtr, &TmpBuffer, &Length);
    if (EFI_ERROR (Status)) {
      *Progress = TmpPtr;
      goto Exit;
    }

    Offset = 0;
    CopyMem (
      &Offset,
      TmpBuffer,
      (((Length + 1) / 2) < sizeof (UINTN)) ? ((Length + 1) / 2) : sizeof (UINTN)
      );
    FreePool (TmpBuffer);

    StringPtr += Length;
    if (StrnCmp (StringPtr, L"&WIDTH=", StrLen (L"&WIDTH=")) != 0) {
      *Progress = TmpPtr;
      Status    = EFI_INVALID_PARAMETER;
      goto Exit;
    }

    StringPtr += StrLen (L"&WIDTH=");

    //
    // Get Width
    //
    Status = GetValueOfNumber (StringPtr, &TmpBuffer, &Length);
    if (EFI_ERROR (Status)) {
      *Progress = TmpPtr;
      goto Exit;
    }

    Width = 0;
    CopyMem (
      &Width,
      TmpBuffer,
      (((Length + 1) / 2) < sizeof (UINTN)) ? ((Length + 1) / 2) : sizeof (UINTN)
      );
    FreePool (TmpBuffer);

    StringPtr += Length;
    if (StrnCmp (StringPtr, L"&VALUE=", StrLen (L"&VALUE=")) != 0) {
      *Progress = TmpPtr;
      Status    = EFI_INVALID_PARAMETER;
      goto Exit;
    }

    StringPtr += StrLen (L"&VALUE=");

    //
    // Get Value
    //
    Status = GetValueOfNumber (StringPtr, &Value, &Length);
    if (EFI_ERROR (Status)) {
      *Progress = TmpPtr;
      goto Exit;
    }

    StringPtr += Length;
    if ((*StringPtr != 0) && (*StringPtr != L'&')) {
      *Progress = TmpPtr;
      Status    = EFI_INVALID_PARAMETER;
      goto Exit;
    }

    //
    // Update the Block with configuration info
    //
    if ((Block != NULL) && (Offset + Width <= BufferSize)) {
      CopyMem (Block + Offset, Value, Width);
    }

    if (Offset + Width > MaxBlockSize) {
      MaxBlockSize = Offset + Width;
    }

    FreePool (Value);
    Value = NULL;

    //
    // If '\0', parsing is finished.
    //
    if (*StringPtr == 0) {
      break;
    }
  }

  //
  // The input string is not ConfigResp format, return error.
  //
  if (*StringPtr != 0) {
    *Progress = StringPtr;
    Status    = EFI_INVALID_PARAMETER;
    goto Exit;
  }

  *Progress  = StringPtr + StrLen (StringPtr);
  *BlockSize = MaxBlockSize - 1;

  if (MaxBlockSize > BufferSize) {
    *BlockSize = MaxBlockSize;
    if (Block != NULL) {
      return EFI_BUFFER_TOO_SMALL;
    }
  }

  if (Block == NULL) {
    *Progress = ConfigResp;
    return EFI_INVALID_PARAMETER;
  }

  return EFI_SUCCESS;

Exit:

  if (Value != NULL) {
    FreePool (Value);
  }

  return Status;
}

/**
  This helper function is to be called by drivers to extract portions of
  a larger configuration string.

  @param  This                   A pointer to the EFI_HII_CONFIG_ROUTING_PROTOCOL
                                 instance.
  @param  Configuration          A null-terminated Unicode string in
                                 <MultiConfigAltResp> format.
  @param  Guid                   A pointer to the GUID value to search for in the
                                 routing portion of the ConfigResp string when
                                 retrieving  the requested data. If Guid is NULL,
                                 then all GUID  values will be searched for.
  @param  Name                   A pointer to the NAME value to search for in the
                                 routing portion of the ConfigResp string when
                                 retrieving  the requested data. If Name is NULL,
                                 then all Name  values will be searched for.
  @param  DevicePath             A pointer to the PATH value to search for in the
                                 routing portion of the ConfigResp string when
                                 retrieving  the requested data. If DevicePath is
                                 NULL, then all  DevicePath values will be searched
                                 for.
  @param  AltCfgId               A pointer to the ALTCFG value to search for in the
                                  routing portion of the ConfigResp string when
                                 retrieving  the requested data.  If this parameter
                                 is NULL,  then the current setting will be
                                 retrieved.
  @param  AltCfgResp             A pointer to a buffer which will be allocated by
                                 the  function which contains the retrieved string
                                 as requested.   This buffer is only allocated if
                                 the call was successful. It is <ConfigResp> format.

  @retval EFI_SUCCESS            The request succeeded. The requested data was
                                 extracted  and placed in the newly allocated
                                 AltCfgResp buffer.
  @retval EFI_OUT_OF_RESOURCES   Not enough memory to allocate AltCfgResp.
  @retval EFI_INVALID_PARAMETER  Any parameter is invalid.
  @retval EFI_NOT_FOUND          Target for the specified routing data was not
                                 found.

**/
EFI_STATUS
EFIAPI
HiiGetAltCfg (
  IN  CONST EFI_HII_CONFIG_ROUTING_PROTOCOL  *This,
  IN  CONST EFI_STRING                       Configuration,
  IN  CONST EFI_GUID                         *Guid,
  IN  CONST EFI_STRING                       Name,
  IN  CONST EFI_DEVICE_PATH_PROTOCOL         *DevicePath,
  IN  CONST UINT16                           *AltCfgId,
  OUT EFI_STRING                             *AltCfgResp
  )
{
  EFI_STATUS  Status;
  EFI_STRING  StringPtr;
  EFI_STRING  HdrStart;
  EFI_STRING  HdrEnd;
  EFI_STRING  TmpPtr;
  UINTN       Length;
  EFI_STRING  GuidStr;
  EFI_STRING  NameStr;
  EFI_STRING  PathStr;
  EFI_STRING  AltIdStr;
  EFI_STRING  Result;
  BOOLEAN     GuidFlag;
  BOOLEAN     NameFlag;
  BOOLEAN     PathFlag;

  HdrStart = NULL;
  HdrEnd   = NULL;
  GuidStr  = NULL;
  NameStr  = NULL;
  PathStr  = NULL;
  AltIdStr = NULL;
  Result   = NULL;
  GuidFlag = FALSE;
  NameFlag = FALSE;
  PathFlag = FALSE;

  if ((This == NULL) || (Configuration == NULL) || (AltCfgResp == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  StringPtr = Configuration;
  if (StrnCmp (StringPtr, L"GUID=", StrLen (L"GUID=")) != 0) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Generate the sub string for later matching.
  //
  GenerateSubStr (L"GUID=", sizeof (EFI_GUID), (VOID *)Guid, 1, &GuidStr);
  GenerateSubStr (
    L"PATH=",
    GetDevicePathSize ((EFI_DEVICE_PATH_PROTOCOL *)DevicePath),
    (VOID *)DevicePath,
    1,
    &PathStr
    );
  if (AltCfgId != NULL) {
    GenerateSubStr (L"ALTCFG=", sizeof (UINT16), (VOID *)AltCfgId, 3, &AltIdStr);
    if (AltIdStr == NULL) {
      ASSERT (AltIdStr != NULL);
      return EFI_OUT_OF_RESOURCES;
    }
  }

  if (Name != NULL) {
    GenerateSubStr (L"NAME=", StrLen (Name) * sizeof (CHAR16), (VOID *)Name, 2, &NameStr);
  } else {
    GenerateSubStr (L"NAME=", 0, NULL, 2, &NameStr);
  }

  if (NameStr == NULL) {
    ASSERT (NameStr != NULL);
    return EFI_OUT_OF_RESOURCES;
  }

  while (*StringPtr != 0) {
    //
    // Try to match the GUID
    //
    if (!GuidFlag) {
      TmpPtr = StrStr (StringPtr, GuidStr);
      if (TmpPtr == NULL) {
        Status = EFI_NOT_FOUND;
        goto Exit;
      }

      HdrStart = TmpPtr;

      //
      // Jump to <NameHdr>
      //
      if (Guid != NULL) {
        StringPtr = TmpPtr + StrLen (GuidStr);
      } else {
        StringPtr = StrStr (TmpPtr, L"NAME=");
        if (StringPtr == NULL) {
          Status = EFI_NOT_FOUND;
          goto Exit;
        }
      }

      GuidFlag = TRUE;
    }

    //
    // Try to match the NAME
    //
    if (GuidFlag && !NameFlag) {
      if (StrnCmp (StringPtr, NameStr, StrLen (NameStr)) != 0) {
        GuidFlag = FALSE;
      } else {
        //
        // Jump to <PathHdr>
        //
        if (Name != NULL) {
          StringPtr += StrLen (NameStr);
        } else {
          StringPtr = StrStr (StringPtr, L"PATH=");
          if (StringPtr == NULL) {
            Status = EFI_NOT_FOUND;
            goto Exit;
          }
        }

        NameFlag = TRUE;
      }
    }

    //
    // Try to match the DevicePath
    //
    if (GuidFlag && NameFlag && !PathFlag) {
      if (StrnCmp (StringPtr, PathStr, StrLen (PathStr)) != 0) {
        GuidFlag = FALSE;
        NameFlag = FALSE;
      } else {
        //
        // Jump to '&' before <DescHdr> or <ConfigBody>
        //
        if (DevicePath != NULL) {
          StringPtr += StrLen (PathStr);
        } else {
          StringPtr = StrStr (StringPtr, L"&");
          if (StringPtr == NULL) {
            Status = EFI_NOT_FOUND;
            goto Exit;
          }

          StringPtr++;
        }

        PathFlag = TRUE;
        HdrEnd   = StringPtr;
      }
    }

    //
    // Try to match the AltCfgId
    //
    if (GuidFlag && NameFlag && PathFlag) {
      if (AltCfgId == NULL) {
        //
        // Return Current Setting when AltCfgId is NULL.
        //
        Status = OutputConfigBody (StringPtr, &Result);
        goto Exit;
      }

      if (AltIdStr == NULL) {
        ASSERT (AltIdStr != NULL);
        Status = EFI_NOT_FOUND;
        goto Exit;
      }

      //
      // Search the <ConfigAltResp> to get the <AltResp> with AltCfgId.
      //
      if (StrnCmp (StringPtr, AltIdStr, StrLen (AltIdStr)) != 0) {
        GuidFlag = FALSE;
        NameFlag = FALSE;
        PathFlag = FALSE;
      } else {
        //
        // Skip AltIdStr and &
        //
        StringPtr = StringPtr + StrLen (AltIdStr);
        Status    = OutputConfigBody (StringPtr, &Result);
        goto Exit;
      }
    }
  }

  Status = EFI_NOT_FOUND;

Exit:
  *AltCfgResp = NULL;
  if (!EFI_ERROR (Status) && (Result != NULL)) {
    //
    // Copy the <ConfigHdr> and <ConfigBody>
    //
    Length      = HdrEnd - HdrStart + StrLen (Result) + 1;
    *AltCfgResp = AllocateZeroPool (Length * sizeof (CHAR16));
    if (*AltCfgResp == NULL) {
      Status = EFI_OUT_OF_RESOURCES;
    } else {
      StrnCpyS (*AltCfgResp, Length, HdrStart, HdrEnd - HdrStart);
      StrCatS (*AltCfgResp, Length, Result);
      Status = EFI_SUCCESS;
    }
  }

  if (GuidStr != NULL) {
    FreePool (GuidStr);
  }

  if (NameStr != NULL) {
    FreePool (NameStr);
  }

  if (PathStr != NULL) {
    FreePool (PathStr);
  }

  if (AltIdStr != NULL) {
    FreePool (AltIdStr);
  }

  if (Result != NULL) {
    FreePool (Result);
  }

  return Status;
}
