2008-05-21 03:40:12 +02:00
|
|
|
/** @file
|
2008-04-09 09:07:50 +02:00
|
|
|
FFS file access utilities.
|
|
|
|
|
2011-05-17 14:13:35 +02:00
|
|
|
Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
|
2010-04-24 11:49:11 +02:00
|
|
|
This program and the accompanying materials
|
2008-05-21 03:40:12 +02:00
|
|
|
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.
|
2007-07-04 12:51:54 +02:00
|
|
|
|
2008-04-09 09:07:50 +02:00
|
|
|
**/
|
2007-07-04 12:51:54 +02:00
|
|
|
|
|
|
|
|
2008-08-27 16:29:23 +02:00
|
|
|
#include "DxeMain.h"
|
2008-09-23 09:35:34 +02:00
|
|
|
#include "FwVolDriver.h"
|
2007-07-04 12:51:54 +02:00
|
|
|
|
|
|
|
|
2008-05-09 09:08:30 +02:00
|
|
|
/**
|
|
|
|
Get the FFS file state by checking the highest bit set in the header's state field.
|
|
|
|
|
2008-07-24 04:54:45 +02:00
|
|
|
@param ErasePolarity Erase polarity attribute of the firmware volume
|
|
|
|
@param FfsHeader Points to the FFS file header
|
2008-05-09 09:08:30 +02:00
|
|
|
|
|
|
|
@return FFS File state
|
|
|
|
|
|
|
|
**/
|
2007-07-04 12:51:54 +02:00
|
|
|
EFI_FFS_FILE_STATE
|
|
|
|
GetFileState (
|
|
|
|
IN UINT8 ErasePolarity,
|
|
|
|
IN EFI_FFS_FILE_HEADER *FfsHeader
|
|
|
|
)
|
|
|
|
{
|
|
|
|
EFI_FFS_FILE_STATE FileState;
|
|
|
|
UINT8 HighestBit;
|
|
|
|
|
|
|
|
FileState = FfsHeader->State;
|
|
|
|
|
|
|
|
if (ErasePolarity != 0) {
|
|
|
|
FileState = (EFI_FFS_FILE_STATE)~FileState;
|
|
|
|
}
|
|
|
|
|
|
|
|
HighestBit = 0x80;
|
|
|
|
while (HighestBit != 0 && ((HighestBit & FileState) == 0)) {
|
|
|
|
HighestBit >>= 1;
|
|
|
|
}
|
|
|
|
|
2008-07-18 11:50:09 +02:00
|
|
|
return (EFI_FFS_FILE_STATE) HighestBit;
|
2007-07-04 12:51:54 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-05-09 09:08:30 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
Check if a block of buffer is erased.
|
|
|
|
|
2008-07-24 04:54:45 +02:00
|
|
|
@param ErasePolarity Erase polarity attribute of the firmware volume
|
|
|
|
@param InBuffer The buffer to be checked
|
|
|
|
@param BufferSize Size of the buffer in bytes
|
2008-05-09 09:08:30 +02:00
|
|
|
|
2008-07-24 04:54:45 +02:00
|
|
|
@retval TRUE The block of buffer is erased
|
2008-05-09 09:08:30 +02:00
|
|
|
@retval FALSE The block of buffer is not erased
|
|
|
|
|
|
|
|
**/
|
2007-07-04 12:51:54 +02:00
|
|
|
BOOLEAN
|
|
|
|
IsBufferErased (
|
|
|
|
IN UINT8 ErasePolarity,
|
|
|
|
IN VOID *InBuffer,
|
|
|
|
IN UINTN BufferSize
|
|
|
|
)
|
|
|
|
{
|
|
|
|
UINTN Count;
|
|
|
|
UINT8 EraseByte;
|
|
|
|
UINT8 *Buffer;
|
|
|
|
|
|
|
|
if(ErasePolarity == 1) {
|
|
|
|
EraseByte = 0xFF;
|
|
|
|
} else {
|
|
|
|
EraseByte = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
Buffer = InBuffer;
|
|
|
|
for (Count = 0; Count < BufferSize; Count++) {
|
|
|
|
if (Buffer[Count] != EraseByte) {
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-05-09 09:08:30 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
Verify checksum of the firmware volume header.
|
|
|
|
|
2008-07-24 04:54:45 +02:00
|
|
|
@param FvHeader Points to the firmware volume header to be checked
|
2008-05-09 09:08:30 +02:00
|
|
|
|
2008-07-24 04:54:45 +02:00
|
|
|
@retval TRUE Checksum verification passed
|
2008-05-09 09:08:30 +02:00
|
|
|
@retval FALSE Checksum verification failed
|
|
|
|
|
|
|
|
**/
|
2007-07-04 12:51:54 +02:00
|
|
|
BOOLEAN
|
|
|
|
VerifyFvHeaderChecksum (
|
|
|
|
IN EFI_FIRMWARE_VOLUME_HEADER *FvHeader
|
|
|
|
)
|
|
|
|
{
|
|
|
|
UINT16 Checksum;
|
|
|
|
|
2011-05-17 14:13:35 +02:00
|
|
|
Checksum = CalculateSum16 ((UINT16 *) FvHeader, FvHeader->HeaderLength);
|
2007-07-04 12:51:54 +02:00
|
|
|
|
|
|
|
if (Checksum == 0) {
|
|
|
|
return TRUE;
|
|
|
|
} else {
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-05-09 09:08:30 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
Verify checksum of the FFS file header.
|
|
|
|
|
2008-07-24 04:54:45 +02:00
|
|
|
@param FfsHeader Points to the FFS file header to be checked
|
2008-05-09 09:08:30 +02:00
|
|
|
|
2008-07-24 04:54:45 +02:00
|
|
|
@retval TRUE Checksum verification passed
|
2008-05-09 09:08:30 +02:00
|
|
|
@retval FALSE Checksum verification failed
|
|
|
|
|
|
|
|
**/
|
2007-07-04 12:51:54 +02:00
|
|
|
BOOLEAN
|
|
|
|
VerifyHeaderChecksum (
|
|
|
|
IN EFI_FFS_FILE_HEADER *FfsHeader
|
|
|
|
)
|
|
|
|
{
|
2011-05-17 14:13:35 +02:00
|
|
|
UINT8 HeaderChecksum;
|
2007-07-04 12:51:54 +02:00
|
|
|
|
2011-10-27 11:23:19 +02:00
|
|
|
if (IS_FFS_FILE2 (FfsHeader)) {
|
|
|
|
HeaderChecksum = CalculateSum8 ((UINT8 *) FfsHeader, sizeof (EFI_FFS_FILE_HEADER2));
|
|
|
|
} else {
|
|
|
|
HeaderChecksum = CalculateSum8 ((UINT8 *) FfsHeader, sizeof (EFI_FFS_FILE_HEADER));
|
|
|
|
}
|
2007-07-04 12:51:54 +02:00
|
|
|
HeaderChecksum = (UINT8) (HeaderChecksum - FfsHeader->State - FfsHeader->IntegrityCheck.Checksum.File);
|
|
|
|
|
|
|
|
if (HeaderChecksum == 0) {
|
|
|
|
return TRUE;
|
|
|
|
} else {
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-05-09 09:08:30 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
Check if it's a valid FFS file header.
|
|
|
|
|
2008-07-24 04:54:45 +02:00
|
|
|
@param ErasePolarity Erase polarity attribute of the firmware volume
|
|
|
|
@param FfsHeader Points to the FFS file header to be checked
|
|
|
|
@param FileState FFS file state to be returned
|
2008-05-09 09:08:30 +02:00
|
|
|
|
2008-07-24 04:54:45 +02:00
|
|
|
@retval TRUE Valid FFS file header
|
2008-05-09 09:08:30 +02:00
|
|
|
@retval FALSE Invalid FFS file header
|
|
|
|
|
|
|
|
**/
|
2007-07-04 12:51:54 +02:00
|
|
|
BOOLEAN
|
|
|
|
IsValidFfsHeader (
|
|
|
|
IN UINT8 ErasePolarity,
|
|
|
|
IN EFI_FFS_FILE_HEADER *FfsHeader,
|
|
|
|
OUT EFI_FFS_FILE_STATE *FileState
|
|
|
|
)
|
|
|
|
{
|
|
|
|
*FileState = GetFileState (ErasePolarity, FfsHeader);
|
|
|
|
|
|
|
|
switch (*FileState) {
|
2008-07-18 11:50:09 +02:00
|
|
|
case EFI_FILE_HEADER_VALID:
|
|
|
|
case EFI_FILE_DATA_VALID:
|
|
|
|
case EFI_FILE_MARKED_FOR_UPDATE:
|
|
|
|
case EFI_FILE_DELETED:
|
|
|
|
//
|
|
|
|
// Here we need to verify header checksum
|
|
|
|
//
|
|
|
|
return VerifyHeaderChecksum (FfsHeader);
|
2008-07-24 04:54:45 +02:00
|
|
|
|
2008-07-18 11:50:09 +02:00
|
|
|
case EFI_FILE_HEADER_CONSTRUCTION:
|
|
|
|
case EFI_FILE_HEADER_INVALID:
|
|
|
|
default:
|
|
|
|
return FALSE;
|
2007-07-04 12:51:54 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-05-09 09:08:30 +02:00
|
|
|
/**
|
|
|
|
Check if it's a valid FFS file.
|
|
|
|
Here we are sure that it has a valid FFS file header since we must call IsValidFfsHeader() first.
|
|
|
|
|
2008-07-24 04:54:45 +02:00
|
|
|
@param ErasePolarity Erase polarity attribute of the firmware volume
|
|
|
|
@param FfsHeader Points to the FFS file to be checked
|
2008-05-09 09:08:30 +02:00
|
|
|
|
2008-07-24 04:54:45 +02:00
|
|
|
@retval TRUE Valid FFS file
|
2008-05-09 09:08:30 +02:00
|
|
|
@retval FALSE Invalid FFS file
|
|
|
|
|
|
|
|
**/
|
2007-07-04 12:51:54 +02:00
|
|
|
BOOLEAN
|
|
|
|
IsValidFfsFile (
|
|
|
|
IN UINT8 ErasePolarity,
|
|
|
|
IN EFI_FFS_FILE_HEADER *FfsHeader
|
|
|
|
)
|
|
|
|
{
|
|
|
|
EFI_FFS_FILE_STATE FileState;
|
2011-02-23 04:09:55 +01:00
|
|
|
UINT8 DataCheckSum;
|
2007-07-04 12:51:54 +02:00
|
|
|
|
|
|
|
FileState = GetFileState (ErasePolarity, FfsHeader);
|
|
|
|
switch (FileState) {
|
|
|
|
|
2008-07-18 11:50:09 +02:00
|
|
|
case EFI_FILE_DELETED:
|
|
|
|
case EFI_FILE_DATA_VALID:
|
|
|
|
case EFI_FILE_MARKED_FOR_UPDATE:
|
2011-02-23 04:09:55 +01:00
|
|
|
DataCheckSum = FFS_FIXED_CHECKSUM;
|
|
|
|
if ((FfsHeader->Attributes & FFS_ATTRIB_CHECKSUM) == FFS_ATTRIB_CHECKSUM) {
|
2011-10-27 11:23:19 +02:00
|
|
|
if (IS_FFS_FILE2 (FfsHeader)) {
|
|
|
|
DataCheckSum = CalculateCheckSum8 ((CONST UINT8 *) FfsHeader + sizeof (EFI_FFS_FILE_HEADER2), FFS_FILE2_SIZE (FfsHeader) - sizeof(EFI_FFS_FILE_HEADER2));
|
|
|
|
} else {
|
|
|
|
DataCheckSum = CalculateCheckSum8 ((CONST UINT8 *) FfsHeader + sizeof (EFI_FFS_FILE_HEADER), FFS_FILE_SIZE (FfsHeader) - sizeof(EFI_FFS_FILE_HEADER));
|
|
|
|
}
|
2011-02-23 04:09:55 +01:00
|
|
|
}
|
|
|
|
if (FfsHeader->IntegrityCheck.Checksum.File == DataCheckSum) {
|
|
|
|
return TRUE;
|
|
|
|
}
|
2007-07-04 12:51:54 +02:00
|
|
|
|
2008-07-18 11:50:09 +02:00
|
|
|
default:
|
|
|
|
return FALSE;
|
2007-07-04 12:51:54 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-05-09 09:08:30 +02:00
|
|
|
|