/** @file
Implementation of interfaces function for EFI_CONFIG_KEYWORD_HANDLER_PROTOCOL.

Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "HiiDatabase.h"

extern HII_DATABASE_PRIVATE_DATA  mPrivate;

/**
  Convert the hex UNICODE %02x encoding of a UEFI device path to binary
  from <PathHdr> of <MultiKeywordRequest>.

  This is a internal function.

  @param  String                 MultiKeywordRequest string.
  @param  DevicePathData         Binary of a UEFI device path.
  @param  NextString             string follow the possible PathHdr string.

  @retval EFI_INVALID_PARAMETER  The device path is not valid or the 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.
                                 The Input string not include PathHdr section.

**/
EFI_STATUS
ExtractDevicePath (
  IN  EFI_STRING  String,
  OUT UINT8       **DevicePathData,
  OUT EFI_STRING  *NextString
  )
{
  UINTN                     Length;
  EFI_STRING                PathHdr;
  UINT8                     *DevicePathBuffer;
  CHAR16                    TemStr[2];
  UINTN                     Index;
  UINT8                     DigitUint8;
  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;

  ASSERT (NextString != NULL && DevicePathData != NULL);

  //
  // KeywordRequest == NULL case.
  //
  if (String == NULL) {
    *DevicePathData = NULL;
    *NextString     = NULL;
    return EFI_SUCCESS;
  }

  //
  // Skip '&' if exist.
  //
  if (*String == L'&') {
    String++;
  }

  //
  // Find the 'PATH=' of <PathHdr>.
  //
  if (StrnCmp (String, L"PATH=", StrLen (L"PATH=")) != 0) {
    if (StrnCmp (String, L"KEYWORD=", StrLen (L"KEYWORD=")) != 0) {
      return EFI_INVALID_PARAMETER;
    } else {
      //
      // Not include PathHdr, return success and DevicePath = NULL.
      //
      *DevicePathData = NULL;
      *NextString     = String;
      return EFI_SUCCESS;
    }
  }

  //
  // 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++) {
  }

  //
  // Save the return next keyword string value.
  //
  *NextString = String;

  //
  // Check DevicePath Length
  //
  if (((Length + 1) / 2) < sizeof (EFI_DEVICE_PATH_PROTOCOL)) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // 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_INVALID_PARAMETER;
    }

    DevicePath = NextDevicePathNode (DevicePath);
  }

  //
  // return the device path
  //
  *DevicePathData = DevicePathBuffer;

  return EFI_SUCCESS;
}

