REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3737 Apply uncrustify changes to .c/.h files in the MdeModulePkg package Cc: Andrew Fish <afish@apple.com> Cc: Leif Lindholm <leif@nuviainc.com> Cc: Michael D Kinney <michael.d.kinney@intel.com> Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com> Reviewed-by: Liming Gao <gaoliming@byosoft.com.cn>
		
			
				
	
	
		
			807 lines
		
	
	
		
			25 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			807 lines
		
	
	
		
			25 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/** @file
 | 
						|
  Functions in this module are associated with variable parsing operations and
 | 
						|
  are intended to be usable across variable driver source files.
 | 
						|
 | 
						|
Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
 | 
						|
SPDX-License-Identifier: BSD-2-Clause-Patent
 | 
						|
 | 
						|
**/
 | 
						|
 | 
						|
#include "VariableParsing.h"
 | 
						|
 | 
						|
/**
 | 
						|
 | 
						|
  This code checks if variable header is valid or not.
 | 
						|
 | 
						|
  @param[in] Variable           Pointer to the Variable Header.
 | 
						|
  @param[in] VariableStoreEnd   Pointer to the Variable Store End.
 | 
						|
 | 
						|
  @retval TRUE              Variable header is valid.
 | 
						|
  @retval FALSE             Variable header is not valid.
 | 
						|
 | 
						|
**/
 | 
						|
BOOLEAN
 | 
						|
