]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/HiiDatabaseDxe/ConfigKeywordHandler.c
MdeModulePkg: Refine function comments in Keyword Handler Protocol
[mirror_edk2.git] / MdeModulePkg / Universal / HiiDatabaseDxe / ConfigKeywordHandler.c
index c3cd064074a8213b3e736e3d16b255b7f183abf3..5e7aca96816e4d8fce42dcbe30b86f4f84c19090 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
@@ -1321,10 +1321,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 +1353,7 @@ GetStringIdFromRecord (
     }\r
   }\r
 \r
-  return KEYWORD_HANDLER_NAMESPACE_ID_NOT_FOUND;\r
+  return RetVal;\r
 }\r
 \r
 /**\r
@@ -1571,7 +1573,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 +1583,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
@@ -1668,6 +1671,7 @@ ConstructConfigHdr (
   CHAR16                    *Name;\r
   CHAR8                     *AsciiName;\r
   EFI_GUID                  *Guid;\r
+  UINTN                     MaxLen;\r
 \r
   ASSERT (OpCodeData != NULL);\r
 \r
@@ -1731,7 +1735,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 +1744,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 +1760,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 +1775,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 +1995,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 +2034,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 +2045,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 +2098,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 +2138,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 +2149,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
+      StrCatS (StringPtr, MaxLen, L"VALUE=");\r
 \r
-      StrCpy (StringPtr, ValueElement);\r
-      StringPtr += StrLen (StringPtr);\r
-      *StringPtr = L'\0';\r
+      StrCatS (StringPtr, MaxLen, ValueElement);\r
 \r
       FreePool (ConfigHdr);\r
       FreePool (RequestElement);\r
@@ -2429,9 +2427,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 +2443,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 +2518,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 +2534,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 +2544,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 +2553,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 +2565,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 +2575,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 +2588,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 +2598,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
@@ -2713,6 +2701,11 @@ Error:
   //\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 +2754,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 +2797,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 +2808,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 +2818,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 +2841,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 +2868,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
@@ -2911,8 +2925,8 @@ EfiConfigKeywordHandlerSetData (
     // 8. Check the readonly flag.\r
     //\r
     if (ExtractReadOnlyFromOpCode (OpCode) != ReadOnly) {\r
-      *ProgressErr = KEYWORD_HANDLER_INCOMPATIBLE_VALUE_DETECTED;\r
-      Status = EFI_INVALID_PARAMETER;\r
+      *ProgressErr = KEYWORD_HANDLER_ACCESS_NOT_PERMITTED;\r
+      Status = EFI_ACCESS_DENIED;\r
       goto Done;      \r
     }\r
     \r
@@ -2939,6 +2953,7 @@ EfiConfigKeywordHandlerSetData (
       FreePool (ConfigResp);\r
       ConfigResp = NULL;\r
     }\r
+    KeywordStartPos = NULL;\r
   }\r
 \r
   //\r
@@ -2957,6 +2972,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 +2997,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 +3033,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
@@ -3073,6 +3097,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 +3113,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 +3261,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 +3271,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 +3285,6 @@ Done:
   if (KeywordData != NULL) {\r
     FreePool (KeywordData);\r
   }\r
-  *Progress = StringPtr;\r
+\r
   return Status;\r
 }\r