/**
  Get NameSpace from the input NameSpaceId string.

  This is a internal function.

  @param  String                 <NameSpaceId> format string.
  @param  NameSpace              Return the name space string.
  @param  NextString             Return the next string follow namespace.

  @retval   EFI_SUCCESS             Get the namespace string success.
  @retval   EFI_INVALID_PARAMETER   The NameSpaceId string not follow spec definition.

**/
EFI_STATUS
ExtractNameSpace (
  IN  EFI_STRING  String,
  OUT CHAR8       **NameSpace,
  OUT EFI_STRING  *NextString
  )
{
  CHAR16  *TmpPtr;
  UINTN   NameSpaceSize;

  ASSERT (NameSpace != NULL);

  TmpPtr = NULL;

  //
  // Input NameSpaceId == NULL
  //
  if (String == NULL) {
    *NameSpace = NULL;
    if (NextString != NULL) {
      *NextString = NULL;
    }

    return EFI_SUCCESS;
  }

  //
  // Skip '&' if exist.
  //
  if (*String == L'&') {
    String++;
  }

  if (StrnCmp (String, L"NAMESPACE=", StrLen (L"NAMESPACE=")) != 0) {
    return EFI_INVALID_PARAMETER;
  }

  String += StrLen (L"NAMESPACE=");

  TmpPtr = StrStr (String, L"&");
  if (TmpPtr != NULL) {
    *TmpPtr = 0;
  }

  if (NextString != NULL) {
    *NextString = String + StrLen (String);
  }

  //
  // Input NameSpace is unicode string. The language in String package is ascii string.
  // Here will convert the unicode string to ascii and save it.
  //
  NameSpaceSize = StrLen (String) + 1;
  *NameSpace    = AllocatePool (NameSpaceSize);
  if (*NameSpace == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  UnicodeStrToAsciiStrS (String, *NameSpace, NameSpaceSize);

  if (TmpPtr != NULL) {
    *TmpPtr = L'&';
  }

  return EFI_SUCCESS;
}

/**
  Get Keyword from the input KeywordRequest string.

  This is a internal function.

  @param  String                 KeywordRequestformat string.
  @param  Keyword                return the extract keyword string.
  @param  NextString             return the next string follow this keyword section.

  @retval EFI_SUCCESS            Success to get the keyword string.
  @retval EFI_INVALID_PARAMETER  Parse the input string return error.

**/
EFI_STATUS
ExtractKeyword (
  IN  EFI_STRING  String,
  OUT EFI_STRING  *Keyword,
  OUT EFI_STRING  *NextString
  )
{
  EFI_STRING  TmpPtr;

  ASSERT ((Keyword != NULL) && (NextString != NULL));

  TmpPtr = NULL;

  //
  // KeywordRequest == NULL case.
  //
  if (String == NULL) {
    *Keyword    = NULL;
    *NextString = NULL;
    return EFI_SUCCESS;
  }

  //
  // Skip '&' if exist.
  //
  if (*String == L'&') {
    String++;
  }

  if (StrnCmp (String, L"KEYWORD=", StrLen (L"KEYWORD=")) != 0) {
    return EFI_INVALID_PARAMETER;
  }

  String += StrLen (L"KEYWORD=");

  TmpPtr = StrStr (String, L"&");
  if (TmpPtr != NULL) {
    *TmpPtr = 0;
  }

  *NextString = String + StrLen (String);

  *Keyword = AllocateCopyPool (StrSize (String), String);
  if (*Keyword == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  if (TmpPtr != NULL) {
    *TmpPtr = L'&';
  }

  return EFI_SUCCESS;
}

/**
  Get value from the input KeywordRequest string.

  This is a internal function.

  @param  String                 KeywordRequestformat string.
  @param  Value                  return the extract value string.
  @param  NextString             return the next string follow this keyword section.

  @retval EFI_SUCCESS            Success to get the keyword string.
  @retval EFI_INVALID_PARAMETER  Parse the input string return error.

**/
EFI_STATUS
ExtractValue (
  IN  EFI_STRING  String,
  OUT EFI_STRING  *Value,
  OUT EFI_STRING  *NextString
  )
{
  EFI_STRING  TmpPtr;

  ASSERT ((Value != NULL) && (NextString != NULL) && (String != NULL));

  //
  // Skip '&' if exist.
  //
  if (*String == L'&') {
    String++;
  }

  if (StrnCmp (String, L"VALUE=", StrLen (L"VALUE=")) != 0) {
    return EFI_INVALID_PARAMETER;
  }

  String += StrLen (L"VALUE=");

  TmpPtr = StrStr (String, L"&");
  if (TmpPtr != NULL) {
    *TmpPtr = 0;
  }

  *NextString = String + StrLen (String);

  *Value = AllocateCopyPool (StrSize (String), String);
  if (*Value == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  if (TmpPtr != NULL) {
    *TmpPtr = L'&';
  }

  return EFI_SUCCESS;
}

/**
  Get filter from the input KeywordRequest string.

  This is a internal function.

  @param  String                 KeywordRequestformat string.
  @param  FilterFlags            return the filter condition.
  @param  NextString             return the next string follow this keyword section.

  @retval EFI_SUCCESS            Success to get the keyword string.
  @retval EFI_INVALID_PARAMETER  Parse the input string return error.

**/
BOOLEAN
ExtractFilter (
  IN  EFI_STRING  String,
  OUT UINT8       *FilterFlags,
  OUT EFI_STRING  *NextString
  )
{
  CHAR16   *PathPtr;
  CHAR16   *KeywordPtr;
  BOOLEAN  RetVal;

  ASSERT ((FilterFlags != NULL) && (NextString != NULL));

  //
  // String end, no filter section.
  //
  if (String == NULL) {
    *NextString = NULL;
    return FALSE;
  }

  *FilterFlags = 0;
  RetVal       = TRUE;

  //
  // Skip '&' if exist.
  //
  if (*String == L'&') {
    String++;
  }

  if (StrnCmp (String, L"ReadOnly", StrLen (L"ReadOnly")) == 0) {
    //
    // Find ReadOnly filter.
    //
    *FilterFlags |= EFI_KEYWORD_FILTER_READONY;
    String       += StrLen (L"ReadOnly");
  } else if (StrnCmp (String, L"ReadWrite", StrLen (L"ReadWrite")) == 0) {
    //
    // Find ReadWrite filter.
    //
    *FilterFlags |= EFI_KEYWORD_FILTER_REAWRITE;
    String       += StrLen (L"ReadWrite");
  } else if (StrnCmp (String, L"Buffer", StrLen (L"Buffer")) == 0) {
    //
    // Find Buffer Filter.
    //
    *FilterFlags |= EFI_KEYWORD_FILTER_BUFFER;
    String       += StrLen (L"Buffer");
  } else if (StrnCmp (String, L"Numeric", StrLen (L"Numeric")) == 0) {
    //
    // Find Numeric Filter
    //
    String += StrLen (L"Numeric");
    if (*String != L':') {
      *FilterFlags |= EFI_KEYWORD_FILTER_NUMERIC;
    } else {
      String++;
      switch (*String) {
        case L'1':
          *FilterFlags |= EFI_KEYWORD_FILTER_NUMERIC_1;
          break;
        case L'2':
          *FilterFlags |= EFI_KEYWORD_FILTER_NUMERIC_2;
          break;
        case L'4':
          *FilterFlags |= EFI_KEYWORD_FILTER_NUMERIC_4;
          break;
        case L'8':
          *FilterFlags |= EFI_KEYWORD_FILTER_NUMERIC_8;
          break;
        default:
          ASSERT (FALSE);
          break;
      }

      String++;
    }
  } else {
    //
    // Check whether other filter item defined by Platform.
    //
    if ((StrnCmp (String, L"&PATH", StrLen (L"&PATH")) == 0) ||
        (StrnCmp (String, L"&KEYWORD", StrLen (L"&KEYWORD")) == 0))
    {
      //
      // New KeywordRequest start, no platform defined filter.
      //
    } else {
      //
      // Platform defined filter rule.
      // Just skip platform defined filter rule, return success.
      //
      PathPtr    = StrStr (String, L"&PATH");
      KeywordPtr = StrStr (String, L"&KEYWORD");
      if ((PathPtr != NULL) && (KeywordPtr != NULL)) {
        //
        // If both sections exist, return the first follow string.
        //
        String = KeywordPtr > PathPtr ? PathPtr : KeywordPtr;
      } else if (PathPtr != NULL) {
        //
        // Should not exist PathPtr != NULL && KeywordPtr == NULL case.
        //
        ASSERT (FALSE);
      } else if (KeywordPtr != NULL) {
        //
        // Just to the next keyword section.
        //
        String = KeywordPtr;
      } else {
        //
        // Only has platform defined filter section, just skip it.
        //
        String += StrLen (String);
      }
    }

    RetVal = FALSE;
  }

  *NextString = String;

  return RetVal;
}

/**
  Extract Readonly flag from opcode.

  This is a internal function.

  @param  OpCodeData             Input opcode for this question.

  @retval TRUE                   This question is readonly.
  @retval FALSE                  This question is not readonly.

**/
BOOLEAN
ExtractReadOnlyFromOpCode (
  IN  UINT8  *OpCodeData
  )
{
  EFI_IFR_QUESTION_HEADER  *QuestionHdr;

  ASSERT (OpCodeData != NULL);

  QuestionHdr = (EFI_IFR_QUESTION_HEADER *)(OpCodeData + sizeof (EFI_IFR_OP_HEADER));

  return (QuestionHdr->Flags & EFI_IFR_FLAG_READ_ONLY) != 0;
}

/**
  Create a circuit to check the filter section.

  This is a internal function.

  @param  OpCodeData             The question binary ifr data.
  @param  KeywordRequest         KeywordRequestformat string.
  @param  NextString             return the next string follow this keyword section.
  @param  ReadOnly               Return whether this question is read only.

  @retval KEYWORD_HANDLER_NO_ERROR                     Success validate.
  @retval KEYWORD_HANDLER_INCOMPATIBLE_VALUE_DETECTED  Validate fail.

**/
UINT32
ValidateFilter (
  IN  UINT8    *OpCodeData,
  IN  CHAR16   *KeywordRequest,
  OUT CHAR16   **NextString,
  OUT BOOLEAN  *ReadOnly
  )
{
  CHAR16                   *NextFilter;
  CHAR16                   *StringPtr;
  UINT8                    FilterFlags;
  EFI_IFR_QUESTION_HEADER  *QuestionHdr;
  EFI_IFR_OP_HEADER        *OpCodeHdr;
  UINT8                    Flags;
  UINT32                   RetVal;

  RetVal    = KEYWORD_HANDLER_NO_ERROR;
  StringPtr = KeywordRequest;

  OpCodeHdr   = (EFI_IFR_OP_HEADER *)OpCodeData;
  QuestionHdr = (EFI_IFR_QUESTION_HEADER *)(OpCodeData + sizeof (EFI_IFR_OP_HEADER));
  if ((OpCodeHdr->OpCode == EFI_IFR_ONE_OF_OP) || (OpCodeHdr->OpCode == EFI_IFR_NUMERIC_OP)) {
    Flags = *(OpCodeData + sizeof (EFI_IFR_OP_HEADER) + sizeof (EFI_IFR_QUESTION_HEADER));
  } else {
    Flags = 0;
  }

  //
  // Get ReadOnly flag from Question.
  //
  *ReadOnly = ExtractReadOnlyFromOpCode (OpCodeData);

  while (ExtractFilter (StringPtr, &FilterFlags, &NextFilter)) {
    switch (FilterFlags) {
      case EFI_KEYWORD_FILTER_READONY:
        if ((QuestionHdr->Flags & EFI_IFR_FLAG_READ_ONLY) == 0) {
          RetVal = KEYWORD_HANDLER_INCOMPATIBLE_VALUE_DETECTED;
          goto Done;
        }

        break;

      case EFI_KEYWORD_FILTER_REAWRITE:
        if ((QuestionHdr->Flags & EFI_IFR_FLAG_READ_ONLY) != 0) {
          RetVal = KEYWORD_HANDLER_INCOMPATIBLE_VALUE_DETECTED;
          goto Done;
        }

        break;

      case EFI_KEYWORD_FILTER_BUFFER:
        //
        // Only these three opcode use numeric value type.
        //
        if ((OpCodeHdr->OpCode == EFI_IFR_ONE_OF_OP) || (OpCodeHdr->OpCode == EFI_IFR_NUMERIC_OP) || (OpCodeHdr->OpCode == EFI_IFR_CHECKBOX_OP)) {
          RetVal = KEYWORD_HANDLER_INCOMPATIBLE_VALUE_DETECTED;
          goto Done;
        }

        break;

      case EFI_KEYWORD_FILTER_NUMERIC:
        if ((OpCodeHdr->OpCode != EFI_IFR_ONE_OF_OP) && (OpCodeHdr->OpCode != EFI_IFR_NUMERIC_OP) && (OpCodeHdr->OpCode != EFI_IFR_CHECKBOX_OP)) {
          RetVal = KEYWORD_HANDLER_INCOMPATIBLE_VALUE_DETECTED;
          goto Done;
        }

        break;

      case EFI_KEYWORD_FILTER_NUMERIC_1:
      case EFI_KEYWORD_FILTER_NUMERIC_2:
      case EFI_KEYWORD_FILTER_NUMERIC_4:
      case EFI_KEYWORD_FILTER_NUMERIC_8:
        if ((OpCodeHdr->OpCode != EFI_IFR_ONE_OF_OP) && (OpCodeHdr->OpCode != EFI_IFR_NUMERIC_OP) && (OpCodeHdr->OpCode != EFI_IFR_CHECKBOX_OP)) {
          RetVal = KEYWORD_HANDLER_INCOMPATIBLE_VALUE_DETECTED;
          goto Done;
        }

        //
        // For numeric and oneof, it has flags field to specify the detail numeric type.
        //
        if ((OpCodeHdr->OpCode == EFI_IFR_ONE_OF_OP) || (OpCodeHdr->OpCode == EFI_IFR_NUMERIC_OP)) {
          switch (Flags & EFI_IFR_NUMERIC_SIZE) {
            case EFI_IFR_NUMERIC_SIZE_1:
              if (FilterFlags != EFI_KEYWORD_FILTER_NUMERIC_1) {
                RetVal = KEYWORD_HANDLER_INCOMPATIBLE_VALUE_DETECTED;
                goto Done;
              }

              break;

            case EFI_IFR_NUMERIC_SIZE_2:
              if (FilterFlags != EFI_KEYWORD_FILTER_NUMERIC_2) {
                RetVal = KEYWORD_HANDLER_INCOMPATIBLE_VALUE_DETECTED;
                goto Done;
              }

              break;

            case EFI_IFR_NUMERIC_SIZE_4:
              if (FilterFlags != EFI_KEYWORD_FILTER_NUMERIC_4) {
                RetVal = KEYWORD_HANDLER_INCOMPATIBLE_VALUE_DETECTED;
                goto Done;
              }

              break;

            case EFI_IFR_NUMERIC_SIZE_8:
              if (FilterFlags != EFI_KEYWORD_FILTER_NUMERIC_8) {
                RetVal = KEYWORD_HANDLER_INCOMPATIBLE_VALUE_DETECTED;
                goto Done;
              }

              break;

            default:
              ASSERT (FALSE);
              break;
          }
        }

        break;

      default:
        ASSERT (FALSE);
        break;
    }

    //
    // Jump to the next filter.
    //
    StringPtr = NextFilter;
  }

Done:
  //
  // The current filter which is processing.
  //
  *NextString = StringPtr;

  return RetVal;
}

/**
  Get HII_DATABASE_RECORD from the input device path info.

  This is a internal function.

  @param  DevicePath             UEFI device path protocol.

  @retval Internal data base record.

**/
HII_DATABASE_RECORD *
GetRecordFromDevicePath (
  IN EFI_DEVICE_PATH_PROTOCOL  *DevicePath
  )
{
  LIST_ENTRY           *Link;
  UINT8                *DevicePathPkg;
  UINT8                *CurrentDevicePath;
  UINTN                DevicePathSize;
  HII_DATABASE_RECORD  *TempDatabase;

  ASSERT (DevicePath != NULL);

  for (Link = mPrivate.DatabaseList.ForwardLink; Link != &mPrivate.DatabaseList; Link = Link->ForwardLink) {
    TempDatabase  = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);
    DevicePathPkg = TempDatabase->PackageList->DevicePathPkg;
    if (DevicePathPkg != NULL) {
      CurrentDevicePath = DevicePathPkg + sizeof (EFI_HII_PACKAGE_HEADER);
      DevicePathSize    = GetDevicePathSize ((EFI_DEVICE_PATH_PROTOCOL *)CurrentDevicePath);
      if ((CompareMem (DevicePath, CurrentDevicePath, DevicePathSize) == 0)) {
        return TempDatabase;
      }
    }
  }

  return NULL;
}

/**
  Calculate the size of StringSrc and output it. Also copy string text from src
  to dest.

  This is a internal function.

  @param  StringSrc              Points to current null-terminated string.
  @param  BufferSize             Length of the buffer.
  @param  StringDest             Buffer to store the string text.

  @retval EFI_SUCCESS            The string text was outputted successfully.
  @retval EFI_OUT_OF_RESOURCES   Out of resource.

**/
EFI_STATUS
GetUnicodeStringTextAndSize (
  IN  UINT8       *StringSrc,
  OUT UINTN       *BufferSize,
  OUT EFI_STRING  *StringDest
  )
{
  UINTN  StringSize;
  UINT8  *StringPtr;

  ASSERT (StringSrc != NULL && BufferSize != NULL && StringDest != NULL);

  StringSize = sizeof (CHAR16);
  StringPtr  = StringSrc;
  while (ReadUnaligned16 ((UINT16 *)StringPtr) != 0) {
    StringSize += sizeof (CHAR16);
    StringPtr  += sizeof (CHAR16);
  }

  *StringDest = AllocatePool (StringSize);
  if (*StringDest == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  CopyMem (*StringDest, StringSrc, StringSize);

  *BufferSize = StringSize;
  return EFI_SUCCESS;
}

/**
  Find the string id for the input keyword.

  @param  StringPackage           Hii string package instance.
  @param  KeywordValue            Input keyword value.
  @param  StringId                The string's id, which is unique within PackageList.


  @retval EFI_SUCCESS             The string text and font is retrieved
                                  successfully.
  @retval EFI_NOT_FOUND           The specified text or font info can not be found
                                  out.
  @retval EFI_OUT_OF_RESOURCES    The system is out of resources to accomplish the
                                  task.
**/
EFI_STATUS
GetStringIdFromString (
  IN HII_STRING_PACKAGE_INSTANCE  *StringPackage,
  IN CHAR16                       *KeywordValue,
  OUT EFI_STRING_ID               *StringId
  )
{
  UINT8                    *BlockHdr;
  EFI_STRING_ID            CurrentStringId;
  UINTN                    BlockSize;
  UINTN                    Index;
  UINT8                    *StringTextPtr;
  UINTN                    Offset;
  UINT16                   StringCount;
  UINT16                   SkipCount;
  UINT8                    Length8;
  EFI_HII_SIBT_EXT2_BLOCK  Ext2;
  UINT32                   Length32;
  UINTN                    StringSize;
  CHAR16                   *String;
  CHAR8                    *AsciiKeywordValue;
  UINTN                    KeywordValueSize;
  EFI_STATUS               Status;

  ASSERT (StringPackage != NULL && KeywordValue != NULL && StringId != NULL);
  ASSERT (StringPackage->Signature == HII_STRING_PACKAGE_SIGNATURE);

  CurrentStringId = 1;
  Status          = EFI_SUCCESS;
  String          = NULL;
  BlockHdr        = StringPackage->StringBlock;
  BlockSize       = 0;
  Offset          = 0;

  //
  // Make a ascii keyword value for later use.
  //
  KeywordValueSize  = StrLen (KeywordValue) + 1;
  AsciiKeywordValue = AllocatePool (KeywordValueSize);
  if (AsciiKeywordValue == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  UnicodeStrToAsciiStrS (KeywordValue, AsciiKeywordValue, KeywordValueSize);

  while (*BlockHdr != EFI_HII_SIBT_END) {
    switch (*BlockHdr) {
      case EFI_HII_SIBT_STRING_SCSU:
        Offset        = sizeof (EFI_HII_STRING_BLOCK);
        StringTextPtr = BlockHdr + Offset;
        BlockSize    += Offset + AsciiStrSize ((CHAR8 *)StringTextPtr);
        if (AsciiStrCmp (AsciiKeywordValue, (CHAR8 *)StringTextPtr) == 0) {
          *StringId = CurrentStringId;
          goto Done;
        }

        CurrentStringId++;
        break;

      case EFI_HII_SIBT_STRING_SCSU_FONT:
        Offset        = sizeof (EFI_HII_SIBT_STRING_SCSU_FONT_BLOCK) - sizeof (UINT8);
        StringTextPtr = BlockHdr + Offset;
        if (AsciiStrCmp (AsciiKeywordValue, (CHAR8 *)StringTextPtr) == 0) {
          *StringId = CurrentStringId;
          goto Done;
        }

        BlockSize += Offset + AsciiStrSize ((CHAR8 *)StringTextPtr);
        CurrentStringId++;
        break;

      case EFI_HII_SIBT_STRINGS_SCSU:
        CopyMem (&StringCount, BlockHdr + sizeof (EFI_HII_STRING_BLOCK), sizeof (UINT16));
        StringTextPtr = (UINT8 *)((UINTN)BlockHdr + sizeof (EFI_HII_SIBT_STRINGS_SCSU_BLOCK) - sizeof (UINT8));
        BlockSize    += StringTextPtr - BlockHdr;

        for (Index = 0; Index < StringCount; Index++) {
          BlockSize += AsciiStrSize ((CHAR8 *)StringTextPtr);
          if (AsciiStrCmp (AsciiKeywordValue, (CHAR8 *)StringTextPtr) == 0) {
            *StringId = CurrentStringId;
            goto Done;
          }

          StringTextPtr = StringTextPtr + AsciiStrSize ((CHAR8 *)StringTextPtr);
          CurrentStringId++;
        }

        break;

      case EFI_HII_SIBT_STRINGS_SCSU_FONT:
        CopyMem (
          &StringCount,
          (UINT8 *)((UINTN)BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8)),
          sizeof (UINT16)
          );
        StringTextPtr = (UINT8 *)((UINTN)BlockHdr + sizeof (EFI_HII_SIBT_STRINGS_SCSU_FONT_BLOCK) - sizeof (UINT8));
        BlockSize    += StringTextPtr - BlockHdr;

        for (Index = 0; Index < StringCount; Index++) {
          BlockSize += AsciiStrSize ((CHAR8 *)StringTextPtr);
          if (AsciiStrCmp (AsciiKeywordValue, (CHAR8 *)StringTextPtr) == 0) {
            *StringId = CurrentStringId;
            goto Done;
          }

          StringTextPtr = StringTextPtr + AsciiStrSize ((CHAR8 *)StringTextPtr);
          CurrentStringId++;
        }

        break;

      case EFI_HII_SIBT_STRING_UCS2:
        Offset        = sizeof (EFI_HII_STRING_BLOCK);
        StringTextPtr = BlockHdr + Offset;
        //
        // Use StringSize to store the size of the specified string, including the NULL
        // terminator.
        //
        Status = GetUnicodeStringTextAndSize (StringTextPtr, &StringSize, &String);
        if (EFI_ERROR (Status)) {
          goto Done;
        }

        ASSERT (String != NULL);
        if (StrCmp (KeywordValue, String) == 0) {
          *StringId = CurrentStringId;
          goto Done;
        }

        BlockSize += Offset + StringSize;
        CurrentStringId++;
        break;

      case EFI_HII_SIBT_STRING_UCS2_FONT:
        Offset        = sizeof (EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK)  - sizeof (CHAR16);
        StringTextPtr = BlockHdr + Offset;
        //
        // Use StringSize to store the size of the specified string, including the NULL
        // terminator.
        //
        Status = GetUnicodeStringTextAndSize (StringTextPtr, &StringSize, &String);
        if (EFI_ERROR (Status)) {
          goto Done;
        }

        ASSERT (String != NULL);
        if (StrCmp (KeywordValue, String) == 0) {
          *StringId = CurrentStringId;
          goto Done;
        }

        BlockSize += Offset + StringSize;
        CurrentStringId++;
        break;

      case EFI_HII_SIBT_STRINGS_UCS2:
        Offset        = sizeof (EFI_HII_SIBT_STRINGS_UCS2_BLOCK) - sizeof (CHAR16);
        StringTextPtr = BlockHdr + Offset;
        BlockSize    += Offset;
        CopyMem (&StringCount, BlockHdr + sizeof (EFI_HII_STRING_BLOCK), sizeof (UINT16));
        for (Index = 0; Index < StringCount; Index++) {
          Status = GetUnicodeStringTextAndSize (StringTextPtr, &StringSize, &String);
          if (EFI_ERROR (Status)) {
            goto Done;
          }

          ASSERT (String != NULL);
          BlockSize += StringSize;
          if (StrCmp (KeywordValue, String) == 0) {
            *StringId = CurrentStringId;
            goto Done;
          }

          StringTextPtr = StringTextPtr + StringSize;
          CurrentStringId++;
        }

        break;

      case EFI_HII_SIBT_STRINGS_UCS2_FONT:
        Offset        = sizeof (EFI_HII_SIBT_STRINGS_UCS2_FONT_BLOCK) - sizeof (CHAR16);
        StringTextPtr = BlockHdr + Offset;
        BlockSize    += Offset;
        CopyMem (
          &StringCount,
          (UINT8 *)((UINTN)BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8)),
          sizeof (UINT16)
          );
        for (Index = 0; Index < StringCount; Index++) {
          Status = GetUnicodeStringTextAndSize (StringTextPtr, &StringSize, &String);
          if (EFI_ERROR (Status)) {
            goto Done;
          }

          ASSERT (String != NULL);
          BlockSize += StringSize;
          if (StrCmp (KeywordValue, String) == 0) {
            *StringId = CurrentStringId;
            goto Done;
          }

          StringTextPtr = StringTextPtr + StringSize;
          CurrentStringId++;
        }

        break;

      case EFI_HII_SIBT_DUPLICATE:
        BlockSize += sizeof (EFI_HII_SIBT_DUPLICATE_BLOCK);
        CurrentStringId++;
        break;

      case EFI_HII_SIBT_SKIP1:
        SkipCount       = (UINT16)(*(UINT8 *)((UINTN)BlockHdr + sizeof (EFI_HII_STRING_BLOCK)));
        CurrentStringId = (UINT16)(CurrentStringId + SkipCount);
        BlockSize      +=  sizeof (EFI_HII_SIBT_SKIP1_BLOCK);
        break;

      case EFI_HII_SIBT_SKIP2:
        CopyMem (&SkipCount, BlockHdr + sizeof (EFI_HII_STRING_BLOCK), sizeof (UINT16));
        CurrentStringId = (UINT16)(CurrentStringId + SkipCount);
        BlockSize      +=  sizeof (EFI_HII_SIBT_SKIP2_BLOCK);
        break;

      case EFI_HII_SIBT_EXT1:
        CopyMem (
          &Length8,
          (UINT8 *)((UINTN)BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8)),
          sizeof (UINT8)
          );
        BlockSize += Length8;
        break;

      case EFI_HII_SIBT_EXT2:
        CopyMem (&Ext2, BlockHdr, sizeof (EFI_HII_SIBT_EXT2_BLOCK));
        BlockSize += Ext2.Length;
        break;

      case EFI_HII_SIBT_EXT4:
        CopyMem (
          &Length32,
          (UINT8 *)((UINTN)BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8)),
          sizeof (UINT32)
          );

        BlockSize += Length32;
        break;

      default:
        break;
    }

    if (String != NULL) {
      FreePool (String);
      String = NULL;
    }

    BlockHdr = StringPackage->StringBlock + BlockSize;
  }

  Status = EFI_NOT_FOUND;

Done:
  if (AsciiKeywordValue != NULL) {
    FreePool (AsciiKeywordValue);
  }

  if (String != NULL) {
    FreePool (String);
  }

  return Status;
}

