Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Star Zeng <star.zeng@intel.com> Reviewed-by: Jiewen Yao <jiewen.yao@intel.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@16669 6f19259b-4bc3-4df7-8a09-765794883524
		
			
				
	
	
		
			1131 lines
		
	
	
		
			32 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			1131 lines
		
	
	
		
			32 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/** @file
 | 
						|
  Implementation functions and structures for var check protocol.
 | 
						|
 | 
						|
Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
 | 
						|
This program and the accompanying materials 
 | 
						|
are licensed and made available under the terms and conditions of the BSD License 
 | 
						|
which accompanies this distribution.  The full text of the license may be found at 
 | 
						|
http://opensource.org/licenses/bsd-license.php
 | 
						|
 | 
						|
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 
 | 
						|
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 | 
						|
 | 
						|
**/
 | 
						|
 | 
						|
#include "Variable.h"
 | 
						|
#include <Library/DevicePathLib.h>
 | 
						|
 | 
						|
extern LIST_ENTRY mLockedVariableList;
 | 
						|
extern BOOLEAN mEndOfDxe;
 | 
						|
extern BOOLEAN mEnableLocking;
 | 
						|
 | 
						|
#define VAR_CHECK_HANDLER_TABLE_SIZE    0x8
 | 
						|
 | 
						|
UINT32                                  mNumberOfHandler = 0;
 | 
						|
UINT32                                  mMaxNumberOfHandler = 0;
 | 
						|
VAR_CHECK_SET_VARIABLE_CHECK_HANDLER    *mHandlerTable = NULL;
 | 
						|
 | 
						|
typedef struct {
 | 
						|
  LIST_ENTRY                    Link;
 | 
						|
  EFI_GUID                      Guid;
 | 
						|
  VAR_CHECK_VARIABLE_PROPERTY   VariableProperty;
 | 
						|
  //CHAR16                        *Name;
 | 
						|
} VAR_CHECK_VARIABLE_ENTRY;
 | 
						|
 | 
						|
LIST_ENTRY mVarCheckVariableList = INITIALIZE_LIST_HEAD_VARIABLE (mVarCheckVariableList);
 | 
						|
 | 
						|
typedef
 | 
						|
EFI_STATUS
 | 
						|
(EFIAPI *INTERNAL_VAR_CHECK_FUNCTION) (
 | 
						|
  IN VAR_CHECK_VARIABLE_PROPERTY    *Propery,
 | 
						|
  IN UINTN                          DataSize,
 | 
						|
  IN VOID                           *Data
 | 
						|
  );
 | 
						|
 | 
						|
typedef struct {
 | 
						|
  CHAR16                        *Name;
 | 
						|
  VAR_CHECK_VARIABLE_PROPERTY   VariableProperty;
 | 
						|
  INTERNAL_VAR_CHECK_FUNCTION   CheckFunction;
 | 
						|
} UEFI_DEFINED_VARIABLE_ENTRY;
 | 
						|
 | 
						|
