2015-01-05 04:38:36 +01:00
/** @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
)
{
2015-01-27 09:42:47 +01:00
UINT16 FilePathListLength ;
2015-01-05 04:38:36 +01:00
CHAR16 * Description ;
EFI_DEVICE_PATH_PROTOCOL * FilePathList ;
2015-01-27 09:42:47 +01:00
FilePathListLength = * ( ( UINT16 * ) ( ( UINTN ) Data + sizeof ( UINT32 ) ) ) ;
2015-01-05 04:38:36 +01:00
//
// Check Description
//
2015-01-27 09:42:47 +01:00
Description = ( CHAR16 * ) ( ( UINTN ) Data + sizeof ( UINT32 ) + sizeof ( UINT16 ) ) ;
2015-01-05 04:38:36 +01:00
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 ;
2015-01-27 09:42:47 +01:00
if ( ( UINTN ) FilePathList > ( MAX_ADDRESS - FilePathListLength ) ) {
2015-01-05 04:38:36 +01:00
return EFI_INVALID_PARAMETER ;
}
2015-01-27 09:42:47 +01:00
if ( ( ( UINTN ) FilePathList + FilePathListLength ) > ( ( UINTN ) Data + DataSize ) ) {
2015-01-05 04:38:36 +01:00
return EFI_INVALID_PARAMETER ;
}
2015-01-27 09:42:47 +01:00
if ( FilePathListLength < sizeof ( EFI_DEVICE_PATH_PROTOCOL ) ) {
2015-01-05 04:38:36 +01:00
return EFI_INVALID_PARAMETER ;
}
2015-01-27 09:42:47 +01:00
if ( ! IsDevicePathValid ( FilePathList , FilePathListLength ) ) {
2015-01-05 04:38:36 +01:00
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
} ,
2015-06-08 11:35:53 +02:00
{
EFI_SYS_PREP_ORDER_VARIABLE_NAME ,
{
VAR_CHECK_VARIABLE_PROPERTY_REVISION ,
0 ,
VARIABLE_ATTRIBUTE_NV_BS_RT ,
sizeof ( UINT16 ) ,
MAX_UINTN
} ,
InternalVarCheckSizeArray
} ,
2015-01-05 04:38:36 +01:00
{
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 ,
2015-01-27 09:42:47 +01:00
sizeof ( UINT32 ) + sizeof ( UINT16 ) ,
2015-01-05 04:38:36 +01:00
MAX_UINTN
} ,
InternalVarCheckLoadOption
} ,
{
L " Driver#### " ,
2015-06-08 11:35:53 +02:00
{
VAR_CHECK_VARIABLE_PROPERTY_REVISION ,
0 ,
VARIABLE_ATTRIBUTE_NV_BS_RT ,
sizeof ( UINT32 ) + sizeof ( UINT16 ) ,
MAX_UINTN
} ,
InternalVarCheckLoadOption
} ,
{
L " SysPrep#### " ,
2015-01-05 04:38:36 +01:00
{
VAR_CHECK_VARIABLE_PROPERTY_REVISION ,
0 ,
VARIABLE_ATTRIBUTE_NV_BS_RT ,
2015-01-27 09:42:47 +01:00
sizeof ( UINT32 ) + sizeof ( UINT16 ) ,
2015-01-05 04:38:36 +01:00
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
} ,
} ;
2015-01-27 09:42:47 +01:00
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 ) ,
}
} ,
} ;
2015-01-05 04:38:36 +01:00
/**
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 ;
}
2015-01-27 09:42:47 +01:00
}
if ( StrCmp ( mGlobalVariableList2 [ Index ] . Name , VariableName ) = = 0 ) {
if ( VarCheckFunction ! = NULL ) {
* VarCheckFunction = mGlobalVariableList2 [ Index ] . CheckFunction ;
2015-01-05 04:38:36 +01:00
}
2015-01-27 09:42:47 +01:00
* VariableProperty = & mGlobalVariableList2 [ Index ] . VariableProperty ;
return EFI_SUCCESS ;
2015-01-05 04:38:36 +01:00
}
}
//
// The variable name is not in the lists.
//
return EFI_INVALID_PARAMETER ;
}
//
// It is not global variable.
//
return EFI_SUCCESS ;
}
2015-01-27 09:42:47 +01:00
/**
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 ;
}
2015-01-05 04:38:36 +01:00
/**
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 .
2015-01-27 09:42:47 +01:00
@ retval EFI_INVALID_PARAMETER An invalid combination of attribute bits , name , and GUID was supplied ,
2015-01-05 04:38:36 +01:00
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 ;
2015-01-27 09:42:47 +01:00
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 ;
}
2015-01-05 04:38:36 +01:00
}
if ( Property = = NULL ) {
2015-01-27 09:42:47 +01:00
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 ;
2015-01-05 04:38:36 +01:00
}
}
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 ;
}
2015-01-27 09:42:47 +01:00
if ( ! ( ( DataSize = = 0 ) | | ( Attributes = = 0 ) ) ) {
2015-01-05 04:38:36 +01:00
//
2015-01-27 09:42:47 +01:00
// Not to delete variable.
2015-01-05 04:38:36 +01:00
//
2015-01-27 09:42:47 +01:00
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 ;
}
2015-01-05 04:38:36 +01:00
}
}
}
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 ;
}
/**
2015-01-27 09:42:47 +01:00
Variable property get function .
2015-01-05 04:38:36 +01:00
2015-01-27 09:42:47 +01:00
@ param [ in ] Name Pointer to the variable name .
@ param [ in ] Guid Pointer to the vendor GUID .
@ param [ in ] WildcardMatch Try wildcard match or not .
2015-01-05 04:38:36 +01:00
@ return Pointer to the property of variable specified by the Name and Guid .
* */
VAR_CHECK_VARIABLE_PROPERTY *
2015-01-27 09:42:47 +01:00
VariablePropertyGetFunction (
IN CHAR16 * Name ,
IN EFI_GUID * Guid ,
IN BOOLEAN WildcardMatch
2015-01-05 04:38:36 +01:00
)
{
LIST_ENTRY * Link ;
VAR_CHECK_VARIABLE_ENTRY * Entry ;
CHAR16 * VariableName ;
VAR_CHECK_VARIABLE_PROPERTY * Property ;
2015-01-27 09:42:47 +01:00
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 ;
2015-01-05 04:38:36 +01:00
}
}
2015-01-27 09:42:47 +01:00
Property = GetVariableDriverVariableProperty ( Name , Guid ) ;
if ( Property = = NULL ) {
GetUefiDefinedVariableProperty ( Name , Guid , WildcardMatch , & Property , NULL ) ;
}
return Property ;
2015-01-05 04:38:36 +01:00
}
/**
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 ) ;
2015-01-27 09:42:47 +01:00
Property = VariablePropertyGetFunction ( Name , Guid , FALSE ) ;
2015-01-05 04:38:36 +01:00
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 ;
}
/**
2015-01-27 09:42:47 +01:00
Internal variable property get .
2015-01-05 04:38:36 +01:00
@ 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
2015-01-27 09:42:47 +01:00
InternalVarCheckVariablePropertyGet (
2015-01-05 04:38:36 +01:00
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 ;
2015-01-27 09:42:47 +01:00
Property = VariablePropertyGetFunction ( Name , Guid , TRUE ) ;
2015-01-05 04:38:36 +01:00
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 ;
}
}
}
2015-01-27 09:42:47 +01:00
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 ) ;
2015-01-05 04:38:36 +01:00
ReleaseLockOnlyAtBootTime ( & mVariableModuleGlobal - > VariableGlobal . VariableServicesLock ) ;
2015-01-27 09:42:47 +01:00
return Status ;
2015-01-05 04:38:36 +01:00
}