/**
  Find the next valid string id for the input string id.

  @param  StringPackage           Hii string package instance.
  @param  StringId                The current string id which is already got.
                                  1 means just begin to get the string id.
  @param  KeywordValue            Return the string for the next string id.


  @retval EFI_STRING_ID           Not 0 means a valid stringid found.
                                  0 means not found a valid string id.
**/
EFI_STRING_ID
GetNextStringId (
  IN  HII_STRING_PACKAGE_INSTANCE  *StringPackage,
  IN  EFI_STRING_ID                StringId,
  OUT EFI_STRING                   *KeywordValue
  )
{
  UINT8                    *BlockHdr;
  EFI_STRING_ID            CurrentStringId;
  UINTN                    BlockSize;
  UINTN                    Index;
  UINT8                    *StringTextPtr;
  UINTN                    Offset;
  UINT16                   StringCount;
  UINT16                   SkipCount;
  UINT8                    Length8;
  EFI_HII_SIBT_EXT2_BLOCK  Ext2;
  UINT32                   Length32;
  BOOLEAN                  FindString;
  UINTN                    StringSize;
  CHAR16                   *String;

  ASSERT (StringPackage != NULL);
  ASSERT (StringPackage->Signature == HII_STRING_PACKAGE_SIGNATURE);

  CurrentStringId = 1;
  FindString      = FALSE;
  String          = NULL;

  //
  // Parse the string blocks to get the string text and font.
  //
  BlockHdr  = StringPackage->StringBlock;
  BlockSize = 0;
  Offset    = 0;
  while (*BlockHdr != EFI_HII_SIBT_END) {
    switch (*BlockHdr) {
      case EFI_HII_SIBT_STRING_SCSU:
        Offset        = sizeof (EFI_HII_STRING_BLOCK);
        StringTextPtr = BlockHdr + Offset;

        if (FindString) {
          StringSize    = AsciiStrSize ((CHAR8 *)StringTextPtr);
          *KeywordValue = AllocatePool (StringSize * sizeof (CHAR16));
          if (*KeywordValue == NULL) {
            return 0;
          }

          AsciiStrToUnicodeStrS ((CHAR8 *)StringTextPtr, *KeywordValue, StringSize);
          return CurrentStringId;
        } else if (CurrentStringId == StringId) {
          FindString = TRUE;
        }

        BlockSize += Offset + AsciiStrSize ((CHAR8 *)StringTextPtr);
        CurrentStringId++;
        break;

      case EFI_HII_SIBT_STRING_SCSU_FONT:
        Offset        = sizeof (EFI_HII_SIBT_STRING_SCSU_FONT_BLOCK) - sizeof (UINT8);
        StringTextPtr = BlockHdr + Offset;

        if (FindString) {
          StringSize    = AsciiStrSize ((CHAR8 *)StringTextPtr);
          *KeywordValue = AllocatePool (StringSize * sizeof (CHAR16));
          if (*KeywordValue == NULL) {
            return 0;
          }

          AsciiStrToUnicodeStrS ((CHAR8 *)StringTextPtr, *KeywordValue, StringSize);
          return CurrentStringId;
        } else if (CurrentStringId == StringId) {
          FindString = TRUE;
        }

        BlockSize += Offset + AsciiStrSize ((CHAR8 *)StringTextPtr);
        CurrentStringId++;
        break;

      case EFI_HII_SIBT_STRINGS_SCSU:
        CopyMem (&StringCount, BlockHdr + sizeof (EFI_HII_STRING_BLOCK), sizeof (UINT16));
        StringTextPtr = (UINT8 *)((UINTN)BlockHdr + sizeof (EFI_HII_SIBT_STRINGS_SCSU_BLOCK) - sizeof (UINT8));
        BlockSize    += StringTextPtr - BlockHdr;

        for (Index = 0; Index < StringCount; Index++) {
          if (FindString) {
            StringSize    = AsciiStrSize ((CHAR8 *)StringTextPtr);
            *KeywordValue = AllocatePool (StringSize * sizeof (CHAR16));
            if (*KeywordValue == NULL) {
              return 0;
            }

            AsciiStrToUnicodeStrS ((CHAR8 *)StringTextPtr, *KeywordValue, StringSize);
            return CurrentStringId;
          } else if (CurrentStringId == StringId) {
            FindString = TRUE;
          }

          BlockSize    += AsciiStrSize ((CHAR8 *)StringTextPtr);
          StringTextPtr = StringTextPtr + AsciiStrSize ((CHAR8 *)StringTextPtr);
          CurrentStringId++;
        }

        break;

      case EFI_HII_SIBT_STRINGS_SCSU_FONT:
        CopyMem (
          &StringCount,
          (UINT8 *)((UINTN)BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8)),
          sizeof (UINT16)
          );
        StringTextPtr = (UINT8 *)((UINTN)BlockHdr + sizeof (EFI_HII_SIBT_STRINGS_SCSU_FONT_BLOCK) - sizeof (UINT8));
        BlockSize    += StringTextPtr - BlockHdr;

        for (Index = 0; Index < StringCount; Index++) {
          if (FindString) {
            StringSize    = AsciiStrSize ((CHAR8 *)StringTextPtr);
            *KeywordValue = AllocatePool (StringSize * sizeof (CHAR16));
            if (*KeywordValue == NULL) {
              return 0;
            }

            AsciiStrToUnicodeStrS ((CHAR8 *)StringTextPtr, *KeywordValue, StringSize);
            return CurrentStringId;
          } else if (CurrentStringId == StringId) {
            FindString = TRUE;
          }

          BlockSize    += AsciiStrSize ((CHAR8 *)StringTextPtr);
          StringTextPtr = StringTextPtr + AsciiStrSize ((CHAR8 *)StringTextPtr);
          CurrentStringId++;
        }

        break;

      case EFI_HII_SIBT_STRING_UCS2:
        Offset        = sizeof (EFI_HII_STRING_BLOCK);
        StringTextPtr = BlockHdr + Offset;
        //
        // Use StringSize to store the size of the specified string, including the NULL
        // terminator.
        //
        GetUnicodeStringTextAndSize (StringTextPtr, &StringSize, &String);
        if (FindString && (String != NULL) && (*String != L'\0')) {
          //
          // String protocol use this type for the string id which has value for other package.
          // It will allocate an empty string block for this string id. so here we also check
          // *String != L'\0' to prohibit this case.
          //
          *KeywordValue = String;
          return CurrentStringId;
        } else if (CurrentStringId == StringId) {
          FindString = TRUE;
        }

        BlockSize += Offset + StringSize;
        CurrentStringId++;
        break;

      case EFI_HII_SIBT_STRING_UCS2_FONT:
        Offset        = sizeof (EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK)  - sizeof (CHAR16);
        StringTextPtr = BlockHdr + Offset;
        //
        // Use StringSize to store the size of the specified string, including the NULL
        // terminator.
        //
        GetUnicodeStringTextAndSize (StringTextPtr, &StringSize, &String);
        if (FindString) {
          *KeywordValue = String;
          return CurrentStringId;
        } else if (CurrentStringId == StringId) {
          FindString = TRUE;
        }

        BlockSize += Offset + StringSize;
        CurrentStringId++;
        break;

      case EFI_HII_SIBT_STRINGS_UCS2:
        Offset        = sizeof (EFI_HII_SIBT_STRINGS_UCS2_BLOCK) - sizeof (CHAR16);
        StringTextPtr = BlockHdr + Offset;
        BlockSize    += Offset;
        CopyMem (&StringCount, BlockHdr + sizeof (EFI_HII_STRING_BLOCK), sizeof (UINT16));
        for (Index = 0; Index < StringCount; Index++) {
          GetUnicodeStringTextAndSize (StringTextPtr, &StringSize, &String);

          if (FindString) {
            *KeywordValue = String;
            return CurrentStringId;
          } else if (CurrentStringId == StringId) {
            FindString = TRUE;
          }

          BlockSize    += StringSize;
          StringTextPtr = StringTextPtr + StringSize;
          CurrentStringId++;
        }

        break;

      case EFI_HII_SIBT_STRINGS_UCS2_FONT:
        Offset        = sizeof (EFI_HII_SIBT_STRINGS_UCS2_FONT_BLOCK) - sizeof (CHAR16);
        StringTextPtr = BlockHdr + Offset;
        BlockSize    += Offset;
        CopyMem (
          &StringCount,
          (UINT8 *)((UINTN)BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8)),
          sizeof (UINT16)
          );
        for (Index = 0; Index < StringCount; Index++) {
          GetUnicodeStringTextAndSize (StringTextPtr, &StringSize, &String);
          if (FindString) {
            *KeywordValue = String;
            return CurrentStringId;
          } else if (CurrentStringId == StringId) {
            FindString = TRUE;
          }

          BlockSize    += StringSize;
          StringTextPtr = StringTextPtr + StringSize;
          CurrentStringId++;
        }

        break;

      case EFI_HII_SIBT_DUPLICATE:
        BlockSize += sizeof (EFI_HII_SIBT_DUPLICATE_BLOCK);
        CurrentStringId++;
        break;

      case EFI_HII_SIBT_SKIP1:
        SkipCount       = (UINT16)(*(UINT8 *)((UINTN)BlockHdr + sizeof (EFI_HII_STRING_BLOCK)));
        CurrentStringId = (UINT16)(CurrentStringId + SkipCount);
        BlockSize      +=  sizeof (EFI_HII_SIBT_SKIP1_BLOCK);
        break;

      case EFI_HII_SIBT_SKIP2:
        CopyMem (&SkipCount, BlockHdr + sizeof (EFI_HII_STRING_BLOCK), sizeof (UINT16));
        CurrentStringId = (UINT16)(CurrentStringId + SkipCount);
        BlockSize      +=  sizeof (EFI_HII_SIBT_SKIP2_BLOCK);
        break;

      case EFI_HII_SIBT_EXT1:
        CopyMem (
          &Length8,
          (UINT8 *)((UINTN)BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8)),
          sizeof (UINT8)
          );
        BlockSize += Length8;
        break;

      case EFI_HII_SIBT_EXT2:
        CopyMem (&Ext2, BlockHdr, sizeof (EFI_HII_SIBT_EXT2_BLOCK));
        BlockSize += Ext2.Length;
        break;

      case EFI_HII_SIBT_EXT4:
        CopyMem (
          &Length32,
          (UINT8 *)((UINTN)BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8)),
          sizeof (UINT32)
          );

        BlockSize += Length32;
        break;

      default:
        break;
    }

    if (String != NULL) {
      FreePool (String);
      String = NULL;
    }

    BlockHdr = StringPackage->StringBlock + BlockSize;
  }

  return 0;
}