/**
 | 
						|
  Internal check for load option.
 | 
						|
 | 
						|
  @param[in] VariablePropery    Pointer to variable property.
 | 
						|
  @param[in] DataSize           Data size.
 | 
						|
  @param[in] Data               Pointer to data buffer.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS           The SetVariable check result was success.
 | 
						|
  @retval EFI_INVALID_PARAMETER The data buffer is not a valid load option.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
InternalVarCheckLoadOption (
 | 
						|
  IN VAR_CHECK_VARIABLE_PROPERTY    *VariablePropery,
 | 
						|
  IN UINTN                          DataSize,
 | 
						|
  IN VOID                           *Data
 | 
						|
  )
 | 
						|
{
 | 
						|
  UINT16                    FilePathListLength;
 | 
						|
  CHAR16                    *Description;
 | 
						|
  EFI_DEVICE_PATH_PROTOCOL  *FilePathList;
 | 
						|
 | 
						|
  FilePathListLength = *((UINT16 *) ((UINTN) Data + sizeof (UINT32)));
 | 
						|
 | 
						|
  //
 | 
						|
  // Check Description
 | 
						|
  //
 | 
						|
  Description = (CHAR16 *) ((UINTN) Data + sizeof (UINT32) + sizeof (UINT16));
 | 
						|
  while (Description < (CHAR16 *) ((UINTN) Data + DataSize)) {
 | 
						|
    if (*Description == L'\0') {
 | 
						|
      break;
 | 
						|
    }
 | 
						|
    Description++;
 | 
						|
  }
 | 
						|
  if ((UINTN) Description >= ((UINTN) Data + DataSize)) {
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
  Description++;
 | 
						|
 | 
						|
  //
 | 
						|
  // Check FilePathList
 | 
						|
  //
 | 
						|
  FilePathList = (EFI_DEVICE_PATH_PROTOCOL *) Description;
 | 
						|
  if ((UINTN) FilePathList > (MAX_ADDRESS - FilePathListLength)) {
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
  if (((UINTN) FilePathList + FilePathListLength) > ((UINTN) Data + DataSize)) {
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
  if (FilePathListLength < sizeof (EFI_DEVICE_PATH_PROTOCOL)) {
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
  if (!IsDevicePathValid (FilePathList, FilePathListLength)) {
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Internal check for key option.
 | 
						|
 | 
						|
  @param[in] VariablePropery    Pointer to variable property.
 | 
						|
  @param[in] DataSize           Data size.
 | 
						|
  @param[in] Data               Pointer to data buffer.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS           The SetVariable check result was success.
 | 
						|
  @retval EFI_INVALID_PARAMETER The data buffer is not a valid key option.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
InternalVarCheckKeyOption (
 | 
						|
  IN VAR_CHECK_VARIABLE_PROPERTY    *VariablePropery,
 | 
						|
  IN UINTN                          DataSize,
 | 
						|
  IN VOID                           *Data
 | 
						|
  )
 | 
						|
{
 | 
						|
  if (((DataSize - sizeof (EFI_KEY_OPTION)) % sizeof (EFI_INPUT_KEY)) != 0) {
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Internal check for device path.
 | 
						|
 | 
						|
  @param[in] VariablePropery    Pointer to variable property.
 | 
						|
  @param[in] DataSize           Data size.
 | 
						|
  @param[in] Data               Pointer to data buffer.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS           The SetVariable check result was success.
 | 
						|
  @retval EFI_INVALID_PARAMETER The data buffer is not a valid device path.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
InternalVarCheckDevicePath (
 | 
						|
  IN VAR_CHECK_VARIABLE_PROPERTY    *VariablePropery,
 | 
						|
  IN UINTN                          DataSize,
 | 
						|
  IN VOID                           *Data
 | 
						|
  )
 | 
						|
{
 | 
						|
  if (!IsDevicePathValid ((EFI_DEVICE_PATH_PROTOCOL *) Data, DataSize)) {
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Internal check for ASCII string.
 | 
						|
 | 
						|
  @param[in] VariablePropery    Pointer to variable property.
 | 
						|
  @param[in] DataSize           Data size.
 | 
						|
  @param[in] Data               Pointer to data buffer.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS           The SetVariable check result was success.
 | 
						|
  @retval EFI_INVALID_PARAMETER The data buffer is not a Null-terminated ASCII string.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
InternalVarCheckAsciiString (
 | 
						|
  IN VAR_CHECK_VARIABLE_PROPERTY    *VariablePropery,
 | 
						|
  IN UINTN                          DataSize,
 | 
						|
  IN VOID                           *Data
 | 
						|
  )
 | 
						|
{
 | 
						|
  CHAR8     *String;
 | 
						|
  UINTN     Index;
 | 
						|
 | 
						|
  String = (CHAR8 *) Data;
 | 
						|
  if (String[DataSize - 1] == '\0') {
 | 
						|
    return EFI_SUCCESS;
 | 
						|
  } else {
 | 
						|
    for (Index = 1; Index < DataSize && (String[DataSize - 1 - Index] != '\0'); Index++);
 | 
						|
    if (Index == DataSize) {
 | 
						|
      return EFI_INVALID_PARAMETER;
 | 
						|
    }
 | 
						|
  }
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Internal check for size array.
 | 
						|
 | 
						|
  @param[in] VariablePropery    Pointer to variable property.
 | 
						|
  @param[in] DataSize           Data size.
 | 
						|
  @param[in] Data               Pointer to data buffer.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS           The SetVariable check result was success.
 | 
						|
  @retval EFI_INVALID_PARAMETER The DataSize is not size array.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
InternalVarCheckSizeArray (
 | 
						|
  IN VAR_CHECK_VARIABLE_PROPERTY    *VariablePropery,
 | 
						|
  IN UINTN                          DataSize,
 | 
						|
  IN VOID                           *Data
 | 
						|
  )
 | 
						|
{
 | 
						|
  if ((DataSize % VariablePropery->MinSize) != 0) {
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
//
 | 
						|
// To prevent name collisions with possible future globally defined variables,
 | 
						|
// other internal firmware data variables that are not defined here must be
 | 
						|
// saved with a unique VendorGuid other than EFI_GLOBAL_VARIABLE or
 | 
						|
// any other GUID defined by the UEFI Specification. Implementations must
 | 
						|
// only permit the creation of variables with a UEFI Specification-defined
 | 
						|
// VendorGuid when these variables are documented in the UEFI Specification.
 | 
						|
//
 | 
						|
UEFI_DEFINED_VARIABLE_ENTRY mGlobalVariableList[] = {
 | 
						|
  {
 | 
						|
    EFI_LANG_CODES_VARIABLE_NAME,
 | 
						|
    {
 | 
						|
      VAR_CHECK_VARIABLE_PROPERTY_REVISION,
 | 
						|
      0,
 | 
						|
      VARIABLE_ATTRIBUTE_BS_RT,
 | 
						|
      1,
 | 
						|
      MAX_UINTN
 | 
						|
    },
 | 
						|
    InternalVarCheckAsciiString
 | 
						|
  },
 | 
						|
  {
 | 
						|
    EFI_LANG_VARIABLE_NAME,
 | 
						|
    {
 | 
						|
      VAR_CHECK_VARIABLE_PROPERTY_REVISION,
 | 
						|
      0,
 | 
						|
      VARIABLE_ATTRIBUTE_NV_BS_RT,
 | 
						|
      1,
 | 
						|
      MAX_UINTN
 | 
						|
    },
 | 
						|
    InternalVarCheckAsciiString
 | 
						|
  },
 | 
						|
  {
 | 
						|
    EFI_TIME_OUT_VARIABLE_NAME,
 | 
						|
    {
 | 
						|
      VAR_CHECK_VARIABLE_PROPERTY_REVISION,
 | 
						|
      0,
 | 
						|
      VARIABLE_ATTRIBUTE_NV_BS_RT,
 | 
						|
      sizeof (UINT16),
 | 
						|
      sizeof (UINT16)
 | 
						|
    },
 | 
						|
    NULL
 | 
						|
  },
 | 
						|
  {
 | 
						|
    EFI_PLATFORM_LANG_CODES_VARIABLE_NAME,
 | 
						|
    {
 | 
						|
      VAR_CHECK_VARIABLE_PROPERTY_REVISION,
 | 
						|
      0,
 | 
						|
      VARIABLE_ATTRIBUTE_BS_RT,
 | 
						|
      1,
 | 
						|
      MAX_UINTN
 | 
						|
    },
 | 
						|
    InternalVarCheckAsciiString
 | 
						|
  },
 | 
						|
  {
 | 
						|
    EFI_PLATFORM_LANG_VARIABLE_NAME,
 | 
						|
    {
 | 
						|
      VAR_CHECK_VARIABLE_PROPERTY_REVISION,
 | 
						|
      0,
 | 
						|
      VARIABLE_ATTRIBUTE_NV_BS_RT,
 | 
						|
      1,
 | 
						|
      MAX_UINTN
 | 
						|
    },
 | 
						|
    InternalVarCheckAsciiString
 | 
						|
  },
 | 
						|
  {
 | 
						|
    EFI_CON_IN_VARIABLE_NAME,
 | 
						|
    {
 | 
						|
      VAR_CHECK_VARIABLE_PROPERTY_REVISION,
 | 
						|
      0,
 | 
						|
      VARIABLE_ATTRIBUTE_NV_BS_RT,
 | 
						|
      sizeof (EFI_DEVICE_PATH_PROTOCOL),
 | 
						|
      MAX_UINTN
 | 
						|
    },
 | 
						|
    InternalVarCheckDevicePath
 | 
						|
  },
 | 
						|
  {
 | 
						|
    EFI_CON_OUT_VARIABLE_NAME,
 | 
						|
    {
 | 
						|
      VAR_CHECK_VARIABLE_PROPERTY_REVISION,
 | 
						|
      0,
 | 
						|
      VARIABLE_ATTRIBUTE_NV_BS_RT,
 | 
						|
      sizeof (EFI_DEVICE_PATH_PROTOCOL),
 | 
						|
      MAX_UINTN
 | 
						|
    },
 | 
						|
    InternalVarCheckDevicePath
 | 
						|
  },
 | 
						|
  {
 | 
						|
    EFI_ERR_OUT_VARIABLE_NAME,
 | 
						|
    {
 | 
						|
      VAR_CHECK_VARIABLE_PROPERTY_REVISION,
 | 
						|
      0,
 | 
						|
      VARIABLE_ATTRIBUTE_NV_BS_RT,
 | 
						|
      sizeof (EFI_DEVICE_PATH_PROTOCOL),
 | 
						|
      MAX_UINTN
 | 
						|
    },
 | 
						|
    InternalVarCheckDevicePath
 | 
						|
  },
 | 
						|
  {
 | 
						|
    EFI_CON_IN_DEV_VARIABLE_NAME,
 | 
						|
    {
 | 
						|
      VAR_CHECK_VARIABLE_PROPERTY_REVISION,
 | 
						|
      0,
 | 
						|
      VARIABLE_ATTRIBUTE_BS_RT,
 | 
						|
      sizeof (EFI_DEVICE_PATH_PROTOCOL),
 | 
						|
      MAX_UINTN
 | 
						|
    },
 | 
						|
    InternalVarCheckDevicePath
 | 
						|
  },
 | 
						|
  {
 | 
						|
    EFI_CON_OUT_DEV_VARIABLE_NAME,
 | 
						|
    {
 | 
						|
      VAR_CHECK_VARIABLE_PROPERTY_REVISION,
 | 
						|
      0,
 | 
						|
      VARIABLE_ATTRIBUTE_BS_RT,
 | 
						|
      sizeof (EFI_DEVICE_PATH_PROTOCOL),
 | 
						|
      MAX_UINTN
 | 
						|
    },
 | 
						|
    InternalVarCheckDevicePath
 | 
						|
  },
 | 
						|
  {
 | 
						|
    EFI_ERR_OUT_DEV_VARIABLE_NAME,
 | 
						|
    {
 | 
						|
      VAR_CHECK_VARIABLE_PROPERTY_REVISION,
 | 
						|
      0,
 | 
						|
      VARIABLE_ATTRIBUTE_BS_RT,
 | 
						|
      sizeof (EFI_DEVICE_PATH_PROTOCOL),
 | 
						|
      MAX_UINTN
 | 
						|
    },
 | 
						|
    InternalVarCheckDevicePath
 | 
						|
  },
 | 
						|
  {
 | 
						|
    EFI_BOOT_ORDER_VARIABLE_NAME,
 | 
						|
    {
 | 
						|
      VAR_CHECK_VARIABLE_PROPERTY_REVISION,
 | 
						|
      0,
 | 
						|
      VARIABLE_ATTRIBUTE_NV_BS_RT,
 | 
						|
      sizeof (UINT16),
 | 
						|
      MAX_UINTN
 | 
						|
    },
 | 
						|
    InternalVarCheckSizeArray
 | 
						|
  },
 | 
						|
  {
 | 
						|
    EFI_BOOT_NEXT_VARIABLE_NAME,
 | 
						|
    {
 | 
						|
      VAR_CHECK_VARIABLE_PROPERTY_REVISION,
 | 
						|
      0,
 | 
						|
      VARIABLE_ATTRIBUTE_NV_BS_RT,
 | 
						|
      sizeof (UINT16),
 | 
						|
      sizeof (UINT16)
 | 
						|
    },
 | 
						|
    NULL
 | 
						|
  },
 | 
						|
  {
 | 
						|
    EFI_BOOT_CURRENT_VARIABLE_NAME,
 | 
						|
    {
 | 
						|
      VAR_CHECK_VARIABLE_PROPERTY_REVISION,
 | 
						|
      0,
 | 
						|
      VARIABLE_ATTRIBUTE_BS_RT,
 | 
						|
      sizeof (UINT16),
 | 
						|
      sizeof (UINT16)
 | 
						|
    },
 | 
						|
    NULL
 | 
						|
  },
 | 
						|
  {
 | 
						|
    EFI_BOOT_OPTION_SUPPORT_VARIABLE_NAME,
 | 
						|
    {
 | 
						|
      VAR_CHECK_VARIABLE_PROPERTY_REVISION,
 | 
						|
      0,
 | 
						|
      VARIABLE_ATTRIBUTE_BS_RT,
 | 
						|
      sizeof (UINT32),
 | 
						|
      sizeof (UINT32)
 | 
						|
    },
 | 
						|
    NULL
 | 
						|
  },
 | 
						|
  {
 | 
						|
    EFI_DRIVER_ORDER_VARIABLE_NAME,
 | 
						|
    {
 | 
						|
      VAR_CHECK_VARIABLE_PROPERTY_REVISION,
 | 
						|
      0,
 | 
						|
      VARIABLE_ATTRIBUTE_NV_BS_RT,
 | 
						|
      sizeof (UINT16),
 | 
						|
      MAX_UINTN
 | 
						|
    },
 | 
						|
    InternalVarCheckSizeArray
 | 
						|
  },
 | 
						|
  {
 | 
						|
    EFI_HW_ERR_REC_SUPPORT_VARIABLE_NAME,
 | 
						|
    {
 | 
						|
      VAR_CHECK_VARIABLE_PROPERTY_REVISION,
 | 
						|
      0,
 | 
						|
      VARIABLE_ATTRIBUTE_NV_BS_RT,
 | 
						|
      sizeof (UINT16),
 | 
						|
      sizeof (UINT16)
 | 
						|
    },
 | 
						|
    NULL
 | 
						|
  },
 | 
						|
  {
 | 
						|
    EFI_SETUP_MODE_NAME,
 | 
						|
    {
 | 
						|
      VAR_CHECK_VARIABLE_PROPERTY_REVISION,
 | 
						|
      VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY,
 | 
						|
      VARIABLE_ATTRIBUTE_BS_RT,
 | 
						|
      sizeof (UINT8),
 | 
						|
      sizeof (UINT8)
 | 
						|
    },
 | 
						|
    NULL
 | 
						|
  },
 | 
						|
  {
 | 
						|
    EFI_KEY_EXCHANGE_KEY_NAME,
 | 
						|
    {
 | 
						|
      VAR_CHECK_VARIABLE_PROPERTY_REVISION,
 | 
						|
      0,
 | 
						|
      VARIABLE_ATTRIBUTE_NV_BS_RT_AT,
 | 
						|
      1,
 | 
						|
      MAX_UINTN
 | 
						|
    },
 | 
						|
    NULL
 | 
						|
  },
 | 
						|
  {
 | 
						|
    EFI_PLATFORM_KEY_NAME,
 | 
						|
    {
 | 
						|
      VAR_CHECK_VARIABLE_PROPERTY_REVISION,
 | 
						|
      0,
 | 
						|
      VARIABLE_ATTRIBUTE_NV_BS_RT_AT,
 | 
						|
      1,
 | 
						|
      MAX_UINTN
 | 
						|
    },
 | 
						|
    NULL
 | 
						|
  },
 | 
						|
  {
 | 
						|
    EFI_SIGNATURE_SUPPORT_NAME,
 | 
						|
    {
 | 
						|
      VAR_CHECK_VARIABLE_PROPERTY_REVISION,
 | 
						|
      VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY,
 | 
						|
      VARIABLE_ATTRIBUTE_BS_RT,
 | 
						|
      sizeof (EFI_GUID),
 | 
						|
      MAX_UINTN
 | 
						|
    },
 | 
						|
    InternalVarCheckSizeArray
 | 
						|
  },
 | 
						|
  {
 | 
						|
    EFI_SECURE_BOOT_MODE_NAME,
 | 
						|
    {
 | 
						|
      VAR_CHECK_VARIABLE_PROPERTY_REVISION,
 | 
						|
      VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY,
 | 
						|
      VARIABLE_ATTRIBUTE_BS_RT,
 | 
						|
      sizeof (UINT8),
 | 
						|
      sizeof (UINT8)
 | 
						|
    },
 | 
						|
    NULL
 | 
						|
  },
 | 
						|
  {
 | 
						|
    EFI_KEK_DEFAULT_VARIABLE_NAME,
 | 
						|
    {
 | 
						|
      VAR_CHECK_VARIABLE_PROPERTY_REVISION,
 | 
						|
      VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY,
 | 
						|
      VARIABLE_ATTRIBUTE_BS_RT,
 | 
						|
      1,
 | 
						|
      MAX_UINTN
 | 
						|
    },
 | 
						|
    NULL
 | 
						|
  },
 | 
						|
  {
 | 
						|
    EFI_PK_DEFAULT_VARIABLE_NAME,
 | 
						|
    {
 | 
						|
      VAR_CHECK_VARIABLE_PROPERTY_REVISION,
 | 
						|
      VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY,
 | 
						|
      VARIABLE_ATTRIBUTE_BS_RT,
 | 
						|
      1,
 | 
						|
      MAX_UINTN
 | 
						|
    },
 | 
						|
    NULL
 | 
						|
  },
 | 
						|
  {
 | 
						|
    EFI_DB_DEFAULT_VARIABLE_NAME,
 | 
						|
    {
 | 
						|
      VAR_CHECK_VARIABLE_PROPERTY_REVISION,
 | 
						|
      VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY,
 | 
						|
      VARIABLE_ATTRIBUTE_BS_RT,
 | 
						|
      1,
 | 
						|
      MAX_UINTN
 | 
						|
    },
 | 
						|
    NULL
 | 
						|
  },
 | 
						|
  {
 | 
						|
    EFI_DBX_DEFAULT_VARIABLE_NAME,
 | 
						|
    {
 | 
						|
      VAR_CHECK_VARIABLE_PROPERTY_REVISION,
 | 
						|
      VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY,
 | 
						|
      VARIABLE_ATTRIBUTE_BS_RT,
 | 
						|
      1,
 | 
						|
      MAX_UINTN
 | 
						|
    },
 | 
						|
    NULL
 | 
						|
  },
 | 
						|
  {
 | 
						|
    EFI_DBT_DEFAULT_VARIABLE_NAME,
 | 
						|
    {
 | 
						|
      VAR_CHECK_VARIABLE_PROPERTY_REVISION,
 | 
						|
      VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY,
 | 
						|
      VARIABLE_ATTRIBUTE_BS_RT,
 | 
						|
      1,
 | 
						|
      MAX_UINTN
 | 
						|
    },
 | 
						|
    NULL
 | 
						|
  },
 | 
						|
  {
 | 
						|
    EFI_OS_INDICATIONS_SUPPORT_VARIABLE_NAME,
 | 
						|
    {
 | 
						|
      VAR_CHECK_VARIABLE_PROPERTY_REVISION,
 | 
						|
      0,
 | 
						|
      VARIABLE_ATTRIBUTE_BS_RT,
 | 
						|
      sizeof (UINT64),
 | 
						|
      sizeof (UINT64)
 | 
						|
    },
 | 
						|
    NULL
 | 
						|
  },
 | 
						|
  {
 | 
						|
    EFI_OS_INDICATIONS_VARIABLE_NAME,
 | 
						|
    {
 | 
						|
      VAR_CHECK_VARIABLE_PROPERTY_REVISION,
 | 
						|
      0,
 | 
						|
      VARIABLE_ATTRIBUTE_NV_BS_RT,
 | 
						|
      sizeof (UINT64),
 | 
						|
      sizeof (UINT64)
 | 
						|
    },
 | 
						|
    NULL
 | 
						|
  },
 | 
						|
  {
 | 
						|
    EFI_VENDOR_KEYS_VARIABLE_NAME,
 | 
						|
    {
 | 
						|
      VAR_CHECK_VARIABLE_PROPERTY_REVISION,
 | 
						|
      VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY,
 | 
						|
      VARIABLE_ATTRIBUTE_BS_RT,
 | 
						|
      sizeof (UINT8),
 | 
						|
      sizeof (UINT8)
 | 
						|
    },
 | 
						|
    NULL
 | 
						|
  },
 | 
						|
};
 | 
						|
UEFI_DEFINED_VARIABLE_ENTRY mGlobalVariableList2[] = {
 | 
						|
  {
 | 
						|
    L"Boot####",
 | 
						|
    {
 | 
						|
      VAR_CHECK_VARIABLE_PROPERTY_REVISION,
 | 
						|
      0,
 | 
						|
      VARIABLE_ATTRIBUTE_NV_BS_RT,
 | 
						|
      sizeof (UINT32) + sizeof (UINT16),
 | 
						|
      MAX_UINTN
 | 
						|
    },
 | 
						|
    InternalVarCheckLoadOption
 | 
						|
  },
 | 
						|
  {
 | 
						|
    L"Driver####",
 | 
						|
    {
 | 
						|
      VAR_CHECK_VARIABLE_PROPERTY_REVISION,
 | 
						|
      0,
 | 
						|
      VARIABLE_ATTRIBUTE_NV_BS_RT,
 | 
						|
      sizeof (UINT32) + sizeof (UINT16),
 | 
						|
      MAX_UINTN
 | 
						|
    },
 | 
						|
    InternalVarCheckLoadOption
 | 
						|
  },
 | 
						|
  {
 | 
						|
    L"Key####",
 | 
						|
    {
 | 
						|
      VAR_CHECK_VARIABLE_PROPERTY_REVISION,
 | 
						|
      0,
 | 
						|
      VARIABLE_ATTRIBUTE_NV_BS_RT,
 | 
						|
      sizeof (EFI_KEY_OPTION),
 | 
						|
      sizeof (EFI_KEY_OPTION) + 3 * sizeof (EFI_INPUT_KEY)
 | 
						|
    },
 | 
						|
    InternalVarCheckKeyOption
 | 
						|
  },
 | 
						|
};
 | 
						|
 | 
						|
typedef struct {
 | 
						|
  EFI_GUID                      *Guid;
 | 
						|
  CHAR16                        *Name;
 | 
						|
  VAR_CHECK_VARIABLE_PROPERTY   VariableProperty;
 | 
						|
} VARIABLE_DRIVER_VARIABLE_ENTRY;
 | 
						|
 | 
						|
VARIABLE_DRIVER_VARIABLE_ENTRY mVariableDriverVariableList[] = {
 | 
						|
  {
 | 
						|
    &gEdkiiVarErrorFlagGuid,
 | 
						|
    VAR_ERROR_FLAG_NAME,
 | 
						|
    {
 | 
						|
      VAR_CHECK_VARIABLE_PROPERTY_REVISION,
 | 
						|
      VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY,
 | 
						|
      VARIABLE_ATTRIBUTE_NV_BS_RT,
 | 
						|
      sizeof (VAR_ERROR_FLAG),
 | 
						|
      sizeof (VAR_ERROR_FLAG),
 | 
						|
    }
 | 
						|
  },
 | 
						|
};
 | 
						|
 | 
						|
/**
 | 
						|
  Get UEFI defined global variable property.
 | 
						|
  The code will check if variable guid is global variable guid first.
 | 
						|
  If yes, further check if variable name is in mGlobalVariableList or mGlobalVariableList2.
 | 
						|
 | 
						|
  @param[in]  VariableName      Pointer to variable name.
 | 
						|
  @param[in]  VendorGuid        Variable Vendor Guid.
 | 
						|
  @param[in]  WildcardMatch     Try wildcard match or not.
 | 
						|
  @param[out] VariableProperty  Pointer to variable property.
 | 
						|
  @param[out] VarCheckFunction  Pointer to check function.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS           Variable is not global variable.
 | 
						|
  @retval EFI_INVALID_PARAMETER Variable is global variable, but variable name is not in the lists.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
GetUefiDefinedVariableProperty (
 | 
						|
  IN CHAR16                         *VariableName,
 | 
						|
  IN EFI_GUID                       *VendorGuid,
 | 
						|
  IN BOOLEAN                        WildcardMatch,
 | 
						|
  OUT VAR_CHECK_VARIABLE_PROPERTY   **VariableProperty,
 | 
						|
  OUT INTERNAL_VAR_CHECK_FUNCTION   *VarCheckFunction OPTIONAL
 | 
						|
  )
 | 
						|
{
 | 
						|
  UINTN     Index;
 | 
						|
  UINTN     NameLength;
 | 
						|
 | 
						|
  if (CompareGuid (VendorGuid, &gEfiGlobalVariableGuid)) {
 | 
						|
    //
 | 
						|
    // Try list 1, exactly match.
 | 
						|
    //
 | 
						|
    for (Index = 0; Index < sizeof (mGlobalVariableList)/sizeof (mGlobalVariableList[0]); Index++) {
 | 
						|
      if (StrCmp (mGlobalVariableList[Index].Name, VariableName) == 0) {
 | 
						|
        if (VarCheckFunction != NULL) {
 | 
						|
          *VarCheckFunction = mGlobalVariableList[Index].CheckFunction;
 | 
						|
        }
 | 
						|
        *VariableProperty = &mGlobalVariableList[Index].VariableProperty;
 | 
						|
        return EFI_SUCCESS;
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    //
 | 
						|
    // Try list 2.
 | 
						|
    //
 | 
						|
    NameLength = StrLen (VariableName) - 4;
 | 
						|
    for (Index = 0; Index < sizeof (mGlobalVariableList2)/sizeof (mGlobalVariableList2[0]); Index++) {
 | 
						|
      if (WildcardMatch) {
 | 
						|
        if ((StrLen (VariableName) == StrLen (mGlobalVariableList2[Index].Name)) &&
 | 
						|
            (StrnCmp (mGlobalVariableList2[Index].Name, VariableName, NameLength) == 0) &&
 | 
						|
            IsHexaDecimalDigitCharacter (VariableName[NameLength]) &&
 | 
						|
            IsHexaDecimalDigitCharacter (VariableName[NameLength + 1]) &&
 | 
						|
            IsHexaDecimalDigitCharacter (VariableName[NameLength + 2]) &&
 | 
						|
            IsHexaDecimalDigitCharacter (VariableName[NameLength + 3])) {
 | 
						|
          if (VarCheckFunction != NULL) {
 | 
						|
            *VarCheckFunction = mGlobalVariableList2[Index].CheckFunction;
 | 
						|
          }
 | 
						|
          *VariableProperty = &mGlobalVariableList2[Index].VariableProperty;
 | 
						|
          return EFI_SUCCESS;
 | 
						|
        }
 | 
						|
      }
 | 
						|
      if (StrCmp (mGlobalVariableList2[Index].Name, VariableName) == 0) {
 | 
						|
        if (VarCheckFunction != NULL) {
 | 
						|
          *VarCheckFunction = mGlobalVariableList2[Index].CheckFunction;
 | 
						|
        }
 | 
						|
        *VariableProperty = &mGlobalVariableList2[Index].VariableProperty;
 | 
						|
        return EFI_SUCCESS;
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    //
 | 
						|
    // The variable name is not in the lists.
 | 
						|
    //
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // It is not global variable.
 | 
						|
  //
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Get variable property for variables managed by Varaible driver.
 | 
						|
 | 
						|
  @param[in]  VariableName      Pointer to variable name.
 | 
						|
  @param[in]  VendorGuid        Variable Vendor Guid.
 | 
						|
 | 
						|
  @return Pointer to variable property.
 | 
						|
 | 
						|
**/
 | 
						|
