mirror of https://github.com/acidanthera/audk.git
MdeModulePkg: Add VarCheckHiiLib NULL class library
The check will be based on VarCheckHiiBin that generated from FV and Hii Database. 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@18293 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
parent
b5817491a8
commit
1241af9510
|
@ -0,0 +1,82 @@
|
|||
/** @file
|
||||
Internal structure for Var Check Hii.
|
||||
|
||||
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.
|
||||
|
||||
**/
|
||||
|
||||
#ifndef _VAR_CHECK_STRUCTURE_H_
|
||||
#define _VAR_CHECK_STRUCTURE_H_
|
||||
|
||||
//
|
||||
// Alignment for Hii Variable and Question header.
|
||||
//
|
||||
#define HEADER_ALIGNMENT 4
|
||||
#define HEADER_ALIGN(Header) (((UINTN) (Header) + HEADER_ALIGNMENT - 1) & (~(HEADER_ALIGNMENT - 1)))
|
||||
|
||||
#pragma pack (1)
|
||||
|
||||
#define VAR_CHECK_HII_REVISION 0x0001
|
||||
|
||||
typedef struct {
|
||||
UINT16 Revision;
|
||||
UINT16 HeaderLength;
|
||||
UINT32 Length; // Length include this header
|
||||
UINT8 OpCode;
|
||||
UINT8 Reserved;
|
||||
UINT16 Size;
|
||||
UINT32 Attributes;
|
||||
EFI_GUID Guid;
|
||||
//CHAR16 Name[];
|
||||
} VAR_CHECK_HII_VARIABLE_HEADER;
|
||||
|
||||
typedef struct {
|
||||
UINT8 OpCode;
|
||||
UINT8 Length; // Length include this header
|
||||
UINT16 VarOffset;
|
||||
UINT8 StorageWidth;
|
||||
} VAR_CHECK_HII_QUESTION_HEADER;
|
||||
|
||||
typedef struct {
|
||||
UINT8 OpCode;
|
||||
UINT8 Length; // Length include this header
|
||||
UINT16 VarOffset;
|
||||
UINT8 StorageWidth;
|
||||
//UINTx Data[]; // x = UINT8/UINT16/UINT32/UINT64;
|
||||
} VAR_CHECK_HII_QUESTION_ONEOF;
|
||||
|
||||
typedef struct {
|
||||
UINT8 OpCode;
|
||||
UINT8 Length; // Length include this header
|
||||
UINT16 VarOffset;
|
||||
UINT8 StorageWidth;
|
||||
} VAR_CHECK_HII_QUESTION_CHECKBOX;
|
||||
|
||||
typedef struct {
|
||||
UINT8 OpCode;
|
||||
UINT8 Length; // Length include this header
|
||||
UINT16 VarOffset;
|
||||
UINT8 StorageWidth;
|
||||
//UINTx Minimum; // x = UINT8/UINT16/UINT32/UINT64;
|
||||
//UINTx Maximum; // x = UINT8/UINT16/UINT32/UINT64;
|
||||
} VAR_CHECK_HII_QUESTION_NUMERIC;
|
||||
|
||||
typedef struct {
|
||||
UINT8 OpCode;
|
||||
UINT8 Length; // Length include this header
|
||||
UINT16 VarOffset;
|
||||
UINT8 StorageWidth;
|
||||
UINT8 MaxContainers;
|
||||
//UINTx Data[]; // x = UINT8/UINT16/UINT32/UINT64;
|
||||
} VAR_CHECK_HII_QUESTION_ORDEREDLIST;
|
||||
|
||||
#pragma pack ()
|
||||
|
||||
#endif
|
|
@ -0,0 +1,63 @@
|
|||
/** @file
|
||||
Include file for Var Check Hii handler and bin.
|
||||
|
||||
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.
|
||||
|
||||
**/
|
||||
|
||||
#ifndef _VAR_CHECK_HII_H_
|
||||
#define _VAR_CHECK_HII_H_
|
||||
|
||||
#include <Library/VarCheckLib.h>
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/UefiBootServicesTableLib.h>
|
||||
#include <Library/MemoryAllocationLib.h>
|
||||
|
||||
#include <Guid/ZeroGuid.h>
|
||||
|
||||
#include <Protocol/HiiDatabase.h>
|
||||
#include <Protocol/FirmwareVolume2.h>
|
||||
#include <Protocol/FirmwareVolumeBlock.h>
|
||||
|
||||
#include "InternalVarCheckStructure.h"
|
||||
#include "VarCheckHiiGen.h"
|
||||
|
||||
//#define DUMP_VAR_CHECK_HII
|
||||
//#define DUMP_HII_DATA
|
||||
|
||||
typedef struct {
|
||||
UINT8 HiiOpCode;
|
||||
CHAR8 *HiiOpCodeStr;
|
||||
} VAR_CHECK_HII_OPCODE_STRING;
|
||||
|
||||
typedef struct {
|
||||
UINT8 PackageType;
|
||||
CHAR8 *PackageTypeStr;
|
||||
} VAR_CHECK_HII_PACKAGE_TYPE_STRING;
|
||||
|
||||
/**
|
||||
Dump Var Check HII.
|
||||
|
||||
@param[in] VarCheckHiiBin Pointer to VarCheckHiiBin.
|
||||
@param[in] VarCheckHiiBinSize VarCheckHiiBin size.
|
||||
|
||||
**/
|
||||
VOID
|
||||
DumpVarCheckHii (
|
||||
IN VOID *VarCheckHiiBin,
|
||||
IN UINTN VarCheckHiiBinSize
|
||||
);
|
||||
|
||||
extern VAR_CHECK_HII_VARIABLE_HEADER *mVarCheckHiiBin;
|
||||
extern UINTN mVarCheckHiiBinSize;
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,136 @@
|
|||
/** @file
|
||||
Include file for Var Check Hii bin generation.
|
||||
|
||||
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.
|
||||
|
||||
**/
|
||||
|
||||
#ifndef _VAR_CHECK_HII_GEN_H_
|
||||
#define _VAR_CHECK_HII_GEN_H_
|
||||
|
||||
#include "VarCheckHii.h"
|
||||
|
||||
/**
|
||||
Dump Hii Package.
|
||||
|
||||
@param[in] HiiPackage Pointer to Hii Package.
|
||||
|
||||
**/
|
||||
VOID
|
||||
DumpHiiPackage (
|
||||
IN VOID *HiiPackage
|
||||
);
|
||||
|
||||
/**
|
||||
Dump Hii Database.
|
||||
|
||||
@param[in] HiiDatabase Pointer to Hii Database.
|
||||
@param[in] HiiDatabaseSize Hii Database size.
|
||||
|
||||
**/
|
||||
VOID
|
||||
DumpHiiDatabase (
|
||||
IN VOID *HiiDatabase,
|
||||
IN UINTN HiiDatabaseSize
|
||||
);
|
||||
|
||||
/**
|
||||
Allocates and zeros a buffer of type EfiBootServicesData.
|
||||
|
||||
Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, clears the
|
||||
buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a
|
||||
valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the
|
||||
request, then NULL is returned.
|
||||
|
||||
@param AllocationSize The number of bytes to allocate and zero.
|
||||
|
||||
@return A pointer to the allocated buffer or NULL if allocation fails.
|
||||
|
||||
**/
|
||||
VOID *
|
||||
InternalVarCheckAllocateZeroPool (
|
||||
IN UINTN AllocationSize
|
||||
);
|
||||
|
||||
/**
|
||||
Frees a buffer that was previously allocated with one of the pool allocation functions in the
|
||||
Memory Allocation Library.
|
||||
|
||||
Frees the buffer specified by Buffer. Buffer must have been allocated on a previous call to the
|
||||
pool allocation services of the Memory Allocation Library. If it is not possible to free pool
|
||||
resources, then this function will perform no actions.
|
||||
|
||||
If Buffer was not allocated with a pool allocation function in the Memory Allocation Library,
|
||||
then ASSERT().
|
||||
|
||||
@param Buffer The pointer to the buffer to free.
|
||||
|
||||
**/
|
||||
VOID
|
||||
EFIAPI
|
||||
InternalVarCheckFreePool (
|
||||
IN VOID *Buffer
|
||||
);
|
||||
|
||||
/**
|
||||
Var Check Parse Hii Package.
|
||||
|
||||
@param[in] HiiPackage Pointer to Hii Package.
|
||||
@param[in] FromFv Hii Package from FV.
|
||||
|
||||
**/
|
||||
VOID
|
||||
VarCheckParseHiiPackage (
|
||||
IN VOID *HiiPackage,
|
||||
IN BOOLEAN FromFv
|
||||
);
|
||||
|
||||
/**
|
||||
Var Check Parse Hii Database.
|
||||
|
||||
@param[in] HiiDatabase Pointer to Hii Database.
|
||||
@param[in] HiiDatabaseSize Hii Database size.
|
||||
|
||||
**/
|
||||
VOID
|
||||
VarCheckParseHiiDatabase (
|
||||
IN VOID *HiiDatabase,
|
||||
IN UINTN HiiDatabaseSize
|
||||
);
|
||||
|
||||
/**
|
||||
Generate from FV.
|
||||
|
||||
**/
|
||||
VOID
|
||||
VarCheckHiiGenFromFv (
|
||||
VOID
|
||||
);
|
||||
|
||||
/**
|
||||
Generate from Hii Database.
|
||||
|
||||
**/
|
||||
VOID
|
||||
VarCheckHiiGenFromHiiDatabase (
|
||||
VOID
|
||||
);
|
||||
|
||||
/**
|
||||
Generate VarCheckHiiBin from Hii Database and FV.
|
||||
|
||||
**/
|
||||
VOID
|
||||
EFIAPI
|
||||
VarCheckHiiGen (
|
||||
VOID
|
||||
);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,443 @@
|
|||
/** @file
|
||||
Var Check Hii generation from FV.
|
||||
|
||||
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 "VarCheckHiiGen.h"
|
||||
|
||||
// {d0bc7cb4-6a47-495f-aa11-710746da06a2}
|
||||
#define EFI_VFR_ATTRACT_GUID \
|
||||
{ 0xd0bc7cb4, 0x6a47, 0x495f, { 0xaa, 0x11, 0x71, 0x7, 0x46, 0xda, 0x6, 0xa2 } }
|
||||
|
||||
EFI_GUID gVfrArrayAttractGuid = EFI_VFR_ATTRACT_GUID;
|
||||
|
||||
#define ALL_FF_GUID \
|
||||
{ 0xFFFFFFFF, 0xFFFF, 0xFFFF, { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF } }
|
||||
|
||||
EFI_GUID mAllFfGuid = ALL_FF_GUID;
|
||||
|
||||
#define VAR_CHECK_VFR_DRIVER_INFO_SIGNATURE SIGNATURE_32 ('V', 'D', 'R', 'I')
|
||||
|
||||
typedef struct {
|
||||
UINTN Signature;
|
||||
LIST_ENTRY Link;
|
||||
EFI_GUID *DriverGuid;
|
||||
} VAR_CHECK_VFR_DRIVER_INFO;
|
||||
|
||||
LIST_ENTRY mVfrDriverList = INITIALIZE_LIST_HEAD_VARIABLE (mVfrDriverList);
|
||||
|
||||
#define VAR_CHECK_VFR_DRIVER_INFO_FROM_LINK(a) CR (a, VAR_CHECK_VFR_DRIVER_INFO, Link, VAR_CHECK_VFR_DRIVER_INFO_SIGNATURE)
|
||||
|
||||
#define MAX_MATCH_GUID_NUM 100
|
||||
|
||||
/**
|
||||
Get the address by Guid.
|
||||
|
||||
Parse the FFS and find the GUID address.
|
||||
There may be multiple Guids matching the searched Guid.
|
||||
|
||||
@param Ffs Pointer to the FFS.
|
||||
@param Guid Guid to find.
|
||||
@param Length The length of FFS.
|
||||
@param Offset Pointer to pointer to the offset.
|
||||
@param NumOfMatchingGuid The number of matching Guid.
|
||||
|
||||
@retval EFI_SUCCESS One or multiple Guids matching the searched Guid.
|
||||
@retval EFI_NOT_FOUND No Guid matching the searched Guid.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
GetAddressByGuid (
|
||||
IN VOID *Ffs,
|
||||
IN EFI_GUID *Guid,
|
||||
IN UINTN Length,
|
||||
OUT UINTN **Offset,
|
||||
OUT UINT8 *NumOfMatchingGuid
|
||||
)
|
||||
{
|
||||
UINTN LoopControl;
|
||||
BOOLEAN Found;
|
||||
|
||||
if((Ffs == NULL) || (Guid == NULL) || (Length == 0)){
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
if (NumOfMatchingGuid != NULL) {
|
||||
*NumOfMatchingGuid = 0;
|
||||
}
|
||||
|
||||
Found = FALSE;
|
||||
for (LoopControl = 0; LoopControl < Length; LoopControl++) {
|
||||
if (CompareGuid (Guid, (EFI_GUID *) ((UINT8 *) Ffs + LoopControl))) {
|
||||
Found = TRUE;
|
||||
//
|
||||
// If NumOfMatchGuid or Offset are NULL, means user only want
|
||||
// to check whether current FFS includes this Guid or not.
|
||||
//
|
||||
if ((NumOfMatchingGuid != NULL) && (Offset != NULL)) {
|
||||
if (*NumOfMatchingGuid == 0) {
|
||||
*Offset = InternalVarCheckAllocateZeroPool (sizeof (UINTN) * MAX_MATCH_GUID_NUM);
|
||||
ASSERT (*Offset != NULL);
|
||||
}
|
||||
*(*Offset + *NumOfMatchingGuid) = LoopControl + sizeof (EFI_GUID);
|
||||
(*NumOfMatchingGuid)++;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (Found ? EFI_SUCCESS : EFI_NOT_FOUND);
|
||||
}
|
||||
|
||||
/**
|
||||
Search the VfrBin Base address.
|
||||
|
||||
According to the known GUID gVfrArrayAttractGuid to get the base address from FFS.
|
||||
|
||||
@param Ffs Pointer to the FFS.
|
||||
@param EfiAddr Pointer to the EFI in FFS
|
||||
@param Length The length of FFS.
|
||||
@param Offset Pointer to pointer to the Addr (Offset).
|
||||
@param NumOfMatchingOffset The number of Addr (Offset).
|
||||
|
||||
@retval EFI_SUCCESS Get the address successfully.
|
||||
@retval EFI_NOT_FOUND No VfrBin found.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
SearchVfrBinInFfs (
|
||||
IN VOID *Ffs,
|
||||
IN VOID *EfiAddr,
|
||||
IN UINTN Length,
|
||||
OUT UINTN **Offset,
|
||||
OUT UINT8 *NumOfMatchingOffset
|
||||
)
|
||||
{
|
||||
UINTN Index;
|
||||
EFI_STATUS Status;
|
||||
UINTN VirOffValue;
|
||||
|
||||
if ((Ffs == NULL) || (Offset == NULL)) {
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
Status = GetAddressByGuid (
|
||||
Ffs,
|
||||
&gVfrArrayAttractGuid,
|
||||
Length,
|
||||
Offset,
|
||||
NumOfMatchingOffset
|
||||
);
|
||||
if (Status != EFI_SUCCESS) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
for (Index = 0; Index < *NumOfMatchingOffset; Index++) {
|
||||
//
|
||||
// Got the virOffset after the GUID
|
||||
//
|
||||
VirOffValue = *(UINTN *) ((UINTN) Ffs + *(*Offset + Index));
|
||||
//
|
||||
// Transfer the offset to the VA address. One modules may own multiple VfrBin address.
|
||||
//
|
||||
*(*Offset + Index) = (UINTN) EfiAddr + VirOffValue;
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
Parse FFS.
|
||||
|
||||
@param[in] Fv2 Pointer to Fv2 protocol.
|
||||
@param[in] DriverGuid Pointer to driver GUID.
|
||||
|
||||
@return Found the driver in the FV or not.
|
||||
|
||||
**/
|
||||
BOOLEAN
|
||||
ParseFfs (
|
||||
IN EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv2,
|
||||
IN EFI_GUID *DriverGuid
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_FV_FILETYPE FoundType;
|
||||
EFI_FV_FILE_ATTRIBUTES FileAttributes;
|
||||
UINT32 AuthenticationStatus;
|
||||
UINTN Size;
|
||||
VOID *Buffer;
|
||||
UINTN SectionSize;
|
||||
VOID *SectionBuffer;
|
||||
UINTN VfrBinIndex;
|
||||
UINT8 NumberofMatchingVfrBin;
|
||||
UINTN *VfrBinBaseAddress;
|
||||
|
||||
Status = Fv2->ReadFile (
|
||||
Fv2,
|
||||
DriverGuid,
|
||||
NULL,
|
||||
&Size,
|
||||
&FoundType,
|
||||
&FileAttributes,
|
||||
&AuthenticationStatus
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Buffer = NULL;
|
||||
Status = Fv2->ReadSection (
|
||||
Fv2,
|
||||
DriverGuid,
|
||||
EFI_SECTION_RAW,
|
||||
0, // Instance
|
||||
&Buffer,
|
||||
&Size,
|
||||
&AuthenticationStatus
|
||||
);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
Status = SearchVfrBinInFfs (Buffer, 0, Size, &VfrBinBaseAddress, &NumberofMatchingVfrBin);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
SectionBuffer = NULL;
|
||||
Status = Fv2->ReadSection (
|
||||
Fv2,
|
||||
DriverGuid,
|
||||
EFI_SECTION_PE32,
|
||||
0, // Instance
|
||||
&SectionBuffer,
|
||||
&SectionSize,
|
||||
&AuthenticationStatus
|
||||
);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
DEBUG ((EFI_D_INFO, "FfsNameGuid - %g\n", DriverGuid));
|
||||
DEBUG ((EFI_D_INFO, "NumberofMatchingVfrBin - 0x%02x\n", NumberofMatchingVfrBin));
|
||||
|
||||
for (VfrBinIndex = 0; VfrBinIndex < NumberofMatchingVfrBin; VfrBinIndex++) {
|
||||
#ifdef DUMP_HII_DATA
|
||||
DEBUG_CODE (
|
||||
DumpHiiPackage ((UINT8 *) (UINTN) SectionBuffer + VfrBinBaseAddress[VfrBinIndex] + sizeof (UINT32));
|
||||
);
|
||||
#endif
|
||||
VarCheckParseHiiPackage ((UINT8 *) (UINTN) SectionBuffer + VfrBinBaseAddress[VfrBinIndex] + sizeof (UINT32), TRUE);
|
||||
}
|
||||
|
||||
FreePool (SectionBuffer);
|
||||
}
|
||||
|
||||
InternalVarCheckFreePool (VfrBinBaseAddress);
|
||||
}
|
||||
|
||||
FreePool (Buffer);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
Parse FVs.
|
||||
|
||||
@param[in] ScanAll Scan all modules in all FVs or not.
|
||||
|
||||
**/
|
||||
VOID
|
||||
ParseFv (
|
||||
IN BOOLEAN ScanAll
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_HANDLE *HandleBuffer;
|
||||
UINTN HandleCount;
|
||||
UINTN Index;
|
||||
EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv2;
|
||||
VOID *Key;
|
||||
EFI_FV_FILETYPE FileType;
|
||||
EFI_GUID NameGuid;
|
||||
EFI_FV_FILE_ATTRIBUTES FileAttributes;
|
||||
UINTN Size;
|
||||
UINTN FfsIndex;
|
||||
VAR_CHECK_VFR_DRIVER_INFO *VfrDriverInfo;
|
||||
LIST_ENTRY *VfrDriverLink;
|
||||
|
||||
HandleBuffer = NULL;
|
||||
Status = gBS->LocateHandleBuffer (
|
||||
ByProtocol,
|
||||
&gEfiFirmwareVolume2ProtocolGuid,
|
||||
NULL,
|
||||
&HandleCount,
|
||||
&HandleBuffer
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Search all FVs
|
||||
//
|
||||
for (Index = 0; Index < HandleCount; Index++) {
|
||||
DEBUG ((EFI_D_INFO, "FvIndex - %x\n", Index));
|
||||
Status = gBS->HandleProtocol (
|
||||
HandleBuffer[Index],
|
||||
&gEfiFirmwareVolume2ProtocolGuid,
|
||||
(VOID **) &Fv2
|
||||
);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
DEBUG_CODE (
|
||||
EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *Fvb2;
|
||||
EFI_PHYSICAL_ADDRESS FvAddress;
|
||||
UINT64 FvSize;
|
||||
|
||||
Status = gBS->HandleProtocol (
|
||||
HandleBuffer[Index],
|
||||
&gEfiFirmwareVolumeBlock2ProtocolGuid,
|
||||
(VOID **) &Fvb2
|
||||
);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
Status = Fvb2->GetPhysicalAddress (Fvb2, &FvAddress);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
DEBUG ((EFI_D_INFO, "FvAddress - 0x%08x\n", FvAddress));
|
||||
FvSize = ((EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) FvAddress)->FvLength;
|
||||
DEBUG ((EFI_D_INFO, "FvSize - 0x%08x\n", FvSize));
|
||||
}
|
||||
);
|
||||
|
||||
if (ScanAll) {
|
||||
//
|
||||
// Need to parse all modules in all FVs.
|
||||
//
|
||||
Key = InternalVarCheckAllocateZeroPool (Fv2->KeySize);
|
||||
ASSERT (Key != NULL);
|
||||
|
||||
for (FfsIndex = 0; ; FfsIndex++) {
|
||||
FileType = EFI_FV_FILETYPE_ALL;
|
||||
Status = Fv2->GetNextFile (
|
||||
Fv2,
|
||||
Key,
|
||||
&FileType,
|
||||
&NameGuid,
|
||||
&FileAttributes,
|
||||
&Size
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
break;
|
||||
}
|
||||
|
||||
ParseFfs (Fv2, &NameGuid);
|
||||
}
|
||||
|
||||
InternalVarCheckFreePool (Key);
|
||||
} else {
|
||||
//
|
||||
// Only parse drivers in the VFR drivers list.
|
||||
//
|
||||
VfrDriverLink = mVfrDriverList.ForwardLink;
|
||||
while (VfrDriverLink != &mVfrDriverList) {
|
||||
VfrDriverInfo = VAR_CHECK_VFR_DRIVER_INFO_FROM_LINK (VfrDriverLink);
|
||||
VfrDriverLink = VfrDriverLink->ForwardLink;
|
||||
if (ParseFfs (Fv2, VfrDriverInfo->DriverGuid)) {
|
||||
//
|
||||
// Found the driver in the FV.
|
||||
//
|
||||
RemoveEntryList (&VfrDriverInfo->Link);
|
||||
InternalVarCheckFreePool (VfrDriverInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FreePool (HandleBuffer);
|
||||
}
|
||||
|
||||
/**
|
||||
Create Vfr Driver List.
|
||||
|
||||
@param[in] DriverGuidArray Driver Guid Array
|
||||
|
||||
**/
|
||||
VOID
|
||||
CreateVfrDriverList (
|
||||
IN EFI_GUID *DriverGuidArray
|
||||
)
|
||||
{
|
||||
UINTN Index;
|
||||
VAR_CHECK_VFR_DRIVER_INFO *VfrDriverInfo;
|
||||
|
||||
for (Index = 0; !CompareGuid (&DriverGuidArray[Index], &gZeroGuid); Index++) {
|
||||
DEBUG ((EFI_D_INFO, "CreateVfrDriverList: %g\n", &DriverGuidArray[Index]));
|
||||
VfrDriverInfo = InternalVarCheckAllocateZeroPool (sizeof (*VfrDriverInfo));
|
||||
ASSERT (VfrDriverInfo != NULL);
|
||||
VfrDriverInfo->Signature = VAR_CHECK_VFR_DRIVER_INFO_SIGNATURE;
|
||||
VfrDriverInfo->DriverGuid = &DriverGuidArray[Index];
|
||||
InsertTailList (&mVfrDriverList, &VfrDriverInfo->Link);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Destroy Vfr Driver List.
|
||||
|
||||
**/
|
||||
VOID
|
||||
DestroyVfrDriverList (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
VAR_CHECK_VFR_DRIVER_INFO *VfrDriverInfo;
|
||||
LIST_ENTRY *VfrDriverLink;
|
||||
|
||||
while (mVfrDriverList.ForwardLink != &mVfrDriverList) {
|
||||
VfrDriverLink = mVfrDriverList.ForwardLink;
|
||||
VfrDriverInfo = VAR_CHECK_VFR_DRIVER_INFO_FROM_LINK (VfrDriverLink);
|
||||
RemoveEntryList (&VfrDriverInfo->Link);
|
||||
InternalVarCheckFreePool (VfrDriverInfo);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Generate from FV.
|
||||
|
||||
**/
|
||||
VOID
|
||||
VarCheckHiiGenFromFv (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
EFI_GUID *DriverGuidArray;
|
||||
BOOLEAN ScanAll;
|
||||
|
||||
DEBUG ((EFI_D_INFO, "VarCheckHiiGenDxeFromFv\n"));
|
||||
|
||||
//
|
||||
// Get vfr driver guid array from PCD.
|
||||
//
|
||||
DriverGuidArray = (EFI_GUID *) PcdGetPtr (PcdVarCheckVfrDriverGuidArray);
|
||||
|
||||
if (CompareGuid (&DriverGuidArray[0], &gZeroGuid)) {
|
||||
//
|
||||
// No VFR driver will be parsed from FVs.
|
||||
//
|
||||
return;
|
||||
}
|
||||
|
||||
if (CompareGuid (&DriverGuidArray[0], &mAllFfGuid)) {
|
||||
ScanAll = TRUE;
|
||||
} else {
|
||||
ScanAll = FALSE;
|
||||
CreateVfrDriverList (DriverGuidArray);
|
||||
}
|
||||
|
||||
ParseFv (ScanAll);
|
||||
|
||||
if (!ScanAll) {
|
||||
DestroyVfrDriverList ();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
/** @file
|
||||
Var Check Hii generation from Hii Database.
|
||||
|
||||
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 "VarCheckHiiGen.h"
|
||||
|
||||
/**
|
||||
Generate from Hii Database.
|
||||
|
||||
**/
|
||||
VOID
|
||||
VarCheckHiiGenFromHiiDatabase (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINTN BufferSize;
|
||||
VOID *Buffer;
|
||||
EFI_PHYSICAL_ADDRESS BufferAddress;
|
||||
EFI_HII_DATABASE_PROTOCOL *HiiDatabase;
|
||||
|
||||
//
|
||||
// Locate HII Database protocol
|
||||
//
|
||||
Status = gBS->LocateProtocol (&gEfiHiiDatabaseProtocolGuid, NULL, (VOID **) &HiiDatabase);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Call first time with zero buffer length.
|
||||
// Should fail with EFI_BUFFER_TOO_SMALL.
|
||||
//
|
||||
BufferSize = 0;
|
||||
Buffer = NULL;
|
||||
Status = HiiDatabase->ExportPackageLists (HiiDatabase, 0, &BufferSize, Buffer);
|
||||
if (Status == EFI_BUFFER_TOO_SMALL) {
|
||||
//
|
||||
// Allocate buffer to hold the HII Database.
|
||||
//
|
||||
Status = gBS->AllocatePages (AllocateAnyPages, EfiBootServicesData, EFI_SIZE_TO_PAGES (BufferSize), &BufferAddress);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
Buffer = (VOID *) (UINTN) BufferAddress;
|
||||
|
||||
//
|
||||
// Export HII Database into the buffer.
|
||||
//
|
||||
Status = HiiDatabase->ExportPackageLists (HiiDatabase, 0, &BufferSize, Buffer);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
DEBUG ((EFI_D_INFO, "VarCheckHiiGenDxeFromHii - HII Database exported at 0x%x, size = 0x%x\n", Buffer, BufferSize));
|
||||
|
||||
#ifdef DUMP_HII_DATA
|
||||
DEBUG_CODE (
|
||||
DumpHiiDatabase (Buffer, BufferSize);
|
||||
);
|
||||
#endif
|
||||
|
||||
VarCheckParseHiiDatabase (Buffer, BufferSize);
|
||||
|
||||
gBS->FreePages (BufferAddress, EFI_SIZE_TO_PAGES (BufferSize));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
## @file
|
||||
# NULL class library to register var check HII handler.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
##
|
||||
|
||||
[Defines]
|
||||
INF_VERSION = 0x00010005
|
||||
BASE_NAME = VarCheckHiiLib
|
||||
MODULE_UNI_FILE = VarCheckHiiLib.uni
|
||||
FILE_GUID = A34FBDD0-05D3-4AF7-A720-560E91AC8CDF
|
||||
MODULE_TYPE = DXE_RUNTIME_DRIVER
|
||||
VERSION_STRING = 1.0
|
||||
LIBRARY_CLASS = NULL|DXE_RUNTIME_DRIVER DXE_SMM_DRIVER
|
||||
CONSTRUCTOR = VarCheckHiiLibNullClassConstructor
|
||||
|
||||
[Sources]
|
||||
VarCheckHiiLibNullClass.c
|
||||
VarCheckHii.h
|
||||
VarCheckHiiGenFromFv.c
|
||||
VarCheckHiiGenFromHii.c
|
||||
VarCheckHiiGen.c
|
||||
VarCheckHiiGen.h
|
||||
InternalVarCheckStructure.h
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
MdeModulePkg/MdeModulePkg.dec
|
||||
|
||||
[LibraryClasses]
|
||||
BaseLib
|
||||
DebugLib
|
||||
BaseMemoryLib
|
||||
UefiBootServicesTableLib
|
||||
MemoryAllocationLib
|
||||
PcdLib
|
||||
VarCheckLib
|
||||
|
||||
[Guids]
|
||||
gZeroGuid ## SOMETIMES_CONSUMES ## GUID
|
||||
|
||||
[Protocols]
|
||||
gEfiFirmwareVolume2ProtocolGuid ## SOMETIMES_CONSUMES
|
||||
gEfiFirmwareVolumeBlock2ProtocolGuid ## SOMETIMES_CONSUMES
|
||||
gEfiHiiDatabaseProtocolGuid ## SOMETIMES_CONSUMES
|
||||
|
||||
[Pcd]
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdVarCheckVfrDriverGuidArray ## SOMETIMES_CONSUMES
|
Binary file not shown.
|
@ -0,0 +1,539 @@
|
|||
/** @file
|
||||
Var Check Hii handler.
|
||||
|
||||
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 "VarCheckHii.h"
|
||||
|
||||
GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 mVarCheckHiiHex[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
|
||||
|
||||
/**
|
||||
Dump some hexadecimal data.
|
||||
|
||||
@param[in] Indent How many spaces to indent the output.
|
||||
@param[in] Offset The offset of the dump.
|
||||
@param[in] DataSize The size in bytes of UserData.
|
||||
@param[in] UserData The data to dump.
|
||||
|
||||
**/
|
||||
VOID
|
||||
VarCheckHiiInternalDumpHex (
|
||||
IN UINTN Indent,
|
||||
IN UINTN Offset,
|
||||
IN UINTN DataSize,
|
||||
IN VOID *UserData
|
||||
)
|
||||
{
|
||||
UINT8 *Data;
|
||||
|
||||
CHAR8 Val[50];
|
||||
|
||||
CHAR8 Str[20];
|
||||
|
||||
UINT8 TempByte;
|
||||
UINTN Size;
|
||||
UINTN Index;
|
||||
|
||||
Data = UserData;
|
||||
while (DataSize != 0) {
|
||||
Size = 16;
|
||||
if (Size > DataSize) {
|
||||
Size = DataSize;
|
||||
}
|
||||
|
||||
for (Index = 0; Index < Size; Index += 1) {
|
||||
TempByte = Data[Index];
|
||||
Val[Index * 3 + 0] = mVarCheckHiiHex[TempByte >> 4];
|
||||
Val[Index * 3 + 1] = mVarCheckHiiHex[TempByte & 0xF];
|
||||
Val[Index * 3 + 2] = (CHAR8) ((Index == 7) ? '-' : ' ');
|
||||
Str[Index] = (CHAR8) ((TempByte < ' ' || TempByte > 'z') ? '.' : TempByte);
|
||||
}
|
||||
|
||||
Val[Index * 3] = 0;
|
||||
Str[Index] = 0;
|
||||
DEBUG ((EFI_D_INFO, "%*a%08X: %-48a *%a*\r\n", Indent, "", Offset, Val, Str));
|
||||
|
||||
Data += Size;
|
||||
Offset += Size;
|
||||
DataSize -= Size;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Var Check Hii Question.
|
||||
|
||||
@param[in] HiiQuestion Pointer to Hii Question
|
||||
@param[in] Data Data pointer.
|
||||
@param[in] DataSize Size of Data to set.
|
||||
|
||||
@retval TRUE Check pass
|
||||
@retval FALSE Check fail.
|
||||
|
||||
**/
|
||||
BOOLEAN
|
||||
VarCheckHiiQuestion (
|
||||
IN VAR_CHECK_HII_QUESTION_HEADER *HiiQuestion,
|
||||
IN VOID *Data,
|
||||
IN UINTN DataSize
|
||||
)
|
||||
{
|
||||
UINT64 OneData;
|
||||
UINT64 Minimum;
|
||||
UINT64 Maximum;
|
||||
UINT64 OneValue;
|
||||
UINT8 *Ptr;
|
||||
UINT8 Index;
|
||||
UINT8 MaxContainers;
|
||||
|
||||
if ((UINTN) (HiiQuestion->VarOffset + HiiQuestion->StorageWidth) > DataSize) {
|
||||
DEBUG ((EFI_D_INFO, "VarCheckHiiQuestion fail: (VarOffset(0x%04x) + StorageWidth(0x%02x)) > Size(0x%x)\n", HiiQuestion->VarOffset, HiiQuestion->StorageWidth, DataSize));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
OneData = 0;
|
||||
CopyMem (&OneData, (UINT8 *) Data + HiiQuestion->VarOffset, HiiQuestion->StorageWidth);
|
||||
|
||||
switch (HiiQuestion->OpCode) {
|
||||
case EFI_IFR_ONE_OF_OP:
|
||||
Ptr = (UINT8 *) ((VAR_CHECK_HII_QUESTION_ONEOF *) HiiQuestion + 1);
|
||||
while ((UINTN) Ptr < (UINTN) HiiQuestion + HiiQuestion->Length) {
|
||||
OneValue = 0;
|
||||
CopyMem (&OneValue, Ptr, HiiQuestion->StorageWidth);
|
||||
if (OneData == OneValue) {
|
||||
//
|
||||
// Match
|
||||
//
|
||||
break;
|
||||
}
|
||||
Ptr += HiiQuestion->StorageWidth;
|
||||
}
|
||||
if ((UINTN) Ptr >= ((UINTN) HiiQuestion + HiiQuestion->Length)) {
|
||||
//
|
||||
// No match
|
||||
//
|
||||
DEBUG ((EFI_D_INFO, "VarCheckHiiQuestion fail: OneOf mismatch (0x%lx)\n", OneData));
|
||||
DEBUG_CODE (VarCheckHiiInternalDumpHex (2, 0, HiiQuestion->Length, (UINT8 *) HiiQuestion););
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
|
||||
case EFI_IFR_CHECKBOX_OP:
|
||||
if ((OneData != 0) && (OneData != 1)) {
|
||||
DEBUG ((EFI_D_INFO, "VarCheckHiiQuestion fail: CheckBox mismatch (0x%lx)\n", OneData));
|
||||
DEBUG_CODE (VarCheckHiiInternalDumpHex (2, 0, HiiQuestion->Length, (UINT8 *) HiiQuestion););
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
|
||||
case EFI_IFR_NUMERIC_OP:
|
||||
Minimum = 0;
|
||||
Maximum = 0;
|
||||
Ptr = (UINT8 *) ((VAR_CHECK_HII_QUESTION_NUMERIC *) HiiQuestion + 1);
|
||||
CopyMem (&Minimum, Ptr, HiiQuestion->StorageWidth);
|
||||
Ptr += HiiQuestion->StorageWidth;
|
||||
CopyMem (&Maximum, Ptr, HiiQuestion->StorageWidth);
|
||||
Ptr += HiiQuestion->StorageWidth;
|
||||
|
||||
//
|
||||
// No need to check Step, because it is ONLY for UI.
|
||||
//
|
||||
if ((OneData < Minimum) || (OneData > Maximum)) {
|
||||
DEBUG ((EFI_D_INFO, "VarCheckHiiQuestion fail: Numeric mismatch (0x%lx)\n", OneData));
|
||||
DEBUG_CODE (VarCheckHiiInternalDumpHex (2, 0, HiiQuestion->Length, (UINT8 *) HiiQuestion););
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
|
||||
case EFI_IFR_ORDERED_LIST_OP:
|
||||
MaxContainers = ((VAR_CHECK_HII_QUESTION_ORDEREDLIST *) HiiQuestion)->MaxContainers;
|
||||
if ((UINTN) (HiiQuestion->VarOffset + HiiQuestion->StorageWidth * MaxContainers) > DataSize) {
|
||||
DEBUG ((EFI_D_INFO, "VarCheckHiiQuestion fail: (VarOffset(0x%04x) + StorageWidth(0x%02x) * MaxContainers(0x%02x)) > Size(0x%x)\n", HiiQuestion->VarOffset, HiiQuestion->StorageWidth, MaxContainers, DataSize));
|
||||
return FALSE;
|
||||
}
|
||||
for (Index = 0; Index < MaxContainers; Index++) {
|
||||
OneData = 0;
|
||||
CopyMem (&OneData, (UINT8 *) Data + HiiQuestion->VarOffset + HiiQuestion->StorageWidth * Index, HiiQuestion->StorageWidth);
|
||||
if (OneData == 0) {
|
||||
//
|
||||
// The value of 0 is used to determine if a particular "slot" in the array is empty.
|
||||
//
|
||||
continue;
|
||||
}
|
||||
|
||||
Ptr = (UINT8 *) ((VAR_CHECK_HII_QUESTION_ORDEREDLIST *) HiiQuestion + 1);
|
||||
while ((UINTN) Ptr < ((UINTN) HiiQuestion + HiiQuestion->Length)) {
|
||||
OneValue = 0;
|
||||
CopyMem (&OneValue, Ptr, HiiQuestion->StorageWidth);
|
||||
if (OneData == OneValue) {
|
||||
//
|
||||
// Match
|
||||
//
|
||||
break;
|
||||
}
|
||||
Ptr += HiiQuestion->StorageWidth;
|
||||
}
|
||||
if ((UINTN) Ptr >= ((UINTN) HiiQuestion + HiiQuestion->Length)) {
|
||||
//
|
||||
// No match
|
||||
//
|
||||
DEBUG ((EFI_D_INFO, "VarCheckHiiQuestion fail: OrderedList mismatch\n"));
|
||||
DEBUG_CODE (VarCheckHiiInternalDumpHex (2, 0, HiiQuestion->StorageWidth * MaxContainers, (UINT8 *) Data + HiiQuestion->VarOffset););
|
||||
DEBUG_CODE (VarCheckHiiInternalDumpHex (2, 0, HiiQuestion->Length, (UINT8 *) HiiQuestion););
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
ASSERT (FALSE);
|
||||
break;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
VAR_CHECK_HII_VARIABLE_HEADER *mVarCheckHiiBin = NULL;
|
||||
UINTN mVarCheckHiiBinSize = 0;
|
||||
|
||||
/**
|
||||
SetVariable check handler HII.
|
||||
|
||||
@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_SECURITY_VIOLATION Check fail.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
SetVariableCheckHandlerHii (
|
||||
IN CHAR16 *VariableName,
|
||||
IN EFI_GUID *VendorGuid,
|
||||
IN UINT32 Attributes,
|
||||
IN UINTN DataSize,
|
||||
IN VOID *Data
|
||||
)
|
||||
{
|
||||
VAR_CHECK_HII_VARIABLE_HEADER *HiiVariable;
|
||||
VAR_CHECK_HII_QUESTION_HEADER *HiiQuestion;
|
||||
|
||||
if (mVarCheckHiiBin == NULL) {
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
if ((((Attributes & EFI_VARIABLE_APPEND_WRITE) == 0) && (DataSize == 0)) || (Attributes == 0)) {
|
||||
//
|
||||
// Do not check delete variable.
|
||||
//
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
//
|
||||
// For Hii Variable header align.
|
||||
//
|
||||
HiiVariable = (VAR_CHECK_HII_VARIABLE_HEADER *) HEADER_ALIGN (mVarCheckHiiBin);
|
||||
while ((UINTN) HiiVariable < ((UINTN) mVarCheckHiiBin + mVarCheckHiiBinSize)) {
|
||||
if ((StrCmp ((CHAR16 *) (HiiVariable + 1), VariableName) == 0) &&
|
||||
(CompareGuid (&HiiVariable->Guid, VendorGuid))) {
|
||||
//
|
||||
// Found the Hii Variable that could be used to do check.
|
||||
//
|
||||
DEBUG ((EFI_D_INFO, "VarCheckHiiVariable - %s:%g with Attributes = 0x%08x Size = 0x%x\n", VariableName, VendorGuid, Attributes, DataSize));
|
||||
if (HiiVariable->Attributes != Attributes) {
|
||||
DEBUG ((EFI_D_INFO, "VarCheckHiiVariable fail for Attributes - 0x%08x\n", HiiVariable->Attributes));
|
||||
return EFI_SECURITY_VIOLATION;
|
||||
}
|
||||
|
||||
if (DataSize == 0) {
|
||||
DEBUG ((EFI_D_INFO, "VarCheckHiiVariable - CHECK PASS with DataSize == 0 !\n"));
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
if (HiiVariable->Size != DataSize) {
|
||||
DEBUG ((EFI_D_INFO, "VarCheckHiiVariable fail for Size - 0x%x\n", HiiVariable->Size));
|
||||
return EFI_SECURITY_VIOLATION;
|
||||
}
|
||||
|
||||
//
|
||||
// Do the check.
|
||||
// For Hii Question header align.
|
||||
//
|
||||
HiiQuestion = (VAR_CHECK_HII_QUESTION_HEADER *) HEADER_ALIGN (((UINTN) HiiVariable + HiiVariable->HeaderLength));
|
||||
while ((UINTN) HiiQuestion < ((UINTN) HiiVariable + HiiVariable->Length)) {
|
||||
if (!VarCheckHiiQuestion (HiiQuestion, Data, DataSize)) {
|
||||
return EFI_SECURITY_VIOLATION;
|
||||
}
|
||||
//
|
||||
// For Hii Question header align.
|
||||
//
|
||||
HiiQuestion = (VAR_CHECK_HII_QUESTION_HEADER *) HEADER_ALIGN (((UINTN) HiiQuestion + HiiQuestion->Length));
|
||||
}
|
||||
|
||||
DEBUG ((EFI_D_INFO, "VarCheckHiiVariable - ALL CHECK PASS!\n"));
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
//
|
||||
// For Hii Variable header align.
|
||||
//
|
||||
HiiVariable = (VAR_CHECK_HII_VARIABLE_HEADER *) HEADER_ALIGN (((UINTN) HiiVariable + HiiVariable->Length));
|
||||
}
|
||||
|
||||
// Not found, so pass.
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
#ifdef DUMP_VAR_CHECK_HII
|
||||
GLOBAL_REMOVE_IF_UNREFERENCED VAR_CHECK_HII_OPCODE_STRING mHiiOpCodeStringTable[] = {
|
||||
{EFI_IFR_VARSTORE_EFI_OP, "EfiVarStore"},
|
||||
{EFI_IFR_ONE_OF_OP, "OneOf"},
|
||||
{EFI_IFR_CHECKBOX_OP, "CheckBox"},
|
||||
{EFI_IFR_NUMERIC_OP, "Numeric"},
|
||||
{EFI_IFR_ORDERED_LIST_OP, "OrderedList"},
|
||||
};
|
||||
|
||||
/**
|
||||
HII opcode to string.
|
||||
|
||||
@param[in] HiiOpCode Hii OpCode.
|
||||
|
||||
@return Pointer to string.
|
||||
|
||||
**/
|
||||
CHAR8 *
|
||||
HiiOpCodeToStr (
|
||||
IN UINT8 HiiOpCode
|
||||
)
|
||||
{
|
||||
UINTN Index;
|
||||
for (Index = 0; Index < sizeof (mHiiOpCodeStringTable) / sizeof (mHiiOpCodeStringTable[0]); Index++) {
|
||||
if (mHiiOpCodeStringTable[Index].HiiOpCode == HiiOpCode) {
|
||||
return mHiiOpCodeStringTable[Index].HiiOpCodeStr;
|
||||
}
|
||||
}
|
||||
|
||||
return "<UnknownHiiOpCode>";
|
||||
}
|
||||
|
||||
/**
|
||||
Dump Hii Question.
|
||||
|
||||
@param[in] HiiQuestion Pointer to Hii Question.
|
||||
|
||||
**/
|
||||
VOID
|
||||
DumpHiiQuestion (
|
||||
IN VAR_CHECK_HII_QUESTION_HEADER *HiiQuestion
|
||||
)
|
||||
{
|
||||
UINT64 Minimum;
|
||||
UINT64 Maximum;
|
||||
UINT64 OneValue;
|
||||
UINT8 *Ptr;
|
||||
|
||||
DEBUG ((EFI_D_INFO, " VAR_CHECK_HII_QUESTION_HEADER\n"));
|
||||
DEBUG ((EFI_D_INFO, " OpCode - 0x%02x (%a)\n", HiiQuestion->OpCode, HiiOpCodeToStr (HiiQuestion->OpCode)));
|
||||
DEBUG ((EFI_D_INFO, " Length - 0x%02x\n", HiiQuestion->Length));
|
||||
DEBUG ((EFI_D_INFO, " VarOffset - 0x%04x\n", HiiQuestion->VarOffset));
|
||||
DEBUG ((EFI_D_INFO, " StorageWidth - 0x%02x\n", HiiQuestion->StorageWidth));
|
||||
|
||||
switch (HiiQuestion->OpCode) {
|
||||
case EFI_IFR_ONE_OF_OP:
|
||||
Ptr = (UINT8 *) ((VAR_CHECK_HII_QUESTION_ONEOF *) HiiQuestion + 1);
|
||||
while ((UINTN) Ptr < ((UINTN) HiiQuestion + HiiQuestion->Length)) {
|
||||
OneValue = 0;
|
||||
CopyMem (&OneValue, Ptr, HiiQuestion->StorageWidth);
|
||||
switch (HiiQuestion->StorageWidth) {
|
||||
case sizeof (UINT8):
|
||||
DEBUG ((EFI_D_INFO, " OneOfOption - 0x%02x\n", OneValue));
|
||||
break;
|
||||
case sizeof (UINT16):
|
||||
DEBUG ((EFI_D_INFO, " OneOfOption - 0x%04x\n", OneValue));
|
||||
break;
|
||||
case sizeof (UINT32):
|
||||
DEBUG ((EFI_D_INFO, " OneOfOption - 0x%08x\n", OneValue));
|
||||
break;
|
||||
case sizeof (UINT64):
|
||||
DEBUG ((EFI_D_INFO, " OneOfOption - 0x%016lx\n", OneValue));
|
||||
break;
|
||||
default:
|
||||
ASSERT (FALSE);
|
||||
break;
|
||||
}
|
||||
Ptr += HiiQuestion->StorageWidth;
|
||||
}
|
||||
break;
|
||||
|
||||
case EFI_IFR_CHECKBOX_OP:
|
||||
break;
|
||||
|
||||
case EFI_IFR_NUMERIC_OP:
|
||||
Minimum = 0;
|
||||
Maximum = 0;
|
||||
Ptr = (UINT8 *) ((VAR_CHECK_HII_QUESTION_NUMERIC *) HiiQuestion + 1);
|
||||
CopyMem (&Minimum, Ptr, HiiQuestion->StorageWidth);
|
||||
Ptr += HiiQuestion->StorageWidth;
|
||||
CopyMem (&Maximum, Ptr, HiiQuestion->StorageWidth);
|
||||
Ptr += HiiQuestion->StorageWidth;
|
||||
|
||||
switch (HiiQuestion->StorageWidth) {
|
||||
case sizeof (UINT8):
|
||||
DEBUG ((EFI_D_INFO, " Minimum - 0x%02x\n", Minimum));
|
||||
DEBUG ((EFI_D_INFO, " Maximum - 0x%02x\n", Maximum));
|
||||
break;
|
||||
case sizeof (UINT16):
|
||||
DEBUG ((EFI_D_INFO, " Minimum - 0x%04x\n", Minimum));
|
||||
DEBUG ((EFI_D_INFO, " Maximum - 0x%04x\n", Maximum));
|
||||
break;
|
||||
case sizeof (UINT32):
|
||||
DEBUG ((EFI_D_INFO, " Minimum - 0x%08x\n", Minimum));
|
||||
DEBUG ((EFI_D_INFO, " Maximum - 0x%08x\n", Maximum));
|
||||
break;
|
||||
case sizeof (UINT64):
|
||||
DEBUG ((EFI_D_INFO, " Minimum - 0x%016lx\n", Minimum));
|
||||
DEBUG ((EFI_D_INFO, " Maximum - 0x%016lx\n", Maximum));
|
||||
break;
|
||||
default:
|
||||
ASSERT (FALSE);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case EFI_IFR_ORDERED_LIST_OP:
|
||||
DEBUG ((EFI_D_INFO, " MaxContainers - 0x%02x\n", ((VAR_CHECK_HII_QUESTION_ORDEREDLIST *) HiiQuestion)->MaxContainers));
|
||||
Ptr = (UINT8 *) ((VAR_CHECK_HII_QUESTION_ORDEREDLIST *) HiiQuestion + 1);
|
||||
while ((UINTN) Ptr < ((UINTN) HiiQuestion + HiiQuestion->Length)) {
|
||||
OneValue = 0;
|
||||
CopyMem (&OneValue, Ptr, HiiQuestion->StorageWidth);
|
||||
switch (HiiQuestion->StorageWidth) {
|
||||
case sizeof (UINT8):
|
||||
DEBUG ((EFI_D_INFO, " OneOfOption - 0x%02x\n", OneValue));
|
||||
break;
|
||||
case sizeof (UINT16):
|
||||
DEBUG ((EFI_D_INFO, " OneOfOption - 0x%04x\n", OneValue));
|
||||
break;
|
||||
case sizeof (UINT32):
|
||||
DEBUG ((EFI_D_INFO, " OneOfOption - 0x%08x\n", OneValue));
|
||||
break;
|
||||
case sizeof (UINT64):
|
||||
DEBUG ((EFI_D_INFO, " OneOfOption - 0x%016lx\n", OneValue));
|
||||
break;
|
||||
default:
|
||||
ASSERT (FALSE);
|
||||
break;
|
||||
}
|
||||
Ptr += HiiQuestion->StorageWidth;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
ASSERT (FALSE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Dump Hii Variable.
|
||||
|
||||
@param[in] HiiVariable Pointer to Hii Variable.
|
||||
|
||||
**/
|
||||
VOID
|
||||
DumpHiiVariable (
|
||||
IN VAR_CHECK_HII_VARIABLE_HEADER *HiiVariable
|
||||
)
|
||||
{
|
||||
VAR_CHECK_HII_QUESTION_HEADER *HiiQuestion;
|
||||
|
||||
DEBUG ((EFI_D_INFO, "VAR_CHECK_HII_VARIABLE_HEADER\n"));
|
||||
DEBUG ((EFI_D_INFO, " Revision - 0x%04x\n", HiiVariable->Revision));
|
||||
DEBUG ((EFI_D_INFO, " HeaderLength - 0x%04x\n", HiiVariable->HeaderLength));
|
||||
DEBUG ((EFI_D_INFO, " Length - 0x%08x\n", HiiVariable->Length));
|
||||
DEBUG ((EFI_D_INFO, " OpCode - 0x%02x (%a)\n", HiiVariable->OpCode, HiiOpCodeToStr (HiiVariable->OpCode)));
|
||||
DEBUG ((EFI_D_INFO, " Size - 0x%04x\n", HiiVariable->Size));
|
||||
DEBUG ((EFI_D_INFO, " Attributes - 0x%08x\n", HiiVariable->Attributes));
|
||||
DEBUG ((EFI_D_INFO, " Guid - %g\n", &HiiVariable->Guid));
|
||||
DEBUG ((EFI_D_INFO, " Name - %s\n", HiiVariable + 1));
|
||||
|
||||
//
|
||||
// For Hii Question header align.
|
||||
//
|
||||
HiiQuestion = (VAR_CHECK_HII_QUESTION_HEADER *) HEADER_ALIGN (((UINTN) HiiVariable + HiiVariable->HeaderLength));
|
||||
while ((UINTN) HiiQuestion < ((UINTN) HiiVariable + HiiVariable->Length)) {
|
||||
//
|
||||
// Dump Hii Question related to the Hii Variable.
|
||||
//
|
||||
DumpHiiQuestion (HiiQuestion);
|
||||
//
|
||||
// For Hii Question header align.
|
||||
//
|
||||
HiiQuestion = (VAR_CHECK_HII_QUESTION_HEADER *) HEADER_ALIGN (((UINTN) HiiQuestion + HiiQuestion->Length));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Dump Var Check HII.
|
||||
|
||||
@param[in] VarCheckHiiBin Pointer to VarCheckHiiBin.
|
||||
@param[in] VarCheckHiiBinSize VarCheckHiiBin size.
|
||||
|
||||
**/
|
||||
VOID
|
||||
DumpVarCheckHii (
|
||||
IN VOID *VarCheckHiiBin,
|
||||
IN UINTN VarCheckHiiBinSize
|
||||
)
|
||||
{
|
||||
VAR_CHECK_HII_VARIABLE_HEADER *HiiVariable;
|
||||
|
||||
DEBUG ((EFI_D_INFO, "DumpVarCheckHii\n"));
|
||||
|
||||
//
|
||||
// For Hii Variable header align.
|
||||
//
|
||||
HiiVariable = (VAR_CHECK_HII_VARIABLE_HEADER *) HEADER_ALIGN (VarCheckHiiBin);
|
||||
while ((UINTN) HiiVariable < ((UINTN) VarCheckHiiBin + VarCheckHiiBinSize)) {
|
||||
DumpHiiVariable (HiiVariable);
|
||||
//
|
||||
// For Hii Variable header align.
|
||||
//
|
||||
HiiVariable = (VAR_CHECK_HII_VARIABLE_HEADER *) HEADER_ALIGN (((UINTN) HiiVariable + HiiVariable->Length));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
Constructor function of VarCheckHiiLib to register var check HII handler.
|
||||
|
||||
@param[in] ImageHandle The firmware allocated handle for the EFI image.
|
||||
@param[in] SystemTable A pointer to the EFI System Table.
|
||||
|
||||
@retval EFI_SUCCESS The constructor executed correctly.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
VarCheckHiiLibNullClassConstructor (
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
)
|
||||
{
|
||||
VarCheckLibRegisterEndOfDxeCallback (VarCheckHiiGen);
|
||||
VarCheckLibRegisterAddressPointer ((VOID **) &mVarCheckHiiBin);
|
||||
VarCheckLibRegisterSetVariableCheckHandler (SetVariableCheckHandlerHii);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
|
@ -974,6 +974,12 @@
|
|||
# @Prompt Set NX for stack.
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdSetNxForStack|FALSE|BOOLEAN|0x0001006f
|
||||
|
||||
## This PCD to include the driver guid of VFR drivers for VarCheckHiiBin generation.<BR><BR>
|
||||
# Default is gZeroGuid that means no VFR driver will be parsed for VarCheckHiiBin generation.<BR>
|
||||
# If it is set to an all FFs GUID, it means all modules in all FVs will be parsed for VarCheckHiiBin generation.<BR>
|
||||
# @Prompt Driver guid array of VFR drivers for VarCheckHiiBin generation.
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdVarCheckVfrDriverGuidArray|{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }|VOID*|0x3000103A
|
||||
|
||||
[PcdsPatchableInModule, PcdsDynamic, PcdsDynamicEx]
|
||||
## This PCD defines the Console output row. The default value is 25 according to UEFI spec.
|
||||
# This PCD could be set to 0 then console output would be at max column and max row.
|
||||
|
|
|
@ -280,6 +280,7 @@
|
|||
MdeModulePkg/Library/AuthVariableLibNull/AuthVariableLibNull.inf
|
||||
MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf
|
||||
MdeModulePkg/Library/VarCheckUefiLib/VarCheckUefiLib.inf
|
||||
MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLib.inf
|
||||
|
||||
MdeModulePkg/Universal/BdsDxe/BdsDxe.inf
|
||||
MdeModulePkg/Application/BootManagerMenuApp/BootManagerMenuApp.inf
|
||||
|
@ -375,6 +376,7 @@
|
|||
MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf {
|
||||
<LibraryClasses>
|
||||
NULL|MdeModulePkg/Library/VarCheckUefiLib/VarCheckUefiLib.inf
|
||||
NULL|MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLib.inf
|
||||
}
|
||||
MdeModulePkg/Universal/Variable/EmuRuntimeDxe/EmuVariableRuntimeDxe.inf
|
||||
|
||||
|
@ -384,6 +386,7 @@
|
|||
MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf {
|
||||
<LibraryClasses>
|
||||
NULL|MdeModulePkg/Library/VarCheckUefiLib/VarCheckUefiLib.inf
|
||||
NULL|MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLib.inf
|
||||
}
|
||||
MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.inf
|
||||
MdeModulePkg/Library/SmmReportStatusCodeLib/SmmReportStatusCodeLib.inf
|
||||
|
|
Binary file not shown.
Loading…
Reference in New Issue