/**
  Get string package from the input NameSpace string.

  This is a internal function.

  @param  DatabaseRecord                 HII_DATABASE_RECORD format string.
  @param  NameSpace                      NameSpace format string.
  @param  KeywordValue                   Keyword value.
  @param  StringId                       String Id for this keyword.

  @retval KEYWORD_HANDLER_NO_ERROR                     Get String id successfully.
  @retval KEYWORD_HANDLER_KEYWORD_NOT_FOUND            Not found the string id in the string package.
  @retval KEYWORD_HANDLER_NAMESPACE_ID_NOT_FOUND       Not found the string package for this namespace.
  @retval KEYWORD_HANDLER_UNDEFINED_PROCESSING_ERROR   Out of resource error.

**/
UINT32
GetStringIdFromRecord (
  IN HII_DATABASE_RECORD  *DatabaseRecord,
  IN CHAR8                **NameSpace,
  IN CHAR16               *KeywordValue,
  OUT EFI_STRING_ID       *StringId
  )
{
  LIST_ENTRY                          *Link;
  HII_DATABASE_PACKAGE_LIST_INSTANCE  *PackageListNode;
  HII_STRING_PACKAGE_INSTANCE         *StringPackage;
  EFI_STATUS                          Status;
  CHAR8                               *Name;
  UINT32                              RetVal;

  ASSERT (DatabaseRecord != NULL && NameSpace != NULL && KeywordValue != NULL);

  PackageListNode = DatabaseRecord->PackageList;
  RetVal          = KEYWORD_HANDLER_NAMESPACE_ID_NOT_FOUND;

  if (*NameSpace != NULL) {
    Name = *NameSpace;
  } else {
    Name = UEFI_CONFIG_LANG;
  }

  for (Link = PackageListNode->StringPkgHdr.ForwardLink; Link != &PackageListNode->StringPkgHdr; Link = Link->ForwardLink) {
    StringPackage = CR (Link, HII_STRING_PACKAGE_INSTANCE, StringEntry, HII_STRING_PACKAGE_SIGNATURE);

    if (AsciiStrnCmp (Name, StringPackage->StringPkgHdr->Language, AsciiStrLen (Name)) == 0) {
      Status = GetStringIdFromString (StringPackage, KeywordValue, StringId);
      if (EFI_ERROR (Status)) {
        return KEYWORD_HANDLER_KEYWORD_NOT_FOUND;
      } else {
        if (*NameSpace == NULL) {
          *NameSpace = AllocateCopyPool (AsciiStrSize (StringPackage->StringPkgHdr->Language), StringPackage->StringPkgHdr->Language);
          if (*NameSpace == NULL) {
            return KEYWORD_HANDLER_UNDEFINED_PROCESSING_ERROR;
          }
        }

        return KEYWORD_HANDLER_NO_ERROR;
      }
    }
  }

  return RetVal;
}

/**
  Tell whether this Operand is an Statement OpCode.

  @param  Operand                Operand of an IFR OpCode.

  @retval TRUE                   This is an Statement OpCode.
  @retval FALSE                  Not an Statement OpCode.

**/
BOOLEAN
IsStatementOpCode (
  IN UINT8  Operand
  )
{
  if ((Operand == EFI_IFR_SUBTITLE_OP) ||
      (Operand == EFI_IFR_TEXT_OP) ||
      (Operand == EFI_IFR_RESET_BUTTON_OP) ||
      (Operand == EFI_IFR_REF_OP) ||
      (Operand == EFI_IFR_ACTION_OP) ||
      (Operand == EFI_IFR_NUMERIC_OP) ||
      (Operand == EFI_IFR_ORDERED_LIST_OP) ||
      (Operand == EFI_IFR_CHECKBOX_OP) ||
      (Operand == EFI_IFR_STRING_OP) ||
      (Operand == EFI_IFR_PASSWORD_OP) ||
      (Operand == EFI_IFR_DATE_OP) ||
      (Operand == EFI_IFR_TIME_OP) ||
      (Operand == EFI_IFR_GUID_OP) ||
      (Operand == EFI_IFR_ONE_OF_OP))
  {
    return TRUE;
  }

  return FALSE;
}

/**
  Tell whether this Operand is an Statement OpCode.

  @param  Operand                Operand of an IFR OpCode.

  @retval TRUE                   This is an Statement OpCode.
  @retval FALSE                  Not an Statement OpCode.

**/
BOOLEAN
IsStorageOpCode (
  IN UINT8  Operand
  )
{
  if ((Operand == EFI_IFR_VARSTORE_OP) ||
      (Operand == EFI_IFR_VARSTORE_NAME_VALUE_OP) ||
      (Operand == EFI_IFR_VARSTORE_EFI_OP))
  {
    return TRUE;
  }

  return FALSE;
}

/**
  Base on the prompt string id to find the question.

  @param  FormPackage            The input form package.
  @param  KeywordStrId           The input prompt string id for one question.

  @retval  the opcode for the question.

**/
UINT8 *
FindQuestionFromStringId (
  IN HII_IFR_PACKAGE_INSTANCE  *FormPackage,
  IN EFI_STRING_ID             KeywordStrId
  )
{
  UINT8                     *OpCodeData;
  UINT32                    Offset;
  EFI_IFR_STATEMENT_HEADER  *StatementHeader;
  EFI_IFR_OP_HEADER         *OpCodeHeader;
  UINT32                    FormDataLen;

  ASSERT (FormPackage != NULL);

  FormDataLen = FormPackage->FormPkgHdr.Length - sizeof (EFI_HII_PACKAGE_HEADER);
  Offset      = 0;
  while (Offset < FormDataLen) {
    OpCodeData   = FormPackage->IfrData + Offset;
    OpCodeHeader = (EFI_IFR_OP_HEADER *)OpCodeData;

    if (IsStatementOpCode (OpCodeHeader->OpCode)) {
      StatementHeader = (EFI_IFR_STATEMENT_HEADER *)(OpCodeData + sizeof (EFI_IFR_OP_HEADER));
      if (StatementHeader->Prompt == KeywordStrId) {
        return OpCodeData;
      }
    }

    Offset += OpCodeHeader->Length;
  }

  return NULL;
}

/**
  Base on the varstore id to find the storage info.

  @param  FormPackage            The input form package.
  @param  VarStoreId             The input storage id.

  @retval  the opcode for the storage.

**/
UINT8 *
FindStorageFromVarId (
  IN HII_IFR_PACKAGE_INSTANCE  *FormPackage,
  IN EFI_VARSTORE_ID           VarStoreId
  )
{
  UINT8              *OpCodeData;
  UINT32             Offset;
  EFI_IFR_OP_HEADER  *OpCodeHeader;
  UINT32             FormDataLen;

  ASSERT (FormPackage != NULL);

  FormDataLen = FormPackage->FormPkgHdr.Length - sizeof (EFI_HII_PACKAGE_HEADER);
  Offset      = 0;
  while (Offset < FormDataLen) {
    OpCodeData   = FormPackage->IfrData + Offset;
    OpCodeHeader = (EFI_IFR_OP_HEADER *)OpCodeData;

    if (IsStorageOpCode (OpCodeHeader->OpCode)) {
      switch (OpCodeHeader->OpCode) {
        case EFI_IFR_VARSTORE_OP:
          if (VarStoreId == ((EFI_IFR_VARSTORE *)OpCodeData)->VarStoreId) {
            return OpCodeData;
          }

          break;

        case EFI_IFR_VARSTORE_NAME_VALUE_OP:
          if (VarStoreId == ((EFI_IFR_VARSTORE_NAME_VALUE *)OpCodeData)->VarStoreId) {
            return OpCodeData;
          }

          break;

        case EFI_IFR_VARSTORE_EFI_OP:
          if (VarStoreId == ((EFI_IFR_VARSTORE_EFI *)OpCodeData)->VarStoreId) {
            return OpCodeData;
          }

          break;

        default:
          break;
      }
    }

    Offset += OpCodeHeader->Length;
  }

  return NULL;
}

/**
  Get width info for one question.

  @param  OpCodeData            The input opcode for one question.

  @retval  the width info for one question.

**/
UINT16
GetWidth (
  IN UINT8  *OpCodeData
  )
{
  UINT8  *NextOpCodeData;

  ASSERT (OpCodeData != NULL);

  switch (((EFI_IFR_OP_HEADER *)OpCodeData)->OpCode) {
    case EFI_IFR_REF_OP:
      return (UINT16)sizeof (EFI_HII_REF);

    case EFI_IFR_ONE_OF_OP:
    case EFI_IFR_NUMERIC_OP:
      switch (((EFI_IFR_ONE_OF *)OpCodeData)->Flags & EFI_IFR_NUMERIC_SIZE) {
        case EFI_IFR_NUMERIC_SIZE_1:
          return (UINT16)sizeof (UINT8);

        case EFI_IFR_NUMERIC_SIZE_2:
          return (UINT16)sizeof (UINT16);

        case EFI_IFR_NUMERIC_SIZE_4:
          return (UINT16)sizeof (UINT32);

        case EFI_IFR_NUMERIC_SIZE_8:
          return (UINT16)sizeof (UINT64);

        default:
          ASSERT (FALSE);
          return 0;
      }

    case EFI_IFR_ORDERED_LIST_OP:
      NextOpCodeData = OpCodeData + ((EFI_IFR_ORDERED_LIST *)OpCodeData)->Header.Length;
      //
      // OneOfOption must follow the orderedlist opcode.
      //
      ASSERT (((EFI_IFR_OP_HEADER *)NextOpCodeData)->OpCode == EFI_IFR_ONE_OF_OPTION_OP);
      switch (((EFI_IFR_ONE_OF_OPTION *)NextOpCodeData)->Type) {
        case EFI_IFR_TYPE_NUM_SIZE_8:
          return (UINT16)sizeof (UINT8) * ((EFI_IFR_ORDERED_LIST *)OpCodeData)->MaxContainers;

        case EFI_IFR_TYPE_NUM_SIZE_16:
          return (UINT16)sizeof (UINT16) * ((EFI_IFR_ORDERED_LIST *)OpCodeData)->MaxContainers;

        case EFI_IFR_TYPE_NUM_SIZE_32:
          return (UINT16)sizeof (UINT32) * ((EFI_IFR_ORDERED_LIST *)OpCodeData)->MaxContainers;

        case EFI_IFR_TYPE_NUM_SIZE_64:
          return (UINT16)sizeof (UINT64) * ((EFI_IFR_ORDERED_LIST *)OpCodeData)->MaxContainers;

        default:
          ASSERT (FALSE);
          return 0;
      }

    case EFI_IFR_CHECKBOX_OP:
      return (UINT16)sizeof (BOOLEAN);

    case EFI_IFR_PASSWORD_OP:
      return (UINT16)((UINTN)((EFI_IFR_PASSWORD *)OpCodeData)->MaxSize * sizeof (CHAR16));

    case EFI_IFR_STRING_OP:
      return (UINT16)((UINTN)((EFI_IFR_STRING *)OpCodeData)->MaxSize * sizeof (CHAR16));

    case EFI_IFR_DATE_OP:
      return (UINT16)sizeof (EFI_HII_DATE);

    case EFI_IFR_TIME_OP:
      return (UINT16)sizeof (EFI_HII_TIME);

    default:
      ASSERT (FALSE);
      return 0;
  }
}

/**
  Converts all hex string characters in range ['A'..'F'] to ['a'..'f'] for
  hex digits that appear between a '=' and a '&' in a config string.

  If ConfigString is NULL, then ASSERT().

  @param[in] ConfigString  Pointer to a Null-terminated Unicode string.

  @return  Pointer to the Null-terminated Unicode result string.

**/
EFI_STRING
EFIAPI
InternalLowerConfigString (
  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 ConfigString;
}

