/** This function compares a variable with variable entries in database. @param Variable Pointer to the variable in our database @param VariableName Name of the variable to compare to 'Variable' @param VendorGuid GUID of the variable to compare to 'Variable' @param PtrTrack Variable Track Pointer structure that contains Variable Information. @retval EFI_SUCCESS Found match variable @retval EFI_NOT_FOUND Variable not found **/ EFI_STATUS CompareWithValidVariable ( IN VARIABLE_HEADER *Variable, IN CONST CHAR16 *VariableName, IN CONST EFI_GUID *VendorGuid, OUT VARIABLE_POINTER_TRACK *PtrTrack ) { VOID *Point; if (VariableName[0] == 0) { PtrTrack->CurrPtr = Variable; return EFI_SUCCESS; } else { // // Don't use CompareGuid function here for performance reasons. // Instead we compare the GUID a UINT32 at a time and branch // on the first failed comparison. // if ((((INT32 *) VendorGuid)[0] == ((INT32 *) &Variable->VendorGuid)[0]) && (((INT32 *) VendorGuid)[1] == ((INT32 *) &Variable->VendorGuid)[1]) && (((INT32 *) VendorGuid)[2] == ((INT32 *) &Variable->VendorGuid)[2]) && (((INT32 *) VendorGuid)[3] == ((INT32 *) &Variable->VendorGuid)[3]) ) { ASSERT (NameSizeOfVariable (Variable) != 0); Point = (VOID *) GetVariableNamePtr (Variable); if (CompareMem (VariableName, Point, NameSizeOfVariable (Variable)) == 0) { PtrTrack->CurrPtr = Variable; return EFI_SUCCESS; } } } return EFI_NOT_FOUND; }
/** This code gets the pointer to the variable data. @param Variable Pointer to the Variable Header. @return A UINT8* pointer to Variable Data. **/ UINT8 * GetVariableDataPtr ( IN VARIABLE_HEADER *Variable ) { UINTN Value; // // Be careful about pad size for alignment // Value = (UINTN) GetVariableNamePtr (Variable); Value += NameSizeOfVariable (Variable); Value += GET_PAD_SIZE (NameSizeOfVariable (Variable)); return (UINT8 *) Value; }
/** Return the next variable name and GUID. This function is called multiple times to retrieve the VariableName and VariableGuid of all variables currently available in the system. On each call, the previous results are passed into the interface, and, on return, the interface returns the data for the next interface. When the entire variable list has been returned, EFI_NOT_FOUND is returned. @param This A pointer to this instance of the EFI_PEI_READ_ONLY_VARIABLE2_PPI. @param VariableNameSize On entry, points to the size of the buffer pointed to by VariableName. On return, the size of the variable name buffer. @param VariableName On entry, a pointer to a null-terminated string that is the variable's name. On return, points to the next variable's null-terminated name string. @param VariableGuid On entry, a pointer to an EFI_GUID that is the variable's GUID. On return, a pointer to the next variable's GUID. @retval EFI_SUCCESS The variable was read successfully. @retval EFI_NOT_FOUND The variable could not be found. @retval EFI_BUFFER_TOO_SMALL The VariableNameSize is too small for the resulting data. VariableNameSize is updated with the size required for the specified variable. @retval EFI_INVALID_PARAMETER VariableName, VariableGuid or VariableNameSize is NULL. @retval EFI_DEVICE_ERROR The variable could not be retrieved because of a device error. **/ EFI_STATUS EFIAPI PeiGetNextVariableName ( IN CONST EFI_PEI_READ_ONLY_VARIABLE2_PPI *This, IN OUT UINTN *VariableNameSize, IN OUT CHAR16 *VariableName, IN OUT EFI_GUID *VariableGuid ) { VARIABLE_STORE_TYPE Type; VARIABLE_POINTER_TRACK Variable; VARIABLE_POINTER_TRACK VariableInHob; VARIABLE_POINTER_TRACK VariablePtrTrack; UINTN VarNameSize; EFI_STATUS Status; VARIABLE_STORE_HEADER *VariableStoreHeader[VariableStoreTypeMax]; VARIABLE_HEADER *VariableHeader; VARIABLE_STORE_INFO StoreInfo; VARIABLE_STORE_INFO StoreInfoForNv; VARIABLE_STORE_INFO StoreInfoForHob; if (VariableName == NULL || VariableGuid == NULL || VariableNameSize == NULL) { return EFI_INVALID_PARAMETER; } VariableHeader = NULL; Status = FindVariable (VariableName, VariableGuid, &Variable, &StoreInfo); if (Variable.CurrPtr == NULL || Status != EFI_SUCCESS) { return Status; } if (VariableName[0] != 0) { // // If variable name is not NULL, get next variable // GetVariableHeader (&StoreInfo, Variable.CurrPtr, &VariableHeader); Variable.CurrPtr = GetNextVariablePtr (&StoreInfo, Variable.CurrPtr, VariableHeader); } VariableStoreHeader[VariableStoreTypeHob] = GetVariableStore (VariableStoreTypeHob, &StoreInfoForHob); VariableStoreHeader[VariableStoreTypeNv] = GetVariableStore (VariableStoreTypeNv, &StoreInfoForNv); while (TRUE) { // // Switch from HOB to Non-Volatile. // while (!GetVariableHeader (&StoreInfo, Variable.CurrPtr, &VariableHeader)) { // // Find current storage index // for (Type = (VARIABLE_STORE_TYPE) 0; Type < VariableStoreTypeMax; Type++) { if ((VariableStoreHeader[Type] != NULL) && (Variable.StartPtr == GetStartPointer (VariableStoreHeader[Type]))) { break; } } ASSERT (Type < VariableStoreTypeMax); // // Switch to next storage // for (Type++; Type < VariableStoreTypeMax; Type++) { if (VariableStoreHeader[Type] != NULL) { break; } } // // Capture the case that // 1. current storage is the last one, or // 2. no further storage // if (Type == VariableStoreTypeMax) { return EFI_NOT_FOUND; } Variable.StartPtr = GetStartPointer (VariableStoreHeader[Type]); Variable.EndPtr = GetEndPointer (VariableStoreHeader[Type]); Variable.CurrPtr = Variable.StartPtr; GetVariableStore (Type, &StoreInfo); } if (VariableHeader->State == VAR_ADDED || VariableHeader->State == (VAR_IN_DELETED_TRANSITION & VAR_ADDED)) { if (VariableHeader->State == (VAR_IN_DELETED_TRANSITION & VAR_ADDED)) { // // If it is a IN_DELETED_TRANSITION variable, // and there is also a same ADDED one at the same time, // don't return it. // Status = FindVariableEx ( &StoreInfo, GetVariableNamePtr (Variable.CurrPtr, StoreInfo.AuthFlag), GetVendorGuidPtr (VariableHeader, StoreInfo.AuthFlag), &VariablePtrTrack ); if (!EFI_ERROR (Status) && VariablePtrTrack.CurrPtr != Variable.CurrPtr) { Variable.CurrPtr = GetNextVariablePtr (&StoreInfo, Variable.CurrPtr, VariableHeader); continue; } } // // Don't return NV variable when HOB overrides it // if ((VariableStoreHeader[VariableStoreTypeHob] != NULL) && (VariableStoreHeader[VariableStoreTypeNv] != NULL) && (Variable.StartPtr == GetStartPointer (VariableStoreHeader[VariableStoreTypeNv])) ) { Status = FindVariableEx ( &StoreInfoForHob, GetVariableNamePtr (Variable.CurrPtr, StoreInfo.AuthFlag), GetVendorGuidPtr (VariableHeader, StoreInfo.AuthFlag), &VariableInHob ); if (!EFI_ERROR (Status)) { Variable.CurrPtr = GetNextVariablePtr (&StoreInfo, Variable.CurrPtr, VariableHeader); continue; } } VarNameSize = NameSizeOfVariable (VariableHeader, StoreInfo.AuthFlag); ASSERT (VarNameSize != 0); if (VarNameSize <= *VariableNameSize) { GetVariableNameOrData (&StoreInfo, (UINT8 *) GetVariableNamePtr (Variable.CurrPtr, StoreInfo.AuthFlag), VarNameSize, (UINT8 *) VariableName); CopyMem (VariableGuid, GetVendorGuidPtr (VariableHeader, StoreInfo.AuthFlag), sizeof (EFI_GUID)); Status = EFI_SUCCESS; } else { Status = EFI_BUFFER_TOO_SMALL; } *VariableNameSize = VarNameSize; // // Variable is found // return Status; } else { Variable.CurrPtr = GetNextVariablePtr (&StoreInfo, Variable.CurrPtr, VariableHeader); } } }