VAR_CHECK_VARIABLE_PROPERTY *
 | 
						|
GetVariableDriverVariableProperty (
 | 
						|
  IN CHAR16                         *VariableName,
 | 
						|
  IN EFI_GUID                       *VendorGuid
 | 
						|
  )
 | 
						|
{
 | 
						|
  UINTN     Index;
 | 
						|
 | 
						|
  for (Index = 0; Index < sizeof (mVariableDriverVariableList)/sizeof (mVariableDriverVariableList[0]); Index++) {
 | 
						|
    if ((CompareGuid (mVariableDriverVariableList[Index].Guid, VendorGuid)) && (StrCmp (mVariableDriverVariableList[Index].Name, VariableName) == 0)) {
 | 
						|
      return &mVariableDriverVariableList[Index].VariableProperty;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  return NULL;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Internal SetVariable check.
 | 
						|
 | 
						|
  @param[in] VariableName       Name of Variable to set.
 | 
						|
  @param[in] VendorGuid         Variable vendor GUID.
 | 
						|
  @param[in] Attributes         Attribute value of the variable.
 | 
						|
  @param[in] DataSize           Size of Data to set.
 | 
						|
  @param[in] Data               Data pointer.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS           The SetVariable check result was success.
 | 
						|
  @retval EFI_INVALID_PARAMETER An invalid combination of attribute bits, name, and GUID was supplied,
 | 
						|
                                or the DataSize exceeds the minimum or maximum allowed,
 | 
						|
                                or the Data value is not following UEFI spec for UEFI defined variables.
 | 
						|
  @retval EFI_WRITE_PROTECTED   The variable in question is read-only.
 | 
						|
  @retval Others                The return status from check handler.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
InternalVarCheckSetVariableCheck (
 | 
						|
  IN CHAR16     *VariableName,
 | 
						|
  IN EFI_GUID   *VendorGuid,
 | 
						|
  IN UINT32     Attributes,
 | 
						|
  IN UINTN      DataSize,
 | 
						|
  IN VOID       *Data
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS                    Status;
 | 
						|
  UINTN                         Index;
 | 
						|
  LIST_ENTRY                    *Link;
 | 
						|
  VAR_CHECK_VARIABLE_ENTRY      *Entry;
 | 
						|
  CHAR16                        *Name;
 | 
						|
  VAR_CHECK_VARIABLE_PROPERTY   *Property;
 | 
						|
  INTERNAL_VAR_CHECK_FUNCTION   VarCheckFunction;
 | 
						|
 | 
						|
  if (!mEndOfDxe) {
 | 
						|
    //
 | 
						|
    // Only do check after End Of Dxe.
 | 
						|
    //
 | 
						|
    return EFI_SUCCESS;
 | 
						|
  }
 | 
						|
 | 
						|
  Property = NULL;
 | 
						|
  VarCheckFunction = NULL;
 | 
						|
 | 
						|
  for ( Link = GetFirstNode (&mVarCheckVariableList)
 | 
						|
      ; !IsNull (&mVarCheckVariableList, Link)
 | 
						|
      ; Link = GetNextNode (&mVarCheckVariableList, Link)
 | 
						|
      ) {
 | 
						|
    Entry = BASE_CR (Link, VAR_CHECK_VARIABLE_ENTRY, Link);
 | 
						|
    Name = (CHAR16 *) ((UINTN) Entry + sizeof (*Entry));
 | 
						|
    if (CompareGuid (&Entry->Guid, VendorGuid) && (StrCmp (Name, VariableName) == 0)) {
 | 
						|
      Property = &Entry->VariableProperty;
 | 
						|
      break;
 | 
						|
    }
 | 
						|
  }
 | 
						|
  if (Property == NULL) {
 | 
						|
    Property = GetVariableDriverVariableProperty (VariableName, VendorGuid);
 | 
						|
  }
 | 
						|
  if (Property == NULL) {
 | 
						|
    Status = GetUefiDefinedVariableProperty (VariableName, VendorGuid, TRUE, &Property, &VarCheckFunction);
 | 
						|
    if (EFI_ERROR (Status)) {
 | 
						|
      DEBUG ((EFI_D_INFO, "[Variable]: Var Check UEFI defined variable fail %r - %g:%s\n", Status, VendorGuid, VariableName));
 | 
						|
      return Status;
 | 
						|
    }
 | 
						|
  }
 | 
						|
  if (Property != NULL) {
 | 
						|
    if (mEnableLocking && ((Property->Property & VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY) != 0)) {
 | 
						|
      DEBUG ((EFI_D_INFO, "[Variable]: Var Check ReadOnly variable fail %r - %g:%s\n", EFI_WRITE_PROTECTED, VendorGuid, VariableName));
 | 
						|
      return EFI_WRITE_PROTECTED;
 | 
						|
    }
 | 
						|
    if (!((DataSize == 0) || (Attributes == 0))) {
 | 
						|
      //
 | 
						|
      // Not to delete variable.
 | 
						|
      //
 | 
						|
      if (Attributes != Property->Attributes) {
 | 
						|
        DEBUG ((EFI_D_INFO, "[Variable]: Var Check Attributes(0x%08x to 0x%08x) fail %r - %g:%s\n", Property->Attributes, Attributes, EFI_INVALID_PARAMETER, VendorGuid, VariableName));
 | 
						|
        return EFI_INVALID_PARAMETER;
 | 
						|
      }
 | 
						|
      if ((DataSize < Property->MinSize) || (DataSize > Property->MaxSize)) {
 | 
						|
        DEBUG ((EFI_D_INFO, "[Variable]: Var Check DataSize fail(0x%x not in 0x%x - 0x%x) %r - %g:%s\n", DataSize, Property->MinSize, Property->MaxSize, EFI_INVALID_PARAMETER, VendorGuid, VariableName));
 | 
						|
        return EFI_INVALID_PARAMETER;
 | 
						|
      }
 | 
						|
      if (VarCheckFunction != NULL) {
 | 
						|
        Status = VarCheckFunction (
 | 
						|
                   Property,
 | 
						|
                   DataSize,
 | 
						|
                   Data
 | 
						|
                   );
 | 
						|
        if (EFI_ERROR (Status)) {
 | 
						|
          DEBUG ((EFI_D_INFO, "[Variable]: Internal Var Check function fail %r - %g:%s\n", Status, VendorGuid, VariableName));
 | 
						|
          return Status;
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  for (Index = 0; Index < mNumberOfHandler; Index++) {
 | 
						|
    Status = mHandlerTable[Index] (
 | 
						|
               VariableName,
 | 
						|
               VendorGuid,
 | 
						|
               Attributes,
 | 
						|
               DataSize,
 | 
						|
               Data
 | 
						|
               );
 | 
						|
    if (EFI_ERROR (Status)) {
 | 
						|
      DEBUG ((EFI_D_INFO, "[Variable]: Var Check handler fail %r - %g:%s\n", Status, VendorGuid, VariableName));
 | 
						|
      return Status;
 | 
						|
    }
 | 
						|
  }
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Reallocates more global memory to store the registered handler list.
 | 
						|
 | 
						|
  @retval RETURN_SUCCESS            Reallocate memory successfully.
 | 
						|
  @retval RETURN_OUT_OF_RESOURCES   No enough memory to allocate.
 | 
						|
 | 
						|
**/
 | 
						|
RETURN_STATUS
 | 
						|
EFIAPI
 | 
						|
ReallocateHandlerTable (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
{
 | 
						|
  VAR_CHECK_SET_VARIABLE_CHECK_HANDLER  *HandlerTable;
 | 
						|
 | 
						|
  //
 | 
						|
  // Reallocate memory for check handler table.
 | 
						|
  //
 | 
						|
  HandlerTable = ReallocateRuntimePool (
 | 
						|
                     mMaxNumberOfHandler * sizeof (VAR_CHECK_SET_VARIABLE_CHECK_HANDLER), 
 | 
						|
                     (mMaxNumberOfHandler + VAR_CHECK_HANDLER_TABLE_SIZE) * sizeof (VAR_CHECK_SET_VARIABLE_CHECK_HANDLER), 
 | 
						|
                     mHandlerTable
 | 
						|
                     );
 | 
						|
 | 
						|
  //
 | 
						|
  // No enough resource to allocate.
 | 
						|
  //
 | 
						|
  if (HandlerTable == NULL) {
 | 
						|
    return RETURN_OUT_OF_RESOURCES;
 | 
						|
  }
 | 
						|
 | 
						|
  mHandlerTable = HandlerTable;
 | 
						|
  //
 | 
						|
  // Increase max handler number.
 | 
						|
  //
 | 
						|
  mMaxNumberOfHandler = mMaxNumberOfHandler + VAR_CHECK_HANDLER_TABLE_SIZE;
 | 
						|
  return RETURN_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Register SetVariable check handler.
 | 
						|
 | 
						|
  @param[in] Handler            Pointer to check handler.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS           The SetVariable check handler was registered successfully.
 | 
						|
  @retval EFI_INVALID_PARAMETER Handler is NULL.
 | 
						|
  @retval EFI_ACCESS_DENIED     EFI_END_OF_DXE_EVENT_GROUP_GUID or EFI_EVENT_GROUP_READY_TO_BOOT has
 | 
						|
                                already been signaled.
 | 
						|
  @retval EFI_OUT_OF_RESOURCES  There is not enough resource for the SetVariable check handler register request.
 | 
						|
  @retval EFI_UNSUPPORTED       This interface is not implemented.
 | 
						|
                                For example, it is unsupported in VarCheck protocol if both VarCheck and SmmVarCheck protocols are present.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
VarCheckRegisterSetVariableCheckHandler (
 | 
						|
  IN VAR_CHECK_SET_VARIABLE_CHECK_HANDLER   Handler
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS    Status;
 | 
						|
 | 
						|
  if (Handler == NULL) {
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  if (mEndOfDxe) {
 | 
						|
    return EFI_ACCESS_DENIED;
 | 
						|
  }
 | 
						|
 | 
						|
  DEBUG ((EFI_D_INFO, "RegisterSetVariableCheckHandler - 0x%x\n", Handler));
 | 
						|
 | 
						|
  //
 | 
						|
  // Check whether the handler list is enough to store new handler.
 | 
						|
  //
 | 
						|
  if (mNumberOfHandler == mMaxNumberOfHandler) {
 | 
						|
    //
 | 
						|
    // Allocate more resources for new handler.
 | 
						|
    //
 | 
						|
    Status = ReallocateHandlerTable();
 | 
						|
    if (EFI_ERROR (Status)) {
 | 
						|
      return Status;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Register new handler into the handler list.
 | 
						|
  //
 | 
						|
  mHandlerTable[mNumberOfHandler] = Handler;
 | 
						|
  mNumberOfHandler++;
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Variable property get function.
 | 
						|
 | 
						|
  @param[in] Name           Pointer to the variable name.
 | 
						|
  @param[in] Guid           Pointer to the vendor GUID.
 | 
						|
  @param[in] WildcardMatch  Try wildcard match or not.
 | 
						|
 | 
						|
  @return Pointer to the property of variable specified by the Name and Guid.
 | 
						|
 | 
						|
**/
 | 
						|
VAR_CHECK_VARIABLE_PROPERTY *
 | 
						|
VariablePropertyGetFunction (
 | 
						|
  IN CHAR16                 *Name,
 | 
						|
  IN EFI_GUID               *Guid,
 | 
						|
  IN BOOLEAN                WildcardMatch
 | 
						|
  )
 | 
						|
{
 | 
						|
  LIST_ENTRY                    *Link;
 | 
						|
  VAR_CHECK_VARIABLE_ENTRY      *Entry;
 | 
						|
  CHAR16                        *VariableName;
 | 
						|
  VAR_CHECK_VARIABLE_PROPERTY   *Property;
 | 
						|
 | 
						|
  for ( Link = GetFirstNode (&mVarCheckVariableList)
 | 
						|
      ; !IsNull (&mVarCheckVariableList, Link)
 | 
						|
      ; Link = GetNextNode (&mVarCheckVariableList, Link)
 | 
						|
      ) {
 | 
						|
    Entry = BASE_CR (Link, VAR_CHECK_VARIABLE_ENTRY, Link);
 | 
						|
    VariableName = (CHAR16 *) ((UINTN) Entry + sizeof (*Entry));
 | 
						|
    if (CompareGuid (&Entry->Guid, Guid) && (StrCmp (VariableName, Name) == 0)) {
 | 
						|
      return &Entry->VariableProperty;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  Property = GetVariableDriverVariableProperty (Name, Guid);
 | 
						|
  if (Property == NULL) {
 | 
						|
    GetUefiDefinedVariableProperty (Name, Guid, WildcardMatch, &Property, NULL);
 | 
						|
  }
 | 
						|
 | 
						|
  return Property;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Variable property set.
 | 
						|
 | 
						|
  @param[in] Name               Pointer to the variable name.
 | 
						|
  @param[in] Guid               Pointer to the vendor GUID.
 | 
						|
  @param[in] VariableProperty   Pointer to the input variable property.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS           The property of variable specified by the Name and Guid was set successfully.
 | 
						|
  @retval EFI_INVALID_PARAMETER Name, Guid or VariableProperty is NULL, or Name is an empty string,
 | 
						|
                                or the fields of VariableProperty are not valid.
 | 
						|
  @retval EFI_ACCESS_DENIED     EFI_END_OF_DXE_EVENT_GROUP_GUID or EFI_EVENT_GROUP_READY_TO_BOOT has
 | 
						|
                                already been signaled.
 | 
						|
  @retval EFI_OUT_OF_RESOURCES  There is not enough resource for the variable property set request.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
VarCheckVariablePropertySet (
 | 
						|
  IN CHAR16                         *Name,
 | 
						|
  IN EFI_GUID                       *Guid,
 | 
						|
  IN VAR_CHECK_VARIABLE_PROPERTY    *VariableProperty
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS                    Status;
 | 
						|
  VAR_CHECK_VARIABLE_ENTRY      *Entry;
 | 
						|
  CHAR16                        *VariableName;
 | 
						|
  VAR_CHECK_VARIABLE_PROPERTY   *Property;
 | 
						|
 | 
						|
  if (Name == NULL || Name[0] == 0 || Guid == NULL) {
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  if (VariableProperty == NULL) {
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  if (VariableProperty->Revision != VAR_CHECK_VARIABLE_PROPERTY_REVISION) {
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  if (mEndOfDxe) {
 | 
						|
    return EFI_ACCESS_DENIED;
 | 
						|
  }
 | 
						|
 | 
						|
  Status = EFI_SUCCESS;
 | 
						|
 | 
						|
  AcquireLockOnlyAtBootTime (&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);
 | 
						|
 | 
						|
  Property = VariablePropertyGetFunction (Name, Guid, FALSE);
 | 
						|
  if (Property != NULL) {
 | 
						|
    CopyMem (Property, VariableProperty, sizeof (*VariableProperty));
 | 
						|
  } else {
 | 
						|
    Entry = AllocateRuntimeZeroPool (sizeof (*Entry) + StrSize (Name));
 | 
						|
    if (Entry == NULL) {
 | 
						|
      Status = EFI_OUT_OF_RESOURCES;
 | 
						|
      goto Done;
 | 
						|
    }
 | 
						|
    VariableName = (CHAR16 *) ((UINTN) Entry + sizeof (*Entry));
 | 
						|
    StrnCpy (VariableName, Name, StrLen (Name));
 | 
						|
    CopyGuid (&Entry->Guid, Guid);
 | 
						|
    CopyMem (&Entry->VariableProperty, VariableProperty, sizeof (*VariableProperty));
 | 
						|
    InsertTailList (&mVarCheckVariableList, &Entry->Link);
 | 
						|
  }
 | 
						|
 | 
						|
Done:
 | 
						|
  ReleaseLockOnlyAtBootTime (&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);
 | 
						|
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Internal variable property get.
 | 
						|
 | 
						|
  @param[in]  Name              Pointer to the variable name.
 | 
						|
  @param[in]  Guid              Pointer to the vendor GUID.
 | 
						|
  @param[out] VariableProperty  Pointer to the output variable property.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS           The property of variable specified by the Name and Guid was got successfully.
 | 
						|
  @retval EFI_NOT_FOUND         The property of variable specified by the Name and Guid was not found.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
InternalVarCheckVariablePropertyGet (
 | 
						|
  IN CHAR16                         *Name,
 | 
						|
  IN EFI_GUID                       *Guid,
 | 
						|
  OUT VAR_CHECK_VARIABLE_PROPERTY   *VariableProperty
 | 
						|
  )
 | 
						|
{
 | 
						|
  LIST_ENTRY                    *Link;
 | 
						|
  VARIABLE_ENTRY                *Entry;
 | 
						|
  CHAR16                        *VariableName;
 | 
						|
  BOOLEAN                       Found;
 | 
						|
  VAR_CHECK_VARIABLE_PROPERTY   *Property;
 | 
						|
 | 
						|
  Found = FALSE;
 | 
						|
 | 
						|
  Property = VariablePropertyGetFunction (Name, Guid, TRUE);
 | 
						|
  if (Property != NULL) {
 | 
						|
    CopyMem (VariableProperty, Property, sizeof (*VariableProperty));
 | 
						|
    Found = TRUE;
 | 
						|
  }
 | 
						|
 | 
						|
  for ( Link = GetFirstNode (&mLockedVariableList)
 | 
						|
      ; !IsNull (&mLockedVariableList, Link)
 | 
						|
      ; Link = GetNextNode (&mLockedVariableList, Link)
 | 
						|
      ) {
 | 
						|
    Entry = BASE_CR (Link, VARIABLE_ENTRY, Link);
 | 
						|
    VariableName = (CHAR16 *) ((UINTN) Entry + sizeof (*Entry));
 | 
						|
    if (CompareGuid (&Entry->Guid, Guid) && (StrCmp (VariableName, Name) == 0)) {
 | 
						|
      VariableProperty->Property |= VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY;
 | 
						|
      if (!Found) {
 | 
						|
        VariableProperty->Revision = VAR_CHECK_VARIABLE_PROPERTY_REVISION;
 | 
						|
        Found = TRUE;
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  return (Found ? EFI_SUCCESS : EFI_NOT_FOUND);
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Variable property get.
 | 
						|
 | 
						|
  @param[in]  Name              Pointer to the variable name.
 | 
						|
  @param[in]  Guid              Pointer to the vendor GUID.
 | 
						|
  @param[out] VariableProperty  Pointer to the output variable property.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS           The property of variable specified by the Name and Guid was got successfully.
 | 
						|
  @retval EFI_INVALID_PARAMETER Name, Guid or VariableProperty is NULL, or Name is an empty string.
 | 
						|
  @retval EFI_NOT_FOUND         The property of variable specified by the Name and Guid was not found.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
VarCheckVariablePropertyGet (
 | 
						|
  IN CHAR16                         *Name,
 | 
						|
  IN EFI_GUID                       *Guid,
 | 
						|
  OUT VAR_CHECK_VARIABLE_PROPERTY   *VariableProperty
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS    Status;
 | 
						|
 | 
						|
  if (Name == NULL || Name[0] == 0 || Guid == NULL) {
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  if (VariableProperty == NULL) {
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  AcquireLockOnlyAtBootTime (&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);
 | 
						|
 | 
						|
  Status = InternalVarCheckVariablePropertyGet (Name, Guid, VariableProperty);
 | 
						|
 | 
						|
  ReleaseLockOnlyAtBootTime (&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);
 | 
						|
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 |