/**
  Allocates and returns a Null-terminated Unicode <ConfigHdr> string.

  The format of a <ConfigHdr> is as follows:

    GUID=<HexCh>32&NAME=<Char>NameLength&PATH=<HexChar>DevicePathSize<Null>

  @param[in]  OpCodeData    The opcode for the storage.
  @param[in]  DriverHandle  The driver handle which supports a Device Path Protocol
                            that is the routing information PATH.  Each byte of
                            the Device Path associated with DriverHandle is converted
                            to a 2 Unicode character hexadecimal string.

  @retval NULL   DriverHandle does not support the Device Path Protocol.
  @retval Other  A pointer to the Null-terminate Unicode <ConfigHdr> string

**/
EFI_STRING
ConstructConfigHdr (
  IN UINT8       *OpCodeData,
  IN EFI_HANDLE  DriverHandle
  )
{
  UINTN                     NameLength;
  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
  UINTN                     DevicePathSize;
  CHAR16                    *String;
  CHAR16                    *ReturnString;
  UINTN                     Index;
  UINT8                     *Buffer;
  CHAR16                    *Name;
  CHAR8                     *AsciiName;
  UINTN                     NameSize;
  EFI_GUID                  *Guid;
  UINTN                     MaxLen;

  ASSERT (OpCodeData != NULL);

  switch (((EFI_IFR_OP_HEADER *)OpCodeData)->OpCode) {
    case EFI_IFR_VARSTORE_OP:
      Guid      = (EFI_GUID *)(UINTN *)&((EFI_IFR_VARSTORE *)OpCodeData)->Guid;
      AsciiName = (CHAR8 *)((EFI_IFR_VARSTORE *)OpCodeData)->Name;
      break;

    case EFI_IFR_VARSTORE_NAME_VALUE_OP:
      Guid      = (EFI_GUID *)(UINTN *)&((EFI_IFR_VARSTORE_NAME_VALUE *)OpCodeData)->Guid;
      AsciiName = NULL;
      break;

    case EFI_IFR_VARSTORE_EFI_OP:
      Guid      = (EFI_GUID *)(UINTN *)&((EFI_IFR_VARSTORE_EFI *)OpCodeData)->Guid;
      AsciiName = (CHAR8 *)((EFI_IFR_VARSTORE_EFI *)OpCodeData)->Name;
      break;

    default:
      ASSERT (FALSE);
      Guid      = NULL;
      AsciiName = NULL;
      break;
  }

  if (AsciiName != NULL) {
    NameSize = AsciiStrSize (AsciiName);
    Name     = AllocateZeroPool (NameSize * sizeof (CHAR16));
    ASSERT (Name != NULL);
    AsciiStrToUnicodeStrS (AsciiName, Name, NameSize);
  } else {
    Name = NULL;
  }

  //
  // Compute the length of Name in Unicode characters.
  // If Name is NULL, then the length is 0.
  //
  NameLength = 0;
  if (Name != NULL) {
    NameLength = StrLen (Name);
  }

  DevicePath     = NULL;
  DevicePathSize = 0;
  //
  // Retrieve DevicePath Protocol associated with DriverHandle
  //
  if (DriverHandle != NULL) {
    DevicePath = DevicePathFromHandle (DriverHandle);
    if (DevicePath == NULL) {
      return NULL;
    }

    //
    // Compute the size of the device path in bytes
    //
    DevicePathSize = GetDevicePathSize (DevicePath);
  }

  //
  // GUID=<HexCh>32&NAME=<Char>NameLength&PATH=<HexChar>DevicePathSize <Null>
  // | 5 | sizeof (EFI_GUID) * 2 | 6 | NameStrLen*4 | 6 | DevicePathSize * 2 | 1 |
  //
  MaxLen = 5 + sizeof (EFI_GUID) * 2 + 6 + NameLength * 4 + 6 + DevicePathSize * 2 + 1;
  String = AllocateZeroPool (MaxLen * sizeof (CHAR16));
  if (String == NULL) {
    return NULL;
  }

  //
  // Start with L"GUID="
  //
  StrCpyS (String, MaxLen, L"GUID=");
  ReturnString = String;
  String      += StrLen (String);

  if (Guid != NULL) {
    //
    // Append Guid converted to <HexCh>32
    //
    for (Index = 0, Buffer = (UINT8 *)Guid; Index < sizeof (EFI_GUID); Index++) {
      UnicodeValueToStringS (
        String,
        MaxLen * sizeof (CHAR16) - ((UINTN)String - (UINTN)ReturnString),
        PREFIX_ZERO | RADIX_HEX,
        *(Buffer++),
        2
        );
      String += StrnLenS (String, MaxLen - ((UINTN)String - (UINTN)ReturnString) / sizeof (CHAR16));
    }
  }

  //
  // Append L"&NAME="
  //
  StrCatS (ReturnString, MaxLen, L"&NAME=");
  String += StrLen (String);

  if (Name != NULL) {
    //
    // Append Name converted to <Char>NameLength
    //
    for ( ; *Name != L'\0'; Name++) {
      UnicodeValueToStringS (
        String,
        MaxLen * sizeof (CHAR16) - ((UINTN)String - (UINTN)ReturnString),
        PREFIX_ZERO | RADIX_HEX,
        *Name,
        4
        );
      String += StrnLenS (String, MaxLen - ((UINTN)String - (UINTN)ReturnString) / sizeof (CHAR16));
    }
  }

  //
  // Append L"&PATH="
  //
  StrCatS (ReturnString, MaxLen, L"&PATH=");
  String += StrLen (String);

  //
  // Append the device path associated with DriverHandle converted to <HexChar>DevicePathSize
  //
  for (Index = 0, Buffer = (UINT8 *)DevicePath; Index < DevicePathSize; Index++) {
    UnicodeValueToStringS (
      String,
      MaxLen * sizeof (CHAR16) - ((UINTN)String - (UINTN)ReturnString),
      PREFIX_ZERO | RADIX_HEX,
      *(Buffer++),
      2
      );
    String += StrnLenS (String, MaxLen - ((UINTN)String - (UINTN)ReturnString) / sizeof (CHAR16));
  }

  //
  // Null terminate the Unicode string
  //
  *String = L'\0';

  //
  // Convert all hex digits in range [A-F] in the configuration header to [a-f]
  //
  return InternalLowerConfigString (ReturnString);
}

/**
  Generate the Config request element for one question.

  @param   Name    The name info for one question.
  @param   Offset  The offset info for one question.
  @param   Width   The width info for one question.

  @return  Pointer to the Null-terminated Unicode request element string.

**/
EFI_STRING
ConstructRequestElement (
  IN CHAR16  *Name,
  IN UINT16  Offset,
  IN UINT16  Width
  )
{
  CHAR16  *StringPtr;
  UINTN   Length;

  if (Name != NULL) {
    //
    // Add <BlockName> length for each Name
    //
    // <BlockName> ::= Name + \0
    //                 StrLen(Name) | 1
    //
    Length = StrLen (Name) + 1;
  } else {
    //
    // Add <BlockName> length for each Offset/Width pair
    //
    // <BlockName> ::= OFFSET=1234&WIDTH=1234 + \0
    //                 |  7   | 4 |   7  | 4 |  1
    //
    Length = (7 + 4 + 7 + 4 + 1);
  }

  //
  // Allocate buffer for the entire <ConfigRequest>
  //
  StringPtr = AllocateZeroPool (Length * sizeof (CHAR16));
  ASSERT (StringPtr != NULL);

  if (Name != NULL) {
    //
    // Append Name\0
    //
    UnicodeSPrint (
      StringPtr,
      (StrLen (Name) + 1) * sizeof (CHAR16),
      L"%s",
      Name
      );
  } else {
    //
    // Append OFFSET=XXXX&WIDTH=YYYY\0
    //
    UnicodeSPrint (
      StringPtr,
      (7 + 4 + 7 + 4 + 1) * sizeof (CHAR16),
      L"OFFSET=%04X&WIDTH=%04X",
      Offset,
      Width
      );
  }

  return StringPtr;
}

/**
  Get string value for question's name field.

  @param  DatabaseRecord                 HII_DATABASE_RECORD format string.
  @param  NameId                         The string id for the name field.

  @retval Name string.

**/
CHAR16 *
GetNameFromId (
  IN HII_DATABASE_RECORD  *DatabaseRecord,
  IN EFI_STRING_ID        NameId
  )
{
  CHAR16      *Name;
  CHAR8       *PlatformLanguage;
  CHAR8       *SupportedLanguages;
  CHAR8       *BestLanguage;
  UINTN       StringSize;
  CHAR16      TempString;
  EFI_STATUS  Status;

  Name               = NULL;
  BestLanguage       = NULL;
  PlatformLanguage   = NULL;
  SupportedLanguages = NULL;

  GetEfiGlobalVariable2 (L"PlatformLang", (VOID **)&PlatformLanguage, NULL);
  SupportedLanguages = GetSupportedLanguages (DatabaseRecord->Handle);

  //
  // Get the best matching language from SupportedLanguages
  //
  BestLanguage = GetBestLanguage (
                   SupportedLanguages,
                   FALSE,                                             // RFC 4646 mode
                   PlatformLanguage != NULL ? PlatformLanguage : "",  // Highest priority
                   SupportedLanguages,                                // Lowest priority
                   NULL
                   );
  if (BestLanguage == NULL) {
    BestLanguage = AllocateCopyPool (sizeof ("en-US"), "en-US");
    ASSERT (BestLanguage != NULL);
  }

  StringSize = 0;
  Status     = mPrivate.HiiString.GetString (
                                    &mPrivate.HiiString,
                                    BestLanguage,
                                    DatabaseRecord->Handle,
                                    NameId,
                                    &TempString,
                                    &StringSize,
                                    NULL
                                    );
  if (Status != EFI_BUFFER_TOO_SMALL) {
    goto Done;
  }

  Name = AllocateZeroPool (StringSize);
  if (Name == NULL) {
    goto Done;
  }

  Status = mPrivate.HiiString.GetString (
                                &mPrivate.HiiString,
                                BestLanguage,
                                DatabaseRecord->Handle,
                                NameId,
                                Name,
                                &StringSize,
                                NULL
                                );

  if (EFI_ERROR (Status)) {
    FreePool (Name);
    Name = NULL;
    goto Done;
  }

Done:
  if (SupportedLanguages != NULL) {
    FreePool (SupportedLanguages);
  }

  if (BestLanguage != NULL) {
    FreePool (BestLanguage);
  }

  if (PlatformLanguage != NULL) {
    FreePool (PlatformLanguage);
  }

  return Name;
}

/**
  Base on the input parameter to generate the ConfigRequest string.

  This is a internal function.

  @param  DatabaseRecord                 HII_DATABASE_RECORD format string.
  @param  KeywordStrId                   Keyword string id.
  @param  OpCodeData                     The IFR data for this question.
  @param  ConfigRequest                  Return the generate ConfigRequest string.

  @retval EFI_SUCCESS               Generate ConfigResp string success.
  @retval EFI_OUT_OF_RESOURCES      System out of memory resource error.
  @retval EFI_NOT_FOUND             Not found the question which use this string id
                                    as the prompt string id.
**/
EFI_STATUS
ExtractConfigRequest (
  IN  HII_DATABASE_RECORD  *DatabaseRecord,
  IN  EFI_STRING_ID        KeywordStrId,
  OUT UINT8                **OpCodeData,
  OUT EFI_STRING           *ConfigRequest
  )
{
  LIST_ENTRY                          *Link;
  HII_DATABASE_PACKAGE_LIST_INSTANCE  *PackageListNode;
  HII_IFR_PACKAGE_INSTANCE            *FormPackage;
  EFI_IFR_QUESTION_HEADER             *Header;
  UINT8                               *Storage;
  UINT8                               *OpCode;
  CHAR16                              *Name;
  UINT16                              Offset;
  UINT16                              Width;
  CHAR16                              *ConfigHdr;
  CHAR16                              *RequestElement;
  UINTN                               MaxLen;
  CHAR16                              *StringPtr;

  ASSERT (DatabaseRecord != NULL && OpCodeData != NULL && ConfigRequest != NULL);

  OpCode = NULL;
  Name   = NULL;
  Width  = 0;
  Offset = 0;

  PackageListNode = DatabaseRecord->PackageList;

  //
  // Search the languages in the specified packagelist.
  //
  for (Link = PackageListNode->FormPkgHdr.ForwardLink; Link != &PackageListNode->FormPkgHdr; Link = Link->ForwardLink) {
    FormPackage = CR (Link, HII_IFR_PACKAGE_INSTANCE, IfrEntry, HII_IFR_PACKAGE_SIGNATURE);

    OpCode = FindQuestionFromStringId (FormPackage, KeywordStrId);
    if (OpCode != NULL) {
      *OpCodeData = OpCode;
      Header      = (EFI_IFR_QUESTION_HEADER *)(OpCode + sizeof (EFI_IFR_OP_HEADER));
      //
      // Header->VarStoreId == 0 means no storage for this question.
      //
      ASSERT (Header->VarStoreId != 0);
      DEBUG ((DEBUG_INFO, "Varstore Id: 0x%x\n", Header->VarStoreId));

      Storage = FindStorageFromVarId (FormPackage, Header->VarStoreId);
      ASSERT (Storage != NULL);

      if (((EFI_IFR_OP_HEADER *)Storage)->OpCode == EFI_IFR_VARSTORE_NAME_VALUE_OP) {
        Name = GetNameFromId (DatabaseRecord, Header->VarStoreInfo.VarName);
      } else {
        Offset = Header->VarStoreInfo.VarOffset;
        Width  = GetWidth (OpCode);
      }

      RequestElement = ConstructRequestElement (Name, Offset, Width);
      ConfigHdr      = ConstructConfigHdr (Storage, DatabaseRecord->DriverHandle);
      ASSERT (ConfigHdr != NULL);

      MaxLen         = StrLen (ConfigHdr) + 1 + StrLen (RequestElement) + 1;
      *ConfigRequest = AllocatePool (MaxLen * sizeof (CHAR16));
      if (*ConfigRequest == NULL) {
        FreePool (ConfigHdr);
        FreePool (RequestElement);
        return EFI_OUT_OF_RESOURCES;
      }

      StringPtr = *ConfigRequest;

      StrCpyS (StringPtr, MaxLen, ConfigHdr);

      StrCatS (StringPtr, MaxLen, L"&");

      StrCatS (StringPtr, MaxLen, RequestElement);

      FreePool (ConfigHdr);
      FreePool (RequestElement);

      return EFI_SUCCESS;
    }
  }

  return EFI_NOT_FOUND;
}

