]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/HiiDatabaseDxe/ConfigRouting.c
MdeModulePkg: Replace [Ascii|Unicode]ValueToString
[mirror_edk2.git] / MdeModulePkg / Universal / HiiDatabaseDxe / ConfigRouting.c
index 24b6b24536071763f5f08df3caf1f180b7e50be1..c9ff1cff627f9cf49e1ac6976d00a131d1b472c6 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
 Implementation of interfaces function for EFI_HII_CONFIG_ROUTING_PROTOCOL.\r
 \r
-Copyright (c) 2007 - 2016, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2007 - 2017, Intel Corporation. All rights reserved.<BR>\r
 This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
 which accompanies this distribution.  The full text of the license may be found at\r
@@ -65,7 +65,7 @@ CalculateConfigStringLen (
 \r
   @retval EFI_NOT_FOUND          The device path is not invalid.\r
   @retval EFI_INVALID_PARAMETER  Any incoming parameter is invalid.\r
-  @retval EFI_OUT_OF_RESOURCES   Lake of resources to store neccesary structures.\r
+  @retval EFI_OUT_OF_RESOURCES   Lake of resources to store necessary structures.\r
   @retval EFI_SUCCESS            The device path is retrieved and translated to\r
                                  binary format.\r
 \r
@@ -264,7 +264,14 @@ GenerateSubStr (
     //\r
     TemBuffer = ((UINT8 *) Buffer);\r
     for (Index = 0; Index < BufferLen; Index ++, TemBuffer ++) {\r
-      TemString += UnicodeValueToString (TemString, PREFIX_ZERO | RADIX_HEX, *TemBuffer, 2);\r
+      UnicodeValueToStringS (\r
+        TemString,\r
+        sizeof (CHAR16) * (Length - StrnLenS (Str, Length)),\r
+        PREFIX_ZERO | RADIX_HEX,\r
+        *TemBuffer,\r
+        2\r
+        );\r
+      TemString += StrnLenS (TemString, Length - StrnLenS (Str, Length));\r
     }\r
     break;\r
   case 2:\r
@@ -277,7 +284,14 @@ GenerateSubStr (
     // Convert Unicode String to Config String, e.g. "ABCD" => "0041004200430044"\r
     //\r
     for (; *TemName != L'\0'; TemName++) {\r
-      TemString += UnicodeValueToString (TemString, PREFIX_ZERO | RADIX_HEX, *TemName, 4);\r
+      UnicodeValueToStringS (\r
+        TemString,\r
+        sizeof (CHAR16) * (Length - StrnLenS (Str, Length)),\r
+        PREFIX_ZERO | RADIX_HEX,\r
+        *TemName,\r
+        4\r
+        );\r
+      TemString += StrnLenS (TemString, Length - StrnLenS (Str, Length));\r
     }\r
     break;\r
   case 3:\r
@@ -286,7 +300,14 @@ GenerateSubStr (
     //\r
     TemBuffer = ((UINT8 *) Buffer) + BufferLen - 1;\r
     for (Index = 0; Index < BufferLen; Index ++, TemBuffer --) {\r
-      TemString += UnicodeValueToString (TemString, PREFIX_ZERO | RADIX_HEX, *TemBuffer, 2);\r
+      UnicodeValueToStringS (\r
+        TemString,\r
+        sizeof (CHAR16) * (Length - StrnLenS (Str, Length)),\r
+        PREFIX_ZERO | RADIX_HEX,\r
+        *TemBuffer,\r
+        2\r
+        );\r
+      TemString += StrnLenS (TemString, Length - StrnLenS (Str, Length));\r
     }\r
     break;\r
   default:\r
@@ -436,7 +457,7 @@ AppendToMultiString (
                                  to free memory.\r
   @param  Len                    Length of the <Number>, in characters.\r
 \r
-  @retval EFI_OUT_OF_RESOURCES   Insufficient resources to store neccessary\r
+  @retval EFI_OUT_OF_RESOURCES   Insufficient resources to store necessary\r
                                  structures.\r
   @retval EFI_SUCCESS            Value of <Number> is outputted in Number\r
                                  successfully.\r
@@ -518,7 +539,7 @@ Exit:
   @param  Found                  The Block whether has been found.\r
   @param  BufferLen              The length of the buffer.\r
 \r
-  @retval EFI_OUT_OF_RESOURCES   Insufficient resources to store neccessary structures.\r
+  @retval EFI_OUT_OF_RESOURCES   Insufficient resources to store necessary structures.\r
   @retval EFI_SUCCESS            The function finishes successfully.\r
 \r
 **/\r
@@ -549,6 +570,8 @@ FindSameBlockElement(
     ASSERT (TempBuffer != NULL);\r
     if ((BufferLen == Length) && (0 == CompareMem (Buffer, TempBuffer, Length))) {\r
       *Found = TRUE;\r
+      FreePool (TempBuffer);\r
+      TempBuffer = NULL;\r
       return EFI_SUCCESS;\r
     } else {\r
       FreePool (TempBuffer);\r
@@ -572,7 +595,7 @@ FindSameBlockElement(
   @param  AltConfigHdr           Pointer to a Unicode string in <AltConfigHdr> format.\r
   @param  ConfigAltRespChanged   Whether the ConfigAltResp has been changed.\r
 \r
-  @retval EFI_OUT_OF_RESOURCES   Insufficient resources to store neccessary structures.\r
+  @retval EFI_OUT_OF_RESOURCES   Insufficient resources to store necessary structures.\r
   @retval EFI_SUCCESS            The function finishes  successfully.\r
 \r
 **/\r
@@ -713,7 +736,7 @@ Exit:
   @param  AltConfigHdr           Pointer to a Unicode string in <AltConfigHdr> format.\r
   @param  ConfigAltRespChanged   Whether the ConfigAltResp has been changed.\r
 \r
-  @retval EFI_OUT_OF_RESOURCES   Insufficient resources to store neccessary structures.\r
+  @retval EFI_OUT_OF_RESOURCES   Insufficient resources to store necessary structures.\r
   @retval EFI_SUCCESS            The function finishes  successfully.\r
 \r
 **/\r
@@ -843,7 +866,7 @@ Exit:
                                  string for the different varstore buffer.\r
   @param  AltConfigHdr           Pointer to a Unicode string in <AltConfigHdr> format.\r
 \r
-  @retval EFI_OUT_OF_RESOURCES   Insufficient resources to store neccessary\r
+  @retval EFI_OUT_OF_RESOURCES   Insufficient resources to store necessary\r
                                  structures.\r
   @retval EFI_SUCCESS            The function finishes  successfully.\r
 \r
@@ -939,7 +962,7 @@ CompareAndMergeDefaultString (
   //\r
   // If the ConfigAltResp has no change,no need to update the content in AltCfgResp.\r
   //\r
-  if (ConfigAltRespChanged == FALSE) {\r
+  if (!ConfigAltRespChanged) {\r
     Status = EFI_SUCCESS;\r
     goto Exit;\r
   }\r
@@ -1019,7 +1042,7 @@ MergeDefaultString (
   }\r
   \r
   //\r
-  // Get the requestr ConfigHdr\r
+  // Get the request ConfigHdr\r
   //\r
   SizeAltCfgResp  = 0;\r
   StringPtr       = *AltCfgResp;\r
@@ -1149,8 +1172,9 @@ InsertDefaultValue (
     if (DefaultValueArray->DefaultId == DefaultValueData->DefaultId) {\r
       //\r
       // DEFAULT_VALUE_FROM_OPCODE has high priority, DEFAULT_VALUE_FROM_DEFAULT has low priority.\r
+      // When default types are DEFAULT_VALUE_FROM_OTHER_DEFAULT, the default value can be overrode.\r
       //\r
-      if (DefaultValueData->Type > DefaultValueArray->Type) {\r
+      if ((DefaultValueData->Type > DefaultValueArray->Type) || (DefaultValueData->Type == DefaultValueArray->Type && DefaultValueData->Type == DefaultValueFromOtherDefault)) {\r
         //\r
         // Update the default value array in BlockData.\r
         //\r
@@ -1246,9 +1270,9 @@ InsertBlockData (
   @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
+  @retval NULL   There are not enough resources available to retrieve the supported\r
                  languages.\r
-  @retval NULL   The list of suported languages could not be retrieved.\r
+  @retval NULL   The list of supported languages could not be retrieved.\r
   @retval Other  A pointer to the Null-terminated ASCII string of supported languages.\r
 \r
 **/\r
@@ -1602,6 +1626,7 @@ GetVarStoreType (
   UINTN                    PackageOffset;\r
   EFI_IFR_OP_HEADER        *IfrOpHdr;\r
   CHAR16                   *VarStoreName;\r
+  UINTN                    NameSize;\r
   EFI_STRING               GuidStr;\r
   EFI_STRING               NameStr;\r
   EFI_STRING               TempStr;\r
@@ -1656,12 +1681,13 @@ GetVarStoreType (
         continue;\r
       }\r
 \r
-      VarStoreName = AllocateZeroPool (AsciiStrSize ((CHAR8 *)IfrEfiVarStore->Name) * sizeof (CHAR16));\r
+      NameSize = AsciiStrSize ((CHAR8 *)IfrEfiVarStore->Name);\r
+      VarStoreName = AllocateZeroPool (NameSize * sizeof (CHAR16));\r
       if (VarStoreName == NULL) {\r
         Status = EFI_OUT_OF_RESOURCES;\r
         goto Done;\r
       }\r
-      AsciiStrToUnicodeStr ((CHAR8 *) IfrEfiVarStore->Name, VarStoreName);\r
+      AsciiStrToUnicodeStrS ((CHAR8 *) IfrEfiVarStore->Name, VarStoreName, NameSize);\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
@@ -1692,7 +1718,7 @@ GetVarStoreType (
       } \r
         \r
       //\r
-      // Free alllocated temp string.\r
+      // Free allocated temp string.\r
       //\r
       FreePool (VarStoreName);\r
       FreePool (GuidStr);\r
@@ -1750,8 +1776,8 @@ GetElementsFromRequest (
   @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
+  @retval  TRUE              This varstore is the request one.\r
+  @retval  FALSE             This varstore is not the request one.\r
                                  \r
 **/\r
 BOOLEAN\r
@@ -1820,8 +1846,8 @@ Done:
   @param  DataBaseRecord        The DataBaseRecord instance contains the found Hii handle and package.\r
   @param  ConfigHdr             Request string ConfigHdr. If it is NULL,\r
                                 the first found varstore will be as ConfigHdr.\r
-  @retval  TRUE                 This hii package is the reqeust one.\r
-  @retval  FALSE                This hii package is not the reqeust one.\r
+  @retval  TRUE                 This hii package is the request one.\r
+  @retval  FALSE                This hii package is not the request one.\r
 **/                                \r
 BOOLEAN\r
 IsThisPackageList (\r
@@ -1834,6 +1860,7 @@ IsThisPackageList (
   UINTN                    PackageOffset;\r
   EFI_IFR_OP_HEADER        *IfrOpHdr;\r
   CHAR16                   *VarStoreName;\r
+  UINTN                    NameSize;\r
   UINT8                    *HiiFormPackage;\r
   UINTN                    PackageSize;\r
   EFI_IFR_VARSTORE_EFI     *IfrEfiVarStore;\r
@@ -1878,29 +1905,37 @@ IsThisPackageList (
     case EFI_IFR_VARSTORE_OP:\r
       IfrVarStore = (EFI_IFR_VARSTORE *) IfrOpHdr;\r
 \r
-      VarStoreName = AllocateZeroPool (AsciiStrSize ((CHAR8 *)IfrVarStore->Name) * sizeof (CHAR16));\r
+      NameSize = AsciiStrSize ((CHAR8 *)IfrVarStore->Name);\r
+      VarStoreName = AllocateZeroPool (NameSize * sizeof (CHAR16));\r
       if (VarStoreName == NULL) {\r
         goto Done;\r
       }\r
-      AsciiStrToUnicodeStr ((CHAR8 *)IfrVarStore->Name, VarStoreName);\r
+      AsciiStrToUnicodeStrS ((CHAR8 *)IfrVarStore->Name, VarStoreName, NameSize);\r
 \r
       if (IsThisVarstore((VOID *)&IfrVarStore->Guid, VarStoreName, ConfigHdr)) {\r
         FindVarstore = TRUE;\r
         goto Done;\r
+      } else {\r
+        FreePool (VarStoreName);\r
+        VarStoreName = NULL;\r
       }\r
       break;\r
 \r
     case EFI_IFR_VARSTORE_EFI_OP:\r
       IfrEfiVarStore = (EFI_IFR_VARSTORE_EFI *) IfrOpHdr;\r
-      VarStoreName = AllocateZeroPool (AsciiStrSize ((CHAR8 *)IfrEfiVarStore->Name) * sizeof (CHAR16));\r
+      NameSize = AsciiStrSize ((CHAR8 *)IfrEfiVarStore->Name);\r
+      VarStoreName = AllocateZeroPool (NameSize * sizeof (CHAR16));\r
       if (VarStoreName == NULL) {\r
         goto Done;\r
       }\r
-      AsciiStrToUnicodeStr ((CHAR8 *)IfrEfiVarStore->Name, VarStoreName);\r
+      AsciiStrToUnicodeStrS ((CHAR8 *)IfrEfiVarStore->Name, VarStoreName, NameSize);\r
 \r
       if (IsThisVarstore (&IfrEfiVarStore->Guid, VarStoreName, ConfigHdr)) {\r
         FindVarstore = TRUE;\r
         goto Done;\r
+      } else {\r
+        FreePool (VarStoreName);\r
+        VarStoreName = NULL;\r
       }\r
       break;\r
 \r
@@ -1941,7 +1976,7 @@ Done:
 \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  VarStorageData         The varstore data structure.\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
@@ -2034,7 +2069,7 @@ IsThisOpcodeRequired (
 \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  PackageLength         Length of the package.\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
@@ -2042,7 +2077,7 @@ IsThisOpcodeRequired (
   @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
+  @retval EFI_INVALID_PARAMETER The varstore definition in the different form packages\r
                                 are conflicted. \r
   @retval EFI_OUT_OF_RESOURCES  No enough memory.\r
 **/\r
@@ -2078,6 +2113,7 @@ ParseIfrData (
   IFR_DEFAULT_DATA         *DefaultDataPtr;\r
   IFR_BLOCK_DATA           *BlockData;\r
   CHAR16                   *VarStoreName;\r
+  UINTN                    NameSize;\r
   UINT16                   VarWidth;\r
   UINT16                   VarDefaultId;\r
   BOOLEAN                  FirstOneOfOption;\r
@@ -2087,6 +2123,9 @@ ParseIfrData (
   EFI_IFR_VARSTORE_NAME_VALUE *IfrNameValueVarStore;\r
   EFI_HII_PACKAGE_HEADER   *PackageHeader;\r
   EFI_VARSTORE_ID          VarStoreId;\r
+  UINT16                   SmallestDefaultId;\r
+  BOOLEAN                  SmallestIdFromFlag;\r
+  BOOLEAN                  FromOtherDefaultOpcode;\r
 \r
   Status           = EFI_SUCCESS;\r
   BlockData        = NULL;\r
@@ -2094,7 +2133,10 @@ ParseIfrData (
   FirstOneOfOption = FALSE;\r
   VarStoreId       = 0;\r
   FirstOrderedList = FALSE;\r
+  VarStoreName     = NULL;\r
   ZeroMem (&DefaultData, sizeof (IFR_DEFAULT_DATA));\r
+  SmallestDefaultId = 0xFFFF;\r
+  FromOtherDefaultOpcode = FALSE;\r
 \r
   //\r
   // Go through the form package to parse OpCode one by one.\r
@@ -2135,12 +2177,13 @@ ParseIfrData (
 \r
       IfrVarStore = (EFI_IFR_VARSTORE *) IfrOpHdr;\r
 \r
-      VarStoreName = AllocateZeroPool (AsciiStrSize ((CHAR8 *)IfrVarStore->Name) * sizeof (CHAR16));\r
+      NameSize = AsciiStrSize ((CHAR8 *)IfrVarStore->Name);\r
+      VarStoreName = AllocateZeroPool (NameSize * sizeof (CHAR16));\r
       if (VarStoreName == NULL) {\r
         Status = EFI_OUT_OF_RESOURCES;\r
         goto Done;\r
       }\r
-      AsciiStrToUnicodeStr ((CHAR8 *)IfrVarStore->Name, VarStoreName);\r
+      AsciiStrToUnicodeStrS ((CHAR8 *)IfrVarStore->Name, VarStoreName, NameSize);\r
 \r
       if (IsThisVarstore((VOID *)&IfrVarStore->Guid, VarStoreName, ConfigHdr)) {\r
         //\r
@@ -2151,6 +2194,9 @@ ParseIfrData (
         VarStorageData->Name       = VarStoreName;\r
         VarStorageData->Type       = EFI_HII_VARSTORE_BUFFER;\r
         VarStoreId                 = IfrVarStore->VarStoreId;\r
+      } else {\r
+        FreePool (VarStoreName);\r
+        VarStoreName = NULL;\r
       }\r
       break;\r
 \r
@@ -2173,12 +2219,13 @@ ParseIfrData (
         break;\r
       }\r
 \r
-      VarStoreName = AllocateZeroPool (AsciiStrSize ((CHAR8 *)IfrEfiVarStore->Name) * sizeof (CHAR16));\r
+      NameSize = AsciiStrSize ((CHAR8 *)IfrEfiVarStore->Name);\r
+      VarStoreName = AllocateZeroPool (NameSize * sizeof (CHAR16));\r
       if (VarStoreName == NULL) {\r
         Status = EFI_OUT_OF_RESOURCES;\r
         goto Done;\r
       }\r
-      AsciiStrToUnicodeStr ((CHAR8 *)IfrEfiVarStore->Name, VarStoreName);\r
+      AsciiStrToUnicodeStrS ((CHAR8 *)IfrEfiVarStore->Name, VarStoreName, NameSize);\r
 \r
       if (IsThisVarstore (&IfrEfiVarStore->Guid, VarStoreName, ConfigHdr)) {\r
         //\r
@@ -2189,6 +2236,9 @@ ParseIfrData (
         VarStorageData->Name       = VarStoreName;\r
         VarStorageData->Type       = EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER;\r
         VarStoreId                 = IfrEfiVarStore->VarStoreId;\r
+      } else {\r
+        FreePool (VarStoreName);\r
+        VarStoreName = NULL;\r
       }\r
       break;\r
 \r
@@ -2452,6 +2502,8 @@ ParseIfrData (
       //\r
       ASSERT (BlockData != NULL);\r
 \r
+      SmallestIdFromFlag = FALSE;\r
+\r
       //\r
       // Add default value for standard ID by CheckBox Flag\r
       //\r
@@ -2462,21 +2514,20 @@ ParseIfrData (
       DefaultData.DefaultId   = VarDefaultId;\r
       if ((IfrCheckBox->Flags & EFI_IFR_CHECKBOX_DEFAULT) == EFI_IFR_CHECKBOX_DEFAULT) {\r
         //\r
-        // When flag is set, defautl value is TRUE.\r
+        // When flag is set, default value is TRUE.\r
         //\r
         DefaultData.Type    = DefaultValueFromFlag;\r
         DefaultData.Value.b = TRUE;\r
-      } else {\r
-        //\r
-        // When flag is not set, defautl value is FASLE.\r
-        //\r
-        DefaultData.Type    = DefaultValueFromDefault;\r
-        DefaultData.Value.b = FALSE;\r
+        InsertDefaultValue (BlockData, &DefaultData);\r
+\r
+        if (SmallestDefaultId > EFI_HII_DEFAULT_CLASS_STANDARD) {\r
+          //\r
+          // Record the SmallestDefaultId and update the SmallestIdFromFlag.\r
+          //\r
+          SmallestDefaultId = EFI_HII_DEFAULT_CLASS_STANDARD;\r
+          SmallestIdFromFlag = TRUE;\r
+        }\r
       }\r
-      //\r
-      // Add DefaultValue into current BlockData\r
-      //\r
-      InsertDefaultValue (BlockData, &DefaultData);\r
 \r
       //\r
       // Add default value for Manufacture ID by CheckBox Flag\r
@@ -2488,21 +2539,49 @@ ParseIfrData (
       DefaultData.DefaultId   = VarDefaultId;\r
       if ((IfrCheckBox->Flags & EFI_IFR_CHECKBOX_DEFAULT_MFG) == EFI_IFR_CHECKBOX_DEFAULT_MFG) {\r
         //\r
-        // When flag is set, defautl value is TRUE.\r
+        // When flag is set, default value is TRUE.\r
         //\r
         DefaultData.Type    = DefaultValueFromFlag;\r
         DefaultData.Value.b = TRUE;\r
+        InsertDefaultValue (BlockData, &DefaultData);\r
+\r
+        if (SmallestDefaultId > EFI_HII_DEFAULT_CLASS_MANUFACTURING) {\r
+          //\r
+          // Record the SmallestDefaultId and update the SmallestIdFromFlag.\r
+          //\r
+          SmallestDefaultId = EFI_HII_DEFAULT_CLASS_MANUFACTURING;\r
+          SmallestIdFromFlag = TRUE;\r
+        }\r
+      }\r
+      if (SmallestIdFromFlag) {\r
+        //\r
+        // When smallest default Id is given by the  flag of CheckBox, set default value with TRUE for other default Id in the DefaultId list.\r
+        //\r
+        DefaultData.Type    = DefaultValueFromOtherDefault;\r
+        DefaultData.Value.b = TRUE;\r
+        //\r
+        // Set default value for all the default id in the DefaultId list.\r
+        //\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
       } else {\r
         //\r
-        // When flag is not set, defautl value is FASLE.\r
+        // When flag is not set, default value is FASLE.\r
         //\r
         DefaultData.Type    = DefaultValueFromDefault;\r
         DefaultData.Value.b = FALSE;\r
+        //\r
+        // Set default value for all the default id in the DefaultId list.\r
+        //\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
-      // Add DefaultValue into current BlockData\r
-      //\r
-      InsertDefaultValue (BlockData, &DefaultData);\r
       break;\r
 \r
     case EFI_IFR_DATE_OP:\r
@@ -2756,6 +2835,7 @@ ParseIfrData (
 \r
       //\r
       // 1. Set default value for OneOf option when flag field has default attribute.\r
+      //    And set the default value with the smallest default id for other default id in the DefaultId list.\r
       //\r
       if (((IfrOneOfOption->Flags & EFI_IFR_OPTION_DEFAULT) == EFI_IFR_OPTION_DEFAULT) ||\r
           ((IfrOneOfOption->Flags & EFI_IFR_OPTION_DEFAULT_MFG) == EFI_IFR_OPTION_DEFAULT_MFG)) {\r
@@ -2764,6 +2844,8 @@ ParseIfrData (
         // The first oneof option value will be used as default value when no default value is specified. \r
         //\r
         FirstOneOfOption = FALSE;\r
+\r
+        SmallestIdFromFlag = FALSE;\r
         \r
         // Prepare new DefaultValue\r
         //\r
@@ -2772,10 +2854,39 @@ ParseIfrData (
         if ((IfrOneOfOption->Flags & EFI_IFR_OPTION_DEFAULT) == EFI_IFR_OPTION_DEFAULT) {\r
           DefaultData.DefaultId = EFI_HII_DEFAULT_CLASS_STANDARD;\r
           InsertDefaultValue (BlockData, &DefaultData);\r
-        } \r
+          if (SmallestDefaultId > EFI_HII_DEFAULT_CLASS_STANDARD) {\r
+            //\r
+            // Record the SmallestDefaultId and update the SmallestIdFromFlag.\r
+            //\r
+            SmallestDefaultId = EFI_HII_DEFAULT_CLASS_STANDARD;\r
+            SmallestIdFromFlag = TRUE;\r
+          }\r
+        }\r
         if ((IfrOneOfOption->Flags & EFI_IFR_OPTION_DEFAULT_MFG) == EFI_IFR_OPTION_DEFAULT_MFG) {\r
           DefaultData.DefaultId = EFI_HII_DEFAULT_CLASS_MANUFACTURING;\r
           InsertDefaultValue (BlockData, &DefaultData);\r
+          if (SmallestDefaultId > EFI_HII_DEFAULT_CLASS_MANUFACTURING) {\r
+            //\r
+            // Record the SmallestDefaultId and update the SmallestIdFromFlag.\r
+            //\r
+            SmallestDefaultId = EFI_HII_DEFAULT_CLASS_MANUFACTURING;\r
+            SmallestIdFromFlag = TRUE;\r
+          }\r
+        }\r
+\r
+        if (SmallestIdFromFlag) {\r
+          //\r
+          // When smallest default Id is given by the flag of oneofOption, set this option value for other default Id in the DefaultId list.\r
+          //\r
+          DefaultData.Type = DefaultValueFromOtherDefault;\r
+          //\r
+          // Set default value for other default id in the DefaultId list.\r
+          //\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
 \r
@@ -2833,8 +2944,27 @@ ParseIfrData (
       InsertDefaultValue (BlockData, &DefaultData);\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
+      // Set default value for other default id in the DefaultId list.\r
+      // when SmallestDefaultId == VarDefaultId means there are two defaults with same default Id.\r
+      // If the two defaults are both from default opcode, use the first default as the default value of other default Id.\r
+      // If one from flag and the other form default opcode, use the default opcode value as the default value of other default Id.\r
+      //\r
+      if ((SmallestDefaultId > VarDefaultId) || (SmallestDefaultId == VarDefaultId && !FromOtherDefaultOpcode)) {\r
+        FromOtherDefaultOpcode = TRUE;\r
+        SmallestDefaultId = VarDefaultId;\r
+        for (LinkData = DefaultIdArray->Entry.ForwardLink; LinkData != &DefaultIdArray->Entry; LinkData = LinkData->ForwardLink) {\r
+          DefaultDataPtr = BASE_CR (LinkData, IFR_DEFAULT_DATA, Entry);\r
+          if (DefaultDataPtr->DefaultId != DefaultData.DefaultId){\r
+            DefaultData.Type        = DefaultValueFromOtherDefault;\r
+            DefaultData.DefaultId   = DefaultDataPtr->DefaultId;\r
+            InsertDefaultValue (BlockData, &DefaultData);\r
+          }\r
+        }\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 every time.\r
       // use it.\r
       //\r
       DefaultData.Cleaned     = FALSE;\r
@@ -2850,6 +2980,11 @@ ParseIfrData (
         }\r
         if (BlockData->Scope == 0) {\r
           BlockData = NULL;\r
+          //\r
+          // when finishing parsing a question, clean the SmallestDefaultId and GetDefaultFromDefaultOpcode.\r
+          //\r
+          SmallestDefaultId = 0xFFFF;\r
+          FromOtherDefaultOpcode = FALSE;\r
         }\r
       }\r
 \r
@@ -3014,7 +3149,7 @@ GetBlockElement (
       if (EFI_ERROR (Status)) {\r
         goto Done;\r
       }\r
-\r
+      FreePool (TmpBuffer);\r
       StringPtr += Length;\r
       if (*StringPtr != 0 && *StringPtr != L'&') {\r
         goto Done;\r
@@ -3467,6 +3602,7 @@ GenerateAltConfigResp (
   UINTN                 Width;\r
   UINT8                 *TmpBuffer;\r
   CHAR16                *DefaultString;\r
+  UINTN                 StrSize;\r
 \r
   BlockData     = NULL;\r
   DataExist     = FALSE;\r
@@ -3584,17 +3720,36 @@ GenerateAltConfigResp (
         //\r
         if (BlockData->OpCode == EFI_IFR_STRING_OP){\r
           DefaultString   = InternalGetString(HiiHandle, DefaultValueData->Value.string);\r
-          TmpBuffer = (UINT8 *) DefaultString;\r
+          TmpBuffer = AllocateZeroPool (Width);\r
+          ASSERT (TmpBuffer != NULL);\r
+          if (DefaultString != NULL) {\r
+            StrSize = StrLen(DefaultString)* sizeof (CHAR16);\r
+            if (StrSize > Width) {\r
+              StrSize = Width;\r
+            }\r
+            CopyMem (TmpBuffer, (UINT8 *) DefaultString, StrSize);\r
+          }\r
         } else {\r
           TmpBuffer = (UINT8 *) &(DefaultValueData->Value);\r
         }\r
         for (; Width > 0 && (TmpBuffer != NULL); Width--) {\r
-          StringPtr += UnicodeValueToString (StringPtr, PREFIX_ZERO | RADIX_HEX, TmpBuffer[Width - 1], 2);\r
+          UnicodeValueToStringS (\r
+            StringPtr,\r
+            Length * sizeof (CHAR16) - ((UINTN)StringPtr - (UINTN)*DefaultAltCfgResp),\r
+            PREFIX_ZERO | RADIX_HEX,\r
+            TmpBuffer[Width - 1],\r
+            2\r
+            );\r
+          StringPtr += StrnLenS (StringPtr, Length - ((UINTN)StringPtr - (UINTN)*DefaultAltCfgResp) / sizeof (CHAR16));\r
         }\r
         if (DefaultString != NULL){\r
           FreePool(DefaultString);\r
           DefaultString = NULL;\r
         }\r
+        if (BlockData->OpCode == EFI_IFR_STRING_OP && TmpBuffer != NULL) {\r
+          FreePool(TmpBuffer);\r
+          TmpBuffer  = NULL;\r
+        }\r
       }\r
     }\r
   }\r
@@ -3629,7 +3784,7 @@ GenerateAltConfigResp (
                                  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
+  @param  PointerProgress        Optional parameter, it can 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
@@ -3693,7 +3848,7 @@ GetFullStringFromHiiFormPackages (
   }\r
 \r
   //\r
-  // 1. Get the request block array by Request String when Request string containts the block array.\r
+  // 1. Get the request block array by Request String when Request string contains the block array.\r
   //\r
   StringPtr = NULL;\r
   if (*Request != NULL) {\r
@@ -3776,7 +3931,7 @@ GetFullStringFromHiiFormPackages (
   //\r
 \r
   //\r
-  // Parse the opcode in form pacakge to get the default setting.\r
+  // Parse the opcode in form package to get the default setting.\r
   //\r
   Status = ParseIfrData (DataBaseRecord->Handle,\r
                          HiiFormPackage,\r
@@ -3822,7 +3977,7 @@ GetFullStringFromHiiFormPackages (
   }\r
 \r
   //\r
-  // 5. Merge string into the input AltCfgResp if the iput *AltCfgResp is not NULL.\r
+  // 5. Merge string into the input AltCfgResp if the input *AltCfgResp is not NULL.\r
   //\r
   if (*AltCfgResp != NULL && DefaultAltCfgResp != NULL) {\r
     Status = MergeDefaultString (AltCfgResp, DefaultAltCfgResp);\r
@@ -3868,6 +4023,10 @@ Done:
       }\r
       FreePool (BlockData);\r
     }\r
+    if (VarStorageData ->Name != NULL) {\r
+      FreePool (VarStorageData ->Name);\r
+      VarStorageData ->Name = NULL;\r
+    }\r
     FreePool (VarStorageData);\r
   }\r
 \r
@@ -3891,7 +4050,7 @@ Done:
   }\r
 \r
   //\r
-  // Free Pacakge data\r
+  // Free Package data\r
   //\r
   if (HiiFormPackage != NULL) {\r
     FreePool (HiiFormPackage);\r
@@ -3947,6 +4106,7 @@ GetConfigRespFromEfiVarStore (
 {\r
   EFI_STATUS Status;\r
   EFI_STRING VarStoreName;\r
+  UINTN      NameSize;\r
   UINT8      *VarStore;\r
   UINTN      BufferSize;\r
 \r
@@ -3955,13 +4115,14 @@ GetConfigRespFromEfiVarStore (
   VarStore        = NULL;\r
   VarStoreName    = NULL;\r
   *AccessProgress = Request;\r
-  \r
-  VarStoreName = AllocateZeroPool (AsciiStrSize ((CHAR8 *)EfiVarStoreInfo->Name) * sizeof (CHAR16));\r
+\r
+  NameSize = AsciiStrSize ((CHAR8 *)EfiVarStoreInfo->Name);\r
+  VarStoreName = AllocateZeroPool (NameSize * sizeof (CHAR16));\r
   if (VarStoreName == NULL) {\r
     Status = EFI_OUT_OF_RESOURCES;\r
     goto Done;\r
   }\r
-  AsciiStrToUnicodeStr ((CHAR8 *) EfiVarStoreInfo->Name, VarStoreName);\r
+  AsciiStrToUnicodeStrS ((CHAR8 *) EfiVarStoreInfo->Name, VarStoreName, NameSize);\r
    \r
   \r
   Status = gRT->GetVariable (VarStoreName, &EfiVarStoreInfo->Guid, NULL, &BufferSize, NULL);\r
@@ -4022,6 +4183,7 @@ RouteConfigRespForEfiVarStore (
 {\r
   EFI_STATUS Status;\r
   EFI_STRING VarStoreName;\r
+  UINTN      NameSize;\r
   UINT8      *VarStore;\r
   UINTN      BufferSize;\r
   UINTN      BlockSize;\r
@@ -4030,16 +4192,19 @@ RouteConfigRespForEfiVarStore (
   BufferSize   = 0;\r
   VarStore     = NULL;\r
   VarStoreName = NULL;\r
+  *Result = RequestResp;\r
 \r
-  VarStoreName = AllocateZeroPool (AsciiStrSize ((CHAR8 *)EfiVarStoreInfo->Name) * sizeof (CHAR16));\r
+  NameSize = AsciiStrSize ((CHAR8 *)EfiVarStoreInfo->Name);\r
+  VarStoreName = AllocateZeroPool (NameSize * sizeof (CHAR16));\r
   if (VarStoreName == NULL) {\r
     Status = EFI_OUT_OF_RESOURCES;\r
     goto Done;\r
   }\r
-  AsciiStrToUnicodeStr ((CHAR8 *) EfiVarStoreInfo->Name, VarStoreName);\r
+  AsciiStrToUnicodeStrS ((CHAR8 *) EfiVarStoreInfo->Name, VarStoreName, NameSize);\r
       \r
   Status = gRT->GetVariable (VarStoreName, &EfiVarStoreInfo->Guid, NULL, &BufferSize, NULL);\r
   if (Status != EFI_BUFFER_TOO_SMALL) {\r
+    DEBUG ((DEBUG_ERROR, "The variable does not exist!"));\r
     goto Done;\r
   }\r
 \r
@@ -4058,6 +4223,7 @@ RouteConfigRespForEfiVarStore (
 \r
   Status = gRT->SetVariable (VarStoreName, &EfiVarStoreInfo->Guid, EfiVarStoreInfo->Attributes, BufferSize, VarStore);\r
   if (EFI_ERROR (Status)) {\r
+    *Result = RequestResp;\r
     goto Done;\r
   }\r
 \r
@@ -4550,7 +4716,7 @@ HiiConfigRoutingExtractConfig (
 \r
     //\r
     // Attach this <ConfigAltResp> to a <MultiConfigAltResp>. There is a '&'\r
-    // which seperates the first <ConfigAltResp> and the following ones.\r
+    // which separates the first <ConfigAltResp> and the following ones.\r
     //\r
     ASSERT (*AccessProgress == 0);\r
 \r
@@ -4803,7 +4969,7 @@ HiiConfigRoutingExportConfig (
       \r
       //\r
       // Attach this <ConfigAltResp> to a <MultiConfigAltResp>. There is a '&'\r
-      // which seperates the first <ConfigAltResp> and the following ones.      \r
+      // which separates the first <ConfigAltResp> and the following ones.\r
       //\r
       if (!FirstElement) {\r
         Status = AppendToMultiString (Results, L"&");\r
@@ -5265,7 +5431,14 @@ HiiBlockToConfig (
     TemString = ValueStr;\r
     TemBuffer = Value + Width - 1;\r
     for (Index = 0; Index < Width; Index ++, TemBuffer --) {\r
-      TemString += UnicodeValueToString (TemString, PREFIX_ZERO | RADIX_HEX, *TemBuffer, 2);\r
+      UnicodeValueToStringS (\r
+        TemString,\r
+        Length  * sizeof (CHAR16) - ((UINTN)TemString - (UINTN)ValueStr),\r
+        PREFIX_ZERO | RADIX_HEX,\r
+        *TemBuffer,\r
+        2\r
+        );\r
+      TemString += StrnLenS (TemString, Length - ((UINTN)TemString - (UINTN)ValueStr) / sizeof (CHAR16));\r
     }\r
 \r
     FreePool (Value);\r