]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/HiiDatabaseDxe/ConfigKeywordHandler.c
IntelFrameworkModulePkg: Replace [Ascii|Unicode]ValueToString
[mirror_edk2.git] / MdeModulePkg / Universal / HiiDatabaseDxe / ConfigKeywordHandler.c
index c3cd064074a8213b3e736e3d16b255b7f183abf3..8e23a51533d63902d5302d4b39ff7698d81a2c2f 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
 Implementation of interfaces function for EFI_CONFIG_KEYWORD_HANDLER_PROTOCOL.\r
 \r
-Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2015 - 2016, 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
@@ -28,7 +28,7 @@ extern HII_DATABASE_PRIVATE_DATA mPrivate;
   @param  NextString             string follow the possible PathHdr string.\r
 \r
   @retval EFI_INVALID_PARAMETER  The device path is not valid or the 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 binary format.\r
                                  The Input string not include PathHdr section.\r
 \r
@@ -178,6 +178,7 @@ ExtractNameSpace (
   )\r
 {\r
   CHAR16    *TmpPtr;\r
+  UINTN     NameSpaceSize;\r
 \r
   ASSERT (NameSpace != NULL);\r
 \r
@@ -218,11 +219,12 @@ ExtractNameSpace (
   // Input NameSpace is unicode string. The language in String package is ascii string.\r
   // Here will convert the unicode string to ascii and save it.\r
   //\r
-  *NameSpace = AllocatePool (StrLen (String) + 1);\r
+  NameSpaceSize = StrLen (String) + 1;\r
+  *NameSpace = AllocatePool (NameSpaceSize);\r
   if (*NameSpace == NULL) {\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
-  UnicodeStrToAsciiStr (String, *NameSpace);\r
+  UnicodeStrToAsciiStrS (String, *NameSpace, NameSpaceSize);\r
 \r
   if (TmpPtr != NULL) {\r
     *TmpPtr = L'&'; \r
@@ -238,10 +240,10 @@ ExtractNameSpace (
 \r
   @param  String                 KeywordRequestformat string.\r
   @param  Keyword                return the extract keyword string.\r
-  @param  NextString             return the next string follow this keyword sectin.\r
+  @param  NextString             return the next string follow this keyword section.\r
 \r
   @retval EFI_SUCCESS            Success to get the keyword string.\r
-  @retval EFI_INVALID_PARAMETER  Parsr the input string return error.\r
+  @retval EFI_INVALID_PARAMETER  Parse the input string return error.\r
 \r
 **/\r
 EFI_STATUS\r
@@ -304,10 +306,10 @@ ExtractKeyword (
 \r
   @param  String                 KeywordRequestformat string.\r
   @param  Value                  return the extract value string.\r
-  @param  NextString             return the next string follow this keyword sectin.\r
+  @param  NextString             return the next string follow this keyword section.\r
 \r
   @retval EFI_SUCCESS            Success to get the keyword string.\r
-  @retval EFI_INVALID_PARAMETER  Parsr the input string return error.\r
+  @retval EFI_INVALID_PARAMETER  Parse the input string return error.\r
 \r
 **/\r
 EFI_STATUS\r
@@ -359,10 +361,10 @@ ExtractValue (
 \r
   @param  String                 KeywordRequestformat string.\r
   @param  FilterFlags            return the filter condition.\r
-  @param  NextString             return the next string follow this keyword sectin.\r
+  @param  NextString             return the next string follow this keyword section.\r
 \r
   @retval EFI_SUCCESS            Success to get the keyword string.\r
-  @retval EFI_INVALID_PARAMETER  Parsr the input string return error.\r
+  @retval EFI_INVALID_PARAMETER  Parse the input string return error.\r
 \r
 **/\r
 BOOLEAN\r
@@ -475,7 +477,7 @@ ExtractFilter (
         String = KeywordPtr;\r
       } else {\r
         //\r
-        // Only has paltform defined filter section, just skip it.\r
+        // Only has platform defined filter section, just skip it.\r
         //\r
         String += StrLen (String);\r
       }\r
@@ -518,9 +520,9 @@ ExtractReadOnlyFromOpCode (
 \r
   This is a internal function.\r
 \r
-  @param  OpCodeData             The questin binary ifr data.\r
+  @param  OpCodeData             The question binary ifr data.\r
   @param  KeywordRequest         KeywordRequestformat string.\r
-  @param  NextString             return the next string follow this keyword sectin.\r
+  @param  NextString             return the next string follow this keyword section.\r
   @param  ReadOnly               Return whether this question is read only.\r
 \r
   @retval KEYWORD_HANDLER_NO_ERROR                     Success validate.\r
@@ -709,7 +711,7 @@ GetRecordFromDevicePath (
   @param  BufferSize             Length of the buffer.\r
   @param  StringDest             Buffer to store the string text. \r
 \r
-  @retval EFI_SUCCESS            The string text was outputed successfully.\r
+  @retval EFI_SUCCESS            The string text was outputted successfully.\r
   @retval EFI_OUT_OF_RESOURCES   Out of resource.\r
 \r
 **/\r
@@ -779,6 +781,7 @@ GetStringIdFromString (
   UINTN                                StringSize;\r
   CHAR16                               *String;\r
   CHAR8                                *AsciiKeywordValue;\r
+  UINTN                                KeywordValueSize;\r
   EFI_STATUS                           Status;\r
 \r
   ASSERT (StringPackage != NULL && KeywordValue != NULL && StringId != NULL);\r
@@ -794,11 +797,12 @@ GetStringIdFromString (
   //\r
   // Make a ascii keyword value for later use.\r
   //\r
-  AsciiKeywordValue = AllocatePool (StrLen (KeywordValue) + 1);\r
+  KeywordValueSize = StrLen (KeywordValue) + 1;\r
+  AsciiKeywordValue = AllocatePool (KeywordValueSize);\r
   if (AsciiKeywordValue == NULL) {\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
-  UnicodeStrToAsciiStr(KeywordValue, AsciiKeywordValue);\r
+  UnicodeStrToAsciiStrS (KeywordValue, AsciiKeywordValue, KeywordValueSize);\r
 \r
   while (*BlockHdr != EFI_HII_SIBT_END) {\r
     switch (*BlockHdr) {\r
@@ -871,7 +875,7 @@ GetStringIdFromString (
       if (EFI_ERROR (Status)) {\r
         goto Done;\r
       }\r
-      \r
+      ASSERT (String != NULL);\r
       if (StrCmp(KeywordValue, String) == 0) {\r
         *StringId = CurrentStringId;\r
         goto Done;\r
@@ -891,7 +895,7 @@ GetStringIdFromString (
       if (EFI_ERROR (Status)) {\r
         goto Done;\r
       }\r
-      \r
+      ASSERT (String != NULL);\r
       if (StrCmp(KeywordValue, String) == 0) {\r
         *StringId = CurrentStringId;\r
         goto Done;\r
@@ -910,7 +914,7 @@ GetStringIdFromString (
         if (EFI_ERROR (Status)) {\r
           goto Done;\r
         }\r
-\r
+        ASSERT (String != NULL);\r
         BlockSize += StringSize;\r
         if (StrCmp(KeywordValue, String) == 0) {\r
           *StringId = CurrentStringId;\r
@@ -935,7 +939,7 @@ GetStringIdFromString (
         if (EFI_ERROR (Status)) {\r
           goto Done;\r
         }\r
-\r
+        ASSERT (String != NULL);\r
         BlockSize += StringSize;\r
         if (StrCmp(KeywordValue, String) == 0) {\r
           *StringId = CurrentStringId;\r
@@ -1065,11 +1069,12 @@ GetNextStringId (
       StringTextPtr = BlockHdr + Offset;\r
       \r
       if (FindString) {\r
-        *KeywordValue = AllocatePool (AsciiStrSize ((CHAR8 *) StringTextPtr) * sizeof (CHAR16));\r
+        StringSize = AsciiStrSize ((CHAR8 *) StringTextPtr);\r
+        *KeywordValue = AllocatePool (StringSize * sizeof (CHAR16));\r
         if (*KeywordValue == NULL) {\r
           return 0;\r
         }\r
-        AsciiStrToUnicodeStr ((CHAR8 *) StringTextPtr, *KeywordValue);\r
+        AsciiStrToUnicodeStrS ((CHAR8 *) StringTextPtr, *KeywordValue, StringSize);\r
         return CurrentStringId;\r
       } else if (CurrentStringId == StringId) {\r
         FindString = TRUE;\r
@@ -1084,11 +1089,12 @@ GetNextStringId (
       StringTextPtr = BlockHdr + Offset;\r
       \r
       if (FindString) {\r
-        *KeywordValue = AllocatePool (AsciiStrSize ((CHAR8 *) StringTextPtr) * sizeof (CHAR16));\r
+        StringSize = AsciiStrSize ((CHAR8 *) StringTextPtr);\r
+        *KeywordValue = AllocatePool (StringSize * sizeof (CHAR16));\r
         if (*KeywordValue == NULL) {\r
           return 0;\r
         }\r
-        AsciiStrToUnicodeStr ((CHAR8 *) StringTextPtr, *KeywordValue);\r
+        AsciiStrToUnicodeStrS ((CHAR8 *) StringTextPtr, *KeywordValue, StringSize);\r
         return CurrentStringId;\r
       } else if (CurrentStringId == StringId) {\r
         FindString = TRUE;\r
@@ -1105,11 +1111,12 @@ GetNextStringId (
 \r
       for (Index = 0; Index < StringCount; Index++) {\r
         if (FindString) {\r
-          *KeywordValue = AllocatePool (AsciiStrSize ((CHAR8 *) StringTextPtr) * sizeof (CHAR16));\r
+          StringSize = AsciiStrSize ((CHAR8 *) StringTextPtr);\r
+          *KeywordValue = AllocatePool (StringSize * sizeof (CHAR16));\r
           if (*KeywordValue == NULL) {\r
             return 0;\r
           }\r
-          AsciiStrToUnicodeStr ((CHAR8 *) StringTextPtr, *KeywordValue);\r
+          AsciiStrToUnicodeStrS ((CHAR8 *) StringTextPtr, *KeywordValue, StringSize);\r
           return CurrentStringId;\r
         } else if (CurrentStringId == StringId) {\r
           FindString = TRUE;\r
@@ -1132,11 +1139,12 @@ GetNextStringId (
 \r
       for (Index = 0; Index < StringCount; Index++) {\r
         if (FindString) {\r
-          *KeywordValue = AllocatePool (AsciiStrSize ((CHAR8 *) StringTextPtr) * sizeof (CHAR16));\r
+          StringSize = AsciiStrSize ((CHAR8 *) StringTextPtr);\r
+          *KeywordValue = AllocatePool (StringSize * sizeof (CHAR16));\r
           if (*KeywordValue == NULL) {\r
             return 0;\r
           }\r
-          AsciiStrToUnicodeStr ((CHAR8 *) StringTextPtr, *KeywordValue);\r
+          AsciiStrToUnicodeStrS ((CHAR8 *) StringTextPtr, *KeywordValue, StringSize);\r
           return CurrentStringId;\r
         } else if (CurrentStringId == StringId) {\r
           FindString = TRUE;\r
@@ -1302,7 +1310,7 @@ GetNextStringId (
   @param  KeywordValue                   Keyword value.\r
   @param  StringId                       String Id for this keyword.\r
 \r
-  @retval KEYWORD_HANDLER_NO_ERROR                     Get String id succes.\r
+  @retval KEYWORD_HANDLER_NO_ERROR                     Get String id successfully.\r
   @retval KEYWORD_HANDLER_KEYWORD_NOT_FOUND            Not found the string id in the string package.\r
   @retval KEYWORD_HANDLER_NAMESPACE_ID_NOT_FOUND       Not found the string package for this namespace.\r
   @retval KEYWORD_HANDLER_UNDEFINED_PROCESSING_ERROR   Out of resource error.\r
@@ -1321,10 +1329,12 @@ GetStringIdFromRecord (
   HII_STRING_PACKAGE_INSTANCE         *StringPackage;\r
   EFI_STATUS                          Status;\r
   CHAR8                               *Name;\r
+  UINT32                              RetVal;\r
 \r
   ASSERT (DatabaseRecord != NULL && NameSpace != NULL && KeywordValue != NULL);\r
 \r
   PackageListNode = DatabaseRecord->PackageList;\r
+  RetVal = KEYWORD_HANDLER_NAMESPACE_ID_NOT_FOUND;\r
 \r
   if (*NameSpace != NULL) {\r
     Name = *NameSpace;\r
@@ -1351,7 +1361,7 @@ GetStringIdFromRecord (
     }\r
   }\r
 \r
-  return KEYWORD_HANDLER_NAMESPACE_ID_NOT_FOUND;\r
+  return RetVal;\r
 }\r
 \r
 /**\r
@@ -1571,7 +1581,6 @@ GetWidth (
     \r
     case EFI_IFR_TYPE_NUM_SIZE_64:\r
       return (UINT16) sizeof (UINT64) * ((EFI_IFR_ORDERED_LIST *) OpCodeData)->MaxContainers;\r
-      break;\r
     \r
     default:\r
       ASSERT (FALSE);\r
@@ -1582,6 +1591,8 @@ GetWidth (
     return (UINT16) sizeof (BOOLEAN);\r
     \r
   case EFI_IFR_PASSWORD_OP:\r
+    return (UINT16)((UINTN) ((EFI_IFR_PASSWORD *) OpCodeData)->MaxSize * sizeof (CHAR16));\r
+\r
   case EFI_IFR_STRING_OP:\r
     return (UINT16)((UINTN) ((EFI_IFR_STRING *) OpCodeData)->MaxSize * sizeof (CHAR16));\r
 \r
@@ -1598,7 +1609,7 @@ GetWidth (
 }\r
 \r
 /**\r
-  Converts all hex dtring characters in range ['A'..'F'] to ['a'..'f'] for \r
+  Converts all hex string characters in range ['A'..'F'] to ['a'..'f'] for\r
   hex digits that appear between a '=' and a '&' in a config string.\r
 \r
   If ConfigString is NULL, then ASSERT().\r
@@ -1646,7 +1657,7 @@ InternalLowerConfigString (
   @param[in]  DriverHandle  The driver handle which supports a Device Path Protocol\r
                             that is the routing information PATH.  Each byte of\r
                             the Device Path associated with DriverHandle is converted\r
-                            to a 2 Unicode character hexidecimal string.\r
+                            to a 2 Unicode character hexadecimal string.\r
 \r
   @retval NULL   DriverHandle does not support the Device Path Protocol.\r
   @retval Other  A pointer to the Null-terminate Unicode <ConfigHdr> string\r
@@ -1667,7 +1678,9 @@ ConstructConfigHdr (
   UINT8                     *Buffer;\r
   CHAR16                    *Name;\r
   CHAR8                     *AsciiName;\r
+  UINTN                     NameSize;\r
   EFI_GUID                  *Guid;\r
+  UINTN                     MaxLen;\r
 \r
   ASSERT (OpCodeData != NULL);\r
 \r
@@ -1695,9 +1708,10 @@ ConstructConfigHdr (
   }\r
 \r
   if (AsciiName != NULL) {\r
-    Name = AllocateZeroPool (AsciiStrSize (AsciiName) * 2);\r
+    NameSize = AsciiStrSize (AsciiName);\r
+    Name = AllocateZeroPool (NameSize * sizeof (CHAR16));\r
     ASSERT (Name != NULL);\r
-    AsciiStrToUnicodeStr(AsciiName, Name);\r
+    AsciiStrToUnicodeStrS (AsciiName, Name, NameSize);\r
   } else {\r
     Name = NULL;\r
   }\r
@@ -1731,7 +1745,8 @@ ConstructConfigHdr (
   // GUID=<HexCh>32&NAME=<Char>NameLength&PATH=<HexChar>DevicePathSize <Null>\r
   // | 5 | sizeof (EFI_GUID) * 2 | 6 | NameStrLen*4 | 6 | DevicePathSize * 2 | 1 |\r
   //\r
-  String = AllocateZeroPool ((5 + sizeof (EFI_GUID) * 2 + 6 + NameLength * 4 + 6 + DevicePathSize * 2 + 1) * sizeof (CHAR16));\r
+  MaxLen = 5 + sizeof (EFI_GUID) * 2 + 6 + NameLength * 4 + 6 + DevicePathSize * 2 + 1;\r
+  String = AllocateZeroPool (MaxLen * sizeof (CHAR16));\r
   if (String == NULL) {\r
     return NULL;\r
   }\r
@@ -1739,7 +1754,8 @@ ConstructConfigHdr (
   //\r
   // Start with L"GUID="\r
   //\r
-  ReturnString = StrCpy (String, L"GUID=");\r
+  StrCpyS (String, MaxLen, L"GUID=");\r
+  ReturnString = String;\r
   String += StrLen (String);\r
 \r
   if (Guid != NULL) {\r
@@ -1754,7 +1770,7 @@ ConstructConfigHdr (
   //\r
   // Append L"&NAME="\r
   //\r
-  StrCpy (String, L"&NAME=");\r
+  StrCatS (ReturnString, MaxLen, L"&NAME=");\r
   String += StrLen (String);\r
 \r
   if (Name != NULL) {\r
@@ -1769,7 +1785,7 @@ ConstructConfigHdr (
   //\r
   // Append L"&PATH="\r
   //\r
-  StrCpy (String, L"&PATH=");\r
+  StrCatS (ReturnString, MaxLen, L"&PATH=");\r
   String += StrLen (String);\r
 \r
   //\r
@@ -1989,7 +2005,7 @@ ExtractConfigRequest (
   UINT16                              Width;\r
   CHAR16                              *ConfigHdr;\r
   CHAR16                              *RequestElement;\r
-  UINTN                               Length;\r
+  UINTN                               MaxLen;\r
   CHAR16                              *StringPtr;\r
 \r
   ASSERT (DatabaseRecord != NULL && OpCodeData != NULL && ConfigRequest != NULL);\r
@@ -2028,9 +2044,10 @@ ExtractConfigRequest (
       }\r
       RequestElement = ConstructRequestElement(Name, Offset, Width);\r
       ConfigHdr = ConstructConfigHdr(Storage, DatabaseRecord->DriverHandle);\r
+      ASSERT (ConfigHdr != NULL);\r
 \r
-      Length = (StrLen (ConfigHdr) + 1 + StrLen(RequestElement) + 1) * sizeof (CHAR16);\r
-      *ConfigRequest = AllocatePool (Length);\r
+      MaxLen = StrLen (ConfigHdr) + 1 + StrLen(RequestElement) + 1;\r
+      *ConfigRequest = AllocatePool (MaxLen * sizeof (CHAR16));\r
       if (*ConfigRequest == NULL) {\r
         FreePool (ConfigHdr);\r
         FreePool (RequestElement);\r
@@ -2038,15 +2055,11 @@ ExtractConfigRequest (
       }\r
       StringPtr = *ConfigRequest;\r
 \r
-      StrCpy (StringPtr, ConfigHdr);\r
-      StringPtr += StrLen (StringPtr);\r
+      StrCpyS (StringPtr, MaxLen, ConfigHdr);\r
 \r
-      *StringPtr = L'&';\r
-      StringPtr++;\r
+      StrCatS (StringPtr, MaxLen, L"&");\r
 \r
-      StrCpy (StringPtr, RequestElement);\r
-      StringPtr += StrLen (StringPtr);\r
-      *StringPtr = L'\0';\r
+      StrCatS (StringPtr, MaxLen, RequestElement);\r
 \r
       FreePool (ConfigHdr);\r
       FreePool (RequestElement);\r
@@ -2095,7 +2108,7 @@ ExtractConfigResp (
   UINT16                              Width;\r
   CHAR16                              *ConfigHdr;\r
   CHAR16                              *RequestElement;\r
-  UINTN                               Length;\r
+  UINTN                               MaxLen;\r
   CHAR16                              *StringPtr;\r
 \r
   ASSERT ((DatabaseRecord != NULL) && (OpCodeData != NULL) && (ConfigResp != NULL) && (ValueElement != NULL));\r
@@ -2135,9 +2148,10 @@ ExtractConfigResp (
       RequestElement = ConstructRequestElement(Name, Offset, Width);\r
 \r
       ConfigHdr = ConstructConfigHdr(Storage, DatabaseRecord->DriverHandle);\r
+      ASSERT (ConfigHdr != NULL);\r
 \r
-      Length = (StrLen (ConfigHdr) + 1 + StrLen(RequestElement) + 1 + StrLen (L"VALUE=") + StrLen(ValueElement) + 1) * sizeof (CHAR16);\r
-      *ConfigResp = AllocatePool (Length);\r
+      MaxLen = StrLen (ConfigHdr) + 1 + StrLen(RequestElement) + 1 + StrLen (L"VALUE=") + StrLen(ValueElement) + 1;\r
+      *ConfigResp = AllocatePool (MaxLen * sizeof (CHAR16));\r
       if (*ConfigResp == NULL) {\r
         FreePool (ConfigHdr);\r
         FreePool (RequestElement);\r
@@ -2145,24 +2159,18 @@ ExtractConfigResp (
       }\r
       StringPtr = *ConfigResp;\r
 \r
-      StrCpy (StringPtr, ConfigHdr);\r
-      StringPtr += StrLen (StringPtr);\r
+      StrCpyS (StringPtr, MaxLen, ConfigHdr);\r
 \r
-      *StringPtr = L'&';\r
-      StringPtr++;\r
+      StrCatS (StringPtr, MaxLen, L"&");\r
 \r
-      StrCpy (StringPtr, RequestElement);\r
-      StringPtr += StrLen (StringPtr);\r
-      \r
-      *StringPtr = L'&';\r
-      StringPtr++;\r
 \r
-      StrCpy (StringPtr, L"VALUE=");\r
-      StringPtr += StrLen (StringPtr);\r
+      StrCatS (StringPtr, MaxLen, RequestElement);\r
+\r
+      StrCatS (StringPtr, MaxLen, L"&");\r
 \r
-      StrCpy (StringPtr, ValueElement);\r
-      StringPtr += StrLen (StringPtr);\r
-      *StringPtr = L'\0';\r
+      StrCatS (StringPtr, MaxLen, L"VALUE=");\r
+\r
+      StrCatS (StringPtr, MaxLen, ValueElement);\r
 \r
       FreePool (ConfigHdr);\r
       FreePool (RequestElement);\r
@@ -2348,7 +2356,7 @@ GetStringIdFromDatabase (
 }\r
 \r
 /**\r
-  Genereate the KeywordResp String.\r
+  Generate the KeywordResp String.\r
 \r
   <KeywordResp> ::= <NameSpaceId><PathHdr>'&'<Keyword>'&VALUE='<Number>['&READONLY']\r
 \r
@@ -2377,6 +2385,7 @@ GenerateKeywordResp (
   CHAR16    *RespStr;\r
   CHAR16    *PathHdr;\r
   CHAR16    *UnicodeNameSpace;\r
+  UINTN     NameSpaceLength;\r
 \r
   ASSERT ((NameSpace != NULL) && (DevicePath != NULL) && (KeywordData != NULL) && (ValueStr != NULL) && (KeywordResp != NULL));\r
 \r
@@ -2387,12 +2396,13 @@ GenerateKeywordResp (
   // 1.1 NameSpaceId size.\r
   // 'NAMESPACE='<String>\r
   //\r
-  RespStrLen = 10 + AsciiStrLen (NameSpace);\r
-  UnicodeNameSpace = AllocatePool ((AsciiStrLen (NameSpace) + 1) * sizeof (CHAR16));\r
+  NameSpaceLength = AsciiStrLen (NameSpace);\r
+  RespStrLen = 10 + NameSpaceLength;\r
+  UnicodeNameSpace = AllocatePool ((NameSpaceLength + 1) * sizeof (CHAR16));\r
   if (UnicodeNameSpace == NULL) {\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
-  AsciiStrToUnicodeStr(NameSpace, UnicodeNameSpace);\r
+  AsciiStrToUnicodeStrS (NameSpace, UnicodeNameSpace, NameSpaceLength + 1);\r
 \r
   //\r
   // 1.2 PathHdr size.\r
@@ -2409,7 +2419,7 @@ GenerateKeywordResp (
   RespStrLen += StrLen (PathHdr);\r
 \r
   //\r
-  // 1.3 Keyword setion.\r
+  // 1.3 Keyword section.\r
   // 'KEYWORD='<String>[':'<DecCh>(1/4)]\r
   //\r
   RespStrLen += 8 + StrLen (KeywordData);\r
@@ -2429,9 +2439,10 @@ GenerateKeywordResp (
   }\r
 \r
   //\r
-  // 2. Allocate the buffer and create the KeywordResp string.\r
+  // 2. Allocate the buffer and create the KeywordResp string include '\0'.\r
   //\r
-  *KeywordResp = AllocatePool ((RespStrLen + 1) * sizeof (CHAR16));\r
+  RespStrLen += 1;\r
+  *KeywordResp = AllocatePool (RespStrLen * sizeof (CHAR16));\r
   if (*KeywordResp == NULL) {\r
     if (UnicodeNameSpace != NULL) {\r
       FreePool (UnicodeNameSpace);\r
@@ -2444,44 +2455,34 @@ GenerateKeywordResp (
   //\r
   // 2.1 Copy NameSpaceId section.\r
   //\r
-  StrCpy (RespStr, L"NAMESPACE=");\r
-  RespStr += StrLen (RespStr);\r
-  StrCpy (RespStr, UnicodeNameSpace);\r
-  RespStr += StrLen (RespStr);\r
+  StrCpyS (RespStr, RespStrLen, L"NAMESPACE=");\r
+\r
+  StrCatS (RespStr, RespStrLen, UnicodeNameSpace);\r
 \r
   //\r
   // 2.2 Copy PathHdr section.\r
   //\r
-  StrCpy (RespStr, PathHdr);\r
-  RespStr += StrLen (RespStr);\r
+  StrCatS (RespStr, RespStrLen, PathHdr);\r
 \r
   //\r
   // 2.3 Copy Keyword section.\r
   //\r
-  StrCpy (RespStr, L"KEYWORD=");\r
-  RespStr += StrLen (RespStr);\r
-  StrCpy (RespStr, KeywordData);\r
-  RespStr += StrLen (RespStr);\r
+  StrCatS (RespStr, RespStrLen, L"KEYWORD=");\r
+\r
+  StrCatS (RespStr, RespStrLen, KeywordData);\r
 \r
   //\r
   // 2.4 Copy the Value section.\r
   //\r
-  StrCpy (RespStr, ValueStr);\r
-  RespStr += StrLen (RespStr);\r
+  StrCatS (RespStr, RespStrLen, ValueStr);\r
 \r
   //\r
   // 2.5 Copy ReadOnly section if exist.\r
   //\r
   if (ReadOnly) {\r
-    StrCpy (RespStr, L"&READONLY");\r
-    RespStr += StrLen (RespStr);\r
+    StrCatS (RespStr, RespStrLen, L"&READONLY");\r
   }\r
 \r
-  //\r
-  // 2.6 Add the end.\r
-  //\r
-  *RespStr = L'\0';\r
-\r
   if (UnicodeNameSpace != NULL) {\r
     FreePool (UnicodeNameSpace);\r
   }\r
@@ -2529,12 +2530,9 @@ MergeToMultiKeywordResp (
   FreePool (*MultiKeywordResp);\r
   *MultiKeywordResp = StringPtr;\r
 \r
-  StringPtr += StrLen (StringPtr);\r
-\r
-  *StringPtr = L'&';\r
-  StringPtr++;\r
+  StrCatS (StringPtr, MultiKeywordRespLen / sizeof (CHAR16), L"&");\r
 \r
-  StrCpy (StringPtr, *KeywordResp);\r
+  StrCatS (StringPtr, MultiKeywordRespLen / sizeof (CHAR16), *KeywordResp);\r
 \r
   return EFI_SUCCESS;\r
 }\r
@@ -2548,6 +2546,7 @@ MergeToMultiKeywordResp (
 \r
   @param  NameSpace                      The namespace used to search the string.\r
   @param  MultiResp                      Return the MultiKeywordResp string for the system.\r
+  @param  ProgressErr                    Return the error status.\r
 \r
   @retval EFI_OUT_OF_RESOURCES           The memory can't be allocated.\r
   @retval EFI_SUCCESS                    Generate the MultiKeywordResp string.\r
@@ -2557,7 +2556,8 @@ MergeToMultiKeywordResp (
 EFI_STATUS\r
 EnumerateAllKeywords (\r
   IN  CHAR8             *NameSpace,\r
-  OUT EFI_STRING        *MultiResp\r
+  OUT EFI_STRING        *MultiResp,\r
+  OUT UINT32            *ProgressErr\r
   )\r
 {\r
   LIST_ENTRY                          *Link;\r
@@ -2565,7 +2565,6 @@ EnumerateAllKeywords (
   UINT8                               *DevicePathPkg;\r
   UINT8                               *DevicePath;\r
   HII_DATABASE_RECORD                 *DataBaseRecord;\r
-  UINTN                               DevicePathSize;\r
   HII_DATABASE_PACKAGE_LIST_INSTANCE  *PackageListNode;\r
   HII_STRING_PACKAGE_INSTANCE         *StringPackage;\r
   CHAR8                               *LocalNameSpace;\r
@@ -2578,9 +2577,9 @@ EnumerateAllKeywords (
   CHAR16                              *MultiKeywordResp;\r
   CHAR16                              *KeywordData;\r
   BOOLEAN                             ReadOnly;\r
+  BOOLEAN                             FindKeywordPackages;\r
 \r
   DataBaseRecord   = NULL;\r
-  DevicePathSize   = 0;\r
   Status           = EFI_SUCCESS;\r
   MultiKeywordResp = NULL;\r
   DevicePath       = NULL;\r
@@ -2588,6 +2587,7 @@ EnumerateAllKeywords (
   ConfigRequest    = NULL;\r
   ValueElement     = NULL;\r
   KeywordResp      = NULL;\r
+  FindKeywordPackages = FALSE;\r
 \r
   if (NameSpace == NULL) {\r
     NameSpace = UEFI_CONFIG_LANG;\r
@@ -2600,7 +2600,6 @@ EnumerateAllKeywords (
     DataBaseRecord = CR (Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);\r
     if ((DevicePathPkg = DataBaseRecord->PackageList->DevicePathPkg) != NULL) {\r
       DevicePath = DevicePathPkg + sizeof (EFI_HII_PACKAGE_HEADER);\r
-      DevicePathSize    = GetDevicePathSize ((EFI_DEVICE_PATH_PROTOCOL *) DevicePath);\r
     }\r
     PackageListNode = DataBaseRecord->PackageList;\r
 \r
@@ -2611,6 +2610,7 @@ EnumerateAllKeywords (
       // Check whether has keyword string package.\r
       //\r
       if (AsciiStrnCmp(NameSpace, StringPackage->StringPkgHdr->Language, AsciiStrLen (NameSpace)) == 0) {\r
+        FindKeywordPackages = TRUE;\r
         //\r
         // Keep the NameSpace string.\r
         //\r
@@ -2709,10 +2709,15 @@ Error:
   }\r
 \r
   //\r
-  // return the already get MultiKeywordString even error occured.\r
+  // return the already get MultiKeywordString even error occurred.\r
   //\r
   if (MultiKeywordResp == NULL) {\r
     Status = EFI_NOT_FOUND;\r
+    if (!FindKeywordPackages) {\r
+      *ProgressErr = KEYWORD_HANDLER_NAMESPACE_ID_NOT_FOUND;\r
+    } else {\r
+      *ProgressErr = KEYWORD_HANDLER_KEYWORD_NOT_FOUND;\r
+    }\r
   } else {\r
     Status = EFI_SUCCESS;\r
   }\r
@@ -2761,8 +2766,9 @@ Done:
   @param Progress         On return, points to a character in the KeywordString. \r
                           Points to the string's NULL terminator if the request \r
                           was successful. Points to the most recent '&' before \r
-                          the first failing string element if the request was \r
-                          not successful.\r
+                          the first failing name / value pair (or the beginning\r
+                          of the string if the failure is in the first name / value\r
+                          pair) if the request was not successful.\r
 \r
   @param ProgressErr      If during the processing of the KeywordString there was\r
                           a failure, this parameter gives additional information \r
@@ -2803,7 +2809,7 @@ EfiConfigKeywordHandlerSetData (
   EFI_STATUS                          Status;\r
   CHAR16                              *StringPtr;\r
   EFI_DEVICE_PATH_PROTOCOL            *DevicePath;\r
-  CHAR16                              *NextStringPtr;  \r
+  CHAR16                              *NextStringPtr;\r
   CHAR16                              *KeywordData;\r
   EFI_STRING_ID                       KeywordStringId;\r
   UINT32                              RetVal;\r
@@ -2814,6 +2820,8 @@ EfiConfigKeywordHandlerSetData (
   CHAR16                              *ValueElement;\r
   BOOLEAN                             ReadOnly;\r
   EFI_STRING                          InternalProgress;\r
+  CHAR16                              *TempString;\r
+  CHAR16                              *KeywordStartPos;\r
 \r
   if (This == NULL || Progress == NULL || ProgressErr == NULL || KeywordString == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
@@ -2822,15 +2830,22 @@ EfiConfigKeywordHandlerSetData (
   *Progress    = KeywordString;\r
   *ProgressErr = KEYWORD_HANDLER_UNDEFINED_PROCESSING_ERROR;\r
   Status       = EFI_SUCCESS;\r
-  StringPtr    = KeywordString;\r
   MultiConfigResp = NULL;\r
   NameSpace       = NULL;\r
   DevicePath      = NULL;\r
   KeywordData     = NULL;\r
   ValueElement    = NULL;\r
   ConfigResp      = NULL;\r
+  KeywordStartPos = NULL;\r
   KeywordStringId = 0;\r
 \r
+  //\r
+  // Use temp string to avoid changing input string buffer.\r
+  //\r
+  TempString = AllocateCopyPool (StrSize (KeywordString), KeywordString);\r
+  ASSERT (TempString != NULL);\r
+  StringPtr = TempString;\r
+\r
   while ((StringPtr != NULL) && (*StringPtr != L'\0')) {\r
     //\r
     // 1. Get NameSpace from NameSpaceId keyword.\r
@@ -2838,8 +2853,18 @@ EfiConfigKeywordHandlerSetData (
     Status = ExtractNameSpace (StringPtr, &NameSpace, &NextStringPtr);\r
     if (EFI_ERROR (Status)) {\r
       *ProgressErr = KEYWORD_HANDLER_MALFORMED_STRING;\r
-      return Status;\r
+      goto Done;\r
+    }\r
+    ASSERT (NameSpace != NULL);\r
+    //\r
+    // 1.1 Check whether the input namespace is valid.\r
+    //\r
+    if (AsciiStrnCmp(NameSpace, UEFI_CONFIG_LANG, AsciiStrLen (UEFI_CONFIG_LANG)) != 0) {\r
+      *ProgressErr = KEYWORD_HANDLER_MALFORMED_STRING;\r
+      Status = EFI_INVALID_PARAMETER;\r
+      goto Done;\r
     }\r
+\r
     StringPtr = NextStringPtr;\r
 \r
     //\r
@@ -2855,6 +2880,7 @@ EfiConfigKeywordHandlerSetData (
     //\r
     // 3. Extract keyword from the KeywordRequest string.\r
     //\r
+    KeywordStartPos = StringPtr;\r
     Status = ExtractKeyword(StringPtr, &KeywordData, &NextStringPtr);\r
     if (EFI_ERROR (Status)) {\r
       //\r
@@ -2881,11 +2907,11 @@ EfiConfigKeywordHandlerSetData (
     StringPtr = NextStringPtr;\r
 \r
     //\r
-    // 5. Find ReadOnly filter.\r
+    // 5. Find READONLY tag.\r
     //\r
-    if ((StringPtr != NULL) && StrnCmp (StringPtr, L"&ReadOnly", StrLen (L"&ReadOnly")) == 0) {\r
+    if ((StringPtr != NULL) && StrnCmp (StringPtr, L"&READONLY", StrLen (L"&READONLY")) == 0) {\r
       ReadOnly = TRUE;\r
-      StringPtr += StrLen (L"&ReadOnly");\r
+      StringPtr += StrLen (L"&READONLY");\r
     } else {\r
       ReadOnly = FALSE;\r
     }\r
@@ -2911,9 +2937,18 @@ EfiConfigKeywordHandlerSetData (
     // 8. Check the readonly flag.\r
     //\r
     if (ExtractReadOnlyFromOpCode (OpCode) != ReadOnly) {\r
+      //\r
+      // Extracting readonly flag form opcode and extracting "READONLY" tag form KeywordString should have the same results.\r
+      // If not, the input KeywordString must be incorrect, return the error status to caller.\r
+      //\r
       *ProgressErr = KEYWORD_HANDLER_INCOMPATIBLE_VALUE_DETECTED;\r
       Status = EFI_INVALID_PARAMETER;\r
-      goto Done;      \r
+      goto Done;\r
+    }\r
+    if (ReadOnly) {\r
+      *ProgressErr = KEYWORD_HANDLER_ACCESS_NOT_PERMITTED;\r
+      Status = EFI_ACCESS_DENIED;\r
+      goto Done;\r
     }\r
     \r
     //\r
@@ -2939,6 +2974,7 @@ EfiConfigKeywordHandlerSetData (
       FreePool (ConfigResp);\r
       ConfigResp = NULL;\r
     }\r
+    KeywordStartPos = NULL;\r
   }\r
 \r
   //\r
@@ -2957,6 +2993,14 @@ EfiConfigKeywordHandlerSetData (
   *ProgressErr = KEYWORD_HANDLER_NO_ERROR;\r
 \r
 Done:\r
+  if (KeywordStartPos != NULL) {\r
+    *Progress = KeywordString + (KeywordStartPos - TempString);\r
+  } else {\r
+    *Progress = KeywordString + (StringPtr - TempString);\r
+  }\r
+\r
+  ASSERT (TempString != NULL);\r
+  FreePool (TempString);\r
   if (NameSpace != NULL) {\r
     FreePool (NameSpace);\r
   }\r
@@ -2974,8 +3018,8 @@ Done:
   }\r
   if (MultiConfigResp != NULL && MultiConfigResp != ConfigResp) {\r
     FreePool (MultiConfigResp);\r
-  }  \r
-  *Progress = StringPtr;\r
+  }\r
+\r
   return Status;\r
 }\r
 \r
@@ -3010,8 +3054,9 @@ Done:
   \r
   @param Progress       On return, points to a character in the KeywordString. Points\r
                         to the string's NULL terminator if the request was successful. \r
-                        Points to the most recent '&' before the first failing string\r
-                        element if the request was not successful.\r
+                        Points to the most recent '&' before the first failing name / value\r
+                        pair (or the beginning of the string if the failure is in the first\r
+                        name / value pair) if the request was not successful.\r
                         \r
   @param ProgressErr    If during the processing of the KeywordString there was a\r
                         failure, this parameter gives additional information about the \r
@@ -3026,7 +3071,7 @@ Done:
   @retval EFI_SUCCESS             The specified action was completed successfully.\r
   \r
   @retval EFI_INVALID_PARAMETER   One or more of the following are TRUE:\r
-                                  1.Progress, ProgressErr, or Resuts is NULL.\r
+                                  1.Progress, ProgressErr, or Results is NULL.\r
                                   2.Parsing of the KeywordString resulted in an error. See\r
                                     Progress and ProgressErr for more data.\r
   \r
@@ -3073,6 +3118,7 @@ EfiConfigKeywordHandlerGetData (
   BOOLEAN                             ReadOnly;\r
   CHAR16                              *KeywordResp;\r
   CHAR16                              *MultiKeywordResp;\r
+  CHAR16                              *TempString;\r
 \r
   if (This == NULL || Progress == NULL || ProgressErr == NULL || Results == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
@@ -3088,18 +3134,44 @@ EfiConfigKeywordHandlerGetData (
   ReadOnly     = FALSE;\r
   MultiKeywordResp = NULL;\r
   KeywordStringId  = 0;\r
+  TempString   = NULL;\r
 \r
+  //\r
+  // Use temp string to avoid changing input string buffer.\r
+  //\r
+  if (NameSpaceId != NULL) {\r
+    TempString = AllocateCopyPool (StrSize (NameSpaceId), NameSpaceId);\r
+    ASSERT (TempString != NULL);\r
+  }\r
   //\r
   // 1. Get NameSpace from NameSpaceId keyword.\r
   //\r
-  Status = ExtractNameSpace (NameSpaceId, &NameSpace, NULL);\r
+  Status = ExtractNameSpace (TempString, &NameSpace, NULL);\r
+  if (TempString != NULL) {\r
+    FreePool (TempString);\r
+    TempString = NULL;\r
+  }\r
   if (EFI_ERROR (Status)) {\r
-    *ProgressErr = KEYWORD_HANDLER_NAMESPACE_ID_NOT_FOUND;\r
+    *ProgressErr = KEYWORD_HANDLER_MALFORMED_STRING;\r
     return Status;\r
   }\r
-\r
+  //\r
+  // 1.1 Check whether the input namespace is valid.\r
+  //\r
+  if (NameSpace != NULL){\r
+    if (AsciiStrnCmp(NameSpace, UEFI_CONFIG_LANG, AsciiStrLen (UEFI_CONFIG_LANG)) != 0) {\r
+      *ProgressErr = KEYWORD_HANDLER_MALFORMED_STRING;\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+  }\r
+  \r
   if (KeywordString != NULL) {\r
-    StringPtr = KeywordString;\r
+    //\r
+    // Use temp string to avoid changing input string buffer.\r
+    //\r
+    TempString = AllocateCopyPool (StrSize (KeywordString), KeywordString);\r
+    ASSERT (TempString != NULL);\r
+    StringPtr = TempString;\r
 \r
     while (*StringPtr != L'\0') {\r
       //\r
@@ -3210,7 +3282,7 @@ EfiConfigKeywordHandlerGetData (
     //\r
     // Enumerate all keyword in the system.\r
     //\r
-    Status = EnumerateAllKeywords(NameSpace, &MultiKeywordResp);\r
+    Status = EnumerateAllKeywords(NameSpace, &MultiKeywordResp, ProgressErr);\r
     if (EFI_ERROR (Status)) {\r
       goto Done;\r
     }\r
@@ -3220,6 +3292,11 @@ EfiConfigKeywordHandlerGetData (
   *ProgressErr = KEYWORD_HANDLER_NO_ERROR;\r
 \r
 Done:\r
+  *Progress = KeywordString + (StringPtr - TempString);\r
+\r
+  if (TempString != NULL) {\r
+    FreePool (TempString);\r
+  }\r
   if (NameSpace != NULL) {\r
     FreePool (NameSpace);\r
   }\r
@@ -3229,6 +3306,6 @@ Done:
   if (KeywordData != NULL) {\r
     FreePool (KeywordData);\r
   }\r
-  *Progress = StringPtr;\r
+\r
   return Status;\r
 }\r