/** @file
Implementation of interfaces function for EFI_CONFIG_KEYWORD_HANDLER_PROTOCOL.

Copyright (c) 2015 - 2017, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution.  The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php

THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

**/


#include "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 (AsciiStrLen ("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 ((EFI_D_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 ((EFI_D_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;
}