/**
  Base on the input parameter to generate the ConfigResp string.

  This is a internal function.

  @param  DatabaseRecord                 HII_DATABASE_RECORD format string.
  @param  KeywordStrId                   Keyword string id.
  @param  ValueElement                   The value for the question which use keyword string id
                                         as the prompt string id.
  @param  OpCodeData                     The IFR data for this question.
  @param  ConfigResp                     Return the generate ConfigResp string.

  @retval EFI_SUCCESS               Generate ConfigResp string success.
  @retval EFI_OUT_OF_RESOURCES      System out of memory resource error.
  @retval EFI_NOT_FOUND             Not found the question which use this string id
                                    as the prompt string id.
**/
EFI_STATUS
ExtractConfigResp (
  IN  HII_DATABASE_RECORD  *DatabaseRecord,
  IN  EFI_STRING_ID        KeywordStrId,
  IN  EFI_STRING           ValueElement,
  OUT UINT8                **OpCodeData,
  OUT EFI_STRING           *ConfigResp
  )
{
  LIST_ENTRY                          *Link;
  HII_DATABASE_PACKAGE_LIST_INSTANCE  *PackageListNode;
  HII_IFR_PACKAGE_INSTANCE            *FormPackage;
  EFI_IFR_QUESTION_HEADER             *Header;
  UINT8                               *Storage;
  UINT8                               *OpCode;
  CHAR16                              *Name;
  UINT16                              Offset;
  UINT16                              Width;
  CHAR16                              *ConfigHdr;
  CHAR16                              *RequestElement;
  UINTN                               MaxLen;
  CHAR16                              *StringPtr;

  ASSERT ((DatabaseRecord != NULL) && (OpCodeData != NULL) && (ConfigResp != NULL) && (ValueElement != NULL));

  OpCode = NULL;
  Name   = NULL;
  Width  = 0;
  Offset = 0;

  PackageListNode = DatabaseRecord->PackageList;

  //
  // Search the languages in the specified packagelist.
  //
  for (Link = PackageListNode->FormPkgHdr.ForwardLink; Link != &PackageListNode->FormPkgHdr; Link = Link->ForwardLink) {
    FormPackage = CR (Link, HII_IFR_PACKAGE_INSTANCE, IfrEntry, HII_IFR_PACKAGE_SIGNATURE);

    OpCode = FindQuestionFromStringId (FormPackage, KeywordStrId);
    if (OpCode != NULL) {
      *OpCodeData = OpCode;
      Header      = (EFI_IFR_QUESTION_HEADER *)(OpCode + sizeof (EFI_IFR_OP_HEADER));
      //
      // Header->VarStoreId == 0 means no storage for this question.
      //
      ASSERT (Header->VarStoreId != 0);
      DEBUG ((DEBUG_INFO, "Varstore Id: 0x%x\n", Header->VarStoreId));

      Storage = FindStorageFromVarId (FormPackage, Header->VarStoreId);
      ASSERT (Storage != NULL);

      if (((EFI_IFR_OP_HEADER *)Storage)->OpCode == EFI_IFR_VARSTORE_NAME_VALUE_OP) {
        Name = GetNameFromId (DatabaseRecord, Header->VarStoreInfo.VarName);
      } else {
        Offset = Header->VarStoreInfo.VarOffset;
        Width  = GetWidth (OpCode);
      }

      RequestElement = ConstructRequestElement (Name, Offset, Width);

      ConfigHdr = ConstructConfigHdr (Storage, DatabaseRecord->DriverHandle);
      ASSERT (ConfigHdr != NULL);

      MaxLen      = StrLen (ConfigHdr) + 1 + StrLen (RequestElement) + 1 + StrLen (L"VALUE=") + StrLen (ValueElement) + 1;
      *ConfigResp = AllocatePool (MaxLen * sizeof (CHAR16));
      if (*ConfigResp == NULL) {
        FreePool (ConfigHdr);
        FreePool (RequestElement);
        return EFI_OUT_OF_RESOURCES;
      }

      StringPtr = *ConfigResp;

      StrCpyS (StringPtr, MaxLen, ConfigHdr);

      StrCatS (StringPtr, MaxLen, L"&");

      StrCatS (StringPtr, MaxLen, RequestElement);

      StrCatS (StringPtr, MaxLen, L"&");

      StrCatS (StringPtr, MaxLen, L"VALUE=");

      StrCatS (StringPtr, MaxLen, ValueElement);

      FreePool (ConfigHdr);
      FreePool (RequestElement);

      return EFI_SUCCESS;
    }
  }

  return EFI_NOT_FOUND;
}

/**
  Get the Value section from the Hii driver.

  This is a internal function.

  @param  ConfigRequest                  The input ConfigRequest string.
  @param  ValueElement                   The respond Value section from the hii driver.

  @retval Misc value                     The error status return from ExtractConfig function.
  @retval EFI_OUT_OF_RESOURCES           The memory can't be allocated
  @retval EFI_SUCCESS                    Get the value section success.

**/
EFI_STATUS
ExtractValueFromDriver (
  IN  CHAR16  *ConfigRequest,
  OUT CHAR16  **ValueElement
  )
{
  EFI_STATUS  Status;
  EFI_STRING  Result;
  EFI_STRING  Progress;
  CHAR16      *StringPtr;
  CHAR16      *StringEnd;

  ASSERT ((ConfigRequest != NULL) && (ValueElement != NULL));

  Status = mPrivate.ConfigRouting.ExtractConfig (
                                    &mPrivate.ConfigRouting,
                                    (EFI_STRING)ConfigRequest,
                                    &Progress,
                                    &Result
                                    );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Find Value Section and return it.
  //
  StringPtr = StrStr (Result, L"&VALUE=");
  ASSERT (StringPtr != NULL);
  StringEnd = StrStr (StringPtr + 1, L"&");
  if (StringEnd != NULL) {
    *StringEnd = L'\0';
  }

  *ValueElement = AllocateCopyPool (StrSize (StringPtr), StringPtr);
  if (*ValueElement == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  if (StringEnd != NULL) {
    *StringEnd = L'&';
  }

  FreePool (Result);

  return EFI_SUCCESS;
}

/**
  Get EFI_STRING_ID info from the input device path, namespace and keyword.

  This is a internal function.

  @param  DevicePath                     Input device path info.
  @param  NameSpace                      NameSpace format string.
  @param  KeywordData                    Keyword used to get string id.
  @param  ProgressErr                    Return extra error type.
  @param  KeywordStringId                Return EFI_STRING_ID.
  @param  DataBaseRecord                 DataBase record data for this driver.

  @retval EFI_INVALID_PARAMETER          Can't find the database record base on the input device path or namespace.
  @retval EFI_NOT_FOUND                  Can't find the EFI_STRING_ID for the keyword.
  @retval EFI_SUCCESS                    Find the EFI_STRING_ID.

**/
EFI_STATUS
GetStringIdFromDatabase (
  IN  EFI_DEVICE_PATH_PROTOCOL  **DevicePath,
  IN  CHAR8                     **NameSpace,
  IN  CHAR16                    *KeywordData,
  OUT UINT32                    *ProgressErr,
  OUT EFI_STRING_ID             *KeywordStringId,
  OUT HII_DATABASE_RECORD       **DataBaseRecord
  )
{
  HII_DATABASE_RECORD       *Record;
  LIST_ENTRY                *Link;
  BOOLEAN                   FindNameSpace;
  EFI_DEVICE_PATH_PROTOCOL  *DestDevicePath;
  UINT8                     *DevicePathPkg;
  UINTN                     DevicePathSize;

  ASSERT ((NameSpace != NULL) && (KeywordData != NULL) && (ProgressErr != NULL) && (KeywordStringId != NULL) && (DataBaseRecord != NULL));

  FindNameSpace = FALSE;

  if (*DevicePath != NULL) {
    //
    // Get DataBaseRecord from device path protocol.
    //
    Record = GetRecordFromDevicePath (*DevicePath);
    if (Record == NULL) {
      //
      // Can't find the DatabaseRecord base on the input device path info.
      // NEED TO CONFIRM the return ProgressErr.
      //
      *ProgressErr = KEYWORD_HANDLER_MALFORMED_STRING;
      return EFI_INVALID_PARAMETER;
    }

    //
    // Get string id from the record.
    //
    *ProgressErr = GetStringIdFromRecord (Record, NameSpace, KeywordData, KeywordStringId);
    switch (*ProgressErr) {
      case KEYWORD_HANDLER_NO_ERROR:
        *DataBaseRecord = Record;
        return EFI_SUCCESS;

      case KEYWORD_HANDLER_NAMESPACE_ID_NOT_FOUND:
        return EFI_INVALID_PARAMETER;

      default:
        ASSERT (*ProgressErr == KEYWORD_HANDLER_KEYWORD_NOT_FOUND);
        return EFI_NOT_FOUND;
    }
  } else {
    //
    // Find driver which matches the routing data.
    //
    for (Link = mPrivate.DatabaseList.ForwardLink; Link != &mPrivate.DatabaseList; Link = Link->ForwardLink) {
      Record = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);

      *ProgressErr = GetStringIdFromRecord (Record, NameSpace, KeywordData, KeywordStringId);
      if (*ProgressErr == KEYWORD_HANDLER_NO_ERROR) {
        *DataBaseRecord = Record;

        if ((DevicePathPkg = Record->PackageList->DevicePathPkg) != NULL) {
          DestDevicePath = (EFI_DEVICE_PATH_PROTOCOL *)(DevicePathPkg + sizeof (EFI_HII_PACKAGE_HEADER));
          DevicePathSize = GetDevicePathSize ((EFI_DEVICE_PATH_PROTOCOL *)DestDevicePath);
          *DevicePath    = AllocateCopyPool (DevicePathSize, DestDevicePath);
          if (*DevicePath == NULL) {
            return EFI_OUT_OF_RESOURCES;
          }
        } else {
          //
          // Need to verify this ASSERT.
          //
          ASSERT (FALSE);
        }

        return EFI_SUCCESS;
      } else if (*ProgressErr == KEYWORD_HANDLER_UNDEFINED_PROCESSING_ERROR) {
        return EFI_OUT_OF_RESOURCES;
      } else if (*ProgressErr == KEYWORD_HANDLER_KEYWORD_NOT_FOUND) {
        FindNameSpace = TRUE;
      }
    }

    //
    // When PathHdr not input, if ever find the namespace, will return KEYWORD_HANDLER_KEYWORD_NOT_FOUND.
    // This is a bit more progress than KEYWORD_HANDLER_NAMESPACE_ID_NOT_FOUND.
    //
    if (FindNameSpace) {
      return EFI_NOT_FOUND;
    } else {
      return EFI_INVALID_PARAMETER;
    }
  }
}

