]> git.proxmox.com Git - mirror_edk2.git/commitdiff
Update HiiDataBase and UefiHiiLib to support Name/Value varstore.
authorEric Dong <eric.dong@intel.com>
Tue, 2 Jul 2013 07:53:35 +0000 (07:53 +0000)
committerydong10 <ydong10@6f19259b-4bc3-4df7-8a09-765794883524>
Tue, 2 Jul 2013 07:53:35 +0000 (07:53 +0000)
Signed-off-by: Eric Dong <eric.dong@intel.com>
Reviewed-by: Liming Gao <liming.gao@intel.com>
git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@14451 6f19259b-4bc3-4df7-8a09-765794883524

MdeModulePkg/Library/UefiHiiLib/HiiLib.c
MdeModulePkg/Universal/DriverSampleDxe/DriverSample.c
MdeModulePkg/Universal/DriverSampleDxe/Vfr.vfr
MdeModulePkg/Universal/HiiDatabaseDxe/ConfigRouting.c
MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabase.h

index 9590f8f14a295759aa681b4c5f70fd1bc034ec31..87aeb947ae50134543b879e34b7516d3c58d4a3c 100644 (file)
@@ -31,6 +31,11 @@ typedef struct {
   UINT8               Scope;\r
 } IFR_BLOCK_DATA;\r
 \r
+typedef struct {\r
+  EFI_VARSTORE_ID     VarStoreId;\r
+  UINT16              Size;\r
+} IFR_VARSTORAGE_DATA;\r
+\r
 //\r
 // <ConfigHdr> Template\r
 //\r
@@ -913,43 +918,94 @@ InternalHiiGetValueOfNumber (
   return EFI_SUCCESS;\r
 }\r
 \r
