\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
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
return Status;\r
}\r
\r
+/**\r
+ To find the BlockName in the string with same value.\r
+\r
+ @param String Pointer to a Null-terminated Unicode string.\r
+ @param BlockName Pointer to a Null-terminated Unicode string to search for.\r
+ @param Buffer Pointer to the value correspond to the BlockName.\r
+ @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 necessary structures.\r
+ @retval EFI_SUCCESS The function finishes successfully.\r
+\r
+**/\r
+EFI_STATUS\r
+FindSameBlockElement(\r
+ IN EFI_STRING String,\r
+ IN EFI_STRING BlockName,\r
+ IN UINT8 *Buffer,\r
+ OUT BOOLEAN *Found,\r
+ IN UINTN BufferLen\r
+ )\r
+{\r
+ EFI_STRING BlockPtr;\r
+ UINTN Length;\r
+ UINT8 *TempBuffer;\r
+ EFI_STATUS Status;\r
+\r
+ TempBuffer = NULL;\r
+ *Found = FALSE;\r
+ BlockPtr = StrStr (String, BlockName);\r
+\r
+ while (BlockPtr != NULL) {\r
+ BlockPtr += StrLen (BlockName);\r
+ Status = GetValueOfNumber (BlockPtr, &TempBuffer, &Length);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ 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
+ TempBuffer = NULL;\r
+ BlockPtr = StrStr (BlockPtr + 1, BlockName);\r
+ }\r
+ }\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ Compare the <AltResp> in ConfigAltResp and DefaultAltCfgResp, if the <AltResp>\r
+ in DefaultAltCfgResp but not in ConfigAltResp,add it to the ConfigAltResp.\r
+\r
+ @param DefaultAltCfgResp Pointer to a null-terminated Unicode string in\r
+ <MultiConfigAltResp> format. The default value\r
+ string may contain more than one ConfigAltResp\r
+ string for the different varstore buffer.\r
+ @param ConfigAltResp Pointer to a null-terminated Unicode string in\r
+ <ConfigAltResp> format.\r
+ @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 necessary structures.\r
+ @retval EFI_SUCCESS The function finishes successfully.\r
+\r
+**/\r
+EFI_STATUS\r
+CompareBlockElementDefault (\r
+ IN EFI_STRING DefaultAltCfgResp,\r
+ IN OUT EFI_STRING *ConfigAltResp,\r
+ IN EFI_STRING AltConfigHdr,\r
+ IN OUT BOOLEAN *ConfigAltRespChanged\r
+)\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_STRING BlockPtr;\r
+ EFI_STRING BlockPtrStart;\r
+ EFI_STRING StringPtr;\r
+ EFI_STRING AppendString;\r
+ EFI_STRING AltConfigHdrPtr;\r
+ UINT8 *TempBuffer;\r
+ UINTN OffsetLength;\r
+ UINTN AppendSize;\r
+ UINTN TotalSize;\r
+ BOOLEAN FoundOffset;\r
+\r
+ AppendString = NULL;\r
+ TempBuffer = NULL;\r
+ //\r
+ // Make BlockPtr point to the first <BlockConfig> with AltConfigHdr in DefaultAltCfgResp.\r
+ //\r
+ AltConfigHdrPtr = StrStr (DefaultAltCfgResp, AltConfigHdr);\r
+ ASSERT (AltConfigHdrPtr != NULL);\r
+ BlockPtr = StrStr (AltConfigHdrPtr, L"&OFFSET=");\r
+ //\r
+ // Make StringPtr point to the AltConfigHdr in ConfigAltResp.\r
+ //\r
+ StringPtr = StrStr (*ConfigAltResp, AltConfigHdr);\r
+ ASSERT (StringPtr != NULL);\r
+\r
+ while (BlockPtr != NULL) {\r
+ //\r
+ // Find the "&OFFSET=<Number>" block and get the value of the Number with AltConfigHdr in DefaultAltCfgResp.\r
+ //\r
+ BlockPtrStart = BlockPtr;\r
+ BlockPtr += StrLen (L"&OFFSET=");\r
+ Status = GetValueOfNumber (BlockPtr, &TempBuffer, &OffsetLength);\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto Exit;\r
+ }\r
+ //\r
+ // To find the same "&OFFSET=<Number>" block in ConfigAltResp.\r
+ //\r
+ Status = FindSameBlockElement (StringPtr, L"&OFFSET=", TempBuffer, &FoundOffset, OffsetLength);\r
+ if (TempBuffer != NULL) {\r
+ FreePool (TempBuffer);\r
+ TempBuffer = NULL;\r
+ }\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto Exit;\r
+ }\r
+ if (!FoundOffset) {\r
+ //\r
+ // Don't find the same "&OFFSET=<Number>" block in ConfigAltResp.\r
+ // Calculate the size of <BlockConfig>.\r
+ // <BlockConfig>::='OFFSET='<Number>'&WIDTH='<Number>'&VALUE='<Number>.\r
+ //\r
+ BlockPtr = StrStr (BlockPtr + 1, L"&OFFSET=");\r
+ if (BlockPtr != NULL) {\r
+ AppendSize = (BlockPtr - BlockPtrStart) * sizeof (CHAR16);\r
+ } else {\r
+ AppendSize = StrSize (BlockPtrStart);\r
+ }\r
+ //\r
+ // Copy the <BlockConfig> to AppendString.\r
+ //\r
+ if (AppendString == NULL) {\r
+ AppendString = (EFI_STRING) AllocateZeroPool (AppendSize + sizeof (CHAR16));\r
+ StrnCatS (AppendString, AppendSize / sizeof (CHAR16) + 1, BlockPtrStart, AppendSize / sizeof (CHAR16));\r
+ } else {\r
+ TotalSize = StrSize (AppendString) + AppendSize + sizeof (CHAR16);\r
+ AppendString = (EFI_STRING) ReallocatePool (\r
+ StrSize (AppendString),\r
+ TotalSize,\r
+ AppendString\r
+ );\r
+ if (AppendString == NULL) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto Exit;\r
+ }\r
+ StrnCatS (AppendString, TotalSize / sizeof (CHAR16), BlockPtrStart, AppendSize / sizeof (CHAR16));\r
+ }\r
+ } else {\r
+ //\r
+ // To find next "&OFFSET=<Number>" block with AltConfigHdr in DefaultAltCfgResp.\r
+ //\r
+ BlockPtr = StrStr (BlockPtr + 1, L"&OFFSET=");\r
+ }\r
+ }\r
+\r
+ if (AppendString != NULL) {\r
+ //\r
+ // Reallocate ConfigAltResp to copy the AppendString.\r
+ //\r
+ TotalSize = StrSize (*ConfigAltResp) + StrSize (AppendString) + sizeof (CHAR16);\r
+ *ConfigAltResp = (EFI_STRING) ReallocatePool (\r
+ StrSize (*ConfigAltResp),\r
+ TotalSize,\r
+ *ConfigAltResp\r
+ );\r
+ if (*ConfigAltResp == NULL) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto Exit;\r
+ }\r
+ StrCatS (*ConfigAltResp, TotalSize / sizeof (CHAR16), AppendString);\r
+ *ConfigAltRespChanged = TRUE;\r
+ }\r
+\r
+ Status = EFI_SUCCESS;\r
+\r
+Exit:\r
+ if (AppendString != NULL) {\r
+ FreePool (AppendString);\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+/**\r
+ Compare the <AltResp> in ConfigAltResp and DefaultAltCfgResp, if the <AltResp>\r
+ in DefaultAltCfgResp but not in ConfigAltResp,add it to the ConfigAltResp.\r
+\r
+ @param DefaultAltCfgResp Pointer to a null-terminated Unicode string in\r
+ <MultiConfigAltResp> format. The default value\r
+ string may contain more than one ConfigAltResp\r
+ string for the different varstore buffer.\r
+ @param ConfigAltResp Pointer to a null-terminated Unicode string in\r
+ <ConfigAltResp> format.\r
+ @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 necessary structures.\r
+ @retval EFI_SUCCESS The function finishes successfully.\r
+\r
+**/\r
+EFI_STATUS\r
+CompareNameElementDefault (\r
+ IN EFI_STRING DefaultAltCfgResp,\r
+ IN OUT EFI_STRING *ConfigAltResp,\r
+ IN EFI_STRING AltConfigHdr,\r
+ IN OUT BOOLEAN *ConfigAltRespChanged\r
+)\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_STRING NvConfigPtr;\r
+ EFI_STRING NvConfigStart;\r
+ EFI_STRING NvConfigValuePtr;\r
+ EFI_STRING StringPtr;\r
+ EFI_STRING NvConfigExist;\r
+ EFI_STRING AppendString;\r
+ CHAR16 TempChar;\r
+ UINTN AppendSize;\r
+ UINTN TotalSize;\r
+\r
+ AppendString = NULL;\r
+ NvConfigExist = NULL;\r
+ //\r
+ // Make NvConfigPtr point to the first <NvConfig> with AltConfigHdr in DefaultAltCfgResp.\r
+ //\r
+ NvConfigPtr = StrStr (DefaultAltCfgResp, AltConfigHdr);\r
+ ASSERT (NvConfigPtr != NULL);\r
+ NvConfigPtr = StrStr (NvConfigPtr + StrLen(AltConfigHdr),L"&");\r
+ //\r
+ // Make StringPtr point to the first <NvConfig> with AltConfigHdr in ConfigAltResp.\r
+ //\r
+ StringPtr = StrStr (*ConfigAltResp, AltConfigHdr);\r
+ ASSERT (StringPtr != NULL);\r
+ StringPtr = StrStr (StringPtr + StrLen (AltConfigHdr), L"&");\r
+ ASSERT (StringPtr != NULL);\r
+\r
+ while (NvConfigPtr != NULL) {\r
+ //\r
+ // <NvConfig> ::= <Label>'='<String> | <Label>'='<Number>.\r
+ // Get the <Label> with AltConfigHdr in DefaultAltCfgResp.\r
+ //\r
+ NvConfigStart = NvConfigPtr;\r
+ NvConfigValuePtr = StrStr (NvConfigPtr + 1, L"=");\r
+ ASSERT (NvConfigValuePtr != NULL);\r
+ TempChar = *NvConfigValuePtr;\r
+ *NvConfigValuePtr = L'\0';\r
+ //\r
+ // Get the <Label> with AltConfigHdr in ConfigAltResp.\r
+ //\r
+ NvConfigExist = StrStr (StringPtr, NvConfigPtr);\r
+ if (NvConfigExist == NULL) {\r
+ //\r
+ // Don't find same <Label> in ConfigAltResp.\r
+ // Calculate the size of <NvConfig>.\r
+ //\r
+ *NvConfigValuePtr = TempChar;\r
+ NvConfigPtr = StrStr (NvConfigPtr + 1, L"&");\r
+ if (NvConfigPtr != NULL) {\r
+ AppendSize = (NvConfigPtr - NvConfigStart) * sizeof (CHAR16);\r
+ } else {\r
+ AppendSize = StrSize (NvConfigStart);\r
+ }\r
+ //\r
+ // Copy the <NvConfig> to AppendString.\r
+ //\r
+ if (AppendString == NULL) {\r
+ AppendString = (EFI_STRING) AllocateZeroPool (AppendSize + sizeof (CHAR16));\r
+ StrnCatS (AppendString, AppendSize / sizeof (CHAR16) + 1, NvConfigStart, AppendSize / sizeof (CHAR16));\r
+ } else {\r
+ TotalSize = StrSize (AppendString) + AppendSize + sizeof (CHAR16);\r
+ AppendString = (EFI_STRING) ReallocatePool (\r
+ StrSize (AppendString),\r
+ TotalSize,\r
+ AppendString\r
+ );\r
+ if (AppendString == NULL) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto Exit;\r
+ }\r
+ StrnCatS (AppendString, TotalSize / sizeof (CHAR16), NvConfigStart, AppendSize / sizeof (CHAR16));\r
+ }\r
+ } else {\r
+ //\r
+ // To find next <Label> in DefaultAltCfgResp.\r
+ //\r
+ *NvConfigValuePtr = TempChar;\r
+ NvConfigPtr = StrStr (NvConfigPtr + 1, L"&");\r
+ }\r
+ }\r
+ if (AppendString != NULL) {\r
+ //\r
+ // Reallocate ConfigAltResp to copy the AppendString.\r
+ //\r
+ TotalSize = StrSize (*ConfigAltResp) + StrSize (AppendString) + sizeof (CHAR16);\r
+ *ConfigAltResp = (EFI_STRING) ReallocatePool (\r
+ StrSize (*ConfigAltResp),\r
+ StrSize (*ConfigAltResp) + StrSize (AppendString) + sizeof (CHAR16),\r
+ *ConfigAltResp\r
+ );\r
+ if (*ConfigAltResp == NULL) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto Exit;\r
+ }\r
+ StrCatS (*ConfigAltResp, TotalSize / sizeof (CHAR16), AppendString);\r
+ *ConfigAltRespChanged = TRUE;\r
+ }\r
+ Status = EFI_SUCCESS;\r
+\r
+Exit:\r
+ if (AppendString != NULL) {\r
+ FreePool (AppendString);\r
+ }\r
+ return Status;\r
+}\r
+\r
+/**\r
+ Compare the <AltResp> in AltCfgResp and DefaultAltCfgResp, if the <AltResp>\r
+ in DefaultAltCfgResp but not in AltCfgResp,add it to the AltCfgResp.\r
+\r
+ @param AltCfgResp Pointer to a null-terminated Unicode string in\r
+ <ConfigAltResp> format.\r
+ @param DefaultAltCfgResp Pointer to a null-terminated Unicode string in\r
+ <MultiConfigAltResp> format. The default value\r
+ string may contain more than one ConfigAltResp\r
+ 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 necessary\r
+ structures.\r
+ @retval EFI_SUCCESS The function finishes successfully.\r
+\r
+**/\r
+EFI_STATUS\r
+CompareAndMergeDefaultString (\r
+ IN OUT EFI_STRING *AltCfgResp,\r
+ IN EFI_STRING DefaultAltCfgResp,\r
+ IN EFI_STRING AltConfigHdr\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_STRING AltCfgRespBackup;\r
+ EFI_STRING AltConfigHdrPtr;\r
+ EFI_STRING AltConfigHdrPtrNext;\r
+ EFI_STRING ConfigAltResp;\r
+ EFI_STRING StringPtr;\r
+ EFI_STRING StringPtrNext;\r
+ EFI_STRING BlockPtr;\r
+ UINTN ReallocateSize;\r
+ CHAR16 TempChar;\r
+ CHAR16 TempCharA;\r
+ BOOLEAN ConfigAltRespChanged;\r
+\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ BlockPtr = NULL;\r
+ AltConfigHdrPtrNext = NULL;\r
+ StringPtrNext = NULL;\r
+ ConfigAltResp = NULL;\r
+ AltCfgRespBackup = NULL;\r
+ TempChar = L'\0';\r
+ TempCharA = L'\0';\r
+ ConfigAltRespChanged = FALSE;\r
+\r
+ //\r
+ //To find the <AltResp> with AltConfigHdr in DefaultAltCfgResp, ignore other <AltResp> which follow it.\r
+ //\r
+ AltConfigHdrPtr = StrStr (DefaultAltCfgResp, AltConfigHdr);\r
+ ASSERT (AltConfigHdrPtr != NULL);\r
+ AltConfigHdrPtrNext = StrStr (AltConfigHdrPtr + 1, L"&GUID");\r
+ if (AltConfigHdrPtrNext != NULL) {\r
+ TempChar = *AltConfigHdrPtrNext;\r
+ *AltConfigHdrPtrNext = L'\0';\r
+ }\r
+ //\r
+ // To find the <AltResp> with AltConfigHdr in AltCfgResp, ignore other <AltResp> which follow it.\r
+ //\r
+ StringPtr = StrStr (*AltCfgResp, AltConfigHdr);\r
+ StringPtrNext = StrStr (StringPtr + 1, L"&GUID");\r
+ if (StringPtrNext != NULL) {\r
+ TempCharA = *StringPtrNext;\r
+ *StringPtrNext = L'\0';\r
+ }\r
+ //\r
+ // Copy the content of <ConfigAltResp> which contain current AltConfigHdr in AltCfgResp.\r
+ //\r
+ ConfigAltResp = AllocateCopyPool (StrSize (*AltCfgResp), *AltCfgResp);\r
+ if (ConfigAltResp == NULL) {\r
+ goto Exit;\r
+ }\r
+ //\r
+ // To find the <ConfigBody> with AltConfigHdr in DefaultAltCfgResp.\r
+ //\r
+ BlockPtr = StrStr (AltConfigHdrPtr, L"&OFFSET=");\r
+ if (BlockPtr != NULL) {\r
+ //\r
+ // <BlockConfig>::='OFFSET='<Number>'&WIDTH='<Number>'&VALUE='<Number> style.\r
+ // Call function CompareBlockElementDefault to compare the <BlockConfig> in DefaultAltCfgResp and ConfigAltResp.\r
+ // The ConfigAltResp which may contain the new <BlockConfig> get from DefaultAltCfgResp.\r
+ //\r
+ Status = CompareBlockElementDefault (DefaultAltCfgResp, &ConfigAltResp, AltConfigHdr, &ConfigAltRespChanged);\r
+ if (EFI_ERROR(Status)) {\r
+ goto Exit;\r
+ }\r
+ } else {\r
+ //\r
+ // <NvConfig> ::= <Label>'='<String> | <Label>'='<Number> style.\r
+ // Call function CompareNameElementDefault to compare the <NvConfig> in DefaultAltCfgResp and ConfigAltResp.\r
+ // The ConfigAltResp which may contain the new <NvConfig> get from DefaultAltCfgResp.\r
+ //\r
+ Status = CompareNameElementDefault (DefaultAltCfgResp, &ConfigAltResp, AltConfigHdr, &ConfigAltRespChanged);\r
+ if (EFI_ERROR(Status)) {\r
+ goto Exit;\r
+ }\r
+ }\r
+ //\r
+ // Restore the AltCfgResp.\r
+ //\r
+ if (StringPtrNext != NULL) {\r
+ *StringPtrNext = TempCharA;\r
+ }\r
+\r
+ //\r
+ // If the ConfigAltResp has no change,no need to update the content in AltCfgResp.\r
+ //\r
+ if (!ConfigAltRespChanged) {\r
+ Status = EFI_SUCCESS;\r
+ goto Exit;\r
+ }\r
+ //\r
+ // ConfigAltResp has been changed, need to update the content in AltCfgResp.\r
+ //\r
+ if (StringPtrNext != NULL) {\r
+ ReallocateSize = StrSize (ConfigAltResp) + StrSize (StringPtrNext) + sizeof (CHAR16);\r
+ } else {\r
+ ReallocateSize = StrSize (ConfigAltResp) + sizeof (CHAR16);\r
+ }\r
+\r
+ AltCfgRespBackup = (EFI_STRING) AllocateZeroPool (ReallocateSize);\r
+ if (AltCfgRespBackup == NULL) {\r
+ goto Exit;\r
+ }\r
+\r
+ StrCatS (AltCfgRespBackup, ReallocateSize / sizeof (CHAR16), ConfigAltResp);\r
+ if (StringPtrNext != NULL) {\r
+ StrCatS (AltCfgRespBackup, ReallocateSize / sizeof (CHAR16), StringPtrNext);\r
+ }\r
+\r
+ FreePool (*AltCfgResp);\r
+ *AltCfgResp = AltCfgRespBackup;\r
+\r
+ Status = EFI_SUCCESS;\r
+\r
+Exit:\r
+ if (ConfigAltResp != NULL) {\r
+ FreePool(ConfigAltResp);\r
+ }\r
+ //\r
+ // Restore the DefaultAltCfgResp.\r
+ //\r
+ if ( AltConfigHdrPtrNext != NULL) {\r
+ *AltConfigHdrPtrNext = TempChar;\r
+ AltConfigHdrPtrNext = NULL;\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
/**\r
This function merges DefaultAltCfgResp string into AltCfgResp string for\r
the missing AltCfgId in AltCfgResq.\r
}\r
\r
//\r
- // Get the requestr ConfigHdr\r
+ // Get the request ConfigHdr\r
//\r
SizeAltCfgResp = 0;\r
StringPtr = *AltCfgResp;\r
StrCatS (*AltCfgResp, TotalSize / sizeof (CHAR16), StringPtrDefault);\r
*StringPtrEnd = TempChar;\r
}\r
+ } else {\r
+ //\r
+ // The AltCfgResp contains <AltCfgResp>.\r
+ // If the <ConfigElement> in <AltCfgResp> in the DefaultAltCfgResp but not in the\r
+ // related <AltCfgResp> in AltCfgResp, merge it to AltCfgResp. else no need to merge.\r
+ //\r
+ CompareAndMergeDefaultString (AltCfgResp, DefaultAltCfgResp, AltConfigHdr);\r
}\r
\r
//\r
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
@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
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
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
} \r
\r
//\r
- // Free alllocated temp string.\r
+ // Free allocated temp string.\r
//\r
FreePool (VarStoreName);\r
FreePool (GuidStr);\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
+ @retval TRUE This varstore is the request one.\r
+ @retval FALSE This varstore is not the request one.\r
\r
**/\r
BOOLEAN\r
@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
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
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
\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
\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
@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
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
EFI_IFR_VARSTORE_NAME_VALUE *IfrNameValueVarStore;\r
EFI_HII_PACKAGE_HEADER *PackageHeader;\r
EFI_VARSTORE_ID VarStoreId;\r
+ UINT16 SmallestDefaultId;\r
+ UINT16 SmallestIdFromFlag;\r
+ BOOLEAN FromOtherDefaultOpcode;\r
\r
Status = EFI_SUCCESS;\r
BlockData = NULL;\r
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
\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
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
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
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
//\r
ASSERT (BlockData != NULL);\r
\r
+ SmallestIdFromFlag = FALSE;\r
+\r
//\r
// Add default value for standard ID by CheckBox Flag\r
//\r
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
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
\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
// 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
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
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
}\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
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
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
}\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
//\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
}\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
}\r
FreePool (BlockData);\r
}\r
+ if (VarStorageData ->Name != NULL) {\r
+ FreePool (VarStorageData ->Name);\r
+ VarStorageData ->Name = NULL;\r
+ }\r
FreePool (VarStorageData);\r
}\r
\r
}\r
\r
//\r
- // Free Pacakge data\r
+ // Free Package data\r
//\r
if (HiiFormPackage != NULL) {\r
FreePool (HiiFormPackage);\r
{\r
EFI_STATUS Status;\r
EFI_STRING VarStoreName;\r
+ UINTN NameSize;\r
UINT8 *VarStore;\r
UINTN BufferSize;\r
\r
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
{\r
EFI_STATUS Status;\r
EFI_STRING VarStoreName;\r
+ UINTN NameSize;\r
UINT8 *VarStore;\r
UINTN BufferSize;\r
UINTN BlockSize;\r
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
\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
EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess;\r
EFI_STRING AccessProgress;\r
EFI_STRING AccessResults;\r
+ EFI_STRING AccessProgressBackup;\r
+ EFI_STRING AccessResultsBackup;\r
EFI_STRING DefaultResults;\r
BOOLEAN FirstElement;\r
BOOLEAN IfrDataParsedFlag;\r
EFI_IFR_VARSTORE_EFI *EfiVarStoreInfo;\r
EFI_STRING ErrorPtr;\r
UINTN DevicePathSize;\r
+ UINTN ConigStringSize;\r
+ UINTN ConigStringSizeNewsize;\r
+ EFI_STRING ConfigStringPtr;\r
\r
if (This == NULL || Progress == NULL || Results == NULL) {\r
return EFI_INVALID_PARAMETER;\r
Status = EFI_SUCCESS;\r
AccessResults = NULL;\r
AccessProgress = NULL;\r
+ AccessResultsBackup = NULL;\r
+ AccessProgressBackup = NULL;\r
DevicePath = NULL;\r
IfrDataParsedFlag = FALSE;\r
IsEfiVarStore = FALSE;\r
//\r
Status = GetConfigRespFromEfiVarStore(This, EfiVarStoreInfo, ConfigRequest, &AccessResults, &AccessProgress);\r
FreePool (EfiVarStoreInfo);\r
+ if (EFI_ERROR (Status)) {\r
+ //\r
+ // AccessProgress indicates the parsing progress on <ConfigRequest>.\r
+ // Map it to the progress on <MultiConfigRequest> then return it.\r
+ //\r
+ *Progress = StrStr (StringPtr, AccessProgress);\r
+ goto Done;\r
+ }\r
+\r
+ //\r
+ // For EfiVarstore, call corresponding ConfigAccess protocol to get the AltCfgResp from driver.\r
+ //\r
+ Status = gBS->HandleProtocol (\r
+ DriverHandle,\r
+ &gEfiHiiConfigAccessProtocolGuid,\r
+ (VOID **) &ConfigAccess\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ //\r
+ // The driver has EfiVarStore, may not install ConfigAccess protocol.\r
+ // So ignore the error status in this case.\r
+ //\r
+ Status = EFI_SUCCESS;\r
+ } else {\r
+ Status = ConfigAccess->ExtractConfig (\r
+ ConfigAccess,\r
+ ConfigRequest,\r
+ &AccessProgressBackup,\r
+ &AccessResultsBackup\r
+ );\r
+ if (!EFI_ERROR(Status)) {\r
+ //\r
+ //Merge the AltCfgResp in AccessResultsBackup to AccessResults\r
+ //\r
+ if ((AccessResultsBackup != NULL) && (StrStr (AccessResultsBackup, L"&ALTCFG=") != NULL)) {\r
+ ConigStringSize = StrSize (AccessResults);\r
+ ConfigStringPtr = StrStr (AccessResultsBackup, L"&GUID=");\r
+ ConigStringSizeNewsize = StrSize (ConfigStringPtr) + ConigStringSize + sizeof (CHAR16);\r
+ AccessResults = (EFI_STRING) ReallocatePool (\r
+ ConigStringSize,\r
+ ConigStringSizeNewsize,\r
+ AccessResults);\r
+ StrCatS (AccessResults, ConigStringSizeNewsize / sizeof (CHAR16), ConfigStringPtr);\r
+ }\r
+ } else {\r
+ //\r
+ // In the ExtractConfig function of some driver may not support EfiVarStore,\r
+ // may return error status, just ignore the error status in this case.\r
+ //\r
+ Status = EFI_SUCCESS;\r
+ }\r
+ if (AccessResultsBackup != NULL) {\r
+ FreePool (AccessResultsBackup);\r
+ AccessResultsBackup = NULL;\r
+ }\r
+ }\r
} else {\r
//\r
// Call corresponding ConfigAccess protocol to extract settings\r
\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
\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