IsValidVariableHeader (
 | 
						|
  IN  VARIABLE_HEADER  *Variable,
 | 
						|
  IN  VARIABLE_HEADER  *VariableStoreEnd
 | 
						|
  )
 | 
						|
{
 | 
						|
  if ((Variable == NULL) || (Variable >= VariableStoreEnd) || (Variable->StartId != VARIABLE_DATA)) {
 | 
						|
    //
 | 
						|
    // Variable is NULL or has reached the end of variable store,
 | 
						|
    // or the StartId is not correct.
 | 
						|
    //
 | 
						|
    return FALSE;
 | 
						|
  }
 | 
						|
 | 
						|
  return TRUE;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 | 
						|
  This code gets the current status of Variable Store.
 | 
						|
 | 
						|
  @param[in] VarStoreHeader  Pointer to the Variable Store Header.
 | 
						|
 | 
						|
  @retval EfiRaw         Variable store status is raw.
 | 
						|
  @retval EfiValid       Variable store status is valid.
 | 
						|
  @retval EfiInvalid     Variable store status is invalid.
 | 
						|
 | 
						|
**/
 | 
						|
VARIABLE_STORE_STATUS
 | 
						|
GetVariableStoreStatus (
 | 
						|
  IN VARIABLE_STORE_HEADER  *VarStoreHeader
 | 
						|
  )
 | 
						|
{
 | 
						|
  if ((CompareGuid (&VarStoreHeader->Signature, &gEfiAuthenticatedVariableGuid) ||
 | 
						|
       CompareGuid (&VarStoreHeader->Signature, &gEfiVariableGuid)) &&
 | 
						|
      (VarStoreHeader->Format == VARIABLE_STORE_FORMATTED) &&
 | 
						|
      (VarStoreHeader->State == VARIABLE_STORE_HEALTHY)
 | 
						|
      )
 | 
						|
  {
 | 
						|
    return EfiValid;
 | 
						|
  } else if ((((UINT32 *)(&VarStoreHeader->Signature))[0] == 0xffffffff) &&
 | 
						|
             (((UINT32 *)(&VarStoreHeader->Signature))[1] == 0xffffffff) &&
 | 
						|
             (((UINT32 *)(&VarStoreHeader->Signature))[2] == 0xffffffff) &&
 | 
						|
             (((UINT32 *)(&VarStoreHeader->Signature))[3] == 0xffffffff) &&
 | 
						|
             (VarStoreHeader->Size == 0xffffffff) &&
 | 
						|
             (VarStoreHeader->Format == 0xff) &&
 | 
						|
             (VarStoreHeader->State == 0xff)
 | 
						|
             )
 | 
						|
  {
 | 
						|
    return EfiRaw;
 | 
						|
  } else {
 | 
						|
    return EfiInvalid;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  This code gets the size of variable header.
 | 
						|
 | 
						|
  @param[in]  AuthFormat    TRUE indicates authenticated variables are used.
 | 
						|
                            FALSE indicates authenticated variables are not used.
 | 
						|
 | 
						|
  @return Size of variable header in bytes in type UINTN.
 | 
						|
 | 
						|
**/
 | 
						|
UINTN
 | 
						|
GetVariableHeaderSize (
 | 
						|
  IN  BOOLEAN  AuthFormat
 | 
						|
  )
 | 
						|
{
 | 
						|
  UINTN  Value;
 | 
						|
 | 
						|
  if (AuthFormat) {
 | 
						|
    Value = sizeof (AUTHENTICATED_VARIABLE_HEADER);
 | 
						|
  } else {
 | 
						|
    Value = sizeof (VARIABLE_HEADER);
 | 
						|
  }
 | 
						|
 | 
						|
  return Value;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 | 
						|
  This code gets the size of name of variable.
 | 
						|
 | 
						|
  @param[in]  Variable      Pointer to the variable header.
 | 
						|
  @param[in]  AuthFormat    TRUE indicates authenticated variables are used.
 | 
						|
                            FALSE indicates authenticated variables are not used.
 | 
						|
 | 
						|
  @return UINTN          Size of variable in bytes.
 | 
						|
 | 
						|
**/
 | 
						|
UINTN
 | 
						|
NameSizeOfVariable (
 | 
						|
  IN  VARIABLE_HEADER  *Variable,
 | 
						|
  IN  BOOLEAN          AuthFormat
 | 
						|
  )
 | 
						|
{
 | 
						|
  AUTHENTICATED_VARIABLE_HEADER  *AuthVariable;
 | 
						|
 | 
						|
  AuthVariable = (AUTHENTICATED_VARIABLE_HEADER *)Variable;
 | 
						|
  if (AuthFormat) {
 | 
						|
    if ((AuthVariable->State == (UINT8)(-1)) ||
 | 
						|
        (AuthVariable->DataSize == (UINT32)(-1)) ||
 | 
						|
        (AuthVariable->NameSize == (UINT32)(-1)) ||
 | 
						|
        (AuthVariable->Attributes == (UINT32)(-1)))
 | 
						|
    {
 | 
						|
      return 0;
 | 
						|
    }
 | 
						|
 | 
						|
    return (UINTN)AuthVariable->NameSize;
 | 
						|
  } else {
 | 
						|
    if ((Variable->State == (UINT8)(-1)) ||
 | 
						|
        (Variable->DataSize == (UINT32)(-1)) ||
 | 
						|
        (Variable->NameSize == (UINT32)(-1)) ||
 | 
						|
        (Variable->Attributes == (UINT32)(-1)))
 | 
						|
    {
 | 
						|
      return 0;
 | 
						|
    }
 | 
						|
 | 
						|
    return (UINTN)Variable->NameSize;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  This code sets the size of name of variable.
 | 
						|
 | 
						|
  @param[in]  Variable      Pointer to the Variable Header.
 | 
						|
  @param[in]  NameSize      Name size to set.
 | 
						|
  @param[in]  AuthFormat    TRUE indicates authenticated variables are used.
 | 
						|
                            FALSE indicates authenticated variables are not used.
 | 
						|
 | 
						|
**/
 | 
						|
VOID
 | 
						|
SetNameSizeOfVariable (
 | 
						|
  IN VARIABLE_HEADER  *Variable,
 | 
						|
  IN UINTN            NameSize,
 | 
						|
  IN BOOLEAN          AuthFormat
 | 
						|
  )
 | 
						|
{
 | 
						|
  AUTHENTICATED_VARIABLE_HEADER  *AuthVariable;
 | 
						|
 | 
						|
  AuthVariable = (AUTHENTICATED_VARIABLE_HEADER *)Variable;
 | 
						|
  if (AuthFormat) {
 | 
						|
    AuthVariable->NameSize = (UINT32)NameSize;
 | 
						|
  } else {
 | 
						|
    Variable->NameSize = (UINT32)NameSize;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 | 
						|
  This code gets the size of variable data.
 | 
						|
 | 
						|
  @param[in]  Variable      Pointer to the Variable Header.
 | 
						|
  @param[in]  AuthFormat    TRUE indicates authenticated variables are used.
 | 
						|
                            FALSE indicates authenticated variables are not used.
 | 
						|
 | 
						|
  @return Size of variable in bytes.
 | 
						|
 | 
						|
**/
 | 
						|
UINTN
 | 
						|
DataSizeOfVariable (
 | 
						|
  IN  VARIABLE_HEADER  *Variable,
 | 
						|
  IN  BOOLEAN          AuthFormat
 | 
						|
  )
 | 
						|
{
 | 
						|
  AUTHENTICATED_VARIABLE_HEADER  *AuthVariable;
 | 
						|
 | 
						|
  AuthVariable = (AUTHENTICATED_VARIABLE_HEADER *)Variable;
 | 
						|
  if (AuthFormat) {
 | 
						|
    if ((AuthVariable->State == (UINT8)(-1)) ||
 | 
						|
        (AuthVariable->DataSize == (UINT32)(-1)) ||
 | 
						|
        (AuthVariable->NameSize == (UINT32)(-1)) ||
 | 
						|
        (AuthVariable->Attributes == (UINT32)(-1)))
 | 
						|
    {
 | 
						|
      return 0;
 | 
						|
    }
 | 
						|
 | 
						|
    return (UINTN)AuthVariable->DataSize;
 | 
						|
  } else {
 | 
						|
    if ((Variable->State == (UINT8)(-1)) ||
 | 
						|
        (Variable->DataSize == (UINT32)(-1)) ||
 | 
						|
        (Variable->NameSize == (UINT32)(-1)) ||
 | 
						|
        (Variable->Attributes == (UINT32)(-1)))
 | 
						|
    {
 | 
						|
      return 0;
 | 
						|
    }
 | 
						|
 | 
						|
    return (UINTN)Variable->DataSize;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  This code sets the size of variable data.
 | 
						|
 | 
						|
  @param[in] Variable   Pointer to the Variable Header.
 | 
						|
  @param[in] DataSize   Data size to set.
 | 
						|
  @param[in] AuthFormat TRUE indicates authenticated variables are used.
 | 
						|
                        FALSE indicates authenticated variables are not used.
 | 
						|
 | 
						|
**/
 | 
						|
VOID
 | 
						|
SetDataSizeOfVariable (
 | 
						|
  IN  VARIABLE_HEADER  *Variable,
 | 
						|
  IN  UINTN            DataSize,
 | 
						|
  IN  BOOLEAN          AuthFormat
 | 
						|
  )
 | 
						|
{
 | 
						|
  AUTHENTICATED_VARIABLE_HEADER  *AuthVariable;
 | 
						|
 | 
						|
  AuthVariable = (AUTHENTICATED_VARIABLE_HEADER *)Variable;
 | 
						|
  if (AuthFormat) {
 | 
						|
    AuthVariable->DataSize = (UINT32)DataSize;
 | 
						|
  } else {
 | 
						|
    Variable->DataSize = (UINT32)DataSize;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 | 
						|
  This code gets the pointer to the variable name.
 | 
						|
 | 
						|
  @param[in] Variable     Pointer to the Variable Header.
 | 
						|
  @param[in] AuthFormat   TRUE indicates authenticated variables are used.
 | 
						|
                          FALSE indicates authenticated variables are not used.
 | 
						|
 | 
						|
  @return Pointer to Variable Name which is Unicode encoding.
 | 
						|
 | 
						|
**/
 | 
						|
CHAR16 *
 | 
						|
GetVariableNamePtr (
 | 
						|
  IN  VARIABLE_HEADER  *Variable,
 | 
						|
  IN  BOOLEAN          AuthFormat
 | 
						|
  )
 | 
						|
{
 | 
						|
  return (CHAR16 *)((UINTN)Variable + GetVariableHeaderSize (AuthFormat));
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  This code gets the pointer to the variable guid.
 | 
						|
 | 
						|
  @param[in] Variable     Pointer to the Variable Header.
 | 
						|
  @param[in] AuthFormat   TRUE indicates authenticated variables are used.
 | 
						|
                          FALSE indicates authenticated variables are not used.
 | 
						|
 | 
						|
  @return A EFI_GUID* pointer to Vendor Guid.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_GUID *
 | 
						|
GetVendorGuidPtr (
 | 
						|
  IN  VARIABLE_HEADER  *Variable,
 | 
						|
  IN  BOOLEAN          AuthFormat
 | 
						|
  )
 | 
						|
{
 | 
						|
  AUTHENTICATED_VARIABLE_HEADER  *AuthVariable;
 | 
						|
 | 
						|
  AuthVariable = (AUTHENTICATED_VARIABLE_HEADER *)Variable;
 | 
						|
  if (AuthFormat) {
 | 
						|
    return &AuthVariable->VendorGuid;
 | 
						|
  } else {
 | 
						|
    return &Variable->VendorGuid;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 | 
						|
  This code gets the pointer to the variable data.
 | 
						|
 | 
						|
  @param[in] Variable     Pointer to the Variable Header.
 | 
						|
  @param[in] AuthFormat   TRUE indicates authenticated variables are used.
 | 
						|
                          FALSE indicates authenticated variables are not used.
 | 
						|
 | 
						|
  @return Pointer to Variable Data.
 | 
						|
 | 
						|
**/
 | 
						|
UINT8 *
 | 
						|
GetVariableDataPtr (
 | 
						|
  IN  VARIABLE_HEADER  *Variable,
 | 
						|
  IN  BOOLEAN          AuthFormat
 | 
						|
  )
 | 
						|
{
 | 
						|
  UINTN  Value;
 | 
						|
 | 
						|
  //
 | 
						|
  // Be careful about pad size for alignment.
 | 
						|
  //
 | 
						|
  Value  =  (UINTN)GetVariableNamePtr (Variable, AuthFormat);
 | 
						|
  Value += NameSizeOfVariable (Variable, AuthFormat);
 | 
						|
  Value += GET_PAD_SIZE (NameSizeOfVariable (Variable, AuthFormat));
 | 
						|
 | 
						|
  return (UINT8 *)Value;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  This code gets the variable data offset related to variable header.
 | 
						|
 | 
						|
  @param[in] Variable     Pointer to the Variable Header.
 | 
						|
  @param[in] AuthFormat   TRUE indicates authenticated variables are used.
 | 
						|
                          FALSE indicates authenticated variables are not used.
 | 
						|
 | 
						|
  @return Variable Data offset.
 | 
						|
 | 
						|
**/
 | 
						|
UINTN
 | 
						|
GetVariableDataOffset (
 | 
						|
  IN  VARIABLE_HEADER  *Variable,
 | 
						|
  IN  BOOLEAN          AuthFormat
 | 
						|
  )
 | 
						|
{
 | 
						|
  UINTN  Value;
 | 
						|
 | 
						|
  //
 | 
						|
  // Be careful about pad size for alignment
 | 
						|
  //
 | 
						|
  Value  = GetVariableHeaderSize (AuthFormat);
 | 
						|
  Value += NameSizeOfVariable (Variable, AuthFormat);
 | 
						|
  Value += GET_PAD_SIZE (NameSizeOfVariable (Variable, AuthFormat));
 | 
						|
 | 
						|
  return Value;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 | 
						|
  This code gets the pointer to the next variable header.
 | 
						|
 | 
						|
  @param[in] Variable     Pointer to the Variable Header.
 | 
						|
  @param[in] AuthFormat   TRUE indicates authenticated variables are used.
 | 
						|
                          FALSE indicates authenticated variables are not used.
 | 
						|
 | 
						|
  @return Pointer to next variable header.
 | 
						|
 | 
						|
**/
 | 
						|
VARIABLE_HEADER *
 | 
						|
GetNextVariablePtr (
 | 
						|
  IN  VARIABLE_HEADER  *Variable,
 | 
						|
  IN  BOOLEAN          AuthFormat
 | 
						|
  )
 | 
						|
{
 | 
						|
  UINTN  Value;
 | 
						|
 | 
						|
  Value  =  (UINTN)GetVariableDataPtr (Variable, AuthFormat);
 | 
						|
  Value += DataSizeOfVariable (Variable, AuthFormat);
 | 
						|
  Value += GET_PAD_SIZE (DataSizeOfVariable (Variable, AuthFormat));
 | 
						|
 | 
						|
  //
 | 
						|
  // Be careful about pad size for alignment.
 | 
						|
  //
 | 
						|
  return (VARIABLE_HEADER *)HEADER_ALIGN (Value);
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 | 
						|
  Gets the pointer to the first variable header in given variable store area.
 | 
						|
 | 
						|
  @param[in] VarStoreHeader  Pointer to the Variable Store Header.
 | 
						|
 | 
						|
  @return Pointer to the first variable header.
 | 
						|
 | 
						|
**/
 | 
						|
VARIABLE_HEADER *
 | 
						|
GetStartPointer (
 | 
						|
  IN VARIABLE_STORE_HEADER  *VarStoreHeader
 | 
						|
  )
 | 
						|
{
 | 
						|
  //
 | 
						|
  // The start of variable store.
 | 
						|
  //
 | 
						|
  return (VARIABLE_HEADER *)HEADER_ALIGN (VarStoreHeader + 1);
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 | 
						|
  Gets the pointer to the end of the variable storage area.
 | 
						|
 | 
						|
  This function gets pointer to the end of the variable storage
 | 
						|
  area, according to the input variable store header.
 | 
						|
 | 
						|
  @param[in] VarStoreHeader  Pointer to the Variable Store Header.
 | 
						|
 | 
						|
  @return Pointer to the end of the variable storage area.
 | 
						|
 | 
						|
**/
 | 
						|
VARIABLE_HEADER *
 | 
						|
GetEndPointer (
 | 
						|
  IN VARIABLE_STORE_HEADER  *VarStoreHeader
 | 
						|
  )
 | 
						|
{
 | 
						|
  //
 | 
						|
  // The end of variable store
 | 
						|
  //
 | 
						|
  return (VARIABLE_HEADER *)HEADER_ALIGN ((UINTN)VarStoreHeader + VarStoreHeader->Size);
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Compare two EFI_TIME data.
 | 
						|
 | 
						|
 | 
						|
  @param[in] FirstTime       A pointer to the first EFI_TIME data.
 | 
						|
  @param[in] SecondTime      A pointer to the second EFI_TIME data.
 | 
						|
 | 
						|
  @retval  TRUE              The FirstTime is not later than the SecondTime.
 | 
						|
  @retval  FALSE             The FirstTime is later than the SecondTime.
 | 
						|
 | 
						|
**/
 | 
						|
BOOLEAN
 | 
						|
VariableCompareTimeStampInternal (
 | 
						|
  IN EFI_TIME  *FirstTime,
 | 
						|
  IN EFI_TIME  *SecondTime
 | 
						|
  )
 | 
						|
{
 | 
						|
  if (FirstTime->Year != SecondTime->Year) {
 | 
						|
    return (BOOLEAN)(FirstTime->Year < SecondTime->Year);
 | 
						|
  } else if (FirstTime->Month != SecondTime->Month) {
 | 
						|
    return (BOOLEAN)(FirstTime->Month < SecondTime->Month);
 | 
						|
  } else if (FirstTime->Day != SecondTime->Day) {
 | 
						|
    return (BOOLEAN)(FirstTime->Day < SecondTime->Day);
 | 
						|
  } else if (FirstTime->Hour != SecondTime->Hour) {
 | 
						|
    return (BOOLEAN)(FirstTime->Hour < SecondTime->Hour);
 | 
						|
  } else if (FirstTime->Minute != SecondTime->Minute) {
 | 
						|
    return (BOOLEAN)(FirstTime->Minute < SecondTime->Minute);
 | 
						|
  }
 | 
						|
 | 
						|
  return (BOOLEAN)(FirstTime->Second <= SecondTime->Second);
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Find the variable in the specified variable store.
 | 
						|
 | 
						|
  @param[in]       VariableName        Name of the variable to be found
 | 
						|
  @param[in]       VendorGuid          Vendor GUID to be found.
 | 
						|
  @param[in]       IgnoreRtCheck       Ignore EFI_VARIABLE_RUNTIME_ACCESS attribute
 | 
						|
                                       check at runtime when searching variable.
 | 
						|
  @param[in, out]  PtrTrack            Variable Track Pointer structure that contains Variable Information.
 | 
						|
  @param[in]       AuthFormat          TRUE indicates authenticated variables are used.
 | 
						|
                                       FALSE indicates authenticated variables are not used.
 | 
						|
 | 
						|
  @retval          EFI_SUCCESS         Variable found successfully
 | 
						|
  @retval          EFI_NOT_FOUND       Variable not found
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
FindVariableEx (
 | 
						|
  IN     CHAR16                  *VariableName,
 | 
						|
  IN     EFI_GUID                *VendorGuid,
 | 
						|
  IN     BOOLEAN                 IgnoreRtCheck,
 | 
						|
  IN OUT VARIABLE_POINTER_TRACK  *PtrTrack,
 | 
						|
  IN     BOOLEAN                 AuthFormat
 | 
						|
  )
 | 
						|
{
 | 
						|
  VARIABLE_HEADER  *InDeletedVariable;
 | 
						|
  VOID             *Point;
 | 
						|
 | 
						|
  PtrTrack->InDeletedTransitionPtr = NULL;
 | 
						|
 | 
						|
  //
 | 
						|
  // Find the variable by walk through HOB, volatile and non-volatile variable store.
 | 
						|
  //
 | 
						|
  InDeletedVariable = NULL;
 | 
						|
 | 
						|
  for ( PtrTrack->CurrPtr = PtrTrack->StartPtr
 | 
						|
        ; IsValidVariableHeader (PtrTrack->CurrPtr, PtrTrack->EndPtr)
 | 
						|
        ; PtrTrack->CurrPtr = GetNextVariablePtr (PtrTrack->CurrPtr, AuthFormat)
 | 
						|
        )
 | 
						|
  {
 | 
						|
    if ((PtrTrack->CurrPtr->State == VAR_ADDED) ||
 | 
						|
        (PtrTrack->CurrPtr->State == (VAR_IN_DELETED_TRANSITION & VAR_ADDED))
 | 
						|
        )
 | 
						|
    {
 | 
						|
      if (IgnoreRtCheck || !AtRuntime () || ((PtrTrack->CurrPtr->Attributes & EFI_VARIABLE_RUNTIME_ACCESS) != 0)) {
 | 
						|
        if (VariableName[0] == 0) {
 | 
						|
          if (PtrTrack->CurrPtr->State == (VAR_IN_DELETED_TRANSITION & VAR_ADDED)) {
 | 
						|
            InDeletedVariable = PtrTrack->CurrPtr;
 | 
						|
          } else {
 | 
						|
            PtrTrack->InDeletedTransitionPtr = InDeletedVariable;
 | 
						|
            return EFI_SUCCESS;
 | 
						|
          }
 | 
						|
        } else {
 | 
						|
          if (CompareGuid (VendorGuid, GetVendorGuidPtr (PtrTrack->CurrPtr, AuthFormat))) {
 | 
						|
            Point = (VOID *)GetVariableNamePtr (PtrTrack->CurrPtr, AuthFormat);
 | 
						|
 | 
						|
            ASSERT (NameSizeOfVariable (PtrTrack->CurrPtr, AuthFormat) != 0);
 | 
						|
            if (CompareMem (VariableName, Point, NameSizeOfVariable (PtrTrack->CurrPtr, AuthFormat)) == 0) {
 | 
						|
              if (PtrTrack->CurrPtr->State == (VAR_IN_DELETED_TRANSITION & VAR_ADDED)) {
 | 
						|
                InDeletedVariable = PtrTrack->CurrPtr;
 | 
						|
              } else {
 | 
						|
                PtrTrack->InDeletedTransitionPtr = InDeletedVariable;
 | 
						|
                return EFI_SUCCESS;
 | 
						|
              }
 | 
						|
            }
 | 
						|
          }
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  PtrTrack->CurrPtr = InDeletedVariable;
 | 
						|
  return (PtrTrack->CurrPtr  == NULL) ? EFI_NOT_FOUND : EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  This code finds the next available variable.
 | 
						|
 | 
						|
  Caution: This function may receive untrusted input.
 | 
						|
  This function may be invoked in SMM mode. This function will do basic validation, before parse the data.
 | 
						|
 | 
						|
  @param[in]  VariableName      Pointer to variable name.
 | 
						|
  @param[in]  VendorGuid        Variable Vendor Guid.
 | 
						|
  @param[in]  VariableStoreList A list of variable stores that should be used to get the next variable.
 | 
						|
                                The maximum number of entries is the max value of VARIABLE_STORE_TYPE.
 | 
						|
  @param[out] VariablePtr       Pointer to variable header address.
 | 
						|
  @param[in]  AuthFormat        TRUE indicates authenticated variables are used.
 | 
						|
                                FALSE indicates authenticated variables are not used.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS           The function completed successfully.
 | 
						|
  @retval EFI_NOT_FOUND         The next variable was not found.
 | 
						|
  @retval EFI_INVALID_PARAMETER If VariableName is not an empty string, while VendorGuid is NULL.
 | 
						|
  @retval EFI_INVALID_PARAMETER The input values of VariableName and VendorGuid are not a name and
 | 
						|
                                GUID of an existing variable.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
VariableServiceGetNextVariableInternal (
 | 
						|
  IN  CHAR16                 *VariableName,
 | 
						|
  IN  EFI_GUID               *VendorGuid,
 | 
						|
  IN  VARIABLE_STORE_HEADER  **VariableStoreList,
 | 
						|
  OUT VARIABLE_HEADER        **VariablePtr,
 | 
						|
  IN  BOOLEAN                AuthFormat
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS              Status;
 | 
						|
  VARIABLE_STORE_TYPE     StoreType;
 | 
						|
  VARIABLE_POINTER_TRACK  Variable;
 | 
						|
  VARIABLE_POINTER_TRACK  VariableInHob;
 | 
						|
  VARIABLE_POINTER_TRACK  VariablePtrTrack;
 | 
						|
 | 
						|
  Status = EFI_NOT_FOUND;
 | 
						|
 | 
						|
  if (VariableStoreList == NULL) {
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  ZeroMem (&Variable, sizeof (Variable));
 | 
						|
 | 
						|
  // Check if the variable exists in the given variable store list
 | 
						|
  for (StoreType = (VARIABLE_STORE_TYPE)0; StoreType < VariableStoreTypeMax; StoreType++) {
 | 
						|
    if (VariableStoreList[StoreType] == NULL) {
 | 
						|
      continue;
 | 
						|
    }
 | 
						|
 | 
						|
    Variable.StartPtr = GetStartPointer (VariableStoreList[StoreType]);
 | 
						|
    Variable.EndPtr   = GetEndPointer (VariableStoreList[StoreType]);
 | 
						|
    Variable.Volatile = (BOOLEAN)(StoreType == VariableStoreTypeVolatile);
 | 
						|
 | 
						|
    Status = FindVariableEx (VariableName, VendorGuid, FALSE, &Variable, AuthFormat);
 | 
						|
    if (!EFI_ERROR (Status)) {
 | 
						|
      break;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  if ((Variable.CurrPtr == NULL) || EFI_ERROR (Status)) {
 | 
						|
    //
 | 
						|
    // For VariableName is an empty string, FindVariableEx() will try to find and return
 | 
						|
    // the first qualified variable, and if FindVariableEx() returns error (EFI_NOT_FOUND)
 | 
						|
    // as no any variable is found, still go to return the error (EFI_NOT_FOUND).
 | 
						|
    //
 | 
						|
    if (VariableName[0] != 0) {
 | 
						|
      //
 | 
						|
      // For VariableName is not an empty string, and FindVariableEx() returns error as
 | 
						|
      // VariableName and VendorGuid are not a name and GUID of an existing variable,
 | 
						|
      // there is no way to get next variable, follow spec to return EFI_INVALID_PARAMETER.
 | 
						|
      //
 | 
						|
      Status = EFI_INVALID_PARAMETER;
 | 
						|
    }
 | 
						|
 | 
						|
    goto Done;
 | 
						|
  }
 | 
						|
 | 
						|
  if (VariableName[0] != 0) {
 | 
						|
    //
 | 
						|
    // If variable name is not empty, get next variable.
 | 
						|
    //
 | 
						|
    Variable.CurrPtr = GetNextVariablePtr (Variable.CurrPtr, AuthFormat);
 | 
						|
  }
 | 
						|
 | 
						|
  while (TRUE) {
 | 
						|
    //
 | 
						|
    // Switch to the next variable store if needed
 | 
						|
    //
 | 
						|
    while (!IsValidVariableHeader (Variable.CurrPtr, Variable.EndPtr)) {
 | 
						|
      //
 | 
						|
      // Find current storage index
 | 
						|
      //
 | 
						|
      for (StoreType = (VARIABLE_STORE_TYPE)0; StoreType < VariableStoreTypeMax; StoreType++) {
 | 
						|
        if ((VariableStoreList[StoreType] != NULL) && (Variable.StartPtr == GetStartPointer (VariableStoreList[StoreType]))) {
 | 
						|
          break;
 | 
						|
        }
 | 
						|
      }
 | 
						|
 | 
						|
      ASSERT (StoreType < VariableStoreTypeMax);
 | 
						|
      //
 | 
						|
      // Switch to next storage
 | 
						|
      //
 | 
						|
      for (StoreType++; StoreType < VariableStoreTypeMax; StoreType++) {
 | 
						|
        if (VariableStoreList[StoreType] != NULL) {
 | 
						|
          break;
 | 
						|
        }
 | 
						|
      }
 | 
						|
 | 
						|
      //
 | 
						|
      // Capture the case that
 | 
						|
      // 1. current storage is the last one, or
 | 
						|
      // 2. no further storage
 | 
						|
      //
 | 
						|
      if (StoreType == VariableStoreTypeMax) {
 | 
						|
        Status = EFI_NOT_FOUND;
 | 
						|
        goto Done;
 | 
						|
      }
 | 
						|
 | 
						|
      Variable.StartPtr = GetStartPointer (VariableStoreList[StoreType]);
 | 
						|
      Variable.EndPtr   = GetEndPointer (VariableStoreList[StoreType]);
 | 
						|
      Variable.CurrPtr  = Variable.StartPtr;
 | 
						|
    }
 | 
						|
 | 
						|
    //
 | 
						|
    // Variable is found
 | 
						|
    //
 | 
						|
    if ((Variable.CurrPtr->State == VAR_ADDED) || (Variable.CurrPtr->State == (VAR_IN_DELETED_TRANSITION & VAR_ADDED))) {
 | 
						|
      if (!AtRuntime () || ((Variable.CurrPtr->Attributes & EFI_VARIABLE_RUNTIME_ACCESS) != 0)) {
 | 
						|
        if (Variable.CurrPtr->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.
 | 
						|
          //
 | 
						|
          VariablePtrTrack.StartPtr = Variable.StartPtr;
 | 
						|
          VariablePtrTrack.EndPtr   = Variable.EndPtr;
 | 
						|
          Status                    = FindVariableEx (
 | 
						|
                                        GetVariableNamePtr (Variable.CurrPtr, AuthFormat),
 | 
						|
                                        GetVendorGuidPtr (Variable.CurrPtr, AuthFormat),
 | 
						|
                                        FALSE,
 | 
						|
                                        &VariablePtrTrack,
 | 
						|
                                        AuthFormat
 | 
						|
                                        );
 | 
						|
          if (!EFI_ERROR (Status) && (VariablePtrTrack.CurrPtr->State == VAR_ADDED)) {
 | 
						|
            Variable.CurrPtr = GetNextVariablePtr (Variable.CurrPtr, AuthFormat);
 | 
						|
            continue;
 | 
						|
          }
 | 
						|
        }
 | 
						|
 | 
						|
        //
 | 
						|
        // Don't return NV variable when HOB overrides it
 | 
						|
        //
 | 
						|
        if ((VariableStoreList[VariableStoreTypeHob] != NULL) && (VariableStoreList[VariableStoreTypeNv] != NULL) &&
 | 
						|
            (Variable.StartPtr == GetStartPointer (VariableStoreList[VariableStoreTypeNv]))
 | 
						|
            )
 | 
						|
        {
 | 
						|
          VariableInHob.StartPtr = GetStartPointer (VariableStoreList[VariableStoreTypeHob]);
 | 
						|
          VariableInHob.EndPtr   = GetEndPointer (VariableStoreList[VariableStoreTypeHob]);
 | 
						|
          Status                 = FindVariableEx (
 | 
						|
                                     GetVariableNamePtr (Variable.CurrPtr, AuthFormat),
 | 
						|
                                     GetVendorGuidPtr (Variable.CurrPtr, AuthFormat),
 | 
						|
                                     FALSE,
 | 
						|
                                     &VariableInHob,
 | 
						|
                                     AuthFormat
 | 
						|
                                     );
 | 
						|
          if (!EFI_ERROR (Status)) {
 | 
						|
            Variable.CurrPtr = GetNextVariablePtr (Variable.CurrPtr, AuthFormat);
 | 
						|
            continue;
 | 
						|
          }
 | 
						|
        }
 | 
						|
 | 
						|
        *VariablePtr = Variable.CurrPtr;
 | 
						|
        Status       = EFI_SUCCESS;
 | 
						|
        goto Done;
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    Variable.CurrPtr = GetNextVariablePtr (Variable.CurrPtr, AuthFormat);
 | 
						|
  }
 | 
						|
 | 
						|
Done:
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Routine used to track statistical information about variable usage.
 | 
						|
  The data is stored in the EFI system table so it can be accessed later.
 | 
						|
  VariableInfo.efi can dump out the table. Only Boot Services variable
 | 
						|
  accesses are tracked by this code. The PcdVariableCollectStatistics
 | 
						|
  build flag controls if this feature is enabled.
 | 
						|
 | 
						|
  A read that hits in the cache will have Read and Cache true for
 | 
						|
  the transaction. Data is allocated by this routine, but never
 | 
						|
  freed.
 | 
						|
 | 
						|
  @param[in]      VariableName   Name of the Variable to track.
 | 
						|
  @param[in]      VendorGuid     Guid of the Variable to track.
 | 
						|
  @param[in]      Volatile       TRUE if volatile FALSE if non-volatile.
 | 
						|
  @param[in]      Read           TRUE if GetVariable() was called.
 | 
						|
  @param[in]      Write          TRUE if SetVariable() was called.
 | 
						|
  @param[in]      Delete         TRUE if deleted via SetVariable().
 | 
						|
  @param[in]      Cache          TRUE for a cache hit.
 | 
						|
  @param[in,out]  VariableInfo   Pointer to a pointer of VARIABLE_INFO_ENTRY structures.
 | 
						|
 | 
						|
**/
 | 
						|
VOID
 | 
						|
UpdateVariableInfo (
 | 
						|
  IN  CHAR16                  *VariableName,
 | 
						|
  IN  EFI_GUID                *VendorGuid,
 | 
						|
  IN  BOOLEAN                 Volatile,
 | 
						|
  IN  BOOLEAN                 Read,
 | 
						|
  IN  BOOLEAN                 Write,
 | 
						|
  IN  BOOLEAN                 Delete,
 | 
						|
  IN  BOOLEAN                 Cache,
 | 
						|
  IN OUT VARIABLE_INFO_ENTRY  **VariableInfo
 | 
						|
  )
 | 
						|
{
 | 
						|
  VARIABLE_INFO_ENTRY  *Entry;
 | 
						|
 | 
						|
  if (FeaturePcdGet (PcdVariableCollectStatistics)) {
 | 
						|
    if ((VariableName == NULL) || (VendorGuid == NULL) || (VariableInfo == NULL)) {
 | 
						|
      return;
 | 
						|
    }
 | 
						|
 | 
						|
    if (AtRuntime ()) {
 | 
						|
      // Don't collect statistics at runtime.
 | 
						|
      return;
 | 
						|
    }
 | 
						|
 | 
						|
    if (*VariableInfo == NULL) {
 | 
						|
      //
 | 
						|
      // On the first call allocate a entry and place a pointer to it in
 | 
						|
      // the EFI System Table.
 | 
						|
      //
 | 
						|
      *VariableInfo = AllocateZeroPool (sizeof (VARIABLE_INFO_ENTRY));
 | 
						|
      ASSERT (*VariableInfo != NULL);
 | 
						|
 | 
						|
      CopyGuid (&(*VariableInfo)->VendorGuid, VendorGuid);
 | 
						|
      (*VariableInfo)->Name = AllocateZeroPool (StrSize (VariableName));
 | 
						|
      ASSERT ((*VariableInfo)->Name != NULL);
 | 
						|
      StrCpyS ((*VariableInfo)->Name, StrSize (VariableName)/sizeof (CHAR16), VariableName);
 | 
						|
      (*VariableInfo)->Volatile = Volatile;
 | 
						|
    }
 | 
						|
 | 
						|
    for (Entry = (*VariableInfo); Entry != NULL; Entry = Entry->Next) {
 | 
						|
      if (CompareGuid (VendorGuid, &Entry->VendorGuid)) {
 | 
						|
        if (StrCmp (VariableName, Entry->Name) == 0) {
 | 
						|
          if (Read) {
 | 
						|
            Entry->ReadCount++;
 | 
						|
          }
 | 
						|
 | 
						|
          if (Write) {
 | 
						|
            Entry->WriteCount++;
 | 
						|
          }
 | 
						|
 | 
						|
          if (Delete) {
 | 
						|
            Entry->DeleteCount++;
 | 
						|
          }
 | 
						|
 | 
						|
          if (Cache) {
 | 
						|
            Entry->CacheCount++;
 | 
						|
          }
 | 
						|
 | 
						|
          return;
 | 
						|
        }
 | 
						|
      }
 | 
						|
 | 
						|
      if (Entry->Next == NULL) {
 | 
						|
        //
 | 
						|
        // If the entry is not in the table add it.
 | 
						|
        // Next iteration of the loop will fill in the data.
 | 
						|
        //
 | 
						|
        Entry->Next = AllocateZeroPool (sizeof (VARIABLE_INFO_ENTRY));
 | 
						|
        ASSERT (Entry->Next != NULL);
 | 
						|
 | 
						|
        CopyGuid (&Entry->Next->VendorGuid, VendorGuid);
 | 
						|
        Entry->Next->Name = AllocateZeroPool (StrSize (VariableName));
 | 
						|
        ASSERT (Entry->Next->Name != NULL);
 | 
						|
        StrCpyS (Entry->Next->Name, StrSize (VariableName)/sizeof (CHAR16), VariableName);
 | 
						|
        Entry->Next->Volatile = Volatile;
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 |