+/**\r
+  Get value from config request resp string.\r
+\r
+  @param ConfigElement           ConfigResp string contains the current setting.\r
+  @param VarName                 The variable name which need to get value.\r
+  @param VarValue                The return value.\r
+  \r
+  @retval EFI_SUCCESS            Get the value for the VarName\r
+  @retval EFI_OUT_OF_RESOURCES   The memory is not enough.\r
+**/\r
+EFI_STATUS\r
+GetValueFromRequest (\r
+  IN CHAR16                       *ConfigElement,\r
+  IN CHAR16                       *VarName,\r
+  OUT UINT64                      *VarValue\r
+  )\r
+{\r
+  UINT8                        *TmpBuffer;\r
+  CHAR16                       *StringPtr;\r
+  UINTN                        Length;\r
+  EFI_STATUS                   Status;\r
+\r
+  //\r
+  // Find VarName related string.\r
+  //\r
+  StringPtr = StrStr (ConfigElement, VarName);\r
+  ASSERT (StringPtr != NULL);\r
+\r
+  //\r
+  // Skip the "VarName=" string\r
+  //\r
+  StringPtr += StrLen (VarName) + 1;\r
+\r
+  //\r
+  // Get Offset\r
+  //\r
+  Status = InternalHiiGetValueOfNumber (StringPtr, &TmpBuffer, &Length);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  *VarValue = 0;\r
+  CopyMem (VarValue, TmpBuffer, (((Length + 1) / 2) < sizeof (UINT64)) ? ((Length + 1) / 2) : sizeof (UINT64));\r
+\r
+  FreePool (TmpBuffer);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
 /**\r
   This internal function parses IFR data to validate current setting.\r
 \r
-  @param ConfigResp         ConfigResp string contains the current setting.\r
+  Base on the NameValueType, if it is TRUE, RequestElement and HiiHandle is valid;\r
+  else the VarBuffer and CurrentBlockArray is valid.\r
+\r
   @param HiiPackageList     Point to Hii package list.\r
   @param PackageListLength  The length of the pacakge.\r
   @param VarGuid            Guid of the buffer storage.\r
   @param VarName            Name of the buffer storage.\r
+  @param VarBuffer          The data buffer for the storage.\r
+  @param CurrentBlockArray  The block array from the config Requst string.\r
+  @param RequestElement     The config string for this storage.\r
+  @param HiiHandle          The HiiHandle for this formset.\r
+  @param NameValueType      Whether current storage is name/value varstore or not.\r
   \r
   @retval EFI_SUCCESS            The current setting is valid.\r
   @retval EFI_OUT_OF_RESOURCES   The memory is not enough.\r
   @retval EFI_INVALID_PARAMETER  The config string or the Hii package is invalid.\r
 **/\r
 EFI_STATUS\r
-EFIAPI\r
-InternalHiiValidateCurrentSetting (\r
-  IN EFI_STRING                    ConfigResp,\r
+ValidateQuestionFromVfr (\r
   IN EFI_HII_PACKAGE_LIST_HEADER   *HiiPackageList,\r
   IN UINTN                         PackageListLength,\r
   IN EFI_GUID                      *VarGuid,\r
-  IN CHAR16                        *VarName\r
+  IN CHAR16                        *VarName,\r
+  IN UINT8                         *VarBuffer,\r
+  IN IFR_BLOCK_DATA                *CurrentBlockArray,\r
+  IN CHAR16                        *RequestElement,\r
+  IN EFI_HII_HANDLE                HiiHandle,\r
+  IN BOOLEAN                       NameValueType\r
   )\r
-{ \r
-  IFR_BLOCK_DATA               *CurrentBlockArray;\r
-  IFR_BLOCK_DATA               *BlockData;\r
-  IFR_BLOCK_DATA               *NewBlockData;\r
+{\r
   IFR_BLOCK_DATA               VarBlockData;\r
-  EFI_STRING                   StringPtr;\r
-  UINTN                        Length;\r
   UINT8                        *TmpBuffer;\r
   UINT16                       Offset;\r
   UINT16                       Width;\r
   UINT64                       VarValue;\r
   EFI_IFR_TYPE_VALUE           TmpValue;\r
-  LIST_ENTRY                   *Link;\r
-  UINT8                        *VarBuffer;\r
-  UINTN                        MaxBufferSize;\r
   EFI_STATUS                   Status;\r
   EFI_HII_PACKAGE_HEADER       PacakgeHeader;\r
   UINT32                       PackageOffset;\r
@@ -957,6 +1013,9 @@ InternalHiiValidateCurrentSetting (
   UINTN                        IfrOffset;\r
   EFI_IFR_OP_HEADER            *IfrOpHdr;\r
   EFI_IFR_VARSTORE             *IfrVarStore;\r
+  EFI_IFR_VARSTORE_NAME_VALUE  *IfrNameValueStore;\r
+  EFI_IFR_VARSTORE_EFI         *IfrEfiVarStore;\r
+  IFR_VARSTORAGE_DATA          VarStoreData;\r
   EFI_IFR_ONE_OF               *IfrOneOf;\r
   EFI_IFR_NUMERIC              *IfrNumeric;\r
   EFI_IFR_ONE_OF_OPTION        *IfrOneOfOption;\r
@@ -964,230 +1023,30 @@ InternalHiiValidateCurrentSetting (
   EFI_IFR_STRING               *IfrString;\r
   CHAR8                        *VarStoreName;\r
   UINTN                        Index;\r
-  \r
-  //\r
-  // 1. Get the current setting to current block data array and Convert them into VarBuffer\r
-  //\r
+  CHAR16                       *QuestionName;\r
+  CHAR16                       *StringPtr;\r
 \r
-  //\r
-  // Skip ConfigHdr string\r
-  //\r
-  StringPtr = ConfigResp;\r
-  StringPtr = StrStr (ConfigResp, L"&OFFSET");\r
-  if (StringPtr == NULL) {\r
-    //\r
-    // No ConfigBlock value is required to be validated.\r
-    // EFI_SUCCESS directly return.\r
-    //\r
-    return EFI_SUCCESS;\r
-  }\r
-   \r
   //\r
   // Initialize the local variables.\r
   //\r
-  Index         = 0;\r
-  VarStoreName  = NULL;\r
-  Status        = EFI_SUCCESS;\r
-  BlockData     = NULL;\r
-  NewBlockData  = NULL;\r
-  TmpBuffer     = NULL;\r
-  MaxBufferSize = HII_LIB_DEFAULT_VARSTORE_SIZE;\r
-  VarBuffer     = AllocateZeroPool (MaxBufferSize);\r
-  if (VarBuffer == NULL) {\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
-\r
-  //\r
-  // Init CurrentBlockArray\r
-  //\r
-  CurrentBlockArray = (IFR_BLOCK_DATA *) AllocateZeroPool (sizeof (IFR_BLOCK_DATA));\r
-  if (CurrentBlockArray == NULL) {\r
-    Status = EFI_OUT_OF_RESOURCES;\r
-    goto Done;\r
-  }\r
-  InitializeListHead (&CurrentBlockArray->Entry);\r
-  \r
-  //\r
-  // Parse each <RequestElement> if exists\r
-  // Only <BlockName> format is supported by this help function.\r
-  // <BlockName> ::= &'OFFSET='<Number>&'WIDTH='<Number>\r
-  //\r
-  while (*StringPtr != 0 && StrnCmp (StringPtr, L"&OFFSET=", StrLen (L"&OFFSET=")) == 0) {\r
-    //\r
-    // Skip the &OFFSET= string\r
-    // \r
-    StringPtr += StrLen (L"&OFFSET=");\r
-\r
-    //\r
-    // Get Offset\r
-    //\r
-    Status = InternalHiiGetValueOfNumber (StringPtr, &TmpBuffer, &Length);\r
-    if (EFI_ERROR (Status)) {\r
-      goto Done;\r
-    }\r
-    Offset = 0;\r
-    CopyMem (\r
-      &Offset,\r
-      TmpBuffer,\r
-      (((Length + 1) / 2) < sizeof (UINT16)) ? ((Length + 1) / 2) : sizeof (UINT16)\r
-      );\r
-    FreePool (TmpBuffer);\r
-    TmpBuffer = NULL;\r
-\r
-    StringPtr += Length;\r
-    if (StrnCmp (StringPtr, L"&WIDTH=", StrLen (L"&WIDTH=")) != 0) {\r
-      Status = EFI_INVALID_PARAMETER;\r
-      goto Done;\r
-    }\r
-    StringPtr += StrLen (L"&WIDTH=");\r
-\r
-    //\r
-    // Get Width\r
-    //\r
-    Status = InternalHiiGetValueOfNumber (StringPtr, &TmpBuffer, &Length);\r
-    if (EFI_ERROR (Status)) {\r
-      goto Done;\r
-    }\r
-    Width = 0;\r
-    CopyMem (\r
-      &Width,\r
-      TmpBuffer,\r
-      (((Length + 1) / 2) < sizeof (UINT16)) ? ((Length + 1) / 2) : sizeof (UINT16)\r
-      );\r
-    FreePool (TmpBuffer);\r
-    TmpBuffer = NULL;\r
-\r
-    StringPtr += Length;\r
-    if (*StringPtr != 0 && *StringPtr != L'&') {\r
-      Status = EFI_INVALID_PARAMETER;\r
-      goto Done;\r
-    }\r
-\r
-    if (StrnCmp (StringPtr, L"&VALUE=", StrLen (L"&VALUE=")) != 0) {\r
-      Status = EFI_INVALID_PARAMETER;\r
-      goto Done;\r
-    }\r
-    StringPtr += StrLen (L"&VALUE=");\r
-\r
-    //\r
-    // Get Value\r
-    //\r
-    Status = InternalHiiGetValueOfNumber (StringPtr, &TmpBuffer, &Length);\r
-    if (EFI_ERROR (Status)) {\r
-      goto Done;\r
-    }\r
-\r
-    StringPtr += Length;\r
-    if (*StringPtr != 0 && *StringPtr != L'&') {\r
-      Status = EFI_INVALID_PARAMETER;\r
-      goto Done;\r
-    }\r
-\r
-    //\r
-    // Check whether VarBuffer is enough\r
-    //\r
-    if ((UINTN) (Offset + Width) > MaxBufferSize) {\r
-      VarBuffer = ReallocatePool (\r
-                    MaxBufferSize,\r
-                    Offset + Width + HII_LIB_DEFAULT_VARSTORE_SIZE,\r
-                    VarBuffer\r
-                    );\r
-      if (VarBuffer == NULL) {\r
-        Status = EFI_OUT_OF_RESOURCES;\r
-        goto Done;\r
-      }\r
-      MaxBufferSize = Offset + Width + HII_LIB_DEFAULT_VARSTORE_SIZE;\r
-    }\r
-\r
-    //\r
-    // Update the Block with configuration info\r
-    //\r
-    CopyMem (VarBuffer + Offset, TmpBuffer, Width);\r
-    FreePool (TmpBuffer);\r
-    TmpBuffer = NULL;\r
-\r
-    //\r
-    // Set new Block Data\r
-    //\r
-    NewBlockData = (IFR_BLOCK_DATA *) AllocateZeroPool (sizeof (IFR_BLOCK_DATA));\r
-    if (NewBlockData == NULL) {\r
-      Status = EFI_OUT_OF_RESOURCES;\r
-      goto Done;\r
-    }\r
-    NewBlockData->Offset = Offset;\r
-    NewBlockData->Width  = Width;\r
-\r
-    //\r
-    // Insert the new block data into the block data array.\r
-    //\r
-    for (Link = CurrentBlockArray->Entry.ForwardLink; Link != &CurrentBlockArray->Entry; Link = Link->ForwardLink) {\r
-      BlockData = BASE_CR (Link, IFR_BLOCK_DATA, Entry);\r
-      if (NewBlockData->Offset == BlockData->Offset) {\r
-        if (NewBlockData->Width > BlockData->Width) {\r
-          BlockData->Width = NewBlockData->Width;\r
-        }\r
-        FreePool (NewBlockData);\r
-        break;\r
-      } else if (NewBlockData->Offset < BlockData->Offset) {\r
-        //\r
-        // Insert new block data as the previous one of this link.\r
-        //\r
-        InsertTailList (Link, &NewBlockData->Entry);\r
-        break;\r
-      }\r
-    }\r
-\r
-    //\r
-    // Insert new block data into the array tail.\r
-    //\r
-    if (Link == &CurrentBlockArray->Entry) {\r
-      InsertTailList (Link, &NewBlockData->Entry);\r
-    }\r
-\r
-    //\r
-    // If '\0', parsing is finished. \r
-    //\r
-    if (*StringPtr == 0) {\r
-      break;\r
-    }\r
-    //\r
-    // Go to next ConfigBlock \r
-    //\r
-  }\r
-\r
-  //\r
-  // Merge the aligned block data into the single block data.\r
-  //\r
-  Link = CurrentBlockArray->Entry.ForwardLink;\r
-  while ((Link != &CurrentBlockArray->Entry) && (Link->ForwardLink != &CurrentBlockArray->Entry)) {\r
-    BlockData = BASE_CR (Link, IFR_BLOCK_DATA, Entry);\r
-    NewBlockData = BASE_CR (Link->ForwardLink, IFR_BLOCK_DATA, Entry);\r
-    if ((NewBlockData->Offset >= BlockData->Offset) && (NewBlockData->Offset <= (BlockData->Offset + BlockData->Width))) {\r
-      if ((NewBlockData->Offset + NewBlockData->Width) > (BlockData->Offset + BlockData->Width)) {\r
-        BlockData->Width = (UINT16) (NewBlockData->Offset + NewBlockData->Width - BlockData->Offset);\r
-      }\r
-      RemoveEntryList (Link->ForwardLink);\r
-      FreePool (NewBlockData);\r
-      continue;\r
-    }\r
-    Link = Link->ForwardLink;      \r
-  }\r
-  \r
-  if (IsListEmpty (&CurrentBlockArray->Entry)) {\r
-    Status = EFI_SUCCESS;\r
-    goto Done;\r
-  }\r
+  Index             = 0;\r
+  VarStoreName      = NULL;\r
+  Status            = EFI_SUCCESS;\r
+  TmpBuffer         = NULL;\r
+  VarValue          = 0;\r
+  IfrVarStore       = NULL;\r
+  IfrNameValueStore = NULL;\r
+  IfrEfiVarStore    = NULL;\r
+  ZeroMem (&VarStoreData, sizeof (IFR_VARSTORAGE_DATA));\r
+  ZeroMem (&VarBlockData, sizeof (VarBlockData));\r
 \r
   //\r
-  // 2. Check IFR value is in block data, then Validate Value\r
+  // Check IFR value is in block data, then Validate Value\r
   //\r
-  ZeroMem (&VarBlockData, sizeof (VarBlockData));\r
-  VarValue      = 0;\r
-  IfrVarStore   = NULL;\r
   PackageOffset = sizeof (EFI_HII_PACKAGE_LIST_HEADER);\r
   while (PackageOffset < PackageListLength) {\r
     CopyMem (&PacakgeHeader, (UINT8 *) HiiPackageList + PackageOffset, sizeof (PacakgeHeader));\r
-    \r
+\r
     //\r
     // Parse IFR opcode from the form package.\r
     //\r
@@ -1200,11 +1059,11 @@ InternalHiiValidateCurrentSetting (
         // Validate current setting to the value built in IFR opcode\r
         //\r
         switch (IfrOpHdr->OpCode) {\r
-        case EFI_IFR_VARSTORE_OP:          \r
+        case EFI_IFR_VARSTORE_OP:\r
           //\r
           // VarStoreId has been found. No further found.\r
           //\r
-          if (IfrVarStore != NULL) {\r
+          if (VarStoreData.VarStoreId != 0) {\r
             break;\r
           }\r
           //\r
@@ -1227,72 +1086,152 @@ InternalHiiValidateCurrentSetting (
           } else {\r
             IfrVarStore = NULL;\r
           }\r
+\r
+          if (IfrVarStore != NULL) {\r
+            VarStoreData.VarStoreId = IfrVarStore->VarStoreId;\r
+            VarStoreData.Size       = IfrVarStore->Size;\r
+          }\r
           break;\r
-        case EFI_IFR_FORM_OP:\r
-        case EFI_IFR_FORM_MAP_OP:\r
+        case EFI_IFR_VARSTORE_NAME_VALUE_OP:\r
           //\r
-          // Check the matched VarStoreId is found.\r
+          // VarStoreId has been found. No further found.\r
           //\r
-          if (IfrVarStore == NULL) {\r
-            Status = EFI_SUCCESS;\r
-            goto Done;\r
+          if (VarStoreData.VarStoreId != 0) {\r
+            break;\r
           }\r
-          break;\r
-        case EFI_IFR_ONE_OF_OP:\r
           //\r
-          // Check whether current value is the one of option.\r
+          // Find the matched VarStoreId to the input VarGuid\r
           //\r
+          IfrNameValueStore = (EFI_IFR_VARSTORE_NAME_VALUE *) IfrOpHdr;\r
+          if (!CompareGuid ((EFI_GUID *) (VOID *) &IfrNameValueStore->Guid, VarGuid)) {\r
+            IfrNameValueStore = NULL;\r
+          }\r
 \r
-          //\r
-          // OneOf question is not in IFR Form. This IFR form is not valid. \r
-          //\r
-          if (IfrVarStore == NULL) {\r
-            Status = EFI_INVALID_PARAMETER;\r
-            goto Done;\r
+          if (IfrNameValueStore != NULL) {\r
+            VarStoreData.VarStoreId = IfrNameValueStore->VarStoreId;\r
           }\r
-          // \r
-          // Check whether this question is for the requested varstore.\r
+          break;\r
+        case EFI_IFR_VARSTORE_EFI_OP:\r
           //\r
-          IfrOneOf = (EFI_IFR_ONE_OF *) IfrOpHdr;\r
-          if (IfrOneOf->Question.VarStoreId != IfrVarStore->VarStoreId) {\r
+          // VarStore is found. Don't need to search any more.\r
+          //\r
+          if (VarStoreData.VarStoreId != 0) {\r
             break;\r
           }\r
-          \r
-          //\r
-          // Get Offset by Question header and Width by DataType Flags\r
-          //\r
-          Offset = IfrOneOf->Question.VarStoreInfo.VarOffset;\r
-          Width  = (UINT16) (1 << (IfrOneOf->Flags & EFI_IFR_NUMERIC_SIZE));\r
+\r
+          IfrEfiVarStore = (EFI_IFR_VARSTORE_EFI *) IfrOpHdr;\r
+\r
           //\r
-          // Check whether this question is in current block array.\r
+          // If the length is small than the structure, this is from old efi \r
+          // varstore definition. Old efi varstore get config directly from \r
+          // GetVariable function.\r
           //\r
-          if (!BlockArrayCheck (CurrentBlockArray, Offset, Width)) {\r
+          if (IfrOpHdr->Length < sizeof (EFI_IFR_VARSTORE_EFI)) {\r
+            break;\r
+          }\r
+\r
+          if (CompareGuid ((EFI_GUID *) (VOID *) &IfrEfiVarStore->Guid, VarGuid)) {\r
+            VarStoreName = (CHAR8 *) IfrEfiVarStore->Name;\r
+            for (Index = 0; VarStoreName[Index] != 0; Index ++) {\r
+              if ((CHAR16) VarStoreName[Index] != VarName[Index]) {\r
+                break;\r
+              }\r
+            }\r
             //\r
-            // This question is not in the current configuration string. Skip it.\r
+            // The matched VarStore is found.\r
             //\r
-            break;\r
+            if ((VarStoreName[Index] != 0) || (VarName[Index] != 0)) {\r
+              IfrEfiVarStore = NULL;\r
+            }\r
+          } else {\r
+            IfrEfiVarStore = NULL;\r
           }\r
-          //\r
-          // Check this var question is in the var storage \r
-          //\r
-          if ((Offset + Width) > IfrVarStore->Size) {\r
+\r
+          if (IfrEfiVarStore != NULL) {\r
             //\r
-            // This question exceeds the var store size. \r
+            // Find the matched VarStore\r
             //\r
-            Status = EFI_INVALID_PARAMETER;\r
-            goto Done;\r
+            VarStoreData.VarStoreId = IfrEfiVarStore->VarStoreId;\r
+            VarStoreData.Size       = IfrEfiVarStore->Size;\r
+          }\r
+          break;\r
+        case EFI_IFR_FORM_OP:\r
+        case EFI_IFR_FORM_MAP_OP:\r
+          //\r
+          // Check the matched VarStoreId is found.\r
+          //\r
+          if (VarStoreData.VarStoreId == 0) {\r
+            return EFI_SUCCESS;\r
           }\r
+          break;\r
+        case EFI_IFR_ONE_OF_OP:\r
+          //\r
+          // Check whether current value is the one of option.\r
+          //\r
 \r
           //\r
-          // Get the current value for oneof opcode\r
+          // OneOf question is not in IFR Form. This IFR form is not valid. \r
           //\r
-          VarValue = 0;\r
-          CopyMem (&VarValue, VarBuffer +  Offset, Width);\r
+          if (VarStoreData.VarStoreId == 0) {\r
+            return EFI_INVALID_PARAMETER;\r
+          }\r
+          // \r
+          // Check whether this question is for the requested varstore.\r
+          //\r
+          IfrOneOf = (EFI_IFR_ONE_OF *) IfrOpHdr;\r
+          if (IfrOneOf->Question.VarStoreId != VarStoreData.VarStoreId) {\r
+            break;\r
+          }\r
+\r
+          if (NameValueType) {\r
+            QuestionName = HiiGetString (HiiHandle, IfrOneOf->Question.VarStoreInfo.VarName, NULL);\r
+            ASSERT (QuestionName != NULL);\r
+\r
+            if (StrStr (RequestElement, QuestionName) == NULL) {\r
+              //\r
+              // This question is not in the current configuration string. Skip it.\r
+              //\r
+              break;\r
+            }\r
+\r
+            Status = GetValueFromRequest (RequestElement, QuestionName, &VarValue);\r
+            if (EFI_ERROR (Status)) {\r
+              return Status;\r
+            }\r
+          } else {\r
+            //\r
+            // Get Offset by Question header and Width by DataType Flags\r
+            //\r
+            Offset = IfrOneOf->Question.VarStoreInfo.VarOffset;\r
+            Width  = (UINT16) (1 << (IfrOneOf->Flags & EFI_IFR_NUMERIC_SIZE));\r
+            //\r
+            // Check whether this question is in current block array.\r
+            //\r
+            if (!BlockArrayCheck (CurrentBlockArray, Offset, Width)) {\r
+              //\r
+              // This question is not in the current configuration string. Skip it.\r
+              //\r
+              break;\r
+            }\r
+            //\r
+            // Check this var question is in the var storage \r
+            //\r
+            if ((Offset + Width) > VarStoreData.Size) {\r
+              //\r
+              // This question exceeds the var store size. \r
+              //\r
+              return EFI_INVALID_PARAMETER;\r
+            }\r
+\r
+            //\r
+            // Get the current value for oneof opcode\r
+            //\r
+            VarValue = 0;\r
+            CopyMem (&VarValue, VarBuffer +  Offset, Width);\r
+          }\r
           //\r
           // Set Block Data, to be checked in the following Oneof option opcode.\r
           //\r
-          VarBlockData.Offset     = Offset;\r
-          VarBlockData.Width      = Width;\r
           VarBlockData.OpCode     = IfrOpHdr->OpCode;\r
           VarBlockData.Scope      = IfrOpHdr->Scope;\r
           break;\r
@@ -1304,56 +1243,70 @@ InternalHiiValidateCurrentSetting (
           //\r
           // Numeric question is not in IFR Form. This IFR form is not valid. \r
           //\r
-          if (IfrVarStore == NULL) {\r
-            Status = EFI_INVALID_PARAMETER;\r
-            goto Done;\r
+          if (VarStoreData.VarStoreId == 0) {\r
+            return EFI_INVALID_PARAMETER;\r
           }\r
           //\r
           // Check whether this question is for the requested varstore.\r
           //\r
           IfrNumeric = (EFI_IFR_NUMERIC *) IfrOpHdr;\r
-          if (IfrNumeric->Question.VarStoreId != IfrVarStore->VarStoreId) {\r
+          if (IfrNumeric->Question.VarStoreId != VarStoreData.VarStoreId) {\r
             break;\r
           }\r
-          \r
-          //\r
-          // Get Offset by Question header and Width by DataType Flags\r
-          //\r
-          Offset = IfrNumeric->Question.VarStoreInfo.VarOffset;\r
-          Width  = (UINT16) (1 << (IfrNumeric->Flags & EFI_IFR_NUMERIC_SIZE));\r
-          //\r
-          // Check whether this question is in current block array.\r
-          //\r
-          if (!BlockArrayCheck (CurrentBlockArray, Offset, Width)) {\r
+\r
+          if (NameValueType) {\r
+            QuestionName = HiiGetString (HiiHandle, IfrNumeric->Question.VarStoreInfo.VarName, NULL);\r
+            ASSERT (QuestionName != NULL);\r
+\r
+            if (StrStr (RequestElement, QuestionName) == NULL) {\r
+              //\r
+              // This question is not in the current configuration string. Skip it.\r
+              //\r
+              break;\r
+            }\r
+            \r
+            Status = GetValueFromRequest (RequestElement, QuestionName, &VarValue);\r
+            if (EFI_ERROR (Status)) {\r
+              return Status;\r
+            }\r
+          } else {\r
             //\r
-            // This question is not in the current configuration string. Skip it.\r
+            // Get Offset by Question header and Width by DataType Flags\r
             //\r
-            break;\r
-          }\r
-          //\r
-          // Check this var question is in the var storage \r
-          //\r
-          if ((Offset + Width) > IfrVarStore->Size) {\r
+            Offset = IfrNumeric->Question.VarStoreInfo.VarOffset;\r
+            Width  = (UINT16) (1 << (IfrNumeric->Flags & EFI_IFR_NUMERIC_SIZE));\r
             //\r
-            // This question exceeds the var store size. \r
+            // Check whether this question is in current block array.\r
             //\r
-            Status = EFI_INVALID_PARAMETER;\r
-            goto Done;\r
-          }\r
+            if (!BlockArrayCheck (CurrentBlockArray, Offset, Width)) {\r
+              //\r
+              // This question is not in the current configuration string. Skip it.\r
+              //\r
+              break;\r
+            }\r
+            //\r
+            // Check this var question is in the var storage \r
+            //\r
+            if ((Offset + Width) > VarStoreData.Size) {\r
+              //\r
+              // This question exceeds the var store size. \r
+              //\r
+              return EFI_INVALID_PARAMETER;\r
+            }\r
 \r
-          //\r
-          // Check the current value is in the numeric range.\r
-          //\r
-          VarValue = 0;\r
-          CopyMem (&VarValue, VarBuffer +  Offset, Width);\r
+            //\r
+            // Check the current value is in the numeric range.\r
+            //\r
+            VarValue = 0;\r
+            CopyMem (&VarValue, VarBuffer +  Offset, Width);\r
+          }\r
           switch (IfrNumeric->Flags & EFI_IFR_NUMERIC_SIZE) {\r
           case EFI_IFR_NUMERIC_SIZE_1:\r
             if ((UINT8) VarValue < IfrNumeric->data.u8.MinValue || (UINT8) VarValue > IfrNumeric->data.u8.MaxValue) {\r
               //\r
               // Not in the valid range.\r
               //\r
-              Status = EFI_INVALID_PARAMETER;\r
-              goto Done;\r
+              return EFI_INVALID_PARAMETER;\r
             }\r
             break;\r
           case EFI_IFR_NUMERIC_SIZE_2:\r
@@ -1361,8 +1314,7 @@ InternalHiiValidateCurrentSetting (
               //\r
               // Not in the valid range.\r
               //\r
-              Status = EFI_INVALID_PARAMETER;\r
-              goto Done;\r
+              return EFI_INVALID_PARAMETER;\r
             }\r
             break;\r
           case EFI_IFR_NUMERIC_SIZE_4:\r
@@ -1370,8 +1322,7 @@ InternalHiiValidateCurrentSetting (
               //\r
               // Not in the valid range.\r
               //\r
-              Status = EFI_INVALID_PARAMETER;\r
-              goto Done;\r
+              return EFI_INVALID_PARAMETER;\r
             }\r
             break;\r
           case EFI_IFR_NUMERIC_SIZE_8:\r
@@ -1379,8 +1330,7 @@ InternalHiiValidateCurrentSetting (
               //\r
               // Not in the valid range.\r
               //\r
-              Status = EFI_INVALID_PARAMETER;\r
-              goto Done;\r
+              return EFI_INVALID_PARAMETER;\r
             }\r
             break;\r
           }\r
@@ -1394,52 +1344,69 @@ InternalHiiValidateCurrentSetting (
           //\r
           // CheckBox question is not in IFR Form. This IFR form is not valid. \r
           //\r
-          if (IfrVarStore == NULL) {\r
-            Status = EFI_INVALID_PARAMETER;\r
-            goto Done;\r
+          if (VarStoreData.VarStoreId == 0) {\r
+            return EFI_INVALID_PARAMETER;\r
           }\r
 \r
           //\r
           // Check whether this question is for the requested varstore.\r
           //\r
           IfrCheckBox = (EFI_IFR_CHECKBOX *) IfrOpHdr;\r
-          if (IfrCheckBox->Question.VarStoreId != IfrVarStore->VarStoreId) {\r
+          if (IfrCheckBox->Question.VarStoreId != VarStoreData.VarStoreId) {\r
             break;\r
           }\r
-          \r
-          //\r
-          // Get Offset by Question header\r
-          //\r
-          Offset = IfrCheckBox->Question.VarStoreInfo.VarOffset;\r
-          Width  = (UINT16) sizeof (BOOLEAN);\r
-          //\r
-          // Check whether this question is in current block array.\r
-          //\r
-          if (!BlockArrayCheck (CurrentBlockArray, Offset, Width)) {\r
+\r
+          if (NameValueType) {\r
+            QuestionName = HiiGetString (HiiHandle, IfrCheckBox->Question.VarStoreInfo.VarName, NULL);\r
+            ASSERT (QuestionName != NULL);\r
+\r
+            if (StrStr (RequestElement, QuestionName) == NULL) {\r
+              //\r
+              // This question is not in the current configuration string. Skip it.\r
+              //\r
+              break;\r
+            }\r
+            \r
+            Status = GetValueFromRequest (RequestElement, QuestionName, &VarValue);\r
+            if (EFI_ERROR (Status)) {\r
+              return Status;\r
+            }\r
+          } else {\r
             //\r
-            // This question is not in the current configuration string. Skip it.\r
+            // Get Offset by Question header\r
             //\r
-            break;\r
-          }\r
-          //\r
-          // Check this var question is in the var storage \r
-          //\r
-          if ((Offset + Width) > IfrVarStore->Size) {\r
+            Offset = IfrCheckBox->Question.VarStoreInfo.VarOffset;\r
+            Width  = (UINT16) sizeof (BOOLEAN);\r
+            //\r
+            // Check whether this question is in current block array.\r
+            //\r
+            if (!BlockArrayCheck (CurrentBlockArray, Offset, Width)) {\r
+              //\r
+              // This question is not in the current configuration string. Skip it.\r
+              //\r
+              break;\r
+            }\r
             //\r
-            // This question exceeds the var store size. \r
+            // Check this var question is in the var storage \r
             //\r
-            Status = EFI_INVALID_PARAMETER;\r
-            goto Done;\r
+            if ((Offset + Width) > VarStoreData.Size) {\r
+              //\r
+              // This question exceeds the var store size. \r
+              //\r
+              return EFI_INVALID_PARAMETER;\r
+            }\r
+            //\r
+            // Check the current value is in the numeric range.\r
+            //\r
+            VarValue = 0;\r
+            CopyMem (&VarValue, VarBuffer +  Offset, Width);\r
           }\r
-\r
           //\r
           // Boolean type, only 1 and 0 is valid.\r
           //\r
-          if (*(VarBuffer + Offset) > 1) {\r
-            Status = EFI_INVALID_PARAMETER;\r
-            goto Done;            \r
+          if (VarValue > 1) {\r
+            return EFI_INVALID_PARAMETER;\r
           }\r
-          \r
           break;\r
         case EFI_IFR_STRING_OP:\r
           //\r
@@ -1449,50 +1416,74 @@ InternalHiiValidateCurrentSetting (
           //\r
           // CheckBox question is not in IFR Form. This IFR form is not valid. \r
           //\r
-          if (IfrVarStore == NULL) {\r
-            Status = EFI_INVALID_PARAMETER;\r
-            goto Done;\r
+          if (VarStoreData.VarStoreId == 0) {\r
+            return EFI_INVALID_PARAMETER;\r
           }\r
 \r
           //\r
           // Check whether this question is for the requested varstore.\r
           //\r
           IfrString = (EFI_IFR_STRING *) IfrOpHdr;\r
-          if (IfrString->Question.VarStoreId != IfrVarStore->VarStoreId) {\r
+          if (IfrString->Question.VarStoreId != VarStoreData.VarStoreId) {\r
             break;\r
           }\r
-          \r
           //\r
-          // Get Offset/Width by Question header and OneOf Flags\r
+          // Get Width by OneOf Flags\r
           //\r
-          Offset = IfrString->Question.VarStoreInfo.VarOffset;\r
           Width  = (UINT16) (IfrString->MaxSize * sizeof (UINT16));\r
-          //\r
-          // Check whether this question is in current block array.\r
-          //\r
-          if (!BlockArrayCheck (CurrentBlockArray, Offset, Width)) {\r
+          if (NameValueType) {\r
+            QuestionName = HiiGetString (HiiHandle, IfrString->Question.VarStoreInfo.VarName, NULL);\r
+            ASSERT (QuestionName != NULL);\r
+\r
+            StringPtr = StrStr (RequestElement, QuestionName);\r
+            if (StringPtr == NULL) {\r
+              //\r
+              // This question is not in the current configuration string. Skip it.\r
+              //\r
+              break;\r
+            }\r
+\r
             //\r
-            // This question is not in the current configuration string. Skip it.\r
+            // Skip the "=".\r
+            // \r
+            StringPtr += 1;\r
+            \r
             //\r
-            break;\r
-          }\r
-          //\r
-          // Check this var question is in the var storage \r
-          //\r
-          if ((Offset + Width) > IfrVarStore->Size) {\r
+            // Check current string length is less than maxsize\r
             //\r
-            // This question exceeds the var store size. \r
+            if (StrSize (StringPtr) > Width) {\r
+              return EFI_INVALID_PARAMETER;\r
+            }\r
+          } else {\r
             //\r
-            Status = EFI_INVALID_PARAMETER;\r
-            goto Done;\r
-          }\r
-          \r
-          //\r
-          // Check current string length is less than maxsize\r
-          //\r
-          if (StrSize ((CHAR16 *) (VarBuffer + Offset)) > Width) {\r
-            Status = EFI_INVALID_PARAMETER;\r
-            goto Done;            \r
+            // Get Offset/Width by Question header and OneOf Flags\r
+            //\r
+            Offset = IfrString->Question.VarStoreInfo.VarOffset;\r
+            //\r
+            // Check whether this question is in current block array.\r
+            //\r
+            if (!BlockArrayCheck (CurrentBlockArray, Offset, Width)) {\r
+              //\r
+              // This question is not in the current configuration string. Skip it.\r
+              //\r
+              break;\r
+            }\r
+            //\r
+            // Check this var question is in the var storage \r
+            //\r
+            if ((Offset + Width) > VarStoreData.Size) {\r
+              //\r
+              // This question exceeds the var store size. \r
+              //\r
+              return EFI_INVALID_PARAMETER;\r
+            }\r
+\r
+            //\r
+            // Check current string length is less than maxsize\r
+            //\r
+            if (StrSize ((CHAR16 *) (VarBuffer + Offset)) > Width) {\r
+              return EFI_INVALID_PARAMETER;\r
+            }\r
           }\r
           break;\r
         case EFI_IFR_ONE_OF_OPTION_OP:\r
@@ -1522,7 +1513,6 @@ InternalHiiValidateCurrentSetting (
               VarBlockData.OpCode = 0;\r
             }\r
           }\r
-\r
           break;\r
         case EFI_IFR_END_OP:\r
           //\r
@@ -1536,8 +1526,7 @@ InternalHiiValidateCurrentSetting (
           // OneOf value doesn't belong to one of option value. \r
           //\r
           if ((VarBlockData.Scope == 0) && (VarBlockData.OpCode == EFI_IFR_ONE_OF_OP)) {\r
-            Status = EFI_INVALID_PARAMETER;\r
-            goto Done;\r
+            return EFI_INVALID_PARAMETER;\r
           }\r
           break;\r
         default:\r
@@ -1559,14 +1548,343 @@ InternalHiiValidateCurrentSetting (
       //\r
       break;\r
     }\r
-    \r
+\r
     //\r
     // Go to next package.\r
     //\r
-    PackageOffset += PacakgeHeader.Length;      \r
+    PackageOffset += PacakgeHeader.Length;\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  This internal function parses IFR data to validate current setting.\r
+\r
+  @param ConfigElement         ConfigResp element string contains the current setting.\r
+  @param CurrentBlockArray     Current block array.\r
+  @param VarBuffer             Data buffer for this varstore.\r
+  \r
+  @retval EFI_SUCCESS            The current setting is valid.\r
+  @retval EFI_OUT_OF_RESOURCES   The memory is not enough.\r
+  @retval EFI_INVALID_PARAMETER  The config string or the Hii package is invalid.\r
+**/\r
+EFI_STATUS\r
+GetBlockDataInfo (\r
+  IN  CHAR16                        *ConfigElement,\r
+  OUT IFR_BLOCK_DATA                **CurrentBlockArray,\r
+  OUT UINT8                         **VarBuffer\r
+  )\r
+{\r
+  IFR_BLOCK_DATA               *BlockData;\r
+  IFR_BLOCK_DATA               *NewBlockData;\r
+  EFI_STRING                   StringPtr;\r
+  UINTN                        Length;\r
+  UINT8                        *TmpBuffer;\r
+  UINT16                       Offset;\r
+  UINT16                       Width;\r
+  LIST_ENTRY                   *Link;\r
+  UINTN                        MaxBufferSize;\r
+  EFI_STATUS                   Status;\r
+  CHAR8                        *VarStoreName;\r
+  UINTN                        Index;\r
+  IFR_BLOCK_DATA               *BlockArray;\r
+  UINT8                        *DataBuffer;\r
+  \r
+  //\r
+  // Initialize the local variables.\r
+  //\r
+  Index         = 0;\r
+  VarStoreName  = NULL;\r
+  Status        = EFI_SUCCESS;\r
+  BlockData     = NULL;\r
+  NewBlockData  = NULL;\r
+  TmpBuffer     = NULL;\r
+  BlockArray    = NULL;\r
+  MaxBufferSize = HII_LIB_DEFAULT_VARSTORE_SIZE;\r
+  DataBuffer     = AllocateZeroPool (MaxBufferSize);\r
+  if (DataBuffer == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
   }\r
 \r
+  //\r
+  // Init BlockArray\r
+  //\r
+  BlockArray = (IFR_BLOCK_DATA *) AllocateZeroPool (sizeof (IFR_BLOCK_DATA));\r
+  if (BlockArray == NULL) {\r
+    Status = EFI_OUT_OF_RESOURCES;\r
+    goto Done;\r
+  }\r
+  InitializeListHead (&BlockArray->Entry);\r
+\r
+  StringPtr = StrStr (ConfigElement, L"&OFFSET=");\r
+  ASSERT (StringPtr != NULL);\r
+\r
+  //\r
+  // Parse each <RequestElement> if exists\r
+  // Only <BlockName> format is supported by this help function.\r
+  // <BlockName> ::= &'OFFSET='<Number>&'WIDTH='<Number>\r
+  //\r
+  while (*StringPtr != 0 && StrnCmp (StringPtr, L"&OFFSET=", StrLen (L"&OFFSET=")) == 0) {\r
+    //\r
+    // Skip the &OFFSET= string\r
+    // \r
+    StringPtr += StrLen (L"&OFFSET=");\r
+\r
+    //\r
+    // Get Offset\r
+    //\r
+    Status = InternalHiiGetValueOfNumber (StringPtr, &TmpBuffer, &Length);\r
+    if (EFI_ERROR (Status)) {\r
+      goto Done;\r
+    }\r
+    Offset = 0;\r
+    CopyMem (\r
+      &Offset,\r
+      TmpBuffer,\r
+      (((Length + 1) / 2) < sizeof (UINT16)) ? ((Length + 1) / 2) : sizeof (UINT16)\r
+      );\r
+    FreePool (TmpBuffer);\r
+    TmpBuffer = NULL;\r
+\r
+    StringPtr += Length;\r
+    if (StrnCmp (StringPtr, L"&WIDTH=", StrLen (L"&WIDTH=")) != 0) {\r
+      Status = EFI_INVALID_PARAMETER;\r
+      goto Done;\r
+    }\r
+    StringPtr += StrLen (L"&WIDTH=");\r
+\r
+    //\r
+    // Get Width\r
+    //\r
+    Status = InternalHiiGetValueOfNumber (StringPtr, &TmpBuffer, &Length);\r
+    if (EFI_ERROR (Status)) {\r
+      goto Done;\r
+    }\r
+    Width = 0;\r
+    CopyMem (\r
+      &Width,\r
+      TmpBuffer,\r
+      (((Length + 1) / 2) < sizeof (UINT16)) ? ((Length + 1) / 2) : sizeof (UINT16)\r
+      );\r
+    FreePool (TmpBuffer);\r
+    TmpBuffer = NULL;\r
+\r
+    StringPtr += Length;\r
+    if (*StringPtr != 0 && *StringPtr != L'&') {\r
+      Status = EFI_INVALID_PARAMETER;\r
+      goto Done;\r
+    }\r
+\r
+    if (StrnCmp (StringPtr, L"&VALUE=", StrLen (L"&VALUE=")) != 0) {\r
+      Status = EFI_INVALID_PARAMETER;\r
+      goto Done;\r
+    }\r
+    StringPtr += StrLen (L"&VALUE=");\r
+\r
+    //\r
+    // Get Value\r
+    //\r
+    Status = InternalHiiGetValueOfNumber (StringPtr, &TmpBuffer, &Length);\r
+    if (EFI_ERROR (Status)) {\r
+      goto Done;\r
+    }\r
+\r
+    StringPtr += Length;\r
+    if (*StringPtr != 0 && *StringPtr != L'&') {\r
+      Status = EFI_INVALID_PARAMETER;\r
+      goto Done;\r
+    }\r
+\r
+    //\r
+    // Check whether VarBuffer is enough\r
+    //\r
+    if ((UINTN) (Offset + Width) > MaxBufferSize) {\r
+      DataBuffer = ReallocatePool (\r
+                    MaxBufferSize,\r
+                    Offset + Width + HII_LIB_DEFAULT_VARSTORE_SIZE,\r
+                    DataBuffer\r
+                    );\r
+      if (DataBuffer == NULL) {\r
+        Status = EFI_OUT_OF_RESOURCES;\r
+        goto Done;\r
+      }\r
+      MaxBufferSize = Offset + Width + HII_LIB_DEFAULT_VARSTORE_SIZE;\r
+    }\r
+\r
+    //\r
+    // Update the Block with configuration info\r
+    //\r
+    CopyMem (DataBuffer + Offset, TmpBuffer, Width);\r
+    FreePool (TmpBuffer);\r
+    TmpBuffer = NULL;\r
+\r
+    //\r
+    // Set new Block Data\r
+    //\r
+    NewBlockData = (IFR_BLOCK_DATA *) AllocateZeroPool (sizeof (IFR_BLOCK_DATA));\r
+    if (NewBlockData == NULL) {\r
+      Status = EFI_OUT_OF_RESOURCES;\r
+      goto Done;\r
+    }\r
+    NewBlockData->Offset = Offset;\r
+    NewBlockData->Width  = Width;\r
+\r
+    //\r
+    // Insert the new block data into the block data array.\r
+    //\r
+    for (Link = BlockArray->Entry.ForwardLink; Link != &BlockArray->Entry; Link = Link->ForwardLink) {\r
+      BlockData = BASE_CR (Link, IFR_BLOCK_DATA, Entry);\r
+      if (NewBlockData->Offset == BlockData->Offset) {\r
+        if (NewBlockData->Width > BlockData->Width) {\r
+          BlockData->Width = NewBlockData->Width;\r
+        }\r
+        FreePool (NewBlockData);\r
+        break;\r
+      } else if (NewBlockData->Offset < BlockData->Offset) {\r
+        //\r
+        // Insert new block data as the previous one of this link.\r
+        //\r
+        InsertTailList (Link, &NewBlockData->Entry);\r
+        break;\r
+      }\r
+    }\r
+\r
+    //\r
+    // Insert new block data into the array tail.\r
+    //\r
+    if (Link == &BlockArray->Entry) {\r
+      InsertTailList (Link, &NewBlockData->Entry);\r
+    }\r
+\r
+    //\r
+    // If '\0', parsing is finished. \r
+    //\r
+    if (*StringPtr == 0) {\r
+      break;\r
+    }\r
+    //\r
+    // Go to next ConfigBlock \r
+    //\r
+  }\r
+\r
+  //\r
+  // Merge the aligned block data into the single block data.\r
+  //\r
+  Link = BlockArray->Entry.ForwardLink;\r
+  while ((Link != &BlockArray->Entry) && (Link->ForwardLink != &BlockArray->Entry)) {\r
+    BlockData = BASE_CR (Link, IFR_BLOCK_DATA, Entry);\r
+    NewBlockData = BASE_CR (Link->ForwardLink, IFR_BLOCK_DATA, Entry);\r
+    if ((NewBlockData->Offset >= BlockData->Offset) && (NewBlockData->Offset <= (BlockData->Offset + BlockData->Width))) {\r
+      if ((NewBlockData->Offset + NewBlockData->Width) > (BlockData->Offset + BlockData->Width)) {\r
+        BlockData->Width = (UINT16) (NewBlockData->Offset + NewBlockData->Width - BlockData->Offset);\r
+      }\r
+      RemoveEntryList (Link->ForwardLink);\r
+      FreePool (NewBlockData);\r
+      continue;\r
+    }\r
+    Link = Link->ForwardLink;\r
+  }\r
+\r
+  *VarBuffer         = DataBuffer;\r
+  *CurrentBlockArray = BlockArray;\r
+  return EFI_SUCCESS;\r
+\r
 Done:\r
+  if (DataBuffer != NULL) {\r
+    FreePool (DataBuffer);\r
+  }\r
+  \r
+  if (BlockArray != NULL) {\r
+    //\r
+    // Free Link Array CurrentBlockArray\r
+    //\r
+    while (!IsListEmpty (&BlockArray->Entry)) {\r
+      BlockData = BASE_CR (BlockArray->Entry.ForwardLink, IFR_BLOCK_DATA, Entry);\r
+      RemoveEntryList (&BlockData->Entry);\r
+      FreePool (BlockData);\r
+    }\r
+    FreePool (BlockArray);\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  This internal function parses IFR data to validate current setting.\r
+\r
+  @param ConfigResp         ConfigResp string contains the current setting.\r
+  @param HiiPackageList     Point to Hii package list.\r
+  @param PackageListLength  The length of the pacakge.\r
+  @param VarGuid            Guid of the buffer storage.\r
+  @param VarName            Name of the buffer storage.\r
+  @param HiiHandle          The HiiHandle for this package.\r
+  \r
+  @retval EFI_SUCCESS            The current setting is valid.\r
+  @retval EFI_OUT_OF_RESOURCES   The memory is not enough.\r
+  @retval EFI_INVALID_PARAMETER  The config string or the Hii package is invalid.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+InternalHiiValidateCurrentSetting (\r
+  IN EFI_STRING                    ConfigResp,\r
+  IN EFI_HII_PACKAGE_LIST_HEADER   *HiiPackageList,\r
+  IN UINTN                         PackageListLength,\r
+  IN EFI_GUID                      *VarGuid,\r
+  IN CHAR16                        *VarName,\r
+  IN EFI_HII_HANDLE                HiiHandle\r
+  )\r
+{\r
+  CHAR16              *StringPtr;\r
+  EFI_STATUS          Status;\r
+  IFR_BLOCK_DATA      *CurrentBlockArray;\r
+  IFR_BLOCK_DATA      *BlockData;\r
+  UINT8               *VarBuffer;\r
+  BOOLEAN             NameValueType;\r
+\r
+  CurrentBlockArray = NULL;\r
+  VarBuffer         = NULL;\r
+  StringPtr         = NULL;\r
+  Status            = EFI_SUCCESS;\r
+\r
+  //\r
+  // If StringPtr != NULL, get the request elements.\r
+  //\r
+  if (StrStr (ConfigResp, L"&OFFSET=") != NULL) {\r
+    Status = GetBlockDataInfo(ConfigResp, &CurrentBlockArray, &VarBuffer);\r
+    if (EFI_ERROR (Status)) {\r
+      return Status;\r
+    }\r
+    NameValueType = FALSE;\r
+  } else {\r
+    //\r
+    // Skip header part.\r
+    //\r
+    StringPtr = StrStr (ConfigResp, L"PATH=");\r
+    ASSERT (StringPtr != NULL);\r
+\r
+    if (StrStr (StringPtr, L"&") != NULL) {\r
+      NameValueType = TRUE;\r
+    } else {\r
+      //\r
+      // Not found Request element, return success.\r
+      //\r
+      return EFI_SUCCESS;\r
+    }\r
+  }\r
+\r
+  Status = ValidateQuestionFromVfr(\r
+                          HiiPackageList,\r
+                          PackageListLength,\r
+                          VarGuid,\r
+                          VarName,\r
+                          VarBuffer,\r
+                          CurrentBlockArray,\r
+                          ConfigResp,\r
+                          HiiHandle,\r
+                          NameValueType\r
+                          );\r
+\r
   if (VarBuffer != NULL) {\r
     FreePool (VarBuffer);\r
   }\r
@@ -1580,12 +1898,40 @@ Done:
       RemoveEntryList (&BlockData->Entry);\r
       FreePool (BlockData);\r
     }\r
-    FreePool (CurrentBlockArray);    \r
+    FreePool (CurrentBlockArray);\r
   }\r
 \r
   return Status;\r
 }\r
 \r
+/**\r
+  Check whether the ConfigRequest string has the request elements.\r
+  For EFI_HII_VARSTORE_BUFFER type, the request has "&OFFSET=****&WIDTH=****..." format.\r
+  For EFI_HII_VARSTORE_NAME_VALUE type, the request has "&NAME1**&NAME2..." format.\r
+\r
+  @param  ConfigRequest      The input config request string.\r
+\r
+  @retval  TRUE              The input include config request elements.\r
+  @retval  FALSE             The input string not includes.\r
+                                 \r
+**/\r
+BOOLEAN\r
+GetElementsFromRequest (\r
+  IN EFI_STRING    ConfigRequest\r
+  )\r
+{\r
+  EFI_STRING   TmpRequest;\r
+\r
+  TmpRequest = StrStr (ConfigRequest, L"PATH=");\r
+  ASSERT (TmpRequest != NULL);\r
+\r
+  if ((StrStr (TmpRequest, L"&OFFSET=") != NULL) || (StrStr (TmpRequest, L"&") != NULL)) {\r
+    return TRUE;\r
+  }\r
+\r
+  return FALSE;\r
+}\r
+\r
 /**\r
   This function parses the input ConfigRequest string and its matched IFR code\r
   string for setting default value and validating current setting.\r
@@ -1765,7 +2111,7 @@ InternalHiiIfrValueAction (
       // Its default value and validating can't execute by parsing IFR data.\r
       // Directly jump into the next ConfigAltResp string for another pair Guid, Name, and Path.   \r
       //\r
-           Status = EFI_SUCCESS;\r
+      Status = EFI_SUCCESS;\r
       goto NextConfigAltResp;\r
     }\r
 \r
@@ -1822,7 +2168,7 @@ InternalHiiIfrValueAction (
     //\r
     // Only the ConfigHdr is found. Not any block data is found. No data is required to be validated and set.\r
     //\r
-    if (StrStr (ConfigResp, L"&OFFSET=") == NULL) {\r
+    if (!GetElementsFromRequest (ConfigResp)) {\r
       goto NextConfigAltResp;\r
     }\r
     \r
@@ -1839,7 +2185,7 @@ InternalHiiIfrValueAction (
       //\r
       // Current Setting is in ConfigResp, will be set into buffer, then check it again.\r
       //\r
-      Status = InternalHiiValidateCurrentSetting (ConfigResp, HiiPackageList, PackageListLength, VarGuid, VarName);\r
+      Status = InternalHiiValidateCurrentSetting (ConfigResp, HiiPackageList, PackageListLength, VarGuid, VarName, HiiHandle);\r
     }\r
 \r
     if (EFI_ERROR (Status)) {\r
@@ -1855,10 +2201,10 @@ NextConfigAltResp:
       HiiPackageList = NULL;\r
     }\r
     \r
-       if (ConfigResp != NULL) {\r
-         FreePool (ConfigResp);\r
-         ConfigResp = NULL;\r
-       }\r
+    if (ConfigResp != NULL) {\r
+      FreePool (ConfigResp);\r
+      ConfigResp = NULL;\r
+    }\r
 \r
     //\r
     // Free the allocated buffer.\r
index 3ae55de2b0dd36adbd6efddc384d25fad7c71e15..cb2cbe7932806e24f66c8df1e2ffb20d48d51f8f 100644 (file)
@@ -1794,6 +1794,7 @@ DriverSampleInit (
   DRIVER_SAMPLE_CONFIGURATION     *Configuration;\r
   BOOLEAN                         ActionFlag;\r
   EFI_STRING                      ConfigRequestHdr;\r
+  EFI_STRING                      NameRequestHdr;\r
   MY_EFI_VARSTORE_DATA            *VarStoreConfig;\r
   EFI_INPUT_KEY                   HotKey;\r
   EFI_FORM_BROWSER_EXTENSION_PROTOCOL *FormBrowserEx;\r
@@ -1973,6 +1974,9 @@ DriverSampleInit (
   ConfigRequestHdr = HiiConstructConfigHdr (&gDriverSampleFormSetGuid, VariableName, DriverHandle[0]);\r
   ASSERT (ConfigRequestHdr != NULL);\r
 \r
+  NameRequestHdr = HiiConstructConfigHdr (&gDriverSampleFormSetGuid, NULL, DriverHandle[0]);\r
+  ASSERT (NameRequestHdr != NULL);\r
+\r
   BufferSize = sizeof (DRIVER_SAMPLE_CONFIGURATION);\r
   Status = gRT->GetVariable (VariableName, &gDriverSampleFormSetGuid, NULL, &BufferSize, Configuration);\r
   if (EFI_ERROR (Status)) {\r
@@ -1991,12 +1995,18 @@ DriverSampleInit (
     // EFI variable for NV config doesn't exit, we should build this variable\r
     // based on default values stored in IFR\r
     //\r
+    ActionFlag = HiiSetToDefaults (NameRequestHdr, EFI_HII_DEFAULT_CLASS_STANDARD);\r
+    ASSERT (ActionFlag);\r
+\r
     ActionFlag = HiiSetToDefaults (ConfigRequestHdr, EFI_HII_DEFAULT_CLASS_STANDARD);\r
     ASSERT (ActionFlag);\r
   } else {\r
     //\r
     // EFI variable does exist and Validate Current Setting\r
     //\r
+    ActionFlag = HiiValidateSettings (NameRequestHdr);\r
+    ASSERT (ActionFlag);\r
+\r
     ActionFlag = HiiValidateSettings (ConfigRequestHdr);\r
     ASSERT (ActionFlag);\r
   }\r
index 60e9cf2a34a29c80361611016c79cb1bb85c7e83..0a77e408fa7be360e22d7da30db539fde03e969c 100644 (file)
@@ -359,6 +359,8 @@ formset
             maximum = 0xff,\r
             step    = 0,\r
             locked,\r
+            default = 16, defaultstore = MyStandardDefault,     // This is standard default value\r
+            default = 17, defaultstore = MyManufactureDefault,  // This is manufacture default value\r
     endnumeric;\r
 \r
     numeric varid   = MyNameValueVar[1],     // This numeric take NameValueVar1 as storage\r
@@ -368,6 +370,8 @@ formset
             minimum = 0,\r
             maximum = 0xffff,\r
             step    = 0,\r
+            default = 18, defaultstore = MyStandardDefault,     // This is standard default value\r
+            default = 19, defaultstore = MyManufactureDefault,  // This is manufacture default value\r
     endnumeric;\r
 \r
     //\r
index 81cebdabcd51ba9e67bb84fb414bbb87abe42244..dbc1948f92054b90bece2dcada81eed07cfe2c31 100644 (file)
@@ -242,7 +242,7 @@ GenerateSubStr (
   if (Buffer == NULL) {\r
     *SubStr = AllocateCopyPool (StrSize (String), String);\r
     ASSERT (*SubStr != NULL);\r
-    return ;\r
+    return;\r
   }\r
   \r
   //\r
@@ -628,7 +628,7 @@ MergeDefaultString (
     // Find next AltCfg String\r
     //\r
     *(AltConfigHdr + HeaderLength) = L'\0';\r
-    StringPtrDefault = StrStr (StringPtrDefault + 1, AltConfigHdr);    \r
+    StringPtrDefault = StrStr (StringPtrDefault + 1, AltConfigHdr);\r
   }\r
   \r
   FreePool (AltConfigHdr);\r
@@ -649,9 +649,12 @@ InsertDefaultValue (
   )\r
 {\r
   LIST_ENTRY             *Link;\r
-  IFR_DEFAULT_DATA       *DefaultValueArray;\r
+  IFR_DEFAULT_DATA       *DefaultValueArray; \r
+  LIST_ENTRY             *DefaultLink;\r
\r
+  DefaultLink   = &BlockData->DefaultValueEntry;\r
 \r
-  for (Link = BlockData->DefaultValueEntry.ForwardLink; Link != &BlockData->DefaultValueEntry; Link = Link->ForwardLink) {\r
+  for (Link = DefaultLink->ForwardLink; Link != DefaultLink; Link = Link->ForwardLink) {\r
     DefaultValueArray = BASE_CR (Link, IFR_DEFAULT_DATA, Entry);\r
     if (DefaultValueArray->DefaultId == DefaultValueData->DefaultId) {\r
       //\r
@@ -681,8 +684,8 @@ InsertDefaultValue (
 /**\r
   This function inserts new BlockData into the block link\r
 \r
-  @param  BlockLink   The list entry points to block array.\r
-  @param  BlockData   The point to BlockData is added.\r
+  @param  BlockLink      The list entry points to block array.\r
+  @param  BlockData      The point to BlockData is added.\r
   \r
 **/\r
 VOID\r
@@ -691,12 +694,17 @@ InsertBlockData (
   IN IFR_BLOCK_DATA    **BlockData\r
   )\r
 {\r
-  LIST_ENTRY      *Link;\r
-  IFR_BLOCK_DATA  *BlockArray;\r
-  IFR_BLOCK_DATA  *BlockSingleData;\r
+  LIST_ENTRY          *Link;\r
+  IFR_BLOCK_DATA      *BlockArray;\r
+  IFR_BLOCK_DATA      *BlockSingleData;\r
 \r
   BlockSingleData = *BlockData;\r
-  \r
+\r
+  if (BlockSingleData->Name != NULL) {\r
+    InsertTailList (BlockLink, &BlockSingleData->Entry);\r
+    return;\r
+  }\r
+\r
   //\r
   // Insert block data in its Offset and Width order.\r
   //\r
@@ -715,8 +723,10 @@ InsertBlockData (
         //\r
         // The same block array has been added.\r
         //\r
-        FreePool (BlockSingleData);\r
-        *BlockData = BlockArray;\r
+        if (BlockSingleData != BlockArray) {\r
+          FreePool (BlockSingleData);\r
+          *BlockData = BlockArray;\r
+        }\r
         return;\r
       }\r
     } else if (BlockArray->Offset > BlockSingleData->Offset) {\r
@@ -731,8 +741,225 @@ InsertBlockData (
   //\r
   // Add new block data into the tail.\r
   //\r
-  InsertTailList (Link, &BlockSingleData->Entry);\r
-  return;  \r
+  InsertTailList (Link, &BlockSingleData->Entry); \r
+}\r
+\r
+/**\r
+  Retrieves a pointer to the a Null-terminated ASCII string containing the list \r
+  of languages that an HII handle in the HII Database supports.  The returned \r
+  string is allocated using AllocatePool().  The caller is responsible for freeing\r
+  the returned string using FreePool().  The format of the returned string follows\r
+  the language format assumed the HII Database.\r
+  \r
+  If HiiHandle is NULL, then ASSERT().\r
+\r
+  @param[in]  HiiHandle  A handle that was previously registered in the HII Database.\r
+\r
+  @retval NULL   HiiHandle is not registered in the HII database\r
+  @retval NULL   There are not enough resources available to retrieve the suported \r
+                 languages.\r
+  @retval NULL   The list of suported languages could not be retrieved.\r
+  @retval Other  A pointer to the Null-terminated ASCII string of supported languages.\r
+\r
+**/\r
+CHAR8 *\r
+GetSupportedLanguages (\r
+  IN EFI_HII_HANDLE           HiiHandle\r
+  )\r
+{\r
+  EFI_STATUS  Status;\r
+  UINTN       LanguageSize;\r
+  CHAR8       TempSupportedLanguages;\r
+  CHAR8       *SupportedLanguages;\r
+\r
+  ASSERT (HiiHandle != NULL);\r
+\r
+  //\r
+  // Retrieve the size required for the supported languages buffer.\r
+  //\r
+  LanguageSize = 0;\r
+  Status = mPrivate.HiiString.GetLanguages (&mPrivate.HiiString, HiiHandle, &TempSupportedLanguages, &LanguageSize);\r
+\r
+  //\r
+  // If GetLanguages() returns EFI_SUCCESS for a zero size, \r
+  // then there are no supported languages registered for HiiHandle.  If GetLanguages() \r
+  // returns an error other than EFI_BUFFER_TOO_SMALL, then HiiHandle is not present\r
+  // in the HII Database\r
+  //\r
+  if (Status != EFI_BUFFER_TOO_SMALL) {\r
+    //\r
+    // Return NULL if the size can not be retrieved, or if HiiHandle is not in the HII Database\r
+    //\r
+    return NULL;\r
+  }\r
+\r
+  //\r
+  // Allocate the supported languages buffer.\r
+  //\r
+  SupportedLanguages = AllocateZeroPool (LanguageSize);\r
+  if (SupportedLanguages == NULL) {\r
+    //\r
+    // Return NULL if allocation fails.\r
+    //\r
+    return NULL;\r
+  }\r
+\r
+  //\r
+  // Retrieve the supported languages string\r
+  //\r
+  Status = mPrivate.HiiString.GetLanguages (&mPrivate.HiiString, HiiHandle, SupportedLanguages, &LanguageSize);\r
+  if (EFI_ERROR (Status)) {\r
+    //\r
+    // Free the buffer and return NULL if the supported languages can not be retrieved.\r
+    //\r
+    FreePool (SupportedLanguages);\r
+    return NULL;\r
+  }\r
+\r
+  //\r
+  // Return the Null-terminated ASCII string of supported languages\r
+  //\r
+  return SupportedLanguages;\r
+}\r
+\r
+/**\r
+  Retrieves a string from a string package.\r
+  \r
+  If HiiHandle is NULL, then ASSERT().\r
+  If StringId is 0, then ASSET.\r
+\r
+  @param[in]  HiiHandle  A handle that was previously registered in the HII Database.\r
+  @param[in]  StringId   The identifier of the string to retrieved from the string \r
+                         package associated with HiiHandle.\r
+\r
+  @retval NULL   The string specified by StringId is not present in the string package.\r
+  @retval Other  The string was returned.\r
+\r
+**/\r
+EFI_STRING\r
+InternalGetString (\r
+  IN EFI_HII_HANDLE  HiiHandle,\r
+  IN EFI_STRING_ID   StringId\r
+  )\r
+{\r
+  EFI_STATUS  Status;\r
+  UINTN       StringSize;\r
+  CHAR16      TempString;\r
+  EFI_STRING  String;\r
+  CHAR8       *SupportedLanguages;\r
+  CHAR8       *PlatformLanguage;\r
+  CHAR8       *BestLanguage;\r
+  CHAR8       *Language;\r
+\r
+  ASSERT (HiiHandle != NULL);\r
+  ASSERT (StringId != 0);\r
+\r
+  //\r
+  // Initialize all allocated buffers to NULL\r
+  // \r
+  SupportedLanguages = NULL;\r
+  PlatformLanguage   = NULL;\r
+  BestLanguage       = NULL;\r
+  String             = NULL;\r
+  Language           = "";\r
+\r
+  //\r
+  // Get the languages that the package specified by HiiHandle supports\r
+  //\r
+  SupportedLanguages = GetSupportedLanguages (HiiHandle);\r
+  if (SupportedLanguages == NULL) {\r
+    goto Error;\r
+  }\r
+\r
+  //\r
+  // Get the current platform language setting\r
+  //\r
+  GetEfiGlobalVariable2 (L"PlatformLang", (VOID**)&PlatformLanguage, NULL);\r
+\r
+  //\r
+  // Get the best matching language from SupportedLanguages\r
+  //\r
+  BestLanguage = GetBestLanguage (\r
+                   SupportedLanguages, \r
+                   FALSE,                                             // RFC 4646 mode\r
+                   Language,                                          // Highest priority \r
+                   PlatformLanguage != NULL ? PlatformLanguage : "",  // Next highest priority\r
+                   SupportedLanguages,                                // Lowest priority \r
+                   NULL\r
+                   );\r
+  if (BestLanguage == NULL) {\r
+    goto Error;\r
+  }\r
+\r
+  //\r
+  // Retrieve the size of the string in the string package for the BestLanguage\r
+  //\r
+  StringSize = 0;\r
+  Status = mPrivate.HiiString.GetString (\r
+                         &mPrivate.HiiString,\r
+                         BestLanguage,\r
+                         HiiHandle,\r
+                         StringId,\r
+                         &TempString,\r
+                         &StringSize,\r
+                         NULL\r
+                         );\r
+  //\r
+  // If GetString() returns EFI_SUCCESS for a zero size, \r
+  // then there are no supported languages registered for HiiHandle.  If GetString() \r
+  // returns an error other than EFI_BUFFER_TOO_SMALL, then HiiHandle is not present\r
+  // in the HII Database\r
+  //\r
+  if (Status != EFI_BUFFER_TOO_SMALL) {\r
+    goto Error;\r
+  }\r
+\r
+  //\r
+  // Allocate a buffer for the return string\r
+  //\r
+  String = AllocateZeroPool (StringSize);\r
+  if (String == NULL) {\r
+    goto Error;\r
+  }\r
+\r
+  //\r
+  // Retrieve the string from the string package\r
+  //\r
+  Status = mPrivate.HiiString.GetString (\r
+                         &mPrivate.HiiString,\r
+                         BestLanguage,\r
+                         HiiHandle,\r
+                         StringId,\r
+                         String,\r
+                         &StringSize,\r
+                         NULL\r
+                         );\r
+  if (EFI_ERROR (Status)) {\r
+    //\r
+    // Free the buffer and return NULL if the supported languages can not be retrieved.\r
+    //\r
+    FreePool (String);\r
+    String = NULL;\r
+  }\r
+\r
+Error:\r
+  //\r
+  // Free allocated buffers\r
+  //\r
+  if (SupportedLanguages != NULL) {\r
+    FreePool (SupportedLanguages);\r
+  }\r
+  if (PlatformLanguage != NULL) {\r
+    FreePool (PlatformLanguage);\r
+  }\r
+  if (BestLanguage != NULL) {\r
+    FreePool (BestLanguage);\r
+  }\r
+\r
+  //\r
+  // Return the Null-terminated Unicode string\r
+  //\r
+  return String;\r
 }\r
 \r
 /**\r
@@ -741,6 +968,8 @@ InsertBlockData (
   @param  RequestBlockArray  The block array is to be checked. \r
   @param  VarOffset          Offset of var to the structure\r
   @param  VarWidth           Width of var.\r
+  @param  IsNameValueType    Whether this varstore is name/value varstore or not.\r
+  @param  HiiHandle          Hii handle for this hii package.\r
   \r
   @retval TRUE   This Var is in the block range.\r
   @retval FALSE  This Var is not in the block range.\r
@@ -749,26 +978,41 @@ BOOLEAN
 BlockArrayCheck (\r
   IN IFR_BLOCK_DATA  *RequestBlockArray,\r
   IN UINT16          VarOffset,\r
-  IN UINT16          VarWidth\r
+  IN UINT16          VarWidth,\r
+  IN BOOLEAN         IsNameValueType,\r
+  IN EFI_HII_HANDLE  HiiHandle\r
   )\r
 {\r
   LIST_ENTRY          *Link;\r
   IFR_BLOCK_DATA      *BlockData;\r
-  \r
+  EFI_STRING          Name;\r
+\r
   //\r
   // No Request Block array, all vars are got.\r
   //\r
   if (RequestBlockArray == NULL) {\r
     return TRUE;\r
   }\r
-  \r
+\r
   //\r
   // Check the input var is in the request block range.\r
   //\r
   for (Link = RequestBlockArray->Entry.ForwardLink; Link != &RequestBlockArray->Entry; Link = Link->ForwardLink) {\r
     BlockData = BASE_CR (Link, IFR_BLOCK_DATA, Entry);\r
-    if ((VarOffset >= BlockData->Offset) && ((VarOffset + VarWidth) <= (BlockData->Offset + BlockData->Width))) {\r
-      return TRUE;\r
+\r
+    if (IsNameValueType) {\r
+      Name = InternalGetString (HiiHandle, VarOffset);\r
+      ASSERT (Name != NULL);\r
+\r
+      if (StrnCmp (BlockData->Name, Name, StrLen (Name)) == 0) {\r
+        FreePool (Name);\r
+        return TRUE;\r
+      }\r
+      FreePool (Name);\r
+    } else {\r
+      if ((VarOffset >= BlockData->Offset) && ((VarOffset + VarWidth) <= (BlockData->Offset + BlockData->Width))) {\r
+        return TRUE;\r
+      }\r
     }\r
   }\r
 \r
@@ -861,7 +1105,6 @@ GetVarStoreType (
   IN     EFI_STRING                 ConfigHdr,\r
   OUT    BOOLEAN                    *IsEfiVarstore,\r
   OUT    EFI_IFR_VARSTORE_EFI       **EfiVarStore\r
-  \r
   )\r
 {\r
   EFI_STATUS               Status;\r
@@ -956,17 +1199,201 @@ Done:
   return Status;\r
 }\r
 \r
+/**\r
+  Check whether the ConfigRequest string has the request elements.\r
+  For EFI_HII_VARSTORE_BUFFER type, the request has "&OFFSET=****&WIDTH=****..." format.\r
+  For EFI_HII_VARSTORE_NAME_VALUE type, the request has "&NAME1**&NAME2..." format.\r
+\r
+  @param  ConfigRequest      The input config request string.\r
+\r
+  @retval  TRUE              The input include config request elements.\r
+  @retval  FALSE             The input string not includes.\r
+\r
+**/\r
+BOOLEAN\r
+GetElementsFromRequest (\r
+  IN EFI_STRING    ConfigRequest\r
+  )\r
+{\r
+  EFI_STRING   TmpRequest;\r
+\r
+  TmpRequest = StrStr (ConfigRequest, L"PATH=");\r
+  ASSERT (TmpRequest != NULL);\r
+\r
+  if ((StrStr (TmpRequest, L"&OFFSET=") != NULL) || (StrStr (TmpRequest, L"&") != NULL)) {\r
+    return TRUE;\r
+  }\r
+\r
+  return FALSE;\r
+}\r
+\r
+/**\r
+  Check whether the this varstore is the request varstore.\r
+\r
+  @param  VarstoreGuid      Varstore guid.\r
+  @param  Name              Varstore name.\r
+  @param  ConfigHdr         Current configRequest info.\r
+\r
+  @retval  TRUE              This varstore is the requst one.\r
+  @retval  FALSE             This varstore is not the requst one.\r
+                                 \r
+**/\r
+BOOLEAN\r
+IsThisVarstore (\r
+  IN EFI_GUID    *VarstoreGuid,\r
+  IN CHAR16      *Name,\r
+  IN CHAR16      *ConfigHdr\r
+  )\r
+{\r
+  EFI_STRING               GuidStr;\r
+  EFI_STRING               NameStr;\r
+  EFI_STRING               TempStr;\r
+  UINTN                    LengthString;\r
+  BOOLEAN                  RetVal;\r
+\r
+  RetVal       = FALSE;\r
+  GuidStr      = NULL;\r
+  TempStr      = NULL;\r
+\r
+  GenerateSubStr (L"GUID=", sizeof (EFI_GUID), (VOID *)VarstoreGuid, 1, &GuidStr);\r
+  if (Name != NULL) {\r
+    GenerateSubStr (L"NAME=", StrLen (Name) * sizeof (CHAR16), (VOID *) Name, 2, &NameStr);\r
+  } else {\r
+    GenerateSubStr (L"NAME=", 0, NULL, 2, &NameStr);\r
+  }\r
+  LengthString = StrLen (GuidStr);\r
+  LengthString = LengthString + StrLen (NameStr) + 1;\r
+  TempStr = AllocateZeroPool (LengthString * sizeof (CHAR16));\r
+  if (TempStr == NULL) {\r
+    goto Done;\r
+  }\r
+\r
+  StrCpy (TempStr, GuidStr);\r
+  StrCat (TempStr, NameStr);\r
+\r
+  if (ConfigHdr == NULL || StrnCmp (ConfigHdr, TempStr, StrLen (TempStr)) == 0) {\r
+    RetVal = TRUE;\r
+  }\r
+\r
+Done:\r
+  if (GuidStr != NULL) {\r
+    FreePool (GuidStr); \r
+  }\r
+\r
+  if (NameStr != NULL) {\r
+    FreePool (NameStr);\r
+  }\r
+\r
+  if (TempStr != NULL) {\r
+    FreePool (TempStr);\r
+  }\r
+\r
+  return RetVal;\r
+}\r
+\r
+/**\r
+  Check whether the this op code is required.\r
+\r
+  @param  RequestBlockArray      The array includes all the request info or NULL.\r
+  @param  HiiHandle              The hii handle for this form package.\r
+  @param  VarStorageData         The varstore data strucure.\r
+  @param  IfrOpHdr               Ifr opcode header for this opcode.\r
+  @param  VarWidth               The buffer width for this opcode.\r
+  @param  ReturnData             The data block added for this opcode.\r
+\r
+  @retval  EFI_SUCCESS           This opcode is required.\r
+  @retval  Others                This opcode is not required or error occur.\r
+                                 \r
+**/\r
+EFI_STATUS\r
+IsThisOpcodeRequired (\r
+  IN     IFR_BLOCK_DATA           *RequestBlockArray,\r
+  IN     EFI_HII_HANDLE           HiiHandle,\r
+  IN OUT IFR_VARSTORAGE_DATA      *VarStorageData,\r
+  IN     EFI_IFR_OP_HEADER        *IfrOpHdr,\r
+  IN     UINT16                   VarWidth,\r
+  OUT    IFR_BLOCK_DATA           **ReturnData\r
+  )\r
+{\r
+  IFR_BLOCK_DATA           *BlockData;\r
+  UINT16                   VarOffset;\r
+  EFI_STRING_ID            NameId;\r
+  EFI_IFR_QUESTION_HEADER  *IfrQuestionHdr;\r
+\r
+  NameId    = 0;\r
+  VarOffset = 0;\r
+  IfrQuestionHdr = (EFI_IFR_QUESTION_HEADER  *)((CHAR8 *) IfrOpHdr + sizeof (EFI_IFR_OP_HEADER));\r
+\r
+  if (VarStorageData->Type == EFI_HII_VARSTORE_NAME_VALUE) {\r
+    NameId = IfrQuestionHdr->VarStoreInfo.VarName;\r
+\r
+    //\r
+    // Check whether this question is in requested block array.\r
+    //\r
+    if (!BlockArrayCheck (RequestBlockArray, NameId, 0, TRUE, HiiHandle)) {\r
+      //\r
+      // This question is not in the requested string. Skip it.\r
+      //\r
+      return EFI_SUCCESS;\r
+    }\r
+  } else {\r
+    VarOffset = IfrQuestionHdr->VarStoreInfo.VarOffset;\r
+    \r
+    //\r
+    // Check whether this question is in requested block array.\r
+    //\r
+    if (!BlockArrayCheck (RequestBlockArray, VarOffset, VarWidth, FALSE, HiiHandle)) {\r
+      //\r
+      // This question is not in the requested string. Skip it.\r
+      //\r
+      return EFI_SUCCESS;\r
+    }\r
+\r
+    //\r
+    // Check this var question is in the var storage \r
+    //\r
+    if (((VarOffset + VarWidth) > VarStorageData->Size)) {\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+  }\r
+\r
+  BlockData = (IFR_BLOCK_DATA *) AllocateZeroPool (sizeof (IFR_BLOCK_DATA));\r
+  if (BlockData == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+  if (VarStorageData->Type == EFI_HII_VARSTORE_NAME_VALUE) {\r
+    BlockData->Name   = InternalGetString(HiiHandle, NameId);\r
+  } else {\r
+    BlockData->Offset = VarOffset;\r
+  }\r
+\r
+  BlockData->Width      = VarWidth;\r
+  BlockData->QuestionId = IfrQuestionHdr->QuestionId;\r
+  BlockData->OpCode     = IfrOpHdr->OpCode;\r
+  BlockData->Scope      = IfrOpHdr->Scope;\r
+  InitializeListHead (&BlockData->DefaultValueEntry);\r
+  //\r
+  // Add Block Data into VarStorageData BlockEntry\r
+  //\r
+  InsertBlockData (&VarStorageData->BlockEntry, &BlockData);\r
+  *ReturnData = BlockData;\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
 /**\r
   This function parses Form Package to get the block array and the default\r
   value array according to the request ConfigHdr.\r
 \r
+  @param  HiiHandle             Hii Handle for this hii package.\r
   @param  Package               Pointer to the form package data.\r
   @param  PackageLength         Length of the pacakge.\r
   @param  ConfigHdr             Request string ConfigHdr. If it is NULL,\r
                                 the first found varstore will be as ConfigHdr.\r
   @param  RequestBlockArray     The block array is retrieved from the request string.\r
   @param  VarStorageData        VarStorage structure contains the got block and default value.\r
-  @param  PIfrDefaultIdArray    Point to the got default id and default name array.\r
+  @param  DefaultIdArray        Point to the got default id and default name array.\r
 \r
   @retval EFI_SUCCESS           The block array and the default value array are got.\r
   @retval EFI_INVALID_PARAMETER The varstore defintion in the differnt form pacakges\r
@@ -976,6 +1403,7 @@ Done:
 EFI_STATUS\r
 EFIAPI\r
 ParseIfrData (\r
+  IN     EFI_HII_HANDLE      HiiHandle,\r
   IN     UINT8               *Package,\r
   IN     UINT32              PackageLength,\r
   IN     EFI_STRING          ConfigHdr,\r
@@ -1003,7 +1431,6 @@ ParseIfrData (
   IFR_DEFAULT_DATA         *DefaultDataPtr;\r
   IFR_BLOCK_DATA           *BlockData;\r
   CHAR16                   *VarStoreName;\r
-  UINT16                   VarOffset;\r
   UINT16                   VarWidth;\r
   UINT16                   VarDefaultId;\r
   EFI_STRING               GuidStr;\r
@@ -1013,6 +1440,7 @@ ParseIfrData (
   BOOLEAN                  FirstOneOfOption;\r
   LIST_ENTRY               *LinkData;\r
   LIST_ENTRY               *LinkDefault;\r
+  EFI_IFR_VARSTORE_NAME_VALUE *IfrNameValueVarStore;\r
 \r
   LengthString     = 0;\r
   Status           = EFI_SUCCESS;\r
@@ -1030,44 +1458,25 @@ ParseIfrData (
   IfrOffset   = sizeof (EFI_HII_PACKAGE_HEADER);\r
   while (IfrOffset < PackageLength) {\r
     IfrOpHdr  = (EFI_IFR_OP_HEADER *) (Package + IfrOffset);\r
-\r
     switch (IfrOpHdr->OpCode) {\r
     case EFI_IFR_VARSTORE_OP:\r
       //\r
       // VarStore is found. Don't need to search any more.\r
       //\r
-      if (VarStorageData->Size != 0) {\r
+      if (VarStorageData->VarStoreId != 0) {\r
         break;\r
       }\r
 \r
-      //\r
-      // Get the requied varstore information\r
-      // Add varstore by Guid and Name in ConfigHdr\r
-      // Make sure Offset is in varstore size and varstoreid\r
-      //\r
       IfrVarStore = (EFI_IFR_VARSTORE *) IfrOpHdr;\r
-      VarStoreName = AllocateZeroPool (AsciiStrSize ((CHAR8 *)IfrVarStore->Name) * sizeof (CHAR16));\r
+\r
+      VarStoreName = AllocateZeroPool (AsciiStrSize (IfrVarStore->Name) * sizeof (CHAR16));\r
       if (VarStoreName == NULL) {\r
         Status = EFI_OUT_OF_RESOURCES;\r
         goto Done;\r
       }\r
-      AsciiStrToUnicodeStr ((CHAR8 *) IfrVarStore->Name, VarStoreName);\r
+      AsciiStrToUnicodeStr (IfrVarStore->Name, VarStoreName);\r
 \r
-      GenerateSubStr (L"GUID=", sizeof (EFI_GUID), (VOID *) &IfrVarStore->Guid, 1, &GuidStr);\r
-      GenerateSubStr (L"NAME=", StrLen (VarStoreName) * sizeof (CHAR16), (VOID *) VarStoreName, 2, &NameStr);\r
-      LengthString = StrLen (GuidStr);\r
-      LengthString = LengthString + StrLen (NameStr) + 1;\r
-      TempStr = AllocateZeroPool (LengthString * sizeof (CHAR16));\r
-      if (TempStr == NULL) {\r
-        FreePool (GuidStr);\r
-        FreePool (NameStr);\r
-        FreePool (VarStoreName);\r
-        Status = EFI_OUT_OF_RESOURCES;\r
-        goto Done;\r
-      }\r
-      StrCpy (TempStr, GuidStr);\r
-      StrCat (TempStr, NameStr);\r
-      if (ConfigHdr == NULL || StrnCmp (ConfigHdr, TempStr, StrLen (TempStr)) == 0) {\r
+      if (IsThisVarstore((VOID *)&IfrVarStore->Guid, VarStoreName, ConfigHdr)) {\r
         //\r
         // Find the matched VarStore\r
         //\r
@@ -1075,33 +1484,18 @@ ParseIfrData (
         VarStorageData->VarStoreId = IfrVarStore->VarStoreId;\r
         VarStorageData->Size       = IfrVarStore->Size;\r
         VarStorageData->Name       = VarStoreName;\r
-      } else {\r
-        //\r
-        // No found, free the allocated memory \r
-        //\r
-        FreePool (VarStoreName);\r
+        VarStorageData->Type       = EFI_HII_VARSTORE_BUFFER;\r
       }\r
-      //\r
-      // Free alllocated temp string.\r
-      //\r
-      FreePool (GuidStr);\r
-      FreePool (NameStr);\r
-      FreePool (TempStr);\r
       break;\r
 \r
     case EFI_IFR_VARSTORE_EFI_OP:\r
       //\r
       // VarStore is found. Don't need to search any more.\r
       //\r
-      if (VarStorageData->Size != 0) {\r
+      if (VarStorageData->VarStoreId != 0) {\r
         break;\r
       }\r
 \r
-      //\r
-      // Get the requied varstore information\r
-      // Add varstore by Guid and Name in ConfigHdr\r
-      // Make sure Offset is in varstore size and varstoreid\r
-      //\r
       IfrEfiVarStore = (EFI_IFR_VARSTORE_EFI *) IfrOpHdr;\r
 \r
       //\r
@@ -1113,28 +1507,14 @@ ParseIfrData (
         break;\r
       }\r
 \r
-      VarStoreName = AllocateZeroPool (AsciiStrSize ((CHAR8 *)IfrEfiVarStore->Name) * sizeof (CHAR16));\r
+      VarStoreName = AllocateZeroPool (AsciiStrSize (IfrEfiVarStore->Name) * sizeof (CHAR16));\r
       if (VarStoreName == NULL) {\r
         Status = EFI_OUT_OF_RESOURCES;\r
         goto Done;\r
       }\r
-      AsciiStrToUnicodeStr ((CHAR8 *) IfrEfiVarStore->Name, VarStoreName);\r
+      AsciiStrToUnicodeStr (IfrEfiVarStore->Name, VarStoreName);\r
 \r
-      GenerateSubStr (L"GUID=", sizeof (EFI_GUID), (VOID *) &IfrEfiVarStore->Guid, 1, &GuidStr);\r
-      GenerateSubStr (L"NAME=", StrLen (VarStoreName) * sizeof (CHAR16), (VOID *) VarStoreName, 2, &NameStr);\r
-      LengthString = StrLen (GuidStr);\r
-      LengthString = LengthString + StrLen (NameStr) + 1;\r
-      TempStr = AllocateZeroPool (LengthString * sizeof (CHAR16));\r
-      if (TempStr == NULL) {\r
-        FreePool (GuidStr);\r
-        FreePool (NameStr);\r
-        FreePool (VarStoreName);\r
-        Status = EFI_OUT_OF_RESOURCES;\r
-        goto Done;\r
-      }\r
-      StrCpy (TempStr, GuidStr);\r
-      StrCat (TempStr, NameStr);\r
-      if (ConfigHdr == NULL || StrnCmp (ConfigHdr, TempStr, StrLen (TempStr)) == 0) {\r
+      if (IsThisVarstore (&IfrEfiVarStore->Guid, VarStoreName, ConfigHdr)) {\r
         //\r
         // Find the matched VarStore\r
         //\r
@@ -1142,18 +1522,28 @@ ParseIfrData (
         VarStorageData->VarStoreId = IfrEfiVarStore->VarStoreId;\r
         VarStorageData->Size       = IfrEfiVarStore->Size;\r
         VarStorageData->Name       = VarStoreName;\r
-      } else {\r
-        //\r
-        // No found, free the allocated memory \r
-        //\r
-        FreePool (VarStoreName);\r
+        VarStorageData->Type       = EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER;\r
       }\r
+      break;\r
+\r
+    case EFI_IFR_VARSTORE_NAME_VALUE_OP:\r
       //\r
-      // Free alllocated temp string.\r
+      // VarStore is found. Don't need to search any more.\r
       //\r
-      FreePool (GuidStr);\r
-      FreePool (NameStr);\r
-      FreePool (TempStr);\r
+      if (VarStorageData->VarStoreId != 0) {\r
+        break;\r
+      }\r
+\r
+      IfrNameValueVarStore = (EFI_IFR_VARSTORE_NAME_VALUE *) IfrOpHdr;\r
+\r
+      if (IsThisVarstore (&IfrNameValueVarStore->Guid, NULL, ConfigHdr)) {\r
+        //\r
+        // Find the matched VarStore\r
+        //\r
+        CopyGuid (&VarStorageData->Guid, (EFI_GUID *) (VOID *) &IfrNameValueVarStore->Guid);\r
+        VarStorageData->VarStoreId = IfrNameValueVarStore->VarStoreId;\r
+        VarStorageData->Type       = EFI_HII_VARSTORE_NAME_VALUE;\r
+      }\r
       break;\r
 \r
     case EFI_IFR_DEFAULTSTORE_OP:\r
@@ -1175,7 +1565,7 @@ ParseIfrData (
       //\r
       // No matched varstore is found and directly return.\r
       //\r
-      if (VarStorageData->Size == 0) {\r
+      if (VarStorageData->VarStoreId == 0) {\r
         Status = EFI_SUCCESS;\r
         goto Done;\r
       }\r
@@ -1185,7 +1575,7 @@ ParseIfrData (
       //\r
       // Ref question is not in IFR Form. This IFR form is not valid. \r
       //\r
-      if (VarStorageData->Size == 0) {\r
+      if (VarStorageData->VarStoreId == 0) {\r
         Status = EFI_INVALID_PARAMETER;\r
         goto Done;\r
       }\r
@@ -1196,48 +1586,12 @@ ParseIfrData (
       if (IfrRef->Question.VarStoreId != VarStorageData->VarStoreId) {\r
         break;\r
       }\r
-      \r
-      //\r
-      // Get Offset/Width by Question header.\r
-      //\r
-      VarOffset = IfrRef->Question.VarStoreInfo.VarOffset;\r
       VarWidth  = (UINT16) (sizeof (EFI_HII_REF));\r
-      //\r
-      // Check whether this question is in requested block array.\r
-      //\r
-      if (!BlockArrayCheck (RequestBlockArray, VarOffset, VarWidth)) {\r
-        //\r
-        // This question is not in the requested string. Skip it.\r
-        //\r
-        break;\r
-      }\r
 \r
-      //\r
-      // Check this var question is in the var storage \r
-      //\r
-      if ((VarOffset + VarWidth) > VarStorageData->Size) {\r
-        Status = EFI_INVALID_PARAMETER;\r
-        goto Done;\r
-      }\r
-      \r
-      //\r
-      // Set Block Data\r
-      //\r
-      BlockData = (IFR_BLOCK_DATA *) AllocateZeroPool (sizeof (IFR_BLOCK_DATA));\r
-      if (BlockData == NULL) {\r
-        Status = EFI_OUT_OF_RESOURCES;\r
+      Status = IsThisOpcodeRequired(RequestBlockArray, HiiHandle, VarStorageData, IfrOpHdr, VarWidth, &BlockData);\r
+      if (EFI_ERROR (Status)) {\r
         goto Done;\r
       }\r
-      BlockData->Offset     = VarOffset;\r
-      BlockData->Width      = VarWidth;\r
-      BlockData->QuestionId = IfrRef->Question.QuestionId;\r
-      BlockData->OpCode     = IfrOpHdr->OpCode;\r
-      BlockData->Scope      = IfrOpHdr->Scope;\r
-      InitializeListHead (&BlockData->DefaultValueEntry);\r
-      //\r
-      // Add Block Data into VarStorageData BlockEntry\r
-      //\r
-      InsertBlockData (&VarStorageData->BlockEntry, &BlockData);\r
       break;\r
 \r
     case EFI_IFR_ONE_OF_OP:\r
@@ -1249,7 +1603,7 @@ ParseIfrData (
       //\r
       // Numeric and OneOf question is not in IFR Form. This IFR form is not valid. \r
       //\r
-      if (VarStorageData->Size == 0) {\r
+      if (VarStorageData->VarStoreId == 0) {\r
         Status = EFI_INVALID_PARAMETER;\r
         goto Done;\r
       }\r
@@ -1260,49 +1614,20 @@ ParseIfrData (
       if (IfrOneOf->Question.VarStoreId != VarStorageData->VarStoreId) {\r
         break;\r
       }\r
-      \r
-      //\r
-      // Get Offset/Width by Question header and OneOf Flags\r
-      //\r
-      VarOffset = IfrOneOf->Question.VarStoreInfo.VarOffset;\r
       VarWidth  = (UINT16) (1 << (IfrOneOf->Flags & EFI_IFR_NUMERIC_SIZE));\r
-      //\r
-      // Check whether this question is in requested block array.\r
-      //\r
-      if (!BlockArrayCheck (RequestBlockArray, VarOffset, VarWidth)) {\r
-        //\r
-        // This question is not in the requested string. Skip it.\r
-        //\r
-        break;\r
-      }\r
 \r
-      //\r
-      // Check this var question is in the var storage \r
-      //\r
-      if ((VarOffset + VarWidth) > VarStorageData->Size) {\r
-        Status = EFI_INVALID_PARAMETER;\r
+      Status = IsThisOpcodeRequired(RequestBlockArray, HiiHandle, VarStorageData, IfrOpHdr, VarWidth, &BlockData);\r
+      if (EFI_ERROR (Status)) {\r
         goto Done;\r
       }\r
-      \r
-      //\r
-      // Set Block Data\r
-      //\r
-      BlockData = (IFR_BLOCK_DATA *) AllocateZeroPool (sizeof (IFR_BLOCK_DATA));\r
+\r
       if (BlockData == NULL) {\r
-        Status = EFI_OUT_OF_RESOURCES;\r
-        goto Done;\r
+        //\r
+        // BlockData == NULL means this opcode is not in the requst array.\r
+        //\r
+        break;\r
       }\r
-      BlockData->Offset     = VarOffset;\r
-      BlockData->Width      = VarWidth;\r
-      BlockData->QuestionId = IfrOneOf->Question.QuestionId;\r
-      BlockData->OpCode     = IfrOpHdr->OpCode;\r
-      BlockData->Scope      = IfrOpHdr->Scope;\r
-      InitializeListHead (&BlockData->DefaultValueEntry);\r
-      //\r
-      // Add Block Data into VarStorageData BlockEntry\r
-      //\r
-      InsertBlockData (&VarStorageData->BlockEntry, &BlockData);\r
-      \r
+\r
       if (IfrOpHdr->OpCode == EFI_IFR_ONE_OF_OP) {\r
         //\r
         // Set this flag to TRUE for the first oneof option.\r
@@ -1317,24 +1642,28 @@ ParseIfrData (
         case EFI_IFR_NUMERIC_SIZE_1:\r
           DefaultData.Value.u8 = IfrOneOf->data.u8.MinValue;\r
           break;\r
-  \r
+\r
         case EFI_IFR_NUMERIC_SIZE_2:\r
           CopyMem (&DefaultData.Value.u16, &IfrOneOf->data.u16.MinValue, sizeof (UINT16));\r
           break;\r
-  \r
+\r
         case EFI_IFR_NUMERIC_SIZE_4:\r
           CopyMem (&DefaultData.Value.u32, &IfrOneOf->data.u32.MinValue, sizeof (UINT32));\r
           break;\r
-  \r
+\r
         case EFI_IFR_NUMERIC_SIZE_8:\r
           CopyMem (&DefaultData.Value.u64, &IfrOneOf->data.u64.MinValue, sizeof (UINT64));\r
           break;\r
+\r
+        default:\r
+          Status = EFI_INVALID_PARAMETER;\r
+          goto Done;\r
         }\r
         //\r
         // Set default value base on the DefaultId list get from IFR data.\r
         //        \r
         for (LinkData = DefaultIdArray->Entry.ForwardLink; LinkData != &DefaultIdArray->Entry; LinkData = LinkData->ForwardLink) {\r
-          DefaultDataPtr = BASE_CR (LinkData, IFR_DEFAULT_DATA, Entry);     \r
+          DefaultDataPtr = BASE_CR (LinkData, IFR_DEFAULT_DATA, Entry);\r
           DefaultData.DefaultId   = DefaultDataPtr->DefaultId;\r
           InsertDefaultValue (BlockData, &DefaultData);\r
         }\r
@@ -1351,7 +1680,7 @@ ParseIfrData (
       //\r
       // OrderedList question is not in IFR Form. This IFR form is not valid. \r
       //\r
-      if (VarStorageData->Size == 0) {\r
+      if (VarStorageData->VarStoreId == 0) {\r
         Status = EFI_INVALID_PARAMETER;\r
         goto Done;\r
       }\r
@@ -1363,27 +1692,11 @@ ParseIfrData (
         BlockData = NULL;\r
         break;\r
       }\r
-\r
-      //\r
-      // Get Offset/Width by Question header and OneOf Flags\r
-      //\r
-      VarOffset = IfrOrderedList->Question.VarStoreInfo.VarOffset;\r
       VarWidth  = IfrOrderedList->MaxContainers;\r
-      \r
-      //\r
-      // Set Block Data\r
-      //\r
-      BlockData = (IFR_BLOCK_DATA *) AllocateZeroPool (sizeof (IFR_BLOCK_DATA));\r
-      if (BlockData == NULL) {\r
-        Status = EFI_OUT_OF_RESOURCES;\r
+      Status = IsThisOpcodeRequired(RequestBlockArray, HiiHandle, VarStorageData, IfrOpHdr, VarWidth, &BlockData);\r
+      if (EFI_ERROR (Status)) {\r
         goto Done;\r
       }\r
-      BlockData->Offset     = VarOffset;\r
-      BlockData->Width      = VarWidth;\r
-      BlockData->QuestionId = IfrOrderedList->Question.QuestionId;\r
-      BlockData->OpCode     = IfrOpHdr->OpCode;\r
-      BlockData->Scope      = IfrOpHdr->Scope;\r
-      InitializeListHead (&BlockData->DefaultValueEntry);\r
       break;\r
 \r
     case EFI_IFR_CHECKBOX_OP:\r
@@ -1399,7 +1712,7 @@ ParseIfrData (
       //\r
       // CheckBox question is not in IFR Form. This IFR form is not valid. \r
       //\r
-      if (VarStorageData->Size == 0) {\r
+      if (VarStorageData->VarStoreId == 0) {\r
         Status = EFI_INVALID_PARAMETER;\r
         goto Done;\r
       }\r
@@ -1410,50 +1723,19 @@ ParseIfrData (
       if (IfrCheckBox->Question.VarStoreId != VarStorageData->VarStoreId) {\r
         break;\r
       }\r
-      \r
-      //\r
-      // Get Offset/Width by Question header and OneOf Flags\r
-      //\r
-      VarOffset = IfrCheckBox->Question.VarStoreInfo.VarOffset;\r
       VarWidth  = (UINT16) sizeof (BOOLEAN);\r
+      Status = IsThisOpcodeRequired(RequestBlockArray, HiiHandle, VarStorageData, IfrOpHdr, VarWidth, &BlockData);\r
+      if (EFI_ERROR (Status)) {\r
+        goto Done;\r
+      }\r
 \r
-      //\r
-      // Check whether this question is in requested block array.\r
-      //\r
-      if (!BlockArrayCheck (RequestBlockArray, VarOffset, VarWidth)) {\r
+      if (BlockData == NULL) {\r
         //\r
-        // This question is not in the requested string. Skip it.\r
+        // BlockData == NULL means this opcode is not in the requst array.\r
         //\r
         break;\r
       }\r
 \r
-      //\r
-      // Check this var question is in the var storage \r
-      //\r
-      if ((VarOffset + VarWidth) > VarStorageData->Size) {\r
-        Status = EFI_INVALID_PARAMETER;\r
-        goto Done;\r
-      }\r
-      \r
-      //\r
-      // Set Block Data\r
-      //\r
-      BlockData = (IFR_BLOCK_DATA *) AllocateZeroPool (sizeof (IFR_BLOCK_DATA));\r
-      if (BlockData == NULL) {\r
-        Status = EFI_OUT_OF_RESOURCES;\r
-        goto Done;\r
-      }\r
-      BlockData->Offset     = VarOffset;\r
-      BlockData->Width      = VarWidth;\r
-      BlockData->QuestionId = IfrCheckBox->Question.QuestionId;\r
-      BlockData->OpCode     = IfrOpHdr->OpCode;\r
-      BlockData->Scope      = IfrOpHdr->Scope;\r
-      InitializeListHead (&BlockData->DefaultValueEntry);\r
-      //\r
-      // Add Block Data into VarStorageData BlockEntry\r
-      //\r
-      InsertBlockData (&VarStorageData->BlockEntry, &BlockData);\r
-      \r
       //\r
       // Add default value for standard ID by CheckBox Flag\r
       //\r
@@ -1498,7 +1780,7 @@ ParseIfrData (
         //\r
         // When flag is not set, defautl value is FASLE.\r
         //\r
-        DefaultData.Type    = DefaultValueFromDefault;        \r
+        DefaultData.Type    = DefaultValueFromDefault;\r
         DefaultData.Value.b = FALSE;\r
       }\r
       //\r
@@ -1517,7 +1799,7 @@ ParseIfrData (
       //\r
       // Date question is not in IFR Form. This IFR form is not valid. \r
       //\r
-      if (VarStorageData->Size == 0) {\r
+      if (VarStorageData->VarStoreId == 0) {\r
         Status = EFI_INVALID_PARAMETER;\r
         goto Done;\r
       }\r
@@ -1529,49 +1811,11 @@ ParseIfrData (
         break;\r
       }\r
 \r
-      //\r
-      // Get Offset/Width by Question header and OneOf Flags\r
-      //\r
-      VarOffset = IfrDate->Question.VarStoreInfo.VarOffset;\r
       VarWidth  = (UINT16) sizeof (EFI_HII_DATE);\r
-\r
-      //\r
-      // Check whether this question is in requested block array.\r
-      //\r
-      if (!BlockArrayCheck (RequestBlockArray, VarOffset, VarWidth)) {\r
-        //\r
-        // This question is not in the requested array. Skip it.\r
-        //\r
-        break;\r
-      }\r
-\r
-      //\r
-      // Check this var question is in the var storage \r
-      //\r
-      if ((VarOffset + VarWidth) > VarStorageData->Size) {\r
-        Status = EFI_INVALID_PARAMETER;\r
-        goto Done;\r
-      }\r
-\r
-      //\r
-      // Set Block Data\r
-      //\r
-      BlockData = (IFR_BLOCK_DATA *) AllocateZeroPool (sizeof (IFR_BLOCK_DATA));\r
-      if (BlockData == NULL) {\r
-        Status = EFI_OUT_OF_RESOURCES;\r
+      Status = IsThisOpcodeRequired(RequestBlockArray, HiiHandle, VarStorageData, IfrOpHdr, VarWidth, &BlockData);\r
+      if (EFI_ERROR (Status)) {\r
         goto Done;\r
       }\r
-      BlockData->Offset     = VarOffset;\r
-      BlockData->Width      = VarWidth;\r
-      BlockData->QuestionId = IfrDate->Question.QuestionId;\r
-      BlockData->OpCode     = IfrOpHdr->OpCode;\r
-      BlockData->Scope      = IfrOpHdr->Scope;\r
-      InitializeListHead (&BlockData->DefaultValueEntry);\r
-\r
-      //\r
-      // Add Block Data into VarStorageData BlockEntry\r
-      //\r
-      InsertBlockData (&VarStorageData->BlockEntry, &BlockData);\r
       break;\r
 \r
     case EFI_IFR_TIME_OP:\r
@@ -1584,7 +1828,7 @@ ParseIfrData (
       //\r
       // Time question is not in IFR Form. This IFR form is not valid. \r
       //\r
-      if (VarStorageData->Size == 0) {\r
+      if (VarStorageData->VarStoreId == 0) {\r
         Status = EFI_INVALID_PARAMETER;\r
         goto Done;\r
       }\r
@@ -1596,49 +1840,11 @@ ParseIfrData (
         break;\r
       }\r
 \r
-      //\r
-      // Get Offset/Width by Question header and OneOf Flags\r
-      //\r
-      VarOffset = IfrTime->Question.VarStoreInfo.VarOffset;\r
       VarWidth  = (UINT16) sizeof (EFI_HII_TIME);\r
-\r
-      //\r
-      // Check whether this question is in requested block array.\r
-      //\r
-      if (!BlockArrayCheck (RequestBlockArray, VarOffset, VarWidth)) {\r
-        //\r
-        // This question is not in the requested array. Skip it.\r
-        //\r
-        break;\r
-      }\r
-\r
-      //\r
-      // Check this var question is in the var storage \r
-      //\r
-      if ((VarOffset + VarWidth) > VarStorageData->Size) {\r
-        Status = EFI_INVALID_PARAMETER;\r
-        goto Done;\r
-      }\r
-\r
-      //\r
-      // Set Block Data\r
-      //\r
-      BlockData = (IFR_BLOCK_DATA *) AllocateZeroPool (sizeof (IFR_BLOCK_DATA));\r
-      if (BlockData == NULL) {\r
-        Status = EFI_OUT_OF_RESOURCES;\r
+      Status = IsThisOpcodeRequired(RequestBlockArray, HiiHandle, VarStorageData, IfrOpHdr, VarWidth, &BlockData);\r
+      if (EFI_ERROR (Status)) {\r
         goto Done;\r
       }\r
-      BlockData->Offset     = VarOffset;\r
-      BlockData->Width      = VarWidth;\r
-      BlockData->QuestionId = IfrTime->Question.QuestionId;\r
-      BlockData->OpCode     = IfrOpHdr->OpCode;\r
-      BlockData->Scope      = IfrOpHdr->Scope;\r
-      InitializeListHead (&BlockData->DefaultValueEntry);\r
-\r
-        //\r
-      // Add Block Data into VarStorageData BlockEntry\r
-      //\r
-      InsertBlockData (&VarStorageData->BlockEntry, &BlockData);\r
       break;\r
 \r
     case EFI_IFR_STRING_OP:\r
@@ -1651,7 +1857,7 @@ ParseIfrData (
       //\r
       // String question is not in IFR Form. This IFR form is not valid. \r
       //\r
-      if (VarStorageData->Size == 0) {\r
+      if (VarStorageData->VarStoreId == 0) {\r
         Status = EFI_INVALID_PARAMETER;\r
         goto Done;\r
       }\r
@@ -1662,50 +1868,13 @@ ParseIfrData (
       if (IfrString->Question.VarStoreId != VarStorageData->VarStoreId) {\r
         break;\r
       }\r
-      \r
-      //\r
-      // Get Offset/Width by Question header and OneOf Flags\r
-      //\r
-      VarOffset = IfrString->Question.VarStoreInfo.VarOffset;\r
-      VarWidth  = (UINT16) (IfrString->MaxSize * sizeof (UINT16));\r
-\r
-      //\r
-      // Check whether this question is in requested block array.\r
-      //\r
-      if (!BlockArrayCheck (RequestBlockArray, VarOffset, VarWidth)) {\r
-        //\r
-        // This question is not in the requested string. Skip it.\r
-        //\r
-        break;\r
-      }\r
 \r
-      //\r
-      // Check this var question is in the var storage \r
-      //\r
-      if ((VarOffset + VarWidth) > VarStorageData->Size) {\r
-        Status = EFI_INVALID_PARAMETER;\r
-        goto Done;\r
-      }\r
-      \r
-      //\r
-      // Set Block Data\r
-      //\r
-      BlockData = (IFR_BLOCK_DATA *) AllocateZeroPool (sizeof (IFR_BLOCK_DATA));\r
-      if (BlockData == NULL) {\r
-        Status = EFI_OUT_OF_RESOURCES;\r
+      VarWidth  = (UINT16) (IfrString->MaxSize * sizeof (UINT16));\r
+      Status = IsThisOpcodeRequired(RequestBlockArray, HiiHandle, VarStorageData, IfrOpHdr, VarWidth, &BlockData);\r
+      if (EFI_ERROR (Status)) {\r
         goto Done;\r
       }\r
-      BlockData->Offset     = VarOffset;\r
-      BlockData->Width      = VarWidth;\r
-      BlockData->QuestionId = IfrString->Question.QuestionId;\r
-      BlockData->OpCode     = IfrOpHdr->OpCode;\r
-      InitializeListHead (&BlockData->DefaultValueEntry);\r
-      \r
-      //\r
-      // Add Block Data into VarStorageData BlockEntry\r
-      //\r
-      InsertBlockData (&VarStorageData->BlockEntry, &BlockData);\r
-      \r
+\r
       //\r
       // No default value for string.\r
       //\r
@@ -1722,7 +1891,7 @@ ParseIfrData (
       //\r
       // Password question is not in IFR Form. This IFR form is not valid. \r
       //\r
-      if (VarStorageData->Size == 0) {\r
+      if (VarStorageData->VarStoreId == 0) {\r
         Status = EFI_INVALID_PARAMETER;\r
         goto Done;\r
       }\r
@@ -1733,50 +1902,13 @@ ParseIfrData (
       if (IfrPassword->Question.VarStoreId != VarStorageData->VarStoreId) {\r
         break;\r
       }\r
-      \r
-      //\r
-      // Get Offset/Width by Question header and OneOf Flags\r
-      //\r
-      VarOffset = IfrPassword->Question.VarStoreInfo.VarOffset;\r
-      VarWidth  = (UINT16) (IfrPassword->MaxSize * sizeof (UINT16));\r
-\r
-      //\r
-      // Check whether this question is in requested block array.\r
-      //\r
-      if (!BlockArrayCheck (RequestBlockArray, VarOffset, VarWidth)) {\r
-        //\r
-        // This question is not in the requested string. Skip it.\r
-        //\r
-        break;\r
-      }\r
 \r
-      //\r
-      // Check this var question is in the var storage \r
-      //\r
-      if ((VarOffset + VarWidth) > VarStorageData->Size) {\r
-        Status = EFI_INVALID_PARAMETER;\r
-        goto Done;\r
-      }\r
-      \r
-      //\r
-      // Set Block Data\r
-      //\r
-      BlockData = (IFR_BLOCK_DATA *) AllocateZeroPool (sizeof (IFR_BLOCK_DATA));\r
-      if (BlockData == NULL) {\r
-        Status = EFI_OUT_OF_RESOURCES;\r
+      VarWidth  = (UINT16) (IfrPassword->MaxSize * sizeof (UINT16));\r
+      Status = IsThisOpcodeRequired(RequestBlockArray, HiiHandle, VarStorageData, IfrOpHdr, VarWidth, &BlockData);\r
+      if (EFI_ERROR (Status)) {\r
         goto Done;\r
       }\r
-      BlockData->Offset     = VarOffset;\r
-      BlockData->Width      = VarWidth;\r
-      BlockData->QuestionId = IfrPassword->Question.QuestionId;\r
-      BlockData->OpCode     = IfrOpHdr->OpCode;\r
-      InitializeListHead (&BlockData->DefaultValueEntry);\r
-      \r
-      //\r
-      // Add Block Data into VarStorageData BlockEntry\r
-      //\r
-      InsertBlockData (&VarStorageData->BlockEntry, &BlockData);\r
-      \r
+\r
       //\r
       // No default value for string.\r
       //\r
@@ -1790,7 +1922,7 @@ ParseIfrData (
       if (BlockData == NULL || BlockData->Scope == 0) {\r
         break;\r
       }\r
-      \r
+\r
       IfrOneOfOption = (EFI_IFR_ONE_OF_OPTION *) IfrOpHdr;\r
       if (BlockData->OpCode == EFI_IFR_ORDERED_LIST_OP) {\r
         //\r
@@ -1809,6 +1941,9 @@ ParseIfrData (
           // Invalid ordered list option data type.\r
           //\r
           Status = EFI_INVALID_PARAMETER;\r
+          if (BlockData->Name != NULL) {\r
+            FreePool (BlockData->Name);\r
+          }\r
           FreePool (BlockData);\r
           goto Done;\r
         }\r
@@ -1820,10 +1955,13 @@ ParseIfrData (
         //\r
         // Check whether this question is in requested block array.\r
         //\r
-        if (!BlockArrayCheck (RequestBlockArray, BlockData->Offset, BlockData->Width)) {\r
+        if (!BlockArrayCheck (RequestBlockArray, BlockData->Offset, BlockData->Width, BlockData->Name != NULL, HiiHandle)) {\r
           //\r
           // This question is not in the requested string. Skip it.\r
           //\r
+          if (BlockData->Name != NULL) {\r
+            FreePool (BlockData->Name);\r
+          }\r
           FreePool (BlockData);\r
           BlockData = NULL;\r
           break;\r
@@ -1831,8 +1969,11 @@ ParseIfrData (
         //\r
         // Check this var question is in the var storage \r
         //\r
-        if ((BlockData->Offset + BlockData->Width) > VarStorageData->Size) {\r
+        if ((BlockData->Name == NULL) && ((BlockData->Offset + BlockData->Width) > VarStorageData->Size)) {\r
           Status = EFI_INVALID_PARAMETER;\r
+          if (BlockData->Name != NULL) {\r
+            FreePool (BlockData->Name);\r
+          }\r
           FreePool (BlockData);\r
           goto Done;\r
         }\r
@@ -1860,7 +2001,7 @@ ParseIfrData (
         \r
         // Prepare new DefaultValue\r
         //\r
-        DefaultData.Type  = DefaultValueFromFlag;\r
+        DefaultData.Type     = DefaultValueFromFlag;\r
         CopyMem (&DefaultData.Value, &IfrOneOfOption->Value, IfrOneOfOption->Header.Length - OFFSET_OF (EFI_IFR_ONE_OF_OPTION, Value));\r
         if ((IfrOneOfOption->Flags & EFI_IFR_OPTION_DEFAULT) == EFI_IFR_OPTION_DEFAULT) {\r
           DefaultData.DefaultId = EFI_HII_DEFAULT_CLASS_STANDARD;\r
@@ -1870,10 +2011,8 @@ ParseIfrData (
           DefaultData.DefaultId = EFI_HII_DEFAULT_CLASS_MANUFACTURING;\r
           InsertDefaultValue (BlockData, &DefaultData);\r
         }\r
-\r
-        \r
       }\r
-      \r
+\r
       //\r
       // 2. Set as the default value when this is the first option.\r
       // The first oneof option value will be used as default value when no default value is specified. \r
@@ -1885,13 +2024,13 @@ ParseIfrData (
         //\r
         // Prepare new DefaultValue\r
         //        \r
-        DefaultData.Type        = DefaultValueFromDefault;\r
+        DefaultData.Type     = DefaultValueFromDefault;\r
         CopyMem (&DefaultData.Value, &IfrOneOfOption->Value, IfrOneOfOption->Header.Length - OFFSET_OF (EFI_IFR_ONE_OF_OPTION, Value));\r
         for (LinkData = DefaultIdArray->Entry.ForwardLink; LinkData != &DefaultIdArray->Entry; LinkData = LinkData->ForwardLink) {\r
           DefaultDataPtr = BASE_CR (LinkData, IFR_DEFAULT_DATA, Entry); \r
           DefaultData.DefaultId   = DefaultDataPtr->DefaultId;\r
           InsertDefaultValue (BlockData, &DefaultData);\r
-        }        \r
+        }\r
       }\r
       break;\r
 \r
@@ -1901,7 +2040,7 @@ ParseIfrData (
       //\r
       if (BlockData == NULL || BlockData->Scope == 0) {\r
         //\r
-        // No matched block data is ignored.        \r
+        // No matched block data is ignored.\r
         //\r
         break;\r
       }\r
@@ -1923,7 +2062,7 @@ ParseIfrData (
       DefaultData.Type        = DefaultValueFromOpcode;\r
       DefaultData.DefaultId   = VarDefaultId;\r
       CopyMem (&DefaultData.Value, &IfrDefault->Value, IfrDefault->Header.Length - OFFSET_OF (EFI_IFR_DEFAULT, Value));\r
-      \r
+\r
       // If the value field is expression, set the cleaned flag.\r
       if (IfrDefault->Type ==  EFI_IFR_TYPE_OTHER) {\r
         DefaultData.Cleaned = TRUE;\r
@@ -1932,7 +2071,7 @@ ParseIfrData (
       // Add DefaultValue into current BlockData\r
       //\r
       InsertDefaultValue (BlockData, &DefaultData);\r
-       \r
+\r
       //\r
       // After insert the default value, reset the cleaned value for next \r
       // time used. If not set here, need to set the value before everytime \r
@@ -1940,6 +2079,7 @@ ParseIfrData (
       //\r
       DefaultData.Cleaned     = FALSE;\r
       break;\r
+\r
     case EFI_IFR_END_OP:\r
       //\r
       // End Opcode is for Var question.\r
@@ -1948,6 +2088,7 @@ ParseIfrData (
         BlockData->Scope--;\r
       }\r
       break;\r
+\r
     default:\r
       if (BlockData != NULL && BlockData->Scope > 0) {\r
         BlockData->Scope = (UINT8) (BlockData->Scope + IfrOpHdr->Scope);\r
@@ -1971,40 +2112,734 @@ Done:
     }\r
   }\r
 \r
-  return Status;  \r
+  return Status;\r
 }\r
 \r
 /**\r
-  This function gets the full request string and full default value string by \r
-  parsing IFR data in HII form packages. \r
-  \r
-  When Request points to NULL string, the request string and default value string \r
-  for each varstore in form package will return. \r
+  parse the configrequest string, get the elements.\r
 \r
-  @param  DataBaseRecord         The DataBaseRecord instance contains the found Hii handle and package.\r
-  @param  DevicePath             Device Path which Hii Config Access Protocol is registered.\r
-  @param  Request                Pointer to a null-terminated Unicode string in\r
-                                 <ConfigRequest> format. When it doesn't contain\r
-                                 any RequestElement, it will be updated to return \r
-                                 the full RequestElement retrieved from IFR data.\r
-                                 If it points to NULL, the request string for the first\r
-                                 varstore in form package will be merged into a\r
-                                 <MultiConfigRequest> format string and return. \r
-  @param  AltCfgResp             Pointer to a null-terminated Unicode string in\r
-                                 <ConfigAltResp> format. When the pointer is to NULL,\r
-                                 the full default value string retrieved from IFR data\r
-                                 will return. When the pinter is to a string, the\r
-                                 full default value string retrieved from IFR data\r
-                                 will be merged into the input string and return.\r
-                                 When Request points to NULL, the default value string \r
-                                 for each varstore in form package will be merged into \r
-                                 a <MultiConfigAltResp> format string and return.\r
-  @param  PointerProgress        Optional parameter, it can be be NULL. \r
-                                 When it is not NULL, if Request is NULL, it returns NULL. \r
-                                 On return, points to a character in the Request\r
-                                 string. Points to the string's null terminator if\r
-                                 request was successful. Points to the most recent\r
-                                 & before the first failing name / value pair (or\r
+  @param      ConfigRequest         The input configrequest string.\r
+  @param      Progress              Return the progress data.\r
+\r
+  @retval     Block data pointer.\r
+**/\r
+IFR_BLOCK_DATA *\r
+GetBlockElement (\r
+  IN  EFI_STRING          ConfigRequest,\r
+  OUT EFI_STRING          *Progress\r
+  )\r
+{\r
+  EFI_STRING           StringPtr;\r
+  IFR_BLOCK_DATA       *BlockData;\r
+  IFR_BLOCK_DATA       *RequestBlockArray;\r
+  EFI_STATUS           Status;\r
+  UINT8                *TmpBuffer;\r
+  UINT16               Offset;\r
+  UINT16               Width;\r
+  LIST_ENTRY           *Link;\r
+  IFR_BLOCK_DATA       *NextBlockData;\r
+  UINTN                Length;\r
+\r
+  //\r
+  // Init RequestBlockArray\r
+  //\r
+  RequestBlockArray = (IFR_BLOCK_DATA *) AllocateZeroPool (sizeof (IFR_BLOCK_DATA));\r
+  if (RequestBlockArray == NULL) {\r
+    goto Done;\r
+  }\r
+  InitializeListHead (&RequestBlockArray->Entry);\r
+\r
+  //\r
+  // Get the request Block array from the request string\r
+  // Offset and Width\r
+  //\r
+\r
+  //\r
+  // Parse each <RequestElement> if exists\r
+  // Only <BlockName> format is supported by this help function.\r
+  // <BlockName> ::= &'OFFSET='<Number>&'WIDTH='<Number>\r
+  //\r
+  StringPtr = ConfigRequest;\r
+  while (*StringPtr != 0 && StrnCmp (StringPtr, L"&OFFSET=", StrLen (L"&OFFSET=")) == 0) {\r
+    //\r
+    // Skip the OFFSET string\r
+    //\r
+    *Progress   = StringPtr;\r
+    StringPtr += StrLen (L"&OFFSET=");\r
+    //\r
+    // Get Offset\r
+    //\r
+    Status = GetValueOfNumber (StringPtr, &TmpBuffer, &Length);\r
+    if (EFI_ERROR (Status)) {\r
+      goto Done;\r
+    }\r
+    Offset = 0;\r
+    CopyMem (\r
+      &Offset,\r
+      TmpBuffer,\r
+      (((Length + 1) / 2) < sizeof (UINT16)) ? ((Length + 1) / 2) : sizeof (UINT16)\r
+      );\r
+    FreePool (TmpBuffer);\r
+\r
+    StringPtr += Length;\r
+    if (StrnCmp (StringPtr, L"&WIDTH=", StrLen (L"&WIDTH=")) != 0) {\r
+      goto Done;\r
+    }\r
+    StringPtr += StrLen (L"&WIDTH=");\r
+\r
+    //\r
+    // Get Width\r
+    //\r
+    Status = GetValueOfNumber (StringPtr, &TmpBuffer, &Length);\r
+    if (EFI_ERROR (Status)) {\r
+      goto Done;\r
+    }\r
+    Width = 0;\r
+    CopyMem (\r
+      &Width,\r
+      TmpBuffer,\r
+      (((Length + 1) / 2) < sizeof (UINT16)) ? ((Length + 1) / 2) : sizeof (UINT16)\r
+      );\r
+    FreePool (TmpBuffer);\r
+\r
+    StringPtr += Length;\r
+    if (*StringPtr != 0 && *StringPtr != L'&') {\r
+      goto Done;\r
+    }\r
+    \r
+    //\r
+    // Set Block Data\r
+    //\r
+    BlockData = (IFR_BLOCK_DATA *) AllocateZeroPool (sizeof (IFR_BLOCK_DATA));\r
+    if (BlockData == NULL) {\r
+      goto Done;\r
+    }\r
+    BlockData->Offset = Offset;\r
+    BlockData->Width  = Width;\r
+    InsertBlockData (&RequestBlockArray->Entry, &BlockData);\r
+\r
+    //\r
+    // Skip &VALUE string if &VALUE does exists.\r
+    //\r
+    if (StrnCmp (StringPtr, L"&VALUE=", StrLen (L"&VALUE=")) == 0) {\r
+      StringPtr += StrLen (L"&VALUE=");\r
+\r
+      //\r
+      // Get Value\r
+      //\r
+      Status = GetValueOfNumber (StringPtr, &TmpBuffer, &Length);\r
+      if (EFI_ERROR (Status)) {\r
+        goto Done;\r
+      }\r
+\r
+      StringPtr += Length;\r
+      if (*StringPtr != 0 && *StringPtr != L'&') {\r
+        goto Done;\r
+      }\r
+    }\r
+    //\r
+    // If '\0', parsing is finished. \r
+    //\r
+    if (*StringPtr == 0) {\r
+      break;\r
+    }\r
+  }\r
+\r
+  //\r
+  // Merge the requested block data.\r
+  //\r
+  Link = RequestBlockArray->Entry.ForwardLink;\r
+  while ((Link != &RequestBlockArray->Entry) && (Link->ForwardLink != &RequestBlockArray->Entry)) {\r
+    BlockData = BASE_CR (Link, IFR_BLOCK_DATA, Entry);\r
+    NextBlockData = BASE_CR (Link->ForwardLink, IFR_BLOCK_DATA, Entry);\r
+    if ((NextBlockData->Offset >= BlockData->Offset) && (NextBlockData->Offset <= (BlockData->Offset + BlockData->Width))) {\r
+      if ((NextBlockData->Offset + NextBlockData->Width) > (BlockData->Offset + BlockData->Width)) {\r
+        BlockData->Width = (UINT16) (NextBlockData->Offset + NextBlockData->Width - BlockData->Offset);\r
+      }\r
+      RemoveEntryList (Link->ForwardLink);\r
+      FreePool (NextBlockData);\r
+      continue;\r
+    }\r
+    Link = Link->ForwardLink;\r
+  }\r
+\r
+  return RequestBlockArray;\r
+\r
+Done:\r
+  if (RequestBlockArray != NULL) {\r
+    //\r
+    // Free Link Array RequestBlockArray\r
+    //\r
+    while (!IsListEmpty (&RequestBlockArray->Entry)) {\r
+      BlockData = BASE_CR (RequestBlockArray->Entry.ForwardLink, IFR_BLOCK_DATA, Entry);\r
+      RemoveEntryList (&BlockData->Entry);\r
+      FreePool (BlockData);\r
+    }\r
+\r
+    FreePool (RequestBlockArray);\r
+  }\r
+\r
+  return NULL;\r
+}\r
+\r
+/**\r
+  parse the configrequest string, get the elements.\r
+\r
+  @param      ConfigRequest         The input config request string.\r
+  @param      Progress              Return the progress data.\r
+\r
+  @retval     return data block array.\r
+**/\r
+IFR_BLOCK_DATA *\r
+GetNameElement (\r
+  IN  EFI_STRING           ConfigRequest,\r
+  OUT EFI_STRING           *Progress\r
+  )\r
+{\r
+  EFI_STRING           StringPtr;\r
+  EFI_STRING           NextTag;\r
+  IFR_BLOCK_DATA       *BlockData;\r
+  IFR_BLOCK_DATA       *RequestBlockArray;\r
+  BOOLEAN              HasValue;\r
+\r
+  StringPtr = ConfigRequest;\r
+\r
+  //\r
+  // Init RequestBlockArray\r
+  //\r
+  RequestBlockArray = (IFR_BLOCK_DATA *) AllocateZeroPool (sizeof (IFR_BLOCK_DATA));\r
+  if (RequestBlockArray == NULL) {\r
+    goto Done;\r
+  }\r
+  InitializeListHead (&RequestBlockArray->Entry);\r
+\r
+  //\r
+  // Get the request Block array from the request string\r
+  //\r
+\r
+  //\r
+  // Parse each <RequestElement> if exists\r
+  // Only <BlockName> format is supported by this help function.\r
+  // <BlockName> ::= &'Name***=***\r
+  //\r
+  while (StringPtr != NULL && *StringPtr == L'&') {\r
+\r
+    *Progress   = StringPtr;\r
+    //\r
+    // Skip the L"&" string\r
+    //\r
+    StringPtr += 1;\r
+\r
+    HasValue = FALSE;\r
+    if ((NextTag = StrStr (StringPtr, L"=")) != NULL) {\r
+      *NextTag = L'\0';\r
+      HasValue = TRUE;\r
+    } else if ((NextTag = StrStr (StringPtr, L"&")) != NULL) {\r
+      *NextTag = L'\0';\r
+    }\r
+\r
+    //\r
+    // Set Block Data\r
+    //\r
+    BlockData = (IFR_BLOCK_DATA *) AllocateZeroPool (sizeof (IFR_BLOCK_DATA));\r
+    if (BlockData == NULL) {\r
+      goto Done;\r
+    }\r
+\r
+    //\r
+    // Get Name\r
+    //\r
+    BlockData->Name = AllocateCopyPool(StrSize (StringPtr), StringPtr);\r
+    InsertBlockData (&RequestBlockArray->Entry, &BlockData);\r
+\r
+    if (HasValue) {\r
+      //\r
+      // If has value, skip the value.\r
+      //    \r
+      StringPtr = NextTag + 1;\r
+      *NextTag  = L'=';\r
+      StringPtr = StrStr (StringPtr, L"&");\r
+    } else if (NextTag != NULL) {\r
+      //\r
+      // restore the '&' text.\r
+      //\r
+      StringPtr = NextTag;\r
+      *NextTag  = L'&';\r
+    }\r
+  }\r
+\r
+  return RequestBlockArray;\r
+\r
+Done:\r
+  if (RequestBlockArray != NULL) {\r
+    //\r
+    // Free Link Array RequestBlockArray\r
+    //\r
+    while (!IsListEmpty (&RequestBlockArray->Entry)) {\r
+      BlockData = BASE_CR (RequestBlockArray->Entry.ForwardLink, IFR_BLOCK_DATA, Entry);\r
+      RemoveEntryList (&BlockData->Entry);\r
+      if (BlockData->Name != NULL) {\r
+        FreePool (BlockData->Name);\r
+      }\r
+      FreePool (BlockData);\r
+    }\r
+\r
+    FreePool (RequestBlockArray);\r
+  }\r
+\r
+  return NULL;\r
+}\r
+\r
+/**\r
+  Generate ConfigRequest string base on the varstore info.\r
+\r
+  @param      ConfigHdr             The config header for this varstore.\r
+  @param      VarStorageData        The varstore info.\r
+  @param      Status                Return Status.\r
+  @param      ConfigRequest         The ConfigRequest info may be return.\r
+\r
+  @retval     TRUE                  Need to continue\r
+  @retval     Others                NO need to continue or error occur.\r
+**/\r
+BOOLEAN\r
+GenerateConfigRequest (\r
+  IN  CHAR16                       *ConfigHdr,\r
+  IN  IFR_VARSTORAGE_DATA          *VarStorageData,\r
+  OUT EFI_STATUS                   *Status,\r
+  IN OUT EFI_STRING                *ConfigRequest\r
+  )\r
+{\r
+  BOOLEAN               DataExist;\r
+  UINTN                 Length;\r
+  LIST_ENTRY            *Link;\r
+  CHAR16                *FullConfigRequest;\r
+  CHAR16                *StringPtr;\r
+  IFR_BLOCK_DATA        *BlockData;\r
+\r
+  //\r
+  // Append VarStorageData BlockEntry into *Request string\r
+  // Now support only one varstore in a form package.\r
+  //\r
+  \r
+  //\r
+  // Go through all VarStorageData Entry and get BlockEntry for each one for the multiple varstore in a single form package\r
+  // Then construct them all to return MultiRequest string : ConfigHdr BlockConfig\r
+  //\r
+  \r
+  //\r
+  // Compute the length of the entire request starting with <ConfigHdr> and a \r
+  // Null-terminator\r
+  //\r
+  DataExist = FALSE;\r
+  Length    = StrLen (ConfigHdr) + 1;\r
+\r
+  for (Link = VarStorageData->BlockEntry.ForwardLink; Link != &VarStorageData->BlockEntry; Link = Link->ForwardLink) {\r
+    DataExist = TRUE;\r
+    BlockData = BASE_CR (Link, IFR_BLOCK_DATA, Entry);\r
+    if (VarStorageData->Type == EFI_HII_VARSTORE_NAME_VALUE) {\r
+      //\r
+      // Add <BlockName> length for each Name\r
+      //\r
+      // <BlockName> ::= &Name1&Name2&... \r
+      //                 |1| StrLen(Name1)\r
+      //\r
+      Length = Length + (1 + StrLen (BlockData->Name));\r
+    } else {\r
+      //\r
+      // Add <BlockName> length for each Offset/Width pair\r
+      //\r
+      // <BlockName> ::= &OFFSET=1234&WIDTH=1234\r
+      //                 |  8   | 4 |   7  | 4 |\r
+      //\r
+      Length = Length + (8 + 4 + 7 + 4);\r
+    }\r
+  }\r
+  //\r
+  // No any request block data is found. The request string can't be constructed.\r
+  //\r
+  if (!DataExist) {\r
+    *Status = EFI_SUCCESS;\r
+    return FALSE;\r
+  }\r
+\r
+  //\r
+  // Allocate buffer for the entire <ConfigRequest>\r
+  //\r
+  FullConfigRequest = AllocateZeroPool (Length * sizeof (CHAR16));\r
+  if (FullConfigRequest == NULL) {\r
+    *Status = EFI_OUT_OF_RESOURCES;\r
+    return FALSE;\r
+  }\r
+  StringPtr = FullConfigRequest;\r
+\r
+  //\r
+  // Start with <ConfigHdr>\r
+  //\r
+  StrCpy (StringPtr, ConfigHdr);\r
+  StringPtr += StrLen (StringPtr);\r
+\r
+  //\r
+  // Loop through all the Offset/Width pairs and append them to ConfigRequest\r
+  //\r
+  for (Link = VarStorageData->BlockEntry.ForwardLink; Link != &VarStorageData->BlockEntry; Link = Link->ForwardLink) {\r
+    BlockData = BASE_CR (Link, IFR_BLOCK_DATA, Entry);\r
+    if (VarStorageData->Type == EFI_HII_VARSTORE_NAME_VALUE) {\r
+      //\r
+      // Append &Name1\0\r
+      //\r
+      UnicodeSPrint (\r
+        StringPtr,\r
+        (1 + StrLen (BlockData->Name) + 1) * sizeof (CHAR16),\r
+        L"&%s",\r
+        BlockData->Name\r
+      );\r
+    } else {\r
+      //\r
+      // Append &OFFSET=XXXX&WIDTH=YYYY\0\r
+      //\r
+      UnicodeSPrint (\r
+        StringPtr, \r
+        (8 + 4 + 7 + 4 + 1) * sizeof (CHAR16), \r
+        L"&OFFSET=%04X&WIDTH=%04X", \r
+        BlockData->Offset, \r
+        BlockData->Width\r
+      );\r
+    }\r
+    StringPtr += StrLen (StringPtr);\r
+  }\r
+  //\r
+  // Set to the got full request string.\r
+  //\r
+  HiiToLower (FullConfigRequest);\r
+\r
+  if (*ConfigRequest != NULL) {\r
+    FreePool (*ConfigRequest);\r
+  }\r
+  *ConfigRequest = FullConfigRequest;\r
+\r
+  return TRUE;\r
+}\r
+\r
+/**\r
+  Generate ConfigRequest Header base on the varstore info.\r
+\r
+  @param      VarStorageData        The varstore info.\r
+  @param      DevicePath            Device path for this varstore.\r
+  @param      ConfigHdr             The config header for this varstore.\r
+\r
+  @retval     EFI_SUCCESS           Generate the header success.\r
+  @retval     EFI_OUT_OF_RESOURCES  Allocate buffer fail.\r
+**/\r
+EFI_STATUS\r
+GenerateHdr (\r
+  IN   IFR_VARSTORAGE_DATA          *VarStorageData,\r
+  IN   EFI_DEVICE_PATH_PROTOCOL     *DevicePath,\r
+  OUT  EFI_STRING                   *ConfigHdr\r
+  )\r
+{\r
+  EFI_STRING                   GuidStr;\r
+  EFI_STRING                   NameStr;\r
+  EFI_STRING                   PathStr;\r
+  UINTN                        Length;\r
+  EFI_STATUS                   Status;\r
+\r
+  Status  = EFI_SUCCESS;\r
+  NameStr = NULL;\r
+  GuidStr = NULL;\r
+  PathStr = NULL;\r
+\r
+  //\r
+  // Construct <ConfigHdr> : "GUID=...&NAME=...&PATH=..." by VarStorageData Guid, Name and DriverHandle\r
+  //\r
+  GenerateSubStr (L"GUID=", sizeof (EFI_GUID), (VOID *) &VarStorageData->Guid, 1, &GuidStr);\r
+  if (VarStorageData->Name != NULL) {\r
+    GenerateSubStr (L"NAME=", StrLen (VarStorageData->Name) * sizeof (CHAR16), (VOID *) VarStorageData->Name, 2, &NameStr);\r
+  } else {\r
+    GenerateSubStr (L"NAME=", 0, NULL, 2, &NameStr);\r
+  }\r
+  GenerateSubStr (\r
+    L"PATH=",\r
+    GetDevicePathSize ((EFI_DEVICE_PATH_PROTOCOL *) DevicePath),\r
+    (VOID *) DevicePath,\r
+    1,\r
+    &PathStr\r
+    );\r
+  Length = StrLen (GuidStr) + StrLen (NameStr) + StrLen (PathStr) + 1;\r
+  if (VarStorageData->Name == NULL) {\r
+    Length += 1;\r
+  }\r
+\r
+  *ConfigHdr = AllocateZeroPool (Length * sizeof (CHAR16));\r
+  if (*ConfigHdr == NULL) {\r
+    Status = EFI_OUT_OF_RESOURCES;\r
+    goto Done;\r
+  }\r
+  StrCpy (*ConfigHdr, GuidStr);\r
+  StrCat (*ConfigHdr, NameStr);\r
+  if (VarStorageData->Name == NULL) {\r
+    StrCat (*ConfigHdr, L"&");\r
+  }\r
+  StrCat (*ConfigHdr, PathStr);\r
+\r
+  //\r
+  // Remove the last character L'&'\r
+  //\r
+  *(*ConfigHdr + StrLen (*ConfigHdr) - 1) = L'\0';\r
+\r
+Done:\r
+  if (GuidStr != NULL) {\r
+    FreePool (GuidStr);\r
+  }\r
+\r
+  if (NameStr != NULL) {\r
+    FreePool (NameStr);\r
+  }\r
+\r
+  if (PathStr != NULL) {\r
+    FreePool (PathStr);\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Get Data buffer size based on data type.\r
+\r
+  @param      ValueType             The input data type.\r
+\r
+  @retval     The data buffer size for the input type.\r
+**/\r
+UINT16\r
+GetStorageWidth (\r
+  IN UINT8       ValueType\r
+  )\r
+{\r
+  UINT16         StorageWidth;\r
+\r
+  switch (ValueType) {\r
+  case EFI_IFR_NUMERIC_SIZE_1:\r
+  case EFI_IFR_TYPE_BOOLEAN:\r
+    StorageWidth = (UINT16) sizeof (UINT8);\r
+    break;\r
+\r
+  case EFI_IFR_NUMERIC_SIZE_2:\r
+    StorageWidth = (UINT16) sizeof (UINT16);\r
+    break;\r
+\r
+  case EFI_IFR_NUMERIC_SIZE_4:\r
+    StorageWidth = (UINT16) sizeof (UINT32);\r
+    break;\r
+\r
+  case EFI_IFR_NUMERIC_SIZE_8:\r
+    StorageWidth = (UINT16) sizeof (UINT64);\r
+    break;\r
+\r
+  case EFI_IFR_TYPE_TIME:\r
+    StorageWidth = (UINT16) sizeof (EFI_IFR_TIME);\r
+    break;\r
+\r
+  case EFI_IFR_TYPE_DATE:\r
+    StorageWidth = (UINT16) sizeof (EFI_IFR_DATE);\r
+    break;\r
+\r
+  default:\r
+    StorageWidth = 0;\r
+    break;\r
+  }\r
+\r
+  return StorageWidth;\r
+}\r
+\r
+/**\r
+  Generate ConfigAltResp string base on the varstore info.\r
+\r
+  @param      ConfigHdr             The config header for this varstore.\r
+  @param      VarStorageData        The varstore info.\r
+  @param      DefaultIdArray        The Default id array.\r
+  @param      DefaultAltCfgResp     The DefaultAltCfgResp info may be return.\r
+\r
+  @retval     TRUE                  Need to continue\r
+  @retval     Others                NO need to continue or error occur.\r
+**/\r
+EFI_STATUS\r
+GenerateAltConfigResp (\r
+  IN  CHAR16                       *ConfigHdr,\r
+  IN  IFR_VARSTORAGE_DATA          *VarStorageData,\r
+  IN  IFR_DEFAULT_DATA             *DefaultIdArray,\r
+  IN OUT EFI_STRING                *DefaultAltCfgResp\r
+  )\r
+{\r
+  BOOLEAN               DataExist;\r
+  UINTN                 Length;\r
+  LIST_ENTRY            *Link;\r
+  LIST_ENTRY            *LinkData;\r
+  LIST_ENTRY            *LinkDefault;\r
+  LIST_ENTRY            *ListEntry;\r
+  CHAR16                *StringPtr;\r
+  IFR_BLOCK_DATA        *BlockData;\r
+  IFR_DEFAULT_DATA      *DefaultId;\r
+  IFR_DEFAULT_DATA      *DefaultValueData;\r
+  UINTN                 Width;\r
+  UINT8                 *TmpBuffer;\r
+\r
+  BlockData     = NULL;\r
+  DataExist     = FALSE;\r
+\r
+  //\r
+  // Add length for <ConfigHdr> + '\0'\r
+  //\r
+  Length = StrLen (ConfigHdr) + 1;\r
+\r
+  for (Link = DefaultIdArray->Entry.ForwardLink; Link != &DefaultIdArray->Entry; Link = Link->ForwardLink) {\r
+    DefaultId = BASE_CR (Link, IFR_DEFAULT_DATA, Entry);\r
+    //\r
+    // Add length for "&<ConfigHdr>&ALTCFG=XXXX"\r
+    //                |1| StrLen (ConfigHdr) | 8 | 4 |\r
+    //\r
+    Length += (1 + StrLen (ConfigHdr) + 8 + 4);\r
+    \r
+    for (LinkData = VarStorageData->BlockEntry.ForwardLink; LinkData != &VarStorageData->BlockEntry; LinkData = LinkData->ForwardLink) {\r
+      BlockData = BASE_CR (LinkData, IFR_BLOCK_DATA, Entry);\r
+      ListEntry     = &BlockData->DefaultValueEntry;\r
+      for (LinkDefault = ListEntry->ForwardLink; LinkDefault != ListEntry; LinkDefault = LinkDefault->ForwardLink) {\r
+        DefaultValueData = BASE_CR (LinkDefault, IFR_DEFAULT_DATA, Entry);\r
+        if (DefaultValueData->DefaultId != DefaultId->DefaultId) {\r
+          continue;\r
+        }\r
+        if (VarStorageData->Type == EFI_HII_VARSTORE_NAME_VALUE) {\r
+          //\r
+          // Add length for "&Name1=zzzzzzzzzzzz"\r
+          //                |1|Name|1|Value|\r
+          //\r
+          Length += (1 + StrLen (BlockData->Name) + 1 + BlockData->Width * 2);\r
+        } else {\r
+          //\r
+          // Add length for "&OFFSET=XXXX&WIDTH=YYYY&VALUE=zzzzzzzzzzzz"\r
+          //                |    8  | 4 |   7  | 4 |   7  | Width * 2 |\r
+          //\r
+          Length += (8 + 4 + 7 + 4 + 7 + BlockData->Width * 2);\r
+        }\r
+        DataExist = TRUE;\r
+      }\r
+    }\r
+  }\r
+  \r
+  //\r
+  // No default value is found. The default string doesn't exist.\r
+  //\r
+  if (!DataExist) {\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  //\r
+  // Allocate buffer for the entire <DefaultAltCfgResp>\r
+  //\r
+  *DefaultAltCfgResp = AllocateZeroPool (Length * sizeof (CHAR16));\r
+  if (*DefaultAltCfgResp == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+  StringPtr = *DefaultAltCfgResp;\r
+\r
+  //\r
+  // Start with <ConfigHdr>\r
+  //\r
+  StrCpy (StringPtr, ConfigHdr);\r
+  StringPtr += StrLen (StringPtr);\r
+\r
+  for (Link = DefaultIdArray->Entry.ForwardLink; Link != &DefaultIdArray->Entry; Link = Link->ForwardLink) {\r
+    DefaultId = BASE_CR (Link, IFR_DEFAULT_DATA, Entry);\r
+    //\r
+    // Add <AltConfigHdr> of the form "&<ConfigHdr>&ALTCFG=XXXX\0"\r
+    //                                |1| StrLen (ConfigHdr) | 8 | 4 |\r
+    //\r
+    UnicodeSPrint (\r
+      StringPtr, \r
+      (1 + StrLen (ConfigHdr) + 8 + 4 + 1) * sizeof (CHAR16), \r
+      L"&%s&ALTCFG=%04X", \r
+      ConfigHdr, \r
+      DefaultId->DefaultId\r
+      );\r
+    StringPtr += StrLen (StringPtr);\r
+\r
+    for (LinkData = VarStorageData->BlockEntry.ForwardLink; LinkData != &VarStorageData->BlockEntry; LinkData = LinkData->ForwardLink) {\r
+      BlockData = BASE_CR (LinkData, IFR_BLOCK_DATA, Entry);\r
+      ListEntry     = &BlockData->DefaultValueEntry;\r
+      for (LinkDefault = ListEntry->ForwardLink; LinkDefault != ListEntry; LinkDefault = LinkDefault->ForwardLink) {\r
+        DefaultValueData = BASE_CR (LinkDefault, IFR_DEFAULT_DATA, Entry);\r
+        if (DefaultValueData->DefaultId != DefaultId->DefaultId) {\r
+          continue;\r
+        }\r
+        if (VarStorageData->Type == EFI_HII_VARSTORE_NAME_VALUE) {\r
+          UnicodeSPrint (\r
+            StringPtr, \r
+            (1 + StrLen (ConfigHdr) + 1) * sizeof (CHAR16), \r
+            L"&%s=", \r
+            BlockData->Name\r
+            );\r
+          StringPtr += StrLen (StringPtr);\r
+        } else {\r
+          //\r
+          // Add <BlockConfig>\r
+          // <BlockConfig> ::= 'OFFSET='<Number>&'WIDTH='<Number>&'VALUE'=<Number>\r
+          //\r
+          UnicodeSPrint (\r
+            StringPtr, \r
+            (8 + 4 + 7 + 4 + 7 + 1) * sizeof (CHAR16),\r
+            L"&OFFSET=%04X&WIDTH=%04X&VALUE=", \r
+            BlockData->Offset, \r
+            BlockData->Width\r
+            );\r
+          StringPtr += StrLen (StringPtr);\r
+        }\r
+        Width = BlockData->Width;\r
+        //\r
+        // Convert Value to a hex string in "%x" format\r
+        // NOTE: This is in the opposite byte that GUID and PATH use\r
+        //\r
+        TmpBuffer = (UINT8 *) &(DefaultValueData->Value);\r
+        for (; Width > 0; Width--) {\r
+          StringPtr += UnicodeValueToString (StringPtr, PREFIX_ZERO | RADIX_HEX, TmpBuffer[Width - 1], 2);\r
+        }\r
+      }\r
+    }\r
+  }\r
+\r
+  HiiToLower (*DefaultAltCfgResp);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  This function gets the full request string and full default value string by \r
+  parsing IFR data in HII form packages. \r
+  \r
+  When Request points to NULL string, the request string and default value string \r
+  for each varstore in form package will return. \r
+\r
+  @param  DataBaseRecord         The DataBaseRecord instance contains the found Hii handle and package.\r
+  @param  DevicePath             Device Path which Hii Config Access Protocol is registered.\r
+  @param  Request                Pointer to a null-terminated Unicode string in\r
+                                 <ConfigRequest> format. When it doesn't contain\r
+                                 any RequestElement, it will be updated to return \r
+                                 the full RequestElement retrieved from IFR data.\r
+                                 If it points to NULL, the request string for the first\r
+                                 varstore in form package will be merged into a\r
+                                 <MultiConfigRequest> format string and return. \r
+  @param  AltCfgResp             Pointer to a null-terminated Unicode string in\r
+                                 <ConfigAltResp> format. When the pointer is to NULL,\r
+                                 the full default value string retrieved from IFR data\r
+                                 will return. When the pinter is to a string, the\r
+                                 full default value string retrieved from IFR data\r
+                                 will be merged into the input string and return.\r
+                                 When Request points to NULL, the default value string \r
+                                 for each varstore in form package will be merged into \r
+                                 a <MultiConfigAltResp> format string and return.\r
+  @param  PointerProgress        Optional parameter, it can be be NULL. \r
+                                 When it is not NULL, if Request is NULL, it returns NULL. \r
+                                 On return, points to a character in the Request\r
+                                 string. Points to the string's null terminator if\r
+                                 request was successful. Points to the most recent\r
+                                 & before the first failing name / value pair (or\r
                                  the beginning of the string if the failure is in\r
                                  the first name / value pair) if the request was\r
                                  not successful.\r
@@ -2032,26 +2867,14 @@ GetFullStringFromHiiFormPackages (
   UINTN                        PackageSize;\r
   IFR_BLOCK_DATA               *RequestBlockArray;\r
   IFR_BLOCK_DATA               *BlockData;\r
-  IFR_BLOCK_DATA               *NextBlockData;\r
   IFR_DEFAULT_DATA             *DefaultValueData;\r
   IFR_DEFAULT_DATA             *DefaultId;\r
   IFR_DEFAULT_DATA             *DefaultIdArray;\r
   IFR_VARSTORAGE_DATA          *VarStorageData;\r
   EFI_STRING                   DefaultAltCfgResp;\r
-  EFI_STRING                   FullConfigRequest;\r
   EFI_STRING                   ConfigHdr;\r
-  EFI_STRING                   GuidStr;\r
-  EFI_STRING                   NameStr;\r
-  EFI_STRING                   PathStr;\r
   EFI_STRING                   StringPtr;\r
   EFI_STRING                   Progress;\r
-  UINTN                        Length;\r
-  UINT8                        *TmpBuffer;\r
-  UINT16                       Offset;\r
-  UINT16                       Width;\r
-  LIST_ENTRY                   *Link;\r
-  LIST_ENTRY                   *LinkData;\r
-  LIST_ENTRY                   *LinkDefault;\r
   BOOLEAN                      DataExist;\r
 \r
   if (DataBaseRecord == NULL || DevicePath == NULL || Request == NULL || AltCfgResp == NULL) {\r
@@ -2065,11 +2888,7 @@ GetFullStringFromHiiFormPackages (
   DefaultIdArray    = NULL;\r
   VarStorageData    = NULL;\r
   DefaultAltCfgResp = NULL;\r
-  FullConfigRequest = NULL;\r
   ConfigHdr         = NULL;\r
-  GuidStr           = NULL;\r
-  NameStr           = NULL;\r
-  PathStr           = NULL;\r
   HiiFormPackage    = NULL;\r
   PackageSize       = 0;\r
   DataExist         = FALSE;\r
@@ -2109,414 +2928,105 @@ GetFullStringFromHiiFormPackages (
       Status = EFI_INVALID_PARAMETER;\r
       goto Done;\r
     }\r
-    StringPtr += StrLen (L"&PATH=");\r
-    while (*StringPtr != L'\0' && *StringPtr != L'&') {\r
-      StringPtr ++;\r
-    }\r
-    //\r
-    // Check the following string &OFFSET=\r
-    //\r
-    if (*StringPtr != L'\0' && StrnCmp (StringPtr, L"&OFFSET=", StrLen (L"&OFFSET=")) != 0) {\r
-      Progress = StringPtr;\r
-      Status   = EFI_INVALID_PARAMETER;\r
-      goto Done;\r
-    } else if (*StringPtr == L'\0') {\r
-      //\r
-      // No request block is found.\r
-      //\r
-      StringPtr = NULL;\r
-    }\r
-  }\r
-  if (StringPtr != NULL) {\r
-    //\r
-    // Init RequestBlockArray\r
-    //\r
-    RequestBlockArray = (IFR_BLOCK_DATA *) AllocateZeroPool (sizeof (IFR_BLOCK_DATA));\r
-    if (RequestBlockArray == NULL) {\r
-      Status = EFI_OUT_OF_RESOURCES;\r
-      goto Done;\r
-    }\r
-    InitializeListHead (&RequestBlockArray->Entry);\r
-\r
-    //\r
-    // Get the request Block array from the request string\r
-    // Offset and Width\r
-    //\r
-\r
-    //\r
-    // Parse each <RequestElement> if exists\r
-    // Only <BlockName> format is supported by this help function.\r
-    // <BlockName> ::= &'OFFSET='<Number>&'WIDTH='<Number>\r
-    //\r
-    while (*StringPtr != 0 && StrnCmp (StringPtr, L"&OFFSET=", StrLen (L"&OFFSET=")) == 0) {\r
-      //\r
-      // Skip the OFFSET string\r
-      //\r
-      Progress   = StringPtr;\r
-      StringPtr += StrLen (L"&OFFSET=");\r
-      //\r
-      // Get Offset\r
-      //\r
-      Status = GetValueOfNumber (StringPtr, &TmpBuffer, &Length);\r
-      if (EFI_ERROR (Status)) {\r
-        goto Done;\r
-      }\r
-      Offset = 0;\r
-      CopyMem (\r
-        &Offset,\r
-        TmpBuffer,\r
-        (((Length + 1) / 2) < sizeof (UINT16)) ? ((Length + 1) / 2) : sizeof (UINT16)\r
-        );\r
-      FreePool (TmpBuffer);\r
-  \r
-      StringPtr += Length;\r
-      if (StrnCmp (StringPtr, L"&WIDTH=", StrLen (L"&WIDTH=")) != 0) {\r
-        Status = EFI_INVALID_PARAMETER;\r
-        goto Done;\r
-      }\r
-      StringPtr += StrLen (L"&WIDTH=");\r
-  \r
-      //\r
-      // Get Width\r
-      //\r
-      Status = GetValueOfNumber (StringPtr, &TmpBuffer, &Length);\r
-      if (EFI_ERROR (Status)) {\r
-        goto Done;\r
-      }\r
-      Width = 0;\r
-      CopyMem (\r
-        &Width,\r
-        TmpBuffer,\r
-        (((Length + 1) / 2) < sizeof (UINT16)) ? ((Length + 1) / 2) : sizeof (UINT16)\r
-        );\r
-      FreePool (TmpBuffer);\r
-\r
-      StringPtr += Length;\r
-      if (*StringPtr != 0 && *StringPtr != L'&') {\r
-        Status = EFI_INVALID_PARAMETER;\r
-        goto Done;\r
-      }\r
-      \r
-      //\r
-      // Set Block Data\r
-      //\r
-      BlockData = (IFR_BLOCK_DATA *) AllocateZeroPool (sizeof (IFR_BLOCK_DATA));\r
-      if (BlockData == NULL) {\r
-        Status = EFI_OUT_OF_RESOURCES;\r
-        goto Done;\r
-      }\r
-      BlockData->Offset = Offset;\r
-      BlockData->Width  = Width;\r
-      InsertBlockData (&RequestBlockArray->Entry, &BlockData);\r
-      \r
-      //\r
-      // Skip &VALUE string if &VALUE does exists.\r
-      //\r
-      if (StrnCmp (StringPtr, L"&VALUE=", StrLen (L"&VALUE=")) == 0) {\r
-        StringPtr += StrLen (L"&VALUE=");\r
-\r
-        //\r
-        // Get Value\r
-        //\r
-        Status = GetValueOfNumber (StringPtr, &TmpBuffer, &Length);\r
-        if (EFI_ERROR (Status)) {\r
-          Status = EFI_INVALID_PARAMETER;\r
-          goto Done;\r
-        }\r
-\r
-        StringPtr += Length;\r
-        if (*StringPtr != 0 && *StringPtr != L'&') {\r
-          Status = EFI_INVALID_PARAMETER;\r
-          goto Done;\r
-        }\r
-      }\r
-      //\r
-      // If '\0', parsing is finished. \r
-      //\r
-      if (*StringPtr == 0) {\r
-        break;\r
-      }\r
-    }\r
-    \r
-    //\r
-    // Merge the requested block data.\r
-    //\r
-    Link = RequestBlockArray->Entry.ForwardLink;\r
-    while ((Link != &RequestBlockArray->Entry) && (Link->ForwardLink != &RequestBlockArray->Entry)) {\r
-      BlockData = BASE_CR (Link, IFR_BLOCK_DATA, Entry);\r
-      NextBlockData = BASE_CR (Link->ForwardLink, IFR_BLOCK_DATA, Entry);\r
-      if ((NextBlockData->Offset >= BlockData->Offset) && (NextBlockData->Offset <= (BlockData->Offset + BlockData->Width))) {\r
-        if ((NextBlockData->Offset + NextBlockData->Width) > (BlockData->Offset + BlockData->Width)) {\r
-          BlockData->Width = (UINT16) (NextBlockData->Offset + NextBlockData->Width - BlockData->Offset);\r
-        }\r
-        RemoveEntryList (Link->ForwardLink);\r
-        FreePool (NextBlockData);\r
-        continue;\r
-      }\r
-      Link = Link->ForwardLink;      \r
-    }\r
-  }\r
-  \r
-  //\r
-  // 2. Parse FormPackage to get BlockArray and DefaultId Array for the request BlockArray.\r
-  //\r
-\r
-  //\r
-  // Initialize DefaultIdArray to store the map between DeaultId and DefaultName\r
-  //\r
-  DefaultIdArray   = (IFR_DEFAULT_DATA *) AllocateZeroPool (sizeof (IFR_DEFAULT_DATA));\r
-  if (DefaultIdArray == NULL) {\r
-    Status = EFI_OUT_OF_RESOURCES;\r
-    goto Done;\r
-  }\r
-  InitializeListHead (&DefaultIdArray->Entry);\r
-\r
-  //\r
-  // Initialize VarStorageData to store the var store Block and Default value information.\r
-  //\r
-  VarStorageData = (IFR_VARSTORAGE_DATA *) AllocateZeroPool (sizeof (IFR_VARSTORAGE_DATA));\r
-  if (VarStorageData == NULL) {\r
-    Status = EFI_OUT_OF_RESOURCES;\r
-    goto Done;\r
-  }\r
-  InitializeListHead (&VarStorageData->Entry);\r
-  InitializeListHead (&VarStorageData->BlockEntry);\r
-\r
-  //\r
-  // Parse the opcode in form pacakge to get the default setting.\r
-  //\r
-  Status = ParseIfrData (HiiFormPackage, (UINT32) PackageSize, *Request, RequestBlockArray, VarStorageData, DefaultIdArray);\r
-  if (EFI_ERROR (Status)) {\r
-    goto Done;\r
-  }\r
-  \r
-  //\r
-  // No requested varstore in IFR data and directly return\r
-  //\r
-  if (VarStorageData->Size == 0) {\r
-    Status = EFI_SUCCESS;\r
-    goto Done;\r
-  }\r
-\r
-  //\r
-  // 3. Construct Request Element (Block Name) for 2.1 and 2.2 case.\r
-  //\r
-\r
-  //\r
-  // Construct <ConfigHdr> : "GUID=...&NAME=...&PATH=..." by VarStorageData Guid, Name and DriverHandle\r
-  //\r
-  GenerateSubStr (L"GUID=", sizeof (EFI_GUID), (VOID *) &VarStorageData->Guid, 1, &GuidStr);\r
-  GenerateSubStr (L"NAME=", StrLen (VarStorageData->Name) * sizeof (CHAR16), (VOID *) VarStorageData->Name, 2, &NameStr);\r
-  GenerateSubStr (\r
-    L"PATH=",\r
-    GetDevicePathSize ((EFI_DEVICE_PATH_PROTOCOL *) DevicePath),\r
-    (VOID *) DevicePath,\r
-    1,\r
-    &PathStr\r
-    );\r
-  Length = StrLen (GuidStr);\r
-  Length = Length + StrLen (NameStr);\r
-  Length = Length + StrLen (PathStr) + 1;\r
-  ConfigHdr = AllocateZeroPool (Length * sizeof (CHAR16));\r
-  if (ConfigHdr == NULL) {\r
-    Status = EFI_OUT_OF_RESOURCES;\r
-    goto Done;    \r
-  }\r
-  StrCpy (ConfigHdr, GuidStr);\r
-  StrCat (ConfigHdr, NameStr);\r
-  StrCat (ConfigHdr, PathStr);\r
-\r
-  //\r
-  // Remove the last character L'&'\r
-  //\r
-  *(ConfigHdr + StrLen (ConfigHdr) - 1) = L'\0';\r
-\r
-  if (RequestBlockArray == NULL) {\r
-    //\r
-    // Append VarStorageData BlockEntry into *Request string\r
-    // Now support only one varstore in a form package.\r
-    //\r
-\r
-    //\r
-    // Go through all VarStorageData Entry and get BlockEntry for each one for the multiple varstore in a single form package\r
-    // Then construct them all to return MultiRequest string : ConfigHdr BlockConfig\r
-    //\r
-\r
-    //\r
-    // Compute the length of the entire request starting with <ConfigHdr> and a \r
-    // Null-terminator\r
-    //\r
-    DataExist = FALSE;\r
-    Length    = StrLen (ConfigHdr) + 1;\r
-\r
-    for (Link = VarStorageData->BlockEntry.ForwardLink; Link != &VarStorageData->BlockEntry; Link = Link->ForwardLink) {\r
-      //\r
-      // Add <BlockName> length for each Offset/Width pair\r
-      //\r
-      // <BlockName> ::= &OFFSET=1234&WIDTH=1234\r
-      //                 |  8   | 4 |   7  | 4 |\r
-      //\r
-      DataExist = TRUE;\r
-      Length = Length + (8 + 4 + 7 + 4);\r
-    }\r
-    \r
-    //\r
-    // No any request block data is found. The request string can't be constructed.\r
-    //\r
-    if (!DataExist) {\r
-      Status = EFI_SUCCESS;\r
-      goto Done;\r
-    }\r
-\r
-    //\r
-    // Allocate buffer for the entire <ConfigRequest>\r
-    //\r
-    FullConfigRequest = AllocateZeroPool (Length * sizeof (CHAR16));\r
-    if (FullConfigRequest == NULL) {\r
-      Status = EFI_OUT_OF_RESOURCES;\r
-      goto Done;\r
+    StringPtr += StrLen (L"&PATH=");\r
+    while (*StringPtr != L'\0' && *StringPtr != L'&') {\r
+      StringPtr ++;\r
     }\r
-    StringPtr = FullConfigRequest;\r
-  \r
-    //\r
-    // Start with <ConfigHdr>\r
-    //\r
-    StrCpy (StringPtr, ConfigHdr);\r
-    StringPtr += StrLen (StringPtr);\r
 \r
-    //\r
-    // Loop through all the Offset/Width pairs and append them to ConfigRequest\r
-    //\r
-    for (Link = VarStorageData->BlockEntry.ForwardLink; Link != &VarStorageData->BlockEntry; Link = Link->ForwardLink) {\r
-      BlockData = BASE_CR (Link, IFR_BLOCK_DATA, Entry);\r
+    if (*StringPtr == L'\0') {\r
       //\r
-      // Append &OFFSET=XXXX&WIDTH=YYYY\0\r
+      // No request block is found.\r
       //\r
-      UnicodeSPrint (\r
-        StringPtr, \r
-        (8 + 4 + 7 + 4 + 1) * sizeof (CHAR16), \r
-        L"&OFFSET=%04X&WIDTH=%04X", \r
-        BlockData->Offset, \r
-        BlockData->Width\r
-      );\r
-      StringPtr += StrLen (StringPtr);\r
-    }\r
-    //\r
-    // Set to the got full request string.\r
-    //\r
-    HiiToLower (FullConfigRequest);\r
-    if (*Request != NULL) {\r
-      FreePool (*Request);\r
+      StringPtr = NULL;\r
     }\r
-    *Request = FullConfigRequest;\r
   }\r
-  \r
-  //\r
-  // 4. Construct Default Value string in AltResp according to request element.\r
-  // Go through all VarStorageData Entry and get the DefaultId array for each one\r
-  // Then construct them all to : ConfigHdr AltConfigHdr ConfigBody AltConfigHdr ConfigBody\r
-  //\r
-  DataExist = FALSE;\r
+\r
   //\r
-  // Add length for <ConfigHdr> + '\0'\r
+  // If StringPtr != NULL, get the request elements.\r
   //\r
-  Length = StrLen (ConfigHdr) + 1;\r
-  \r
-  for (Link = DefaultIdArray->Entry.ForwardLink; Link != &DefaultIdArray->Entry; Link = Link->ForwardLink) {\r
-    DefaultId = BASE_CR (Link, IFR_DEFAULT_DATA, Entry);\r
-    //\r
-    // Add length for "&<ConfigHdr>&ALTCFG=XXXX"\r
-    //                |1| StrLen (ConfigHdr) | 8 | 4 |\r
-    //\r
-    Length += (1 + StrLen (ConfigHdr) + 8 + 4);\r
-    \r
-    for (LinkData = VarStorageData->BlockEntry.ForwardLink; LinkData != &VarStorageData->BlockEntry; LinkData = LinkData->ForwardLink) {\r
-      BlockData = BASE_CR (LinkData, IFR_BLOCK_DATA, Entry);\r
-      for (LinkDefault = BlockData->DefaultValueEntry.ForwardLink; LinkDefault != &BlockData->DefaultValueEntry; LinkDefault = LinkDefault->ForwardLink) {\r
-        DefaultValueData = BASE_CR (LinkDefault, IFR_DEFAULT_DATA, Entry);\r
-        if (DefaultValueData->DefaultId == DefaultId->DefaultId) {\r
-          //\r
-          // Add length for "&OFFSET=XXXX&WIDTH=YYYY&VALUE=zzzzzzzzzzzz"\r
-          //                |    8  | 4 |   7  | 4 |   7  | Width * 2 |\r
-          //\r
-          Length += (8 + 4 + 7 + 4 + 7 + BlockData->Width * 2);\r
-          DataExist = TRUE;\r
-        }\r
-      }\r
+  if (StringPtr != NULL) {\r
+    if (StrStr (StringPtr, L"&OFFSET=") != NULL) {\r
+      RequestBlockArray = GetBlockElement(StringPtr, &Progress);\r
+    } else {\r
+      RequestBlockArray = GetNameElement(StringPtr, &Progress);\r
+    }\r
+\r
+    if (RequestBlockArray == NULL) {\r
+      Status = EFI_INVALID_PARAMETER;\r
+      goto Done;\r
     }\r
   }\r
-  \r
+\r
   //\r
-  // No default value is found. The default string doesn't exist.\r
+  // Initialize DefaultIdArray to store the map between DeaultId and DefaultName\r
   //\r
-  if (!DataExist) {\r
-    Status = EFI_SUCCESS;\r
+  DefaultIdArray   = (IFR_DEFAULT_DATA *) AllocateZeroPool (sizeof (IFR_DEFAULT_DATA));\r
+  if (DefaultIdArray == NULL) {\r
+    Status = EFI_OUT_OF_RESOURCES;\r
     goto Done;\r
   }\r
+  InitializeListHead (&DefaultIdArray->Entry);\r
 \r
   //\r
-  // Allocate buffer for the entire <DefaultAltCfgResp>\r
+  // Initialize VarStorageData to store the var store Block and Default value information.\r
   //\r
-  DefaultAltCfgResp = AllocateZeroPool (Length * sizeof (CHAR16));\r
-  if (DefaultAltCfgResp == NULL) {\r
+  VarStorageData = (IFR_VARSTORAGE_DATA *) AllocateZeroPool (sizeof (IFR_VARSTORAGE_DATA));\r
+  if (VarStorageData == NULL) {\r
     Status = EFI_OUT_OF_RESOURCES;\r
     goto Done;\r
   }\r
-  StringPtr = DefaultAltCfgResp;\r
+  InitializeListHead (&VarStorageData->Entry);\r
+  InitializeListHead (&VarStorageData->BlockEntry);\r
 \r
   //\r
-  // Start with <ConfigHdr>\r
+  // 2. Parse FormPackage to get BlockArray and DefaultId Array for the request BlockArray.\r
   //\r
-  StrCpy (StringPtr, ConfigHdr);\r
-  StringPtr += StrLen (StringPtr);\r
 \r
-  for (Link = DefaultIdArray->Entry.ForwardLink; Link != &DefaultIdArray->Entry; Link = Link->ForwardLink) {\r
-    DefaultId = BASE_CR (Link, IFR_DEFAULT_DATA, Entry);\r
-    //\r
-    // Add <AltConfigHdr> of the form "&<ConfigHdr>&ALTCFG=XXXX\0"\r
-    //                                |1| StrLen (ConfigHdr) | 8 | 4 |\r
-    //\r
-    UnicodeSPrint (\r
-      StringPtr, \r
-      (1 + StrLen (ConfigHdr) + 8 + 4 + 1) * sizeof (CHAR16), \r
-      L"&%s&ALTCFG=%04X", \r
-      ConfigHdr, \r
-      DefaultId->DefaultId\r
-      );\r
-    StringPtr += StrLen (StringPtr);\r
-    \r
-    for (LinkData = VarStorageData->BlockEntry.ForwardLink; LinkData != &VarStorageData->BlockEntry; LinkData = LinkData->ForwardLink) {\r
-      BlockData = BASE_CR (LinkData, IFR_BLOCK_DATA, Entry);\r
-      for (LinkDefault = BlockData->DefaultValueEntry.ForwardLink; LinkDefault != &BlockData->DefaultValueEntry; LinkDefault = LinkDefault->ForwardLink) {\r
-        DefaultValueData = BASE_CR (LinkDefault, IFR_DEFAULT_DATA, Entry);\r
-        if (DefaultValueData->DefaultId == DefaultId->DefaultId) {\r
-          //\r
-          // Add <BlockConfig>\r
-          // <BlockConfig> ::= 'OFFSET='<Number>&'WIDTH='<Number>&'VALUE'=<Number>\r
-          //\r
-          UnicodeSPrint (\r
-            StringPtr, \r
-            (8 + 4 + 7 + 4 + 7 + 1) * sizeof (CHAR16),\r
-            L"&OFFSET=%04X&WIDTH=%04X&VALUE=", \r
-            BlockData->Offset, \r
-            BlockData->Width\r
-            );\r
-          StringPtr += StrLen (StringPtr);\r
+  //\r
+  // Parse the opcode in form pacakge to get the default setting.\r
+  //\r
+  Status = ParseIfrData (DataBaseRecord->Handle,\r
+                         HiiFormPackage,\r
+                         (UINT32) PackageSize,\r
+                         *Request,\r
+                         RequestBlockArray,\r
+                         VarStorageData,\r
+                         DefaultIdArray);\r
+  if (EFI_ERROR (Status)) {\r
+    goto Done;\r
+  }\r
 \r
-          //\r
-          // Convert Value to a hex string in "%x" format\r
-          // NOTE: This is in the opposite byte that GUID and PATH use\r
-          //\r
-          Width     = BlockData->Width;\r
-          TmpBuffer = (UINT8 *) &(DefaultValueData->Value);\r
-          for (; Width > 0; Width--) {\r
-            StringPtr += UnicodeValueToString (StringPtr, PREFIX_ZERO | RADIX_HEX, TmpBuffer[Width - 1], 2);\r
-          }\r
-        }\r
-      }\r
+  //\r
+  // No requested varstore in IFR data and directly return\r
+  //\r
+  if (VarStorageData->VarStoreId == 0) {\r
+    Status = EFI_SUCCESS;\r
+    goto Done;\r
+  }\r
+\r
+  //\r
+  // 3. Construct Request Element (Block Name) for 2.1 and 2.2 case.\r
+  //\r
+  Status = GenerateHdr (VarStorageData, DevicePath, &ConfigHdr);\r
+  if (EFI_ERROR (Status)) {\r
+    goto Done;\r
+  }\r
+\r
+  if (RequestBlockArray == NULL) {\r
+    if (!GenerateConfigRequest(ConfigHdr, VarStorageData, &Status, Request)) {\r
+      goto Done;\r
     }\r
   }\r
-  HiiToLower (DefaultAltCfgResp);\r
+\r
+  //\r
+  // 4. Construct Default Value string in AltResp according to request element.\r
+  // Go through all VarStorageData Entry and get the DefaultId array for each one\r
+  // Then construct them all to : ConfigHdr AltConfigHdr ConfigBody AltConfigHdr ConfigBody\r
+  //\r
+  Status = GenerateAltConfigResp (ConfigHdr, VarStorageData, DefaultIdArray, &DefaultAltCfgResp);\r
+  if (EFI_ERROR (Status)) {\r
+    goto Done;\r
+  }\r
 \r
   //\r
   // 5. Merge string into the input AltCfgResp if the iput *AltCfgResp is not NULL.\r
@@ -2536,12 +3046,15 @@ Done:
     while (!IsListEmpty (&RequestBlockArray->Entry)) {\r
       BlockData = BASE_CR (RequestBlockArray->Entry.ForwardLink, IFR_BLOCK_DATA, Entry);\r
       RemoveEntryList (&BlockData->Entry);\r
+      if (BlockData->Name != NULL) {\r
+        FreePool (BlockData->Name);\r
+      }\r
       FreePool (BlockData);\r
     }\r
 \r
     FreePool (RequestBlockArray);\r
   }\r
-  \r
+\r
   if (VarStorageData != NULL) {\r
     //\r
     // Free link array VarStorageData\r
@@ -2549,6 +3062,9 @@ Done:
     while (!IsListEmpty (&VarStorageData->BlockEntry)) {\r
       BlockData = BASE_CR (VarStorageData->BlockEntry.ForwardLink, IFR_BLOCK_DATA, Entry);\r
       RemoveEntryList (&BlockData->Entry);\r
+      if (BlockData->Name != NULL) {\r
+        FreePool (BlockData->Name);\r
+      }\r
       //\r
       // Free default value link array\r
       //\r
@@ -2573,19 +3089,10 @@ Done:
     }\r
     FreePool (DefaultIdArray);\r
   }\r
-  \r
+\r
   //\r
   // Free the allocated string \r
   //\r
-  if (GuidStr != NULL) {\r
-    FreePool (GuidStr);\r
-  }\r
-  if (NameStr != NULL) {\r
-    FreePool (NameStr);\r
-  }\r
-  if (PathStr != NULL) {\r
-    FreePool (PathStr);\r
-  }\r
   if (ConfigHdr != NULL) {\r
     FreePool (ConfigHdr);\r
   }\r
@@ -2601,7 +3108,7 @@ Done:
     if (*Request == NULL) {\r
       *PointerProgress = NULL;\r
     } else if (EFI_ERROR (Status)) {\r
-      *PointerProgress = Progress;\r
+      *PointerProgress = *Request;\r
     } else {\r
       *PointerProgress = *Request + StrLen (*Request);\r
     }\r
@@ -2772,6 +3279,149 @@ Done:
   return Status;\r
 }\r
 \r
+/**\r
+  Validate the config request elements.\r
+\r
+  @param  ConfigElements                A null-terminated Unicode string in <ConfigRequest> format, \r
+                                        without configHdr field.\r
+\r
+  @retval     CHAR16 *    THE first Name/value pair not correct.\r
+  @retval     NULL        Success parse the name/value pair\r
+**/\r
+CHAR16 *\r
+OffsetWidthValidate (\r
+  CHAR16          *ConfigElements\r
+  )\r
+{\r
+  CHAR16    *StringPtr;\r
+  CHAR16    *RetVal;\r
+\r
+  StringPtr = ConfigElements;\r
+\r
+  while (1) {\r
+    RetVal    = StringPtr;\r
+    if (StrnCmp (StringPtr, L"&OFFSET=", StrLen (L"&OFFSET=")) != 0) {\r
+      return RetVal;\r
+    }\r
+\r
+    while (*StringPtr != L'\0' && StrnCmp (StringPtr, L"&WIDTH=", StrLen (L"&WIDTH=")) != 0) {\r
+      StringPtr++;\r
+    }\r
+    if (*StringPtr == L'\0') {\r
+      return RetVal;\r
+    }\r
+\r
+    StringPtr += StrLen (L"&WIDTH=");\r
+    while (*StringPtr != L'\0' && StrnCmp (StringPtr, L"&OFFSET=", StrLen (L"&OFFSET=")) != 0) {\r
+      StringPtr ++;\r
+    }\r
+\r
+    if (*StringPtr == L'\0') {\r
+      return NULL;\r
+    }\r
+  }\r
+}\r
+\r
+/**\r
+  Validate the config request elements.\r
+\r
+  @param  ConfigElements                A null-terminated Unicode string in <ConfigRequest> format, \r
+                                        without configHdr field.\r
+\r
+  @retval     CHAR16 *    THE first Name/value pair not correct.\r
+  @retval     NULL        Success parse the name/value pair\r
+\r
+**/\r
+CHAR16 *\r
+NameValueValidate (\r
+  CHAR16          *ConfigElements\r
+  )\r
+{\r
+  CHAR16    *StringPtr;\r
+  CHAR16    *RetVal;\r
+\r
+  StringPtr = ConfigElements;\r
+\r
+  while (1) {\r
+    RetVal = StringPtr;\r
+    if (*StringPtr != L'&') {\r
+      return RetVal;\r
+    }\r
+    StringPtr += 1;\r
+\r
+    StringPtr = StrStr (StringPtr, L"&");\r
+    \r
+    if (StringPtr == NULL) {\r
+      return NULL;\r
+    }\r
+  }\r
+}\r
+\r
+/**\r
+  Validate the config request string.\r
+\r
+  @param  ConfigRequest                A null-terminated Unicode string in <ConfigRequest> format.\r
+\r
+  @retval     CHAR16 *    THE first element not correct.\r
+  @retval     NULL        Success parse the name/value pair\r
+\r
+**/\r
+CHAR16 *\r
+ConfigRequestValidate (\r
+  CHAR16          *ConfigRequest\r
+  )\r
+{\r
+  BOOLEAN            HasNameField;\r
+  CHAR16             *StringPtr;\r
+\r
+  HasNameField = TRUE;\r
+  StringPtr    = ConfigRequest;\r
+\r
+  //\r
+  // Check <ConfigHdr>\r
+  //\r
+  if (StrnCmp (StringPtr, L"GUID=", StrLen (L"GUID=")) != 0) {\r
+    return ConfigRequest;\r
+  }\r
+  StringPtr += StrLen (L"GUID=");\r
+  while (*StringPtr != L'\0' && StrnCmp (StringPtr, L"&NAME=", StrLen (L"&NAME=")) != 0) {\r
+    StringPtr++;\r
+  }\r
+  if (*StringPtr == L'\0') {\r
+    return ConfigRequest;\r
+  }\r
+  StringPtr += StrLen (L"&NAME=");\r
+  if (*StringPtr == L'&') {\r
+    HasNameField = FALSE;\r
+  }\r
+  while (*StringPtr != L'\0' && StrnCmp (StringPtr, L"&PATH=", StrLen (L"&PATH=")) != 0) {\r
+    StringPtr++;\r
+  }\r
+  if (*StringPtr == L'\0') {\r
+    return ConfigRequest;\r
+  }\r
+  StringPtr += StrLen (L"&PATH=");\r
+  while (*StringPtr != L'\0' && *StringPtr != L'&') {\r
+    StringPtr ++;\r
+  }\r
+\r
+  if (*StringPtr == L'\0') {\r
+    return NULL;\r
+  }\r
+\r
+  if (HasNameField) {\r
+    //\r
+    // Should be Buffer varstore, config request should be "OFFSET/Width" pairs.\r
+    //\r
+    return OffsetWidthValidate(StringPtr);\r
+  } else {\r
+    //\r
+    // Should be Name/Value varstore, config request should be "&name1&name2..." pairs.\r
+    //\r
+    return NameValueValidate(StringPtr);\r
+  }\r
+}\r
+\r
 /**\r
   This function allows a caller to extract the current configuration\r
   for one or more named elements from one or more drivers.\r
@@ -2840,7 +3490,8 @@ HiiConfigRoutingExtractConfig (
   BOOLEAN                             FirstElement;\r
   BOOLEAN                             IfrDataParsedFlag;\r
   BOOLEAN                             IsEfiVarStore;\r
-  EFI_IFR_VARSTORE_EFI                *EfiVarStoreInfo; \r
+  EFI_IFR_VARSTORE_EFI                *EfiVarStoreInfo;\r
+  EFI_STRING                          ErrorPtr;\r
 \r
   if (This == NULL || Progress == NULL || Results == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
@@ -2958,12 +3609,22 @@ HiiConfigRoutingExtractConfig (
         goto Done;\r
       }\r
     }\r
-    \r
+\r
+    //\r
+    // Validate ConfigRequest String.\r
+    //\r
+    ErrorPtr = ConfigRequestValidate(ConfigRequest);\r
+    if (ErrorPtr != NULL) {\r
+      *Progress = StrStr (StringPtr, ErrorPtr);\r
+      Status = EFI_INVALID_PARAMETER;\r
+      goto Done;\r
+    }\r
+\r
     //\r
-    // Check whether ConfigRequest contains request string OFFSET/WIDTH\r
+    // Check whether ConfigRequest contains request string.\r
     //\r
     IfrDataParsedFlag = FALSE;\r
-    if ((HiiHandle != NULL) && (StrStr (ConfigRequest, L"&OFFSET=") == NULL)) {\r
+    if ((HiiHandle != NULL) && !GetElementsFromRequest(ConfigRequest)) {\r
       //\r
       // Get the full request string from IFR when HiiPackage is registered to HiiHandle \r
       //\r
@@ -2974,13 +3635,14 @@ HiiConfigRoutingExtractConfig (
         // AccessProgress indicates the parsing progress on <ConfigRequest>.\r
         // Map it to the progress on <MultiConfigRequest> then return it.\r
         //\r
+        ASSERT (AccessProgress != NULL);\r
         *Progress = StrStr (StringPtr, AccessProgress);\r
         goto Done;\r
       }\r
       //\r
       // Not any request block is found.\r
       //\r
-      if (StrStr (ConfigRequest, L"&OFFSET=") == NULL) {\r
+      if (!GetElementsFromRequest(ConfigRequest)) {\r
         AccessResults = AllocateCopyPool (StrSize (ConfigRequest), ConfigRequest);\r
         goto NextConfigString;\r
       }\r
@@ -2999,7 +3661,7 @@ HiiConfigRoutingExtractConfig (
       // Call the GetVariable function to extract settings.\r
       //\r
       Status = GetConfigRespFromEfiVarStore(This, EfiVarStoreInfo, ConfigRequest, &AccessResults, &AccessProgress);\r
-      FreePool (EfiVarStoreInfo);    \r
+      FreePool (EfiVarStoreInfo);\r
     } else {\r
       //\r
       // Call corresponding ConfigAccess protocol to extract settings\r
@@ -3051,7 +3713,7 @@ HiiConfigRoutingExtractConfig (
       DefaultResults = NULL;\r
     }\r
     \r
-NextConfigString:   \r
+NextConfigString:\r
     if (!FirstElement) {\r
       Status = AppendToMultiString (Results, L"&");\r
       ASSERT_EFI_ERROR (Status);\r
@@ -3262,7 +3924,7 @@ HiiConfigRoutingExportConfig (
         if (StringPtr != NULL) {\r
           *StringPtr = 0;\r
         }\r
-        if (StrStr (AccessResults, L"&OFFSET=") != NULL) {\r
+        if (GetElementsFromRequest (AccessResults)) {\r
           Status = GetFullStringFromHiiFormPackages (Database, DevicePath, &AccessResults, &DefaultResults, NULL);\r
           ASSERT_EFI_ERROR (Status);\r
         }\r
index 455dac3533f5660cf039520aa52150a36d632660..e5628b5bf04cdca1ad8b0b5f6455fbd3023d5625 100644 (file)
@@ -67,6 +67,7 @@ typedef struct {
   CHAR16              *Name;\r
   EFI_VARSTORE_ID     VarStoreId;\r
   UINT16              Size;\r
+  UINT8               Type;\r
   LIST_ENTRY          BlockEntry;        // Link to its Block array\r
 } IFR_VARSTORAGE_DATA;\r
 \r
@@ -78,6 +79,7 @@ typedef struct {
   UINT8               OpCode;\r
   UINT8               Scope;\r
   LIST_ENTRY          DefaultValueEntry; // Link to its default value array\r
+  CHAR16              *Name;\r
 } IFR_BLOCK_DATA;\r
 \r
 //\r
@@ -102,9 +104,10 @@ typedef struct {
 //\r
 // Storage types\r
 //\r
-#define EFI_HII_VARSTORE_BUFFER            0\r
-#define EFI_HII_VARSTORE_NAME_VALUE        1\r
-#define EFI_HII_VARSTORE_EFI_VARIABLE      2\r
+#define EFI_HII_VARSTORE_BUFFER              0\r
+#define EFI_HII_VARSTORE_NAME_VALUE          1\r
+#define EFI_HII_VARSTORE_EFI_VARIABLE        2\r
+#define EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER 3\r
 \r
 #define HII_FORMSET_STORAGE_SIGNATURE           SIGNATURE_32 ('H', 'S', 'T', 'G')\r
 typedef struct {\r