/**
  Generate the KeywordResp String.

  <KeywordResp> ::= <NameSpaceId><PathHdr>'&'<Keyword>'&VALUE='<Number>['&READONLY']

  @param  NameSpace                      NameSpace format string.
  @param  DevicePath                     Input device path info.
  @param  KeywordData                    Keyword used to get string id.
  @param  ValueStr                       The value section for the keyword.
  @param  ReadOnly                       Whether this value is readonly.
  @param  KeywordResp                    Return the point to the KeywordResp string.

  @retval EFI_OUT_OF_RESOURCES           The memory can't be allocated.
  @retval EFI_SUCCESS                    Generate the KeywordResp string.

**/
EFI_STATUS
GenerateKeywordResp (
  IN  CHAR8                     *NameSpace,
  IN  EFI_DEVICE_PATH_PROTOCOL  *DevicePath,
  IN  EFI_STRING                KeywordData,
  IN  EFI_STRING                ValueStr,
  IN  BOOLEAN                   ReadOnly,
  OUT EFI_STRING                *KeywordResp
  )
{
  UINTN   RespStrLen;
  CHAR16  *RespStr;
  CHAR16  *PathHdr;
  CHAR16  *UnicodeNameSpace;
  UINTN   NameSpaceLength;

  ASSERT ((NameSpace != NULL) && (DevicePath != NULL) && (KeywordData != NULL) && (ValueStr != NULL) && (KeywordResp != NULL));

  //
  // 1. Calculate the string length.
  //
  //
  // 1.1 NameSpaceId size.
  // 'NAMESPACE='<String>
  //
  NameSpaceLength  = AsciiStrLen (NameSpace);
  RespStrLen       = 10 + NameSpaceLength;
  UnicodeNameSpace = AllocatePool ((NameSpaceLength + 1) * sizeof (CHAR16));
  if (UnicodeNameSpace == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  AsciiStrToUnicodeStrS (NameSpace, UnicodeNameSpace, NameSpaceLength + 1);

  //
  // 1.2 PathHdr size.
  // PATH=<UEFI binary Device Path represented as hex number>'&'
  // Attention: The output include the '&' at the end.
  //
  GenerateSubStr (
    L"&PATH=",
    GetDevicePathSize ((EFI_DEVICE_PATH_PROTOCOL *)DevicePath),
    (VOID *)DevicePath,
    1,
    &PathHdr
    );
  RespStrLen += StrLen (PathHdr);

  //
  // 1.3 Keyword section.
  // 'KEYWORD='<String>[':'<DecCh>(1/4)]
  //
  RespStrLen += 8 + StrLen (KeywordData);

  //
  // 1.4 Value section.
  // ValueStr = '&VALUE='<Number>
  //
  RespStrLen += StrLen (ValueStr);

  //
  // 1.5 ReadOnly Section.
  // '&READONLY'
  //
  if (ReadOnly) {
    RespStrLen += 9;
  }

  //
  // 2. Allocate the buffer and create the KeywordResp string include '\0'.
  //
  RespStrLen  += 1;
  *KeywordResp = AllocatePool (RespStrLen * sizeof (CHAR16));
  if (*KeywordResp == NULL) {
    if (UnicodeNameSpace != NULL) {
      FreePool (UnicodeNameSpace);
    }

    return EFI_OUT_OF_RESOURCES;
  }

  RespStr = *KeywordResp;

  //
  // 2.1 Copy NameSpaceId section.
  //
  StrCpyS (RespStr, RespStrLen, L"NAMESPACE=");

  StrCatS (RespStr, RespStrLen, UnicodeNameSpace);

  //
  // 2.2 Copy PathHdr section.
  //
  StrCatS (RespStr, RespStrLen, PathHdr);

  //
  // 2.3 Copy Keyword section.
  //
  StrCatS (RespStr, RespStrLen, L"KEYWORD=");

  StrCatS (RespStr, RespStrLen, KeywordData);

  //
  // 2.4 Copy the Value section.
  //
  StrCatS (RespStr, RespStrLen, ValueStr);

  //
  // 2.5 Copy ReadOnly section if exist.
  //
  if (ReadOnly) {
    StrCatS (RespStr, RespStrLen, L"&READONLY");
  }

  if (UnicodeNameSpace != NULL) {
    FreePool (UnicodeNameSpace);
  }

  if (PathHdr != NULL) {
    FreePool (PathHdr);
  }

  return EFI_SUCCESS;
}

/**
  Merge the KeywordResp String to MultiKeywordResp string.

  This is a internal function.

  @param  MultiKeywordResp               The existed multikeywordresp string.
  @param  KeywordResp                    The input keywordResp string.

  @retval EFI_OUT_OF_RESOURCES           The memory can't be allocated.
  @retval EFI_SUCCESS                    Generate the MultiKeywordResp string.

**/
EFI_STATUS
MergeToMultiKeywordResp (
  IN OUT EFI_STRING  *MultiKeywordResp,
  IN     EFI_STRING  *KeywordResp
  )
{
  UINTN       MultiKeywordRespLen;
  EFI_STRING  StringPtr;

  if (*MultiKeywordResp == NULL) {
    *MultiKeywordResp = *KeywordResp;
    *KeywordResp      = NULL;
    return EFI_SUCCESS;
  }

  MultiKeywordRespLen = (StrLen (*MultiKeywordResp) + 1 + StrLen (*KeywordResp) + 1) * sizeof (CHAR16);

  StringPtr = ReallocatePool (
                StrSize (*MultiKeywordResp),
                MultiKeywordRespLen,
                *MultiKeywordResp
                );
  if (StringPtr == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  *MultiKeywordResp = StringPtr;

  StrCatS (StringPtr, MultiKeywordRespLen / sizeof (CHAR16), L"&");

  StrCatS (StringPtr, MultiKeywordRespLen / sizeof (CHAR16), *KeywordResp);

  return EFI_SUCCESS;
}

/**
  Enumerate all keyword in the system.

  If error occur when parse one keyword, just skip it and parse the next one.

  This is a internal function.

  @param  NameSpace                      The namespace used to search the string.
  @param  MultiResp                      Return the MultiKeywordResp string for the system.
  @param  ProgressErr                    Return the error status.

  @retval EFI_OUT_OF_RESOURCES           The memory can't be allocated.
  @retval EFI_SUCCESS                    Generate the MultiKeywordResp string.
  @retval EFI_NOT_FOUND                  No keyword found.

**/
EFI_STATUS
EnumerateAllKeywords (
  IN  CHAR8       *NameSpace,
  OUT EFI_STRING  *MultiResp,
  OUT UINT32      *ProgressErr
  )
{
  LIST_ENTRY                          *Link;
  LIST_ENTRY                          *StringLink;
  UINT8                               *DevicePathPkg;
  UINT8                               *DevicePath;
  HII_DATABASE_RECORD                 *DataBaseRecord;
  HII_DATABASE_PACKAGE_LIST_INSTANCE  *PackageListNode;
  HII_STRING_PACKAGE_INSTANCE         *StringPackage;
  CHAR8                               *LocalNameSpace;
  EFI_STRING_ID                       NextStringId;
  EFI_STATUS                          Status;
  UINT8                               *OpCode;
  CHAR16                              *ConfigRequest;
  CHAR16                              *ValueElement;
  CHAR16                              *KeywordResp;
  CHAR16                              *MultiKeywordResp;
  CHAR16                              *KeywordData;
  BOOLEAN                             ReadOnly;
  BOOLEAN                             FindKeywordPackages;

  DataBaseRecord      = NULL;
  Status              = EFI_SUCCESS;
  MultiKeywordResp    = NULL;
  DevicePath          = NULL;
  LocalNameSpace      = NULL;
  ConfigRequest       = NULL;
  ValueElement        = NULL;
  KeywordResp         = NULL;
  FindKeywordPackages = FALSE;

  if (NameSpace == NULL) {
    NameSpace = UEFI_CONFIG_LANG;
  }

  //
  // Find driver which matches the routing data.
  //
  for (Link = mPrivate.DatabaseList.ForwardLink; Link != &mPrivate.DatabaseList; Link = Link->ForwardLink) {
    DataBaseRecord = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);
    if ((DevicePathPkg = DataBaseRecord->PackageList->DevicePathPkg) != NULL) {
      DevicePath = DevicePathPkg + sizeof (EFI_HII_PACKAGE_HEADER);
    }

    PackageListNode = DataBaseRecord->PackageList;

    for (StringLink = PackageListNode->StringPkgHdr.ForwardLink; StringLink != &PackageListNode->StringPkgHdr; StringLink = StringLink->ForwardLink) {
      StringPackage = CR (StringLink, HII_STRING_PACKAGE_INSTANCE, StringEntry, HII_STRING_PACKAGE_SIGNATURE);

      //
      // Check whether has keyword string package.
      //
      if (AsciiStrnCmp (NameSpace, StringPackage->StringPkgHdr->Language, AsciiStrLen (NameSpace)) == 0) {
        FindKeywordPackages = TRUE;
        //
        // Keep the NameSpace string.
        //
        LocalNameSpace = AllocateCopyPool (AsciiStrSize (StringPackage->StringPkgHdr->Language), StringPackage->StringPkgHdr->Language);
        if (LocalNameSpace == NULL) {
          return EFI_OUT_OF_RESOURCES;
        }

        //
        // 1 means just begin the enumerate the valid string ids.
        // StringId == 1 is always used to save the language for this string package.
        // Any valid string start from 2. so here initial it to 1.
        //
        NextStringId = 1;

        //
        // Enumerate all valid stringid in the package.
        //
        while ((NextStringId = GetNextStringId (StringPackage, NextStringId, &KeywordData)) != 0) {
          //
          // 3.3 Construct the ConfigRequest string.
          //
          Status = ExtractConfigRequest (DataBaseRecord, NextStringId, &OpCode, &ConfigRequest);
          if (EFI_ERROR (Status)) {
            //
            // If can't generate ConfigRequest for this question, skip it and start the next.
            //
            goto Error;
          }

          //
          // 3.4 Extract Value for the input keyword.
          //
          Status = ExtractValueFromDriver (ConfigRequest, &ValueElement);
          if (EFI_ERROR (Status)) {
            if (Status != EFI_OUT_OF_RESOURCES) {
              //
              // If can't generate ConfigRequest for this question, skip it and start the next.
              //
              goto Error;
            }

            //
            // If EFI_OUT_OF_RESOURCES error occur, no need to continue.
            //
            goto Done;
          }

          //
          // Extract readonly flag from opcode.
          //
          ReadOnly = ExtractReadOnlyFromOpCode (OpCode);

          //
          // 5. Generate KeywordResp string.
          //
          ASSERT (DevicePath != NULL);
          Status = GenerateKeywordResp (LocalNameSpace, (EFI_DEVICE_PATH_PROTOCOL *)DevicePath, KeywordData, ValueElement, ReadOnly, &KeywordResp);
          if (Status != EFI_SUCCESS) {
            //
            // If EFI_OUT_OF_RESOURCES error occur, no need to continue.
            //
            goto Done;
          }

          //
          // 6. Merge to the MultiKeywordResp string.
          //
          Status = MergeToMultiKeywordResp (&MultiKeywordResp, &KeywordResp);
          if (EFI_ERROR (Status)) {
            goto Done;
          }

Error:
          //
          // Clean the temp buffer to later use again.
          //
          if (ConfigRequest != NULL) {
            FreePool (ConfigRequest);
            ConfigRequest = NULL;
          }

          if (ValueElement != NULL) {
            FreePool (ValueElement);
            ValueElement = NULL;
          }

          if (KeywordResp != NULL) {
            FreePool (KeywordResp);
            KeywordResp = NULL;
          }
        }

        if (LocalNameSpace != NULL) {
          FreePool (LocalNameSpace);
          LocalNameSpace = NULL;
        }
      }
    }
  }

  //
  // return the already get MultiKeywordString even error occurred.
  //
  if (MultiKeywordResp == NULL) {
    Status = EFI_NOT_FOUND;
    if (!FindKeywordPackages) {
      *ProgressErr = KEYWORD_HANDLER_NAMESPACE_ID_NOT_FOUND;
    } else {
      *ProgressErr = KEYWORD_HANDLER_KEYWORD_NOT_FOUND;
    }
  } else {
    Status = EFI_SUCCESS;
  }

  *MultiResp = MultiKeywordResp;

Done:
  if (LocalNameSpace != NULL) {
    FreePool (LocalNameSpace);
  }

  if (ConfigRequest != NULL) {
    FreePool (ConfigRequest);
  }

  if (ValueElement != NULL) {
    FreePool (ValueElement);
  }

  return Status;
}

/**

  This function accepts a <MultiKeywordResp> formatted string, finds the associated
  keyword owners, creates a <MultiConfigResp> string from it and forwards it to the
  EFI_HII_ROUTING_PROTOCOL.RouteConfig function.

  If there is an issue in resolving the contents of the KeywordString, then the
  function returns an error and also sets the Progress and ProgressErr with the
  appropriate information about where the issue occurred and additional data about
  the nature of the issue.

  In the case when KeywordString containing multiple keywords, when an EFI_NOT_FOUND
  error is generated during processing the second or later keyword element, the system
  storage associated with earlier keywords is not modified. All elements of the
  KeywordString must successfully pass all tests for format and access prior to making
  any modifications to storage.

  In the case when EFI_DEVICE_ERROR is returned from the processing of a KeywordString
  containing multiple keywords, the state of storage associated with earlier keywords
  is undefined.


  @param This             Pointer to the EFI_KEYWORD_HANDLER _PROTOCOL instance.

  @param KeywordString    A null-terminated string in <MultiKeywordResp> format.

  @param Progress         On return, points to a character in the KeywordString.
                          Points to the string's NULL terminator if the 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 ProgressErr      If during the processing of the KeywordString there was
                          a failure, this parameter gives additional information
                          about the possible source of the problem. The various
                          errors are defined in "Related Definitions" below.


  @retval EFI_SUCCESS             The specified action was completed successfully.

  @retval EFI_INVALID_PARAMETER   One or more of the following are TRUE:
                                  1. KeywordString is NULL.
                                  2. Parsing of the KeywordString resulted in an
                                     error. See Progress and ProgressErr for more data.

  @retval EFI_NOT_FOUND           An element of the KeywordString was not found.
                                  See ProgressErr for more data.

  @retval EFI_OUT_OF_RESOURCES    Required system resources could not be allocated.
                                  See ProgressErr for more data.

  @retval EFI_ACCESS_DENIED       The action violated system policy. See ProgressErr
                                  for more data.

  @retval EFI_DEVICE_ERROR        An unexpected system error occurred. See ProgressErr
                                  for more data.

**/
EFI_STATUS
EFIAPI
EfiConfigKeywordHandlerSetData (
  IN EFI_CONFIG_KEYWORD_HANDLER_PROTOCOL  *This,
  IN CONST EFI_STRING                     KeywordString,
  OUT EFI_STRING                          *Progress,
  OUT UINT32                              *ProgressErr
  )
{
  CHAR8                     *NameSpace;
  EFI_STATUS                Status;
  CHAR16                    *StringPtr;
  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
  CHAR16                    *NextStringPtr;
  CHAR16                    *KeywordData;
  EFI_STRING_ID             KeywordStringId;
  UINT32                    RetVal;
  HII_DATABASE_RECORD       *DataBaseRecord;
  UINT8                     *OpCode;
  CHAR16                    *ConfigResp;
  CHAR16                    *MultiConfigResp;
  CHAR16                    *ValueElement;
  BOOLEAN                   ReadOnly;
  EFI_STRING                InternalProgress;
  CHAR16                    *TempString;
  CHAR16                    *KeywordStartPos;

  if ((This == NULL) || (Progress == NULL) || (ProgressErr == NULL) || (KeywordString == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  *Progress       = KeywordString;
  *ProgressErr    = KEYWORD_HANDLER_UNDEFINED_PROCESSING_ERROR;
  Status          = EFI_SUCCESS;
  MultiConfigResp = NULL;
  NameSpace       = NULL;
  DevicePath      = NULL;
  KeywordData     = NULL;
  ValueElement    = NULL;
  ConfigResp      = NULL;
  KeywordStartPos = NULL;
  KeywordStringId = 0;

  //
  // Use temp string to avoid changing input string buffer.
  //
  TempString = AllocateCopyPool (StrSize (KeywordString), KeywordString);
  ASSERT (TempString != NULL);
  StringPtr = TempString;

  while ((StringPtr != NULL) && (*StringPtr != L'\0')) {
    //
    // 1. Get NameSpace from NameSpaceId keyword.
    //
    Status = ExtractNameSpace (StringPtr, &NameSpace, &NextStringPtr);
    if (EFI_ERROR (Status)) {
      *ProgressErr = KEYWORD_HANDLER_MALFORMED_STRING;
      goto Done;
    }

    ASSERT (NameSpace != NULL);
    //
    // 1.1 Check whether the input namespace is valid.
    //
    if (AsciiStrnCmp (NameSpace, UEFI_CONFIG_LANG, AsciiStrLen (UEFI_CONFIG_LANG)) != 0) {
      *ProgressErr = KEYWORD_HANDLER_MALFORMED_STRING;
      Status       = EFI_INVALID_PARAMETER;
      goto Done;
    }

    StringPtr = NextStringPtr;

    //
    // 2. Get possible Device Path info from KeywordString.
    //
    Status = ExtractDevicePath (StringPtr, (UINT8 **)&DevicePath, &NextStringPtr);
    if (EFI_ERROR (Status)) {
      *ProgressErr = KEYWORD_HANDLER_MALFORMED_STRING;
      goto Done;
    }

    StringPtr = NextStringPtr;

    //
    // 3. Extract keyword from the KeywordRequest string.
    //
    KeywordStartPos = StringPtr;
    Status          = ExtractKeyword (StringPtr, &KeywordData, &NextStringPtr);
    if (EFI_ERROR (Status)) {
      //
      // Can't find Keyword base on the input device path info.
      //
      *ProgressErr = KEYWORD_HANDLER_MALFORMED_STRING;
      Status       = EFI_INVALID_PARAMETER;
      goto Done;
    }

    StringPtr = NextStringPtr;

    //
    // 4. Extract Value from the KeywordRequest string.
    //
    Status = ExtractValue (StringPtr, &ValueElement, &NextStringPtr);
    if (EFI_ERROR (Status)) {
      //
      // Can't find Value base on the input device path info.
      //
      *ProgressErr = KEYWORD_HANDLER_MALFORMED_STRING;
      Status       = EFI_INVALID_PARAMETER;
      goto Done;
    }

    StringPtr = NextStringPtr;

    //
    // 5. Find READONLY tag.
    //
    if ((StringPtr != NULL) && (StrnCmp (StringPtr, L"&READONLY", StrLen (L"&READONLY")) == 0)) {
      ReadOnly   = TRUE;
      StringPtr += StrLen (L"&READONLY");
    } else {
      ReadOnly = FALSE;
    }

    //
    // 6. Get EFI_STRING_ID for the input keyword.
    //
    Status = GetStringIdFromDatabase (&DevicePath, &NameSpace, KeywordData, &RetVal, &KeywordStringId, &DataBaseRecord);
    if (EFI_ERROR (Status)) {
      *ProgressErr = RetVal;
      goto Done;
    }

    //
    // 7. Construct the ConfigRequest string.
    //
    Status = ExtractConfigResp (DataBaseRecord, KeywordStringId, ValueElement, &OpCode, &ConfigResp);
    if (EFI_ERROR (Status)) {
      goto Done;
    }

    //
    // 8. Check the readonly flag.
    //
    if (ExtractReadOnlyFromOpCode (OpCode) != ReadOnly) {
      //
      // Extracting readonly flag form opcode and extracting "READONLY" tag form KeywordString should have the same results.
      // If not, the input KeywordString must be incorrect, return the error status to caller.
      //
      *ProgressErr = KEYWORD_HANDLER_INCOMPATIBLE_VALUE_DETECTED;
      Status       = EFI_INVALID_PARAMETER;
      goto Done;
    }

    if (ReadOnly) {
      *ProgressErr = KEYWORD_HANDLER_ACCESS_NOT_PERMITTED;
      Status       = EFI_ACCESS_DENIED;
      goto Done;
    }

    //
    // 9. Merge to the MultiKeywordResp string.
    //
    Status = MergeToMultiKeywordResp (&MultiConfigResp, &ConfigResp);
    if (EFI_ERROR (Status)) {
      goto Done;
    }

    //
    // 10. Clean the temp buffer point.
    //
    FreePool (NameSpace);
    FreePool (DevicePath);
    FreePool (KeywordData);
    FreePool (ValueElement);
    NameSpace    = NULL;
    DevicePath   = NULL;
    KeywordData  = NULL;
    ValueElement = NULL;
    if (ConfigResp != NULL) {
      FreePool (ConfigResp);
      ConfigResp = NULL;
    }

    KeywordStartPos = NULL;
  }

  //
  // 11. Set value to driver.
  //
  Status = mPrivate.ConfigRouting.RouteConfig (
                                    &mPrivate.ConfigRouting,
                                    (EFI_STRING)MultiConfigResp,
                                    &InternalProgress
                                    );
  if (EFI_ERROR (Status)) {
    Status = EFI_DEVICE_ERROR;
    goto Done;
  }

  *ProgressErr = KEYWORD_HANDLER_NO_ERROR;

Done:
  if (KeywordStartPos != NULL) {
    *Progress = KeywordString + (KeywordStartPos - TempString);
  } else {
    *Progress = KeywordString + (StringPtr - TempString);
  }

  ASSERT (TempString != NULL);
  FreePool (TempString);
  if (NameSpace != NULL) {
    FreePool (NameSpace);
  }

  if (DevicePath != NULL) {
    FreePool (DevicePath);
  }

  if (KeywordData != NULL) {
    FreePool (KeywordData);
  }

  if (ValueElement != NULL) {
    FreePool (ValueElement);
  }

  if (ConfigResp != NULL) {
    FreePool (ConfigResp);
  }

  if ((MultiConfigResp != NULL) && (MultiConfigResp != ConfigResp)) {
    FreePool (MultiConfigResp);
  }

  return Status;
}

/**

  This function accepts a <MultiKeywordRequest> formatted string, finds the underlying
  keyword owners, creates a <MultiConfigRequest> string from it and forwards it to the
  EFI_HII_ROUTING_PROTOCOL.ExtractConfig function.

  If there is an issue in resolving the contents of the KeywordString, then the function
  returns an EFI_INVALID_PARAMETER and also set the Progress and ProgressErr with the
  appropriate information about where the issue occurred and additional data about the
  nature of the issue.

  In the case when KeywordString is NULL, or contains multiple keywords, or when
  EFI_NOT_FOUND is generated while processing the keyword elements, the Results string
  contains values returned for all keywords processed prior to the keyword generating the
  error but no values for the keyword with error or any following keywords.


  @param This           Pointer to the EFI_KEYWORD_HANDLER _PROTOCOL instance.

  @param NameSpaceId    A null-terminated string containing the platform configuration
                        language to search through in the system. If a NULL is passed
                        in, then it is assumed that any platform configuration language
                        with the prefix of "x-UEFI-" are searched.

  @param KeywordString  A null-terminated string in <MultiKeywordRequest> format. If a
                        NULL is passed in the KeywordString field, all of the known
                        keywords in the system for the NameSpaceId specified are
                        returned in the Results field.

  @param Progress       On return, points to a character in the KeywordString. Points
                        to the string's NULL terminator if the 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 ProgressErr    If during the processing of the KeywordString there was a
                        failure, this parameter gives additional information about the
                        possible source of the problem. See the definitions in SetData()
                        for valid value definitions.

  @param Results        A null-terminated string in <MultiKeywordResp> format is returned
                        which has all the values filled in for the keywords in the
                        KeywordString. This is a callee-allocated field, and must be freed
                        by the caller after being used.

  @retval EFI_SUCCESS             The specified action was completed successfully.

  @retval EFI_INVALID_PARAMETER   One or more of the following are TRUE:
                                  1.Progress, ProgressErr, or Results is NULL.
                                  2.Parsing of the KeywordString resulted in an error. See
                                    Progress and ProgressErr for more data.


  @retval EFI_NOT_FOUND           An element of the KeywordString was not found. See
                                  ProgressErr for more data.

  @retval EFI_NOT_FOUND           The NamespaceId specified was not found.  See ProgressErr
                                  for more data.

  @retval EFI_OUT_OF_RESOURCES    Required system resources could not be allocated.  See
                                  ProgressErr for more data.

  @retval EFI_ACCESS_DENIED       The action violated system policy.  See ProgressErr for
                                  more data.

  @retval EFI_DEVICE_ERROR        An unexpected system error occurred.  See ProgressErr
                                  for more data.

**/
EFI_STATUS
EFIAPI
EfiConfigKeywordHandlerGetData (
  IN EFI_CONFIG_KEYWORD_HANDLER_PROTOCOL  *This,
  IN CONST EFI_STRING                     NameSpaceId  OPTIONAL,
  IN CONST EFI_STRING                     KeywordString  OPTIONAL,
  OUT EFI_STRING                          *Progress,
  OUT UINT32                              *ProgressErr,
  OUT EFI_STRING                          *Results
  )
{
  CHAR8                     *NameSpace;
  EFI_STATUS                Status;
  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
  HII_DATABASE_RECORD       *DataBaseRecord;
  CHAR16                    *StringPtr;
  CHAR16                    *NextStringPtr;
  CHAR16                    *KeywordData;
  EFI_STRING_ID             KeywordStringId;
  UINT8                     *OpCode;
  CHAR16                    *ConfigRequest;
  CHAR16                    *ValueElement;
  UINT32                    RetVal;
  BOOLEAN                   ReadOnly;
  CHAR16                    *KeywordResp;
  CHAR16                    *MultiKeywordResp;
  CHAR16                    *TempString;

  if ((This == NULL) || (Progress == NULL) || (ProgressErr == NULL) || (Results == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  *ProgressErr     = KEYWORD_HANDLER_UNDEFINED_PROCESSING_ERROR;
  Status           = EFI_SUCCESS;
  DevicePath       = NULL;
  NameSpace        = NULL;
  KeywordData      = NULL;
  ConfigRequest    = NULL;
  StringPtr        = KeywordString;
  ReadOnly         = FALSE;
  MultiKeywordResp = NULL;
  KeywordStringId  = 0;
  TempString       = NULL;

  //
  // Use temp string to avoid changing input string buffer.
  //
  if (NameSpaceId != NULL) {
    TempString = AllocateCopyPool (StrSize (NameSpaceId), NameSpaceId);
    ASSERT (TempString != NULL);
  }

  //
  // 1. Get NameSpace from NameSpaceId keyword.
  //
  Status = ExtractNameSpace (TempString, &NameSpace, NULL);
  if (TempString != NULL) {
    FreePool (TempString);
    TempString = NULL;
  }

  if (EFI_ERROR (Status)) {
    *ProgressErr = KEYWORD_HANDLER_MALFORMED_STRING;
    return Status;
  }

  //
  // 1.1 Check whether the input namespace is valid.
  //
  if (NameSpace != NULL) {
    if (AsciiStrnCmp (NameSpace, UEFI_CONFIG_LANG, AsciiStrLen (UEFI_CONFIG_LANG)) != 0) {
      *ProgressErr = KEYWORD_HANDLER_MALFORMED_STRING;
      return EFI_INVALID_PARAMETER;
    }
  }

  if (KeywordString != NULL) {
    //
    // Use temp string to avoid changing input string buffer.
    //
    TempString = AllocateCopyPool (StrSize (KeywordString), KeywordString);
    ASSERT (TempString != NULL);
    StringPtr = TempString;

    while (*StringPtr != L'\0') {
      //
      // 2. Get possible Device Path info from KeywordString.
      //
      Status = ExtractDevicePath (StringPtr, (UINT8 **)&DevicePath, &NextStringPtr);
      if (EFI_ERROR (Status)) {
        *ProgressErr = KEYWORD_HANDLER_MALFORMED_STRING;
        goto Done;
      }

      StringPtr = NextStringPtr;

      //
      // 3. Process Keyword section from the input keywordRequest string.
      //
      // 3.1 Extract keyword from the KeywordRequest string.
      //
      Status = ExtractKeyword (StringPtr, &KeywordData, &NextStringPtr);
      if (EFI_ERROR (Status)) {
        //
        // Can't find Keyword base on the input device path info.
        //
        *ProgressErr = KEYWORD_HANDLER_MALFORMED_STRING;
        Status       = EFI_INVALID_PARAMETER;
        goto Done;
      }

      //
      // 3.2 Get EFI_STRING_ID for the input keyword.
      //
      Status = GetStringIdFromDatabase (&DevicePath, &NameSpace, KeywordData, &RetVal, &KeywordStringId, &DataBaseRecord);
      if (EFI_ERROR (Status)) {
        *ProgressErr = RetVal;
        goto Done;
      }

      //
      // 3.3 Construct the ConfigRequest string.
      //
      Status = ExtractConfigRequest (DataBaseRecord, KeywordStringId, &OpCode, &ConfigRequest);
      if (EFI_ERROR (Status)) {
        goto Done;
      }

      //
      // 3.4 Extract Value for the input keyword.
      //
      Status = ExtractValueFromDriver (ConfigRequest, &ValueElement);
      if (EFI_ERROR (Status)) {
        if (Status != EFI_OUT_OF_RESOURCES) {
          Status = EFI_DEVICE_ERROR;
        }

        goto Done;
      }

      StringPtr = NextStringPtr;

      //
      // 4. Process the possible filter section.
      //
      RetVal = ValidateFilter (OpCode, StringPtr, &NextStringPtr, &ReadOnly);
      if (RetVal != KEYWORD_HANDLER_NO_ERROR) {
        *ProgressErr = RetVal;
        Status       = EFI_INVALID_PARAMETER;
        goto Done;
      }

      StringPtr = NextStringPtr;

      //
      // 5. Generate KeywordResp string.
      //
      Status = GenerateKeywordResp (NameSpace, DevicePath, KeywordData, ValueElement, ReadOnly, &KeywordResp);
      if (Status != EFI_SUCCESS) {
        goto Done;
      }

      //
      // 6. Merge to the MultiKeywordResp string.
      //
      Status = MergeToMultiKeywordResp (&MultiKeywordResp, &KeywordResp);
      if (EFI_ERROR (Status)) {
        goto Done;
      }

      //
      // 7. Update return value.
      //
      *Results = MultiKeywordResp;

      //
      // 8. Clean the temp buffer.
      //
      FreePool (DevicePath);
      FreePool (KeywordData);
      FreePool (ValueElement);
      FreePool (ConfigRequest);
      DevicePath    = NULL;
      KeywordData   = NULL;
      ValueElement  = NULL;
      ConfigRequest = NULL;
      if (KeywordResp != NULL) {
        FreePool (KeywordResp);
        KeywordResp = NULL;
      }
    }
  } else {
    //
    // Enumerate all keyword in the system.
    //
    Status = EnumerateAllKeywords (NameSpace, &MultiKeywordResp, ProgressErr);
    if (EFI_ERROR (Status)) {
      goto Done;
    }

    *Results = MultiKeywordResp;
  }

  *ProgressErr = KEYWORD_HANDLER_NO_ERROR;

Done:
  *Progress = KeywordString + (StringPtr - TempString);

  if (TempString != NULL) {
    FreePool (TempString);
  }

  if (NameSpace != NULL) {
    FreePool (NameSpace);
  }

  if (DevicePath != NULL) {
    FreePool (DevicePath);
  }

  if (KeywordData != NULL) {
    FreePool (KeywordData);
  }

  return Status;
}
