}\r
\r
/**\r
- This code Finds the Next available variable.\r
+ This code finds the next available variable.\r
\r
Caution: This function may receive untrusted input.\r
This function may be invoked in SMM mode. This function will do basic validation, before parse the data.\r
\r
- @param[in] VariableName Pointer to variable name.\r
- @param[in] VendorGuid Variable Vendor Guid.\r
- @param[out] VariablePtr Pointer to variable header address.\r
+ @param[in] VariableName Pointer to variable name.\r
+ @param[in] VendorGuid Variable Vendor Guid.\r
+ @param[in] VariableStoreList A list of variable stores that should be used to get the next variable.\r
+ The maximum number of entries is the max value of VARIABLE_STORE_TYPE.\r
+ @param[out] VariablePtr Pointer to variable header address.\r
\r
@retval EFI_SUCCESS The function completed successfully.\r
@retval EFI_NOT_FOUND The next variable was not found.\r
VariableServiceGetNextVariableInternal (\r
IN CHAR16 *VariableName,\r
IN EFI_GUID *VendorGuid,\r
+ IN VARIABLE_STORE_HEADER **VariableStoreList,\r
OUT VARIABLE_HEADER **VariablePtr\r
)\r
{\r
- VARIABLE_STORE_TYPE Type;\r
+ EFI_STATUS Status;\r
+ VARIABLE_STORE_TYPE StoreType;\r
VARIABLE_POINTER_TRACK Variable;\r
VARIABLE_POINTER_TRACK VariableInHob;\r
VARIABLE_POINTER_TRACK VariablePtrTrack;\r
- EFI_STATUS Status;\r
- VARIABLE_STORE_HEADER *VariableStoreHeader[VariableStoreTypeMax];\r
\r
- Status = FindVariable (VariableName, VendorGuid, &Variable, &mVariableModuleGlobal->VariableGlobal, FALSE);\r
+ Status = EFI_NOT_FOUND;\r
+\r
+ if (VariableStoreList == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ // Check if the variable exists in the given variable store list\r
+ for (StoreType = (VARIABLE_STORE_TYPE) 0; StoreType < VariableStoreTypeMax; StoreType++) {\r
+ if (VariableStoreList[StoreType] == NULL) {\r
+ continue;\r
+ }\r
+\r
+ Variable.StartPtr = GetStartPointer (VariableStoreList[StoreType]);\r
+ Variable.EndPtr = GetEndPointer (VariableStoreList[StoreType]);\r
+ Variable.Volatile = (BOOLEAN) (StoreType == VariableStoreTypeVolatile);\r
+\r
+ Status = FindVariableEx (VariableName, VendorGuid, FALSE, &Variable);\r
+ if (!EFI_ERROR (Status)) {\r
+ break;\r
+ }\r
+ }\r
+\r
if (Variable.CurrPtr == NULL || EFI_ERROR (Status)) {\r
//\r
- // For VariableName is an empty string, FindVariable() will try to find and return\r
- // the first qualified variable, and if FindVariable() returns error (EFI_NOT_FOUND)\r
+ // For VariableName is an empty string, FindVariableEx() will try to find and return\r
+ // the first qualified variable, and if FindVariableEx() returns error (EFI_NOT_FOUND)\r
// as no any variable is found, still go to return the error (EFI_NOT_FOUND).\r
//\r
if (VariableName[0] != 0) {\r
//\r
- // For VariableName is not an empty string, and FindVariable() returns error as\r
+ // For VariableName is not an empty string, and FindVariableEx() returns error as\r
// VariableName and VendorGuid are not a name and GUID of an existing variable,\r
// there is no way to get next variable, follow spec to return EFI_INVALID_PARAMETER.\r
//\r
\r
if (VariableName[0] != 0) {\r
//\r
- // If variable name is not NULL, get next variable.\r
+ // If variable name is not empty, get next variable.\r
//\r
Variable.CurrPtr = GetNextVariablePtr (Variable.CurrPtr);\r
}\r
\r
- //\r
- // 0: Volatile, 1: HOB, 2: Non-Volatile.\r
- // The index and attributes mapping must be kept in this order as FindVariable\r
- // makes use of this mapping to implement search algorithm.\r
- //\r
- VariableStoreHeader[VariableStoreTypeVolatile] = (VARIABLE_STORE_HEADER *) (UINTN) mVariableModuleGlobal->VariableGlobal.VolatileVariableBase;\r
- VariableStoreHeader[VariableStoreTypeHob] = (VARIABLE_STORE_HEADER *) (UINTN) mVariableModuleGlobal->VariableGlobal.HobVariableBase;\r
- VariableStoreHeader[VariableStoreTypeNv] = mNvVariableCache;\r
-\r
while (TRUE) {\r
//\r
- // Switch from Volatile to HOB, to Non-Volatile.\r
+ // Switch to the next variable store if needed\r
//\r
while (!IsValidVariableHeader (Variable.CurrPtr, Variable.EndPtr)) {\r
//\r
// Find current storage index\r
//\r
- for (Type = (VARIABLE_STORE_TYPE) 0; Type < VariableStoreTypeMax; Type++) {\r
- if ((VariableStoreHeader[Type] != NULL) && (Variable.StartPtr == GetStartPointer (VariableStoreHeader[Type]))) {\r
+ for (StoreType = (VARIABLE_STORE_TYPE) 0; StoreType < VariableStoreTypeMax; StoreType++) {\r
+ if ((VariableStoreList[StoreType] != NULL) && (Variable.StartPtr == GetStartPointer (VariableStoreList[StoreType]))) {\r
break;\r
}\r
}\r
- ASSERT (Type < VariableStoreTypeMax);\r
+ ASSERT (StoreType < VariableStoreTypeMax);\r
//\r
// Switch to next storage\r
//\r
- for (Type++; Type < VariableStoreTypeMax; Type++) {\r
- if (VariableStoreHeader[Type] != NULL) {\r
+ for (StoreType++; StoreType < VariableStoreTypeMax; StoreType++) {\r
+ if (VariableStoreList[StoreType] != NULL) {\r
break;\r
}\r
}\r
// 1. current storage is the last one, or\r
// 2. no further storage\r
//\r
- if (Type == VariableStoreTypeMax) {\r
+ if (StoreType == VariableStoreTypeMax) {\r
Status = EFI_NOT_FOUND;\r
goto Done;\r
}\r
- Variable.StartPtr = GetStartPointer (VariableStoreHeader[Type]);\r
- Variable.EndPtr = GetEndPointer (VariableStoreHeader[Type]);\r
+ Variable.StartPtr = GetStartPointer (VariableStoreList[StoreType]);\r
+ Variable.EndPtr = GetEndPointer (VariableStoreList[StoreType]);\r
Variable.CurrPtr = Variable.StartPtr;\r
}\r
\r
//\r
// Don't return NV variable when HOB overrides it\r
//\r
- if ((VariableStoreHeader[VariableStoreTypeHob] != NULL) && (VariableStoreHeader[VariableStoreTypeNv] != NULL) &&\r
- (Variable.StartPtr == GetStartPointer (VariableStoreHeader[VariableStoreTypeNv]))\r
+ if ((VariableStoreList[VariableStoreTypeHob] != NULL) && (VariableStoreList[VariableStoreTypeNv] != NULL) &&\r
+ (Variable.StartPtr == GetStartPointer (VariableStoreList[VariableStoreTypeNv]))\r
) {\r
- VariableInHob.StartPtr = GetStartPointer (VariableStoreHeader[VariableStoreTypeHob]);\r
- VariableInHob.EndPtr = GetEndPointer (VariableStoreHeader[VariableStoreTypeHob]);\r
+ VariableInHob.StartPtr = GetStartPointer (VariableStoreList[VariableStoreTypeHob]);\r
+ VariableInHob.EndPtr = GetEndPointer (VariableStoreList[VariableStoreTypeHob]);\r
Status = FindVariableEx (\r
GetVariableNamePtr (Variable.CurrPtr),\r
GetVendorGuidPtr (Variable.CurrPtr),\r
);\r
\r
/**\r
- This code Finds the Next available variable.\r
+ This code finds the next available variable.\r
\r
Caution: This function may receive untrusted input.\r
This function may be invoked in SMM mode. This function will do basic validation, before parse the data.\r
\r
- @param[in] VariableName Pointer to variable name.\r
- @param[in] VendorGuid Variable Vendor Guid.\r
- @param[out] VariablePtr Pointer to variable header address.\r
+ @param[in] VariableName Pointer to variable name.\r
+ @param[in] VendorGuid Variable Vendor Guid.\r
+ @param[in] VariableStoreList A list of variable stores that should be used to get the next variable.\r
+ The maximum number of entries is the max value of VARIABLE_STORE_TYPE.\r
+ @param[out] VariablePtr Pointer to variable header address.\r
\r
@retval EFI_SUCCESS The function completed successfully.\r
@retval EFI_NOT_FOUND The next variable was not found.\r
- @retval EFI_INVALID_PARAMETER If VariableName is not an empty string, while VendorGuid is NULL.\r
+ @retval EFI_INVALID_PARAMETER If VariableName is nt an empty string, while VendorGuid is NULL.\r
@retval EFI_INVALID_PARAMETER The input values of VariableName and VendorGuid are not a name and\r
GUID of an existing variable.\r
\r
VariableServiceGetNextVariableInternal (\r
IN CHAR16 *VariableName,\r
IN EFI_GUID *VendorGuid,\r
+ IN VARIABLE_STORE_HEADER **VariableStoreList,\r
OUT VARIABLE_HEADER **VariablePtr\r
);\r
\r